X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=lib%2Flibzfs%2Flibzfs_dataset.c;h=661f9b5f97eca7d6a468188c4061f36efcb07527;hb=c6327b63e6d3a11bb333829a8341d572e2fa7d9f;hp=e8c329ced9cb42773ecf6cb8a3f086647679e04a;hpb=ff998d804ff2fec3adc91fd0e78d25998094aca9;p=zfs.git diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index e8c329c..661f9b5 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -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: /*