1#!/bin/ksh 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) 2012, 2016 by Delphix. All rights reserved. 19# 20 21. $STF_SUITE/include/libtest.shlib 22 23# 24# DESCRIPTION: 25# Verify 'zfs list -t all -o name,origin,clones' prints the correct 26# clone information 27# 28# STRATEGY: 29# 1. Create datasets 30# 2. Create recursive snapshots and their clones 31# 3. Verify zfs clones property displays right information for different 32# cases 33# 34 35verify_runnable "both" 36 37function local_cleanup 38{ 39 typeset -i i=1 40 for ds in $datasets; do 41 datasetexists $ds/$TESTCLONE.$i && \ 42 destroy_dataset $ds/$TESTCLONE.$i -rf 43 datasetexists $ds && destroy_dataset $ds -Rf 44 ((i=i+1)) 45 done 46} 47 48# Set up filesystem with clones 49function setup_ds 50{ 51 typeset -i i=1 52 # create nested datasets 53 log_must zfs create -p $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3 54 55 # verify dataset creation 56 for ds in $datasets; do 57 datasetexists $ds || log_fail "Create $ds dataset fail." 58 done 59 60 # create recursive nested snapshot 61 log_must zfs snapshot -r $TESTPOOL/$TESTFS1@snap 62 for ds in $datasets; do 63 datasetexists $ds@snap || \ 64 log_fail "Create $ds@snap snapshot fail." 65 done 66 for ds in $datasets; do 67 for fs in $datasets; do 68 log_must zfs clone $ds@snap $fs/$TESTCLONE.$i 69 done 70 ((i=i+1)) 71 done 72} 73 74# Verify clone list 75function verify_clones 76{ 77 typeset -i no_clones=$1 78 typeset unexpected=$2 79 typeset clone_snap=$3 80 typeset -i i=1 81 for ds in $datasets; do 82 if [[ -n $clone_snap ]]; then 83 clone_snap=/$TESTCLONE.$i 84 fi 85 snapshot=$(echo "$names" | grep $ds$clone_snap@snap) 86 actual_clone=$(zfs list -t all -o clones $snapshot | tail -1) 87 save=$IFS 88 IFS=',' 89 typeset -a clones=() 90 for token in $actual_clone; do 91 clones=( "${clones[@]}" "$token" ) 92 done 93 IFS=$save 94 [[ ${#clones[*]} -ne $no_clones ]] && \ 95 log_fail "$snapshot has unexpected number of clones" \ 96 " ${#clones[*]}" 97 expected_clone="" 98 unexpected_clone="" 99 if [[ $unexpected -eq 1 ]]; then 100 for fs in $datasets; do 101 if [[ $fs == $ds ]]; then 102 if [[ -z $clone_snap ]]; then 103 unexpected_clone=$fs/$TESTCLONE.$i 104 (for match in ${clones[@]};do 105 [[ $match != $unexpected_clone ]] && \ 106 exit 0; done) || log_fail \ 107 "Unexpected clones of the snapshot" 108 else 109 expected_clone=$fs 110 unexpected_clone=$fs/$TESTCLONE.$i 111 (for match in ${clones[@]};do 112 [[ $match == $expected_clone ]] && \ 113 [[ $match != $unexpected_clone ]] \ 114 && exit 0; done) || log_fail \ 115 "Unexpected clones of the snapshot" 116 fi 117 else 118 expected_clone=$fs/$TESTCLONE.$i 119 (for match in ${clones[@]};do 120 [[ $match == $expected_clone ]] && \ 121 exit 0; done) || log_fail \ 122 "Unexpected clones of the snapshot" 123 fi 124 done 125 else 126 for fs in $datasets; do 127 expected_clone=$fs/$TESTCLONE.$i 128 (for match in ${clones[@]};do 129 [[ $match == $expected_clone ]] && exit 0; \ 130 done) || log_fail "Unexpected clones" \ 131 " of the snapshot" 132 done 133 fi 134 ((i=i+1)) 135 done 136} 137 138 139log_onexit local_cleanup 140datasets="$TESTPOOL/$TESTFS1 $TESTPOOL/$TESTFS1/$TESTFS2 141 $TESTPOOL/$TESTFS1/$TESTFS2/$TESTFS3" 142 143typeset -a d_clones 144typeset -a deferred_snaps 145typeset -i i 146log_must setup_ds 147 148log_note "Verify zfs clone property for multiple clones" 149names=$(zfs list -rt all -o name $TESTPOOL) 150log_must verify_clones 3 0 151 152log_note "verify clone property for clone deletion" 153i=1 154for ds in $datasets; do 155 log_must zfs destroy $ds/$TESTCLONE.$i 156 ((i=i+1)) 157done 158names=$(zfs list -rt all -o name $TESTPOOL) 159log_must verify_clones 2 1 160 161log_must local_cleanup 162log_must setup_ds 163 164log_note "verify zfs deferred destroy on clones property" 165names=$(zfs list -rt all -o name $TESTPOOL) 166for ds in $datasets; do 167 log_must zfs destroy -d $ds@snap 168 deferred_snaps=( "${deferred_snaps[@]}" "$ds@snap" ) 169done 170log_must verify_clones 3 0 171 172log_note "verify zfs deferred destroy by destroying clones on clones property" 173d_clones=() 174i=1 175for ds in $datasets; do 176 for fs in $datasets; do 177 log_must zfs destroy $fs/$TESTCLONE.$i 178 d_clones=( "${d_clones[@]}" "$fs/$TESTCLONE.$i" ) 179 done 180 ((i=i+1)) 181done 182names=$(zfs list -rtall -o name $TESTPOOL) 183for snap in ${deferred_snaps[@]}; do 184 status=$(echo "$names" | grep $snap) 185 [[ -z $status ]] || \ 186 log_fail "$snap exist after deferred destroy" 187done 188for dclone in ${d_clones[@]}; do 189 log_note "D CLONE = $dclone" 190 status=$(echo "$names" | grep $dclone) 191 [[ -z $status ]] || \ 192 log_fail "$dclone exist after deferred destroy" 193done 194 195log_must local_cleanup 196log_must setup_ds 197log_note "verify clone property for zfs promote" 198i=1 199for ds in $datasets; do 200 log_must zfs promote $ds/$TESTCLONE.$i 201 ((i=i+1)) 202done 203names=$(zfs list -rt all -o name,clones $TESTPOOL) 204log_must verify_clones 3 1 $TESTCLONE 205for ds in $datasets; do 206 log_must zfs promote $ds 207done 208log_must local_cleanup 209 210log_note "verify clone list truncated correctly" 211fs=$TESTPOOL/$TESTFS1 212xs=""; for i in {1..200}; do xs+="x"; done 213if is_linux; then 214 ZFS_MAXPROPLEN=4096 215else 216 ZFS_MAXPROPLEN=1024 217fi 218log_must zfs create $fs 219log_must zfs snapshot $fs@snap 220for (( i = 1; i <= (ZFS_MAXPROPLEN / 200 + 1); i++ )); do 221 log_must zfs clone ${fs}@snap ${fs}/${TESTCLONE}${xs}.${i} 222done 223clone_list=$(zfs list -o clones $fs@snap) 224char_count=$(echo "$clone_list" | tail -1 | wc -c) 225[[ $char_count -eq $ZFS_MAXPROPLEN ]] || \ 226 log_fail "Clone list not truncated correctly. Unexpected character count" \ 227 "$char_count" 228 229log_pass "'zfs list -o name,origin,clones prints the correct clone information." 230