#!/bin/ksh -p # # # # # # # # # # # # # # # # # # # # # Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. # . /usr/lib/brand/solaris/common.ksh # Allows developers to override some things like PATH and PYTHONPATH . /usr/lib/brand/solaris/developerenv.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.") m_pkg_revert=$(gettext "Reverting files which are marked with pkg revert tag system:clone and clone-archive.") m_pkg_revert_failed=$(gettext "Warning: pkg revert operation failed for system:clone and clone-archive tags.") # 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 unset sc_config # Source and destination zones 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) sc_config="$(mk_abs_path $OPTARG)" ;; x) ;; # zoneadm only *) fail_usage "";; esac done shift $((OPTIND-1)) if (( $# < 1 )); then fail_usage "" fi check_sc_config "$sc_config" init_zone dst "$opt_z" "$opt_R" init_zone src "$1" shift # Check whether the destination zone has been detached from this system and if # so, suggest either trying to re-attach the zone or marking it incomplete and # uninstalling it first. if has_bootable_bes dst; then log "$f_reattach_or_uninstall" "clone" EXIT_CODE=$ZONE_SUBPROC_TRYAGAIN exit $EXIT_CODE fi 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 are created. clone_zone_rpool src dst "$snapname" || fail_fatal "$f_zone_clone" ZONE_IS_MOUNTED=1 # Reverting files which are marked with system:clone and clone-archive tags vlog "$m_pkg_revert" pkg -R "${dst.root}" revert -q --tagged system:clone --tagged clone-archive \ || pkg_err_check "$m_pkg_revert_failed" log # # 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