issue report:
if i run the heavy duty test from #16859 a couple of times I can get
the loopback layer in the kernel into a state where there's a loopback
block device allocated, that you can open, but where both LOOP_CLR_FD
and _SET_FD fail with EBUSY. and /dev/loop-control still returns it as
the next free one... weird state util-linux losetup when called to
allocate a new device then freezes
This commit:
* restrict number of attempts to 16
* use 200000ms sleep between attempts
* add note about non-atomic loop device setup to the man page
Reported-by: Lennart Poettering <lennart@poettering.net>
Signed-off-by: Karel Zak <kzak@redhat.com>
file.
.B This setup may be dangerous, can cause data loss, corruption and overwrites.
Use \fB\-\-nooverlap\fR with \fB\-\-find\fR during setup to avoid this problem.
+.sp
+The loop device setup is not an atomic operation when used with \fB\-\-find\fP, and
+.B losetup
+does not protect this operation by any lock. The number of attempts is
+internally restricted to a maximum of 16. It is recommended to use for example
+.BR flock (1)
+to avoid a collision in heavily parallel use cases.
.SH OPTIONS
The \fIsize\fR and \fIoffset\fR
uint64_t blocksize)
{
int hasdev = loopcxt_has_device(lc);
- int rc = 0;
+ int rc = 0, ntries = 0;
/* losetup --find --noverlap file.img */
if (!hasdev && nooverlap) {
rc = loopcxt_setup_device(lc);
if (rc == 0)
break; /* success */
- if (errno == EBUSY && !hasdev)
+
+ if (errno == EBUSY && !hasdev && ntries < 16) {
+ xusleep(200000);
+ ntries++;
continue;
+ }
/* errors */
errpre = hasdev && loopcxt_get_fd(lc) < 0 ?