1# 2# CDDL HEADER START 3# 4# The contents of this file are subject to the terms of the 5# Common Development and Distribution License (the "License"). 6# You may not use this file except in compliance with the License. 7# 8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9# or http://www.opensolaris.org/os/licensing. 10# See the License for the specific language governing permissions 11# and limitations under the License. 12# 13# When distributing Covered Code, include this CDDL HEADER in each 14# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15# If applicable, add the following below this CDDL HEADER, with the 16# fields enclosed by brackets "[]" replaced with your own identifying 17# information: Portions Copyright [yyyy] [name of copyright owner] 18# 19# CDDL HEADER END 20# 21# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 22# Use is subject to license terms. 23# 24 25# 26# Send the error message to the screen and to the logfile. 27# 28error() 29{ 30 typeset fmt="$1" 31 shift 32 33 printf "${MSG_PREFIX}ERROR: ${fmt}\n" "$@" 34 [[ -n $LOGFILE ]] && printf "[$(date)] ERROR: ${fmt}\n" "$@" >&2 35} 36 37fatal() 38{ 39 typeset fmt="$1" 40 shift 41 42 error "$fmt" "$@" 43 exit $EXIT_CODE 44} 45 46# 47# Send the provided printf()-style arguments to the screen and to the logfile. 48# 49log() 50{ 51 typeset fmt="$1" 52 shift 53 54 printf "${MSG_PREFIX}${fmt}\n" "$@" 55 [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2 56} 57 58# 59# Print provided text to the screen if the shell variable "OPT_V" is set. 60# The text is always sent to the logfile. 61# 62vlog() 63{ 64 typeset fmt="$1" 65 shift 66 67 [[ -n $OPT_V ]] && printf "${MSG_PREFIX}${fmt}\n" "$@" 68 [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2 69} 70 71# Validate that the directory is safe. 72safe_dir() 73{ 74 typeset dir="$1" 75 76 if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then 77 fatal "$e_baddir" "$dir" 78 fi 79} 80 81# Only make a copy if we haven't already done so. 82safe_backup() 83{ 84 typeset src="$1" 85 typeset dst="$2" 86 87 if [[ ! -h $src && ! -h $dst && ! -d $dst && ! -f $dst ]]; then 88 /usr/bin/cp -p $src $dst || fatal "$e_badfile" "$src" 89 fi 90} 91 92# Make a copy even if the destination already exists. 93safe_copy() 94{ 95 typeset src="$1" 96 typeset dst="$2" 97 98 if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then 99 /usr/bin/cp -p $src $dst || fatal "$e_badfile" "$src" 100 fi 101} 102 103# Move a file 104safe_move() 105{ 106 typeset src="$1" 107 typeset dst="$2" 108 109 if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then 110 /usr/bin/mv $src $dst || fatal "$e_badfile" "$src" 111 fi 112} 113 114# 115# Read zonecfg ipd and fs entries and save the relevant data, one entry per 116# line. 117# This assumes the properties from the zonecfg output, e.g.: 118# inherit-pkg-dir: 119# dir: /usr 120# fs: 121# dir: /opt 122# special: /opt 123# raw not specified 124# type: lofs 125# options: [noexec,ro,noatime] 126# 127# and it assumes the order of the fs properties as above. This also saves the 128# inherit-pkg-dir patterns into the ipd.{cpio|pax} temporary files for 129# filtering while extracting the image into the zonepath. We have to save the 130# IPD patterns in the appropriate format for filtering with the different 131# archivers and we don't know what format we'll get until after the flash 132# archive is unpacked. 133# 134get_fs_info() 135{ 136 zonecfg -z $zonename info inherit-pkg-dir | \ 137 nawk -v ipdcpiof=$ipdcpiofile -v ipdpaxf=$ipdpaxfile '{ 138 if ($1 == "dir:") { 139 dir=$2; 140 printf("%s lofs %s ro\n", dir, dir); 141 142 if (substr(dir, 1, 1) == "/") { 143 printf("%s\n", substr(dir, 2)) >> ipdcpiof 144 printf("%s/*\n", substr(dir, 2)) >> ipdcpiof 145 } else { 146 printf("%s\n", dir) >> ipdcpiof 147 printf("%s/*\n", dir) >> ipdcpiof 148 } 149 150 if (substr(dir, 1, 1) == "/") { 151 printf("%s ", substr(dir, 2)) >> ipdpaxf 152 } else { 153 printf("%s ", dir) >> ipdpaxf 154 } 155 } 156 }' >> $fstmpfile 157 158 zonecfg -z $zonename info fs | nawk '{ 159 if ($1 == "options:") { 160 # Remove brackets. 161 options=substr($2, 2, length($2) - 2); 162 printf("%s %s %s %s\n", dir, type, special, options); 163 } else if ($1 == "dir:") { 164 dir=$2; 165 } else if ($1 == "special:") { 166 special=$2; 167 } else if ($1 == "type:") { 168 type=$2 169 } 170 }' >> $fstmpfile 171} 172 173# 174# Mount zonecfg fs entries into the zonepath. 175# 176mnt_fs() 177{ 178 if [ ! -s $fstmpfile ]; then 179 return; 180 fi 181 182 # Sort the fs entries so we can handle nested mounts. 183 sort $fstmpfile | nawk -v zonepath=$zonepath '{ 184 if (NF == 4) 185 options="-o " $4; 186 else 187 options="" 188 189 # Create the mount point. Ignore errors since we might have 190 # a nested mount with a pre-existing mount point. 191 cmd="/usr/bin/mkdir -p " zonepath "/root" $1 " >/dev/null 2>&1" 192 system(cmd); 193 194 cmd="/usr/sbin/mount -F " $2 " " options " " $3 " " \ 195 zonepath "/root" $1; 196 if (system(cmd) != 0) { 197 printf("command failed: %s\n", cmd); 198 exit 1; 199 } 200 }' >>$LOGFILE 201} 202 203# 204# Unmount zonecfg fs entries from the zonepath. 205# 206umnt_fs() 207{ 208 if [ ! -s $fstmpfile ]; then 209 return; 210 fi 211 212 # Reverse sort the fs entries so we can handle nested unmounts. 213 sort -r $fstmpfile | nawk -v zonepath=$zonepath '{ 214 cmd="/usr/sbin/umount " zonepath "/root" $1 215 if (system(cmd) != 0) { 216 printf("command failed: %s\n", cmd); 217 } 218 }' >>$LOGFILE 219} 220 221# 222# Perform any cleanup in the zoneroot after unpacking the archive. 223# 224post_unpack() 225{ 226 ( cd "$ZONEROOT" && \ 227 find . \( -type b -o -type c \) -exec rm -f "{}" \; ) 228} 229 230# 231# Determine flar compression style from identification file. 232# 233get_compression() 234{ 235 typeset ident=$1 236 typeset line=$(grep "^files_compressed_method=" $ident) 237 238 print ${line##*=} 239} 240 241# 242# Determine flar archive style from identification file. 243# 244get_archiver() 245{ 246 typeset ident=$1 247 typeset line=$(grep "^files_archived_method=" $ident) 248 249 print ${line##*=} 250} 251 252# 253# Unpack flar into current directory (which should be zoneroot). The flash 254# archive is standard input. See flash_archive(4) man page. 255# 256# We can't use "flar split" since it will only unpack into a directory called 257# "archive". We need to unpack in place in order to properly handle nested 258# fs mounts within the zone root. This function does the unpacking into the 259# current directory. 260# 261# This code is derived from the gen_split() function in /usr/sbin/flar so 262# we keep the same style as the original. 263# 264install_flar() 265{ 266 typeset result 267 typeset archiver_command 268 typeset archiver_arguments 269 270 vlog "cd $ZONEROOT && $stage1 "$insrc" | install_flar" 271 272 # Read cookie 273 read -r input_line 274 if (( $? != 0 )); then 275 log "$not_readable" "$install_media" 276 return 1 277 fi 278 # The cookie has format FlAsH-aRcHiVe-m.n where m and n are integers. 279 if [[ ${input_line%%-[0-9]*.[0-9]*} != "FlAsH-aRcHiVe" ]]; then 280 log "$not_flar" 281 return 1 282 fi 283 284 while [ true ] 285 do 286 # We should always be at the start of a section here 287 read -r input_line 288 if [[ ${input_line%%=*} != "section_begin" ]]; then 289 log "$bad_flar" 290 return 1 291 fi 292 section_name=${input_line##*=} 293 294 # If we're at the archive, we're done skipping sections. 295 if [[ "$section_name" == "archive" ]]; then 296 break 297 fi 298 299 # 300 # Save identification section to a file so we can determine 301 # how to unpack the archive. 302 # 303 if [[ "$section_name" == "identification" ]]; then 304 /usr/bin/rm -f identification 305 while read -r input_line 306 do 307 if [[ ${input_line%%=*} == \ 308 "section_begin" ]]; then 309 /usr/bin/rm -f identification 310 log "$bad_flar" 311 return 1 312 fi 313 314 if [[ $input_line == \ 315 "section_end=$section_name" ]]; then 316 break; 317 fi 318 echo $input_line >> identification 319 done 320 321 continue 322 fi 323 324 # 325 # Otherwise skip past this section; read lines until detecting 326 # section_end. According to flash_archive(4) we can have 327 # an arbitrary number of sections but the archive section 328 # must be last. 329 # 330 success=0 331 while read -r input_line 332 do 333 if [[ $input_line == "section_end=$section_name" ]]; 334 then 335 success=1 336 break 337 fi 338 # Fail if we miss the end of the section 339 if [[ ${input_line%%=*} == "section_begin" ]]; then 340 /usr/bin/rm -f identification 341 log "$bad_flar" 342 return 1 343 fi 344 done 345 if (( $success == 0 )); then 346 # 347 # If we get here we read to the end of the file before 348 # seeing the end of the section we were reading. 349 # 350 /usr/bin/rm -f identification 351 log "$bad_flar" 352 return 1 353 fi 354 done 355 356 # Get the information needed to unpack the archive. 357 archiver=$(get_archiver identification) 358 if [[ $archiver == "pax" ]]; then 359 # pax archiver specified 360 archiver_command="/usr/bin/pax" 361 if [[ -s $ipdpaxfile ]]; then 362 archiver_arguments="-r -p e -c \ 363 $(/usr/bin/cat $ipdpaxfile)" 364 else 365 archiver_arguments="-r -p e" 366 fi 367 elif [[ $archiver == "cpio" || -z $archiver ]]; then 368 # cpio archived specified OR no archiver specified - use default 369 archiver_command="/usr/bin/cpio" 370 archiver_arguments="-icdumfE $ipdcpiofile" 371 else 372 # unknown archiver specified 373 log "$unknown_archiver" $archiver 374 return 1 375 fi 376 377 if [[ ! -x $archiver_command ]]; then 378 /usr/bin/rm -f identification 379 log "$cmd_not_exec" $archiver_command 380 return 1 381 fi 382 383 compression=$(get_compression identification) 384 385 # We're done with the identification file 386 /usr/bin/rm -f identification 387 388 # Extract archive 389 if [[ $compression == "compress" ]]; then 390 /usr/bin/zcat | \ 391 $archiver_command $archiver_arguments 2>/dev/null 392 else 393 $archiver_command $archiver_arguments 2>/dev/null 394 fi 395 result=$? 396 397 post_unpack 398 399 (( $result != 0 )) && return 1 400 401 return 0 402} 403 404# 405# Unpack cpio archive into zoneroot. 406# 407install_cpio() 408{ 409 stage1=$1 410 archive=$2 411 412 # Check the first few members of the archive for an absolute path. 413 for i in `$stage1 "$archive" | cpio -it | head | cut -b1` 414 do 415 if [[ "$i" == "/" ]]; then 416 umnt_fs 417 fatal "$e_absolute_archive" 418 fi 419 done 420 421 cpioopts="-idmfE $ipdcpiofile" 422 423 vlog "cd \"$ZONEROOT\" && $stage1 \"$archive\" | cpio $cpioopts" 424 425 ( cd "$ZONEROOT" && $stage1 "$archive" | cpio $cpioopts ) 426 result=$? 427 428 post_unpack 429 430 return $result 431} 432 433# 434# Unpack pax archive into zoneroot. 435# 436install_pax() 437{ 438 archive=$1 439 440 # Check the first few members of the archive for an absolute path. 441 for i in `pax -f "$archive" | head | cut -b1` 442 do 443 if [[ "$i" == "/" ]]; then 444 umnt_fs 445 fatal "$e_absolute_archive" 446 fi 447 done 448 449 if [[ -s $ipdpaxfile ]]; then 450 filtopt="-c $(/usr/bin/cat $ipdpaxfile)" 451 fi 452 453 vlog "cd \"$ZONEROOT\" && pax -r -f \"$archive\" $filtopt" 454 455 ( cd "$ZONEROOT" && pax -r -f "$archive" $filtopt ) 456 result=$? 457 458 post_unpack 459 460 return $result 461} 462 463# 464# Unpack UFS dump into zoneroot. 465# 466install_ufsdump() 467{ 468 archive=$1 469 470 vlog "cd \"$ZONEROOT\" && ufsrestore rf \"$archive\"" 471 472 # 473 # ufsrestore goes interactive if you ^C it. To prevent that, 474 # we make sure its stdin is not a terminal. 475 # Note that there is no way to filter inherit-pkg-dirs for a full 476 # restore so there will be warnings in the log file. 477 # 478 ( cd "$ZONEROOT" && ufsrestore rf "$archive" < /dev/null ) 479 result=$? 480 481 post_unpack 482 483 return $result 484} 485 486# 487# Copy directory hierarchy into zoneroot. 488# 489install_dir() 490{ 491 source_dir=$1 492 493 cpioopts="-pdm" 494 495 first=1 496 filt=$(for i in $(cat $ipdpaxfile) 497 do 498 echo $i | egrep -s "/" && continue 499 if [[ $first == 1 ]]; then 500 printf "^%s" $i 501 first=0 502 else 503 printf "|^%s" $i 504 fi 505 done) 506 507 list=$(cd "$source_dir" && ls -d * | egrep -v "$filt") 508 flist=$(for i in $list 509 do 510 printf "%s " "$i" 511 done) 512 findopts="-xdev ( -type d -o -type f -o -type l ) -print" 513 514 vlog "cd \"$source_dir\" && find $flist $findopts | " 515 vlog "cpio $cpioopts \"$ZONEROOT\"" 516 517 ( cd "$source_dir" && find $flist $findopts | \ 518 cpio $cpioopts "$ZONEROOT" ) 519 result=$? 520 521 post_unpack 522 523 return $result 524} 525 526# 527# This is a common function for laying down a zone image from a variety of 528# different sources. This can be used to either install a fresh zone or as 529# part of zone migration during attach. 530# 531# The first argument specifies the type of image: archive, directory or stdin. 532# The second argument specifies the image itself. In the case of stdin, the 533# second argument specifies the format of the stream (cpio, flar, etc.). 534# Any validation or post-processing on the image is done elsewhere. 535# 536# This function calls a 'sanity_check' function which must be provided by 537# the script which includes this code. 538# 539install_image() 540{ 541 intype=$1 542 insrc=$2 543 544 if [[ -z "$intype" || -z "$insrc" ]]; then 545 return 1 546 fi 547 548 filetype="unknown" 549 filetypename="unknown" 550 stage1="cat" 551 552 if [[ "$intype" == "directory" ]]; then 553 if [[ "$insrc" == "-" ]]; then 554 # Indicates that the existing zonepath is prepopulated. 555 filetype="existing" 556 filetypename="existing" 557 else 558 if [[ "$(echo $insrc | cut -c 1)" != "/" ]]; then 559 fatal "$e_path_abs" "$insrc" 560 fi 561 562 if [[ ! -e "$insrc" ]]; then 563 log "$e_not_found" "$insrc" 564 fatal "$e_install_abort" 565 fi 566 567 if [[ ! -r "$insrc" ]]; then 568 log "$e_not_readable" "$insrc" 569 fatal "$e_install_abort" 570 fi 571 572 if [[ ! -d "$insrc" ]]; then 573 log "$e_not_dir" 574 fatal "$e_install_abort" 575 fi 576 577 sanity_check $insrc 578 579 filetype="directory" 580 filetypename="directory" 581 fi 582 583 else 584 # Common code for both archive and stdin stream. 585 586 if [[ "$intype" == "archive" ]]; then 587 if [[ ! -f "$insrc" ]]; then 588 log "$e_unknown_archive" 589 fatal "$e_install_abort" 590 fi 591 ftype="$(LC_ALL=C file $insrc | cut -d: -f 2)" 592 else 593 # For intype == stdin, the insrc parameter specifies 594 # the stream format coming on stdin. 595 ftype="$insrc" 596 insrc="-" 597 fi 598 599 # Setup vars for the archive type we have. 600 case "$ftype" in 601 *cpio*) filetype="cpio" 602 filetypename="cpio archive" 603 ;; 604 *bzip2*) filetype="bzip2" 605 filetypename="bzipped cpio archive" 606 ;; 607 *gzip*) filetype="gzip" 608 filetypename="gzipped cpio archive" 609 ;; 610 *ufsdump*) filetype="ufsdump" 611 filetypename="ufsdump archive" 612 ;; 613 "flar") 614 filetype="flar" 615 filetypename="flash archive" 616 ;; 617 "flash") 618 filetype="flar" 619 filetypename="flash archive" 620 ;; 621 *Flash\ Archive*) 622 filetype="flar" 623 filetypename="flash archive" 624 ;; 625 "tar") 626 filetype="tar" 627 filetypename="tar archive" 628 ;; 629 *USTAR\ tar\ archive) 630 filetype="tar" 631 filetypename="tar archive" 632 ;; 633 "pax") 634 filetype="xustar" 635 filetypename="pax (xustar) archive" 636 ;; 637 *USTAR\ tar\ archive\ extended\ format*) 638 filetype="xustar" 639 filetypename="pax (xustar) archive" 640 ;; 641 "zfs") 642 filetype="zfs" 643 filetypename="ZFS send stream" 644 ;; 645 *ZFS\ snapshot\ stream*) 646 filetype="zfs" 647 filetypename="ZFS send stream" 648 ;; 649 *) log "$e_unknown_archive" 650 fatal "$e_install_abort" 651 ;; 652 esac 653 fi 654 655 vlog "$filetypename" 656 657 # Check for a non-empty root if no '-d -' option. 658 if [[ "$filetype" != "existing" ]]; then 659 cnt=$(ls $ZONEROOT | wc -l) 660 if (( $cnt != 0 )); then 661 fatal "$e_root_full" "$ZONEROOT" 662 fi 663 fi 664 665 fstmpfile=$(/usr/bin/mktemp -t -p /var/tmp) 666 if [[ -z "$fstmpfile" ]]; then 667 fatal "$e_tmpfile" 668 fi 669 670 # Make sure we always have the files holding the directories to filter 671 # out when extracting from a CPIO or PAX archive. We'll add the fs 672 # entries to these files in get_fs_info() (there may be no IPDs for 673 # some brands but thats ok). 674 ipdcpiofile=$(/usr/bin/mktemp -t -p /var/tmp ipd.cpio.XXXXXX) 675 if [[ -z "$ipdcpiofile" ]]; then 676 rm -f $fstmpfile 677 fatal "$e_tmpfile" 678 fi 679 680 # In addition to the IPDs, also filter out these directories. 681 echo 'dev/*' >>$ipdcpiofile 682 echo 'devices/*' >>$ipdcpiofile 683 echo 'devices' >>$ipdcpiofile 684 echo 'proc/*' >>$ipdcpiofile 685 echo 'tmp/*' >>$ipdcpiofile 686 echo 'var/run/*' >>$ipdcpiofile 687 echo 'system/contract/*' >>$ipdcpiofile 688 echo 'system/object/*' >>$ipdcpiofile 689 690 ipdpaxfile=$(/usr/bin/mktemp -t -p /var/tmp ipd.pax.XXXXXX) 691 if [[ -z "$ipdpaxfile" ]]; then 692 rm -f $fstmpfile $ipdcpiofile 693 fatal "$e_tmpfile" 694 fi 695 696 printf "%s " \ 697 "dev devices proc tmp var/run system/contract system/object" \ 698 >>$ipdpaxfile 699 700 # Set up any fs mounts so the archive will install into the correct 701 # locations. 702 get_fs_info 703 mnt_fs 704 if (( $? != 0 )); then 705 umnt_fs >/dev/null 2>&1 706 rm -f $fstmpfile $ipdcpiofile $ipdpaxfile 707 fatal "$mount_failed" 708 fi 709 710 if [[ "$filetype" == "existing" ]]; then 711 log "$no_installing" 712 else 713 log "$installing" 714 fi 715 716 # 717 # Install the image into the zonepath. 718 # 719 unpack_result=0 720 stage1="cat" 721 if [[ "$filetype" == "gzip" ]]; then 722 stage1="gzcat" 723 filetype="cpio" 724 elif [[ "$filetype" == "bzip2" ]]; then 725 stage1="bzcat" 726 filetype="cpio" 727 fi 728 729 if [[ "$filetype" == "cpio" ]]; then 730 install_cpio "$stage1" "$insrc" 731 unpack_result=$? 732 733 elif [[ "$filetype" == "flar" ]]; then 734 ( cd "$ZONEROOT" && $stage1 $insrc | install_flar ) 735 unpack_result=$? 736 737 elif [[ "$filetype" == "xustar" ]]; then 738 install_pax "$insrc" 739 unpack_result=$? 740 741 elif [[ "$filetype" = "tar" ]]; then 742 vlog "cd \"$ZONEROOT\" && tar -xf \"$insrc\"" 743 ( cd "$ZONEROOT" && tar -xf "$insrc" ) 744 unpack_result=$? 745 post_unpack 746 747 elif [[ "$filetype" == "ufsdump" ]]; then 748 install_ufsdump "$insrc" 749 unpack_result=$? 750 751 elif [[ "$filetype" == "directory" ]]; then 752 install_dir "$insrc" 753 unpack_result=$? 754 755 elif [[ "$filetype" == "zfs" ]]; then 756 # 757 # Given a 'zfs send' stream file, receive the snapshot into 758 # the zone's dataset. We're getting the original system's 759 # zonepath dataset. Destroy the existing dataset created 760 # above since this recreates it. 761 # 762 if [[ -z "$DATASET" ]]; then 763 fatal "$f_nodataset" 764 fi 765 /usr/sbin/zfs destroy "$DATASET" 766 if (( $? != 0 )); then 767 log "$f_zfsdestroy" "$DATASET" 768 fi 769 770 vlog "$stage1 $insrc | zfs receive -F $DATASET" 771 ( $stage1 $insrc | /usr/sbin/zfs receive -F $DATASET ) 772 unpack_result=$? 773 fi 774 775 vlog "$unpack_done" $unpack_result 776 777 # Clean up any fs mounts used during unpacking. 778 umnt_fs 779 rm -f $fstmpfile $ipdcpiofile $ipdpaxfile 780 781 # 782 # If the archive was of a zone then the archive might have been made 783 # of the zonepath (single dir), inside the zonepath (dev, root, etc., 784 # or just even just root) or inside the zonepath root (all the top 785 # level dirs). Try to normalize these possibilities. 786 # 787 dirsize=$(ls $ZONEROOT | wc -l) 788 if [[ -d $ZONEROOT/root && -d $ZONEROOT/root/etc && \ 789 -d $ZONEROOT/root/var ]]; then 790 # The archive was made of the zoneroot. 791 mkdir -m 0755 $ZONEPATH/.attach_root 792 mv $ZONEROOT/root/* $ZONEPATH/.attach_root 793 mv $ZONEROOT/root/.[a-zA-Z]* $ZONEPATH/.attach_root \ 794 >/dev/null 2>&1 795 rm -rf $ZONEROOT 796 mv $ZONEPATH/.attach_root $ZONEROOT 797 798 elif (( $dirsize == 1 )); then 799 # The archive was made of the the zonepath. 800 801 dir=$(ls $ZONEROOT) 802 803 if [[ -d $ZONEROOT/$dir/root ]]; then 804 mkdir -m 0755 $ZONEPATH/.attach_root 805 mv $ZONEROOT/$dir/root/* $ZONEPATH/.attach_root 806 mv $ZONEROOT/$dir/root/.[a-zA-Z]* \ 807 $ZONEPATH/.attach_root >/dev/null 2>&1 808 rm -rf $ZONEROOT 809 mv $ZONEPATH/.attach_root $ZONEROOT 810 else 811 # We don't know where this archive was made. 812 fatal "$e_bad_zone_layout" 813 fi 814 815 elif [[ ! -d $ZONEROOT/etc ]]; then 816 # We were expecting that the archive was made inside the 817 # zoneroot but there's no etc dir, so we don't know where 818 # this archive was made. 819 fatal "$e_bad_zone_layout" 820 fi 821 822 chmod 700 $zonepath 823 824 # Verify this is a valid image. 825 sanity_check $ZONEROOT 826 827 return 0 828} 829 830# Setup i18n output 831TEXTDOMAIN="SUNW_OST_OSCMD" 832export TEXTDOMAIN 833 834e_baddir=$(gettext "Invalid '%s' directory within the zone") 835e_badfile=$(gettext "Invalid '%s' file within the zone") 836e_bad_zone_layout=$(gettext "Unexpected zone layout.") 837e_path_abs=$(gettext "Pathname specified to -a '%s' must be absolute.") 838e_not_found=$(gettext "%s: error: file or directory not found.") 839e_install_abort=$(gettext "Installation aborted.") 840e_not_readable=$(gettext "Cannot read directory '%s'") 841e_not_dir=$(gettext "Error: must be a directory") 842e_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.") 843e_absolute_archive=$(gettext "Error: archive contains absolute paths instead of relative paths.") 844e_tmpfile=$(gettext "Unable to create temporary file") 845e_root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.") 846 847 848not_readable=$(gettext "Cannot read file '%s'") 849not_flar=$(gettext "Input is not a flash archive") 850bad_flar=$(gettext "Flash archive is a corrupt") 851unknown_archiver=$(gettext "Archiver %s is not supported") 852cmd_not_exec=$(gettext "Required command '%s' not executable!") 853 854# 855# Exit values used by the script, as #defined in <sys/zone.h> 856# 857# ZONE_SUBPROC_OK 858# =============== 859# Installation was successful 860# 861# ZONE_SUBPROC_USAGE 862# ================== 863# Improper arguments were passed, so print a usage message before exiting 864# 865# ZONE_SUBPROC_NOTCOMPLETE 866# ======================== 867# Installation did not complete, but another installation attempt can be 868# made without an uninstall 869# 870# ZONE_SUBPROC_FATAL 871# ================== 872# Installation failed and an uninstall will be required before another 873# install can be attempted 874# 875ZONE_SUBPROC_OK=0 876ZONE_SUBPROC_USAGE=253 877ZONE_SUBPROC_NOTCOMPLETE=254 878ZONE_SUBPROC_FATAL=255 879 880