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) 2008, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A# Only change PATH if you give full consideration to GNU or other variants 2N/A# of common commands having different arguments and output. 2N/Asanity_fail_vers=
$(gettext " Sanity Check: the Solaris image (release %s) is not an OpenSolaris image and cannot be installed in this type of branded zone.") 2N/Af_zfs_unmount=
$(gettext "Unable to unmount the zone's root ZFS dataset (%s).\nIs there a global zone process inside the zone root?\nThe current zone boot environment will remain mounted.\n") 2N/A# Used by install and attach during argument processing 2N/Am_zbe_discover_header=
$(gettext "Zone Boot Environment Active Global Zone Boot Environment\n--------------------- ------ ------------------------------------") 2N/Af_osnet=
$(gettext "Could not find the osnet-incorporation package installed in image: %s") 2N/A # Check for some required directories. 2N/A # Check for existence of pkg command. 2N/A # XXX There should be a better way to do this. 2N/A # Check image release. We only work on the same minor release as the 2N/A # system is running. The INST_RELEASE file doesn't exist with IPS on 2N/A # OpenSolaris, so its presence means we have an earlier Solaris 2N/A # (i.e. non-OpenSolaris) image. 2N/A # If there is no alternate root (normal case) then set the 2N/A # global zone boot environment by finding the boot environment 2N/A # that is active now. 2N/A # If a zone exists in a boot environment mounted on an alternate root, 2N/A # then find the boot environment where the alternate root is mounted. 2N/A if (length(alt) == 0) { 2N/A # Field 3 is the BE status. "N" is the active BE. 2N/A # Field 4 is the BE mountpoint. 2N/A # Field 2 is the BE UUID 2N/A# Finds the active boot environment for the given zone. 2N/A# zone zone structure initialized with init_zone 2N/A# CURRENT_GZBE Current global zone boot environment. If not already set, 2N/A# 0 on success, else 1. 2N/A# If the zbe belongs to the existing gzbe or the zbe was extracted from an 2N/A# archive and has not yet been attached, set it as the active zbe. Otherwise, 2N/A# clone it and set the clone to the active zbe. 2N/A# EXIT_CODE On success, set as described in clone_zbe. 2N/A# Returns 0 on success, !0 on failure. 2N/A# clone_zbe [-u] zone zbe 2N/A# Clones a zbe within a zone and sets the new ZBE as the active BE for this 2N/A# Options and arguments: 2N/A# zone zone structure initialized with init_zone 2N/A# zbe Name of the zone boot environment to clone. 2N/A# EXIT_CODE On success, set to ZONE_SUBPROC_UNAVAILABLE. 2N/A# On failure, set as described in clone_zone_rpool. 2N/A# 0 Success, and members of the zone structure have been updated. 2N/A# the root of the zbe. 2N/A# zone.zbe_cloned_from Set to the name of the zbe passed in 2N/A# 1 Failure. Error message has been logged. 2N/A for (( i=0; i < 100; i++ )); do 2N/A if (( i == 100 )); then 2N/A # Clone, activate, and mount ZBE 2N/A # Sets EXIT_CODE. "zone" appears twice as it is the source and target. 2N/A# discover_active_be zone 2N/A# Looks for the ZBE that is best suited to be the active ZBE. 2N/A# The caller may optionally constrain the list of ZBEs that is considered for 2N/A# activation by populating the zone.allowed_bes associative array. In such a 2N/A# case, If zone.allowed_bes is a non-empty associative array, only BEs in that 2N/A# array are considered. 2N/A# After selecting which ZBE is the best candidate for activation, care will 2N/A# be taken not to "steal" the ZBE from another global zone. If the chosen 2N/A# zbe has $PROP_PARENT matching the UUID of an extant global zone BE, it is 2N/A# the chosen ZBE is cloned and this new clone is the ZBE that is selected for 2N/A# that was received from an archive and any existing values in $PROP_PARENT 2N/A# on these ZBEs are stale. 2N/A# zone A zone structure initialized with init_zone. 2N/A# EXIT_CODE ZONE_SUBPROC_UNAVAILABLE ZBE cloning was attempted 2N/A# ZONE_SUBPROC_FATAL ZBE cloning was attempted, 2N/A# failed, and cleanup failed. 2N/A# ZONE_SUBPROC_TRYAGAIN ZBE selection required. A 2N/A# list of available ZBEs was 2N/A# 0 Success. The discovered active_be has been activated (see 2N/A# set_active_be() for details) and has been mounted on the zone root. 2N/A# 1 Active dataset could not be found and an error message has been 2N/A # Load an associative array of global zone BEs. Store current uuid 2N/A # of GZBE in $active_gzbe. 2N/A # uuid2gzbe[<gzbe uuid>]=<gzbe name> 2N/A # Load an associative array of non-global zone BEs and arrays of 2N/A # likely candidates. 2N/A # ngzbe[<ngzbe name>].parent=<gzbe uuid> 2N/A # ngzbe[<ngzbe name>].active=<on|off|-> 2N/A # ngzbe[<ngzbe name>].mountpoint=</|zoneroot> 2N/A typeset -a this_gz # NGZ BEs that match this GZ BE 2N/A # skip the non-BE top-level dataset 2N/A # skip BEs that are not in the allowed_bes list 2N/A vlog "Ignoring dataset %s: %s not in allowed_bes" \ 2N/A # Update some arrays used in decision process. 2N/A # If there are no BEs, return an error 2N/A if (( ${#ngzbe[@]} == 0 )); then 2N/A # If there was only one ZBE active for this GZ, activate it. 2N/A if (( ${#this_gz_active[@]} == 1 )); then 2N/A # If there was only one ZBE associated with this GZ, activate it. 2N/A if (( ${#this_gz[@]} == 1 )); then 2N/A # If there was only one ZBE that was active, clone and/or activate it. 2N/A if (( ${#activezbe[@]} == 1 )); then 2N/A # If the zbe is not associated with any gzbe, do not clone it. 2N/A # If there was only one ZBE, clone and/or activate it 2N/A if (( ${#ngzbe[@]} == 1 )); then 2N/A # We really want the name of index 0, but a subscript of 0 2N/A # is not supported. Since we know that there is only one 2N/A # item in the associative array, the name of all the items 2N/A # is equivalent to the name of the first item. 2N/A # Install and attach need different messages. m_usage_dash_z should 2N/A # be defined in the brand's install and attach scripts. 2N/A if (( ${#ATTACH_Z_COMMAND[@]} != 0 )); then 2N/A# set_active_be zone bootenv 2N/A# Sets the active boot environment for the zone. This includes updating the 2N/A# zone structure and setting the required properties ($PROP_PARENT, 2N/A# $PROP_ACTIVE) on the top-level BE datasets. 2N/A # Turn off the active property on BE's with the same GZBE and ensure 2N/A # that there aren't any BE datasets that will mount automatically. 2N/A # skip the ROOT dataset 2N/A # The root of each BE should only be mounted explicitly. 2N/A # If this was extracted from an archive within this GZ, 2N/A # finish the association process. In the unlikely event 2N/A # that these property updates fail, manual cleanup may 2N/A # be required, but it should not prevent the attach. 2N/A # Setting the parent to this gzbe makes it possible 2N/A # for beadm to clean up the zbes within the zone 2N/A # once one of the candidate zbe's is attached. 2N/A # Deactivate BEs for this GZ that are not being set to active. 2N/A# Run system configuration inside a zone. 2N/A # Remove in case $sc_config_base is a directory 2N/A if (( $? != 0 )); then 2N/A# Emits to stdout the fmri for the supplied package, 2N/A# stripped of publisher name and other junk. 2N/A if (( $? != 0 )); then 2N/A# Emits to stdout the entire incorporation for this image, 2N/A# stripped of publisher name and other junk. 2N/A# Handle pkg exit code. Exit 0 means Command succeeded, exit 4 means 2N/A# No changes were made - nothing to do. Any other exit code is an error. 2N/A# msg Error message passed as argument to error function 2N/A# errfn Function to call if an error is detected. If not specified, 2N/A# fail_fatal is used. 2N/A# Enable the services needed to perform packaging operations inside a zone. 2N/A# tag_candidate_zbes ROOTdsn [be_array_name [curgz_assoc_array_name]] 2N/A# Tags each dataset that is a child of ROOTdsn with 2N/A# $PROP_CANDIDATE=$CURRENT_GZBE. 2N/A# ROOTdsn The name of a dataset that contains zbes. 2N/A# be_array_name If specified, this variable will contain an array 2N/A# of candidate zbes on return. 2N/A# curgz_assoc_array_name If specified and any zbes have $PROP_PARENT that 2N/A# matches $CURRENT_GZBE, curgz_assoc_array_name will 2N/A# contain that list. Otherwise, curgz_assoc_array_name 2N/A# will be updated to reflect all of the zbes found. Note 2N/A# that curgz_assoc_array_name is an associative (not 2N/A# indexed) array with keys that match the zbe name. The 2N/A# value assigned to each key is not significant. 2N/A# Returns 0 if there is at least one zbe found 2N/A# Returns 1 if there are no zbes or there is a failure updating properties. 2N/A if [[ -n $2 ]]; then 2N/A if [[ -n $3 ]]; then 2N/A # See if the zbe is already associated with the GZBE 2N/A if (( ${#bes[@]} == 0 )); then 2N/A # If there were no zbes that already had a parent of $CURRENT_GZBE, 2N/A # mark all of the found zbes as being allowed. 2N/A if (( ${#curgzbes[@]} == 0 )); then 2N/A# attach_image zone allow_update 2N/A# zone A zone reference, initialized by init_zone. A BE 2N/A# contain a GZ or NGZ pkg(5) image. 2N/A# allow_update One of "none", "min", or "all". 2N/A# none: No updates to the zone image are allowed. 2N/A# min: The mininal updates required to attach the 2N/A# zone are allowed. This includes updating 2N/A# the pkg(5) image format and satisfying 2N/A# parent dependencies. Corresponds to the 2N/A# default action of p2v (install <-a|-d>) 2N/A# and the historical -u option to attach. 2N/A# all: Like min, but updates all packages to the 2N/A# latest version that are compatible with the 2N/A# Side effects on global variables: 2N/A# PKG If not set on entry, set to pkg 2N/A# GZ_IMAGE If not set on entry, set to / 2N/A# PKG_CACHEROOT If not set on entry and a pkg(5) cache exists at 2N/A# to the environment. 2N/A# OPT_V If set, pkg(1) commands will be verbose. 2N/A# EXIT_CODE Not changed, but must be set. 2N/A# If it returns, all went well - the zone is attached. Otherwise, it fails. 2N/A # Sanity check arguments 2N/A # EXIT_CODE must be set for proper error handling 2N/A # get the current architecture. 2N/A # If there is a cache, use it. 2N/A # respect PKG_CACHEROOT if the caller has it set. 2N/A # pkg update-format doesn't allow a dry run or provide any other way to 2N/A # see if an update is needed. 2N/A # Set the use-system-repo property. 2N/A # Update that catalogs once, subsequent packaging operations will use 2N/A # --no-refresh to avoid unnecessary catalog checks and updates. If 2N/A # image updates are not allowed, there's no need to refresh the 2N/A # prevent attach of a image with a different architecture 2N/A # Attach the zone to the global zone as a linked image. This 2N/A # writes linked image metadata into the non-global zone which 2N/A # will constrain subsequent packaging operations (but only after 2N/A # the zone variant is set to nonglobal.) The attach operation is 2N/A # performed on the global zone image (and the pkg command will 2N/A # subsequently recurse into and modify the zone image). 2N/A set -A cmd $PKG -R "${GZ_IMAGE}" "${pkg_attach_args[@]}" \ 2N/A # get a list of fmris installed in the ngz image. 2N/A # Lookup the 'entire' incorporation in the global zone. We 2N/A # check for this because if the user has removed it then we'll 2N/A # want to remove it from the zone during attach. The reason is 2N/A # that we're unlikely to be able to attach a highly constrained 2N/A # zone (one that has entire installed) to a loosely constrained 2N/A # global zone (one that doesn't have entire installed). 2N/A # Lookup the 'osnet-incorporation' package in the global zone. 2N/A # We need this to do a manual sync check (and possible manual 2N/A # sync) of the zone. (and by manual we mean a sync that does 2N/A # not utilize the pkg linked image framework.) 2N/A # Lookup for the 'entire' incorporation in the non-global zone. 2N/A # Get the full package name and version. 2N/A # Lookup for the 'osnet-incorporation' package in the non-global zone. 2N/A # Get the full package name and version. 2N/A # get a list of incorporation fmris installed in the ngz image. 2N/A # we're done with the ngz list of packages 2N/A # check if the 'osnet-incorporation' package is in sync between 2N/A # before we do a manual sync, we need to make sure that 2N/A # images may not have this directory, which in turn will 2N/A # cause rem_drv and update_drv to fail (since they want 2N/A # to create lock files in that directory). 2N/A # prepare to try and manually sync the zone image 2N/A # if the gz doesn't have entire installed we need to 2N/A # remove it from the ngz during out sync. 2N/A # to manually sync the image we must relax all the image 2N/A # install holds. we do this by specifying the names of 2N/A # all the installed incorporations (excluding publisher 2N/A # and version numbers). 2N/A # strip version and publisher from the fmri 2N/A # if entire is not installed then we're going to 2N/A # try to sync the image by specifying a version 2N/A # of the osnet-incorporation, but older versions 2N/A # of the pkg client don't allow you to specify 2N/A # overlapping pkg patterns on the cli, so don't 2N/A # try to relax the osnet-incorporation if we're 2N/A # going to explicitly sync it. 2N/A # due to bugs in s11 fcs, it's possible that we 2N/A # may have the ldoms-incorporation installed on 2N/A # non-sparc machines (or nvidia-incorporation 2N/A # on non-i386 machines). if so we don't want to 2N/A # specify these packages on the command line. 2N/A # (since that would require them to be installed 2N/A # and as part of this image update the solver 2N/A # may want to remove them.) 2N/A # relax this incorporation 2N/A # entire is installed in the gz and ngz, so sync that. 2N/A # we're in one of the following three cases: 2N/A # 1) entire is installed in the gz but not in 2N/A # 2) entire is not installed in the gz but is in 2N/A # the ngz (it will be rejected from the ngz). 2N/A # 3) entire is not installed in the gz or ngz 2N/A # in all these cases we must sync osnet-incorporation 2N/A # try to manually sync the image. 2N/A # If the image is a global zone and updates are allowed, do p2v. 2N/A # We can't change the variant if updates aren't allowed. 2N/A # Pass the p2v exit code up to zoneadm 2N/A # Assemble the arguments to sync the zone image 2N/A # $f_update_required advises the use of -u or -U. It should 2N/A # only be used with attach, as -u means something different 2N/A # with install. install will only have "min" or "all" as 2N/A # values for allow_update. 2N/A # Sync the zone image.