3
0
forked from pool/util-linux
util-linux/util-linux-2.12r-mount_racy_loop.patch

71 lines
2.2 KiB
Diff

Index: util-linux-2.12r/mount/lomount.c
===================================================================
--- util-linux-2.12r.orig/mount/lomount.c
+++ util-linux-2.12r/mount/lomount.c
@@ -1005,7 +1005,17 @@ set_loop(const char *device, const char
}
if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
- perror("ioctl: LOOP_SET_FD");
+ switch (errno) {
+ case EBUSY:
+ ret = 2;
+ if (verbose)
+ perror("ioctl: LOOP_SET_FD");
+ break;
+ default:
+ ret = 1;
+ perror("ioctl: LOOP_SET_FD");
+ break;
+ }
keyclean_close_fd_ffd_return1:
memset(loopinfo.lo_encrypt_key, 0, sizeof(loopinfo.lo_encrypt_key));
memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits));
Index: util-linux-2.12r/mount/mount.c
===================================================================
--- util-linux-2.12r.orig/mount/mount.c
+++ util-linux-2.12r/mount/mount.c
@@ -653,18 +653,32 @@ loop_check(const char **spec, const char
printf(_("mount: skipping the setup of a loop device\n"));
} else {
int loopro = (*flags & MS_RDONLY);
+ int res;
- if (!*loopdev || !**loopdev)
- *loopdev = find_unused_loop_device();
- if (!*loopdev)
- return EX_SYSERR; /* no more loop devices */
- if (verbose)
- printf(_("mount: going to use the loop device %s\n"), *loopdev);
- if (set_loop (*loopdev, *loopfile, &loopro, type, AutoChmodPtr)) {
+ do {
+ if (!*loopdev || !**loopdev)
+ *loopdev = find_unused_loop_device();
+ if (!*loopdev)
+ return EX_SYSERR; /* no more loop devices */
if (verbose)
- printf(_("mount: failed setting up loop device\n"));
- return EX_FAIL;
- }
+ printf(_("mount: going to use the loop device %s\n"), *loopdev);
+ if (res = set_loop (*loopdev, *loopfile, &loopro, type, AutoChmodPtr)) {
+ switch(res) {
+ case 2:
+ /* loop dev has been grabbed by some other process,
+ try again */
+ if (verbose)
+ printf("mount: stolen loop=%s ...trying again\n", *loopdev);
+ *loopdev = NULL;
+ continue;
+ default:
+ if (verbose)
+ printf(_("mount: failed setting up loop device\n"));
+ return EX_FAIL;
+ }
+ }
+ } while (!*loopdev);
+
if (verbose > 1)
printf(_("mount: setup loop device successfully\n"));
*spec = *loopdev;