--- a/src/brand/attach Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/attach Fri Nov 13 15:13:18 2009 -0700
@@ -75,8 +75,10 @@
trap_exit()
{
if [[ $EXIT_CODE == $ZONE_SUBPROC_OK ]]; then
- # unmount the zoneroot
- umount $ZONEROOT > /dev/null 2>&1
+ # unmount the zoneroot if labeled brand
+ is_brand_labeled
+ (( $? == 1 )) && ( umount $ZONEROOT || \
+ printf "$f_zfs_unmount" "$ZONEPATH/root" )
else
if [[ "$install_media" != "-" ]]; then
/usr/lib/brand/ipkg/uninstall $ZONENAME $ZONEPATH -F
--- a/src/brand/clone Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/clone Fri Nov 13 15:13:18 2009 -0700
@@ -28,8 +28,17 @@
m_usage=$(gettext "clone {sourcezone}")
f_nosource=$(gettext "Error: unable to determine source zone dataset.")
-f_sysunconfig=$(gettext "Error: sys-unconfig failed.")
-f_nobrand=$(gettext "Error: unable to determine source zone brand.")
+
+# Clean up on failure
+trap_exit()
+{
+ if (( $ZONE_IS_MOUNTED != 0 )); then
+ error "$v_unmount"
+ zoneadm -z $ZONENAME unmount
+ fi
+
+ exit $ZONE_SUBPROC_INCOMPLETE
+}
# Set up ZFS dataset hierarchy for the zone.
@@ -38,8 +47,8 @@
# Other brand clone options are invalid for this brand.
while getopts "R:z:" opt; do
case $opt in
- R) zonepath="$OPTARG" ;;
- z) zonename="$OPTARG" ;;
+ R) ZONEPATH="$OPTARG" ;;
+ z) ZONENAME="$OPTARG" ;;
*) fail_usage "";;
esac
done
@@ -57,13 +66,6 @@
fail_fatal "$f_nosource"
fi
-# Find the active source zone brand
-brand=`/usr/sbin/zoneadm -z $sourcezone list -p | awk -F: '{print $6}'`
-
-if [ -z "$brand" ]; then
- fail_fatal "$f_nobrand"
-fi
-
get_current_gzbe
get_zonepath_ds $sourcezonepath
get_active_ds $CURRENT_GZBE $ZONEPATH_DS
@@ -76,8 +78,8 @@
# First make the top-level dataset.
#
-pdir=`/usr/bin/dirname $zonepath`
-zpname=`/usr/bin/basename $zonepath`
+pdir=`/usr/bin/dirname $ZONEPATH`
+zpname=`/usr/bin/basename $ZONEPATH`
get_zonepath_ds $pdir
zpds=$ZONEPATH_DS
@@ -94,7 +96,7 @@
/usr/sbin/zfs create -o mountpoint=legacy -o zoned=on $zpds/$zpname/ROOT
# make snapshot
-SNAPNAME=${zonename}_snap
+SNAPNAME=${ZONENAME}_snap
SNAPNUM=0
while [ $SNAPNUM -lt 100 ]; do
/usr/sbin/zfs snapshot $ACTIVE_DS@$SNAPNAME
@@ -102,7 +104,7 @@
break
fi
SNAPNUM=`expr $SNAPNUM + 1`
- SNAPNAME="${zonename}_snap$SNAPNUM"
+ SNAPNAME="${ZONENAME}_snap$SNAPNUM"
done
if [ $SNAPNUM -ge 100 ]; then
@@ -134,19 +136,20 @@
/usr/sbin/zfs set canmount=noauto $zpds/$zpname/ROOT/$BENAME || \
fail_incomplete "$f_zfs_create"
-if [ ! -d $zonepath/root ]; then
- /usr/bin/mkdir -p $zonepath/root
- /usr/bin/chmod 700 $zonepath
+if [ ! -d $ZONEPATH/root ]; then
+ /usr/bin/mkdir -p $ZONEPATH/root
+ /usr/bin/chmod 700 $ZONEPATH
fi
-/usr/sbin/mount -F zfs $zpds/$zpname/ROOT/$BENAME $zonepath/root || \
- fail_incomplete "$f_zfs_mount"
+ZONE_IS_MOUNTED=0
+trap trap_exit EXIT
-if [ $brand != labeled ]; then
- /usr/sbin/sys-unconfig -R $zonepath/root || \
- fail_incomplete "$f_sysunconfig"
-fi
+#
+# Completion of unconfigure_zone will leave the zone root mounted for
+# ipkg brand zones. The root won't be mounted for labeled brand zones.
+#
+is_brand_labeled
+(( $? == 0 )) && unconfigure_zone
-/usr/sbin/umount $zonepath/root || fail_fatal "$f_umount"
-
+trap - EXIT
exit $ZONE_SUBPROC_OK
--- a/src/brand/common.ksh Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/common.ksh Fri Nov 13 15:13:18 2009 -0700
@@ -46,6 +46,7 @@
f_no_ds=$(gettext "the zonepath must be a ZFS dataset.\nThe parent directory of the zonepath must be a ZFS dataset so that the\nzonepath ZFS dataset can be created properly.")
f_multiple_ds=$(gettext "multiple active datasets.")
f_no_active_ds=$(gettext "no active dataset.")
+f_zfs_unmount=$(gettext "Unable to unmount the zone's root ZFS dataset (%s).\nIs there a global zone process inside the zone root?\nThe current zone boot environment will remain mounted.\n")
f_zfs_mount=$(gettext "Unable to mount the zone's ZFS dataset.")
f_safedir=$(gettext "Expected %s to be a directory.")
@@ -54,6 +55,14 @@
m_brnd_usage=$(gettext "brand-specific usage: ")
+v_unconfig=$(gettext "Performing zone sys-unconfig")
+e_unconfig=$(gettext "sys-unconfig failed")
+v_mounting=$(gettext "Mounting the zone")
+e_badmount=$(gettext "Zone mount failed")
+v_unmount=$(gettext "Unmounting zone")
+e_badunmount=$(gettext "Zone unmount failed")
+e_exitfail=$(gettext "Postprocessing failed.")
+
m_complete=$(gettext " Done: Installation completed in %s seconds.")
m_postnote=$(gettext " Next Steps: Boot the zone, then log into the zone console (zlogin -C)")
m_postnote2=$(gettext " to complete the configuration process.")
@@ -73,6 +82,12 @@
exit $ZONE_SUBPROC_USAGE
}
+is_brand_labeled() {
+ brand=$(/usr/sbin/zoneadm -z $ZONENAME list -p | awk -F: '{print $6}')
+ [[ $brand == "labeled" ]] && return 1
+ return 0
+}
+
sanity_check()
{
typeset dir="$1"
@@ -180,6 +195,34 @@
}
#
+# Make sure the active dataset is mounted for the zone. There are several
+# cases to consider:
+# 1) First boot of the zone, nothing is mounted
+# 2) Zone is halting, active dataset remains the same.
+# 3) Zone is halting, there is a new active dataset to mount.
+#
+mount_active_ds() {
+ mount -p | cut -d' ' -f3 | egrep -s "^$ZONEPATH/root$"
+ if (( $? == 0 )); then
+ # Umount current dataset on the root (it might be an old BE).
+ umount $ZONEPATH/root
+ if (( $? != 0 )); then
+ # The umount failed, leave the old BE mounted.
+ # Warn about gz process preventing umount.
+ printf "$f_zfs_unmount" "$ZONEPATH/root"
+ return
+ fi
+ fi
+
+ # Mount active dataset on the root.
+ get_current_gzbe
+ get_zonepath_ds $ZONEPATH
+ get_active_ds $CURRENT_GZBE $ZONEPATH_DS
+
+ mount -F zfs $ACTIVE_DS $ZONEPATH/root || fail_fatal "$f_zfs_mount"
+}
+
+#
# Set up ZFS dataset hierarchy for the zone root dataset.
#
create_active_ds() {
@@ -240,6 +283,30 @@
}
#
+# Run sys-unconfig on the zone.
+#
+unconfigure_zone() {
+ vlog "$v_unconfig"
+
+ vlog "$v_mounting"
+ ZONE_IS_MOUNTED=1
+ zoneadm -z $ZONENAME mount -f || fatal "$e_badmount"
+
+ zlogin -S $ZONENAME /usr/sbin/sys-unconfig -R /a \
+ </dev/null >/dev/null 2>&1
+ if (( $? != 0 )); then
+ error "$e_unconfig"
+ failed=1
+ fi
+
+ vlog "$v_unmount"
+ zoneadm -z $ZONENAME unmount || fatal "$e_badunmount"
+ ZONE_IS_MOUNTED=0
+
+ [[ -n $failed ]] && fatal "$e_exitfail"
+}
+
+#
# Emits to stdout the entire incorporation for this image,
# stripped of publisher name and other junk.
#
--- a/src/brand/config.xml Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/config.xml Fri Nov 13 15:13:18 2009 -0700
@@ -40,6 +40,7 @@
<install>/usr/lib/brand/ipkg/pkgcreatezone -z %z -R %R</install>
<installopts>a:c:d:e:hk:P:p:suv</installopts>
<boot></boot>
+ <sysboot>/usr/lib/brand/ipkg/prestate %z %R 2 0</sysboot>
<halt></halt>
<verify_cfg>/usr/lib/brand/ipkg/support verify</verify_cfg>
<verify_adm></verify_adm>
--- a/src/brand/image_install Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/image_install Fri Nov 13 15:13:18 2009 -0700
@@ -221,6 +221,11 @@
trap - EXIT
rm -f $LOGFILE
+
+# Mount active dataset on the root.
+is_brand_labeled
+(( $? == 0 )) && mount_active_ds
+
log ""
log "$m_complete" ${SECONDS}
printf "$install_log\n" "$ZONEROOT/var/log/$ZONENAME.install$$.log"
--- a/src/brand/p2v Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/p2v Fri Nov 13 15:13:18 2009 -0700
@@ -40,7 +40,7 @@
# Clean up on failure
trap_exit()
{
- if (( $zone_is_mounted != 0 )); then
+ if (( $ZONE_IS_MOUNTED != 0 )); then
error "$v_unmount"
zoneadm -z $ZONENAME unmount
fi
@@ -323,7 +323,7 @@
#
# failure should unmount the zone if necessary;
#
-zone_is_mounted=0
+ZONE_IS_MOUNTED=0
trap trap_exit EXIT
#
@@ -363,10 +363,6 @@
e_badupdate=$(gettext "Updating the Zone software failed")
v_adjust=$(gettext "Updating the image to run within a zone")
v_stacktype=$(gettext "Stack type '%s'")
-v_mounting=$(gettext "Mounting the zone")
-e_badmount=$(gettext "Zone mount failed")
-v_unmount=$(gettext "Unmounting zone")
-e_badunmount=$(gettext "Zone unmount failed")
v_rmhollowsvcs=$(gettext "Deleting global zone-only SMF services")
v_fixnetsvcs=$(gettext "Adjusting network SMF services")
v_rminvalidsvcs=$(gettext "Disabling invalid SMF services")
@@ -381,10 +377,7 @@
e_rmpkg=$(gettext "removing package '%s'")
v_rmzones=$(gettext "The following zones in this image will be unusable: %s")
v_rmzonepaths=$(gettext "These zonepaths could be removed from this image:")
-v_unconfig=$(gettext "Performing zone sys-unconfig")
-e_unconfig=$(gettext "sys-unconfig failed")
v_exitgood=$(gettext "Postprocessing successful.")
-e_exitfail=$(gettext "Postprocessing failed.")
#
# Do some validation on the paths we'll be accessing
@@ -442,11 +435,9 @@
#
# Mount the zone so that we can do all of the updates needed on the zone.
-# The zone's root dataset is currently mounted so we have to first umount it.
#
-umount $ZONEROOT || fatal "$f_umount"
vlog "$v_mounting"
-zone_is_mounted=1
+ZONE_IS_MOUNTED=1
zoneadm -z $ZONENAME mount -f || fatal "$e_badmount"
#
@@ -463,13 +454,15 @@
vlog "$v_unmount"
zoneadm -z $ZONENAME unmount || fatal "$e_badunmount"
-zone_is_mounted=0
+ZONE_IS_MOUNTED=0
-# Mount the zone's root dataset back onto ZONEROOT.
-get_current_gzbe
-get_zonepath_ds $ZONEPATH
-get_active_ds $CURRENT_GZBE $ZONEPATH_DS
-mount -F zfs -O $ACTIVE_DS $ZONEROOT || fail_fatal "$f_mount"
+is_brand_labeled
+brand_labeled=$?
+if (( $brand_labeled == 1 )); then
+ # The labeled brand needs to mount the zone's root dataset back onto
+ # ZONEROOT so we can finish processing.
+ mount_active_ds
+fi
# Change the pkging variant from global zone to non-global zone.
log "$v_change_var"
@@ -478,8 +471,7 @@
#
# Run update on attach. State is currently 'incomplete' so use the private
-# force-update option. The zone's root dataset is still mounted at this point.
-# update-on-attach will unmount the zonepath dataset when its done.
+# force-update option.
# This also leaves the zone in the 'installed' state. This is a known bug
# in 'zoneadm attach'. We change the zone state back to 'incomplete' for
# now but this can be removed once 'zoneadm attach' is fixed.
@@ -489,27 +481,9 @@
zoneadm -z $ZONENAME mark incomplete || fatal "$e_badupdate"
log "$v_updatedone"
-if [[ -n $OPT_U ]]; then
- # We're sys-unconfiging the zone.
- vlog "$v_unconfig"
-
- vlog "$v_mounting"
- zone_is_mounted=1
- zoneadm -z $ZONENAME mount -f || fatal "$e_badmount"
+[[ -n $OPT_U ]] && unconfigure_zone
- /usr/sbin/zlogin -S $ZONENAME /usr/sbin/sys-unconfig -R /a \
- </dev/null >/dev/null 2>&1
- if (( $? != 0 )); then
- error "$e_unconfig"
- failed=1
- fi
-
- vlog "$v_unmount"
- zoneadm -z $ZONENAME unmount || fatal "$e_badunmount"
- zone_is_mounted=0
-
- [[ -n $failed ]] && fatal "$e_exitfail"
-fi
+(( $brand_labeled == 1 )) && mount_active_ds
trap - EXIT
vlog "$v_exitgood"
--- a/src/brand/pkgcreatezone Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/pkgcreatezone Fri Nov 13 15:13:18 2009 -0700
@@ -68,14 +68,6 @@
m_done=$(gettext " done.")
-is_brand_labeled() {
- brand_labeled=0
- brand=$(/usr/sbin/zoneadm -z $ZONENAME list -p | awk -F: '{print $6}')
- if [[ $brand == "labeled" ]]; then
- brand_labeled=1
- fi
-}
-
trap_cleanup() {
print "$f_interrupted"
exit $int_code
@@ -147,6 +139,7 @@
zonepath="$ZONEPATH"
is_brand_labeled
+brand_labeled=$?
ZONEROOT=$ZONEPATH/root
secinfo=""
@@ -423,9 +416,7 @@
#
# Get packages for TX zones if appropriate.
#
-if [ $brand_labeled -ne 0 ]; then
- pkglist="$pkglist system/trusted/trusted-nonglobal"
-fi
+(( $brand_labeled == 1 )) && pkglist="$pkglist system/trusted/trusted-nonglobal"
#
# Get man(1) but not the man pages
@@ -486,13 +477,13 @@
/usr/sbin/sysidconfig -b $ZONEROOT -a /lib/svc/method/sshd
touch $ZONEROOT/etc/.UNCONFIGURED
-# Umount the dataset on the root.
-/usr/sbin/umount $ZONEROOT
-
printf "$m_complete\n\n" ${SECONDS}
-if [ $brand_labeled -eq 0 ]; then
+if (( $brand_labeled == 0 )); then
printf "$m_postnote\n"
printf "$m_postnote2\n"
+else
+ # Umount the dataset on the root.
+ umount $ZONEROOT || printf "$f_zfs_unmount" "$ZONEPATH/root"
fi
exit $ZONE_SUBPROC_OK
--- a/src/brand/poststate Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/poststate Fri Nov 13 15:13:18 2009 -0700
@@ -20,14 +20,12 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. /usr/lib/brand/ipkg/common.ksh
-f_umount=$(gettext "Error: error unmounting zone root dataset.")
-
# States
# ZONE_STATE_CONFIGURED 0 (never see)
# ZONE_STATE_INCOMPLETE 1 (never see)
@@ -44,15 +42,23 @@
# boot 1
# halt 4
-zonename=$1
-zonepath=$2
+ZONENAME=$1
+ZONEPATH=$2
state=$3
cmd=$4
# If we're not halting the zone, then just return.
if [ $cmd -eq 4 ]; then
- # Umount dataset on the root.
- /usr/sbin/umount $zonepath/root || fail_fatal "$f_umount"
+ is_brand_labeled
+ if (( $? == 0 )); then
+ # Leave the active dataset mounted after halting (this might be
+ # a different dataset than what was mounted).
+ mount_active_ds
+ else
+ # Umount dataset on the root.
+ zoneroot="$ZONEPATH/root"
+ umount $zoneroot || printf "$f_zfs_unmount" "$zoneroot"
+ fi
fi
exit $ZONE_SUBPROC_OK
--- a/src/brand/prestate Fri Nov 13 13:04:50 2009 -0800
+++ b/src/brand/prestate Fri Nov 13 15:13:18 2009 -0700
@@ -20,14 +20,12 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. /usr/lib/brand/ipkg/common.ksh
-f_mount=$(gettext "Error: error mounting zone root dataset.")
-
# States
# ZONE_STATE_CONFIGURED 0 (never see)
# ZONE_STATE_INCOMPLETE 1 (never see)
@@ -44,20 +42,15 @@
# boot 1
# halt 4
-zonename=$1
-zonepath=$2
+ZONENAME=$1
+ZONEPATH=$2
state=$3
cmd=$4
# If we're not readying the zone, then just return.
if [ $cmd -eq 0 ]; then
# Mount active dataset on the root.
- get_current_gzbe
- get_zonepath_ds $zonepath
- get_active_ds $CURRENT_GZBE $ZONEPATH_DS
-
- /usr/sbin/mount -F zfs -O $ACTIVE_DS $zonepath/root || \
- fail_fatal "$f_mount"
+ mount_active_ds
fi
exit $ZONE_SUBPROC_OK