]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/loop-util: spin on open() returning ENOENT too 14261/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 15 Dec 2019 19:58:59 +0000 (20:58 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 15 Dec 2019 20:06:42 +0000 (21:06 +0100)
https://github.com/systemd/systemd/pull/14261#discussion_r355001559

src/shared/loop-util.c

index 8b4d13e6164826e7d84b156716c19368166b9736..6cb45f1f1bc15db75a2059d1e99dc785c317b4db 100644 (file)
@@ -112,14 +112,20 @@ int loop_device_make_full(
                         return -ENOMEM;
 
                 loop = open(loopdev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags);
-                if (loop < 0)
-                        return -errno;
-                if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
-                        loop_with_fd = TAKE_FD(loop);
-                        break;
+                if (loop < 0) {
+                        /* Somebody might've gotten the same number from the kernel, used the device,
+                         * and called LOOP_CTL_REMOVE on it. Let's retry with a new number. */
+                        if (errno != ENOENT)
+                                return -errno;
+                } else {
+                        if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
+                                loop_with_fd = TAKE_FD(loop);
+                                break;
+                        }
+                        if (errno != EBUSY)
+                                return -errno;
                 }
-                if (errno != EBUSY)
-                        return -errno;
+
                 if (++n_attempts >= 64) /* Give up eventually */
                         return -EBUSY;