#!/bin/ksh -p # # # # # # # # # # # # # # # # # # # # # # Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. # # NOTE: this script runs in the global zone and touches the non-global # zone, so care should be taken to validate any modifications so that they # are safe. # # Only change PATH if you give full consideration to GNU or other variants # of common commands having different arguments and output. # export PATH=/usr/bin:/usr/sbin unset LD_LIBRARY_PATH . /usr/lib/brand/solaris/common.ksh # Allows developer to override some things like PATH and PYTHONPATH . /usr/lib/brand/solaris/developerenv.ksh v_change_var=$(gettext "Changing the pkg variant to nonglobal...") e_change_var=$(gettext "Changing the pkg variant to nonglobal failed") v_update=$(gettext "Updating the zone software to match the global zone...") e_badupdate=$(gettext "Updating the Zone software failed") f_missing_zone_zp=$(gettext "Missing zone or zonepath argument.") m_usage=$(gettext "/usr/lib/brand/solaris/p2v [-uv] [-c sysconfig] zone zonepath") set -A save_args "$0" "$@" PKG=pkg EXIT_CODE=$ZONE_SUBPROC_USAGE # Clean up on failure trap_exit() { if (( $ZONE_IS_MOUNTED != 0 )); then error "$v_unmount" zoneadm -z $ZONENAME unmount fi vlog "Exiting with exit code $EXIT_CODE" finish_log zone exit $EXIT_CODE } # # There are no physical links in a zone. The datalink.conf # file should be empty. # fix_datalink_conf() { # # If the file doesn't exist, that's fine. Just return. # [[ ! -f $ZONEROOT/etc/dladm/datalink.conf ]] && return # # Create an empty file and copy it so that the target file # retains its original ownership and permissions. # touch $ZONEROOT/etc/dladm/datalink.conf.empty || exit $EXIT_CODE cp $ZONEROOT/etc/dladm/datalink.conf.empty \ $ZONEROOT/etc/dladm/datalink.conf || exit $EXIT_CODE rm -f $ZONEROOT/etc/dladm/datalink.conf.empty || exit $EXIT_CODE } # # Comment out most of the old mounts since they are either unneeded or # likely incorrect within a zone. Specific mounts can be manually # reenabled if the corresponding device is added to the zone. # fix_vfstab() { if [[ -h $ZONEROOT/etc/vfstab || ! -f $ZONEROOT/etc/vfstab ]]; then error "$e_badfile" "/etc/vfstab" return fi tmpfile=$(mktemp -t) if [[ -z "$tmpfile" ]]; then error "$e_tmpfile" return fi nawk '{ if (substr($1, 0, 1) == "#") { print $0 } else if ($1 == "fd" || $1 == "/proc" || $1 == "swap" || $1 == "ctfs" || $1 == "objfs" || $1 == "sharefs" || $4 == "nfs" || $4 == "lofs") { print $0 } else { print "#", $0 modified=1 } } END { if (modified == 1) { printf("# Modified by p2v ") system("/usr/bin/date") exit 0 } exit 1 }' $ZONEROOT/etc/vfstab >>$tmpfile if (( $? == 0 )); then if [[ ! -f $ZONEROOT/etc/vfstab.pre_p2v ]]; then safe_copy $ZONEROOT/etc/vfstab \ $ZONEROOT/etc/vfstab.pre_p2v fi safe_copy $tmpfile $ZONEROOT/etc/vfstab chown root:sys $ZONEROOT/etc/vfstab || \ fail_fatal "$f_chown" "$ZONEROOT/etc/vfstab" chmod 644 $ZONEROOT/etc/vfstab || \ fail_fatal "$f_chmod" "$ZONEROOT/etc/vfstab" fi rm -f $tmpfile } # # Delete or disable SMF services. # fix_smf() { SMF_UPGRADE=/a/var/svc/profile/upgrade # # Fix network services if shared stack. # if [[ "$STACK_TYPE" == "shared" ]]; then vlog "$v_fixnetsvcs" NETPHYSDEF="svc:/network/physical:default" NETPHYSNWAM="svc:/network/physical:nwam" vlog "$v_enblsvc" "$NETPHYSDEF" zlogin -S $ZONENAME "echo /usr/sbin/svcadm enable $NETPHYSDEF \ >>$SMF_UPGRADE" >$SMF_UPGRADE" >$SMF_UPGRADE" >$SMF_UPGRADE" /dev/null 2>&1 if (( $? != 0 )); then continue fi vlog "$v_rmpkg" "$i" zlogin -S $ZONENAME LC_ALL=C \ /usr/bin/pkg -R /a uninstall -r $i &2 || \ error "$e_rmpkg" $i done } # # Parse the command line options. # OPT_V= while getopts "v" opt do case "$opt" in v) # Used by vlog() OPT_V="-v" ;; *) fail_usage "" ;; esac done shift OPTIND-1 (( $# != 2 )) && fail_usage "$f_missing_zone_zp" # If fixing up the image fails, force an uninstall. EXIT_CODE=$ZONE_SUBPROC_FATAL init_zone zone "$1" "$2" eval $(bind_legacy_zone_globals zone) # # failure should unmount the zone if necessary; # ZONE_IS_MOUNTED=0 trap trap_exit EXIT start_log zone install "${save_args[@]}" # # Do some validation on the paths we'll be accessing # safe_dir etc safe_dir etc/dfs safe_dir etc/zones safe_dir var safe_dir var/log safe_dir var/pkg # If these paths exist, they must be directories. If they don't exist, # they will be created below. safe_opt_dir etc/svc safe_opt_dir system safe_opt_dir system/volatile # Now do the work to update the zone. # Before booting the zone we may need to create a few mnt points, just in # case they don't exist for some reason. # # Whenever we reach into the zone while running in the global zone we # need to validate that none of the interim directories are symlinks # that could cause us to inadvertently modify the global zone. vlog "$v_mkdirs" if [[ ! -f $ZONEROOT/tmp && ! -d $ZONEROOT/tmp ]]; then mkdir -m 1777 -p $ZONEROOT/tmp || exit $EXIT_CODE fi if [[ ! -h $ZONEROOT/etc && ! -f $ZONEROOT/etc/mnttab ]]; then touch $ZONEROOT/etc/mnttab || exit $EXIT_CODE chmod 444 $ZONEROOT/etc/mnttab || exit $EXIT_CODE fi if [[ ! -f $ZONEROOT/proc && ! -d $ZONEROOT/proc ]]; then mkdir -m 755 -p $ZONEROOT/proc || exit $EXIT_CODE fi if [[ ! -f $ZONEROOT/dev && ! -d $ZONEROOT/dev ]]; then mkdir -m 755 -p $ZONEROOT/dev || exit $EXIT_CODE fi if [[ ! -d $ZONEROOT/system/volatile ]]; then mkdir -m 755 -p $ZONEROOT/system/volatile || exit $EXIT_CODE fi # symlink: /etc/svc/volatile -> /system/volatile if [[ ! -d $ZONEROOT/etc/svc ]]; then mkdir -m 755 -p $ZONEROOT/etc/svc || exit $EXIT_CODE fi if [[ -e $ZONEROOT/etc/svc/volatile || -h $ZONEROOT/etc/svc/volatile ]]; then rm -rf $ZONEROOT/etc/svc/volatile || exit $EXIT_CODE fi ln -s ../../system/volatile $ZONEROOT/etc/svc/volatile # symlink: /var/run -> /system/volatile if [[ -e $ZONEROOT/var/run || -h $ZONEROOT/var/run ]]; then rm -rf $ZONEROOT/var/run || exit $EXIT_CODE fi ln -s ../system/volatile $ZONEROOT/var/run # Check for zones inside of image. warn_zones STACK_TYPE=$(zoneadm -z $ZONENAME list -p | nawk -F: '{print $7}') if (( $? != 0 )); then error "$e_badinfo" "stacktype" fi vlog "$v_stacktype" "$STACK_TYPE" # Note that we're doing this before update-on-attach has run. fix_vfstab # # Mount the zone so that we can do all of the updates needed on the zone. # vlog "$v_mounting" ZONE_IS_MOUNTED=1 zoneadm -z $ZONENAME mount -f || fatal "$e_badmount" # # Any errors in these functions are not considered fatal. The zone can be # be fixed up manually afterwards and it may need some additional manual # cleanup in any case. # log "$v_adjust" # cleanup datalink configuration fix_datalink_conf # cleanup SMF services fix_smf # remove invalid pkgs rm_pkgs # If anything below here fails, a subsequent attach can likely fix it up. EXIT_CODE=$ZONE_SUBPROC_UNAVAILABLE # # This is unintuitive: The call to 'zoneadm unmount' tears down the scratch # zone. Upon completion of 'zoneadm unmount' the zone is in the same state # that it would be in after 'zoneadm sysboot'. That is, brands other than # labeled have the complete active ZBE mounted on the zone root. # vlog "$v_unmount" zoneadm -z $ZONENAME unmount || fatal "$e_badunmount" ZONE_IS_MOUNTED=0 if is_brand_labeled; then # The labeled brand needs to mount the zone's root dataset back onto # ZONEROOT so we can finish processing. mount_active_be -C zone || fatal "$f_mount_active_be" fi # # Change the pkg variant from global zone to non-global zone. This assumes # that the caller has already: # - updated the image format # - refreshed the catalog in the zone's image # - set the pkg image property use-system-repo=true # log "$v_change_var" $PKG -R "$ZONEROOT" change-variant --no-refresh -I \ variant.opensolaris.zone=nonglobal || pkg_err_check "$e_change_var" trap - EXIT vlog "$v_exitgood" finish_log zone exit $ZONE_SUBPROC_OK