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() { 46*19b77901S typeset fmt="$1" 47*19b77901S shift 48*19b77901S 49*19b77901S 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# 329*19b77901S# Perform validation and cleanup in the zoneroot after unpacking the archive. 330eba00995S# 331eba00995Spost_unpack() 332eba00995S{ 333*19b77901S # 334*19b77901S # Check if the image was created with a valid libc.so.1. 335*19b77901S # 336*19b77901S hwcap=`moe -v -32 $ZONEROOT/lib/libc.so.1 2>&1` 337*19b77901S if (( $? != 0 )); then 338*19b77901S vlog "$f_hwcap_info" "$hwcap" 339*19b77901S fail_fatal "$f_sanity_hwcap" 340*19b77901S fi 341*19b77901S 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 5548c20418dSGerald Jelinek# of a physical sytem. 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.") 1026*19b77901Sf_hwcap_info=$(gettext "HWCAP: %s\n") 1027*19b77901Sf_sanity_hwcap=$(gettext \ 1028*19b77901S"The image was created with an incompatible libc.so.1 hwcap lofs mount.\n"\ 1029*19b77901S" The zone will not boot on this platform. See the zone's\n"\ 1030*19b77901S" 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