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 log_must zfs destroy -rf $ds/$TESTCLONE.$i 43 datasetexists $ds && log_must zfs destroy -Rf $ds 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 146i=1 147log_must setup_ds 148 149log_note "Verify zfs clone propery for multiple clones" 150names=$(zfs list -rt all -o name $TESTPOOL) 151log_must verify_clones 3 0 152 153log_note "verfify clone property for clone deletion" 154i=1 155for ds in $datasets; do 156 log_must zfs destroy $ds/$TESTCLONE.$i 157 ((i=i+1)) 158done 159names=$(zfs list -rt all -o name $TESTPOOL) 160i=1 161log_must verify_clones 2 1 162 163log_must local_cleanup 164log_must setup_ds 165 166log_note "verify zfs deferred destroy on clones property" 167i=1 168names=$(zfs list -rt all -o name $TESTPOOL) 169for ds in $datasets; do 170 log_must zfs destroy -d $ds@snap 171 deferred_snaps=( "${deferred_snaps[@]}" "$ds@snap" ) 172 ((i=i+1)) 173done 174log_must verify_clones 3 0 175 176log_note "verify zfs deferred destroy by destroying clones on clones property" 177d_clones=() 178i=1 179for ds in $datasets; do 180 for fs in $datasets; do 181 log_must zfs destroy $fs/$TESTCLONE.$i 182 d_clones=( "${d_clones[@]}" "$fs/$TESTCLONE.$i" ) 183 done 184 ((i=i+1)) 185done 186names=$(zfs list -rtall -o name $TESTPOOL) 187for snap in ${deferred_snaps[@]}; do 188 status=$(echo "$names" | grep $snap) 189 [[ -z $status ]] || \ 190 log_fail "$snap exist after deferred destroy" 191done 192for dclone in ${d_clones[@]}; do 193 log_note "D CLONE = $dclone" 194 status=$(echo "$names" | grep $dclone) 195 [[ -z $status ]] || \ 196 log_fail "$dclone exist after deferred destroy" 197done 198 199log_must local_cleanup 200log_must setup_ds 201log_note "verify clone property for zfs promote" 202i=1 203for ds in $datasets; do 204 log_must zfs promote $ds/$TESTCLONE.$i 205 ((i=i+1)) 206done 207names=$(zfs list -rt all -o name,clones $TESTPOOL) 208log_must verify_clones 3 1 $TESTCLONE 209i=1 210for ds in $datasets; do 211 log_must zfs promote $ds 212 ((i=i+1)) 213done 214log_must local_cleanup 215 216log_note "verify clone list truncated correctly" 217typeset -i j=200 218i=1 219fs=$TESTPOOL/$TESTFS1 220log_must zfs create $fs 221log_must zfs snapshot $fs@snap 222while((i < 7)); do 223 log_must zfs clone $fs@snap $fs/$TESTCLONE$(python -c 'print "x" * 200').$i 224 ((i=i+1)) 225 ((j=j+200)) 226done 227clone_list=$(zfs list -o clones $fs@snap) 228char_count=$(echo "$clone_list" | tail -1 | wc | awk '{print $3}') 229[[ $char_count -eq 1024 ]] || \ 230 log_fail "Clone list not truncated correctly. Unexpected character count" \ 231 "$char_count" 232 233log_pass "'zfs list -o name,origin,clones prints the correct clone information." 234