From: Zbigniew Jędrzejewski-Szmek Date: Sun, 15 Dec 2019 19:58:59 +0000 (+0100) Subject: shared/loop-util: spin on open() returning ENOENT too X-Git-Tag: v245-rc1~261^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=01813148619cb4b78427abe1cb8ccbe2b9916a03;p=thirdparty%2Fsystemd.git shared/loop-util: spin on open() returning ENOENT too https://github.com/systemd/systemd/pull/14261#discussion_r355001559 --- diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index 8b4d13e6164..6cb45f1f1bc 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -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;