diff --git a/man/man8/zfs-mount.8 b/man/man8/zfs-mount.8 index 40adf79059..b6f033297d 100644 --- a/man/man8/zfs-mount.8 +++ b/man/man8/zfs-mount.8 @@ -47,7 +47,7 @@ .Nm zfs .Cm unmount .Op Fl fu -.Fl a Ns | Ns Ar filesystem Ns | Ns Ar mountpoint +.Fl a Oo filesystem Oc | Oo Fl A Oc Ar filesystem | Ar mountpoint . .Sh DESCRIPTION .Bl -tag -width "" @@ -115,21 +115,26 @@ be mounted (e.g. redacted datasets). .Nm zfs .Cm unmount .Op Fl fu -.Fl a Ns | Ns Ar filesystem Ns | Ns Ar mountpoint +.Fl a Oo filesystem Oc | Oo Fl A Oc Ar filesystem | Ar mountpoint .Xc Unmounts currently mounted ZFS file systems. .Bl -tag -width "-a" -.It Fl a -Unmount all available ZFS file systems. +.It Fl a Op filesystem +Unmount the specified filesystem and its children, provided they are available. +If no filesystem is specified, +then all available ZFS file systems are unmounted. Invoked automatically as part of the shutdown process. -.It Fl f -Forcefully unmount the file system, even if it is currently in use. -This option is not supported on Linux. -.It Fl u -Unload keys for any encryption roots unmounted by this command. +.It Fl A Ar filesystem +Unmount the specified filesystem and its children, provided they are available. +Note: datasets with the `canmount=noauto` property will also be unmounted. .It Ar filesystem Ns | Ns Ar mountpoint Unmount the specified filesystem. The command can also be given a path to a ZFS file system mount point on the system. +.It Fl u +Unload keys for any encryption roots unmounted by this command. +.It Fl f +Forcefully unmount the file system, even if it is currently in use. +This option is not supported on Linux. .El .El diff --git a/tests/runfiles/common.run b/tests/runfiles/common.run index eddbf9a1dc..b3be16edc1 100644 --- a/tests/runfiles/common.run +++ b/tests/runfiles/common.run @@ -305,7 +305,8 @@ tags = ['functional', 'cli_root', 'zfs_unload-key'] tests = ['zfs_unmount_001_pos', 'zfs_unmount_002_pos', 'zfs_unmount_003_pos', 'zfs_unmount_004_pos', 'zfs_unmount_005_pos', 'zfs_unmount_006_pos', 'zfs_unmount_007_neg', 'zfs_unmount_008_neg', 'zfs_unmount_009_pos', - 'zfs_unmount_all_001_pos', 'zfs_unmount_nested', 'zfs_unmount_unload_keys'] + 'zfs_unmount_all_001_pos', 'zfs_unmount_all_002_pos', 'zfs_unmount_nested', + 'zfs_unmount_unload_keys'] tags = ['functional', 'cli_root', 'zfs_unmount'] [tests/functional/cli_root/zfs_unshare] diff --git a/tests/zfs-tests/tests/Makefile.am b/tests/zfs-tests/tests/Makefile.am index 483f00d9e8..0277afb1e4 100644 --- a/tests/zfs-tests/tests/Makefile.am +++ b/tests/zfs-tests/tests/Makefile.am @@ -923,6 +923,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \ functional/cli_root/zfs_unmount/zfs_unmount_008_neg.ksh \ functional/cli_root/zfs_unmount/zfs_unmount_009_pos.ksh \ functional/cli_root/zfs_unmount/zfs_unmount_all_001_pos.ksh \ + functional/cli_root/zfs_unmount/zfs_unmount_all_002_pos.ksh \ functional/cli_root/zfs_unmount/zfs_unmount_nested.ksh \ functional/cli_root/zfs_unmount/zfs_unmount_unload_keys.ksh \ functional/cli_root/zfs_unshare/cleanup.ksh \ diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_007_neg.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_007_neg.ksh index 1a8665b86e..ee8d30db4e 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_007_neg.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_007_neg.ksh @@ -37,7 +37,6 @@ # Try each 'zfs unmount' with inapplicable scenarios to make sure # it returns an error. include: # * Multiple filesystem|mountpoint specified -# * '-a', but also with a specific filesystem|mountpoint. # # STRATEGY: # 1. Create an array of parameters @@ -54,7 +53,7 @@ for fs in $multifs ; do datasets="$datasets $TESTPOOL/$fs" done -set -A args "$unmountall $TESTPOOL/$TESTFS" \ +set -A args "$unmountall $datasets" \ "$unmountcmd $datasets" function setup_all diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_008_neg.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_008_neg.ksh index 3524efcd07..a730a0e7b4 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_008_neg.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_008_neg.ksh @@ -73,7 +73,7 @@ log_onexit cleanup fs=$TESTPOOL/$TESTFS vol=$TESTPOOL/vol.$$ snap=$TESTPOOL/$TESTFS@snap.$$ -set -A badargs "A" "-A" "F" "-F" "-" "-x" "-?" +set -A badargs "A" "F" "-F" "-" "-x" "-?" if ! ismounted $fs; then log_must zfs mount $fs diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_all_001_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_all_001_pos.ksh index f98d48ad92..8ae80663ad 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_all_001_pos.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_all_001_pos.ksh @@ -41,8 +41,8 @@ # 2. Create zfs filesystems within the given pools. # 3. Mount all the filesystems. # 4. Verify that 'zfs unmount -a[f]' command succeed, -# and all available ZFS filesystems are unmounted. -# 5. Verify that 'zfs mount' is identical with 'df -F zfs' +# and all available ZFS filesystems are unmounted. +# 5. Verify that 'zfs mount' is identical with 'df -F zfs' # verify_runnable "both" diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_all_002_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_all_002_pos.ksh new file mode 100644 index 0000000000..fcd34b201c --- /dev/null +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_unmount/zfs_unmount_all_002_pos.ksh @@ -0,0 +1,203 @@ +#!/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 https://opensource.org/licenses/CDDL-1.0. +# 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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# Copyright (c) 2016 by Delphix. All rights reserved. +# + +. $STF_SUITE/tests/functional/cli_root/zfs_mount/zfs_mount.kshlib +. $STF_SUITE/tests/functional/cli_root/zfs_unmount/zfs_unmount.kshlib + +# +# DESCRIPTION: +# Verify that 'zfs unmount -a[f]' succeeds as root. +# +# STRATEGY: +# 1. Create a group of pools with specified vdev. +# 2. Create zfs filesystems within the given pools. +# 3. Mount all the filesystems. +# 4. Verify that 'zfs unmount -a filesystem' command succeed, +# and the related available ZFS filesystems are unmounted, +# and the unrelated ZFS filesystems remain mounted +# 5. Verify that 'zfs mount' is identical with 'df -F zfs' +# + +verify_runnable "both" + +set -A fs "$TESTFS" "$TESTFS1" +set -A ctr "" "$TESTCTR" "$TESTCTR1" "$TESTCTR/$TESTCTR1" +set -A vol "$TESTVOL" "$TESTVOL1" + +# Test the mounted state of root dataset (testpool/testctr) +typeset mnt=$TESTCTR + +function setup_all +{ + typeset -i i=0 + typeset -i j=0 + typeset path + + while (( i < ${#ctr[*]} )); do + + path=${TEST_BASE_DIR%%/}/testroot$$/$TESTPOOL + if [[ -n ${ctr[i]} ]]; then + path=$path/${ctr[i]} + + setup_filesystem "$DISKS" "$TESTPOOL" \ + "${ctr[i]}" "$path" \ + "ctr" + fi + + if is_global_zone ; then + j=0 + while (( j < ${#vol[*]} )); do + setup_filesystem "$DISKS" "$TESTPOOL" \ + "${ctr[i]}/${vol[j]}" \ + "$path/${vol[j]}" \ + "vol" + ((j = j + 1)) + done + fi + j=0 + while (( j < ${#fs[*]} )); do + setup_filesystem "$DISKS" "$TESTPOOL" \ + "${ctr[i]}/${fs[j]}" \ + "$path/${fs[j]}" + ((j = j + 1)) + done + + ((i = i + 1)) + done + + return 0 +} + +function cleanup_all +{ + typeset -i i=0 + typeset -i j=0 + + ((i = ${#ctr[*]} - 1)) + + while (( i >= 0 )); do + if is_global_zone ; then + j=0 + while (( j < ${#vol[*]} )); do + cleanup_filesystem "$TESTPOOL" \ + "${ctr[i]}/${vol[j]}" + ((j = j + 1)) + done + fi + + j=0 + while (( j < ${#fs[*]} )); do + cleanup_filesystem "$TESTPOOL" \ + "${ctr[i]}/${fs[j]}" + ((j = j + 1)) + done + + [[ -n ${ctr[i]} ]] && \ + cleanup_filesystem "$TESTPOOL" "${ctr[i]}" + + ((i = i - 1)) + done + + [[ -d ${TEST_BASE_DIR%%/}/testroot$$ ]] && \ + rm -rf ${TEST_BASE_DIR%%/}/testroot$$ +} + +# +# This function verifies that the file systems in $mnt are unmounted. +# Next, it ensures that all other file systems in remain mounted. +# +function verify_related +{ + typeset -i i=0 + typeset -i j=0 + typeset path + + while (( i < ${#ctr[*]} )); do + + if { [[ ${ctr[i]} == $mnt ]] || [[ ${ctr[i]} == $mnt/* ]] }; then + logfunc=log_must + else + logfunc=log_mustnot + fi + + path=$TESTPOOL + [[ -n ${ctr[i]} ]] && \ + path=$path/${ctr[i]} + + if is_global_zone ; then + j=0 + while (( j < ${#vol[*]} )); do + log_must unmounted "$path/${vol[j]}" + ((j = j + 1)) + done + fi + + j=0 + while (( j < ${#fs[*]} )); do + $logfunc unmounted "$path/${fs[j]}" + ((j = j + 1)) + done + + $logfunc unmounted "$path" + + ((i = i + 1)) + done + + return 0 +} + + +log_assert "Verify that 'zfs $unmountall $TESTPOOL/$mnt' succeeds as root, " \ + "and all the related available ZFS filesystems are unmounted." + +log_onexit cleanup_all + +log_must setup_all + +typeset opt +for opt in "-a" "-fa"; do + export __ZFS_POOL_RESTRICT="$TESTPOOL" + log_must zfs $mountall + unset __ZFS_POOL_RESTRICT + + export __ZFS_POOL_RESTRICT="$TESTPOOL" + log_must zfs unmount $opt $TESTPOOL/$mnt + unset __ZFS_POOL_RESTRICT + + log_must verify_related + log_note "Verify that 'zfs $mountcmd' will display " \ + "all available ZFS filesystems related to '$TESTPOOL/$mnt' are unmounted." + log_must verify_mount_display + +done + +log_pass "'zfs mount -[f]a $TESTPOOL/$mnt' succeeds as root, " \ + "and all the related available ZFS filesystems are unmounted."