chiark / gitweb /
nspawn: don't provide /dev/rtc0 in the container
[elogind.git] / src / nspawn / nspawn.c
index 7d188f0712820f9c171bcce10b076590405a1ec3..7b1b5eab846eb1660fb3b176dcbd0ee6495557d8 100644 (file)
@@ -53,6 +53,7 @@
 #include "path-util.h"
 #include "loopback-setup.h"
 #include "sd-id128.h"
+#include "dev-setup.h"
 
 typedef enum LinkJournal {
         LINK_NO,
@@ -268,8 +269,7 @@ static int mount_all(const char *dest) {
                 { "proc",      "/proc",     "proc",  NULL,       MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
                 { "/proc/sys", "/proc/sys", NULL,    NULL,       MS_BIND, true                       },   /* Bind mount first */
                 { NULL,        "/proc/sys", NULL,    NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
-                { "/sys",      "/sys",      NULL,    NULL,       MS_BIND,                      true  },   /* Bind mount first */
-                { NULL,        "/sys",      NULL,    NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
+                { "sysfs",     "/sys",      "sysfs", NULL,       MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
                 { "tmpfs",     "/dev",      "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME,     true  },
                 { "/dev/pts",  "/dev/pts",  NULL,    NULL,       MS_BIND,                      true  },
                 { "tmpfs",     "/run",      "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true  },
@@ -295,7 +295,7 @@ static int mount_all(const char *dest) {
                         break;
                 }
 
-                t = path_is_mount_point(where, false);
+                t = path_is_mount_point(where, true);
                 if (t < 0) {
                         log_error("Failed to detect whether %s is a mount point: %s", where, strerror(-t));
                         free(where);
@@ -306,6 +306,10 @@ static int mount_all(const char *dest) {
                         continue;
                 }
 
+                /* Skip this entry if it is not a remount. */
+                if (mount_table[k].what && t > 0)
+                        continue;
+
                 mkdir_p_label(where, 0755);
 
                 if (mount(mount_table[k].what,
@@ -333,7 +337,8 @@ static int setup_timezone(const char *dest) {
         assert(dest);
 
         /* Fix the timezone, if possible */
-        if (asprintf(&where, "%s/etc/localtime", dest) < 0)
+        where = strappend(dest, "/etc/localtime");
+        if (!where)
                 return log_oom();
 
         if (mount("/etc/localtime", where, "bind", MS_BIND, NULL) >= 0)
@@ -341,7 +346,8 @@ static int setup_timezone(const char *dest) {
 
         free(where);
 
-        if (asprintf(&where, "%s/etc/timezone", dest) < 0)
+        where = strappend(dest, "/etc/timezone");
+        if (!where)
                 return log_oom();
 
         if (mount("/etc/timezone", where, "bind", MS_BIND, NULL) >= 0)
@@ -361,9 +367,9 @@ static int setup_resolv_conf(const char *dest) {
                 return 0;
 
         /* Fix resolv.conf, if possible */
-        if (asprintf(&where, "%s/etc/resolv.conf", dest) < 0) {
+        where = strappend(dest, "/etc/resolv.conf");
+        if (!where)
                 return log_oom();
-        }
 
         if (mount("/etc/resolv.conf", where, "bind", MS_BIND, NULL) >= 0)
                 mount("/etc/resolv.conf", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
@@ -373,6 +379,61 @@ static int setup_resolv_conf(const char *dest) {
         return 0;
 }
 
+static int setup_boot_id(const char *dest) {
+        char *from = NULL, *to = NULL;
+        sd_id128_t rnd;
+        char as_uuid[37];
+        int r;
+
+        assert(dest);
+
+        /* Generate a new randomized boot ID, so that each boot-up of
+         * the container gets a new one */
+
+        from = strappend(dest, "/dev/proc-sys-kernel-random-boot-id");
+        if (!from) {
+                r = log_oom();
+                goto finish;
+        }
+
+        to = strappend(dest, "/proc/sys/kernel/random/boot_id");
+        if (!to) {
+                r = log_oom();
+                goto finish;
+        }
+
+        r = sd_id128_randomize(&rnd);
+        if (r < 0) {
+                log_error("Failed to generate random boot id: %s", strerror(-r));
+                goto finish;
+        }
+
+        snprintf(as_uuid, sizeof(as_uuid),
+                 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                 SD_ID128_FORMAT_VAL(rnd));
+        char_array_0(as_uuid);
+
+        r = write_one_line_file(from, as_uuid);
+        if (r < 0) {
+                log_error("Failed to write boot id: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (mount(from, to, "bind", MS_BIND, NULL) < 0) {
+                log_error("Failed to bind mount boot id: %m");
+                r = -errno;
+        } else
+                mount(from, to, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
+
+        unlink(from);
+
+finish:
+        free(from);
+        free(to);
+
+        return r;
+}
+
 static int copy_devnodes(const char *dest) {
 
         static const char devnodes[] =
@@ -382,8 +443,7 @@ static int copy_devnodes(const char *dest) {
                 "random\0"
                 "urandom\0"
                 "tty\0"
-                "ptmx\0"
-                "rtc0\0";
+                "ptmx\0";
 
         const char *d;
         int r = 0;
@@ -1204,6 +1264,8 @@ int main(int argc, char *argv[]) {
                 if (copy_devnodes(arg_directory) < 0)
                         goto child_fail;
 
+                dev_setup(arg_directory);
+
                 if (setup_dev_console(arg_directory, console) < 0)
                         goto child_fail;
 
@@ -1212,6 +1274,9 @@ int main(int argc, char *argv[]) {
 
                 close_nointr_nofail(kmsg_socket_pair[1]);
 
+                if (setup_boot_id(arg_directory) < 0)
+                        goto child_fail;
+
                 if (setup_timezone(arg_directory) < 0)
                         goto child_fail;