chiark / gitweb /
timedated: use libsystemd-bus instead of libdbus for bus communication
[elogind.git] / src / nspawn / nspawn.c
index 913e73673a5f5decf7a9cfd4520a5914efbeddbe..ad0287dbf40ee6dc4c6dcf1f052635613ba45663 100644 (file)
@@ -39,9 +39,9 @@
 #include <sys/signalfd.h>
 #include <grp.h>
 #include <linux/fs.h>
-#include <linux/netlink.h>
 #include <sys/un.h>
 #include <sys/socket.h>
+#include <linux/netlink.h>
 
 #include <systemd/sd-daemon.h>
 #include <systemd/sd-bus.h>
@@ -61,8 +61,7 @@
 #include "fdset.h"
 #include "build.h"
 #include "fileio.h"
-#include "bus-internal.h"
-#include "bus-message.h"
+#include "bus-util.h"
 
 #ifndef TTY_GID
 #define TTY_GID 5
@@ -411,12 +410,39 @@ static int mount_binds(const char *dest, char **l, unsigned long flags) {
 
         STRV_FOREACH_PAIR(x, y, l) {
                 _cleanup_free_ char *where = NULL;
+                struct stat source_st, dest_st;
+
+                if (stat(*x, &source_st) < 0) {
+                        log_error("failed to stat %s: %m", *x);
+                        return -errno;
+                }
 
                 where = strjoin(dest, "/", *y, NULL);
                 if (!where)
                         return log_oom();
 
-                mkdir_p_label(where, 0755);
+                if (stat(where, &dest_st) == 0) {
+                        if ((source_st.st_mode & S_IFMT) != (dest_st.st_mode & S_IFMT)) {
+                                log_error("The file types of %s and %s do not match. Refusing bind mount",
+                                                *x, where);
+                                return -EINVAL;
+                        }
+                } else {
+                        /* Create the mount point, but be conservative -- refuse to create block
+                         * and char devices. */
+                        if (S_ISDIR(source_st.st_mode))
+                                mkdir_p_label(where, 0755);
+                        else if (S_ISFIFO(source_st.st_mode))
+                                mkfifo(where, 0644);
+                        else if (S_ISSOCK(source_st.st_mode))
+                                mknod(where, 0644 | S_IFSOCK, 0);
+                        else if (S_ISREG(source_st.st_mode))
+                                touch(where);
+                        else {
+                                log_error("Refusing to create mountpoint for file: %s", *x);
+                                return -ENOTSUP;
+                        }
+                }
 
                 if (mount(*x, where, "bind", MS_BIND, NULL) < 0) {
                         log_error("mount(%s) failed: %m", where);
@@ -494,7 +520,6 @@ static int setup_timezone(const char *dest) {
 
 static int setup_resolv_conf(const char *dest) {
         char _cleanup_free_ *where = NULL;
-        _cleanup_close_ int fd = -1;
 
         assert(dest);
 
@@ -506,18 +531,9 @@ static int setup_resolv_conf(const char *dest) {
         if (!where)
                 return log_oom();
 
-        fd = open(where, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
-
         /* We don't really care for the results of this really. If it
          * fails, it fails, but meh... */
-        if (mount("/etc/resolv.conf", where, "bind", MS_BIND, NULL) < 0)
-                log_warning("Failed to bind mount /etc/resolv.conf: %m");
-        else
-                if (mount("/etc/resolv.conf", where, "bind",
-                          MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
-                        log_error("Failed to remount /etc/resolv.conf readonly: %m");
-                        return -errno;
-                }
+        copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW);
 
         return 0;
 }
@@ -1168,16 +1184,16 @@ static int register_machine(void) {
                         "CreateMachine",
                         &error,
                         NULL,
-                        "sayssuss",
+                        "sayssusa(sv)",
                         arg_machine,
-                        SD_BUS_APPEND_ID128(arg_uuid),
+                        SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
                         "nspawn",
                         "container",
                         (uint32_t) 0,
-                        strempty(arg_slice),
-                        strempty(arg_directory));
+                        strempty(arg_directory),
+                        1, "Slice", "s", strempty(arg_slice));
         if (r < 0) {
-                log_error("Failed to register machine: %s", error.message);
+                log_error("Failed to register machine: %s", error.message ? error.message : strerror(-r));
                 return r;
         }
 
@@ -1206,7 +1222,7 @@ int main(int argc, char *argv[]) {
         bool saved_attr_valid = false;
         struct winsize ws;
         int kmsg_socket_pair[2] = { -1, -1 };
-        FDSet *fds = NULL;
+        _cleanup_fdset_free_ FDSet *fds = NULL;
 
         log_parse_environment();
         log_open();
@@ -1602,7 +1618,7 @@ int main(int argc, char *argv[]) {
                                 }
 
                                 if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", n_fd_passed) < 0) ||
-                                    (asprintf((char **)(envp + n_env++), "LISTEN_PID=%lu", (unsigned long) 1) < 0)) {
+                                    (asprintf((char **)(envp + n_env++), "LISTEN_PID=1") < 0)) {
                                         log_oom();
                                         goto child_fail;
                                 }
@@ -1708,7 +1724,5 @@ finish:
         free(arg_directory);
         free(arg_machine);
 
-        fdset_free(fds);
-
         return r;
 }