summaryrefslogtreecommitdiffstats
path: root/src/utils/sys-utils
diff options
context:
space:
mode:
authorManuel Bentele2020-12-02 07:07:44 +0100
committerManuel Bentele2020-12-02 07:07:44 +0100
commitcbdb5025a3127d20a1e18a14bbcb0cc17be84710 (patch)
tree6df46d1e538691cee1b34fba55d6466253d198e2 /src/utils/sys-utils
parentAdd Linux kernel module support for 32-bit architectures (eg. ARM) (diff)
downloadxloop-cbdb5025a3127d20a1e18a14bbcb0cc17be84710.tar.gz
xloop-cbdb5025a3127d20a1e18a14bbcb0cc17be84710.tar.xz
xloop-cbdb5025a3127d20a1e18a14bbcb0cc17be84710.zip
Setup xloop device with XLOOP_CONFIGURE ioctl call
This feature allows the userspace tool xlosetup to completely setup a loop device with a single ioctl call, removing the in-between state where the device can be partially configured, eg. the loop device has a backing file associated with it, but is reading from the wrong offset. Besides removing the intermediate state, another big benefit of this ioctl is that XLOOP_SET_STATUS can be slow. The main reason for this slowness is that XLOOP_SET_STATUS(64) calls blk_mq_freeze_queue() to freeze the associated queue. This requires waiting for RCU.
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 ?