mount: loop device race condition
Fix race in mount -o loop Retry acquiring a loop device if the setup failed with EBUSY. Signed-Off-By: Matthias Koenig <mkoenig@suse.de> Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
653872612c
commit
95ba33f7a4
|
@ -341,8 +341,16 @@ set_loop(const char *device, const char *file, unsigned long long offset,
|
|||
}
|
||||
|
||||
if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
|
||||
perror("ioctl: LOOP_SET_FD");
|
||||
return 1;
|
||||
close(fd);
|
||||
close(ffd);
|
||||
if (errno == EBUSY) {
|
||||
if (verbose)
|
||||
printf(_("ioctl LOOP_SET_FD failed: %s\n"), strerror(errno));
|
||||
return 2;
|
||||
} else {
|
||||
perror("ioctl: LOOP_SET_FD");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
close (ffd);
|
||||
|
||||
|
|
|
@ -846,20 +846,45 @@ loop_check(const char **spec, const char **type, int *flags,
|
|||
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);
|
||||
offset = opt_offset ? strtoull(opt_offset, NULL, 0) : 0;
|
||||
if (set_loop(*loopdev, *loopfile, offset,
|
||||
opt_encryption, pfd, &loopro)) {
|
||||
|
||||
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, offset,
|
||||
opt_encryption, pfd, &loopro))) {
|
||||
if (res == 2) {
|
||||
/* loop dev has been grabbed by some other process,
|
||||
try again, if not given explicitly */
|
||||
if (!opt_loopdev) {
|
||||
if (verbose)
|
||||
printf(_("mount: stolen loop=%s ...trying again\n"), *loopdev);
|
||||
my_free(*loopdev);
|
||||
*loopdev = NULL;
|
||||
continue;
|
||||
}
|
||||
error(_("mount: stolen loop=%s"), *loopdev);
|
||||
return EX_FAIL;
|
||||
|
||||
} else {
|
||||
if (verbose)
|
||||
printf(_("mount: failed setting up loop device\n"));
|
||||
if (!opt_loopdev) {
|
||||
my_free(*loopdev);
|
||||
*loopdev = NULL;
|
||||
}
|
||||
return EX_FAIL;
|
||||
}
|
||||
}
|
||||
} while (!*loopdev);
|
||||
|
||||
if (verbose > 1)
|
||||
printf(_("mount: setup loop device successfully\n"));
|
||||
*spec = *loopdev;
|
||||
|
|
Loading…
Reference in New Issue