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