1#!/bin/ksh -p
2
3#
4# This file and its contents are supplied under the terms of the
5# Common Development and Distribution License ("CDDL"), version 1.0.
6# You may only use this file in accordance with the terms of version
7# 1.0 of the CDDL.
8#
9# A full copy of the text of the CDDL should have accompanied this
10# source.  A copy of the CDDL is also available via the Internet at
11# http://www.illumos.org/license/CDDL.
12#
13
14#
15# Copyright (c) 2013, 2016 by Delphix. All rights reserved.
16#
17
18. $STF_SUITE/include/libtest.shlib
19
20#
21# DESCRIPTION:
22# There are myriad problems associated with trying to test umountall in a way
23# that works reliable across different systems. Some filesystems won't unmount
24# because they're busy. Some won't remount because they were legacy mounts in
25# the first place. etc...
26# Make a best approximation by calling umountall with the -n option, and verify
27# that the list of things it would try to unmout makes sense.
28#
29# STRATEGY:
30# 1. Make a list of file systems umountall is known to ignore.
31# 2. Append all ZFS file systems on this system.
32# 3. Run umountall -n and verify the file systems it reports are in the list.
33#
34
35log_must zfs mount -a
36for fs in 1 2 3 ; do
37	log_must mounted $TESTPOOL/$TESTFS.$fs
38done
39
40# This is the list we check the output of umountall -n against. We seed it
41# with these values because umountall will ignore them, and they're possible
42# (though most are improbable) ZFS filesystem mountpoints.
43zfs_list="/ /lib /sbin /tmp /usr /var /var/adm /var/run"
44
45# Append our ZFS filesystems to the list, not worrying about duplicates.
46if is_linux; then
47	typeset mounts=$(mount | awk '$5 == "zfs" {print $3}')
48elif is_freebsd; then
49	typeset mounts=$(mount -p | awk '$3 == "zfs" {print $2}')
50else
51	typeset mounts=$(mount -p | awk '$4 == "zfs" {print $3}')
52fi
53
54for fs in $mounts; do
55	zfs_list="$zfs_list $fs"
56done
57
58if is_linux; then
59	mounts=$(umount --fake -av -t zfs 2>&1 | awk '/successfully umounted/ {print $1}')
60	# Fallback to /proc/mounts for umount(8) (util-linux-ng 2.17.2)
61	if [[ -z $mounts ]]; then
62		mounts=$(awk '/zfs/ { print $2 }' /proc/mounts)
63	fi
64elif is_freebsd; then
65	# Umountall and umount not supported on FreeBSD
66	mounts=$(mount -t zfs | sort -r | awk '{print $3}')
67else
68	mounts=$(umountall -n -F zfs 2>&1 | awk '{print $2}')
69fi
70
71fs=''
72for fs in $mounts; do
73	for i in $zfs_list; do
74		[[ $fs = $i ]] && continue 2
75	done
76	log_fail "umountall -n -F zfs tried to unmount $fs"
77done
78[[ -n $mounts ]] || log_fail "umountall -n -F zfs produced no output"
79
80log_pass "All ZFS file systems would have been unmounted"
81