diff -Naur a/sys-utils/losetup.8 b/sys-utils/losetup.8 --- a/sys-utils/losetup.8 2021-10-20 15:23:28.983136437 -0700 +++ b/sys-utils/losetup.8 2021-10-20 15:23:54.314264432 -0700 @@ -68,6 +68,13 @@ 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 @@ -170,6 +177,11 @@ displays the status of a loop device, it returns 1 if the device is not configured and 2 if an error occurred which prevented determining the status of the device. +.SH NOTES +Since version 2.37 +.B losetup +uses LOOP_CONFIGURE ioctl to setup a new loop device by one ioctl call. The +old versions use LOOP_SET_FD and LOOP_SET_STATUS64 ioctls to do the same. .SH FILES .TP diff -Naur a/sys-utils/losetup.c b/sys-utils/losetup.c --- a/sys-utils/losetup.c 2021-10-20 15:23:28.902136028 -0700 +++ b/sys-utils/losetup.c 2021-10-20 15:23:54.315264437 -0700 @@ -463,7 +463,7 @@ const char *file, uint64_t offset, uint64_t sizelimit) { int hasdev = loopcxt_has_device(lc); - int rc = 0; + int rc = 0, ntries = 0; /* losetup --find --noverlap file.img */ if (!hasdev && nooverlap) { @@ -556,8 +556,12 @@ 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 ?