From: Lennart Poettering Date: Wed, 5 Sep 2012 21:39:16 +0000 (-0700) Subject: nspawn: generate a new randomized boot ID for each container X-Git-Tag: v190~169 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=04bc4a3f47074d22035831965e97b0990fcf6f63 nspawn: generate a new randomized boot ID for each container --- diff --git a/TODO b/TODO index be301e206..92d709ee4 100644 --- a/TODO +++ b/TODO @@ -80,16 +80,12 @@ Features: * tmpfiles: skip mknod if CAP_MKNOD is missing -* fake boot id - * bind mount read-only the cgroup tree higher than than nspawn * currently system services appear not to generate core dumps... * introduce /run/kmsg in containers? -* introduce $container_boot_id? - * wall messages for shutdown should move to logind * allow writing multiple conditions in unit files on one line diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index ed72c3ebf..8765b0185 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -337,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) @@ -345,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) @@ -365,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); @@ -377,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[] = @@ -1218,6 +1275,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;