From ea3031df6333f509fc51940e0d53c00fe694b39d Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Wed, 22 Jan 2020 22:51:55 +0000 Subject: MFC r356876-r356877: add zfs_mount_at r356876: libzfs: add zfs_mount_at This will be used in libbe in place of the internal zmount(); libbe only wants to be able to mount a dataset at an arbitrary mountpoint without altering dataset/pool properties. The natural way to do this in a portable way is by creating a zfs_mount_at() interface that's effectively zfs_mount() + a mountpoint parameter. zfs_mount() is now a light wrapper around the new method. The interface and implementation have already been accepted into ZFS On Linux, and the next commit to switch libbe() over to this new interface will solve the last compatibility issue with ZoL. The next sysutils/openzfs rebase against ZoL should be able to build libbe/bectl with only minor adjustments to build glue. r356877: libbe: use the new zfs_mount_at() More background is available in r356876, but this new interface is more portable across ZFS implementations and cleaner for what libbe is attempting to achieve anyways. --- .../contrib/opensolaris/lib/libzfs/common/libzfs.h | 1 + .../opensolaris/lib/libzfs/common/libzfs_mount.c | 31 ++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) (limited to 'cddl') diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h index aeae6e3822a3..b2c428608477 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h @@ -752,6 +752,7 @@ extern boolean_t zfs_bookmark_exists(const char *path); extern boolean_t is_mounted(libzfs_handle_t *, const char *special, char **); extern boolean_t zfs_is_mounted(zfs_handle_t *, char **); extern int zfs_mount(zfs_handle_t *, const char *, int); +extern int zfs_mount_at(zfs_handle_t *, const char *, int, const char *); extern int zfs_unmount(zfs_handle_t *, const char *, int); extern int zfs_unmountall(zfs_handle_t *, int); diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c index 0efeba631aff..9d4948cc7173 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_mount.c @@ -301,6 +301,17 @@ zfs_is_mounted(zfs_handle_t *zhp, char **where) return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where)); } +static boolean_t +zfs_is_mountable_internal(zfs_handle_t *zhp, const char *mountpoint) +{ + + if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) && + getzoneid() == GLOBAL_ZONEID) + return (B_FALSE); + + return (B_TRUE); +} + /* * Returns true if the given dataset is mountable, false otherwise. Returns the * mountpoint in 'buf'. @@ -325,8 +336,7 @@ zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen, if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF) return (B_FALSE); - if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) && - getzoneid() == GLOBAL_ZONEID) + if (!zfs_is_mountable_internal(zhp, buf)) return (B_FALSE); if (source) @@ -341,8 +351,19 @@ zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen, int zfs_mount(zfs_handle_t *zhp, const char *options, int flags) { - struct stat buf; char mountpoint[ZFS_MAXPROPLEN]; + + if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) + return (0); + + return (zfs_mount_at(zhp, options, flags, mountpoint)); +} + +int +zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, + const char *mountpoint) +{ + struct stat buf; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; @@ -357,8 +378,8 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) flags |= MS_RDONLY; - if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) - return (0); + if (!zfs_is_mountable_internal(zhp, mountpoint)) + return (B_FALSE); /* Create the directory if it doesn't already exist */ if (lstat(mountpoint, &buf) != 0) { -- cgit v1.2.3