112199Sgerald.jelinek@sun.com# 212199Sgerald.jelinek@sun.com# CDDL HEADER START 312199Sgerald.jelinek@sun.com# 412199Sgerald.jelinek@sun.com# The contents of this file are subject to the terms of the 512199Sgerald.jelinek@sun.com# Common Development and Distribution License (the "License"). 612199Sgerald.jelinek@sun.com# You may not use this file except in compliance with the License. 712199Sgerald.jelinek@sun.com# 812199Sgerald.jelinek@sun.com# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 912199Sgerald.jelinek@sun.com# or http://www.opensolaris.org/os/licensing. 1012199Sgerald.jelinek@sun.com# See the License for the specific language governing permissions 1112199Sgerald.jelinek@sun.com# and limitations under the License. 1212199Sgerald.jelinek@sun.com# 1312199Sgerald.jelinek@sun.com# When distributing Covered Code, include this CDDL HEADER in each 1412199Sgerald.jelinek@sun.com# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1512199Sgerald.jelinek@sun.com# If applicable, add the following below this CDDL HEADER, with the 1612199Sgerald.jelinek@sun.com# fields enclosed by brackets "[]" replaced with your own identifying 1712199Sgerald.jelinek@sun.com# information: Portions Copyright [yyyy] [name of copyright owner] 1812199Sgerald.jelinek@sun.com# 1912199Sgerald.jelinek@sun.com# CDDL HEADER END 2012199Sgerald.jelinek@sun.com# 2112734Sgary.pennington@oracle.com# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 2212199Sgerald.jelinek@sun.com# 2312199Sgerald.jelinek@sun.com 2412199Sgerald.jelinek@sun.com# 2512199Sgerald.jelinek@sun.com# Send the error message to the screen and to the logfile. 2612199Sgerald.jelinek@sun.com# 2712199Sgerald.jelinek@sun.comerror() 2812199Sgerald.jelinek@sun.com{ 2912199Sgerald.jelinek@sun.com typeset fmt="$1" 3012199Sgerald.jelinek@sun.com shift 3112199Sgerald.jelinek@sun.com 3212199Sgerald.jelinek@sun.com printf "${MSG_PREFIX}ERROR: ${fmt}\n" "$@" 3312199Sgerald.jelinek@sun.com [[ -n $LOGFILE ]] && printf "[$(date)] ERROR: ${fmt}\n" "$@" >&2 3412199Sgerald.jelinek@sun.com} 3512199Sgerald.jelinek@sun.com 3612199Sgerald.jelinek@sun.comfatal() 3712199Sgerald.jelinek@sun.com{ 3812199Sgerald.jelinek@sun.com typeset fmt="$1" 3912199Sgerald.jelinek@sun.com shift 4012199Sgerald.jelinek@sun.com 4112199Sgerald.jelinek@sun.com error "$fmt" "$@" 4212199Sgerald.jelinek@sun.com exit $EXIT_CODE 4312199Sgerald.jelinek@sun.com} 4412199Sgerald.jelinek@sun.com 4512199Sgerald.jelinek@sun.comfail_fatal() { 46*12773Sgerald.jelinek@sun.com typeset fmt="$1" 47*12773Sgerald.jelinek@sun.com shift 48*12773Sgerald.jelinek@sun.com 49*12773Sgerald.jelinek@sun.com error "$fmt" "$@" 5012199Sgerald.jelinek@sun.com exit $ZONE_SUBPROC_FATAL 5112199Sgerald.jelinek@sun.com} 5212199Sgerald.jelinek@sun.com 5312199Sgerald.jelinek@sun.com# 5412199Sgerald.jelinek@sun.com# Send the provided printf()-style arguments to the screen and to the logfile. 5512199Sgerald.jelinek@sun.com# 5612199Sgerald.jelinek@sun.comlog() 5712199Sgerald.jelinek@sun.com{ 5812199Sgerald.jelinek@sun.com typeset fmt="$1" 5912199Sgerald.jelinek@sun.com shift 6012199Sgerald.jelinek@sun.com 6112199Sgerald.jelinek@sun.com printf "${MSG_PREFIX}${fmt}\n" "$@" 6212199Sgerald.jelinek@sun.com [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2 6312199Sgerald.jelinek@sun.com} 6412199Sgerald.jelinek@sun.com 6512199Sgerald.jelinek@sun.com# 6612199Sgerald.jelinek@sun.com# Print provided text to the screen if the shell variable "OPT_V" is set. 6712199Sgerald.jelinek@sun.com# The text is always sent to the logfile. 6812199Sgerald.jelinek@sun.com# 6912199Sgerald.jelinek@sun.comvlog() 7012199Sgerald.jelinek@sun.com{ 7112199Sgerald.jelinek@sun.com typeset fmt="$1" 7212199Sgerald.jelinek@sun.com shift 7312199Sgerald.jelinek@sun.com 7412199Sgerald.jelinek@sun.com [[ -n $OPT_V ]] && printf "${MSG_PREFIX}${fmt}\n" "$@" 7512199Sgerald.jelinek@sun.com [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2 7612199Sgerald.jelinek@sun.com} 7712199Sgerald.jelinek@sun.com 7812199Sgerald.jelinek@sun.com# 7912199Sgerald.jelinek@sun.com# Validate that the directory is safe. 8012199Sgerald.jelinek@sun.com# 8112199Sgerald.jelinek@sun.com# It is possible for a malicious zone root user to modify a zone's filesystem 8212199Sgerald.jelinek@sun.com# so that modifications made to the zone's filesystem by administrators in the 8312199Sgerald.jelinek@sun.com# global zone modify the global zone's filesystem. We can prevent this by 8412199Sgerald.jelinek@sun.com# ensuring that all components of paths accessed by scripts are real (i.e., 8512199Sgerald.jelinek@sun.com# non-symlink) directories. 8612199Sgerald.jelinek@sun.com# 8712199Sgerald.jelinek@sun.com# NOTE: The specified path should be an absolute path as would be seen from 8812199Sgerald.jelinek@sun.com# within the zone. Also, this function does not check parent directories. 8912199Sgerald.jelinek@sun.com# If, for example, you need to ensure that every component of the path 9012199Sgerald.jelinek@sun.com# '/foo/bar/baz' is a directory and not a symlink, then do the following: 9112199Sgerald.jelinek@sun.com# 9212199Sgerald.jelinek@sun.com# safe_dir /foo 9312199Sgerald.jelinek@sun.com# safe_dir /foo/bar 9412199Sgerald.jelinek@sun.com# safe_dir /foo/bar/baz 9512199Sgerald.jelinek@sun.com# 9612199Sgerald.jelinek@sun.comsafe_dir() 9712199Sgerald.jelinek@sun.com{ 9812199Sgerald.jelinek@sun.com typeset dir="$1" 9912199Sgerald.jelinek@sun.com 10012199Sgerald.jelinek@sun.com if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then 10112199Sgerald.jelinek@sun.com fatal "$e_baddir" "$dir" 10212199Sgerald.jelinek@sun.com fi 10312199Sgerald.jelinek@sun.com} 10412199Sgerald.jelinek@sun.com 10512199Sgerald.jelinek@sun.com# Like safe_dir except the dir doesn't have to exist. 10612199Sgerald.jelinek@sun.comsafe_opt_dir() 10712199Sgerald.jelinek@sun.com{ 10812199Sgerald.jelinek@sun.com typeset dir="$1" 10912199Sgerald.jelinek@sun.com 11012199Sgerald.jelinek@sun.com [[ ! -e $ZONEROOT/$dir ]] && return 11112199Sgerald.jelinek@sun.com 11212199Sgerald.jelinek@sun.com if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then 11312199Sgerald.jelinek@sun.com fatal "$e_baddir" "$dir" 11412199Sgerald.jelinek@sun.com fi 11512199Sgerald.jelinek@sun.com} 11612199Sgerald.jelinek@sun.com 11712199Sgerald.jelinek@sun.com# Only make a copy if we haven't already done so. 11812199Sgerald.jelinek@sun.comsafe_backup() 11912199Sgerald.jelinek@sun.com{ 12012199Sgerald.jelinek@sun.com typeset src="$1" 12112199Sgerald.jelinek@sun.com typeset dst="$2" 12212199Sgerald.jelinek@sun.com 12312199Sgerald.jelinek@sun.com if [[ ! -h $src && ! -h $dst && ! -d $dst && ! -f $dst ]]; then 12412199Sgerald.jelinek@sun.com /usr/bin/cp -p $src $dst || fatal "$e_badfile" "$src" 12512199Sgerald.jelinek@sun.com fi 12612199Sgerald.jelinek@sun.com} 12712199Sgerald.jelinek@sun.com 12812199Sgerald.jelinek@sun.com# Make a copy even if the destination already exists. 12912199Sgerald.jelinek@sun.comsafe_copy() 13012199Sgerald.jelinek@sun.com{ 13112199Sgerald.jelinek@sun.com typeset src="$1" 13212199Sgerald.jelinek@sun.com typeset dst="$2" 13312199Sgerald.jelinek@sun.com 13412199Sgerald.jelinek@sun.com if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then 13512199Sgerald.jelinek@sun.com /usr/bin/cp -p $src $dst || fatal "$e_badfile" "$src" 13612199Sgerald.jelinek@sun.com fi 13712199Sgerald.jelinek@sun.com} 13812199Sgerald.jelinek@sun.com 13912199Sgerald.jelinek@sun.com# Move a file 14012199Sgerald.jelinek@sun.comsafe_move() 14112199Sgerald.jelinek@sun.com{ 14212199Sgerald.jelinek@sun.com typeset src="$1" 14312199Sgerald.jelinek@sun.com typeset dst="$2" 14412199Sgerald.jelinek@sun.com 14512199Sgerald.jelinek@sun.com if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then 14612199Sgerald.jelinek@sun.com /usr/bin/mv $src $dst || fatal "$e_badfile" "$src" 14712199Sgerald.jelinek@sun.com fi 14812199Sgerald.jelinek@sun.com} 14912199Sgerald.jelinek@sun.com 15012199Sgerald.jelinek@sun.comsafe_rm() 15112199Sgerald.jelinek@sun.com{ 15212199Sgerald.jelinek@sun.com if [[ ! -h $ZONEROOT/$1 && -f $ZONEROOT/$1 ]]; then 15312199Sgerald.jelinek@sun.com rm -f "$ZONEROOT/$1" 15412199Sgerald.jelinek@sun.com fi 15512199Sgerald.jelinek@sun.com} 15612199Sgerald.jelinek@sun.com 15712199Sgerald.jelinek@sun.com# 15812199Sgerald.jelinek@sun.com# Replace the file with a wrapper pointing to the native brand code. 15912199Sgerald.jelinek@sun.com# However, we only do the replacement if the file hasn't already been 16012199Sgerald.jelinek@sun.com# replaced with our wrapper. This function expects the cwd to be the 16112199Sgerald.jelinek@sun.com# location of the file we're replacing. 16212199Sgerald.jelinek@sun.com# 16312199Sgerald.jelinek@sun.com# Some of the files we're replacing are hardlinks to isaexec so we need to 'rm' 16412199Sgerald.jelinek@sun.com# the file before we setup the wrapper while others are hardlinks to rc scripts 16512199Sgerald.jelinek@sun.com# that we need to maintain. 16612199Sgerald.jelinek@sun.com# 16712199Sgerald.jelinek@sun.comsafe_replace() 16812199Sgerald.jelinek@sun.com{ 16912199Sgerald.jelinek@sun.com typeset filename="$1" 17012199Sgerald.jelinek@sun.com typeset runname="$2" 17112199Sgerald.jelinek@sun.com typeset mode="$3" 17212199Sgerald.jelinek@sun.com typeset own="$4" 17312199Sgerald.jelinek@sun.com typeset rem="$5" 17412199Sgerald.jelinek@sun.com 17512199Sgerald.jelinek@sun.com if [ -h $filename -o ! -f $filename ]; then 17612199Sgerald.jelinek@sun.com return 17712199Sgerald.jelinek@sun.com fi 17812199Sgerald.jelinek@sun.com 17912199Sgerald.jelinek@sun.com egrep -s "Solaris Brand Replacement" $filename 18012199Sgerald.jelinek@sun.com if [ $? -eq 0 ]; then 18112199Sgerald.jelinek@sun.com return 18212199Sgerald.jelinek@sun.com fi 18312199Sgerald.jelinek@sun.com 18412199Sgerald.jelinek@sun.com safe_backup $filename $filename.pre_p2v 18512199Sgerald.jelinek@sun.com if [ $rem = "remove" ]; then 18612199Sgerald.jelinek@sun.com rm -f $filename 18712199Sgerald.jelinek@sun.com fi 18812199Sgerald.jelinek@sun.com 18912199Sgerald.jelinek@sun.com cat <<-END >$filename || exit 1 19012651Sgerald.jelinek@sun.com #!/bin/sh -p 19112199Sgerald.jelinek@sun.com # 19212199Sgerald.jelinek@sun.com # Solaris Brand Replacement 19312199Sgerald.jelinek@sun.com # 19412199Sgerald.jelinek@sun.com # Attention. This file has been replaced with a new version for 19512199Sgerald.jelinek@sun.com # use in a virtualized environment. Modification of this script is not 19612199Sgerald.jelinek@sun.com # supported and all changes will be lost upon reboot. The 19712199Sgerald.jelinek@sun.com # {name}.pre_p2v version of this file is a backup copy of the 19812199Sgerald.jelinek@sun.com # original and should not be deleted. 19912199Sgerald.jelinek@sun.com # 20012199Sgerald.jelinek@sun.com END 20112199Sgerald.jelinek@sun.com 20212199Sgerald.jelinek@sun.com echo ". $runname \"\$@\"" >>$filename || exit 1 20312199Sgerald.jelinek@sun.com 20412199Sgerald.jelinek@sun.com chmod $mode $filename 20512199Sgerald.jelinek@sun.com chown $own $filename 20612199Sgerald.jelinek@sun.com} 20712199Sgerald.jelinek@sun.com 20812199Sgerald.jelinek@sun.comsafe_wrap() 20912199Sgerald.jelinek@sun.com{ 21012199Sgerald.jelinek@sun.com typeset filename="$1" 21112199Sgerald.jelinek@sun.com typeset runname="$2" 21212199Sgerald.jelinek@sun.com typeset mode="$3" 21312199Sgerald.jelinek@sun.com typeset own="$4" 21412199Sgerald.jelinek@sun.com 21512199Sgerald.jelinek@sun.com if [ -f $filename ]; then 21612199Sgerald.jelinek@sun.com log "$e_cannot_wrap" "$filename" 21712199Sgerald.jelinek@sun.com exit 1 21812199Sgerald.jelinek@sun.com fi 21912199Sgerald.jelinek@sun.com 22012199Sgerald.jelinek@sun.com cat <<-END >$filename || exit 1 22112199Sgerald.jelinek@sun.com #!/bin/sh 22212199Sgerald.jelinek@sun.com # 22312199Sgerald.jelinek@sun.com # Solaris Brand Wrapper 22412199Sgerald.jelinek@sun.com # 22512199Sgerald.jelinek@sun.com # Attention. This file has been created for use in a 22612199Sgerald.jelinek@sun.com # virtualized environment. Modification of this script 22712199Sgerald.jelinek@sun.com # is not supported and all changes will be lost upon reboot. 22812199Sgerald.jelinek@sun.com # 22912199Sgerald.jelinek@sun.com END 23012199Sgerald.jelinek@sun.com 23112199Sgerald.jelinek@sun.com echo ". $runname \"\$@\"" >>$filename || exit 1 23212199Sgerald.jelinek@sun.com 23312199Sgerald.jelinek@sun.com chmod $mode $filename 23412199Sgerald.jelinek@sun.com chown $own $filename 23512199Sgerald.jelinek@sun.com} 23612199Sgerald.jelinek@sun.com 23712199Sgerald.jelinek@sun.com# 23812734Sgary.pennington@oracle.com# Read zonecfg fs entries and save the relevant data, one entry per 23912199Sgerald.jelinek@sun.com# line. 24012199Sgerald.jelinek@sun.com# This assumes the properties from the zonecfg output, e.g.: 24112199Sgerald.jelinek@sun.com# fs: 24212199Sgerald.jelinek@sun.com# dir: /opt 24312199Sgerald.jelinek@sun.com# special: /opt 24412199Sgerald.jelinek@sun.com# raw not specified 24512199Sgerald.jelinek@sun.com# type: lofs 24612199Sgerald.jelinek@sun.com# options: [noexec,ro,noatime] 24712199Sgerald.jelinek@sun.com# 24812734Sgary.pennington@oracle.com# and it assumes the order of the fs properties as above. 24912199Sgerald.jelinek@sun.com# 25012199Sgerald.jelinek@sun.comget_fs_info() 25112199Sgerald.jelinek@sun.com{ 25212199Sgerald.jelinek@sun.com zonecfg -z $zonename info fs | nawk '{ 25312199Sgerald.jelinek@sun.com if ($1 == "options:") { 25412199Sgerald.jelinek@sun.com # Remove brackets. 25512199Sgerald.jelinek@sun.com options=substr($2, 2, length($2) - 2); 25612199Sgerald.jelinek@sun.com printf("%s %s %s %s\n", dir, type, special, options); 25712199Sgerald.jelinek@sun.com } else if ($1 == "dir:") { 25812199Sgerald.jelinek@sun.com dir=$2; 25912199Sgerald.jelinek@sun.com } else if ($1 == "special:") { 26012199Sgerald.jelinek@sun.com special=$2; 26112199Sgerald.jelinek@sun.com } else if ($1 == "type:") { 26212199Sgerald.jelinek@sun.com type=$2 26312199Sgerald.jelinek@sun.com } 26412199Sgerald.jelinek@sun.com }' >> $fstmpfile 26512199Sgerald.jelinek@sun.com} 26612199Sgerald.jelinek@sun.com 26712199Sgerald.jelinek@sun.com# 26812199Sgerald.jelinek@sun.com# Mount zonecfg fs entries into the zonepath. 26912199Sgerald.jelinek@sun.com# 27012199Sgerald.jelinek@sun.commnt_fs() 27112199Sgerald.jelinek@sun.com{ 27212199Sgerald.jelinek@sun.com if [ ! -s $fstmpfile ]; then 27312199Sgerald.jelinek@sun.com return; 27412199Sgerald.jelinek@sun.com fi 27512199Sgerald.jelinek@sun.com 27612199Sgerald.jelinek@sun.com # Sort the fs entries so we can handle nested mounts. 27712199Sgerald.jelinek@sun.com sort $fstmpfile | nawk -v zonepath=$zonepath '{ 27812199Sgerald.jelinek@sun.com if (NF == 4) 27912199Sgerald.jelinek@sun.com options="-o " $4; 28012199Sgerald.jelinek@sun.com else 28112199Sgerald.jelinek@sun.com options="" 28212199Sgerald.jelinek@sun.com 28312199Sgerald.jelinek@sun.com # Create the mount point. Ignore errors since we might have 28412199Sgerald.jelinek@sun.com # a nested mount with a pre-existing mount point. 28512199Sgerald.jelinek@sun.com cmd="/usr/bin/mkdir -p " zonepath "/root" $1 " >/dev/null 2>&1" 28612199Sgerald.jelinek@sun.com system(cmd); 28712199Sgerald.jelinek@sun.com 28812199Sgerald.jelinek@sun.com cmd="/usr/sbin/mount -F " $2 " " options " " $3 " " \ 28912199Sgerald.jelinek@sun.com zonepath "/root" $1; 29012199Sgerald.jelinek@sun.com if (system(cmd) != 0) { 29112199Sgerald.jelinek@sun.com printf("command failed: %s\n", cmd); 29212199Sgerald.jelinek@sun.com exit 1; 29312199Sgerald.jelinek@sun.com } 29412199Sgerald.jelinek@sun.com }' >>$LOGFILE 29512199Sgerald.jelinek@sun.com} 29612199Sgerald.jelinek@sun.com 29712199Sgerald.jelinek@sun.com# 29812199Sgerald.jelinek@sun.com# Unmount zonecfg fs entries from the zonepath. 29912199Sgerald.jelinek@sun.com# 30012199Sgerald.jelinek@sun.comumnt_fs() 30112199Sgerald.jelinek@sun.com{ 30212199Sgerald.jelinek@sun.com if [ ! -s $fstmpfile ]; then 30312199Sgerald.jelinek@sun.com return; 30412199Sgerald.jelinek@sun.com fi 30512199Sgerald.jelinek@sun.com 30612199Sgerald.jelinek@sun.com # Reverse sort the fs entries so we can handle nested unmounts. 30712199Sgerald.jelinek@sun.com sort -r $fstmpfile | nawk -v zonepath=$zonepath '{ 30812199Sgerald.jelinek@sun.com cmd="/usr/sbin/umount " zonepath "/root" $1 30912199Sgerald.jelinek@sun.com if (system(cmd) != 0) { 31012199Sgerald.jelinek@sun.com printf("command failed: %s\n", cmd); 31112199Sgerald.jelinek@sun.com } 31212199Sgerald.jelinek@sun.com }' >>$LOGFILE 31312199Sgerald.jelinek@sun.com} 31412199Sgerald.jelinek@sun.com 31512199Sgerald.jelinek@sun.com# Find the dataset mounted on the zonepath. 31612199Sgerald.jelinek@sun.comget_zonepath_ds() { 31712199Sgerald.jelinek@sun.com ZONEPATH_DS=`/usr/sbin/zfs list -H -t filesystem -o name,mountpoint | \ 31812199Sgerald.jelinek@sun.com /usr/bin/nawk -v zonepath=$1 '{ 31912199Sgerald.jelinek@sun.com if ($2 == zonepath) 32012199Sgerald.jelinek@sun.com print $1 32112199Sgerald.jelinek@sun.com }'` 32212199Sgerald.jelinek@sun.com 32312199Sgerald.jelinek@sun.com if [ -z "$ZONEPATH_DS" ]; then 32412199Sgerald.jelinek@sun.com fail_fatal "$f_no_ds" 32512199Sgerald.jelinek@sun.com fi 32612199Sgerald.jelinek@sun.com} 32712199Sgerald.jelinek@sun.com 32812199Sgerald.jelinek@sun.com# 329*12773Sgerald.jelinek@sun.com# Perform validation and cleanup in the zoneroot after unpacking the archive. 33012199Sgerald.jelinek@sun.com# 33112199Sgerald.jelinek@sun.compost_unpack() 33212199Sgerald.jelinek@sun.com{ 333*12773Sgerald.jelinek@sun.com # 334*12773Sgerald.jelinek@sun.com # Check if the image was created with a valid libc.so.1. 335*12773Sgerald.jelinek@sun.com # 336*12773Sgerald.jelinek@sun.com hwcap=`moe -v -32 $ZONEROOT/lib/libc.so.1 2>&1` 337*12773Sgerald.jelinek@sun.com if (( $? != 0 )); then 338*12773Sgerald.jelinek@sun.com vlog "$f_hwcap_info" "$hwcap" 339*12773Sgerald.jelinek@sun.com fail_fatal "$f_sanity_hwcap" 340*12773Sgerald.jelinek@sun.com fi 341*12773Sgerald.jelinek@sun.com 34212199Sgerald.jelinek@sun.com ( cd "$ZONEROOT" && \ 34312199Sgerald.jelinek@sun.com find . \( -type b -o -type c \) -exec rm -f "{}" \; ) 34412199Sgerald.jelinek@sun.com} 34512199Sgerald.jelinek@sun.com 34612199Sgerald.jelinek@sun.com# 34712199Sgerald.jelinek@sun.com# Determine flar compression style from identification file. 34812199Sgerald.jelinek@sun.com# 34912199Sgerald.jelinek@sun.comget_compression() 35012199Sgerald.jelinek@sun.com{ 35112199Sgerald.jelinek@sun.com typeset ident=$1 35212199Sgerald.jelinek@sun.com typeset line=$(grep "^files_compressed_method=" $ident) 35312199Sgerald.jelinek@sun.com 35412199Sgerald.jelinek@sun.com print ${line##*=} 35512199Sgerald.jelinek@sun.com} 35612199Sgerald.jelinek@sun.com 35712199Sgerald.jelinek@sun.com# 35812199Sgerald.jelinek@sun.com# Determine flar archive style from identification file. 35912199Sgerald.jelinek@sun.com# 36012199Sgerald.jelinek@sun.comget_archiver() 36112199Sgerald.jelinek@sun.com{ 36212199Sgerald.jelinek@sun.com typeset ident=$1 36312199Sgerald.jelinek@sun.com typeset line=$(grep "^files_archived_method=" $ident) 36412199Sgerald.jelinek@sun.com 36512199Sgerald.jelinek@sun.com print ${line##*=} 36612199Sgerald.jelinek@sun.com} 36712199Sgerald.jelinek@sun.com 36812199Sgerald.jelinek@sun.com# 36912199Sgerald.jelinek@sun.com# Unpack flar into current directory (which should be zoneroot). The flash 37012199Sgerald.jelinek@sun.com# archive is standard input. See flash_archive(4) man page. 37112199Sgerald.jelinek@sun.com# 37212199Sgerald.jelinek@sun.com# We can't use "flar split" since it will only unpack into a directory called 37312199Sgerald.jelinek@sun.com# "archive". We need to unpack in place in order to properly handle nested 37412199Sgerald.jelinek@sun.com# fs mounts within the zone root. This function does the unpacking into the 37512199Sgerald.jelinek@sun.com# current directory. 37612199Sgerald.jelinek@sun.com# 37712199Sgerald.jelinek@sun.com# This code is derived from the gen_split() function in /usr/sbin/flar so 37812199Sgerald.jelinek@sun.com# we keep the same style as the original. 37912199Sgerald.jelinek@sun.com# 38012199Sgerald.jelinek@sun.cominstall_flar() 38112199Sgerald.jelinek@sun.com{ 38212199Sgerald.jelinek@sun.com typeset result 38312199Sgerald.jelinek@sun.com typeset archiver_command 38412199Sgerald.jelinek@sun.com typeset archiver_arguments 38512199Sgerald.jelinek@sun.com 38612199Sgerald.jelinek@sun.com vlog "cd $ZONEROOT && $stage1 "$insrc" | install_flar" 38712199Sgerald.jelinek@sun.com 38812199Sgerald.jelinek@sun.com # Read cookie 38912199Sgerald.jelinek@sun.com read -r input_line 39012199Sgerald.jelinek@sun.com if (( $? != 0 )); then 39112199Sgerald.jelinek@sun.com log "$not_readable" "$install_media" 39212199Sgerald.jelinek@sun.com return 1 39312199Sgerald.jelinek@sun.com fi 39412199Sgerald.jelinek@sun.com # The cookie has format FlAsH-aRcHiVe-m.n where m and n are integers. 39512199Sgerald.jelinek@sun.com if [[ ${input_line%%-[0-9]*.[0-9]*} != "FlAsH-aRcHiVe" ]]; then 39612199Sgerald.jelinek@sun.com log "$not_flar" 39712199Sgerald.jelinek@sun.com return 1 39812199Sgerald.jelinek@sun.com fi 39912199Sgerald.jelinek@sun.com 40012199Sgerald.jelinek@sun.com while [ true ] 40112199Sgerald.jelinek@sun.com do 40212199Sgerald.jelinek@sun.com # We should always be at the start of a section here 40312199Sgerald.jelinek@sun.com read -r input_line 40412199Sgerald.jelinek@sun.com if [[ ${input_line%%=*} != "section_begin" ]]; then 40512199Sgerald.jelinek@sun.com log "$bad_flar" 40612199Sgerald.jelinek@sun.com return 1 40712199Sgerald.jelinek@sun.com fi 40812199Sgerald.jelinek@sun.com section_name=${input_line##*=} 40912199Sgerald.jelinek@sun.com 41012199Sgerald.jelinek@sun.com # If we're at the archive, we're done skipping sections. 41112199Sgerald.jelinek@sun.com if [[ "$section_name" == "archive" ]]; then 41212199Sgerald.jelinek@sun.com break 41312199Sgerald.jelinek@sun.com fi 41412199Sgerald.jelinek@sun.com 41512199Sgerald.jelinek@sun.com # 41612199Sgerald.jelinek@sun.com # Save identification section to a file so we can determine 41712199Sgerald.jelinek@sun.com # how to unpack the archive. 41812199Sgerald.jelinek@sun.com # 41912199Sgerald.jelinek@sun.com if [[ "$section_name" == "identification" ]]; then 42012199Sgerald.jelinek@sun.com /usr/bin/rm -f identification 42112199Sgerald.jelinek@sun.com while read -r input_line 42212199Sgerald.jelinek@sun.com do 42312199Sgerald.jelinek@sun.com if [[ ${input_line%%=*} == \ 42412199Sgerald.jelinek@sun.com "section_begin" ]]; then 42512199Sgerald.jelinek@sun.com /usr/bin/rm -f identification 42612199Sgerald.jelinek@sun.com log "$bad_flar" 42712199Sgerald.jelinek@sun.com return 1 42812199Sgerald.jelinek@sun.com fi 42912199Sgerald.jelinek@sun.com 43012199Sgerald.jelinek@sun.com if [[ $input_line == \ 43112199Sgerald.jelinek@sun.com "section_end=$section_name" ]]; then 43212199Sgerald.jelinek@sun.com break; 43312199Sgerald.jelinek@sun.com fi 43412199Sgerald.jelinek@sun.com echo $input_line >> identification 43512199Sgerald.jelinek@sun.com done 43612199Sgerald.jelinek@sun.com 43712199Sgerald.jelinek@sun.com continue 43812199Sgerald.jelinek@sun.com fi 43912199Sgerald.jelinek@sun.com 44012199Sgerald.jelinek@sun.com # 44112199Sgerald.jelinek@sun.com # Otherwise skip past this section; read lines until detecting 44212199Sgerald.jelinek@sun.com # section_end. According to flash_archive(4) we can have 44312199Sgerald.jelinek@sun.com # an arbitrary number of sections but the archive section 44412199Sgerald.jelinek@sun.com # must be last. 44512199Sgerald.jelinek@sun.com # 44612199Sgerald.jelinek@sun.com success=0 44712199Sgerald.jelinek@sun.com while read -r input_line 44812199Sgerald.jelinek@sun.com do 44912199Sgerald.jelinek@sun.com if [[ $input_line == "section_end=$section_name" ]]; 45012199Sgerald.jelinek@sun.com then 45112199Sgerald.jelinek@sun.com success=1 45212199Sgerald.jelinek@sun.com break 45312199Sgerald.jelinek@sun.com fi 45412199Sgerald.jelinek@sun.com # Fail if we miss the end of the section 45512199Sgerald.jelinek@sun.com if [[ ${input_line%%=*} == "section_begin" ]]; then 45612199Sgerald.jelinek@sun.com /usr/bin/rm -f identification 45712199Sgerald.jelinek@sun.com log "$bad_flar" 45812199Sgerald.jelinek@sun.com return 1 45912199Sgerald.jelinek@sun.com fi 46012199Sgerald.jelinek@sun.com done 46112199Sgerald.jelinek@sun.com if (( $success == 0 )); then 46212199Sgerald.jelinek@sun.com # 46312199Sgerald.jelinek@sun.com # If we get here we read to the end of the file before 46412199Sgerald.jelinek@sun.com # seeing the end of the section we were reading. 46512199Sgerald.jelinek@sun.com # 46612199Sgerald.jelinek@sun.com /usr/bin/rm -f identification 46712199Sgerald.jelinek@sun.com log "$bad_flar" 46812199Sgerald.jelinek@sun.com return 1 46912199Sgerald.jelinek@sun.com fi 47012199Sgerald.jelinek@sun.com done 47112199Sgerald.jelinek@sun.com 47212199Sgerald.jelinek@sun.com # Check for an archive made from a ZFS root pool. 47312199Sgerald.jelinek@sun.com egrep -s "^rootpool=" identification 47412199Sgerald.jelinek@sun.com if (( $? == 0 )); then 47512199Sgerald.jelinek@sun.com /usr/bin/rm -f identification 47612199Sgerald.jelinek@sun.com log "$bad_zfs_flar" 47712199Sgerald.jelinek@sun.com return 1 47812199Sgerald.jelinek@sun.com fi 47912199Sgerald.jelinek@sun.com 48012199Sgerald.jelinek@sun.com # Get the information needed to unpack the archive. 48112199Sgerald.jelinek@sun.com archiver=$(get_archiver identification) 48212199Sgerald.jelinek@sun.com if [[ $archiver == "pax" ]]; then 48312199Sgerald.jelinek@sun.com # pax archiver specified 48412199Sgerald.jelinek@sun.com archiver_command="/usr/bin/pax" 48512734Sgary.pennington@oracle.com if [[ -s $fspaxfile ]]; then 48612199Sgerald.jelinek@sun.com archiver_arguments="-r -p e -c \ 48712734Sgary.pennington@oracle.com $(/usr/bin/cat $fspaxfile)" 48812199Sgerald.jelinek@sun.com else 48912199Sgerald.jelinek@sun.com archiver_arguments="-r -p e" 49012199Sgerald.jelinek@sun.com fi 49112199Sgerald.jelinek@sun.com elif [[ $archiver == "cpio" || -z $archiver ]]; then 49212199Sgerald.jelinek@sun.com # cpio archived specified OR no archiver specified - use default 49312199Sgerald.jelinek@sun.com archiver_command="/usr/bin/cpio" 49412734Sgary.pennington@oracle.com archiver_arguments="-icdumfE $fscpiofile" 49512199Sgerald.jelinek@sun.com else 49612199Sgerald.jelinek@sun.com # unknown archiver specified 49712199Sgerald.jelinek@sun.com log "$unknown_archiver" $archiver 49812199Sgerald.jelinek@sun.com return 1 49912199Sgerald.jelinek@sun.com fi 50012199Sgerald.jelinek@sun.com 50112199Sgerald.jelinek@sun.com if [[ ! -x $archiver_command ]]; then 50212199Sgerald.jelinek@sun.com /usr/bin/rm -f identification 50312199Sgerald.jelinek@sun.com log "$cmd_not_exec" $archiver_command 50412199Sgerald.jelinek@sun.com return 1 50512199Sgerald.jelinek@sun.com fi 50612199Sgerald.jelinek@sun.com 50712199Sgerald.jelinek@sun.com compression=$(get_compression identification) 50812199Sgerald.jelinek@sun.com 50912199Sgerald.jelinek@sun.com # We're done with the identification file 51012199Sgerald.jelinek@sun.com /usr/bin/rm -f identification 51112199Sgerald.jelinek@sun.com 51212199Sgerald.jelinek@sun.com # Extract archive 51312199Sgerald.jelinek@sun.com if [[ $compression == "compress" ]]; then 51412199Sgerald.jelinek@sun.com /usr/bin/zcat | \ 51512199Sgerald.jelinek@sun.com $archiver_command $archiver_arguments 2>/dev/null 51612199Sgerald.jelinek@sun.com else 51712199Sgerald.jelinek@sun.com $archiver_command $archiver_arguments 2>/dev/null 51812199Sgerald.jelinek@sun.com fi 51912199Sgerald.jelinek@sun.com result=$? 52012199Sgerald.jelinek@sun.com 52112199Sgerald.jelinek@sun.com post_unpack 52212199Sgerald.jelinek@sun.com 52312199Sgerald.jelinek@sun.com (( $result != 0 )) && return 1 52412199Sgerald.jelinek@sun.com 52512199Sgerald.jelinek@sun.com return 0 52612199Sgerald.jelinek@sun.com} 52712199Sgerald.jelinek@sun.com 52812199Sgerald.jelinek@sun.com# 52912199Sgerald.jelinek@sun.com# Get the archive base. 53012199Sgerald.jelinek@sun.com# 53112199Sgerald.jelinek@sun.com# We must unpack the archive in the right place within the zonepath so 53212199Sgerald.jelinek@sun.com# that files are installed into the various mounted filesystems that are set 53312199Sgerald.jelinek@sun.com# up in the zone's configuration. These are already mounted for us by the 53412199Sgerald.jelinek@sun.com# mntfs function. 53512199Sgerald.jelinek@sun.com# 53612199Sgerald.jelinek@sun.com# Archives can be made of either a physical host's root file system or a 53712199Sgerald.jelinek@sun.com# zone's zonepath. For a physical system, if the archive is made using an 53812199Sgerald.jelinek@sun.com# absolute path (/...) we can't use it. For a zone the admin can make the 53912199Sgerald.jelinek@sun.com# archive from a variety of locations; 54012199Sgerald.jelinek@sun.com# 54112199Sgerald.jelinek@sun.com# a) zonepath itself: This will be a single dir, probably named with the 54212199Sgerald.jelinek@sun.com# zone name, it will contain a root dir and under the root we'll see all 54312199Sgerald.jelinek@sun.com# the top level dirs; etc, var, usr... We must be above the ZONEPATH 54412199Sgerald.jelinek@sun.com# when we unpack the archive but this will only work if the the archive's 54512199Sgerald.jelinek@sun.com# top-level dir name matches the ZONEPATH base-level dir name. If not, 54612199Sgerald.jelinek@sun.com# this is an error. 54712199Sgerald.jelinek@sun.com# 54812199Sgerald.jelinek@sun.com# b) inside the zonepath: We'll see root and it will contain all the top 54912199Sgerald.jelinek@sun.com# level dirs; etc, var, usr.... We must be in the ZONEPATH when we unpack 55012199Sgerald.jelinek@sun.com# the archive. 55112199Sgerald.jelinek@sun.com# 55212199Sgerald.jelinek@sun.com# c) inside the zonepath root: We'll see all the top level dirs, ./etc, 55312199Sgerald.jelinek@sun.com# ./var, ./usr.... This is also the case we see when we get an archive 55412199Sgerald.jelinek@sun.com# of a physical sytem. We must be in ZONEROOT when we unpack the archive. 55512199Sgerald.jelinek@sun.com# 55612199Sgerald.jelinek@sun.com# Note that there can be a directory named "root" under the ZONEPATH/root 55712199Sgerald.jelinek@sun.com# directory. 55812199Sgerald.jelinek@sun.com# 55912199Sgerald.jelinek@sun.com# This function handles the above possibilities so that we reject absolute 56012199Sgerald.jelinek@sun.com# path archives and figure out where in the file system we need to be to 56112199Sgerald.jelinek@sun.com# properly unpack the archive into the zone. It sets the ARCHIVE_BASE 56212199Sgerald.jelinek@sun.com# variable to the location where the achive should be unpacked. 56312199Sgerald.jelinek@sun.com# 56412199Sgerald.jelinek@sun.comget_archive_base() 56512199Sgerald.jelinek@sun.com{ 56612199Sgerald.jelinek@sun.com stage1=$1 56712199Sgerald.jelinek@sun.com archive=$2 56812199Sgerald.jelinek@sun.com stage2=$3 56912199Sgerald.jelinek@sun.com 57012199Sgerald.jelinek@sun.com vlog "$m_analyse_archive" 57112199Sgerald.jelinek@sun.com 57212199Sgerald.jelinek@sun.com base=`$stage1 $archive | $stage2 2>/dev/null | nawk -F/ '{ 57312199Sgerald.jelinek@sun.com # Check for an absolute path archive 57412199Sgerald.jelinek@sun.com if (substr($0, 1, 1) == "/") 57512199Sgerald.jelinek@sun.com exit 1 57612199Sgerald.jelinek@sun.com 57712199Sgerald.jelinek@sun.com if ($1 != ".") 57812199Sgerald.jelinek@sun.com dirs[$1] = 1 57912199Sgerald.jelinek@sun.com else 58012199Sgerald.jelinek@sun.com dirs[$2] = 1 58112199Sgerald.jelinek@sun.com } 58212199Sgerald.jelinek@sun.com END { 58312199Sgerald.jelinek@sun.com for (d in dirs) { 58412199Sgerald.jelinek@sun.com cnt++ 58512199Sgerald.jelinek@sun.com if (d == "bin") sawbin = 1 58612199Sgerald.jelinek@sun.com if (d == "etc") sawetc = 1 58712199Sgerald.jelinek@sun.com if (d == "root") sawroot = 1 58812199Sgerald.jelinek@sun.com if (d == "var") sawvar = 1 58912199Sgerald.jelinek@sun.com } 59012199Sgerald.jelinek@sun.com 59112199Sgerald.jelinek@sun.com if (cnt == 1) { 59212199Sgerald.jelinek@sun.com # If only one top-level dir named root, we are in the 59312199Sgerald.jelinek@sun.com # zonepath, otherwise this must be an archive *of* 59412199Sgerald.jelinek@sun.com # the zonepath so print the top-level dir name. 59512199Sgerald.jelinek@sun.com if (sawroot) 59612199Sgerald.jelinek@sun.com print "*zonepath*" 59712199Sgerald.jelinek@sun.com else 59812199Sgerald.jelinek@sun.com for (d in dirs) print d 59912199Sgerald.jelinek@sun.com } else { 60012199Sgerald.jelinek@sun.com # We are either in the zonepath or in the zonepath/root 60112199Sgerald.jelinek@sun.com # (or at the top level of a full system archive which 60212199Sgerald.jelinek@sun.com # looks like the zonepath/root case). Figure out which 60312199Sgerald.jelinek@sun.com # one. 60412199Sgerald.jelinek@sun.com if (sawroot && !sawbin && !sawetc && !sawvar) 60512199Sgerald.jelinek@sun.com print "*zonepath*" 60612199Sgerald.jelinek@sun.com else 60712199Sgerald.jelinek@sun.com print "*zoneroot*" 60812199Sgerald.jelinek@sun.com } 60912199Sgerald.jelinek@sun.com }'` 61012199Sgerald.jelinek@sun.com 61112199Sgerald.jelinek@sun.com if (( $? != 0 )); then 61212199Sgerald.jelinek@sun.com umnt_fs 61312199Sgerald.jelinek@sun.com fatal "$e_absolute_archive" 61412199Sgerald.jelinek@sun.com fi 61512199Sgerald.jelinek@sun.com 61612199Sgerald.jelinek@sun.com if [[ "$base" == "*zoneroot*" ]]; then 61712199Sgerald.jelinek@sun.com ARCHIVE_BASE=$ZONEROOT 61812199Sgerald.jelinek@sun.com elif [[ "$base" == "*zonepath*" ]]; then 61912199Sgerald.jelinek@sun.com ARCHIVE_BASE=$ZONEPATH 62012199Sgerald.jelinek@sun.com else 62112199Sgerald.jelinek@sun.com # We need to be in the dir above the ZONEPATH but we need to 62212199Sgerald.jelinek@sun.com # validate that $base matches the final component of ZONEPATH. 62312199Sgerald.jelinek@sun.com bname=`basename $ZONEPATH` 62412199Sgerald.jelinek@sun.com 62512199Sgerald.jelinek@sun.com if [[ "$bname" != "$base" ]]; then 62612199Sgerald.jelinek@sun.com umnt_fs 62712199Sgerald.jelinek@sun.com fatal "$e_mismatch_archive" "$base" "$bname" 62812199Sgerald.jelinek@sun.com fi 62912199Sgerald.jelinek@sun.com ARCHIVE_BASE=`dirname $ZONEPATH` 63012199Sgerald.jelinek@sun.com fi 63112199Sgerald.jelinek@sun.com} 63212199Sgerald.jelinek@sun.com 63312199Sgerald.jelinek@sun.com# 63412199Sgerald.jelinek@sun.com# Unpack cpio archive into zoneroot. 63512199Sgerald.jelinek@sun.com# 63612199Sgerald.jelinek@sun.cominstall_cpio() 63712199Sgerald.jelinek@sun.com{ 63812199Sgerald.jelinek@sun.com stage1=$1 63912199Sgerald.jelinek@sun.com archive=$2 64012199Sgerald.jelinek@sun.com 64112199Sgerald.jelinek@sun.com get_archive_base "$stage1" "$archive" "cpio -it" 64212199Sgerald.jelinek@sun.com 64312734Sgary.pennington@oracle.com cpioopts="-idmfE $fscpiofile" 64412199Sgerald.jelinek@sun.com 64512199Sgerald.jelinek@sun.com vlog "cd \"$ARCHIVE_BASE\" && $stage1 \"$archive\" | cpio $cpioopts" 64612199Sgerald.jelinek@sun.com 64712199Sgerald.jelinek@sun.com # Ignore errors from cpio since we expect some errors depending on 64812199Sgerald.jelinek@sun.com # how the archive was made. 64912199Sgerald.jelinek@sun.com ( cd "$ARCHIVE_BASE" && $stage1 "$archive" | cpio $cpioopts ) 65012199Sgerald.jelinek@sun.com 65112199Sgerald.jelinek@sun.com post_unpack 65212199Sgerald.jelinek@sun.com 65312199Sgerald.jelinek@sun.com return 0 65412199Sgerald.jelinek@sun.com} 65512199Sgerald.jelinek@sun.com 65612199Sgerald.jelinek@sun.com# 65712199Sgerald.jelinek@sun.com# Unpack pax archive into zoneroot. 65812199Sgerald.jelinek@sun.com# 65912199Sgerald.jelinek@sun.cominstall_pax() 66012199Sgerald.jelinek@sun.com{ 66112199Sgerald.jelinek@sun.com archive=$1 66212199Sgerald.jelinek@sun.com 66312199Sgerald.jelinek@sun.com get_archive_base "cat" "$archive" "pax" 66412199Sgerald.jelinek@sun.com 66512734Sgary.pennington@oracle.com if [[ -s $fspaxfile ]]; then 66612734Sgary.pennington@oracle.com filtopt="-c $(/usr/bin/cat $fspaxfile)" 66712199Sgerald.jelinek@sun.com fi 66812199Sgerald.jelinek@sun.com 66912199Sgerald.jelinek@sun.com vlog "cd \"$ARCHIVE_BASE\" && pax -r -f \"$archive\" $filtopt" 67012199Sgerald.jelinek@sun.com 67112199Sgerald.jelinek@sun.com # Ignore errors from pax since we expect some errors depending on 67212199Sgerald.jelinek@sun.com # how the archive was made. 67312199Sgerald.jelinek@sun.com ( cd "$ARCHIVE_BASE" && pax -r -f "$archive" $filtopt ) 67412199Sgerald.jelinek@sun.com 67512199Sgerald.jelinek@sun.com post_unpack 67612199Sgerald.jelinek@sun.com 67712199Sgerald.jelinek@sun.com return 0 67812199Sgerald.jelinek@sun.com} 67912199Sgerald.jelinek@sun.com 68012199Sgerald.jelinek@sun.com# 68112199Sgerald.jelinek@sun.com# Unpack UFS dump into zoneroot. 68212199Sgerald.jelinek@sun.com# 68312199Sgerald.jelinek@sun.cominstall_ufsdump() 68412199Sgerald.jelinek@sun.com{ 68512199Sgerald.jelinek@sun.com archive=$1 68612199Sgerald.jelinek@sun.com 68712199Sgerald.jelinek@sun.com vlog "cd \"$ZONEROOT\" && ufsrestore rf \"$archive\"" 68812199Sgerald.jelinek@sun.com 68912199Sgerald.jelinek@sun.com # 69012199Sgerald.jelinek@sun.com # ufsrestore goes interactive if you ^C it. To prevent that, 69112199Sgerald.jelinek@sun.com # we make sure its stdin is not a terminal. 69212199Sgerald.jelinek@sun.com # 69312199Sgerald.jelinek@sun.com ( cd "$ZONEROOT" && ufsrestore rf "$archive" < /dev/null ) 69412199Sgerald.jelinek@sun.com result=$? 69512199Sgerald.jelinek@sun.com 69612199Sgerald.jelinek@sun.com post_unpack 69712199Sgerald.jelinek@sun.com 69812199Sgerald.jelinek@sun.com return $result 69912199Sgerald.jelinek@sun.com} 70012199Sgerald.jelinek@sun.com 70112199Sgerald.jelinek@sun.com# 70212199Sgerald.jelinek@sun.com# Copy directory hierarchy into zoneroot. 70312199Sgerald.jelinek@sun.com# 70412199Sgerald.jelinek@sun.cominstall_dir() 70512199Sgerald.jelinek@sun.com{ 70612199Sgerald.jelinek@sun.com source_dir=$1 70712199Sgerald.jelinek@sun.com 70812199Sgerald.jelinek@sun.com cpioopts="-pdm" 70912199Sgerald.jelinek@sun.com 71012199Sgerald.jelinek@sun.com first=1 71112734Sgary.pennington@oracle.com filt=$(for i in $(cat $fspaxfile) 71212199Sgerald.jelinek@sun.com do 71312199Sgerald.jelinek@sun.com echo $i | egrep -s "/" && continue 71412199Sgerald.jelinek@sun.com if [[ $first == 1 ]]; then 71512199Sgerald.jelinek@sun.com printf "^%s" $i 71612199Sgerald.jelinek@sun.com first=0 71712199Sgerald.jelinek@sun.com else 71812199Sgerald.jelinek@sun.com printf "|^%s" $i 71912199Sgerald.jelinek@sun.com fi 72012199Sgerald.jelinek@sun.com done) 72112199Sgerald.jelinek@sun.com 72212199Sgerald.jelinek@sun.com list=$(cd "$source_dir" && ls -d * | egrep -v "$filt") 72312199Sgerald.jelinek@sun.com flist=$(for i in $list 72412199Sgerald.jelinek@sun.com do 72512199Sgerald.jelinek@sun.com printf "%s " "$i" 72612199Sgerald.jelinek@sun.com done) 72712199Sgerald.jelinek@sun.com findopts="-xdev ( -type d -o -type f -o -type l ) -print" 72812199Sgerald.jelinek@sun.com 72912199Sgerald.jelinek@sun.com vlog "cd \"$source_dir\" && find $flist $findopts | " 73012199Sgerald.jelinek@sun.com vlog "cpio $cpioopts \"$ZONEROOT\"" 73112199Sgerald.jelinek@sun.com 73212199Sgerald.jelinek@sun.com # Ignore errors from cpio since we expect some errors depending on 73312199Sgerald.jelinek@sun.com # how the archive was made. 73412199Sgerald.jelinek@sun.com ( cd "$source_dir" && find $flist $findopts | \ 73512199Sgerald.jelinek@sun.com cpio $cpioopts "$ZONEROOT" ) 73612199Sgerald.jelinek@sun.com 73712199Sgerald.jelinek@sun.com post_unpack 73812199Sgerald.jelinek@sun.com 73912199Sgerald.jelinek@sun.com return 0 74012199Sgerald.jelinek@sun.com} 74112199Sgerald.jelinek@sun.com 74212199Sgerald.jelinek@sun.com# 74312199Sgerald.jelinek@sun.com# This is a common function for laying down a zone image from a variety of 74412199Sgerald.jelinek@sun.com# different sources. This can be used to either install a fresh zone or as 74512199Sgerald.jelinek@sun.com# part of zone migration during attach. 74612199Sgerald.jelinek@sun.com# 74712199Sgerald.jelinek@sun.com# The first argument specifies the type of image: archive, directory or stdin. 74812199Sgerald.jelinek@sun.com# The second argument specifies the image itself. In the case of stdin, the 74912199Sgerald.jelinek@sun.com# second argument specifies the format of the stream (cpio, flar, etc.). 75012199Sgerald.jelinek@sun.com# Any validation or post-processing on the image is done elsewhere. 75112199Sgerald.jelinek@sun.com# 75212199Sgerald.jelinek@sun.com# This function calls a 'sanity_check' function which must be provided by 75312199Sgerald.jelinek@sun.com# the script which includes this code. 75412199Sgerald.jelinek@sun.com# 75512199Sgerald.jelinek@sun.cominstall_image() 75612199Sgerald.jelinek@sun.com{ 75712199Sgerald.jelinek@sun.com intype=$1 75812199Sgerald.jelinek@sun.com insrc=$2 75912199Sgerald.jelinek@sun.com 76012199Sgerald.jelinek@sun.com if [[ -z "$intype" || -z "$insrc" ]]; then 76112199Sgerald.jelinek@sun.com return 1 76212199Sgerald.jelinek@sun.com fi 76312199Sgerald.jelinek@sun.com 76412199Sgerald.jelinek@sun.com filetype="unknown" 76512199Sgerald.jelinek@sun.com filetypename="unknown" 76612199Sgerald.jelinek@sun.com stage1="cat" 76712199Sgerald.jelinek@sun.com 76812199Sgerald.jelinek@sun.com if [[ "$intype" == "directory" ]]; then 76912199Sgerald.jelinek@sun.com if [[ "$insrc" == "-" ]]; then 77012199Sgerald.jelinek@sun.com # Indicates that the existing zonepath is prepopulated. 77112199Sgerald.jelinek@sun.com filetype="existing" 77212199Sgerald.jelinek@sun.com filetypename="existing" 77312199Sgerald.jelinek@sun.com else 77412199Sgerald.jelinek@sun.com if [[ "$(echo $insrc | cut -c 1)" != "/" ]]; then 77512199Sgerald.jelinek@sun.com fatal "$e_path_abs" "$insrc" 77612199Sgerald.jelinek@sun.com fi 77712199Sgerald.jelinek@sun.com 77812199Sgerald.jelinek@sun.com if [[ ! -e "$insrc" ]]; then 77912199Sgerald.jelinek@sun.com log "$e_not_found" "$insrc" 78012199Sgerald.jelinek@sun.com fatal "$e_install_abort" 78112199Sgerald.jelinek@sun.com fi 78212199Sgerald.jelinek@sun.com 78312199Sgerald.jelinek@sun.com if [[ ! -r "$insrc" ]]; then 78412199Sgerald.jelinek@sun.com log "$e_not_readable" "$insrc" 78512199Sgerald.jelinek@sun.com fatal "$e_install_abort" 78612199Sgerald.jelinek@sun.com fi 78712199Sgerald.jelinek@sun.com 78812199Sgerald.jelinek@sun.com if [[ ! -d "$insrc" ]]; then 78912199Sgerald.jelinek@sun.com log "$e_not_dir" 79012199Sgerald.jelinek@sun.com fatal "$e_install_abort" 79112199Sgerald.jelinek@sun.com fi 79212199Sgerald.jelinek@sun.com 79312199Sgerald.jelinek@sun.com sanity_check $insrc 79412199Sgerald.jelinek@sun.com 79512199Sgerald.jelinek@sun.com filetype="directory" 79612199Sgerald.jelinek@sun.com filetypename="directory" 79712199Sgerald.jelinek@sun.com fi 79812199Sgerald.jelinek@sun.com 79912199Sgerald.jelinek@sun.com else 80012199Sgerald.jelinek@sun.com # Common code for both archive and stdin stream. 80112199Sgerald.jelinek@sun.com 80212199Sgerald.jelinek@sun.com if [[ "$intype" == "archive" ]]; then 80312199Sgerald.jelinek@sun.com if [[ ! -f "$insrc" ]]; then 80412199Sgerald.jelinek@sun.com log "$e_unknown_archive" 80512199Sgerald.jelinek@sun.com fatal "$e_install_abort" 80612199Sgerald.jelinek@sun.com fi 80712199Sgerald.jelinek@sun.com ftype="$(LC_ALL=C file $insrc | cut -d: -f 2)" 80812199Sgerald.jelinek@sun.com else 80912199Sgerald.jelinek@sun.com # For intype == stdin, the insrc parameter specifies 81012199Sgerald.jelinek@sun.com # the stream format coming on stdin. 81112199Sgerald.jelinek@sun.com ftype="$insrc" 81212199Sgerald.jelinek@sun.com insrc="-" 81312199Sgerald.jelinek@sun.com fi 81412199Sgerald.jelinek@sun.com 81512199Sgerald.jelinek@sun.com # Setup vars for the archive type we have. 81612199Sgerald.jelinek@sun.com case "$ftype" in 81712199Sgerald.jelinek@sun.com *cpio*) filetype="cpio" 81812199Sgerald.jelinek@sun.com filetypename="cpio archive" 81912199Sgerald.jelinek@sun.com ;; 82012199Sgerald.jelinek@sun.com *bzip2*) filetype="bzip2" 82112199Sgerald.jelinek@sun.com filetypename="bzipped cpio archive" 82212199Sgerald.jelinek@sun.com ;; 82312199Sgerald.jelinek@sun.com *gzip*) filetype="gzip" 82412199Sgerald.jelinek@sun.com filetypename="gzipped cpio archive" 82512199Sgerald.jelinek@sun.com ;; 82612199Sgerald.jelinek@sun.com *ufsdump*) filetype="ufsdump" 82712199Sgerald.jelinek@sun.com filetypename="ufsdump archive" 82812199Sgerald.jelinek@sun.com ;; 82912199Sgerald.jelinek@sun.com "flar") 83012199Sgerald.jelinek@sun.com filetype="flar" 83112199Sgerald.jelinek@sun.com filetypename="flash archive" 83212199Sgerald.jelinek@sun.com ;; 83312199Sgerald.jelinek@sun.com "flash") 83412199Sgerald.jelinek@sun.com filetype="flar" 83512199Sgerald.jelinek@sun.com filetypename="flash archive" 83612199Sgerald.jelinek@sun.com ;; 83712199Sgerald.jelinek@sun.com *Flash\ Archive*) 83812199Sgerald.jelinek@sun.com filetype="flar" 83912199Sgerald.jelinek@sun.com filetypename="flash archive" 84012199Sgerald.jelinek@sun.com ;; 84112199Sgerald.jelinek@sun.com "tar") 84212199Sgerald.jelinek@sun.com filetype="tar" 84312199Sgerald.jelinek@sun.com filetypename="tar archive" 84412199Sgerald.jelinek@sun.com ;; 84512199Sgerald.jelinek@sun.com *USTAR\ tar\ archive) 84612199Sgerald.jelinek@sun.com filetype="tar" 84712199Sgerald.jelinek@sun.com filetypename="tar archive" 84812199Sgerald.jelinek@sun.com ;; 84912199Sgerald.jelinek@sun.com "pax") 85012199Sgerald.jelinek@sun.com filetype="xustar" 85112199Sgerald.jelinek@sun.com filetypename="pax (xustar) archive" 85212199Sgerald.jelinek@sun.com ;; 85312199Sgerald.jelinek@sun.com *USTAR\ tar\ archive\ extended\ format*) 85412199Sgerald.jelinek@sun.com filetype="xustar" 85512199Sgerald.jelinek@sun.com filetypename="pax (xustar) archive" 85612199Sgerald.jelinek@sun.com ;; 85712199Sgerald.jelinek@sun.com "zfs") 85812199Sgerald.jelinek@sun.com filetype="zfs" 85912199Sgerald.jelinek@sun.com filetypename="ZFS send stream" 86012199Sgerald.jelinek@sun.com ;; 86112199Sgerald.jelinek@sun.com *ZFS\ snapshot\ stream*) 86212199Sgerald.jelinek@sun.com filetype="zfs" 86312199Sgerald.jelinek@sun.com filetypename="ZFS send stream" 86412199Sgerald.jelinek@sun.com ;; 86512199Sgerald.jelinek@sun.com *) log "$e_unknown_archive" 86612199Sgerald.jelinek@sun.com fatal "$e_install_abort" 86712199Sgerald.jelinek@sun.com ;; 86812199Sgerald.jelinek@sun.com esac 86912199Sgerald.jelinek@sun.com fi 87012199Sgerald.jelinek@sun.com 87112199Sgerald.jelinek@sun.com vlog "$filetypename" 87212199Sgerald.jelinek@sun.com 87312199Sgerald.jelinek@sun.com # Check for a non-empty root if no '-d -' option. 87412199Sgerald.jelinek@sun.com if [[ "$filetype" != "existing" ]]; then 87512199Sgerald.jelinek@sun.com cnt=$(ls $ZONEROOT | wc -l) 87612199Sgerald.jelinek@sun.com if (( $cnt != 0 )); then 87712199Sgerald.jelinek@sun.com fatal "$e_root_full" "$ZONEROOT" 87812199Sgerald.jelinek@sun.com fi 87912199Sgerald.jelinek@sun.com fi 88012199Sgerald.jelinek@sun.com 88112199Sgerald.jelinek@sun.com fstmpfile=$(/usr/bin/mktemp -t -p /var/tmp) 88212199Sgerald.jelinek@sun.com if [[ -z "$fstmpfile" ]]; then 88312199Sgerald.jelinek@sun.com fatal "$e_tmpfile" 88412199Sgerald.jelinek@sun.com fi 88512199Sgerald.jelinek@sun.com 88612199Sgerald.jelinek@sun.com # Make sure we always have the files holding the directories to filter 88712199Sgerald.jelinek@sun.com # out when extracting from a CPIO or PAX archive. We'll add the fs 88812734Sgary.pennington@oracle.com # entries to these files in get_fs_info() 88912734Sgary.pennington@oracle.com fscpiofile=$(/usr/bin/mktemp -t -p /var/tmp fs.cpio.XXXXXX) 89012734Sgary.pennington@oracle.com if [[ -z "$fscpiofile" ]]; then 89112199Sgerald.jelinek@sun.com rm -f $fstmpfile 89212199Sgerald.jelinek@sun.com fatal "$e_tmpfile" 89312199Sgerald.jelinek@sun.com fi 89412199Sgerald.jelinek@sun.com 89512734Sgary.pennington@oracle.com # Filter out these directories. 89612734Sgary.pennington@oracle.com echo 'dev/*' >>$fscpiofile 89712734Sgary.pennington@oracle.com echo 'devices/*' >>$fscpiofile 89812734Sgary.pennington@oracle.com echo 'devices' >>$fscpiofile 89912734Sgary.pennington@oracle.com echo 'proc/*' >>$fscpiofile 90012734Sgary.pennington@oracle.com echo 'tmp/*' >>$fscpiofile 90112734Sgary.pennington@oracle.com echo 'var/run/*' >>$fscpiofile 90212734Sgary.pennington@oracle.com echo 'system/contract/*' >>$fscpiofile 90312734Sgary.pennington@oracle.com echo 'system/object/*' >>$fscpiofile 90412199Sgerald.jelinek@sun.com 90512734Sgary.pennington@oracle.com fspaxfile=$(/usr/bin/mktemp -t -p /var/tmp fs.pax.XXXXXX) 90612734Sgary.pennington@oracle.com if [[ -z "$fspaxfile" ]]; then 90712734Sgary.pennington@oracle.com rm -f $fstmpfile $fscpiofile 90812199Sgerald.jelinek@sun.com fatal "$e_tmpfile" 90912199Sgerald.jelinek@sun.com fi 91012199Sgerald.jelinek@sun.com 91112199Sgerald.jelinek@sun.com printf "%s " \ 91212199Sgerald.jelinek@sun.com "dev devices proc tmp var/run system/contract system/object" \ 91312734Sgary.pennington@oracle.com >>$fspaxfile 91412199Sgerald.jelinek@sun.com 91512199Sgerald.jelinek@sun.com # Set up any fs mounts so the archive will install into the correct 91612199Sgerald.jelinek@sun.com # locations. 91712199Sgerald.jelinek@sun.com get_fs_info 91812199Sgerald.jelinek@sun.com mnt_fs 91912199Sgerald.jelinek@sun.com if (( $? != 0 )); then 92012199Sgerald.jelinek@sun.com umnt_fs >/dev/null 2>&1 92112734Sgary.pennington@oracle.com rm -f $fstmpfile $fscpiofile $fspaxfile 92212199Sgerald.jelinek@sun.com fatal "$mount_failed" 92312199Sgerald.jelinek@sun.com fi 92412199Sgerald.jelinek@sun.com 92512199Sgerald.jelinek@sun.com if [[ "$filetype" == "existing" ]]; then 92612199Sgerald.jelinek@sun.com log "$no_installing" 92712199Sgerald.jelinek@sun.com else 92812199Sgerald.jelinek@sun.com log "$installing" 92912199Sgerald.jelinek@sun.com fi 93012199Sgerald.jelinek@sun.com 93112199Sgerald.jelinek@sun.com # 93212199Sgerald.jelinek@sun.com # Install the image into the zonepath. 93312199Sgerald.jelinek@sun.com # 93412199Sgerald.jelinek@sun.com unpack_result=0 93512199Sgerald.jelinek@sun.com stage1="cat" 93612199Sgerald.jelinek@sun.com if [[ "$filetype" == "gzip" ]]; then 93712199Sgerald.jelinek@sun.com stage1="gzcat" 93812199Sgerald.jelinek@sun.com filetype="cpio" 93912199Sgerald.jelinek@sun.com elif [[ "$filetype" == "bzip2" ]]; then 94012199Sgerald.jelinek@sun.com stage1="bzcat" 94112199Sgerald.jelinek@sun.com filetype="cpio" 94212199Sgerald.jelinek@sun.com fi 94312199Sgerald.jelinek@sun.com 94412199Sgerald.jelinek@sun.com if [[ "$filetype" == "cpio" ]]; then 94512199Sgerald.jelinek@sun.com install_cpio "$stage1" "$insrc" 94612199Sgerald.jelinek@sun.com unpack_result=$? 94712199Sgerald.jelinek@sun.com 94812199Sgerald.jelinek@sun.com elif [[ "$filetype" == "flar" ]]; then 94912199Sgerald.jelinek@sun.com ( cd "$ZONEROOT" && $stage1 $insrc | install_flar ) 95012199Sgerald.jelinek@sun.com unpack_result=$? 95112199Sgerald.jelinek@sun.com 95212199Sgerald.jelinek@sun.com elif [[ "$filetype" == "xustar" ]]; then 95312199Sgerald.jelinek@sun.com install_pax "$insrc" 95412199Sgerald.jelinek@sun.com unpack_result=$? 95512199Sgerald.jelinek@sun.com 95612199Sgerald.jelinek@sun.com elif [[ "$filetype" = "tar" ]]; then 95712199Sgerald.jelinek@sun.com vlog "cd \"$ZONEROOT\" && tar -xf \"$insrc\"" 95812199Sgerald.jelinek@sun.com # Ignore errors from tar since we expect some errors depending 95912199Sgerald.jelinek@sun.com # on how the archive was made. 96012199Sgerald.jelinek@sun.com ( cd "$ZONEROOT" && tar -xf "$insrc" ) 96112199Sgerald.jelinek@sun.com unpack_result=0 96212199Sgerald.jelinek@sun.com post_unpack 96312199Sgerald.jelinek@sun.com 96412199Sgerald.jelinek@sun.com elif [[ "$filetype" == "ufsdump" ]]; then 96512199Sgerald.jelinek@sun.com install_ufsdump "$insrc" 96612199Sgerald.jelinek@sun.com unpack_result=$? 96712199Sgerald.jelinek@sun.com 96812199Sgerald.jelinek@sun.com elif [[ "$filetype" == "directory" ]]; then 96912199Sgerald.jelinek@sun.com install_dir "$insrc" 97012199Sgerald.jelinek@sun.com unpack_result=$? 97112199Sgerald.jelinek@sun.com 97212199Sgerald.jelinek@sun.com elif [[ "$filetype" == "zfs" ]]; then 97312199Sgerald.jelinek@sun.com # 97412199Sgerald.jelinek@sun.com # Given a 'zfs send' stream file, receive the snapshot into 97512199Sgerald.jelinek@sun.com # the zone's dataset. We're getting the original system's 97612199Sgerald.jelinek@sun.com # zonepath dataset. Destroy the existing dataset created 97712199Sgerald.jelinek@sun.com # above since this recreates it. 97812199Sgerald.jelinek@sun.com # 97912199Sgerald.jelinek@sun.com if [[ -z "$DATASET" ]]; then 98012199Sgerald.jelinek@sun.com fatal "$f_nodataset" 98112199Sgerald.jelinek@sun.com fi 98212199Sgerald.jelinek@sun.com /usr/sbin/zfs destroy "$DATASET" 98312199Sgerald.jelinek@sun.com if (( $? != 0 )); then 98412199Sgerald.jelinek@sun.com log "$f_zfsdestroy" "$DATASET" 98512199Sgerald.jelinek@sun.com fi 98612199Sgerald.jelinek@sun.com 98712199Sgerald.jelinek@sun.com vlog "$stage1 $insrc | zfs receive -F $DATASET" 98812199Sgerald.jelinek@sun.com ( $stage1 $insrc | /usr/sbin/zfs receive -F $DATASET ) 98912199Sgerald.jelinek@sun.com unpack_result=$? 99012199Sgerald.jelinek@sun.com fi 99112199Sgerald.jelinek@sun.com 99212199Sgerald.jelinek@sun.com # Clean up any fs mounts used during unpacking. 99312199Sgerald.jelinek@sun.com umnt_fs 99412734Sgary.pennington@oracle.com rm -f $fstmpfile $fscpiofile $fspaxfile 99512199Sgerald.jelinek@sun.com 99612199Sgerald.jelinek@sun.com chmod 700 $zonepath 99712199Sgerald.jelinek@sun.com 99812199Sgerald.jelinek@sun.com (( $unpack_result != 0 )) && fatal "$f_unpack_failed" 99912199Sgerald.jelinek@sun.com 100012199Sgerald.jelinek@sun.com # Verify this is a valid image. 100112199Sgerald.jelinek@sun.com sanity_check $ZONEROOT 100212199Sgerald.jelinek@sun.com 100312199Sgerald.jelinek@sun.com return 0 100412199Sgerald.jelinek@sun.com} 100512199Sgerald.jelinek@sun.com 100612199Sgerald.jelinek@sun.com# Setup i18n output 100712199Sgerald.jelinek@sun.comTEXTDOMAIN="SUNW_OST_OSCMD" 100812199Sgerald.jelinek@sun.comexport TEXTDOMAIN 100912199Sgerald.jelinek@sun.com 101012199Sgerald.jelinek@sun.come_cannot_wrap=$(gettext "%s: error: wrapper file already exists") 101112199Sgerald.jelinek@sun.come_baddir=$(gettext "Invalid '%s' directory within the zone") 101212199Sgerald.jelinek@sun.come_badfile=$(gettext "Invalid '%s' file within the zone") 101312199Sgerald.jelinek@sun.come_path_abs=$(gettext "Pathname specified to -a '%s' must be absolute.") 101412199Sgerald.jelinek@sun.come_not_found=$(gettext "%s: error: file or directory not found.") 101512199Sgerald.jelinek@sun.come_install_abort=$(gettext "Installation aborted.") 101612199Sgerald.jelinek@sun.come_not_readable=$(gettext "Cannot read directory '%s'") 101712199Sgerald.jelinek@sun.come_not_dir=$(gettext "Error: must be a directory") 101812199Sgerald.jelinek@sun.come_unknown_archive=$(gettext "Error: Unknown archive format. Must be a flash archive, a cpio archive (can also be gzipped or bzipped), a pax XUSTAR archive, or a level 0 ufsdump archive.") 101912199Sgerald.jelinek@sun.come_absolute_archive=$(gettext "Error: archive contains absolute paths instead of relative paths.") 102012199Sgerald.jelinek@sun.come_mismatch_archive=$(gettext "Error: the archive top-level directory (%s) does not match the zonepath (%s).") 102112199Sgerald.jelinek@sun.come_tmpfile=$(gettext "Unable to create temporary file") 102212199Sgerald.jelinek@sun.come_root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.") 102312199Sgerald.jelinek@sun.comf_mkdir=$(gettext "Unable to create directory %s.") 102412199Sgerald.jelinek@sun.comf_chmod=$(gettext "Unable to chmod directory %s.") 102512199Sgerald.jelinek@sun.comf_chown=$(gettext "Unable to chown directory %s.") 1026*12773Sgerald.jelinek@sun.comf_hwcap_info=$(gettext "HWCAP: %s\n") 1027*12773Sgerald.jelinek@sun.comf_sanity_hwcap=$(gettext \ 1028*12773Sgerald.jelinek@sun.com"The image was created with an incompatible libc.so.1 hwcap lofs mount.\n"\ 1029*12773Sgerald.jelinek@sun.com" The zone will not boot on this platform. See the zone's\n"\ 1030*12773Sgerald.jelinek@sun.com" documentation for the recommended way to create the archive.") 103112199Sgerald.jelinek@sun.com 103212199Sgerald.jelinek@sun.comm_analyse_archive=$(gettext "Analysing the archive") 103312199Sgerald.jelinek@sun.com 103412199Sgerald.jelinek@sun.comnot_readable=$(gettext "Cannot read file '%s'") 103512199Sgerald.jelinek@sun.comnot_flar=$(gettext "Input is not a flash archive") 103612199Sgerald.jelinek@sun.combad_flar=$(gettext "Flash archive is a corrupt") 103712199Sgerald.jelinek@sun.combad_zfs_flar=$(gettext "Flash archive contains a ZFS send stream.\n\tRecreate the flar using the -L option with cpio or pax.") 103812199Sgerald.jelinek@sun.comf_unpack_failed=$(gettext "Unpacking the archive failed") 103912199Sgerald.jelinek@sun.comunknown_archiver=$(gettext "Archiver %s is not supported") 104012199Sgerald.jelinek@sun.comcmd_not_exec=$(gettext "Required command '%s' not executable!") 104112199Sgerald.jelinek@sun.com 104212199Sgerald.jelinek@sun.com# 104312199Sgerald.jelinek@sun.com# Exit values used by the script, as #defined in <sys/zone.h> 104412199Sgerald.jelinek@sun.com# 104512199Sgerald.jelinek@sun.com# ZONE_SUBPROC_OK 104612199Sgerald.jelinek@sun.com# =============== 104712199Sgerald.jelinek@sun.com# Installation was successful 104812199Sgerald.jelinek@sun.com# 104912199Sgerald.jelinek@sun.com# ZONE_SUBPROC_USAGE 105012199Sgerald.jelinek@sun.com# ================== 105112199Sgerald.jelinek@sun.com# Improper arguments were passed, so print a usage message before exiting 105212199Sgerald.jelinek@sun.com# 105312199Sgerald.jelinek@sun.com# ZONE_SUBPROC_NOTCOMPLETE 105412199Sgerald.jelinek@sun.com# ======================== 105512199Sgerald.jelinek@sun.com# Installation did not complete, but another installation attempt can be 105612199Sgerald.jelinek@sun.com# made without an uninstall 105712199Sgerald.jelinek@sun.com# 105812199Sgerald.jelinek@sun.com# ZONE_SUBPROC_FATAL 105912199Sgerald.jelinek@sun.com# ================== 106012199Sgerald.jelinek@sun.com# Installation failed and an uninstall will be required before another 106112199Sgerald.jelinek@sun.com# install can be attempted 106212199Sgerald.jelinek@sun.com# 106312199Sgerald.jelinek@sun.comZONE_SUBPROC_OK=0 106412199Sgerald.jelinek@sun.comZONE_SUBPROC_USAGE=253 106512199Sgerald.jelinek@sun.comZONE_SUBPROC_NOTCOMPLETE=254 106612199Sgerald.jelinek@sun.comZONE_SUBPROC_FATAL=255 106712199Sgerald.jelinek@sun.com 1068