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# See the License for the specific language governing permissions 2N/A# and limitations under the License. 2N/A# When distributing Covered Code, include this CDDL HEADER in each 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# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A# NOTE: this script runs in the global zone and touches the non-global 2N/A# zone, so care should be taken to validate any modifications so that they 2N/A echo "$0 [-s] [-m msgprefix] [-u] [-v] [-b patchid]* [-c sysidcfg] zonename" >&2 2N/A# Clean up on interrupt 2N/A # Delete temporary files created during the hollow package removal 2N/A# Disable any existing live-upgrade configuration. 2N/A# We have already called safe_dir to validate the etc/lu directory. 2N/A# For an exclusive stack zone, verify the zonecfg network configuration 2N/A # and interface names from zonecfg net and anet resources. 2N/A # Make sure list items are separated by a space character. 2N/A # not covered in the zonecfg file. 2N/A # Extract interface name from end of file name 2N/A # Strip logical interface number that may exist 2N/A # Isolate device name 2N/A # Skip virtual and ppp interfaces. 2N/A # Do basic validity checks on interface and device names 2N/A # Build list of unique interfaces names we found. 2N/A # Is the interface name we extracted included in 2N/A # net or anet resource interface names? 2N/A # Walk the list of resources looking for interface names 2N/A# Disable all of the shares since the zone cannot be an NFS server. 2N/A# SMF service in the fix_smf function. 2N/A if (substr($1, 0, 1) == "#") { 2N/A if (modified == 1) { 2N/A printf("# Modified by p2v ") 2N/A if (( $? == 0 )); then 2N/A# Comment out most of the old mounts since they are either unneeded or 2N/A# likely incorrect within a zone. Specific mounts can be manually 2N/A# reenabled if the corresponding device is added to the zone. 2N/A if (substr($1, 0, 1) == "#") { 2N/A } else if ($1 == "fd" || $1 == "/proc" || $1 == "swap" || 2N/A $1 == "ctfs" || $1 == "objfs" || $1 == "sharefs" || 2N/A $4 == "nfs" || $4 == "lofs") { 2N/A if (modified == 1) { 2N/A printf("# Modified by p2v ") 2N/A if (( $? == 0 )); then 2N/A# Collect the data needed to delete SMF services. Since we're p2v-ing a 2N/A# physical image there are SMF services which must be deleted. 2N/A # Start by getting the svc manifests that are delivered by hollow 2N/A # pkgs then use 'svccfg inventory' to get the names of the svcs 2N/A # delivered by those manifests. The svc names are saved into a 2N/A# Delete or disable SMF services. 2N/A# Zone is booted to milestone=none when this function is called. 2N/A# Use the SMF data collected by get_smf_services_to_delete() to delete the 2N/A # Zone was already booted to milestone=none, wait until SMF door exists. 2N/A for i in 0 1 2 3 4 5 6 7 8 9 2N/A if (( i == 9 )) && \ 2N/A # The zone never booted, something is wrong. 2N/A # Get a list of the svcs that now exist in the zone. 2N/A # Fix network services if shared stack. 2N/A if (( $? == 0 )); then 2N/A if (( $? == 0 )); then 2N/A # Disable well-known services that don't run in a zone. 2N/A # Skip svcs not installed in the zone. 2N/A # Since zones can't be NFS servers, disable all of the instances of 2N/A# Remove well-known pkgs that do not work inside a zone. 2N/A /usr/bin/cat <<-EOF > $ZONEROOT/tmp/admin || fatal "$e_adminf" 2N/A for i in $(/usr/bin/egrep -hv "^#" /usr/lib/brand/solaris10/pkgrm.lst \ 2N/A /etc/brand/solaris10/pkgrm.conf) 2N/A [[ ! -d $ZONEROOT/var/sadm/pkg/$i ]] && continue 2N/A vlog "$v_rmpkg" "$i" 2N/A /usr/sbin/zlogin -S $ZONENAME \ 2N/A /usr/sbin/pkgrm -na /tmp/admin $i >&2 || error "$e_rmpkg" $i 2N/A# ^C Should cleanup; if the zone is running, it should try to halt it. 2N/Ainteger zone_is_running=0 2N/Atrap trap_cleanup INT 2N/Aset -A save_args "$0" "$@" 2N/A# Parse the command line options. 2N/Awhile getopts "c:uvm:" opt 2N/A c) sc_sysidcfg="$OPTARG" ;; 2N/A m) MSG_PREFIX="$OPTARG"; OPT_M="-m \"$OPTARG\"";; 2N/A(( $# < 1 )) && usage 2N/A(( $# > 2 )) && usage 2N/A[[ -n $LOGFILE ]] && exec 2>>$LOGFILE 2N/Ainit_zone zone "$1" "$2" 2N/Aeval $(bind_legacy_zone_globals zone) 2N/A# Clear the child dataset list - solaris10 should not create them. 2N/Aset -A zone.new_be_datasets 2N/Astart_log zone install "${save_args[@]}" 2N/Ae_badinfo=$(gettext "Failed to get '%s' zone resource") 2N/Ae_badfile=$(gettext "Invalid '%s' file within the zone") 2N/Av_invalidiface=$(gettext "Invalid interface name in '%s'") 2N/Av_noresource=$(gettext "No zonecfg net or anet resource found for %s") 2N/Av_nonethostname=$(gettext \ 2N/A "No /etc/hostname\* file found for zonecfg net physical=%s") 2N/Av_noanethostname=$(gettext \ 2N/A "No /etc/hostname\* file found for zonecfg anet linkname=%s") 2N/Av_adjust=$(gettext "Updating the image to run within a zone") 2N/Av_stacktype=$(gettext "Stack type '%s'") 2N/Av_booting=$(gettext "Booting zone to single user mode") 2N/Ae_bootfail=$(gettext "Failed to boot zone to single user mode.") 2N/Ae_nosmf=$(gettext "SMF repository unavailable.") 2N/Av_svcsinzone=$(gettext "The following SMF services are installed:") 2N/Av_rmhollowsvcs=$(gettext "Deleting SMF services from hollow packages") 2N/Av_fixnetsvcs=$(gettext "Adjusting network SMF services") 2N/Av_rminvalidsvcs=$(gettext "Disabling invalid SMF services") 2N/Av_delsvc=$(gettext "Delete SMF svc '%s'") 2N/Av_enblsvc=$(gettext "Enable SMF svc '%s'") 2N/Ae_enblsvc=$(gettext "enabling SMF svc '%s'") 2N/Av_dissvc=$(gettext "Disable SMF svc '%s'") 2N/Ae_dissvc=$(gettext "disabling SMF svc '%s'") 2N/Ae_adminf=$(gettext "Unable to create admin file") 2N/Av_rmpkg=$(gettext "Remove package '%s'") 2N/Ae_rmpkg=$(gettext "removing package '%s'") 2N/Av_halting=$(gettext "Halting zone") 2N/Av_sc_config=$(gettext "Copying sysconfig file to zone") 2N/Av_migrate_export=$(gettext "Migrating /export out of boot environment") 2N/Ae_shutdown=$(gettext "Shutting down zone %s...") 2N/Ae_badhalt=$(gettext "Zone halt failed") 2N/Av_exitgood=$(gettext "Postprocessing successful.") 2N/Ae_exitfail=$(gettext "Postprocessing failed.") 2N/A# Do some validation on the paths we'll be accessing 2N/Asafe_dir /var/sadm/install 2N/Asafe_dir /var/sadm/pkg 2N/Asafe_opt_dir /etc/dfs 2N/Asafe_opt_dir /etc/zones 2N/A# Now do the work to update the zone. 2N/A# Check for zones inside of image. 2N/A# Any errors in these functions are not considered fatal. The zone can be 2N/A# be fixed up manually afterwards and it may need some additional manual 2N/A# cleanup in any case. 2N/ASTACK_TYPE=$(/usr/sbin/zoneadm -z $ZONENAME list -p | \ 2N/A /usr/bin/nawk -F: '{print $7}') 2N/Aif (( $? != 0 )); then 2N/A error "$e_badinfo" "stacktype" 2N/Avlog "$v_stacktype" "$STACK_TYPE" 2N/Aif [[ -z $OPT_U ]]; then 2N/A# Boot the zone so that we can do all of the SMF updates needed on the zone's 2N/A/usr/sbin/zoneadm -z $ZONENAME boot -f -- -m milestone=none 2N/Aif (( $? != 0 )); then 2N/A /usr/bin/rm -f $SMFTMPFILE 2N/Aget_smf_services_to_delete 2N/A# Remove all files and directories installed by hollow packages. Such files 2N/A# and directories shouldn't exist inside zones. 2N/Ahollow_pkgs=$(mktemp -t .hollow.pkgs.XXXXXX) 2N/Ahollow_file_list=$(mktemp $ZONEROOT/.hollow.pkgs.files.XXXXXX) 2N/Ahollow_dir_list=$(mktemp $ZONEROOT/.hollow.pkgs.dirs.XXXXXX) 2N/A[ -f "$hollow_pkgs" -a -f "$hollow_file_list" -a -f "$hollow_dir_list" ] || { 2N/A rm -f $hollow_pkgs $hollow_file_list $hollow_dir_list 2N/Afor pkg_name in $ZONEROOT/var/sadm/pkg/*; do 2N/A grep 'SUNW_PKG_HOLLOW=true' $pkg_name/pkginfo >/dev/null 2>&1 && \ 2N/A basename $pkg_name >>$hollow_pkgs 2N/A/usr/bin/nawk -v hollowpkgs=$hollow_pkgs -v filelist=$hollow_file_list \ 2N/A -v dirlist=$hollow_dir_list ' 2N/A while (getline p <hollowpkgs > 0) 2N/A # fld is the field where the pkg names begin. 2N/A # nm is the file/dir entry name. 2N/A } else if ($2 == "d") { 2N/A } else if ($2 == "s" || $2 == "l") { 2N/A # Determine whether the file or directory is delivered by any 2N/A # non-hollow packages. Files and directories can be 2N/A # delivered by multiple pkgs. The file or directory should only 2N/A # be removed if it is only delivered by hollow packages. 2N/A for (i = fld; i <= NF; i++) { 2N/A if (pkgs[get_pkg_name($i)] != 1) { 2N/A # We encountered a non-hollow package. Skip 2N/A # The file or directory is only delivered by hollow packages. 2N/A # Mark it for removal. 2N/A # Get the clean pkg name from the fld entry. 2N/A function get_pkg_name(fld) { 2N/A # Remove any pkg control prefix (e.g. *, !) 2N/A first = substr(fld, 1, 1) 2N/A if (match(first, /[A-Za-z]/)) { 2N/A pname = substr(fld, 2) 2N/A # Then remove any class action script name 2N/A pos = index(pname, ":") 2N/A pname = substr(pname, 1, pos - 1) 2N/A' $ZONEROOT/var/sadm/install/contents 2N/A/usr/sbin/zlogin -S $ZONENAME "cat /$(basename $hollow_file_list) | xargs rm -f" 2N/A/usr/sbin/zlogin -S $ZONENAME "sort -r /$(basename $hollow_dir_list) | \ 2N/A xargs rmdir >/dev/null 2>&1" 2N/Arm -f $hollow_pkgs $hollow_file_list $hollow_dir_list 2N/A# cleanup SMF services 2N/A# remove invalid pkgs 2N/A[[ -z $failed ]] && rm_pkgs 2N/Aif [[ -z $failed && -n $OPT_U ]]; then 2N/A if (( $? != 0 )); then 2N/A# Migrate /export to the non-BE dataset(s). 2N/Avlog "$v_migrate_export" 2N/A/usr/sbin/zoneadm -z $ZONENAME halt 2N/Aif (( $? != 0 )); then 2N/A# Copy in sysidcfg file after zone is halted 2N/Aif [[ -n $sc_sysidcfg ]]; then 2N/A safe_copy $sc_sysidcfg $ZONEROOT/etc/sysidcfg 2N/Aif [[ -n $failed ]]; then