]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
machine-id-setup: acquire machine ID from /run/machine-id if possible 32915/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 19 May 2024 00:14:27 +0000 (09:14 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 19 May 2024 17:17:57 +0000 (02:17 +0900)
If machine ID is previously stored at /run/machine-id, then let's reuse
it. This is important on switching root and /etc/machine-id was previously
a mount point.

Fixes #32908.

src/shared/machine-id-setup.c

index 8dab2ad4282c09db2b9d4dff685a3322aecf5e77..48ee2dd3061c79afc08a18b049cbbb69fa5b97ad 100644 (file)
@@ -48,13 +48,22 @@ static int acquire_machine_id_from_credential(sd_id128_t *ret) {
         return 0;
 }
 
-static int generate_machine_id(const char *root, sd_id128_t *ret) {
+static int acquire_machine_id(const char *root, sd_id128_t *ret) {
         _cleanup_close_ int fd = -EBADF;
         int r;
 
         assert(ret);
 
-        /* First, try reading the D-Bus machine id, unless it is a symlink */
+        /* First, try reading the machine ID from /run/machine-id, which may not be mounted on
+         * /etc/machine-id yet. This is important on switching root, Otherwise, machine ID may be changed
+         * after the transition. */
+        if (empty_or_root(root) && running_in_chroot() <= 0 &&
+            id128_read("/run/machine-id", ID128_FORMAT_PLAIN, ret) >= 0) {
+                log_info("Reusing machine ID stored in /run/machine-id.");
+                return 1; /* Indicate that the machine ID is reused. */
+        }
+
+        /* Then, try reading the D-Bus machine id, unless it is a symlink */
         fd = chase_and_open("/var/lib/dbus/machine-id", root, CHASE_PREFIX_ROOT | CHASE_NOFOLLOW, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
         if (fd >= 0 && id128_read_fd(fd, ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, ret) >= 0) {
                 log_info("Initializing machine ID from D-Bus machine ID.");
@@ -63,9 +72,8 @@ static int generate_machine_id(const char *root, sd_id128_t *ret) {
 
         if (empty_or_root(root) && running_in_chroot() <= 0) {
                 /* Let's use a system credential for the machine ID if we can */
-                r = acquire_machine_id_from_credential(ret);
-                if (r >= 0)
-                        return r;
+                if (acquire_machine_id_from_credential(ret) >= 0)
+                        return 0;
 
                 /* If that didn't work, see if we are running in a container,
                  * and a machine ID was passed in via $container_uuid the way
@@ -105,7 +113,7 @@ static int generate_machine_id(const char *root, sd_id128_t *ret) {
 int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_id, sd_id128_t *ret) {
         const char *etc_machine_id, *run_machine_id;
         _cleanup_close_ int fd = -EBADF;
-        bool writable;
+        bool writable, write_run_machine_id = true;
         int r;
 
         etc_machine_id = prefix_roota(root, "/etc/machine-id");
@@ -146,10 +154,11 @@ int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_
                 if (id128_read_fd(fd, ID128_FORMAT_PLAIN, &machine_id) >= 0)
                         goto finish;
 
-                /* Hmm, so, the id currently stored is not useful, then let's generate one */
-                r = generate_machine_id(root, &machine_id);
+                /* Hmm, so, the id currently stored is not useful, then let's acquire one. */
+                r = acquire_machine_id(root, &machine_id);
                 if (r < 0)
                         return r;
+                write_run_machine_id = !r;
         }
 
         if (writable) {
@@ -187,11 +196,13 @@ int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_
 
         run_machine_id = prefix_roota(root, "/run/machine-id");
 
-        WITH_UMASK(0022)
-                r = id128_write(run_machine_id, ID128_FORMAT_PLAIN, machine_id);
-        if (r < 0) {
-                (void) unlink(run_machine_id);
-                return log_error_errno(r, "Cannot write %s: %m", run_machine_id);
+        if (write_run_machine_id) {
+                WITH_UMASK(0022)
+                        r = id128_write(run_machine_id, ID128_FORMAT_PLAIN, machine_id);
+                if (r < 0) {
+                        (void) unlink(run_machine_id);
+                        return log_error_errno(r, "Cannot write %s: %m", run_machine_id);
+                }
         }
 
         /* And now, let's mount it over */