Retry removal of busy minors
When failing to remove a zvol device link because it's busy, wait a bit and retry in a loop instead of giving up immediately. This technique is similar to the loop in zpool_label_disk_wait(), with the same goal: waiting for the asynchronous udev processes to finish their work. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #692
This commit is contained in:
parent
92e91da208
commit
c6327b63e6
@ -3920,10 +3920,29 @@ int
|
||||
zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
|
||||
{
|
||||
zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
|
||||
int timeout = 3000; /* in milliseconds */
|
||||
int error = 0;
|
||||
int i;
|
||||
|
||||
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
|
||||
|
||||
if (ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc) != 0) {
|
||||
/*
|
||||
* Due to concurrent updates by udev the device may be reported as
|
||||
* busy. In this case don't immediately fail. Instead briefly delay
|
||||
* and retry the ioctl() which is now likely to succeed. If unable
|
||||
* remove the link after timeout milliseconds return the failure.
|
||||
*/
|
||||
for (i = 0; i < timeout; i++) {
|
||||
error = ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc);
|
||||
if (error && errno == EBUSY) {
|
||||
usleep(1000);
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
switch (errno) {
|
||||
case ENXIO:
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user