]> git.proxmox.com Git - mirror_zfs.git/commitdiff
'zfs share -a' should clean noauto exports
authorDon Brady <don.brady@delphix.com>
Thu, 20 Aug 2020 20:12:12 +0000 (14:12 -0600)
committerGitHub <noreply@github.com>
Thu, 20 Aug 2020 20:12:12 +0000 (13:12 -0700)
This is a follow on to PR #10688 where `zfs share -a` allows the
sharing of canmount=noauto datasets if they are mounted.  However,
when a dataset with canmount=noauto is not mounted, the command
should also purge any existing entries from the exports file.
Otherwise, after a reboot, the nfs server attempts to export the
underlying mountpath, not the dataset. This can lead to a hard hang
for existing client mounts.

Instead of just skipping the adding of an export if not mounted
and canmount=noauto, have it also remove an existing export of the
dataset so that, after a reboot, we don't export an unmounted dataset.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Wilson <gwilson@delphix.com>
Signed-off-by: Don Brady <don.brady@delphix.com>
Closes #10747

cmd/zfs/zfs_main.c
tests/runfiles/linux.run
tests/zfs-tests/tests/functional/cli_root/zfs_share/Makefile.am
tests/zfs-tests/tests/functional/cli_root/zfs_share/zfs_share_012_pos.ksh [new file with mode: 0755]

index 2878f03a321474c8b252d8a394aabaa625281002..650b4fc9b74ffbc5ca87afc857c66fc8a3d1fdc8 100644 (file)
@@ -6634,8 +6634,11 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
                 */
                if (op == OP_MOUNT)
                        return (0);
-               if (op == OP_SHARE && !zfs_is_mounted(zhp, NULL))
+               if (op == OP_SHARE && !zfs_is_mounted(zhp, NULL)) {
+                       /* also purge it from existing exports */
+                       zfs_unshareall_bypath(zhp, mountpoint);
                        return (0);
+               }
        }
 
        /*
index 36981bbb05326df321d1afc0888344a6076e203c..b6508a5cb3cfc902a4ed785da6c3c029200b07c4 100644 (file)
@@ -52,7 +52,8 @@ tests = ['zfs_mount_006_pos', 'zfs_mount_008_pos', 'zfs_multi_mount']
 tags = ['functional', 'cli_root', 'zfs_mount']
 
 [tests/functional/cli_root/zfs_share:Linux]
-tests = ['zfs_share_005_pos', 'zfs_share_007_neg', 'zfs_share_009_neg']
+tests = ['zfs_share_005_pos', 'zfs_share_007_neg', 'zfs_share_009_neg',
+    'zfs_share_012_pos']
 tags = ['functional', 'cli_root', 'zfs_share']
 
 [tests/functional/cli_root/zfs_sysfs:Linux]
index 8628b17c4521d7ac19a0a985935e26b0c0c958be..bf33ed038d7844de8d583164b832a2f98864f8b8 100644 (file)
@@ -13,6 +13,7 @@ dist_pkgdata_SCRIPTS = \
        zfs_share_009_neg.ksh \
        zfs_share_010_neg.ksh \
        zfs_share_011_pos.ksh \
+       zfs_share_012_pos.ksh \
        zfs_share_concurrent_shares.ksh
 
 dist_pkgdata_DATA = \
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_share/zfs_share_012_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_share/zfs_share_012_pos.ksh
new file mode 100755 (executable)
index 0000000..fe38d55
--- /dev/null
@@ -0,0 +1,85 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2020 by Delphix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION: Unmounted canmount=noauto export is removed during zfs share -a
+#
+# STRATEGY:
+# 1. Share a dataset that also has canmount set to noauto
+# 2. Capture the zfs exports file when the dataset is mounted + shared
+# 3. Simulate a reboot by unmounting the dataset and restoring the exports file
+# 4. Verify that 'zfs share -a' removes the export since dataset is not mounted
+#
+
+verify_runnable "both"
+
+dataset="$TESTPOOL/$TESTFS"
+mountpt=$(get_prop mountpoint $dataset)
+
+function cleanup
+{
+       zfs set canmount=on $dataset
+       zfs set sharenfs=off $dataset
+       zfs mount -a
+
+       #
+       # unset __ZFS_POOL_EXCLUDE so that we include all file systems when
+       # rebuilding the exports file
+       #
+       unset __ZFS_POOL_EXCLUDE
+       rm /etc/exports.d/zfs.exports
+       zfs share -a
+}
+
+log_assert "Unmounted canmount=noauto export is removed during zfs share -a"
+log_onexit cleanup
+
+log_must zfs set canmount=noauto $dataset
+zfs mount $dataset > /dev/null 2>&1
+log_must mounted $dataset
+log_must zfs set sharenfs=on $dataset
+log_must is_exported $mountpt
+
+log_must cp /etc/exports.d/zfs.exports /etc/exports.d/zfs.exports.save
+log_must zfs umount $dataset
+log_must unmounted $dataset
+log_mustnot is_exported $mountpt
+
+# simulate a reboot condition
+log_must mv /etc/exports.d/zfs.exports.save /etc/exports.d/zfs.exports
+
+log_must is_exported $mountpt
+log_must zfs share -a
+log_mustnot is_exported $mountpt
+
+log_pass "Unmounted canmount=noauto export is removed during zfs share -a"