On Fri, Mar 14, 2014 at 5:43 AM, Greg KH <gre...@linuxfoundation.org> wrote: > This makes it possible to initialize the /etc/machine-id file on an > arbitrary filesystem hierarchy. This helps systems that wish to run > this at image creation time in a subdirectory, or from initramfs before > pivot-root is called.
Thanks. Applied, with a little tweak: I used the _cleanup_free_ macros. Please have a look in case I messed something up. Cheers, Tom > diff --git a/man/systemd-machine-id-setup.xml > b/man/systemd-machine-id-setup.xml > index 5c34b345d012..b879b40b997d 100644 > --- a/man/systemd-machine-id-setup.xml > +++ b/man/systemd-machine-id-setup.xml > @@ -96,6 +96,14 @@ > <para>The following options are understood:</para> > > <variablelist> > + <varlistentry> > + <term><option>--root=ROOT</option></term> > + <listitem><para>Takes a directory path > + as an argument. All paths will be > + prefixed with the given alternate ROOT > + path, including config search paths. > + </para></listitem> > + </varlistentry> > <xi:include href="standard-options.xml" > xpointer="help" /> > <xi:include href="standard-options.xml" > xpointer="version" /> > </variablelist> > diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c > index 1b55da7e56b8..7d52b468a11a 100644 > --- a/src/core/machine-id-setup.c > +++ b/src/core/machine-id-setup.c > @@ -59,18 +59,22 @@ static int shorten_uuid(char destination[36], const char > *source) { > return -EINVAL; > } > > -static int generate(char id[34]) { > - int fd, r; > +static int generate(char id[34], const char *root) { > + int fd, r = 0; > unsigned char *p; > sd_id128_t buf; > char *q; > ssize_t k; > const char *vm_id; > + char *dbus_machine_id; > > assert(id); > > + if (asprintf(&dbus_machine_id, "%s/var/lib/dbus/machine-id", root) < > 0) > + return log_oom(); > + > /* First, try reading the D-Bus machine id, unless it is a symlink */ > - fd = open("/var/lib/dbus/machine-id", > O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); > + fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); > if (fd >= 0) { > k = loop_read(fd, id, 33, false); > close_nointr_nofail(fd); > @@ -83,7 +87,7 @@ static int generate(char id[34]) { > id[33] = 0; > > log_info("Initializing machine ID from D-Bus > machine ID."); > - return 0; > + goto finish; > } > } > } > @@ -105,7 +109,8 @@ static int generate(char id[34]) { > r = shorten_uuid(id, uuid); > if (r >= 0) { > log_info("Initializing machine ID > from KVM UUID."); > - return 0; > + r = 0; > + goto finish; > } > } > } > @@ -124,7 +129,8 @@ static int generate(char id[34]) { > r = shorten_uuid(id, e); > if (r >= 0) { > log_info("Initializing machine ID > from container UUID."); > - return 0; > + r = 0; > + goto finish; > } > } > } > @@ -134,7 +140,7 @@ static int generate(char id[34]) { > r = sd_id128_randomize(&buf); > if (r < 0) { > log_error("Failed to open /dev/urandom: %s", strerror(-r)); > - return r; > + goto finish; > } > > for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += > 2) { > @@ -147,15 +153,27 @@ static int generate(char id[34]) { > > log_info("Initializing machine ID from random generator."); > > - return 0; > +finish: > + free(dbus_machine_id); > + return r; > } > > -int machine_id_setup(void) { > +int machine_id_setup(const char *root) { > _cleanup_close_ int fd = -1; > - int r; > + int r = 0; > bool writable = false; > struct stat st; > char id[34]; /* 32 + \n + \0 */ > + char *etc_machine_id = NULL; > + char *run_machine_id = NULL; > + > + if (asprintf(&etc_machine_id, "%s/etc/machine-id", root) < 0) > + return log_oom(); > + > + if (asprintf(&run_machine_id, "%s/run/machine-id", root) < 0) { > + r = log_oom(); > + goto finish; > + } > > RUN_WITH_UMASK(0000) { > /* We create this 0444, to indicate that this isn't really > @@ -163,14 +181,15 @@ int machine_id_setup(void) { > * will be owned by root it doesn't matter much, but maybe > * people look. */ > > - fd = open("/etc/machine-id", > O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444); > + fd = open(etc_machine_id, O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, > 0444); > if (fd >= 0) > writable = true; > else { > - fd = open("/etc/machine-id", > O_RDONLY|O_CLOEXEC|O_NOCTTY); > + fd = open(etc_machine_id, > O_RDONLY|O_CLOEXEC|O_NOCTTY); > if (fd < 0) { > - log_error("Cannot open /etc/machine-id: %m"); > - return -errno; > + log_error("Cannot open %s: %m", > etc_machine_id); > + r = -errno; > + goto finish; > } > > writable = false; > @@ -179,7 +198,8 @@ int machine_id_setup(void) { > > if (fstat(fd, &st) < 0) { > log_error("fstat() failed: %m"); > - return -errno; > + r = -errno; > + goto finish; > } > > if (S_ISREG(st.st_mode)) > @@ -187,21 +207,21 @@ int machine_id_setup(void) { > id[32] = 0; > > if (id128_is_valid(id)) > - return 0; > + goto finish; > } > > /* Hmm, so, the id currently stored is not useful, then let's > * generate one */ > > - r = generate(id); > + r = generate(id, root); > if (r < 0) > - return r; > + goto finish; > > if (S_ISREG(st.st_mode) && writable) { > lseek(fd, 0, SEEK_SET); > > if (loop_write(fd, id, 33, false) == 33) > - return 0; > + goto finish; > } > > close_nointr_nofail(fd); > @@ -211,27 +231,31 @@ int machine_id_setup(void) { > * /run/machine-id as a replacement */ > > RUN_WITH_UMASK(0022) { > - r = write_string_file("/run/machine-id", id); > + r = write_string_file(run_machine_id, id); > } > if (r < 0) { > - log_error("Cannot write /run/machine-id: %s", strerror(-r)); > - unlink("/run/machine-id"); > - return r; > + log_error("Cannot write %s: %s", run_machine_id, > strerror(-r)); > + unlink(run_machine_id); > + goto finish; > } > > /* And now, let's mount it over */ > - r = mount("/run/machine-id", "/etc/machine-id", NULL, MS_BIND, NULL); > + r = mount(run_machine_id, etc_machine_id, NULL, MS_BIND, NULL); > if (r < 0) { > - log_error("Failed to mount /etc/machine-id: %m"); > - unlink_noerrno("/run/machine-id"); > - return -errno; > + log_error("Failed to mount %s: %m", etc_machine_id); > + unlink_noerrno(run_machine_id); > + r = -errno; > + goto finish; > } > > - log_info("Installed transient /etc/machine-id file."); > + log_info("Installed transient %s file.", etc_machine_id); > > /* Mark the mount read-only */ > - if (mount(NULL, "/etc/machine-id", NULL, > MS_BIND|MS_RDONLY|MS_REMOUNT, NULL) < 0) > - log_warning("Failed to make transient /etc/machine-id > read-only: %m"); > + if (mount(NULL, etc_machine_id, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, > NULL) < 0) > + log_warning("Failed to make transient %s read-only: %m", > etc_machine_id); > > - return 0; > +finish: > + free(etc_machine_id); > + free(run_machine_id); > + return r; > } > diff --git a/src/core/machine-id-setup.h b/src/core/machine-id-setup.h > index b9e6b4d674a6..b0583eefc8fe 100644 > --- a/src/core/machine-id-setup.h > +++ b/src/core/machine-id-setup.h > @@ -21,4 +21,4 @@ > along with systemd; If not, see <http://www.gnu.org/licenses/>. > ***/ > > -int machine_id_setup(void); > +int machine_id_setup(const char *root); > diff --git a/src/core/main.c b/src/core/main.c > index f1b06d88803e..cc876efa9c2c 100644 > --- a/src/core/main.c > +++ b/src/core/main.c > @@ -1582,7 +1582,7 @@ int main(int argc, char *argv[]) { > kmod_setup(); > #endif > hostname_setup(); > - machine_id_setup(); > + machine_id_setup(""); > loopback_setup(); > > test_mtab(); > diff --git a/src/machine-id-setup/machine-id-setup-main.c > b/src/machine-id-setup/machine-id-setup-main.c > index 84af925f517e..a67d436dbd7c 100644 > --- a/src/machine-id-setup/machine-id-setup-main.c > +++ b/src/machine-id-setup/machine-id-setup-main.c > @@ -29,12 +29,15 @@ > #include "log.h" > #include "build.h" > > +static const char *arg_root = ""; > + > static int help(void) { > > printf("%s [OPTIONS...]\n\n" > "Initialize /etc/machine-id from a random source.\n\n" > " -h --help Show this help\n" > - " --version Show package version\n", > + " --version Show package version\n" > + " --root Filesystem root\n", > program_invocation_short_name); > > return 0; > @@ -43,12 +46,14 @@ static int help(void) { > static int parse_argv(int argc, char *argv[]) { > > enum { > - ARG_VERSION = 0x100 > + ARG_VERSION = 0x100, > + ARG_ROOT, > }; > > static const struct option options[] = { > { "help", no_argument, NULL, 'h' }, > { "version", no_argument, NULL, ARG_VERSION }, > + { "root", required_argument, NULL, ARG_ROOT }, > {} > }; > > @@ -69,6 +74,10 @@ static int parse_argv(int argc, char *argv[]) { > puts(SYSTEMD_FEATURES); > return 0; > > + case ARG_ROOT: > + arg_root = optarg; > + break; > + > case '?': > return -EINVAL; > > @@ -95,5 +104,5 @@ int main(int argc, char *argv[]) { > if (r <= 0) > return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; > > - return machine_id_setup() < 0 ? EXIT_FAILURE : EXIT_SUCCESS; > + return machine_id_setup(arg_root) < 0 ? EXIT_FAILURE : EXIT_SUCCESS; > } > _______________________________________________ > systemd-devel mailing list > systemd-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/systemd-devel _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel