]> git.proxmox.com Git - mirror_zfs.git/commitdiff
libzfs: add zfs_mount_at() function
authorKyle Evans <kevans91@users.noreply.github.com>
Tue, 14 Jan 2020 16:49:54 +0000 (10:49 -0600)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 14 Jan 2020 16:49:54 +0000 (08:49 -0800)
zfs_mount_at() mounts a dataset at an arbitrary mountpoint rather than
at the configured mountpoint. This may be used by consumers that wish to
temporarily expose a dataset at another mountpoint without altering
dataset/pool properties.

This will be used by FreeBSD's libbe be_mount(), which mounts a boot
environment at an arbitrary mountpoint.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@ixsystems.com>
Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Closes #9833

include/libzfs.h
lib/libzfs/libzfs_mount.c

index 8069d4cd4dc24879d68279db234ef75e6b83e3dd..05abfdf89ece7790e429bc394be08b905b662fe4 100644 (file)
@@ -788,6 +788,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);
 
index c2955ccfaba51397915cc5000333d6b88f1d1d4a..c3fe97d5573e9d6e85413632cdbe395c4a8e0c46 100644 (file)
@@ -37,6 +37,7 @@
  *
  *     zfs_is_mounted()
  *     zfs_mount()
+ *     zfs_mount_at()
  *     zfs_unmount()
  *     zfs_unmountall()
  *
@@ -239,6 +240,23 @@ zfs_is_mounted(zfs_handle_t *zhp, char **where)
        return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where));
 }
 
+/*
+ * Checks any higher order concerns about whether the given dataset is
+ * mountable, false otherwise.  zfs_is_mountable_internal specifically assumes
+ * that the caller has verified the sanity of mounting the dataset at
+ * mountpoint to the extent the caller wants.
+ */
+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'.
@@ -264,8 +282,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 (zfs_prop_get_int(zhp, ZFS_PROP_REDACTED) && !(flags & MS_FORCE))
@@ -346,14 +363,26 @@ zfs_add_options(zfs_handle_t *zhp, char *options, int len)
        return (error);
 }
 
+int
+zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
+{
+       char mountpoint[ZFS_MAXPROPLEN];
+
+       if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL,
+           flags))
+               return (0);
+
+       return (zfs_mount_at(zhp, options, flags, mountpoint));
+}
+
 /*
  * Mount the given filesystem.
  */
 int
-zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
+zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags,
+    const char *mountpoint)
 {
        struct stat buf;
-       char mountpoint[ZFS_MAXPROPLEN];
        char mntopts[MNT_LINE_MAX];
        char overlay[ZFS_MAXPROPLEN];
        libzfs_handle_t *hdl = zhp->zfs_hdl;
@@ -369,16 +398,16 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
        if (strstr(mntopts, MNTOPT_REMOUNT) != NULL)
                remount = 1;
 
+       /* Potentially duplicates some checks if invoked by zfs_mount(). */
+       if (!zfs_is_mountable_internal(zhp, mountpoint))
+               return (0);
+
        /*
         * If the pool is imported read-only then all mounts must be read-only
         */
        if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL))
                (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts));
 
-       if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL,
-           flags))
-               return (0);
-
        /*
         * Append default mount options which apply to the mount point.
         * This is done because under Linux (unlike Solaris) multiple mount