PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/lib/brand/solaris10/zone/p2v.ksh

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