1 #!/bin/ksh -p
   2 #
   3 # CDDL HEADER START
   4 #
   5 # This file and its contents are supplied under the terms of the
   6 # Common Development and Distribution License ("CDDL"), version 1.0.
   7 # You may only use this file in accordance with the terms of version
   8 # 1.0 of the CDDL.
   9 #
  10 # A full copy of the text of the CDDL should have accompanied this
  11 # source.  A copy of the CDDL is also available via the Internet at
  12 # http://www.illumos.org/license/CDDL.
  13 #
  14 # CDDL HEADER END
  15 #
  16 
  17 #
  18 # Copyright (c) 2017 by Delphix. All rights reserved.
  19 #
  20 
  21 . $STF_SUITE/include/libtest.shlib
  22 . $STF_SUITE/tests/functional/cli_root/zfs_mount/zfs_mount.kshlib
  23 
  24 # DESCRIPTION:
  25 #       Verify that 'zfs mount -a' succeeds given a set of filesystems
  26 #       whose mountpoints have a parent/child relationship which is
  27 #       counter to the filesystem parent/child relationship.
  28 #
  29 # STRATEGY:
  30 #       1. Create zfs filesystems within the given pool.
  31 #       2. Unmount all the filesystems.
  32 #       3. Verify that 'zfs mount -a' command succeed,
  33 #          and all available ZFS filesystems are mounted.
  34 #       4. Verify that 'zfs mount' is identical with 'df -F zfs'
  35 #
  36 
  37 verify_runnable "both"
  38 
  39 typeset -a filesystems
  40 
  41 function setup_all
  42 {
  43         typeset path=${TEST_BASE_DIR%%/}/testroot$$/$TESTPOOL
  44         typeset fscount=10
  45 
  46         #
  47         # Generate an array of filesystem names that represent a deep
  48         # hierarchy as such:
  49         #
  50         # 0
  51         # 0/1
  52         # 0/1/2
  53         # 0/1/2/3
  54         # 0/1/2/3/4
  55         # ...
  56         #
  57         fs=0
  58         for ((i=0; i<$fscount; i++)); do
  59                 if [[ $i -gt 0 ]]; then
  60                         fs=$fs/$i
  61                 fi
  62                 filesystems+=($fs)
  63         done
  64 
  65         # Create all of the above filesystems
  66         for ((i=0; i<$fscount; i++)); do
  67                 fs=${filesystems[$i]}
  68                 setup_filesystem "$DISKS" "$TESTPOOL" "$fs" "$path/$i" ctr
  69         done
  70 
  71         zfs list -r $TESTPOOL
  72 
  73         #
  74         # Unmount all of the above so that we can setup our convoluted
  75         # mount paths.
  76         #
  77         export __ZFS_POOL_RESTRICT="$TESTPOOL"
  78         log_must zfs $unmountall
  79         unset __ZFS_POOL_RESTRICT
  80 
  81         #
  82         # Configure the mount paths so that each mountpoint is contained
  83         # in a child filesystem. We should end up with something like the
  84         # following structure (modulo the number of filesystems):
  85         #
  86         # NAME                       MOUNTPOINT
  87         # testpool                   /testpool
  88         # testpool/0                 /testroot25416/testpool/0/1/2/3/4/5/6
  89         # testpool/0/1               /testroot25416/testpool/0/1/2/3/4/5
  90         # testpool/0/1/2             /testroot25416/testpool/0/1/2/3/4
  91         # testpool/0/1/2/3           /testroot25416/testpool/0/1/2/3
  92         # testpool/0/1/2/3/4         /testroot25416/testpool/0/1/2
  93         # testpool/0/1/2/3/4/5       /testroot25416/testpool/0/1
  94         # testpool/0/1/2/3/4/5/6     /testroot25416/testpool/0
  95         #
  96         for ((i=0; i<$fscount; i++)); do
  97                 fs=$TESTPOOL/${filesystems[$(($fscount - $i - 1))]}
  98                 mnt=$path/${filesystems[$i]}
  99                 zfs set mountpoint=$mnt $fs
 100         done
 101 
 102         zfs list -r $TESTPOOL
 103 
 104         return 0
 105 }
 106 
 107 function cleanup_all
 108 {
 109         export __ZFS_POOL_RESTRICT="$TESTPOOL"
 110         log_must zfs $unmountall
 111         unset __ZFS_POOL_RESTRICT
 112 
 113         for fs in ${filesystems[@]}; do
 114                 cleanup_filesystem "$TESTPOOL" "$fs"
 115         done
 116         [[ -d ${TEST_BASE_DIR%%/}/testroot$$ ]] && \
 117                 rm -rf ${TEST_BASE_DIR%%/}/testroot$$
 118 }
 119 
 120 #
 121 # This function takes a single true/false argument. If true it will verify that
 122 # all file systems are mounted. If false it will verify that they are not
 123 # mounted.
 124 #
 125 function verify_all
 126 {
 127         if $1; then
 128                 logfunc=log_must
 129         else
 130                 logfunc=log_mustnot
 131         fi
 132 
 133         for fs in ${filesystems[@]}; do
 134                 $logfunc mounted "$TESTPOOL/$fs"
 135         done
 136 
 137         return 0
 138 }
 139 
 140 log_onexit cleanup_all
 141 
 142 log_must setup_all
 143 
 144 export __ZFS_POOL_RESTRICT="$TESTPOOL"
 145 log_must zfs $unmountall
 146 unset __ZFS_POOL_RESTRICT
 147 
 148 verify_all false
 149 
 150 export __ZFS_POOL_RESTRICT="$TESTPOOL"
 151 log_must zfs $mountall
 152 unset __ZFS_POOL_RESTRICT
 153 
 154 verify_all true
 155 
 156 log_note "Verify that 'zfs $mountcmd' will display " \
 157         "all ZFS filesystems currently mounted."
 158 
 159 verify_mount_display
 160 
 161 log_pass "'zfs $mountall' succeeds as root, " \
 162         "and all available ZFS filesystems are mounted."