summaryrefslogtreecommitdiffstats
path: root/src/utils/sys-utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/sys-utils')
-rw-r--r--src/utils/sys-utils/xlosetup.87
-rw-r--r--src/utils/sys-utils/xlosetup.c10
2 files changed, 14 insertions, 3 deletions
diff --git a/src/utils/sys-utils/xlosetup.8 b/src/utils/sys-utils/xlosetup.8
index 4e063e6..c948899 100644
--- a/src/utils/sys-utils/xlosetup.8
+++ b/src/utils/sys-utils/xlosetup.8
@@ -68,6 +68,13 @@ It's possible to create more independent xloop 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 xloop device setup is not an atomic operation when used with \fB\-\-find\fP, and
+.B xlosetup
+does not protect this operation by any lock. The number of attempts is
+internally restricted to a maximum of 64. 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
diff --git a/src/utils/sys-utils/xlosetup.c b/src/utils/sys-utils/xlosetup.c
index 60fa0ba..cbc2e69 100644
--- a/src/utils/sys-utils/xlosetup.c
+++ b/src/utils/sys-utils/xlosetup.c
@@ -469,7 +469,7 @@ static int create_loop(struct loopdev_cxt *lc,
uint64_t blocksize, uint32_t file_fmt_type)
{
int hasdev = loopcxt_has_device(lc);
- int rc = 0;
+ int rc = 0, ntries = 0;
/* xlosetup --find --noverlap file.img */
if (!hasdev && nooverlap) {
@@ -501,7 +501,7 @@ static int create_loop(struct loopdev_cxt *lc,
errx(EXIT_FAILURE, _("%s: overlapping encrypted xloop device exists"), file);
}
- lc->info.lo_flags &= ~LO_FLAGS_AUTOCLEAR;
+ lc->config.info.lo_flags &= ~LO_FLAGS_AUTOCLEAR;
if (loopcxt_ioctl_status(lc)) {
loopcxt_deinit(lc);
errx(EXIT_FAILURE, _("%s: failed to re-use xloop device"), file);
@@ -571,8 +571,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 < 64) {
+ xusleep(200000);
+ ntries++;
continue;
+ }
/* errors */
errpre = hasdev && loopcxt_get_fd(lc) < 0 ?