Hi! > I think it wouldn't. Please, see below. > > ## Problem 1 ## > Rapid execution of 'losetup /dev/loop0' file + 'losetup -d /dev/loop0' > may fail. > > Reproducer: > for i in `seq 20`; do > echo "attach" > losetup /dev/loop0 file1.img > echo "detach" > losetup -d /dev/loop0 > done > > 1. Kernel versions without the above kernel patch should fail on the > "detach" phase, i.e. on > if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ > return -EBUSY; > in loop_clr_fd(). > > However, I've not tested it by myself. > > And Jan's commit: > > commit 554b1793a1aa34f8918e8b1c04d8c6835f4a5710 > Author: Jan Stancek <jstan...@redhat.com> > Date: Tue Jan 20 14:35:49 2015 +0100 > > tst_device: sleep/retry if LOOP_CLR_FD fails with EBUSY > > Rapid succession of device attach/detach may lead to EBUSY > from ioctl(LOOP_CLR_FD), because udev rules might still be > running. > > Sleep/retry for a short period if LOOP_CLR_FD fails with EBUSY. > > Signed-off-by: Jan Stancek <jstan...@redhat.com> > Acked-by: Cyril Hrubis <chru...@suse.cz> > > is to fix this scenario.
This has been added due to udev holding reference to the device and preventing the detach. Looks like they "fixed" this in kernel with lazy detach meanwhile... > 2. However, newer kernels (i.e. with the above kernel patch) will fail > with EBUSY at the "attach" phase, because loop_clr_fd() will always > return 0 and mark the loop device for auto clearing, but loop_set_fd() > will go this path: > > error = -EBUSY; > if (lo->lo_state != Lo_unbound) > goto out_putf; > > /* ... */ > > out_putf: > fput(file); > out: > /* This is safe: open() is still holding a reference. */ > module_put(THIS_MODULE); > return error; Hmm, that shouldn't be needed, because the we do losetup -f to get free loop device before the attach operation. If that returns a device that hasn't been detached yet because of lazy detaching it's a kernel bug. > ## Problem 2 - NFS specific ## > > If we have the above kernel patch, even if 'losetup -d' executed without > problems, it doesn't mean that the backend file is not in use. > > So we need to wait some undetermined time until udev finishes its > playing with the loop device, and only after that we can safely remove > the file without a risk to be affected by "NFS silly rename". > > ## > > I think that to nail down both the problems at once, we may need to do > something like this: > > attach_device(const char *dev) > { > /* a cycle to verify that dev is not in use. > * If it's in use after the cycle, call tst_brkm() > */ > ioctl(dev_fd, LOOP_SET_FD); > /* handle ioctl errors */ > } > > detach_device(const char *dev) > { > ioctl(dev_fd, LOOP_CLR_FD); > /* ignore the return code */ > > /* a cycle to verify that dev is not in use. > * If it's still in use after the cycle, call tst_brkm() > */ > } > > ioctl(LOOP_GET_STATUS64) looks like a good way to check whether the loop > device is in use. > > What do you think? I think that we should do: detach_device(..) { while EBUSY: ioctl(fd, LOOP_CLR_FD); while not error: ioclt(LOOP_GET_STATUS); usleep(); } Because if we ignore the return value from LOOP_CLR_FD we will break on older kernels where we may get EBUSSY instead of lazy detach. And the LOOP_GET_STATUS* ioctls should return error when device is not attached, at least if I'm reading kernel code right. -- Cyril Hrubis chru...@suse.cz ------------------------------------------------------------------------------ _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list