1*12199Sgerald.jelinek@sun.com# 2*12199Sgerald.jelinek@sun.com# CDDL HEADER START 3*12199Sgerald.jelinek@sun.com# 4*12199Sgerald.jelinek@sun.com# The contents of this file are subject to the terms of the 5*12199Sgerald.jelinek@sun.com# Common Development and Distribution License (the "License"). 6*12199Sgerald.jelinek@sun.com# You may not use this file except in compliance with the License. 7*12199Sgerald.jelinek@sun.com# 8*12199Sgerald.jelinek@sun.com# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*12199Sgerald.jelinek@sun.com# or http://www.opensolaris.org/os/licensing. 10*12199Sgerald.jelinek@sun.com# See the License for the specific language governing permissions 11*12199Sgerald.jelinek@sun.com# and limitations under the License. 12*12199Sgerald.jelinek@sun.com# 13*12199Sgerald.jelinek@sun.com# When distributing Covered Code, include this CDDL HEADER in each 14*12199Sgerald.jelinek@sun.com# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*12199Sgerald.jelinek@sun.com# If applicable, add the following below this CDDL HEADER, with the 16*12199Sgerald.jelinek@sun.com# fields enclosed by brackets "[]" replaced with your own identifying 17*12199Sgerald.jelinek@sun.com# information: Portions Copyright [yyyy] [name of copyright owner] 18*12199Sgerald.jelinek@sun.com# 19*12199Sgerald.jelinek@sun.com# CDDL HEADER END 20*12199Sgerald.jelinek@sun.com# 21*12199Sgerald.jelinek@sun.com# 22*12199Sgerald.jelinek@sun.com# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23*12199Sgerald.jelinek@sun.com# 24*12199Sgerald.jelinek@sun.com 25*12199Sgerald.jelinek@sun.com# 26*12199Sgerald.jelinek@sun.com# get script name (bname) 27*12199Sgerald.jelinek@sun.com# 28*12199Sgerald.jelinek@sun.combname=`basename $0` 29*12199Sgerald.jelinek@sun.com 30*12199Sgerald.jelinek@sun.com# 31*12199Sgerald.jelinek@sun.com# common shell script functions 32*12199Sgerald.jelinek@sun.com# 33*12199Sgerald.jelinek@sun.com. /usr/lib/brand/shared/common.ksh 34*12199Sgerald.jelinek@sun.com 35*12199Sgerald.jelinek@sun.com# 36*12199Sgerald.jelinek@sun.com# error messages 37*12199Sgerald.jelinek@sun.com# 38*12199Sgerald.jelinek@sun.comm_usage=$(gettext "Usage: %s: [-hFn]") 39*12199Sgerald.jelinek@sun.com 40*12199Sgerald.jelinek@sun.comm_1_zfs_promote=$(gettext "promoting '%s'.") 41*12199Sgerald.jelinek@sun.comm_1_zfs_destroy=$(gettext "destroying '%s'.") 42*12199Sgerald.jelinek@sun.comm_2_zfs_rename=$(gettext "renaming '%s' to '%s'.") 43*12199Sgerald.jelinek@sun.comm_3_zfs_set=$(gettext "setting property %s='%s' for '%s'.") 44*12199Sgerald.jelinek@sun.comm_rm_r=$(gettext "recursively deleting '%s'.") 45*12199Sgerald.jelinek@sun.comm_rm=$(gettext "deleting '%s'.") 46*12199Sgerald.jelinek@sun.com 47*12199Sgerald.jelinek@sun.comw_no_ds=$(gettext "Warning: no zonepath dataset found.") 48*12199Sgerald.jelinek@sun.com 49*12199Sgerald.jelinek@sun.comf_usage_err=$(gettext "Error: invalid usage") 50*12199Sgerald.jelinek@sun.comf_abort=$(gettext "Error: internal error detected, aborting.") 51*12199Sgerald.jelinek@sun.comf_1_zfs_promote=$(gettext "Error: promoting ZFS dataset '%s'.") 52*12199Sgerald.jelinek@sun.comf_2_zfs_rename=$(gettext "Error: renaming ZFS dataset '%s' to '%s'.") 53*12199Sgerald.jelinek@sun.comf_3_zfs_set=$(gettext "Error: setting ZFS propery %s='%s' for '%s'.") 54*12199Sgerald.jelinek@sun.comf_1_zfs_destroy=$(gettext "Error: destroying ZFS dataset.") 55*12199Sgerald.jelinek@sun.comf_2_zfs_get=$(gettext "Error: reading ZFS dataset property '%s' from '%s'.") 56*12199Sgerald.jelinek@sun.comf_user_snap=$(gettext "Error: user snapshot(s) detected.") 57*12199Sgerald.jelinek@sun.comf_stray_snap=$(gettext "Error: uncloned snapshot(s) detected.") 58*12199Sgerald.jelinek@sun.comf_stray_clone=$(gettext "Error: cloned zone datasets found outsize of zone.") 59*12199Sgerald.jelinek@sun.comf_rm_snap=$(gettext "Error: please delete snapshot(s) and retry uninstall.") 60*12199Sgerald.jelinek@sun.comf_rm_clone=$(gettext "Error: please delete clone(s) and retry uninstall.") 61*12199Sgerald.jelinek@sun.comf_iu_clone=$(gettext "Error: cloned zone dataset(s) in use.") 62*12199Sgerald.jelinek@sun.comf_dis_clone=$(gettext "Error: please stop using clone(s) and retry uninstall.") 63*12199Sgerald.jelinek@sun.com 64*12199Sgerald.jelinek@sun.com# 65*12199Sgerald.jelinek@sun.com# functions 66*12199Sgerald.jelinek@sun.com# 67*12199Sgerald.jelinek@sun.comprint_array() 68*12199Sgerald.jelinek@sun.com{ 69*12199Sgerald.jelinek@sun.com typeset -n pa_array=$1 70*12199Sgerald.jelinek@sun.com 71*12199Sgerald.jelinek@sun.com (( pa_i = 0 )) 72*12199Sgerald.jelinek@sun.com while (( $pa_i < ${#pa_array[@]} )); do 73*12199Sgerald.jelinek@sun.com printf "\t${pa_array[$pa_i]}\n" 74*12199Sgerald.jelinek@sun.com (( pa_i = $pa_i + 1 )) 75*12199Sgerald.jelinek@sun.com done 76*12199Sgerald.jelinek@sun.com} 77*12199Sgerald.jelinek@sun.com 78*12199Sgerald.jelinek@sun.comusage() 79*12199Sgerald.jelinek@sun.com{ 80*12199Sgerald.jelinek@sun.com printf "$m_usage\n" "$bname" 81*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_USAGE 82*12199Sgerald.jelinek@sun.com} 83*12199Sgerald.jelinek@sun.com 84*12199Sgerald.jelinek@sun.comusage_err() 85*12199Sgerald.jelinek@sun.com{ 86*12199Sgerald.jelinek@sun.com printf "$f_usage_err\n" >&2 87*12199Sgerald.jelinek@sun.com usage >&2 88*12199Sgerald.jelinek@sun.com} 89*12199Sgerald.jelinek@sun.com 90*12199Sgerald.jelinek@sun.comrm_zonepath() 91*12199Sgerald.jelinek@sun.com{ 92*12199Sgerald.jelinek@sun.com # cleanup stuff we know about and leave any user data alone 93*12199Sgerald.jelinek@sun.com 94*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && 95*12199Sgerald.jelinek@sun.com printf "$m_rm\n" "$zonepath/SUNWattached.xml" 96*12199Sgerald.jelinek@sun.com $nop /bin/rm -f "$zonepath/SUNWattached.xml" 97*12199Sgerald.jelinek@sun.com 98*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && 99*12199Sgerald.jelinek@sun.com printf "$m_rm_r\n" "$zonepath/lu" 100*12199Sgerald.jelinek@sun.com $nop /bin/rm -rf "$zonepath/lu" 101*12199Sgerald.jelinek@sun.com 102*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && 103*12199Sgerald.jelinek@sun.com printf "$m_rm_r\n" "$zonepath/dev" 104*12199Sgerald.jelinek@sun.com $nop /bin/rm -rf "$zonepath/dev" 105*12199Sgerald.jelinek@sun.com 106*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && 107*12199Sgerald.jelinek@sun.com printf "$m_rm_r\n" "$zonepath/root" 108*12199Sgerald.jelinek@sun.com $nop /bin/rm -rf "$zonepath/root" 109*12199Sgerald.jelinek@sun.com 110*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && 111*12199Sgerald.jelinek@sun.com printf "$m_rm\n" "$zonepath" 112*12199Sgerald.jelinek@sun.com $nop /bin/rmdir "$zonepath" 2>/dev/null 113*12199Sgerald.jelinek@sun.com} 114*12199Sgerald.jelinek@sun.com 115*12199Sgerald.jelinek@sun.comzfs_destroy() 116*12199Sgerald.jelinek@sun.com{ 117*12199Sgerald.jelinek@sun.com zd_fs1="$1" 118*12199Sgerald.jelinek@sun.com 119*12199Sgerald.jelinek@sun.com # first figure out if the target fs has an origin snapshot 120*12199Sgerald.jelinek@sun.com zd_origin=`/sbin/zfs get -H -o value origin "$zd_fs1"` 121*12199Sgerald.jelinek@sun.com if [[ $? != 0 ]]; then 122*12199Sgerald.jelinek@sun.com printf "$f_2_zfs_get\n" origin "$zd_fs1" >&2 123*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 124*12199Sgerald.jelinek@sun.com fi 125*12199Sgerald.jelinek@sun.com 126*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && 127*12199Sgerald.jelinek@sun.com printf "$m_1_zfs_destroy\n" "$zd_fs1" 128*12199Sgerald.jelinek@sun.com 129*12199Sgerald.jelinek@sun.com # 130*12199Sgerald.jelinek@sun.com # note that we specify the '-r' flag so that we destroy any 131*12199Sgerald.jelinek@sun.com # descendants (filesystems and snapshot) of the specified 132*12199Sgerald.jelinek@sun.com # filesystem. 133*12199Sgerald.jelinek@sun.com # 134*12199Sgerald.jelinek@sun.com $nop /sbin/zfs destroy -r "$zd_fs1" 135*12199Sgerald.jelinek@sun.com if [[ $? != 0 ]]; then 136*12199Sgerald.jelinek@sun.com printf "$f_1_zfs_destroy\n" "$zd_fs1" >&2 137*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 138*12199Sgerald.jelinek@sun.com fi 139*12199Sgerald.jelinek@sun.com 140*12199Sgerald.jelinek@sun.com [[ "$zd_origin" == "-" ]] && return 141*12199Sgerald.jelinek@sun.com 142*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && 143*12199Sgerald.jelinek@sun.com printf "$m_1_zfs_destroy\n" "$zd_origin" 144*12199Sgerald.jelinek@sun.com 145*12199Sgerald.jelinek@sun.com $nop /sbin/zfs destroy "$zd_origin" 2>/dev/null 146*12199Sgerald.jelinek@sun.com # 147*12199Sgerald.jelinek@sun.com # we ignore errors while trying to destroy the origin since 148*12199Sgerald.jelinek@sun.com # the origin could have been used as the source for other 149*12199Sgerald.jelinek@sun.com # clones 150*12199Sgerald.jelinek@sun.com # 151*12199Sgerald.jelinek@sun.com} 152*12199Sgerald.jelinek@sun.com 153*12199Sgerald.jelinek@sun.comzfs_promote() 154*12199Sgerald.jelinek@sun.com{ 155*12199Sgerald.jelinek@sun.com zp_fs1="$1" 156*12199Sgerald.jelinek@sun.com 157*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && 158*12199Sgerald.jelinek@sun.com printf "$m_1_zfs_promote\n" "$zp_fs1" 159*12199Sgerald.jelinek@sun.com 160*12199Sgerald.jelinek@sun.com $nop /sbin/zfs promote "$zp_fs1" 161*12199Sgerald.jelinek@sun.com if [[ $? != 0 ]]; then 162*12199Sgerald.jelinek@sun.com printf "$f_1_zfs_promote\n" "$zp_fs1" >&2 163*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 164*12199Sgerald.jelinek@sun.com fi 165*12199Sgerald.jelinek@sun.com} 166*12199Sgerald.jelinek@sun.com 167*12199Sgerald.jelinek@sun.comzfs_rename() 168*12199Sgerald.jelinek@sun.com{ 169*12199Sgerald.jelinek@sun.com zr_fs1="$1" 170*12199Sgerald.jelinek@sun.com zr_fs2="$2" 171*12199Sgerald.jelinek@sun.com 172*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && 173*12199Sgerald.jelinek@sun.com printf "$m_2_zfs_rename\n" "$zr_fs1" "$zr_fs2" 174*12199Sgerald.jelinek@sun.com 175*12199Sgerald.jelinek@sun.com $nop /sbin/zfs rename "$zr_fs1" "$zr_fs2" 176*12199Sgerald.jelinek@sun.com if [[ $? != 0 ]]; then 177*12199Sgerald.jelinek@sun.com printf "$f_2_zfs_rename\n" "$zr_fs1" "$zr_fs2" >&2 178*12199Sgerald.jelinek@sun.com return 1 179*12199Sgerald.jelinek@sun.com fi 180*12199Sgerald.jelinek@sun.com return 0 181*12199Sgerald.jelinek@sun.com} 182*12199Sgerald.jelinek@sun.com 183*12199Sgerald.jelinek@sun.comzfs_set() 184*12199Sgerald.jelinek@sun.com{ 185*12199Sgerald.jelinek@sun.com zs_prop=$1 186*12199Sgerald.jelinek@sun.com zs_value=$2 187*12199Sgerald.jelinek@sun.com zs_fs1=$3 188*12199Sgerald.jelinek@sun.com 189*12199Sgerald.jelinek@sun.com [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] && 190*12199Sgerald.jelinek@sun.com printf "$m_3_zfs_set\n" "$zs_prop" "$zs_value" "$zs_fs1" 191*12199Sgerald.jelinek@sun.com 192*12199Sgerald.jelinek@sun.com $nop /sbin/zfs set "$zs_prop"="$zs_value" "$zs_fs1" 193*12199Sgerald.jelinek@sun.com if [[ $? != 0 ]]; then 194*12199Sgerald.jelinek@sun.com printf "$f_3_zfs_set\n" "$zs_prop" "$zs_value" "$zs_fs1" 195*12199Sgerald.jelinek@sun.com return 1 196*12199Sgerald.jelinek@sun.com fi 197*12199Sgerald.jelinek@sun.com return 0 198*12199Sgerald.jelinek@sun.com} 199*12199Sgerald.jelinek@sun.com 200*12199Sgerald.jelinek@sun.comzfs_set_array() 201*12199Sgerald.jelinek@sun.com{ 202*12199Sgerald.jelinek@sun.com zsa_prop=$1 203*12199Sgerald.jelinek@sun.com zsa_value=$2 204*12199Sgerald.jelinek@sun.com typeset -n zsa_array=$3 205*12199Sgerald.jelinek@sun.com zsa_ignore_errors=$4 206*12199Sgerald.jelinek@sun.com 207*12199Sgerald.jelinek@sun.com (( zsa_i = 0 )) 208*12199Sgerald.jelinek@sun.com while (( $zsa_i < ${#zsa_array[@]} )); do 209*12199Sgerald.jelinek@sun.com zfs_set "$zsa_prop" "$zsa_value" "${zsa_array[$zsa_i]}" 210*12199Sgerald.jelinek@sun.com [[ $? != 0 ]] && [[ -z "$zsa_ignore_errors" ]] && 211*12199Sgerald.jelinek@sun.com return 1 212*12199Sgerald.jelinek@sun.com (( zsa_i = $zsa_i + 1 )) 213*12199Sgerald.jelinek@sun.com done 214*12199Sgerald.jelinek@sun.com return 0 215*12199Sgerald.jelinek@sun.com} 216*12199Sgerald.jelinek@sun.com 217*12199Sgerald.jelinek@sun.com 218*12199Sgerald.jelinek@sun.com(( snap_rename_zbe_i = 1 )) 219*12199Sgerald.jelinek@sun.com(( snap_rename_snap_i = 1 )) 220*12199Sgerald.jelinek@sun.comsnap_rename_init() 221*12199Sgerald.jelinek@sun.com{ 222*12199Sgerald.jelinek@sun.com (( snap_rename_zbe_i = 1 )) 223*12199Sgerald.jelinek@sun.com (( snap_rename_snap_i = 1 )) 224*12199Sgerald.jelinek@sun.com} 225*12199Sgerald.jelinek@sun.com 226*12199Sgerald.jelinek@sun.comsnap_rename() 227*12199Sgerald.jelinek@sun.com{ 228*12199Sgerald.jelinek@sun.com eval sr_fs=\${$1} 229*12199Sgerald.jelinek@sun.com eval sr_snap=\${$2} 230*12199Sgerald.jelinek@sun.com 231*12199Sgerald.jelinek@sun.com if [[ "$sr_snap" == ~(Elr)(zbe-[0-9][0-9]*) ]]; then 232*12199Sgerald.jelinek@sun.com sr_snap="zbe-$snap_rename_zbe_i" 233*12199Sgerald.jelinek@sun.com (( snap_rename_zbe_i = $snap_rename_zbe_i + 1 )) 234*12199Sgerald.jelinek@sun.com elif [[ "$sr_snap" == ~(Er)(_snap[0-9]*) ]]; then 235*12199Sgerald.jelinek@sun.com sr_snap=${sr_snap##~(Er)([0-9]*)} 236*12199Sgerald.jelinek@sun.com sr_snap="${sr_snap}${snap_rename_snap_i}" 237*12199Sgerald.jelinek@sun.com (( snap_rename_snap_i = $snap_rename_snap_i + 1 )) 238*12199Sgerald.jelinek@sun.com else 239*12199Sgerald.jelinek@sun.com printf "$f_user_snap\n" >&2 240*12199Sgerald.jelinek@sun.com printf "\t$sr_fs@$sr_snap\n" >&2 241*12199Sgerald.jelinek@sun.com printf "$f_rm_snap\n" >&2 242*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 243*12199Sgerald.jelinek@sun.com fi 244*12199Sgerald.jelinek@sun.com 245*12199Sgerald.jelinek@sun.com eval $2="$sr_snap" 246*12199Sgerald.jelinek@sun.com} 247*12199Sgerald.jelinek@sun.com 248*12199Sgerald.jelinek@sun.com# find the dataset associated with $zonepath 249*12199Sgerald.jelinek@sun.comuninstall_get_zonepath_ds() 250*12199Sgerald.jelinek@sun.com{ 251*12199Sgerald.jelinek@sun.com ZONEPATH_DS=`/sbin/zfs list -t filesystem -o name,mountpoint | \ 252*12199Sgerald.jelinek@sun.com /bin/nawk -v zonepath=$zonepath '{ 253*12199Sgerald.jelinek@sun.com if ($2 == zonepath) 254*12199Sgerald.jelinek@sun.com print $1 255*12199Sgerald.jelinek@sun.com }'` 256*12199Sgerald.jelinek@sun.com 257*12199Sgerald.jelinek@sun.com if [ -z "$ZONEPATH_DS" ]; then 258*12199Sgerald.jelinek@sun.com # there is no $zonepath dataset 259*12199Sgerald.jelinek@sun.com rm_zonepath 260*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_OK 261*12199Sgerald.jelinek@sun.com fi 262*12199Sgerald.jelinek@sun.com} 263*12199Sgerald.jelinek@sun.com 264*12199Sgerald.jelinek@sun.com# find the dataset associated with $ZONEPATH_DS/ROOT 265*12199Sgerald.jelinek@sun.comuninstall_get_zonepath_root_ds() 266*12199Sgerald.jelinek@sun.com{ 267*12199Sgerald.jelinek@sun.com ZONEPATH_RDS=`/sbin/zfs list -H -t filesystem -o name \ 268*12199Sgerald.jelinek@sun.com $ZONEPATH_DS/ROOT 2>/dev/null` 269*12199Sgerald.jelinek@sun.com 270*12199Sgerald.jelinek@sun.com if [ -z "$ZONEPATH_RDS" ]; then 271*12199Sgerald.jelinek@sun.com # there is no $ZONEPATH_DS/ROOT dataset 272*12199Sgerald.jelinek@sun.com c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_DS | wc -l` 273*12199Sgerald.jelinek@sun.com if [ $c = 1 ]; then 274*12199Sgerald.jelinek@sun.com # $zonepath dataset has no descendents 275*12199Sgerald.jelinek@sun.com zfs_destroy "$ZONEPATH_DS" 276*12199Sgerald.jelinek@sun.com fi 277*12199Sgerald.jelinek@sun.com rm_zonepath 278*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_OK 279*12199Sgerald.jelinek@sun.com fi 280*12199Sgerald.jelinek@sun.com} 281*12199Sgerald.jelinek@sun.com 282*12199Sgerald.jelinek@sun.comdestroy_zone_dataset() 283*12199Sgerald.jelinek@sun.com{ 284*12199Sgerald.jelinek@sun.com fs=$1 285*12199Sgerald.jelinek@sun.com 286*12199Sgerald.jelinek@sun.com pool=${fs%%/*} 287*12199Sgerald.jelinek@sun.com 288*12199Sgerald.jelinek@sun.com # Fastpath. if there are no snapshots of $fs then just delete it. 289*12199Sgerald.jelinek@sun.com c=`/sbin/zfs list -H -t snapshot -o name -r $fs | grep "^$fs@" | 290*12199Sgerald.jelinek@sun.com LC_ALL=C LANG=C wc -l` 291*12199Sgerald.jelinek@sun.com if (( $c == 0 )) ; then 292*12199Sgerald.jelinek@sun.com zfs_destroy "$fs" 293*12199Sgerald.jelinek@sun.com return 294*12199Sgerald.jelinek@sun.com fi 295*12199Sgerald.jelinek@sun.com 296*12199Sgerald.jelinek@sun.com # 297*12199Sgerald.jelinek@sun.com # This zone BE has snapshots. This can happen if a zone has 298*12199Sgerald.jelinek@sun.com # multiple BEs (in which case we have snapshots named "zbe-XXX"), 299*12199Sgerald.jelinek@sun.com # if this zone has been used as the source for a clone of 300*12199Sgerald.jelinek@sun.com # another zone (in which case we have snapshots named 301*12199Sgerald.jelinek@sun.com # "XXX_snap"), or if an administrator has been doing manual 302*12199Sgerald.jelinek@sun.com # snapshotting. 303*12199Sgerald.jelinek@sun.com # 304*12199Sgerald.jelinek@sun.com # To be able to destroy this dataset (which we'll call the 305*12199Sgerald.jelinek@sun.com # origin) we need to get rid of all it's snapshots. The "easiest" 306*12199Sgerald.jelinek@sun.com # way to do this is to: 307*12199Sgerald.jelinek@sun.com # 308*12199Sgerald.jelinek@sun.com # - delete any uncloned origin snapshots 309*12199Sgerald.jelinek@sun.com # - find the oldest clone of the youngest origin snapshot (which 310*12199Sgerald.jelinek@sun.com # we'll call the oldest clone) 311*12199Sgerald.jelinek@sun.com # - check if there are any snapshots naming conflicts between 312*12199Sgerald.jelinek@sun.com # the origin and the oldest clone. 313*12199Sgerald.jelinek@sun.com # - if so, find any clones of those conflicting origin snapshots 314*12199Sgerald.jelinek@sun.com # - make sure that those clones are not zoned an in-use. 315*12199Sgerald.jelinek@sun.com # - if any of those clones are zoned, unzone them. 316*12199Sgerald.jelinek@sun.com # - rename origin snapshots to eliminate naming conflicts 317*12199Sgerald.jelinek@sun.com # - for any clones that we unzoned, rezone them. 318*12199Sgerald.jelinek@sun.com # - promote the oldest clone 319*12199Sgerald.jelinek@sun.com # - destroy the origin and all it's descendants 320*12199Sgerald.jelinek@sun.com # 321*12199Sgerald.jelinek@sun.com 322*12199Sgerald.jelinek@sun.com # 323*12199Sgerald.jelinek@sun.com # Get a list of all the cloned datasets within the zpool 324*12199Sgerald.jelinek@sun.com # containing the origin filesystem. Filter out any filesystems 325*12199Sgerald.jelinek@sun.com # that are descendants of origin because we are planning to 326*12199Sgerald.jelinek@sun.com # destroy them anyway. 327*12199Sgerald.jelinek@sun.com # 328*12199Sgerald.jelinek@sun.com unset clones clones_origin 329*12199Sgerald.jelinek@sun.com (( clones_c = 0 )) 330*12199Sgerald.jelinek@sun.com pool=${fs%%/*} 331*12199Sgerald.jelinek@sun.com LANG=C LC_ALL=C /sbin/zfs list -H -t filesystem -s creation \ 332*12199Sgerald.jelinek@sun.com -o name,origin -r "$pool" | 333*12199Sgerald.jelinek@sun.com while IFS=" " read name origin; do 334*12199Sgerald.jelinek@sun.com 335*12199Sgerald.jelinek@sun.com # skip non-clone filesystems 336*12199Sgerald.jelinek@sun.com [[ "$origin" == "-" ]] && 337*12199Sgerald.jelinek@sun.com continue 338*12199Sgerald.jelinek@sun.com 339*12199Sgerald.jelinek@sun.com # skip desendents of the origin we plan to destroy 340*12199Sgerald.jelinek@sun.com [[ "$name" == ~()(${fs}/*) ]] && 341*12199Sgerald.jelinek@sun.com continue 342*12199Sgerald.jelinek@sun.com 343*12199Sgerald.jelinek@sun.com # record this clone and it's origin 344*12199Sgerald.jelinek@sun.com clones[$clones_c]="$name" 345*12199Sgerald.jelinek@sun.com clones_origin[$clones_c]="$origin" 346*12199Sgerald.jelinek@sun.com (( clones_c = $clones_c + 1 )) 347*12199Sgerald.jelinek@sun.com done 348*12199Sgerald.jelinek@sun.com 349*12199Sgerald.jelinek@sun.com # 350*12199Sgerald.jelinek@sun.com # Now do a sanity check. Search for clones of a child datasets 351*12199Sgerald.jelinek@sun.com # of the dataset we want to destroy, that are not themselves 352*12199Sgerald.jelinek@sun.com # children of the dataset we're going to destroy). This should 353*12199Sgerald.jelinek@sun.com # really never happen unless the global zone admin has cloned a 354*12199Sgerald.jelinek@sun.com # snapshot of a zone filesystem to a location outside of that 355*12199Sgerald.jelinek@sun.com # zone. bad admin... 356*12199Sgerald.jelinek@sun.com # 357*12199Sgerald.jelinek@sun.com unset stray_clones 358*12199Sgerald.jelinek@sun.com (( stray_clones_c = 0 )) 359*12199Sgerald.jelinek@sun.com (( j = 0 )) 360*12199Sgerald.jelinek@sun.com while (( $j < $clones_c )); do 361*12199Sgerald.jelinek@sun.com # is the clone origin a descendant of $fs? 362*12199Sgerald.jelinek@sun.com if [[ "${clones_origin[$j]}" != ~()(${fs}/*) ]]; then 363*12199Sgerald.jelinek@sun.com # we don't care. 364*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 365*12199Sgerald.jelinek@sun.com continue 366*12199Sgerald.jelinek@sun.com fi 367*12199Sgerald.jelinek@sun.com stray_clones[$stray_clones_c]=${clones[$j]} 368*12199Sgerald.jelinek@sun.com (( stray_clones_c = $stray_clones_c + 1 )) 369*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 370*12199Sgerald.jelinek@sun.com done 371*12199Sgerald.jelinek@sun.com if (( stray_clones_c > 0 )); then 372*12199Sgerald.jelinek@sun.com # 373*12199Sgerald.jelinek@sun.com # sigh. the admin has done something strange. 374*12199Sgerald.jelinek@sun.com # tell them to clean it up and retry. 375*12199Sgerald.jelinek@sun.com # 376*12199Sgerald.jelinek@sun.com printf "$f_stray_clone\n" >&2 377*12199Sgerald.jelinek@sun.com print_array stray_clones >&2 378*12199Sgerald.jelinek@sun.com printf "$f_rm_clone\n" >&2 379*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 380*12199Sgerald.jelinek@sun.com fi 381*12199Sgerald.jelinek@sun.com 382*12199Sgerald.jelinek@sun.com # Find all the snapshots of the origin filesystem. 383*12199Sgerald.jelinek@sun.com unset s_origin 384*12199Sgerald.jelinek@sun.com (( s_origin_c = 0 )) 385*12199Sgerald.jelinek@sun.com /sbin/zfs list -H -t snapshot -s creation -o name -r $fs | 386*12199Sgerald.jelinek@sun.com grep "^$fs@" | while read name; do 387*12199Sgerald.jelinek@sun.com s_origin[$s_origin_c]=$name 388*12199Sgerald.jelinek@sun.com (( s_origin_c = $s_origin_c + 1 )) 389*12199Sgerald.jelinek@sun.com done 390*12199Sgerald.jelinek@sun.com 391*12199Sgerald.jelinek@sun.com # 392*12199Sgerald.jelinek@sun.com # Now go through the origin snapshots and find those which don't 393*12199Sgerald.jelinek@sun.com # have clones. We're going to explicity delete these snapshots 394*12199Sgerald.jelinek@sun.com # before we do the promotion. 395*12199Sgerald.jelinek@sun.com # 396*12199Sgerald.jelinek@sun.com unset s_delete 397*12199Sgerald.jelinek@sun.com (( s_delete_c = 0 )) 398*12199Sgerald.jelinek@sun.com (( j = 0 )) 399*12199Sgerald.jelinek@sun.com while (( $j < $s_origin_c )); do 400*12199Sgerald.jelinek@sun.com (( k = 0 )) 401*12199Sgerald.jelinek@sun.com while (( $k < $clones_c )); do 402*12199Sgerald.jelinek@sun.com # if we have a match then break out of this loop 403*12199Sgerald.jelinek@sun.com [[ "${s_origin[$j]}" == "${clones_origin[$k]}" ]] && 404*12199Sgerald.jelinek@sun.com break 405*12199Sgerald.jelinek@sun.com (( k = $k + 1 )) 406*12199Sgerald.jelinek@sun.com done 407*12199Sgerald.jelinek@sun.com if (( $k != $clones_c )); then 408*12199Sgerald.jelinek@sun.com # this snapshot has a clone, move on to the next one 409*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 410*12199Sgerald.jelinek@sun.com continue 411*12199Sgerald.jelinek@sun.com fi 412*12199Sgerald.jelinek@sun.com 413*12199Sgerald.jelinek@sun.com # snapshot has no clones so add it to our delete list 414*12199Sgerald.jelinek@sun.com s_delete[$s_delete_c]=${s_origin[$j]} 415*12199Sgerald.jelinek@sun.com (( s_delete_c = $s_delete_c + 1 )) 416*12199Sgerald.jelinek@sun.com # remove it from the origin snapshot list 417*12199Sgerald.jelinek@sun.com (( k = $j + 1 )) 418*12199Sgerald.jelinek@sun.com while (( $k < $s_origin_c )); do 419*12199Sgerald.jelinek@sun.com s_origin[(( $k - 1 ))]=${s_origin[$k]} 420*12199Sgerald.jelinek@sun.com (( k = $k + 1 )) 421*12199Sgerald.jelinek@sun.com done 422*12199Sgerald.jelinek@sun.com (( s_origin_c = $s_origin_c - 1 )) 423*12199Sgerald.jelinek@sun.com done 424*12199Sgerald.jelinek@sun.com 425*12199Sgerald.jelinek@sun.com # 426*12199Sgerald.jelinek@sun.com # Fastpath. If there are no remaining snapshots then just 427*12199Sgerald.jelinek@sun.com # delete the origin filesystem (and all it's descendents) and 428*12199Sgerald.jelinek@sun.com # move onto the next zone BE. 429*12199Sgerald.jelinek@sun.com # 430*12199Sgerald.jelinek@sun.com if (( $s_origin_c == 0 )); then 431*12199Sgerald.jelinek@sun.com zfs_destroy "$fs" 432*12199Sgerald.jelinek@sun.com return 433*12199Sgerald.jelinek@sun.com fi 434*12199Sgerald.jelinek@sun.com 435*12199Sgerald.jelinek@sun.com # find the youngest snapshot of $fs 436*12199Sgerald.jelinek@sun.com s_youngest=${s_origin[(( $s_origin_c - 1 ))]} 437*12199Sgerald.jelinek@sun.com 438*12199Sgerald.jelinek@sun.com # Find the oldest clone of the youngest snapshot of $fs 439*12199Sgerald.jelinek@sun.com unset s_clone 440*12199Sgerald.jelinek@sun.com (( j = $clones_c - 1 )) 441*12199Sgerald.jelinek@sun.com while (( $j >= 0 )); do 442*12199Sgerald.jelinek@sun.com if [[ "$s_youngest" == "${clones_origin[$j]}" ]]; then 443*12199Sgerald.jelinek@sun.com s_clone=${clones[$j]} 444*12199Sgerald.jelinek@sun.com break 445*12199Sgerald.jelinek@sun.com fi 446*12199Sgerald.jelinek@sun.com (( j = $j - 1 )) 447*12199Sgerald.jelinek@sun.com done 448*12199Sgerald.jelinek@sun.com if [[ -z "$s_clone" ]]; then 449*12199Sgerald.jelinek@sun.com # uh oh. something has gone wrong. bail. 450*12199Sgerald.jelinek@sun.com printf "$f_stray_snap\n" >&2 451*12199Sgerald.jelinek@sun.com printf "\t$s_youngest\n" >&2 452*12199Sgerald.jelinek@sun.com printf "$f_rm_snap\n" >&2 453*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 454*12199Sgerald.jelinek@sun.com fi 455*12199Sgerald.jelinek@sun.com 456*12199Sgerald.jelinek@sun.com # create an array of clone snapshot names 457*12199Sgerald.jelinek@sun.com unset s_clone_s 458*12199Sgerald.jelinek@sun.com (( s_clone_s_c = 0 )) 459*12199Sgerald.jelinek@sun.com /sbin/zfs list -H -t snapshot -s creation -o name -r $s_clone | 460*12199Sgerald.jelinek@sun.com grep "^$s_clone@" | while read name; do 461*12199Sgerald.jelinek@sun.com s_clone_s[$s_clone_s_c]=${name##*@} 462*12199Sgerald.jelinek@sun.com (( s_clone_s_c = $s_clone_s_c + 1 )) 463*12199Sgerald.jelinek@sun.com done 464*12199Sgerald.jelinek@sun.com 465*12199Sgerald.jelinek@sun.com # create an arrays of possible origin snapshot renames 466*12199Sgerald.jelinek@sun.com unset s_origin_snap 467*12199Sgerald.jelinek@sun.com unset s_rename 468*12199Sgerald.jelinek@sun.com (( j = 0 )) 469*12199Sgerald.jelinek@sun.com while (( $j < $s_origin_c )); do 470*12199Sgerald.jelinek@sun.com s_origin_snap[$j]=${s_origin[$j]##*@} 471*12199Sgerald.jelinek@sun.com s_rename[$j]=${s_origin[$j]##*@} 472*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 473*12199Sgerald.jelinek@sun.com done 474*12199Sgerald.jelinek@sun.com 475*12199Sgerald.jelinek@sun.com # 476*12199Sgerald.jelinek@sun.com # Search for snapshot name collisions between the origin and 477*12199Sgerald.jelinek@sun.com # oldest clone. If we find one, generate a new name for the 478*12199Sgerald.jelinek@sun.com # origin snapshot and re-do the collision check. 479*12199Sgerald.jelinek@sun.com # 480*12199Sgerald.jelinek@sun.com snap_rename_init 481*12199Sgerald.jelinek@sun.com (( j = 0 )) 482*12199Sgerald.jelinek@sun.com while (( $j < $s_origin_c )); do 483*12199Sgerald.jelinek@sun.com (( k = 0 )) 484*12199Sgerald.jelinek@sun.com while (( $k < $s_clone_s_c )); do 485*12199Sgerald.jelinek@sun.com 486*12199Sgerald.jelinek@sun.com # if there's no naming conflict continue 487*12199Sgerald.jelinek@sun.com if [[ "${s_rename[$j]}" != "${s_clone_s[$k]}" ]]; then 488*12199Sgerald.jelinek@sun.com (( k = $k + 1 )) 489*12199Sgerald.jelinek@sun.com continue 490*12199Sgerald.jelinek@sun.com fi 491*12199Sgerald.jelinek@sun.com 492*12199Sgerald.jelinek@sun.com # 493*12199Sgerald.jelinek@sun.com # The origin snapshot conflicts with a clone 494*12199Sgerald.jelinek@sun.com # snapshot. Choose a new name and then restart 495*12199Sgerald.jelinek@sun.com # then check that against clone snapshot names. 496*12199Sgerald.jelinek@sun.com # 497*12199Sgerald.jelinek@sun.com snap_rename fs "s_rename[$j]" 498*12199Sgerald.jelinek@sun.com (( k = 0 )) 499*12199Sgerald.jelinek@sun.com continue; 500*12199Sgerald.jelinek@sun.com done 501*12199Sgerald.jelinek@sun.com 502*12199Sgerald.jelinek@sun.com # if we didn't rename this snapshot then continue 503*12199Sgerald.jelinek@sun.com if [[ "${s_rename[$j]}" == "${s_origin_snap[$j]}" ]]; then 504*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 505*12199Sgerald.jelinek@sun.com continue 506*12199Sgerald.jelinek@sun.com fi 507*12199Sgerald.jelinek@sun.com 508*12199Sgerald.jelinek@sun.com # 509*12199Sgerald.jelinek@sun.com # We need to rename this origin snapshot because it 510*12199Sgerald.jelinek@sun.com # conflicts with a clone snapshot name. So above we 511*12199Sgerald.jelinek@sun.com # chose a name that didn't conflict with any other clone 512*12199Sgerald.jelinek@sun.com # snapshot names. But we also have to avoid naming 513*12199Sgerald.jelinek@sun.com # conflicts with any other origin snapshot names. So 514*12199Sgerald.jelinek@sun.com # check for that now. 515*12199Sgerald.jelinek@sun.com # 516*12199Sgerald.jelinek@sun.com (( k = 0 )) 517*12199Sgerald.jelinek@sun.com while (( $k < $s_origin_c )); do 518*12199Sgerald.jelinek@sun.com 519*12199Sgerald.jelinek@sun.com # don't compare against ourself 520*12199Sgerald.jelinek@sun.com if (( $j == $k )); then 521*12199Sgerald.jelinek@sun.com (( k = $k + 1 )) 522*12199Sgerald.jelinek@sun.com continue 523*12199Sgerald.jelinek@sun.com fi 524*12199Sgerald.jelinek@sun.com 525*12199Sgerald.jelinek@sun.com # if there's no naming conflict continue 526*12199Sgerald.jelinek@sun.com if [[ "${s_rename[$j]}" != "${s_rename[$k]}" ]]; then 527*12199Sgerald.jelinek@sun.com (( k = $k + 1 )) 528*12199Sgerald.jelinek@sun.com continue 529*12199Sgerald.jelinek@sun.com fi 530*12199Sgerald.jelinek@sun.com 531*12199Sgerald.jelinek@sun.com # 532*12199Sgerald.jelinek@sun.com # The new origin snapshot name conflicts with 533*12199Sgerald.jelinek@sun.com # another origin snapshot name. Choose a new 534*12199Sgerald.jelinek@sun.com # name and then go back to check the new name 535*12199Sgerald.jelinek@sun.com # for uniqueness against all the clone snapshot 536*12199Sgerald.jelinek@sun.com # names. 537*12199Sgerald.jelinek@sun.com # 538*12199Sgerald.jelinek@sun.com snap_rename fs "s_rename[$j]" 539*12199Sgerald.jelinek@sun.com continue 2; 540*12199Sgerald.jelinek@sun.com done 541*12199Sgerald.jelinek@sun.com 542*12199Sgerald.jelinek@sun.com # 543*12199Sgerald.jelinek@sun.com # A new unique name has been chosen. Move on to the 544*12199Sgerald.jelinek@sun.com # next origin snapshot. 545*12199Sgerald.jelinek@sun.com # 546*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 547*12199Sgerald.jelinek@sun.com snap_rename_init 548*12199Sgerald.jelinek@sun.com done 549*12199Sgerald.jelinek@sun.com 550*12199Sgerald.jelinek@sun.com # 551*12199Sgerald.jelinek@sun.com # So now we know what snapshots need to be renamed before the 552*12199Sgerald.jelinek@sun.com # promotion. But there's an additional problem. If any of the 553*12199Sgerald.jelinek@sun.com # filesystems cloned from these snapshots have the "zoned" 554*12199Sgerald.jelinek@sun.com # attribute set (which is highly likely) or if they are in use 555*12199Sgerald.jelinek@sun.com # (and can't be unmounted and re-mounted) then the snapshot 556*12199Sgerald.jelinek@sun.com # rename will fail. So now we'll search for all the clones of 557*12199Sgerald.jelinek@sun.com # snapshots we plan to rename and look for ones that are zoned. 558*12199Sgerald.jelinek@sun.com # 559*12199Sgerald.jelinek@sun.com # We'll ignore any snapshot clones that may be in use but are 560*12199Sgerald.jelinek@sun.com # not zoned. If these clones are in-use, the rename will fail 561*12199Sgerald.jelinek@sun.com # and we'll abort, there's not much else we can do about it. 562*12199Sgerald.jelinek@sun.com # But if they are not in use the snapshot rename will unmount 563*12199Sgerald.jelinek@sun.com # and remount the clone. This is ok because when the zoned 564*12199Sgerald.jelinek@sun.com # attribute is off, we know that the clone was originally 565*12199Sgerald.jelinek@sun.com # mounted from the global zone. (So unmounting and remounting 566*12199Sgerald.jelinek@sun.com # it from the global zone is ok.) 567*12199Sgerald.jelinek@sun.com # 568*12199Sgerald.jelinek@sun.com # But we'll abort this whole operation if we find any clones 569*12199Sgerald.jelinek@sun.com # that that are zoned and in use. (This can happen if another 570*12199Sgerald.jelinek@sun.com # zone has been cloned from this one and is now booted.) The 571*12199Sgerald.jelinek@sun.com # reason we do this is because those zoned filesystems could 572*12199Sgerald.jelinek@sun.com # have originally mounted from within the zone. So if we 573*12199Sgerald.jelinek@sun.com # cleared the zone attribute and did the rename, we'd be 574*12199Sgerald.jelinek@sun.com # remounting the filesystem from the global zone. This would 575*12199Sgerald.jelinek@sun.com # result in the zone losing the ability to unmount the 576*12199Sgerald.jelinek@sun.com # filesystem, which would be bad. 577*12199Sgerald.jelinek@sun.com # 578*12199Sgerald.jelinek@sun.com unset zoned_clones zoned_iu_clones 579*12199Sgerald.jelinek@sun.com (( zoned_clones_c = 0 )) 580*12199Sgerald.jelinek@sun.com (( zoned_iu_clones_c = 0 )) 581*12199Sgerald.jelinek@sun.com (( j = 0 )) 582*12199Sgerald.jelinek@sun.com # walk through all the clones 583*12199Sgerald.jelinek@sun.com while (( $j < $clones_c )); do 584*12199Sgerald.jelinek@sun.com # walk through all the origin snapshots 585*12199Sgerald.jelinek@sun.com (( k = 0 )) 586*12199Sgerald.jelinek@sun.com while (( $k < $s_origin_c )); do 587*12199Sgerald.jelinek@sun.com # 588*12199Sgerald.jelinek@sun.com # check if this clone originated from a snapshot that 589*12199Sgerald.jelinek@sun.com # we need to rename. 590*12199Sgerald.jelinek@sun.com # 591*12199Sgerald.jelinek@sun.com [[ "${clones_origin[$j]}" == "${s_origin[$k]}" ]] && 592*12199Sgerald.jelinek@sun.com [[ "${s_origin_snap[$k]}" != "${s_rename[$k]}" ]] && 593*12199Sgerald.jelinek@sun.com break 594*12199Sgerald.jelinek@sun.com (( k = $k + 1 )) 595*12199Sgerald.jelinek@sun.com continue 596*12199Sgerald.jelinek@sun.com done 597*12199Sgerald.jelinek@sun.com if (( $k == $s_origin_c )); then 598*12199Sgerald.jelinek@sun.com # This isn't a clone of a snapshot we want to rename. 599*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 600*12199Sgerald.jelinek@sun.com continue; 601*12199Sgerald.jelinek@sun.com fi 602*12199Sgerald.jelinek@sun.com 603*12199Sgerald.jelinek@sun.com # get the zoned attr for this clone. 604*12199Sgerald.jelinek@sun.com zoned=`LC_ALL=C LANG=C \ 605*12199Sgerald.jelinek@sun.com /sbin/zfs get -H -o value zoned ${clones[$j]}` 606*12199Sgerald.jelinek@sun.com if [[ "$zoned" != on ]]; then 607*12199Sgerald.jelinek@sun.com # This clone isn't zoned so ignore it. 608*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 609*12199Sgerald.jelinek@sun.com continue 610*12199Sgerald.jelinek@sun.com fi 611*12199Sgerald.jelinek@sun.com 612*12199Sgerald.jelinek@sun.com # remember this clone so we can muck with it's zoned attr. 613*12199Sgerald.jelinek@sun.com zoned_clones[$zoned_clones_c]=${clones[$j]} 614*12199Sgerald.jelinek@sun.com (( zoned_clones_c = $zoned_clones_c + 1 )) 615*12199Sgerald.jelinek@sun.com 616*12199Sgerald.jelinek@sun.com # check if it's in use 617*12199Sgerald.jelinek@sun.com mounted=`LC_ALL=C LANG=C \ 618*12199Sgerald.jelinek@sun.com /sbin/zfs get -H -o value mounted ${clones[$j]}` 619*12199Sgerald.jelinek@sun.com if [[ "$mounted" != yes ]]; then 620*12199Sgerald.jelinek@sun.com # Good news. This clone isn't in use. 621*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 622*12199Sgerald.jelinek@sun.com continue 623*12199Sgerald.jelinek@sun.com fi 624*12199Sgerald.jelinek@sun.com 625*12199Sgerald.jelinek@sun.com # Sigh. This clone is in use so we're destined to fail. 626*12199Sgerald.jelinek@sun.com zoned_iu_clones[$zoned_iu_clones_c]=${clones[$j]} 627*12199Sgerald.jelinek@sun.com (( zoned_iu_clones_c = $zoned_iu_clones_c + 1 )) 628*12199Sgerald.jelinek@sun.com 629*12199Sgerald.jelinek@sun.com # keep looking for errors so we can report them all at once. 630*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 631*12199Sgerald.jelinek@sun.com done 632*12199Sgerald.jelinek@sun.com if (( zoned_iu_clones_c > 0 )); then 633*12199Sgerald.jelinek@sun.com # 634*12199Sgerald.jelinek@sun.com # Tell the admin 635*12199Sgerald.jelinek@sun.com # 636*12199Sgerald.jelinek@sun.com printf "$f_iu_clone\n" >&2 637*12199Sgerald.jelinek@sun.com print_array zoned_iu_clones >&2 638*12199Sgerald.jelinek@sun.com printf "$f_dis_clone\n" >&2 639*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 640*12199Sgerald.jelinek@sun.com fi 641*12199Sgerald.jelinek@sun.com 642*12199Sgerald.jelinek@sun.com # 643*12199Sgerald.jelinek@sun.com # Ok. So we're finally done with planning and we can do some 644*12199Sgerald.jelinek@sun.com # damage. We're going to: 645*12199Sgerald.jelinek@sun.com # - destroy unused snapshots 646*12199Sgerald.jelinek@sun.com # - unzone clones which originate from snapshots we need to rename 647*12199Sgerald.jelinek@sun.com # - rename conflicting snapshots 648*12199Sgerald.jelinek@sun.com # - rezone any clones which we unzoned 649*12199Sgerald.jelinek@sun.com # - promote the oldest clone of the youngest snapshot 650*12199Sgerald.jelinek@sun.com # - finally destroy the origin filesystem. 651*12199Sgerald.jelinek@sun.com # 652*12199Sgerald.jelinek@sun.com 653*12199Sgerald.jelinek@sun.com # delete any unsed snapshot 654*12199Sgerald.jelinek@sun.com (( j = 0 )) 655*12199Sgerald.jelinek@sun.com while (( $j < $s_delete_c )); do 656*12199Sgerald.jelinek@sun.com zfs_destroy "${s_delete[$j]}" 657*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 658*12199Sgerald.jelinek@sun.com done 659*12199Sgerald.jelinek@sun.com 660*12199Sgerald.jelinek@sun.com # unzone clones 661*12199Sgerald.jelinek@sun.com zfs_set_array zoned off zoned_clones || 662*12199Sgerald.jelinek@sun.com zfs_set_array zoned on zoned_clones 1 663*12199Sgerald.jelinek@sun.com 664*12199Sgerald.jelinek@sun.com # rename conflicting snapshots 665*12199Sgerald.jelinek@sun.com (( j = 0 )) 666*12199Sgerald.jelinek@sun.com while (( $j < $s_origin_c )); do 667*12199Sgerald.jelinek@sun.com if [[ "${s_origin_snap[$j]}" != "${s_rename[$j]}" ]]; then 668*12199Sgerald.jelinek@sun.com zfs_rename "${s_origin[$j]}" "$fs@${s_rename[$j]}" 669*12199Sgerald.jelinek@sun.com if [[ $? != 0 ]]; then 670*12199Sgerald.jelinek@sun.com # re-zone the clones before aborting 671*12199Sgerald.jelinek@sun.com zfs_set_array zoned on zoned_clones 1 672*12199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 673*12199Sgerald.jelinek@sun.com fi 674*12199Sgerald.jelinek@sun.com fi 675*12199Sgerald.jelinek@sun.com (( j = $j + 1 )) 676*12199Sgerald.jelinek@sun.com done 677*12199Sgerald.jelinek@sun.com 678*12199Sgerald.jelinek@sun.com # re-zone the clones 679*12199Sgerald.jelinek@sun.com zfs_set_array zoned on zoned_clones 1 680*12199Sgerald.jelinek@sun.com 681*12199Sgerald.jelinek@sun.com # promote the youngest clone of the oldest snapshot 682*12199Sgerald.jelinek@sun.com zfs_promote "$s_clone" 683*12199Sgerald.jelinek@sun.com 684*12199Sgerald.jelinek@sun.com # destroy the origin filesystem and it's descendants 685*12199Sgerald.jelinek@sun.com zfs_destroy "$fs" 686*12199Sgerald.jelinek@sun.com} 687*12199Sgerald.jelinek@sun.com 688*12199Sgerald.jelinek@sun.com# 689*12199Sgerald.jelinek@sun.com# This function expects an array named fs_all to exist which is initialized 690*12199Sgerald.jelinek@sun.com# with the zone's ZFS datasets that should be destroyed. fs_all_c is the 691*12199Sgerald.jelinek@sun.com# count of the number of elements in the array. ZONEPATH_RDS is the 692*12199Sgerald.jelinek@sun.com# zonepath/root dataset and ZONEPATH_DS is the zonepath dataset. 693*12199Sgerald.jelinek@sun.com# 694*12199Sgerald.jelinek@sun.comdestroy_zone_datasets() 695*12199Sgerald.jelinek@sun.com{ 696*12199Sgerald.jelinek@sun.com # Destroy the zone BEs datasets one by one. 697*12199Sgerald.jelinek@sun.com (( i = 0 )) 698*12199Sgerald.jelinek@sun.com while (( $i < $fs_all_c )); do 699*12199Sgerald.jelinek@sun.com fs=${fs_all[$i]} 700*12199Sgerald.jelinek@sun.com 701*12199Sgerald.jelinek@sun.com destroy_zone_dataset "$fs" 702*12199Sgerald.jelinek@sun.com (( i = $i + 1 )) 703*12199Sgerald.jelinek@sun.com done 704*12199Sgerald.jelinek@sun.com 705*12199Sgerald.jelinek@sun.com # 706*12199Sgerald.jelinek@sun.com # Check if there are any other datasets left. There may be datasets 707*12199Sgerald.jelinek@sun.com # associated with other GZ BEs, so we need to leave things alone in 708*12199Sgerald.jelinek@sun.com # that case. 709*12199Sgerald.jelinek@sun.com # 710*12199Sgerald.jelinek@sun.com c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_RDS | wc -l` 711*12199Sgerald.jelinek@sun.com if [ $c = 1 ]; then 712*12199Sgerald.jelinek@sun.com zfs_destroy "$ZONEPATH_RDS" 713*12199Sgerald.jelinek@sun.com fi 714*12199Sgerald.jelinek@sun.com c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_DS | wc -l` 715*12199Sgerald.jelinek@sun.com if [ $c = 1 ]; then 716*12199Sgerald.jelinek@sun.com zfs_destroy "$ZONEPATH_DS" 717*12199Sgerald.jelinek@sun.com fi 718*12199Sgerald.jelinek@sun.com 719*12199Sgerald.jelinek@sun.com rm_zonepath 720*12199Sgerald.jelinek@sun.com} 721