Пример #1
0
/*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);
}
Пример #2
0
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);
}
Пример #3
0
/*
 * 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);
}