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