diff --git a/sys-utils/losetup.8 b/sys-utils/losetup.8 index c3ff5fe06..3d03e513f 100644 --- a/sys-utils/losetup.8 +++ b/sys-utils/losetup.8 @@ -68,6 +68,13 @@ It's possible to create more independent loop devices for the same backing 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 @@ -177,6 +184,11 @@ returns 0 on success, nonzero on failure. When 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 ENVIRONMENT .IP LOOPDEV_DEBUG=all diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c index cc4d206b7..51baf1440 100644 --- a/sys-utils/losetup.c +++ b/sys-utils/losetup.c @@ -476,7 +476,7 @@ static int create_loop(struct loopdev_cxt *lc, 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) { @@ -572,8 +572,12 @@ static int create_loop(struct loopdev_cxt *lc, 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 ?