1edfa49ffS# 2edfa49ffS# CDDL HEADER START 3edfa49ffS# 4edfa49ffS# The contents of this file are subject to the terms of the 5edfa49ffS# Common Development and Distribution License (the "License"). 6edfa49ffS# You may not use this file except in compliance with the License. 7edfa49ffS# 8edfa49ffS# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9edfa49ffS# or http://www.opensolaris.org/os/licensing. 10edfa49ffS# See the License for the specific language governing permissions 11edfa49ffS# and limitations under the License. 12edfa49ffS# 13edfa49ffS# When distributing Covered Code, include this CDDL HEADER in each 14edfa49ffS# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15edfa49ffS# If applicable, add the following below this CDDL HEADER, with the 16edfa49ffS# fields enclosed by brackets "[]" replaced with your own identifying 17edfa49ffS# information: Portions Copyright [yyyy] [name of copyright owner] 18edfa49ffS# 19edfa49ffS# CDDL HEADER END 20edfa49ffS# 216e1ae2a3SGary Pennington# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 22edfa49ffS# 23edfa49ffS 24edfa49ffS# 25edfa49ffS# Send the error message to the screen and to the logfile. 26edfa49ffS# 27edfa49ffSerror() 28edfa49ffS{ 29edfa49ffS typeset fmt="$1" 30edfa49ffS shift 31edfa49ffS 32edfa49ffS printf "${MSG_PREFIX}ERROR: ${fmt}\n" "$@" 33edfa49ffS [[ -n $LOGFILE ]] && printf "[$(date)] ERROR: ${fmt}\n" "$@" >&2 34edfa49ffS} 35edfa49ffS 36edfa49ffSfatal() 37edfa49ffS{ 38edfa49ffS typeset fmt="$1" 39edfa49ffS shift 40edfa49ffS 41edfa49ffS error "$fmt" "$@" 42edfa49ffS exit $EXIT_CODE 43edfa49ffS} 44edfa49ffS 45e71ca95cSGerald Jelinekfail_fatal() { 4619b77901S typeset fmt="$1" 4719b77901S shift 4819b77901S 4919b77901S error "$fmt" "$@" 50e71ca95cSGerald Jelinek exit $ZONE_SUBPROC_FATAL 51e71ca95cSGerald Jelinek} 52e71ca95cSGerald Jelinek 53edfa49ffS# 54edfa49ffS# Send the provided printf()-style arguments to the screen and to the logfile. 55edfa49ffS# 56edfa49ffSlog() 57edfa49ffS{ 58edfa49ffS typeset fmt="$1" 59edfa49ffS shift 60edfa49ffS 61edfa49ffS printf "${MSG_PREFIX}${fmt}\n" "$@" 62edfa49ffS [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2 63edfa49ffS} 64edfa49ffS 65edfa49ffS# 66edfa49ffS# Print provided text to the screen if the shell variable "OPT_V" is set. 67edfa49ffS# The text is always sent to the logfile. 68edfa49ffS# 69edfa49ffSvlog() 70edfa49ffS{ 71edfa49ffS typeset fmt="$1" 72edfa49ffS shift 73edfa49ffS 74edfa49ffS [[ -n $OPT_V ]] && printf "${MSG_PREFIX}${fmt}\n" "$@" 75edfa49ffS [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2 76edfa49ffS} 77edfa49ffS 78e71ca95cSGerald Jelinek# 79edfa49ffS# Validate that the directory is safe. 80e71ca95cSGerald Jelinek# 81e71ca95cSGerald Jelinek# It is possible for a malicious zone root user to modify a zone's filesystem 82e71ca95cSGerald Jelinek# so that modifications made to the zone's filesystem by administrators in the 83e71ca95cSGerald Jelinek# global zone modify the global zone's filesystem. We can prevent this by 84e71ca95cSGerald Jelinek# ensuring that all components of paths accessed by scripts are real (i.e., 85e71ca95cSGerald Jelinek# non-symlink) directories. 86e71ca95cSGerald Jelinek# 87e71ca95cSGerald Jelinek# NOTE: The specified path should be an absolute path as would be seen from 88e71ca95cSGerald Jelinek# within the zone. Also, this function does not check parent directories. 89e71ca95cSGerald Jelinek# If, for example, you need to ensure that every component of the path 90e71ca95cSGerald Jelinek# '/foo/bar/baz' is a directory and not a symlink, then do the following: 91e71ca95cSGerald Jelinek# 92e71ca95cSGerald Jelinek# safe_dir /foo 93e71ca95cSGerald Jelinek# safe_dir /foo/bar 94e71ca95cSGerald Jelinek# safe_dir /foo/bar/baz 95e71ca95cSGerald Jelinek# 96edfa49ffSsafe_dir() 97edfa49ffS{ 98edfa49ffS typeset dir="$1" 99edfa49ffS 100edfa49ffS if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then 101edfa49ffS fatal "$e_baddir" "$dir" 102edfa49ffS fi 103edfa49ffS} 104edfa49ffS 105e71ca95cSGerald Jelinek# Like safe_dir except the dir doesn't have to exist. 106e71ca95cSGerald Jelineksafe_opt_dir() 107e71ca95cSGerald Jelinek{ 108e71ca95cSGerald Jelinek typeset dir="$1" 109e71ca95cSGerald Jelinek 110e71ca95cSGerald Jelinek [[ ! -e $ZONEROOT/$dir ]] && return 111e71ca95cSGerald Jelinek 112e71ca95cSGerald Jelinek if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then 113e71ca95cSGerald Jelinek fatal "$e_baddir" "$dir" 114e71ca95cSGerald Jelinek fi 115e71ca95cSGerald Jelinek} 116e71ca95cSGerald Jelinek 117edfa49ffS# Only make a copy if we haven't already done so. 118edfa49ffSsafe_backup() 119edfa49ffS{ 120edfa49ffS typeset src="$1" 121edfa49ffS typeset dst="$2" 122edfa49ffS 123edfa49ffS if [[ ! -h $src && ! -h $dst && ! -d $dst && ! -f $dst ]]; then 124edfa49ffS /usr/bin/cp -p $src $dst || fatal "$e_badfile" "$src" 125edfa49ffS fi 126edfa49ffS} 127edfa49ffS 128edfa49ffS# Make a copy even if the destination already exists. 129edfa49ffSsafe_copy() 130edfa49ffS{ 131edfa49ffS typeset src="$1" 132edfa49ffS typeset dst="$2" 133edfa49ffS 134edfa49ffS if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then 135edfa49ffS /usr/bin/cp -p $src $dst || fatal "$e_badfile" "$src" 136edfa49ffS fi 137edfa49ffS} 138edfa49ffS 139edfa49ffS# Move a file 140edfa49ffSsafe_move() 141edfa49ffS{ 142edfa49ffS typeset src="$1" 143edfa49ffS typeset dst="$2" 144edfa49ffS 145edfa49ffS if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then 146edfa49ffS /usr/bin/mv $src $dst || fatal "$e_badfile" "$src" 147edfa49ffS fi 148edfa49ffS} 149edfa49ffS 150e71ca95cSGerald Jelineksafe_rm() 151e71ca95cSGerald Jelinek{ 152e71ca95cSGerald Jelinek if [[ ! -h $ZONEROOT/$1 && -f $ZONEROOT/$1 ]]; then 153e71ca95cSGerald Jelinek rm -f "$ZONEROOT/$1" 154e71ca95cSGerald Jelinek fi 155e71ca95cSGerald Jelinek} 156e71ca95cSGerald Jelinek 157e71ca95cSGerald Jelinek# 158e71ca95cSGerald Jelinek# Replace the file with a wrapper pointing to the native brand code. 159e71ca95cSGerald Jelinek# However, we only do the replacement if the file hasn't already been 160e71ca95cSGerald Jelinek# replaced with our wrapper. This function expects the cwd to be the 161e71ca95cSGerald Jelinek# location of the file we're replacing. 162e71ca95cSGerald Jelinek# 163e71ca95cSGerald Jelinek# Some of the files we're replacing are hardlinks to isaexec so we need to 'rm' 164e71ca95cSGerald Jelinek# the file before we setup the wrapper while others are hardlinks to rc scripts 165e71ca95cSGerald Jelinek# that we need to maintain. 166e71ca95cSGerald Jelinek# 167e71ca95cSGerald Jelineksafe_replace() 168e71ca95cSGerald Jelinek{ 169e71ca95cSGerald Jelinek typeset filename="$1" 170e71ca95cSGerald Jelinek typeset runname="$2" 171e71ca95cSGerald Jelinek typeset mode="$3" 172e71ca95cSGerald Jelinek typeset own="$4" 173e71ca95cSGerald Jelinek typeset rem="$5" 174e71ca95cSGerald Jelinek 175e71ca95cSGerald Jelinek if [ -h $filename -o ! -f $filename ]; then 176e71ca95cSGerald Jelinek return 177e71ca95cSGerald Jelinek fi 178e71ca95cSGerald Jelinek 179e71ca95cSGerald Jelinek egrep -s "Solaris Brand Replacement" $filename 180e71ca95cSGerald Jelinek if [ $? -eq 0 ]; then 181e71ca95cSGerald Jelinek return 182e71ca95cSGerald Jelinek fi 183e71ca95cSGerald Jelinek 184e71ca95cSGerald Jelinek safe_backup $filename $filename.pre_p2v 185e71ca95cSGerald Jelinek if [ $rem = "remove" ]; then 186e71ca95cSGerald Jelinek rm -f $filename 187e71ca95cSGerald Jelinek fi 188e71ca95cSGerald Jelinek 189e71ca95cSGerald Jelinek cat <<-END >$filename || exit 1 1901022fd2aS #!/bin/sh -p 191e71ca95cSGerald Jelinek # 192e71ca95cSGerald Jelinek # Solaris Brand Replacement 193e71ca95cSGerald Jelinek # 194e71ca95cSGerald Jelinek # Attention. This file has been replaced with a new version for 195e71ca95cSGerald Jelinek # use in a virtualized environment. Modification of this script is not 196e71ca95cSGerald Jelinek # supported and all changes will be lost upon reboot. The 197e71ca95cSGerald Jelinek # {name}.pre_p2v version of this file is a backup copy of the 198e71ca95cSGerald Jelinek # original and should not be deleted. 199e71ca95cSGerald Jelinek # 200e71ca95cSGerald Jelinek END 201e71ca95cSGerald Jelinek 202e71ca95cSGerald Jelinek echo ". $runname \"\$@\"" >>$filename || exit 1 203e71ca95cSGerald Jelinek 204e71ca95cSGerald Jelinek chmod $mode $filename 205e71ca95cSGerald Jelinek chown $own $filename 206e71ca95cSGerald Jelinek} 207e71ca95cSGerald Jelinek 208ae104932SJonathan Adamssafe_wrap() 209ae104932SJonathan Adams{ 210ae104932SJonathan Adams typeset filename="$1" 211ae104932SJonathan Adams typeset runname="$2" 212ae104932SJonathan Adams typeset mode="$3" 213ae104932SJonathan Adams typeset own="$4" 214ae104932SJonathan Adams 215ae104932SJonathan Adams if [ -f $filename ]; then 216ae104932SJonathan Adams log "$e_cannot_wrap" "$filename" 217ae104932SJonathan Adams exit 1 218ae104932SJonathan Adams fi 219ae104932SJonathan Adams 220ae104932SJonathan Adams cat <<-END >$filename || exit 1 221ae104932SJonathan Adams #!/bin/sh 222ae104932SJonathan Adams # 223ae104932SJonathan Adams # Solaris Brand Wrapper 224ae104932SJonathan Adams # 225ae104932SJonathan Adams # Attention. This file has been created for use in a 226ae104932SJonathan Adams # virtualized environment. Modification of this script 227ae104932SJonathan Adams # is not supported and all changes will be lost upon reboot. 228ae104932SJonathan Adams # 229ae104932SJonathan Adams END 230ae104932SJonathan Adams 231ae104932SJonathan Adams echo ". $runname \"\$@\"" >>$filename || exit 1 232ae104932SJonathan Adams 233ae104932SJonathan Adams chmod $mode $filename 234ae104932SJonathan Adams chown $own $filename 235ae104932SJonathan Adams} 236ae104932SJonathan Adams 237edfa49ffS# 2386e1ae2a3SGary Pennington# Read zonecfg fs entries and save the relevant data, one entry per 239edfa49ffS# line. 240edfa49ffS# This assumes the properties from the zonecfg output, e.g.: 241edfa49ffS# fs: 242edfa49ffS# dir: /opt 243edfa49ffS# special: /opt 244edfa49ffS# raw not specified 245edfa49ffS# type: lofs 246edfa49ffS# options: [noexec,ro,noatime] 247edfa49ffS# 2486e1ae2a3SGary Pennington# and it assumes the order of the fs properties as above. 249edfa49ffS# 250edfa49ffSget_fs_info() 251edfa49ffS{ 252edfa49ffS zonecfg -z $zonename info fs | nawk '{ 253edfa49ffS if ($1 == "options:") { 254edfa49ffS # Remove brackets. 255edfa49ffS options=substr($2, 2, length($2) - 2); 256edfa49ffS printf("%s %s %s %s\n", dir, type, special, options); 257edfa49ffS } else if ($1 == "dir:") { 258edfa49ffS dir=$2; 259edfa49ffS } else if ($1 == "special:") { 260edfa49ffS special=$2; 261edfa49ffS } else if ($1 == "type:") { 262edfa49ffS type=$2 263edfa49ffS } 264edfa49ffS }' >> $fstmpfile 265edfa49ffS} 266edfa49ffS 267edfa49ffS# 268edfa49ffS# Mount zonecfg fs entries into the zonepath. 269edfa49ffS# 270edfa49ffSmnt_fs() 271edfa49ffS{ 272edfa49ffS if [ ! -s $fstmpfile ]; then 273edfa49ffS return; 274edfa49ffS fi 275edfa49ffS 276edfa49ffS # Sort the fs entries so we can handle nested mounts. 277edfa49ffS sort $fstmpfile | nawk -v zonepath=$zonepath '{ 278edfa49ffS if (NF == 4) 279edfa49ffS options="-o " $4; 280edfa49ffS else 281edfa49ffS options="" 282edfa49ffS 283edfa49ffS # Create the mount point. Ignore errors since we might have 284edfa49ffS # a nested mount with a pre-existing mount point. 285edfa49ffS cmd="/usr/bin/mkdir -p " zonepath "/root" $1 " >/dev/null 2>&1" 286edfa49ffS system(cmd); 287edfa49ffS 288edfa49ffS cmd="/usr/sbin/mount -F " $2 " " options " " $3 " " \ 289edfa49ffS zonepath "/root" $1; 290edfa49ffS if (system(cmd) != 0) { 291edfa49ffS printf("command failed: %s\n", cmd); 292edfa49ffS exit 1; 293edfa49ffS } 294edfa49ffS }' >>$LOGFILE 295edfa49ffS} 296edfa49ffS 297edfa49ffS# 298edfa49ffS# Unmount zonecfg fs entries from the zonepath. 299edfa49ffS# 300edfa49ffSumnt_fs() 301edfa49ffS{ 302edfa49ffS if [ ! -s $fstmpfile ]; then 303edfa49ffS return; 304edfa49ffS fi 305edfa49ffS 306edfa49ffS # Reverse sort the fs entries so we can handle nested unmounts. 307edfa49ffS sort -r $fstmpfile | nawk -v zonepath=$zonepath '{ 308edfa49ffS cmd="/usr/sbin/umount " zonepath "/root" $1 309edfa49ffS if (system(cmd) != 0) { 310edfa49ffS printf("command failed: %s\n", cmd); 311edfa49ffS } 312edfa49ffS }' >>$LOGFILE 313edfa49ffS} 314edfa49ffS 315e71ca95cSGerald Jelinek# Find the dataset mounted on the zonepath. 316e71ca95cSGerald Jelinekget_zonepath_ds() { 317e71ca95cSGerald Jelinek ZONEPATH_DS=`/usr/sbin/zfs list -H -t filesystem -o name,mountpoint | \ 318e71ca95cSGerald Jelinek /usr/bin/nawk -v zonepath=$1 '{ 319e71ca95cSGerald Jelinek if ($2 == zonepath) 320e71ca95cSGerald Jelinek print $1 321e71ca95cSGerald Jelinek }'` 322e71ca95cSGerald Jelinek 323e71ca95cSGerald Jelinek if [ -z "$ZONEPATH_DS" ]; then 324e71ca95cSGerald Jelinek fail_fatal "$f_no_ds" 325e71ca95cSGerald Jelinek fi 326e71ca95cSGerald Jelinek} 327e71ca95cSGerald Jelinek 328eba00995S# 32919b77901S# Perform validation and cleanup in the zoneroot after unpacking the archive. 330eba00995S# 331eba00995Spost_unpack() 332eba00995S{ 33319b77901S # 33419b77901S # Check if the image was created with a valid libc.so.1. 33519b77901S # 33619b77901S hwcap=`moe -v -32 $ZONEROOT/lib/libc.so.1 2>&1` 33719b77901S if (( $? != 0 )); then 33819b77901S vlog "$f_hwcap_info" "$hwcap" 33919b77901S fail_fatal "$f_sanity_hwcap" 34019b77901S fi 34119b77901S 342eba00995S ( cd "$ZONEROOT" && \ 343eba00995S find . \( -type b -o -type c \) -exec rm -f "{}" \; ) 344eba00995S} 345eba00995S 346edfa49ffS# 347edfa49ffS# Determine flar compression style from identification file. 348edfa49ffS# 349edfa49ffSget_compression() 350edfa49ffS{ 351edfa49ffS typeset ident=$1 352edfa49ffS typeset line=$(grep "^files_compressed_method=" $ident) 353edfa49ffS 354edfa49ffS print ${line##*=} 355edfa49ffS} 356edfa49ffS 357edfa49ffS# 358edfa49ffS# Determine flar archive style from identification file. 359edfa49ffS# 360edfa49ffSget_archiver() 361edfa49ffS{ 362edfa49ffS typeset ident=$1 363edfa49ffS typeset line=$(grep "^files_archived_method=" $ident) 364edfa49ffS 365edfa49ffS print ${line##*=} 366edfa49ffS} 367edfa49ffS 368edfa49ffS# 369edfa49ffS# Unpack flar into current directory (which should be zoneroot). The flash 370edfa49ffS# archive is standard input. See flash_archive(4) man page. 371edfa49ffS# 372edfa49ffS# We can't use "flar split" since it will only unpack into a directory called 373edfa49ffS# "archive". We need to unpack in place in order to properly handle nested 374edfa49ffS# fs mounts within the zone root. This function does the unpacking into the 375edfa49ffS# current directory. 376edfa49ffS# 377edfa49ffS# This code is derived from the gen_split() function in /usr/sbin/flar so 378edfa49ffS# we keep the same style as the original. 379edfa49ffS# 380edfa49ffSinstall_flar() 381edfa49ffS{ 382edfa49ffS typeset result 383edfa49ffS typeset archiver_command 384edfa49ffS typeset archiver_arguments 385edfa49ffS 38674bbcaa8S vlog "cd $ZONEROOT && $stage1 "$insrc" | install_flar" 387edfa49ffS 388edfa49ffS # Read cookie 389edfa49ffS read -r input_line 390edfa49ffS if (( $? != 0 )); then 391edfa49ffS log "$not_readable" "$install_media" 392edfa49ffS return 1 393edfa49ffS fi 394edfa49ffS # The cookie has format FlAsH-aRcHiVe-m.n where m and n are integers. 395edfa49ffS if [[ ${input_line%%-[0-9]*.[0-9]*} != "FlAsH-aRcHiVe" ]]; then 396edfa49ffS log "$not_flar" 397edfa49ffS return 1 398edfa49ffS fi 399edfa49ffS 400edfa49ffS while [ true ] 401edfa49ffS do 402edfa49ffS # We should always be at the start of a section here 403edfa49ffS read -r input_line 404edfa49ffS if [[ ${input_line%%=*} != "section_begin" ]]; then 405edfa49ffS log "$bad_flar" 406edfa49ffS return 1 407edfa49ffS fi 408edfa49ffS section_name=${input_line##*=} 409edfa49ffS 410edfa49ffS # If we're at the archive, we're done skipping sections. 411edfa49ffS if [[ "$section_name" == "archive" ]]; then 412edfa49ffS break 413edfa49ffS fi 414edfa49ffS 415edfa49ffS # 416edfa49ffS # Save identification section to a file so we can determine 417edfa49ffS # how to unpack the archive. 418edfa49ffS # 419edfa49ffS if [[ "$section_name" == "identification" ]]; then 420edfa49ffS /usr/bin/rm -f identification 421edfa49ffS while read -r input_line 422edfa49ffS do 423edfa49ffS if [[ ${input_line%%=*} == \ 424edfa49ffS "section_begin" ]]; then 425edfa49ffS /usr/bin/rm -f identification 426edfa49ffS log "$bad_flar" 427edfa49ffS return 1 428edfa49ffS fi 429edfa49ffS 430edfa49ffS if [[ $input_line == \ 431edfa49ffS "section_end=$section_name" ]]; then 432edfa49ffS break; 433edfa49ffS fi 434edfa49ffS echo $input_line >> identification 435edfa49ffS done 436edfa49ffS 437edfa49ffS continue 438edfa49ffS fi 439edfa49ffS 440edfa49ffS # 441edfa49ffS # Otherwise skip past this section; read lines until detecting 442edfa49ffS # section_end. According to flash_archive(4) we can have 443edfa49ffS # an arbitrary number of sections but the archive section 444edfa49ffS # must be last. 445edfa49ffS # 446edfa49ffS success=0 447edfa49ffS while read -r input_line 448edfa49ffS do 449edfa49ffS if [[ $input_line == "section_end=$section_name" ]]; 450edfa49ffS then 451edfa49ffS success=1 452edfa49ffS break 453edfa49ffS fi 454edfa49ffS # Fail if we miss the end of the section 455edfa49ffS if [[ ${input_line%%=*} == "section_begin" ]]; then 456edfa49ffS /usr/bin/rm -f identification 457edfa49ffS log "$bad_flar" 458edfa49ffS return 1 459edfa49ffS fi 460edfa49ffS done 461edfa49ffS if (( $success == 0 )); then 462edfa49ffS # 463edfa49ffS # If we get here we read to the end of the file before 464edfa49ffS # seeing the end of the section we were reading. 465edfa49ffS # 466edfa49ffS /usr/bin/rm -f identification 467edfa49ffS log "$bad_flar" 468edfa49ffS return 1 469edfa49ffS fi 470edfa49ffS done 471edfa49ffS 472cec6066bS # Check for an archive made from a ZFS root pool. 473cec6066bS egrep -s "^rootpool=" identification 474cec6066bS if (( $? == 0 )); then 475cec6066bS /usr/bin/rm -f identification 476cec6066bS log "$bad_zfs_flar" 477cec6066bS return 1 478cec6066bS fi 479cec6066bS 480edfa49ffS # Get the information needed to unpack the archive. 481edfa49ffS archiver=$(get_archiver identification) 482edfa49ffS if [[ $archiver == "pax" ]]; then 483edfa49ffS # pax archiver specified 484edfa49ffS archiver_command="/usr/bin/pax" 4856e1ae2a3SGary Pennington if [[ -s $fspaxfile ]]; then 486edfa49ffS archiver_arguments="-r -p e -c \ 4876e1ae2a3SGary Pennington $(/usr/bin/cat $fspaxfile)" 488edfa49ffS else 489edfa49ffS archiver_arguments="-r -p e" 490edfa49ffS fi 491edfa49ffS elif [[ $archiver == "cpio" || -z $archiver ]]; then 492edfa49ffS # cpio archived specified OR no archiver specified - use default 493edfa49ffS archiver_command="/usr/bin/cpio" 4946e1ae2a3SGary Pennington archiver_arguments="-icdumfE $fscpiofile" 495edfa49ffS else 496edfa49ffS # unknown archiver specified 497edfa49ffS log "$unknown_archiver" $archiver 498edfa49ffS return 1 499edfa49ffS fi 500edfa49ffS 501edfa49ffS if [[ ! -x $archiver_command ]]; then 502edfa49ffS /usr/bin/rm -f identification 503edfa49ffS log "$cmd_not_exec" $archiver_command 504edfa49ffS return 1 505edfa49ffS fi 506edfa49ffS 507edfa49ffS compression=$(get_compression identification) 508edfa49ffS 509edfa49ffS # We're done with the identification file 510edfa49ffS /usr/bin/rm -f identification 511edfa49ffS 512edfa49ffS # Extract archive 513edfa49ffS if [[ $compression == "compress" ]]; then 514eba00995S /usr/bin/zcat | \ 515edfa49ffS $archiver_command $archiver_arguments 2>/dev/null 516edfa49ffS else 517eba00995S $archiver_command $archiver_arguments 2>/dev/null 518edfa49ffS fi 519edfa49ffS result=$? 520edfa49ffS 521eba00995S post_unpack 522eba00995S 523edfa49ffS (( $result != 0 )) && return 1 524edfa49ffS 525edfa49ffS return 0 526edfa49ffS} 527edfa49ffS 5288c20418dSGerald Jelinek# 5298c20418dSGerald Jelinek# Get the archive base. 5308c20418dSGerald Jelinek# 5318c20418dSGerald Jelinek# We must unpack the archive in the right place within the zonepath so 5328c20418dSGerald Jelinek# that files are installed into the various mounted filesystems that are set 5338c20418dSGerald Jelinek# up in the zone's configuration. These are already mounted for us by the 5348c20418dSGerald Jelinek# mntfs function. 5358c20418dSGerald Jelinek# 5368c20418dSGerald Jelinek# Archives can be made of either a physical host's root file system or a 5378c20418dSGerald Jelinek# zone's zonepath. For a physical system, if the archive is made using an 5388c20418dSGerald Jelinek# absolute path (/...) we can't use it. For a zone the admin can make the 5398c20418dSGerald Jelinek# archive from a variety of locations; 5408c20418dSGerald Jelinek# 5418c20418dSGerald Jelinek# a) zonepath itself: This will be a single dir, probably named with the 5428c20418dSGerald Jelinek# zone name, it will contain a root dir and under the root we'll see all 5438c20418dSGerald Jelinek# the top level dirs; etc, var, usr... We must be above the ZONEPATH 5448c20418dSGerald Jelinek# when we unpack the archive but this will only work if the the archive's 5458c20418dSGerald Jelinek# top-level dir name matches the ZONEPATH base-level dir name. If not, 5468c20418dSGerald Jelinek# this is an error. 5478c20418dSGerald Jelinek# 5488c20418dSGerald Jelinek# b) inside the zonepath: We'll see root and it will contain all the top 5498c20418dSGerald Jelinek# level dirs; etc, var, usr.... We must be in the ZONEPATH when we unpack 5508c20418dSGerald Jelinek# the archive. 5518c20418dSGerald Jelinek# 5528c20418dSGerald Jelinek# c) inside the zonepath root: We'll see all the top level dirs, ./etc, 5538c20418dSGerald Jelinek# ./var, ./usr.... This is also the case we see when we get an archive 554*d0b12b66SToomas Soome# of a physical system. We must be in ZONEROOT when we unpack the archive. 5558c20418dSGerald Jelinek# 5568c20418dSGerald Jelinek# Note that there can be a directory named "root" under the ZONEPATH/root 5578c20418dSGerald Jelinek# directory. 5588c20418dSGerald Jelinek# 5598c20418dSGerald Jelinek# This function handles the above possibilities so that we reject absolute 5608c20418dSGerald Jelinek# path archives and figure out where in the file system we need to be to 5618c20418dSGerald Jelinek# properly unpack the archive into the zone. It sets the ARCHIVE_BASE 5628c20418dSGerald Jelinek# variable to the location where the achive should be unpacked. 5638c20418dSGerald Jelinek# 5648c20418dSGerald Jelinekget_archive_base() 5658c20418dSGerald Jelinek{ 5668c20418dSGerald Jelinek stage1=$1 5678c20418dSGerald Jelinek archive=$2 5688c20418dSGerald Jelinek stage2=$3 5698c20418dSGerald Jelinek 5708c20418dSGerald Jelinek vlog "$m_analyse_archive" 5718c20418dSGerald Jelinek 5728c20418dSGerald Jelinek base=`$stage1 $archive | $stage2 2>/dev/null | nawk -F/ '{ 5738c20418dSGerald Jelinek # Check for an absolute path archive 5748c20418dSGerald Jelinek if (substr($0, 1, 1) == "/") 5758c20418dSGerald Jelinek exit 1 5768c20418dSGerald Jelinek 5778c20418dSGerald Jelinek if ($1 != ".") 5788c20418dSGerald Jelinek dirs[$1] = 1 5798c20418dSGerald Jelinek else 5808c20418dSGerald Jelinek dirs[$2] = 1 5818c20418dSGerald Jelinek } 5828c20418dSGerald Jelinek END { 5838c20418dSGerald Jelinek for (d in dirs) { 5848c20418dSGerald Jelinek cnt++ 5858c20418dSGerald Jelinek if (d == "bin") sawbin = 1 5868c20418dSGerald Jelinek if (d == "etc") sawetc = 1 5878c20418dSGerald Jelinek if (d == "root") sawroot = 1 5888c20418dSGerald Jelinek if (d == "var") sawvar = 1 5898c20418dSGerald Jelinek } 5908c20418dSGerald Jelinek 5918c20418dSGerald Jelinek if (cnt == 1) { 5928c20418dSGerald Jelinek # If only one top-level dir named root, we are in the 5938c20418dSGerald Jelinek # zonepath, otherwise this must be an archive *of* 5948c20418dSGerald Jelinek # the zonepath so print the top-level dir name. 5958c20418dSGerald Jelinek if (sawroot) 5968c20418dSGerald Jelinek print "*zonepath*" 5978c20418dSGerald Jelinek else 5988c20418dSGerald Jelinek for (d in dirs) print d 5998c20418dSGerald Jelinek } else { 6008c20418dSGerald Jelinek # We are either in the zonepath or in the zonepath/root 6018c20418dSGerald Jelinek # (or at the top level of a full system archive which 6028c20418dSGerald Jelinek # looks like the zonepath/root case). Figure out which 6038c20418dSGerald Jelinek # one. 6048c20418dSGerald Jelinek if (sawroot && !sawbin && !sawetc && !sawvar) 6058c20418dSGerald Jelinek print "*zonepath*" 6068c20418dSGerald Jelinek else 6078c20418dSGerald Jelinek print "*zoneroot*" 6088c20418dSGerald Jelinek } 6098c20418dSGerald Jelinek }'` 6108c20418dSGerald Jelinek 6118c20418dSGerald Jelinek if (( $? != 0 )); then 6128c20418dSGerald Jelinek umnt_fs 6138c20418dSGerald Jelinek fatal "$e_absolute_archive" 6148c20418dSGerald Jelinek fi 6158c20418dSGerald Jelinek 6168c20418dSGerald Jelinek if [[ "$base" == "*zoneroot*" ]]; then 6178c20418dSGerald Jelinek ARCHIVE_BASE=$ZONEROOT 6188c20418dSGerald Jelinek elif [[ "$base" == "*zonepath*" ]]; then 6198c20418dSGerald Jelinek ARCHIVE_BASE=$ZONEPATH 6208c20418dSGerald Jelinek else 6218c20418dSGerald Jelinek # We need to be in the dir above the ZONEPATH but we need to 6228c20418dSGerald Jelinek # validate that $base matches the final component of ZONEPATH. 6238c20418dSGerald Jelinek bname=`basename $ZONEPATH` 6248c20418dSGerald Jelinek 6258c20418dSGerald Jelinek if [[ "$bname" != "$base" ]]; then 6268c20418dSGerald Jelinek umnt_fs 6278c20418dSGerald Jelinek fatal "$e_mismatch_archive" "$base" "$bname" 6288c20418dSGerald Jelinek fi 6298c20418dSGerald Jelinek ARCHIVE_BASE=`dirname $ZONEPATH` 6308c20418dSGerald Jelinek fi 6318c20418dSGerald Jelinek} 6328c20418dSGerald Jelinek 633edfa49ffS# 634edfa49ffS# Unpack cpio archive into zoneroot. 635edfa49ffS# 636edfa49ffSinstall_cpio() 637edfa49ffS{ 638edfa49ffS stage1=$1 639edfa49ffS archive=$2 640edfa49ffS 6418c20418dSGerald Jelinek get_archive_base "$stage1" "$archive" "cpio -it" 64262ac5336S 6436e1ae2a3SGary Pennington cpioopts="-idmfE $fscpiofile" 644edfa49ffS 6458c20418dSGerald Jelinek vlog "cd \"$ARCHIVE_BASE\" && $stage1 \"$archive\" | cpio $cpioopts" 646eba00995S 647cec6066bS # Ignore errors from cpio since we expect some errors depending on 648cec6066bS # how the archive was made. 6498c20418dSGerald Jelinek ( cd "$ARCHIVE_BASE" && $stage1 "$archive" | cpio $cpioopts ) 650eba00995S 651eba00995S post_unpack 652edfa49ffS 653cec6066bS return 0 654edfa49ffS} 655edfa49ffS 656edfa49ffS# 657edfa49ffS# Unpack pax archive into zoneroot. 658edfa49ffS# 659edfa49ffSinstall_pax() 660edfa49ffS{ 661edfa49ffS archive=$1 662edfa49ffS 6638c20418dSGerald Jelinek get_archive_base "cat" "$archive" "pax" 66462ac5336S 6656e1ae2a3SGary Pennington if [[ -s $fspaxfile ]]; then 6666e1ae2a3SGary Pennington filtopt="-c $(/usr/bin/cat $fspaxfile)" 667edfa49ffS fi 668edfa49ffS 6698c20418dSGerald Jelinek vlog "cd \"$ARCHIVE_BASE\" && pax -r -f \"$archive\" $filtopt" 670edfa49ffS 671cec6066bS # Ignore errors from pax since we expect some errors depending on 672cec6066bS # how the archive was made. 6738c20418dSGerald Jelinek ( cd "$ARCHIVE_BASE" && pax -r -f "$archive" $filtopt ) 674eba00995S 675eba00995S post_unpack 676eba00995S 677cec6066bS return 0 678edfa49ffS} 679edfa49ffS 680edfa49ffS# 681edfa49ffS# Unpack UFS dump into zoneroot. 682edfa49ffS# 683edfa49ffSinstall_ufsdump() 684edfa49ffS{ 685edfa49ffS archive=$1 686edfa49ffS 687eba00995S vlog "cd \"$ZONEROOT\" && ufsrestore rf \"$archive\"" 688edfa49ffS 689edfa49ffS # 690edfa49ffS # ufsrestore goes interactive if you ^C it. To prevent that, 691edfa49ffS # we make sure its stdin is not a terminal. 692edfa49ffS # 693eba00995S ( cd "$ZONEROOT" && ufsrestore rf "$archive" < /dev/null ) 694eba00995S result=$? 695eba00995S 696eba00995S post_unpack 697eba00995S 698eba00995S return $result 699edfa49ffS} 700edfa49ffS 701edfa49ffS# 702edfa49ffS# Copy directory hierarchy into zoneroot. 703edfa49ffS# 704edfa49ffSinstall_dir() 705edfa49ffS{ 706edfa49ffS source_dir=$1 707edfa49ffS 708edfa49ffS cpioopts="-pdm" 709edfa49ffS 710edfa49ffS first=1 7116e1ae2a3SGary Pennington filt=$(for i in $(cat $fspaxfile) 712edfa49ffS do 713edfa49ffS echo $i | egrep -s "/" && continue 714edfa49ffS if [[ $first == 1 ]]; then 715edfa49ffS printf "^%s" $i 716edfa49ffS first=0 717edfa49ffS else 718edfa49ffS printf "|^%s" $i 719edfa49ffS fi 720edfa49ffS done) 721edfa49ffS 722edfa49ffS list=$(cd "$source_dir" && ls -d * | egrep -v "$filt") 723edfa49ffS flist=$(for i in $list 724edfa49ffS do 725edfa49ffS printf "%s " "$i" 726edfa49ffS done) 727edfa49ffS findopts="-xdev ( -type d -o -type f -o -type l ) -print" 728edfa49ffS 729edfa49ffS vlog "cd \"$source_dir\" && find $flist $findopts | " 730eba00995S vlog "cpio $cpioopts \"$ZONEROOT\"" 731edfa49ffS 732cec6066bS # Ignore errors from cpio since we expect some errors depending on 733cec6066bS # how the archive was made. 734edfa49ffS ( cd "$source_dir" && find $flist $findopts | \ 735eba00995S cpio $cpioopts "$ZONEROOT" ) 736eba00995S 737eba00995S post_unpack 738eba00995S 739cec6066bS return 0 740edfa49ffS} 741edfa49ffS 74274bbcaa8S# 74374bbcaa8S# This is a common function for laying down a zone image from a variety of 74474bbcaa8S# different sources. This can be used to either install a fresh zone or as 74574bbcaa8S# part of zone migration during attach. 74674bbcaa8S# 74774bbcaa8S# The first argument specifies the type of image: archive, directory or stdin. 74874bbcaa8S# The second argument specifies the image itself. In the case of stdin, the 74974bbcaa8S# second argument specifies the format of the stream (cpio, flar, etc.). 75074bbcaa8S# Any validation or post-processing on the image is done elsewhere. 75174bbcaa8S# 75274bbcaa8S# This function calls a 'sanity_check' function which must be provided by 75374bbcaa8S# the script which includes this code. 75474bbcaa8S# 75574bbcaa8Sinstall_image() 75674bbcaa8S{ 75774bbcaa8S intype=$1 75874bbcaa8S insrc=$2 75974bbcaa8S 76074bbcaa8S if [[ -z "$intype" || -z "$insrc" ]]; then 76174bbcaa8S return 1 76274bbcaa8S fi 76374bbcaa8S 76474bbcaa8S filetype="unknown" 76574bbcaa8S filetypename="unknown" 76674bbcaa8S stage1="cat" 76774bbcaa8S 76874bbcaa8S if [[ "$intype" == "directory" ]]; then 76974bbcaa8S if [[ "$insrc" == "-" ]]; then 77074bbcaa8S # Indicates that the existing zonepath is prepopulated. 77174bbcaa8S filetype="existing" 77274bbcaa8S filetypename="existing" 77374bbcaa8S else 77474bbcaa8S if [[ "$(echo $insrc | cut -c 1)" != "/" ]]; then 77574bbcaa8S fatal "$e_path_abs" "$insrc" 77674bbcaa8S fi 77774bbcaa8S 77874bbcaa8S if [[ ! -e "$insrc" ]]; then 77974bbcaa8S log "$e_not_found" "$insrc" 78074bbcaa8S fatal "$e_install_abort" 78174bbcaa8S fi 78274bbcaa8S 78374bbcaa8S if [[ ! -r "$insrc" ]]; then 78474bbcaa8S log "$e_not_readable" "$insrc" 78574bbcaa8S fatal "$e_install_abort" 78674bbcaa8S fi 78774bbcaa8S 78874bbcaa8S if [[ ! -d "$insrc" ]]; then 78974bbcaa8S log "$e_not_dir" 79074bbcaa8S fatal "$e_install_abort" 79174bbcaa8S fi 79274bbcaa8S 79374bbcaa8S sanity_check $insrc 79474bbcaa8S 79574bbcaa8S filetype="directory" 79674bbcaa8S filetypename="directory" 79774bbcaa8S fi 79874bbcaa8S 79974bbcaa8S else 80074bbcaa8S # Common code for both archive and stdin stream. 80174bbcaa8S 80274bbcaa8S if [[ "$intype" == "archive" ]]; then 80374bbcaa8S if [[ ! -f "$insrc" ]]; then 80474bbcaa8S log "$e_unknown_archive" 80574bbcaa8S fatal "$e_install_abort" 80674bbcaa8S fi 80774bbcaa8S ftype="$(LC_ALL=C file $insrc | cut -d: -f 2)" 80874bbcaa8S else 80974bbcaa8S # For intype == stdin, the insrc parameter specifies 81074bbcaa8S # the stream format coming on stdin. 81174bbcaa8S ftype="$insrc" 81274bbcaa8S insrc="-" 81374bbcaa8S fi 81474bbcaa8S 81574bbcaa8S # Setup vars for the archive type we have. 81674bbcaa8S case "$ftype" in 81774bbcaa8S *cpio*) filetype="cpio" 81874bbcaa8S filetypename="cpio archive" 81974bbcaa8S ;; 82074bbcaa8S *bzip2*) filetype="bzip2" 82174bbcaa8S filetypename="bzipped cpio archive" 82274bbcaa8S ;; 82374bbcaa8S *gzip*) filetype="gzip" 82474bbcaa8S filetypename="gzipped cpio archive" 82574bbcaa8S ;; 82674bbcaa8S *ufsdump*) filetype="ufsdump" 82774bbcaa8S filetypename="ufsdump archive" 82874bbcaa8S ;; 82974bbcaa8S "flar") 83074bbcaa8S filetype="flar" 83174bbcaa8S filetypename="flash archive" 83274bbcaa8S ;; 83374bbcaa8S "flash") 83474bbcaa8S filetype="flar" 83574bbcaa8S filetypename="flash archive" 83674bbcaa8S ;; 83774bbcaa8S *Flash\ Archive*) 83874bbcaa8S filetype="flar" 83974bbcaa8S filetypename="flash archive" 84074bbcaa8S ;; 84174bbcaa8S "tar") 84274bbcaa8S filetype="tar" 84374bbcaa8S filetypename="tar archive" 84474bbcaa8S ;; 84574bbcaa8S *USTAR\ tar\ archive) 84674bbcaa8S filetype="tar" 84774bbcaa8S filetypename="tar archive" 84874bbcaa8S ;; 84974bbcaa8S "pax") 85074bbcaa8S filetype="xustar" 85174bbcaa8S filetypename="pax (xustar) archive" 85274bbcaa8S ;; 85374bbcaa8S *USTAR\ tar\ archive\ extended\ format*) 85474bbcaa8S filetype="xustar" 85574bbcaa8S filetypename="pax (xustar) archive" 85674bbcaa8S ;; 85774bbcaa8S "zfs") 85874bbcaa8S filetype="zfs" 85974bbcaa8S filetypename="ZFS send stream" 86074bbcaa8S ;; 86174bbcaa8S *ZFS\ snapshot\ stream*) 86274bbcaa8S filetype="zfs" 86374bbcaa8S filetypename="ZFS send stream" 86474bbcaa8S ;; 86574bbcaa8S *) log "$e_unknown_archive" 86674bbcaa8S fatal "$e_install_abort" 86774bbcaa8S ;; 86874bbcaa8S esac 86974bbcaa8S fi 87074bbcaa8S 87174bbcaa8S vlog "$filetypename" 87274bbcaa8S 87374bbcaa8S # Check for a non-empty root if no '-d -' option. 87474bbcaa8S if [[ "$filetype" != "existing" ]]; then 87574bbcaa8S cnt=$(ls $ZONEROOT | wc -l) 87674bbcaa8S if (( $cnt != 0 )); then 87774bbcaa8S fatal "$e_root_full" "$ZONEROOT" 87874bbcaa8S fi 87974bbcaa8S fi 88074bbcaa8S 88174bbcaa8S fstmpfile=$(/usr/bin/mktemp -t -p /var/tmp) 88274bbcaa8S if [[ -z "$fstmpfile" ]]; then 88374bbcaa8S fatal "$e_tmpfile" 88474bbcaa8S fi 88574bbcaa8S 88674bbcaa8S # Make sure we always have the files holding the directories to filter 88774bbcaa8S # out when extracting from a CPIO or PAX archive. We'll add the fs 8886e1ae2a3SGary Pennington # entries to these files in get_fs_info() 8896e1ae2a3SGary Pennington fscpiofile=$(/usr/bin/mktemp -t -p /var/tmp fs.cpio.XXXXXX) 8906e1ae2a3SGary Pennington if [[ -z "$fscpiofile" ]]; then 89174bbcaa8S rm -f $fstmpfile 89274bbcaa8S fatal "$e_tmpfile" 89374bbcaa8S fi 89474bbcaa8S 8956e1ae2a3SGary Pennington # Filter out these directories. 8966e1ae2a3SGary Pennington echo 'dev/*' >>$fscpiofile 8976e1ae2a3SGary Pennington echo 'devices/*' >>$fscpiofile 8986e1ae2a3SGary Pennington echo 'devices' >>$fscpiofile 8996e1ae2a3SGary Pennington echo 'proc/*' >>$fscpiofile 9006e1ae2a3SGary Pennington echo 'tmp/*' >>$fscpiofile 9016e1ae2a3SGary Pennington echo 'var/run/*' >>$fscpiofile 9026e1ae2a3SGary Pennington echo 'system/contract/*' >>$fscpiofile 9036e1ae2a3SGary Pennington echo 'system/object/*' >>$fscpiofile 9046e1ae2a3SGary Pennington 9056e1ae2a3SGary Pennington fspaxfile=$(/usr/bin/mktemp -t -p /var/tmp fs.pax.XXXXXX) 9066e1ae2a3SGary Pennington if [[ -z "$fspaxfile" ]]; then 9076e1ae2a3SGary Pennington rm -f $fstmpfile $fscpiofile 90874bbcaa8S fatal "$e_tmpfile" 90974bbcaa8S fi 91074bbcaa8S 91174bbcaa8S printf "%s " \ 91274bbcaa8S "dev devices proc tmp var/run system/contract system/object" \ 9136e1ae2a3SGary Pennington >>$fspaxfile 91474bbcaa8S 91574bbcaa8S # Set up any fs mounts so the archive will install into the correct 91674bbcaa8S # locations. 91774bbcaa8S get_fs_info 91874bbcaa8S mnt_fs 91974bbcaa8S if (( $? != 0 )); then 92074bbcaa8S umnt_fs >/dev/null 2>&1 9216e1ae2a3SGary Pennington rm -f $fstmpfile $fscpiofile $fspaxfile 92274bbcaa8S fatal "$mount_failed" 92374bbcaa8S fi 92474bbcaa8S 92574bbcaa8S if [[ "$filetype" == "existing" ]]; then 92674bbcaa8S log "$no_installing" 92774bbcaa8S else 92874bbcaa8S log "$installing" 92974bbcaa8S fi 93074bbcaa8S 93174bbcaa8S # 93274bbcaa8S # Install the image into the zonepath. 93374bbcaa8S # 93474bbcaa8S unpack_result=0 93574bbcaa8S stage1="cat" 93674bbcaa8S if [[ "$filetype" == "gzip" ]]; then 93774bbcaa8S stage1="gzcat" 93874bbcaa8S filetype="cpio" 93974bbcaa8S elif [[ "$filetype" == "bzip2" ]]; then 94074bbcaa8S stage1="bzcat" 94174bbcaa8S filetype="cpio" 94274bbcaa8S fi 94374bbcaa8S 94474bbcaa8S if [[ "$filetype" == "cpio" ]]; then 94574bbcaa8S install_cpio "$stage1" "$insrc" 94674bbcaa8S unpack_result=$? 94774bbcaa8S 94874bbcaa8S elif [[ "$filetype" == "flar" ]]; then 94974bbcaa8S ( cd "$ZONEROOT" && $stage1 $insrc | install_flar ) 95074bbcaa8S unpack_result=$? 95174bbcaa8S 95274bbcaa8S elif [[ "$filetype" == "xustar" ]]; then 95374bbcaa8S install_pax "$insrc" 95474bbcaa8S unpack_result=$? 95574bbcaa8S 95674bbcaa8S elif [[ "$filetype" = "tar" ]]; then 95774bbcaa8S vlog "cd \"$ZONEROOT\" && tar -xf \"$insrc\"" 958cec6066bS # Ignore errors from tar since we expect some errors depending 959cec6066bS # on how the archive was made. 96074bbcaa8S ( cd "$ZONEROOT" && tar -xf "$insrc" ) 961cec6066bS unpack_result=0 96274bbcaa8S post_unpack 96374bbcaa8S 96474bbcaa8S elif [[ "$filetype" == "ufsdump" ]]; then 96574bbcaa8S install_ufsdump "$insrc" 96674bbcaa8S unpack_result=$? 96774bbcaa8S 96874bbcaa8S elif [[ "$filetype" == "directory" ]]; then 96974bbcaa8S install_dir "$insrc" 97074bbcaa8S unpack_result=$? 97174bbcaa8S 97274bbcaa8S elif [[ "$filetype" == "zfs" ]]; then 97374bbcaa8S # 97474bbcaa8S # Given a 'zfs send' stream file, receive the snapshot into 97574bbcaa8S # the zone's dataset. We're getting the original system's 97674bbcaa8S # zonepath dataset. Destroy the existing dataset created 97774bbcaa8S # above since this recreates it. 97874bbcaa8S # 97974bbcaa8S if [[ -z "$DATASET" ]]; then 98074bbcaa8S fatal "$f_nodataset" 98174bbcaa8S fi 98274bbcaa8S /usr/sbin/zfs destroy "$DATASET" 98374bbcaa8S if (( $? != 0 )); then 98474bbcaa8S log "$f_zfsdestroy" "$DATASET" 98574bbcaa8S fi 98674bbcaa8S 98774bbcaa8S vlog "$stage1 $insrc | zfs receive -F $DATASET" 98874bbcaa8S ( $stage1 $insrc | /usr/sbin/zfs receive -F $DATASET ) 98974bbcaa8S unpack_result=$? 99074bbcaa8S fi 99174bbcaa8S 99274bbcaa8S # Clean up any fs mounts used during unpacking. 99374bbcaa8S umnt_fs 9946e1ae2a3SGary Pennington rm -f $fstmpfile $fscpiofile $fspaxfile 99574bbcaa8S 99674bbcaa8S chmod 700 $zonepath 99774bbcaa8S 998cec6066bS (( $unpack_result != 0 )) && fatal "$f_unpack_failed" 999cec6066bS 100074bbcaa8S # Verify this is a valid image. 100174bbcaa8S sanity_check $ZONEROOT 100274bbcaa8S 100374bbcaa8S return 0 100474bbcaa8S} 100574bbcaa8S 1006edfa49ffS# Setup i18n output 1007edfa49ffSTEXTDOMAIN="SUNW_OST_OSCMD" 1008edfa49ffSexport TEXTDOMAIN 1009edfa49ffS 1010ae104932SJonathan Adamse_cannot_wrap=$(gettext "%s: error: wrapper file already exists") 1011edfa49ffSe_baddir=$(gettext "Invalid '%s' directory within the zone") 1012edfa49ffSe_badfile=$(gettext "Invalid '%s' file within the zone") 101374bbcaa8Se_path_abs=$(gettext "Pathname specified to -a '%s' must be absolute.") 101474bbcaa8Se_not_found=$(gettext "%s: error: file or directory not found.") 101574bbcaa8Se_install_abort=$(gettext "Installation aborted.") 101674bbcaa8Se_not_readable=$(gettext "Cannot read directory '%s'") 101774bbcaa8Se_not_dir=$(gettext "Error: must be a directory") 101874bbcaa8Se_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.") 101962ac5336Se_absolute_archive=$(gettext "Error: archive contains absolute paths instead of relative paths.") 10208c20418dSGerald Jelineke_mismatch_archive=$(gettext "Error: the archive top-level directory (%s) does not match the zonepath (%s).") 102174bbcaa8Se_tmpfile=$(gettext "Unable to create temporary file") 102274bbcaa8Se_root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.") 1023e71ca95cSGerald Jelinekf_mkdir=$(gettext "Unable to create directory %s.") 1024e71ca95cSGerald Jelinekf_chmod=$(gettext "Unable to chmod directory %s.") 1025e71ca95cSGerald Jelinekf_chown=$(gettext "Unable to chown directory %s.") 102619b77901Sf_hwcap_info=$(gettext "HWCAP: %s\n") 102719b77901Sf_sanity_hwcap=$(gettext \ 102819b77901S"The image was created with an incompatible libc.so.1 hwcap lofs mount.\n"\ 102919b77901S" The zone will not boot on this platform. See the zone's\n"\ 103019b77901S" documentation for the recommended way to create the archive.") 103174bbcaa8S 10328c20418dSGerald Jelinekm_analyse_archive=$(gettext "Analysing the archive") 10338c20418dSGerald Jelinek 103474bbcaa8Snot_readable=$(gettext "Cannot read file '%s'") 103574bbcaa8Snot_flar=$(gettext "Input is not a flash archive") 103674bbcaa8Sbad_flar=$(gettext "Flash archive is a corrupt") 1037cec6066bSbad_zfs_flar=$(gettext "Flash archive contains a ZFS send stream.\n\tRecreate the flar using the -L option with cpio or pax.") 1038cec6066bSf_unpack_failed=$(gettext "Unpacking the archive failed") 103974bbcaa8Sunknown_archiver=$(gettext "Archiver %s is not supported") 104074bbcaa8Scmd_not_exec=$(gettext "Required command '%s' not executable!") 1041edfa49ffS 1042edfa49ffS# 1043edfa49ffS# Exit values used by the script, as #defined in <sys/zone.h> 1044edfa49ffS# 1045edfa49ffS# ZONE_SUBPROC_OK 1046edfa49ffS# =============== 1047edfa49ffS# Installation was successful 1048edfa49ffS# 1049edfa49ffS# ZONE_SUBPROC_USAGE 1050edfa49ffS# ================== 1051edfa49ffS# Improper arguments were passed, so print a usage message before exiting 1052edfa49ffS# 1053edfa49ffS# ZONE_SUBPROC_NOTCOMPLETE 1054edfa49ffS# ======================== 1055edfa49ffS# Installation did not complete, but another installation attempt can be 1056edfa49ffS# made without an uninstall 1057edfa49ffS# 1058edfa49ffS# ZONE_SUBPROC_FATAL 1059edfa49ffS# ================== 1060edfa49ffS# Installation failed and an uninstall will be required before another 1061edfa49ffS# install can be attempted 1062edfa49ffS# 1063edfa49ffSZONE_SUBPROC_OK=0 1064edfa49ffSZONE_SUBPROC_USAGE=253 1065edfa49ffSZONE_SUBPROC_NOTCOMPLETE=254 1066edfa49ffSZONE_SUBPROC_FATAL=255 1067edfa49ffS 1068