]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect-image: wait for the root to appear
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 13 Dec 2018 13:35:15 +0000 (14:35 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 17 Dec 2018 12:50:57 +0000 (13:50 +0100)
dissect-image would wait for the root device and paritions to appear. But if we
had an image with no partitions, we'd not wait at all. If the kernel or udev
were slow in creating device nodes or symlinks, subsequent mount attempt might
fail if nspawn won the race.

Calling wait_for_partitions_to_appear() in case of no partitions means that we
verify that the kernel agrees that there are no partitions. We verify that the
kernel sees the same number of partitions as blkid, so let's that also in this
case.

This makes the failure in #10526 much less likely, but doesn't eliminate it
completely. Stay tuned.

src/shared/dissect-image.c

index 0147c45d8e067882d9299c929714db8ecc6d03bc..0e2fb9afbe6f2251e3a1e63ee6e0eb0106fdf4c5 100644 (file)
@@ -221,6 +221,8 @@ static int loop_wait_for_partitions_to_appear(
                 sd_device_enumerator **ret_enumerator) {
         int r;
 
+        log_debug("Waiting for device (parent + %d partitions) to appear...", num_partitions);
+
         for (unsigned i = 0; i < N_DEVICE_NODE_LIST_ATTEMPTS; i++) {
                 r = wait_for_partitions_to_appear(fd, d, num_partitions, ret_enumerator);
                 if (r != -EAGAIN)
@@ -320,6 +322,10 @@ int dissect_image(
         if (!m)
                 return -ENOMEM;
 
+        r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
+        if (r < 0)
+                return r;
+
         if (!(flags & DISSECT_IMAGE_GPT_ONLY) &&
             (flags & DISSECT_IMAGE_REQUIRE_ROOT)) {
                 const char *usage = NULL;
@@ -353,6 +359,10 @@ int dissect_image(
 
                         m->encrypted = streq_ptr(fstype, "crypto_LUKS");
 
+                        r = loop_wait_for_partitions_to_appear(fd, d, 0, &e);
+                        if (r < 0)
+                                return r;
+
                         *ret = TAKE_PTR(m);
 
                         return 0;
@@ -374,10 +384,6 @@ int dissect_image(
         if (!pl)
                 return -errno ?: -ENOMEM;
 
-        r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
-        if (r < 0)
-                return r;
-
         r = loop_wait_for_partitions_to_appear(fd, d, blkid_partlist_numof_partitions(pl), &e);
         if (r < 0)
                 return r;