1# 2# CDDL HEADER START 3# 4# The contents of this file are subject to the terms of the 5# Common Development and Distribution License (the "License"). 6# You may not use this file except in compliance with the License. 7# 8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9# or http://www.opensolaris.org/os/licensing. 10# See the License for the specific language governing permissions 11# and limitations under the License. 12# 13# When distributing Covered Code, include this CDDL HEADER in each 14# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15# If applicable, add the following below this CDDL HEADER, with the 16# fields enclosed by brackets "[]" replaced with your own identifying 17# information: Portions Copyright [yyyy] [name of copyright owner] 18# 19# CDDL HEADER END 20# 21 22# 23# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. 24# 25 26. $STF_SUITE/include/libtest.shlib 27. $STF_SUITE/tests/functional/cli_root/zfs_set/zfs_set_common.kshlib 28. $STF_SUITE/tests/functional/zvol/zvol_common.shlib 29 30# 31# Wait for udev to settle, completely. 32# This is quite discomforting, but there's a race condition here 33# (Amazon 2015.09 x86_64 Release (TEST) is good at triggering this) where the 34# kernel tries to remove zvol device nodes while they're open by [blkid], 35# [zvol_id] or other udev related processes. 36# Calling 'udevadm settle' is not enough: wait for those processes "manually". 37# 38function udev_wait 39{ 40 sleep 1 41 is_linux || return 0 42 udevadm trigger --action=change 43 udevadm settle 44 for i in {1..3}; do 45 blkid="$(pgrep blkid | wc -l)" 46 zvol_id="$(pgrep zvol_id | wc -l)" 47 [[ "0" == "$zvol_id" && "0" == "$blkid" ]] && return 48 udevadm settle 49 done 50 log_fail "Wait timeout reached for udev_wait" 51} 52 53# 54# Clean up udev status 55# This is also a problem on "Amazon 2015.09 x86_64 Release (TEST)" where udev, 56# sometimes, does not clean up /dev/zvol symlinks correctly for removed ZVOLs. 57# Prune those links manually, then tell udev to forget them. 58# 59function udev_cleanup 60{ 61 is_linux || return 0 62 log_note "Pruning broken ZVOL symlinks ..." 63 64 udevadm settle 65 # find all dangling links and delete them 66 find -L "${ZVOL_DEVDIR}" -type l -print -delete 67 # purge those links from udev database 68 udevadm info --cleanup-db 69} 70 71# 72# Verify $device exists and is a block device 73# 74function blockdev_exists # device 75{ 76 typeset device="$1" 77 78 # we wait here instead of doing it in a wrapper around 'zfs set snapdev' 79 # because there are other commands (zfs snap, zfs inherit, zfs destroy) 80 # that can affect device nodes 81 for i in {1..3}; do 82 udev_wait 83 is_disk_device "$device" && return 0 84 done 85 log_fail "$device does not exist as a block device" 86} 87 88# 89# Verify $device does not exist 90# 91function blockdev_missing # device 92{ 93 typeset device="$1" 94 95 # we wait here instead of doing it in a wrapper around 'zfs set snapdev' 96 # because there are other commands (zfs snap, zfs inherit, zfs destroy) 97 # that can affect device nodes 98 for i in {1..3}; do 99 udev_wait 100 [[ ! -e "$device" ]] && return 0 101 done 102 log_fail "$device exists when not expected" 103} 104 105# 106# Verify $property on $dataset is inherited by $parent and is set to $value 107# 108function verify_inherited # property value dataset parent 109{ 110 typeset property="$1" 111 typeset value="$2" 112 typeset dataset="$3" 113 typeset parent="$4" 114 115 typeset val=$(get_prop "$property" "$dataset") 116 typeset src=$(get_source "$property" "$dataset") 117 if [[ "$val" != "$value" || "$src" != "inherited from $parent" ]]; then 118 log_fail "Dataset $dataset did not inherit $property properly:"\ 119 "expected=$value, value=$val, source=$src." 120 fi 121} 122 123# 124# Create a small partition on $device, then verify if we can access it 125# 126function verify_partition # device 127{ 128 typeset device="$1" 129 130 if ! is_disk_device "$device"; then 131 log_fail "$device is not a block device" 132 fi 133 # create a small dummy partition 134 set_partition 0 "" 1m $device 135 # verify we can access the partition on the device 136 devname="$(readlink -f "$device")" 137 if is_linux || is_freebsd; then 138 is_disk_device "$devname""p1" 139 else 140 is_disk_device "$devname""s0" 141 fi 142 return $? 143} 144