#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
#
. /usr/lib/brand/solaris/common.ksh
m_usage=$(gettext "clone [-c profile.xml | dir] {sourcezone}\n\tThe -c option gives a profile or a directory of profiles to be applied to the system after clone.")
m_failed=$(gettext "Result: Clone Failed.")
# Clean up on failure
trap_exit()
{
if (( ZONE_IS_MOUNTED != 0 )); then
error "$v_unmount"
zoneadm -z $ZONENAME unmount
fi
case $EXIT_CODE in
$ZONE_SUBPROC_OK)
# unmount the zoneroot if labeled brand
is_brand_labeled
(( $? == 1 )) && ( umount "${dst.root}" || \
log "$f_zfs_unmount" "${dst.root}" )
unpin_datasets "${dst.path.ds}" || error "$f_unpin"
;;
$ZONE_SUBPROC_TRYAGAIN|$ZONE_SUBPROC_UNAVAILABLE)
unpin_datasets "${dst.path.ds}" || error "$f_unpin"
log "$m_failed"
;;
*)
# Remove datasets that shouldn't exist
delete_unpinned_datasets "${dst.path.ds}" &&
EXIT_CODE=$ZONE_SUBPROC_TRYAGAIN
unpin_datasets "${dst.path.ds}" || error "$f_unpin"
log "$m_failed"
;;
esac
finish_log dst
exit $EXIT_CODE
}
set -A save_args "$0" "$@"
EXIT_CODE=$ZONE_SUBPROC_USAGE
# Source and destination zones
unset sc_config
typeset src dst
# Other brand clone options are invalid for this brand.
while getopts "R:z:c:x:" opt; do
case $opt in
R) opt_R="$OPTARG" ;;
z) opt_z="$OPTARG" ;;
c) ls "$OPTARG" >/dev/null 2>&1
[[ -f $OPTARG ]] || [[ -d $OPTARG ]] || fatal "$f_arg_not_file_or_dir" "$OPTARG"
sc_config="$OPTARG"
;;
x) ;; # zoneadm only
*) fail_usage "";;
esac
done
shift $((OPTIND-1))
if (($# < 1)); then
fail_usage ""
fi
# Configuration profile file must have .xml suffix
if [[ -f $sc_config && $sc_config != *.xml ]]; then
fail_usage "$f_scxml" "$sc_config"
fi
init_zone dst "$opt_z" "$opt_R"
init_zone src "$1"
shift
start_log dst clone "${save_args[@]}"
pin_datasets "${dst.path.ds}" || fatal "$f_pin"
EXIT_CODE=$ZONE_SUBPROC_TRYAGAIN
trap trap_exit EXIT
get_current_gzbe
get_active_be src || fail_unavailable "$e_no_active_be"
# From here on out the global variables referenced are for the destination zone
eval $(bind_legacy_zone_globals dst)
# Make dataset snapshots
snapshot_zone_rpool src "${dst}_snap%02d" snapname \
|| fail_tryagain "$f_zfs_snapshot"
# Make dataset clones. This sets EXIT_CODE if datasets created.
clone_zone_rpool src dst "$snapname" || fail_fatal "$f_zone_clone"
ZONE_IS_MOUNTED=1
#
# Completion of reconfigure_zone will leave the zone root mounted for
# solaris brand zones. The root won't be mounted for labeled brand zones.
#
is_brand_labeled
brand_labeled=$?
if [[ $brand_labeled = 0 ]] && [[ ! -n $sc_config ]]; then
. /usr/lib/brand/labeled/common.ksh
labeled_reconfigure system --destructive || fatal "$e_badmount"
else
reconfigure_zone $sc_config
fi
unpin_datasets "${dst.path.ds}" || error "$f_unpin"
finish_log dst
trap - EXIT
exit $ZONE_SUBPROC_OK