1 #!/bin/ksh -p 2 # 3 # CDDL HEADER START 4 # 5 # The contents of this file are subject to the terms of the 6 # Common Development and Distribution License (the "License"). 7 # You may not use this file except in compliance with the License. 8 # 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 # or http://www.opensolaris.org/os/licensing. 11 # See the License for the specific language governing permissions 12 # and limitations under the License. 13 # 14 # When distributing Covered Code, include this CDDL HEADER in each 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 # If applicable, add the following below this CDDL HEADER, with the 17 # fields enclosed by brackets "[]" replaced with your own identifying 18 # information: Portions Copyright [yyyy] [name of copyright owner] 19 # 20 # CDDL HEADER END 21 # 22 # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 23 # 24 25 # NOTE: this script runs in the global zone and touches the non-global 26 # zone, so care should be taken to validate any modifications so that they 27 # are safe. 28 29 . /usr/lib/brand/solaris10/common.ksh 30 31 LOGFILE= 32 MSG_PREFIX="p2v: " 33 EXIT_CODE=1 34 35 usage() 36 { 37 echo "$0 [-s] [-m msgprefix] [-u] [-v] [-b patchid]* zonename" >&2 38 exit $EXIT_CODE 39 } 40 41 # Clean up on interrupt 42 trap_cleanup() 43 { 44 msg=$(gettext "Postprocessing cancelled due to interrupt.") 45 error "$msg" 46 47 if (( $zone_is_running != 0 )); then 48 error "$e_shutdown" "$ZONENAME" 49 /usr/sbin/zoneadm -z $ZONENAME halt 50 fi 51 52 # 53 # Delete temporary files created during the hollow package removal 54 # process. 55 # 56 rm -f $hollow_pkgs $hollow_file_list $hollow_dir_list 57 58 exit $EXIT_CODE 59 } 60 61 # 62 # Disable any existing live-upgrade configuration. 63 # We have already called safe_dir to validate the etc/lu directory. 64 # 65 fix_lu() 66 { 67 ludir=$ZONEROOT/etc/lu 68 69 [[ ! -d $ludir ]] && return 70 71 safe_rm etc/lutab 72 safe_rm etc/lu/.BE_CONFIG 73 safe_rm etc/lu/.CURR_VARS 74 safe_rm etc/lu/ludb.local.xml 75 for i in $ludir/ICF* $ludir/vtoc* $ludir/GRUB* 76 do 77 nm=`basename $i` 78 safe_rm etc/lu/$nm 79 done 80 } 81 82 # 83 # For an exclusive stack zone, fix up the network configuration files. 84 # We need to do this even if unconfiguring the zone so sys-unconfig works 85 # correctly. 86 # 87 fix_net() 88 { 89 [[ "$STACK_TYPE" == "shared" ]] && return 90 91 NETIF_CNT=$(/usr/bin/ls $ZONEROOT/etc/hostname.* 2>/dev/null | \ 92 /usr/bin/wc -l) 93 if (( $NETIF_CNT != 1 )); then 94 vlog "$v_nonetfix" 95 return 96 fi 97 98 NET=$(LC_ALL=C /usr/sbin/zonecfg -z $ZONENAME info net) 99 if (( $? != 0 )); then 100 error "$e_badinfo" "net" 101 return 102 fi 103 104 NETIF=$(echo $NET | /usr/xpg4/bin/awk '{ 105 for (i = 1; i < NF; i++) { 106 if ($i == "physical:") { 107 if (length(net) == 0) { 108 i++ 109 net = $i 110 } else { 111 multiple=1 112 } 113 } 114 } 115 } 116 END { if (!multiple) 117 print net 118 }') 119 120 if [[ -z "$NETIF" ]]; then 121 vlog "$v_nonetfix" 122 return 123 fi 124 125 OLD_HOSTNET=$(/usr/bin/ls $ZONEROOT/etc/hostname.*) 126 if [[ "$OLD_HOSTNET" != "$ZONEROOT/etc/hostname.$NETIF" ]]; then 127 safe_move $OLD_HOSTNET $ZONEROOT/etc/hostname.$NETIF 128 fi 129 } 130 131 # 132 # Disable all of the shares since the zone cannot be an NFS server. 133 # Note that we disable the various instances of the svc:/network/shares/group 134 # SMF service in the fix_smf function. 135 # 136 fix_nfs() 137 { 138 zonedfs=$ZONEROOT/etc/dfs 139 140 [[ ! -d $zonedfs ]] && return 141 142 if [[ -h $zonedfs/dfstab || ! -f $zonedfs/dfstab ]]; then 143 error "$e_badfile" "/etc/dfs/dfstab" 144 return 145 fi 146 147 tmpfile=$(mktemp -t) 148 if [[ $? == 1 || -z "$tmpfile" ]]; then 149 error "$e_tmpfile" 150 return 151 fi 152 153 /usr/xpg4/bin/awk '{ 154 if (substr($1, 0, 1) == "#") { 155 print $0 156 } else { 157 print "#", $0 158 modified=1 159 } 160 } 161 END { 162 if (modified == 1) { 163 printf("# Modified by p2v ") 164 system("/usr/bin/date") 165 exit 0 166 } 167 exit 1 168 }' $zonedfs/dfstab >>$tmpfile 169 170 if (( $? == 0 )); then 171 if [[ ! -f $zonedfs/dfstab.pre_p2v ]]; then 172 safe_copy $zonedfs/dfstab $zonedfs/dfstab.pre_p2v 173 fi 174 safe_copy $tmpfile $zonedfs/dfstab 175 chown root:sys $zonedfs/dfstab || \ 176 fail_fatal "$f_chown" "$zonedfs/dfstab" 177 chmod 644 $zonedfs/dfstab || \ 178 fail_fatal "$f_chmod" "$zonedfs/dfstab" 179 fi 180 /usr/bin/rm -f $tmpfile 181 } 182 183 # 184 # Comment out most of the old mounts since they are either unneeded or 185 # likely incorrect within a zone. Specific mounts can be manually 186 # reenabled if the corresponding device is added to the zone. 187 # 188 fix_vfstab() 189 { 190 if [[ -h $ZONEROOT/etc/vfstab || ! -f $ZONEROOT/etc/vfstab ]]; then 191 error "$e_badfile" "/etc/vfstab" 192 return 193 fi 194 195 tmpfile=$(mktemp -t) 196 if [[ $? == 1 || -z "$tmpfile" ]]; then 197 error "$e_tmpfile" 198 return 199 fi 200 201 /usr/xpg4/bin/awk '{ 202 if (substr($1, 0, 1) == "#") { 203 print $0 204 } else if ($1 == "fd" || $1 == "/proc" || $1 == "swap" || 205 $1 == "ctfs" || $1 == "objfs" || $1 == "sharefs" || 206 $4 == "nfs" || $4 == "lofs") { 207 print $0 208 } else { 209 print "#", $0 210 modified=1 211 } 212 } 213 END { 214 if (modified == 1) { 215 printf("# Modified by p2v ") 216 system("/usr/bin/date") 217 exit 0 218 } 219 exit 1 220 }' $ZONEROOT/etc/vfstab >>$tmpfile 221 222 if (( $? == 0 )); then 223 if [[ ! -f $ZONEROOT/etc/vfstab.pre_p2v ]]; then 224 safe_copy $ZONEROOT/etc/vfstab \ 225 $ZONEROOT/etc/vfstab.pre_p2v 226 fi 227 safe_copy $tmpfile $ZONEROOT/etc/vfstab 228 chown root:sys $ZONEROOT/etc/vfstab || \ 229 fail_fatal "$f_chown" "$ZONEROOT/etc/vfstab" 230 chmod 644 $ZONEROOT/etc/vfstab || \ 231 fail_fatal "$f_chmod" "$ZONEROOT/etc/vfstab" 232 fi 233 /usr/bin/rm -f $tmpfile 234 } 235 236 # 237 # Collect the data needed to delete SMF services. Since we're p2v-ing a 238 # physical image there are SMF services which must be deleted. 239 # 240 fix_smf_pre_uoa() 241 { 242 # 243 # Start by getting the svc manifests that are delivered by hollow 244 # pkgs then use 'svccfg inventory' to get the names of the svcs 245 # delivered by those manifests. The svc names are saved into a 246 # temporary file. 247 # 248 249 SMFTMPFILE=$(mktemp -t smf.XXXXXX) 250 if [[ $? == 1 || -z "$SMFTMPFILE" ]]; then 251 error "$e_tmpfile" 252 return 253 fi 254 255 for i in $ZONEROOT/var/sadm/pkg/* 256 do 257 pkg=$(/usr/bin/basename $i) 258 [[ ! -f $ZONEROOT/var/sadm/pkg/$pkg/save/pspool/$pkg/pkgmap ]] \ 259 && continue 260 261 /usr/bin/egrep -s "SUNW_PKG_HOLLOW=true" \ 262 $ZONEROOT/var/sadm/pkg/$pkg/pkginfo || continue 263 264 for j in $(/usr/xpg4/bin/awk '{if ($2 == "f" && 265 substr($4, 1, 17) == "var/svc/manifest/") print $4}' \ 266 $ZONEROOT/var/sadm/pkg/$pkg/save/pspool/$pkg/pkgmap) 267 do 268 svcs=$(SVCCFG_NOVALIDATE=1 \ 269 SVCCFG_REPOSITORY=$ZONEROOT/etc/svc/repository.db \ 270 /usr/sbin/svccfg inventory $ZONEROOT/$j) 271 for k in $svcs 272 do 273 echo $k /$j >> $SMFTMPFILE 274 done 275 done 276 done 277 } 278 279 # 280 # Delete or disable SMF services. 281 # Zone is booted to milestone=none when this function is called. 282 # Use the SMF data collected by fix_smf_pre_uoa() to delete the services. 283 # 284 fix_smf() 285 { 286 # 287 # Zone was already booted to milestone=none, wait until SMF door exists. 288 # 289 for i in 0 1 2 3 4 5 6 7 8 9 290 do 291 [[ -r $ZONEROOT/etc/svc/volatile/repository_door ]] && break 292 sleep 5 293 done 294 295 if [[ $i -eq 9 && ! -r $ZONEROOT/etc/svc/volatile/repository_door ]]; 296 then 297 # 298 # The zone never booted, something is wrong. 299 # 300 error "$e_nosmf" 301 error "$e_bootfail" 302 /usr/bin/rm -f $SMFTMPFILE 303 return 1 304 fi 305 306 insttmpfile=$(mktemp -t instsmf.XXXXXX) 307 if [[ $? == 1 || -z "$insttmpfile" ]]; then 308 error "$e_tmpfile" 309 /usr/bin/rm -f $SMFTMPFILE 310 return 1 311 fi 312 313 vlog "$v_rmhollowsvcs" 314 while read fmri mfst 315 do 316 # Delete the svc. 317 vlog "$v_delsvc" "$fmri" 318 echo "/usr/sbin/svccfg delete -f $fmri" 319 echo "/usr/sbin/svccfg delhash -d $mfst" 320 echo "rm -f $mfst" 321 done < $SMFTMPFILE > $ZONEROOT/tmp/smf_rm 322 323 /usr/sbin/zlogin -S $ZONENAME /bin/sh /tmp/smf_rm >/dev/null 2>&1 324 325 /usr/bin/rm -f $SMFTMPFILE 326 327 # Get a list of the svcs that now exist in the zone. 328 LANG=C /usr/sbin/zlogin -S $ZONENAME /usr/bin/svcs -aH | \ 329 /usr/xpg4/bin/awk '{print $3}' >>$insttmpfile 330 331 [[ -n $LOGFILE ]] && \ 332 printf "[$(date)] ${MSG_PREFIX}${v_svcsinzone}\n" >&2 333 [[ -n $LOGFILE ]] && cat $insttmpfile >&2 334 335 # 336 # Import ip-interface-management service in S10C, network 337 # loopback service requires ipmgmtd in exclusive stack zones. 338 # 339 /usr/sbin/zlogin -S $ZONENAME /usr/sbin/svccfg import \ 340 $ZONEROOT/var/svc/manifest/network/network-ipmgmt.xml 341 342 # 343 # Fix network services if shared stack. 344 # 345 if [[ "$STACK_TYPE" == "shared" ]]; then 346 vlog "$v_fixnetsvcs" 347 348 NETPHYSDEF="svc:/network/physical:default" 349 NETPHYSNWAM="svc:/network/physical:nwam" 350 351 /usr/bin/egrep -s "$NETPHYSDEF" $insttmpfile 352 if (( $? == 0 )); then 353 vlog "$v_enblsvc" "$NETPHYSDEF" 354 /usr/sbin/zlogin -S $ZONENAME \ 355 /usr/sbin/svcadm enable $NETPHYSDEF || \ 356 error "$e_dissvc" "$NETPHYSDEF" 357 fi 358 359 /usr/bin/egrep -s "$NETPHYSNWAM" $insttmpfile 360 if (( $? == 0 )); then 361 vlog "$v_dissvc" "$NETPHYSNWAM" 362 /usr/sbin/zlogin -S $ZONENAME \ 363 /usr/sbin/svcadm disable $NETPHYSNWAM || \ 364 error "$e_enblsvc" "$NETPHYSNWAM" 365 fi 366 367 for i in $(/usr/bin/egrep network/routing $insttmpfile) 368 do 369 # Disable the svc. 370 vlog "$v_dissvc" "$i" 371 /usr/sbin/zlogin -S $ZONENAME \ 372 /usr/sbin/svcadm disable $i || \ 373 error "$e_dissvc" $i 374 done 375 fi 376 377 # 378 # Disable well-known services that don't run in a zone. 379 # 380 vlog "$v_rminvalidsvcs" 381 for i in $(/usr/bin/egrep -hv "^#" \ 382 /usr/lib/brand/solaris10/smf_disable.lst \ 383 /etc/brand/solaris10/smf_disable.conf) 384 do 385 # Skip svcs not installed in the zone. 386 /usr/bin/egrep -s "$i:" $insttmpfile || continue 387 388 # Disable the svc. 389 vlog "$v_dissvc" "$i" 390 /usr/sbin/zlogin -S $ZONENAME /usr/sbin/svcadm disable $i || \ 391 error "$e_dissvc" $i 392 done 393 394 # 395 # Since zones can't be NFS servers, disable all of the instances of 396 # the shares svc. 397 # 398 for i in $(/usr/bin/egrep network/shares/group $insttmpfile) 399 do 400 vlog "$v_dissvc" "$i" 401 /usr/sbin/zlogin -S $ZONENAME /usr/sbin/svcadm disable $i || \ 402 error "$e_dissvc" $i 403 done 404 405 /usr/bin/rm -f $insttmpfile 406 407 return 0 408 } 409 410 # 411 # Remove well-known pkgs that do not work inside a zone. 412 # 413 rm_pkgs() 414 { 415 /usr/bin/cat <<-EOF > $ZONEROOT/tmp/admin || fatal "$e_adminf" 416 mail= 417 instance=overwrite 418 partial=nocheck 419 runlevel=nocheck 420 idepend=nocheck 421 rdepend=nocheck 422 space=nocheck 423 setuid=nocheck 424 conflict=nocheck 425 action=nocheck 426 basedir=default 427 EOF 428 429 for i in $(/usr/bin/egrep -hv "^#" /usr/lib/brand/solaris10/pkgrm.lst \ 430 /etc/brand/solaris10/pkgrm.conf) 431 do 432 [[ ! -d $ZONEROOT/var/sadm/pkg/$i ]] && continue 433 434 vlog "$v_rmpkg" "$i" 435 /usr/sbin/zlogin -S $ZONENAME \ 436 /usr/sbin/pkgrm -na /tmp/admin $i >&2 || error "$e_rmpkg" $i 437 done 438 } 439 440 # 441 # Zoneadmd writes a one-line index file into the zone when the zone boots, 442 # so any information about installed zones from the original system will 443 # be lost at that time. Here we'll warn the sysadmin about any pre-existing 444 # zones that they might want to clean up by hand, but we'll leave the zonepaths 445 # in place in case they're on shared storage and will be migrated to 446 # a new host. 447 # 448 warn_zones() 449 { 450 zoneconfig=$ZONEROOT/etc/zones 451 452 [[ ! -d $zoneconfig ]] && return 453 454 if [[ -h $zoneconfig/index || ! -f $zoneconfig/index ]]; then 455 error "$e_badfile" "/etc/zones/index" 456 return 457 fi 458 459 NGZ=$(/usr/xpg4/bin/awk -F: '{ 460 if (substr($1, 0, 1) == "#" || $1 == "global") 461 continue 462 463 if ($2 == "installed") 464 printf("%s ", $1) 465 }' $zoneconfig/index) 466 467 # Return if there are no installed zones to warn about. 468 [[ -z "$NGZ" ]] && return 469 470 log "$v_rmzones" "$NGZ" 471 472 NGZP=$(/usr/xpg4/bin/awk -F: '{ 473 if (substr($1, 0, 1) == "#" || $1 == "global") 474 continue 475 476 if ($2 == "installed") 477 printf("%s ", $3) 478 }' $zoneconfig/index) 479 480 log "$v_rmzonepaths" 481 482 for i in $NGZP 483 do 484 log " %s" "$i" 485 done 486 } 487 488 # 489 # ^C Should cleanup; if the zone is running, it should try to halt it. 490 # 491 zone_is_running=0 492 trap trap_cleanup INT 493 494 # 495 # Parse the command line options. 496 # 497 OPT_U= 498 OPT_V= 499 OPT_M= 500 OPT_L= 501 while getopts "uvm:l:" opt 502 do 503 case "$opt" in 504 u) OPT_U="-u";; 505 v) OPT_V="-v";; 506 m) MSG_PREFIX="$OPTARG"; OPT_M="-m \"$OPTARG\"";; 507 l) LOGFILE="$OPTARG"; OPT_L="-l \"$OPTARG\"";; 508 *) usage;; 509 esac 510 done 511 shift OPTIND-1 512 513 (( $# < 1 )) && usage 514 515 (( $# > 2 )) && usage 516 517 [[ -n $LOGFILE ]] && exec 2>>$LOGFILE 518 519 ZONENAME=$1 520 ZONEPATH=$2 521 # XXX shared/common script currently uses lower case zonename & zonepath 522 zonename="$ZONENAME" 523 zonepath="$ZONEPATH" 524 ZONEROOT=$ZONEPATH/root 525 526 e_badinfo=$(gettext "Failed to get '%s' zone resource") 527 e_badfile=$(gettext "Invalid '%s' file within the zone") 528 v_mkdirs=$(gettext "Creating mount points") 529 v_nonetfix=$(gettext "Cannot update /etc/hostname.{net} file") 530 v_adjust=$(gettext "Updating the image to run within a zone") 531 v_stacktype=$(gettext "Stack type '%s'") 532 v_booting=$(gettext "Booting zone to single user mode") 533 e_bootfail=$(gettext "Failed to boot zone to single user mode.") 534 e_nosmf=$(gettext "SMF repository unavailable.") 535 v_svcsinzone=$(gettext "The following SMF services are installed:") 536 v_rmhollowsvcs=$(gettext "Deleting SMF services from hollow packages") 537 v_fixnetsvcs=$(gettext "Adjusting network SMF services") 538 v_rminvalidsvcs=$(gettext "Disabling invalid SMF services") 539 v_delsvc=$(gettext "Delete SMF svc '%s'") 540 e_delsvc=$(gettext "deleting SMF svc '%s'") 541 v_enblsvc=$(gettext "Enable SMF svc '%s'") 542 e_enblsvc=$(gettext "enabling SMF svc '%s'") 543 v_dissvc=$(gettext "Disable SMF svc '%s'") 544 e_dissvc=$(gettext "disabling SMF svc '%s'") 545 e_adminf=$(gettext "Unable to create admin file") 546 v_rmpkg=$(gettext "Remove package '%s'") 547 e_rmpkg=$(gettext "removing package '%s'") 548 v_rmzones=$(gettext "The following zones in this image will be unusable: %s") 549 v_rmzonepaths=$(gettext "These zonepaths could be removed from this image:") 550 v_halting=$(gettext "Halting zone") 551 e_shutdown=$(gettext "Shutting down zone %s...") 552 e_badhalt=$(gettext "Zone halt failed") 553 v_exitgood=$(gettext "Postprocessing successful.") 554 e_exitfail=$(gettext "Postprocessing failed.") 555 556 # 557 # Do some validation on the paths we'll be accessing 558 # 559 safe_dir /etc 560 safe_dir /var 561 safe_dir /var/sadm 562 safe_dir /var/sadm/install 563 safe_dir /var/sadm/pkg 564 safe_opt_dir /etc/dfs 565 safe_opt_dir /etc/lu 566 safe_opt_dir /etc/zones 567 568 mk_zone_dirs 569 570 # Now do the work to update the zone. 571 572 # Check for zones inside of image. 573 warn_zones 574 fix_smf_pre_uoa 575 576 log "$v_adjust" 577 578 # 579 # Any errors in these functions are not considered fatal. The zone can be 580 # be fixed up manually afterwards and it may need some additional manual 581 # cleanup in any case. 582 # 583 584 STACK_TYPE=$(/usr/sbin/zoneadm -z $ZONENAME list -p | \ 585 /usr/xpg4/bin/awk -F: '{print $7}') 586 if (( $? != 0 )); then 587 error "$e_badinfo" "stacktype" 588 fi 589 vlog "$v_stacktype" "$STACK_TYPE" 590 591 fix_lu 592 fix_net 593 fix_nfs 594 fix_vfstab 595 596 vlog "$v_booting" 597 598 # 599 # Boot the zone so that we can do all of the SMF updates needed on the zone's 600 # repository. 601 # 602 603 zone_is_running=1 604 605 /usr/sbin/zoneadm -z $ZONENAME boot -f -- -m milestone=none 606 if (( $? != 0 )); then 607 error "$e_badboot" 608 /usr/bin/rm -f $SMFTMPFILE 609 fatal "$e_exitfail" 610 fi 611 612 # 613 # Remove all files and directories installed by hollow packages. Such files 614 # and directories shouldn't exist inside zones. 615 # 616 hollow_pkgs=$(mktemp -t .hollow.pkgs.XXXXXX) 617 hollow_file_list=$(mktemp $ZONEROOT/.hollow.pkgs.files.XXXXXX) 618 hollow_dir_list=$(mktemp $ZONEROOT/.hollow.pkgs.dirs.XXXXXX) 619 [ -f "$hollow_pkgs" -a -f "$hollow_file_list" -a -f "$hollow_dir_list" ] || { 620 error "$e_tmpfile" 621 rm -f $hollow_pkgs $hollow_file_list $hollow_dir_list 622 fatal "$e_exitfail" 623 } 624 for pkg_name in $ZONEROOT/var/sadm/pkg/*; do 625 grep 'SUNW_PKG_HOLLOW=true' $pkg_name/pkginfo >/dev/null 2>&1 && \ 626 basename $pkg_name >>$hollow_pkgs 627 done 628 /usr/xpg4/bin/awk -v hollowpkgs=$hollow_pkgs -v filelist=$hollow_file_list \ 629 -v dirlist=$hollow_dir_list ' 630 BEGIN { 631 while (getline p <hollowpkgs > 0) 632 pkgs[p] = 1; 633 close(hollowpkgs); 634 } 635 { 636 # fld is the field where the pkg names begin. 637 # nm is the file/dir entry name. 638 if ($2 == "f") { 639 fld=10; 640 nm=$1; 641 } else if ($2 == "d") { 642 fld=7; 643 nm=$1; 644 } else if ($2 == "s" || $2 == "l") { 645 fld=4; 646 split($1, a, "="); 647 nm=a[1]; 648 } else { 649 next; 650 } 651 652 # Determine whether the file or directory is delivered by any 653 # non-hollow packages. Files and directories can be 654 # delivered by multiple pkgs. The file or directory should only 655 # be removed if it is only delivered by hollow packages. 656 for (i = fld; i <= NF; i++) { 657 if (pkgs[get_pkg_name($i)] != 1) { 658 # We encountered a non-hollow package. Skip 659 # this entry. 660 next; 661 } 662 } 663 664 # The file or directory is only delivered by hollow packages. 665 # Mark it for removal. 666 if (fld != 7) 667 print nm >>filelist 668 else 669 print nm >>dirlist 670 } 671 672 # Get the clean pkg name from the fld entry. 673 function get_pkg_name(fld) { 674 # Remove any pkg control prefix (e.g. *, !) 675 first = substr(fld, 1, 1) 676 if (match(first, /[A-Za-z]/)) { 677 pname = fld 678 } else { 679 pname = substr(fld, 2) 680 } 681 682 # Then remove any class action script name 683 pos = index(pname, ":") 684 if (pos != 0) 685 pname = substr(pname, 1, pos - 1) 686 return (pname) 687 } 688 ' $ZONEROOT/var/sadm/install/contents 689 /usr/sbin/zlogin -S $ZONENAME "cat /$(basename $hollow_file_list) | xargs rm -f" 690 /usr/sbin/zlogin -S $ZONENAME "sort -r /$(basename $hollow_dir_list) | \ 691 xargs rmdir >/dev/null 2>&1" 692 rm -f $hollow_pkgs $hollow_file_list $hollow_dir_list 693 694 # cleanup SMF services 695 fix_smf || failed=1 696 697 # remove invalid pkgs 698 [[ -z $failed ]] && rm_pkgs 699 700 if [[ -z $failed && -n $OPT_U ]]; then 701 vlog "$v_unconfig" 702 703 sysunconfig_zone 704 if (( $? != 0 )); then 705 failed=1 706 fi 707 fi 708 709 vlog "$v_halting" 710 /usr/sbin/zoneadm -z $ZONENAME halt 711 if (( $? != 0 )); then 712 error "$e_badhalt" 713 failed=1 714 fi 715 zone_is_running=0 716 717 if [[ -n $failed ]]; then 718 fatal "$e_exitfail" 719 fi 720 721 vlog "$v_exitgood" 722 exit 0