/*ARGSUSED*/ static int do_zvol_create(zfs_handle_t *zhp, void *data) { int ret; if (ZFS_IS_VOLUME(zhp)) (void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name); ret = zfs_iter_children(zhp, do_zvol_create, NULL); zfs_close(zhp); return (ret); }
static int do_zvol(zfs_handle_t *zhp, void *data) { int linktype = (int)(uintptr_t)data; int ret; /* * We check for volblocksize intead of ZFS_TYPE_VOLUME so that we * correctly handle snapshots of volumes. */ if (zhp->zfs_volblocksize != 0) { if (linktype) ret = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name); else ret = zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name); } ret = zfs_iter_children(zhp, do_zvol, data); zfs_close(zhp); return (ret); }
/* * If the property is 'mountpoint' or 'sharenfs', go through and remount and/or * reshare the filesystems as necessary. In changelist_gather() we recorded * whether the filesystem was previously shared or mounted. The action we take * depends on the previous state, and whether the value was previously 'legacy'. * For non-legacy properties, we only remount/reshare the filesystem if it was * previously mounted/shared. Otherwise, we always remount/reshare the * filesystem. */ int changelist_postfix(prop_changelist_t *clp) { prop_changenode_t *cn; char shareopts[ZFS_MAXPROPLEN]; int ret = 0; libzfs_handle_t *hdl; /* * If we're changing the mountpoint, attempt to destroy the underlying * mountpoint. All other datasets will have inherited from this dataset * (in which case their mountpoints exist in the filesystem in the new * location), or have explicit mountpoints set (in which case they won't * be in the changelist). */ if ((cn = uu_list_last(clp->cl_list)) == NULL) return (0); if (clp->cl_prop == ZFS_PROP_MOUNTPOINT) remove_mountpoint(cn->cn_handle); /* * It is possible that the changelist_prefix() used libshare * to unshare some entries. Since libshare caches data, an * attempt to reshare during postfix can fail unless libshare * is uninitialized here so that it will reinitialize later. */ if (cn->cn_handle != NULL) { hdl = cn->cn_handle->zfs_hdl; assert(hdl != NULL); #ifndef __APPLE__ zfs_uninit_libshare(hdl); #endif } /* * We walk the datasets in reverse, because we want to mount any parent * datasets before mounting the children. */ for (cn = uu_list_last(clp->cl_list); cn != NULL; cn = uu_list_prev(clp->cl_list, cn)) { boolean_t sharenfs; #ifndef __APPLE__ /* * If we are in the global zone, but this dataset is exported * to a local zone, do nothing. */ if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned) continue; #endif /*!__APPLE__*/ zfs_refresh_properties(cn->cn_handle); if (ZFS_IS_VOLUME(cn->cn_handle)) { /* * If we're doing a rename, recreate the /dev/zvol * links. */ if (clp->cl_realprop == ZFS_PROP_NAME && zvol_create_link(cn->cn_handle->zfs_hdl, cn->cn_handle->zfs_name) != 0) { ret = -1; } else if (cn->cn_shared || clp->cl_prop == ZFS_PROP_SHAREISCSI) { if (zfs_prop_get(cn->cn_handle, ZFS_PROP_SHAREISCSI, shareopts, sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0 && strcmp(shareopts, "off") == 0) { ret = zfs_unshare_iscsi(cn->cn_handle); } else { ret = zfs_share_iscsi(cn->cn_handle); } } continue; } /* * Remount if previously mounted or mountpoint was legacy, * or sharenfs property is set. */ sharenfs = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS, shareopts, sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0) && (strcmp(shareopts, "off") != 0)); if ((cn->cn_mounted || clp->cl_waslegacy || sharenfs) && !zfs_is_mounted(cn->cn_handle, NULL) && zfs_mount(cn->cn_handle, NULL, 0) != 0) ret = -1; /* * We always re-share even if the filesystem is currently * shared, so that we can adopt any new options. */ if (cn->cn_shared || clp->cl_waslegacy || sharenfs) { if (sharenfs) ret = zfs_share_nfs(cn->cn_handle); else ret = zfs_unshare_nfs(cn->cn_handle, NULL); } } return (ret); }