--- a/src/brand/Makefile Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/Makefile Wed Jun 01 13:11:09 2011 +0100
@@ -20,7 +20,7 @@
#
#
-# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
MACH:sh = uname -p
@@ -58,7 +58,6 @@
$(ROOTBRANDPKG)/poststate \
$(ROOTBRANDPKG)/prestate \
$(ROOTBRANDPKG)/support \
- $(ROOTBRANDPKG)/sysboot \
$(ROOTBRANDPKG)/uninstall
ROOTFILES = \
--- a/src/brand/attach Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/attach Wed Jun 01 13:11:09 2011 +0100
@@ -97,20 +97,15 @@
# Restore the zone properties for the pre-existing
# dataset.
if [[ -n "$ACTIVE_DS" ]]; then
- zfs set canmount=off $ACTIVE_DS
- (( $? != 0 )) && error "$f_ds_config" \
- "$ACTIVE_DS" "canmount=on"
zfs set zoned=off $ACTIVE_DS
(( $? != 0 )) && error "$f_ds_config" \
"$ACTIVE_DS" "zoned=off"
+ zfs set canmount=on $ACTIVE_DS
+ (( $? != 0 )) && error "$f_ds_config" \
+ "$ACTIVE_DS" "canmount=on"
zfs set mountpoint=$ZONEROOT $ACTIVE_DS
(( $? != 0 )) && error "$f_ds_config" \
"$ACTIVE_DS" "mountpoint=$ZONEROOT"
- zfs set canmount=on $ACTIVE_DS
- (( $? != 0 )) && error "$f_ds_config" \
- "$ACTIVE_DS" "canmount=on"
- zfs mount "$ACTIVE_DS" || \
- error "$e_mount1_failed" "$ACTIVE_DS"
fi
fi
log "$m_failed"
@@ -125,19 +120,27 @@
trap trap_cleanup INT
trap trap_exit EXIT
+<<<<<<< local
PKG=pkg
+=======
+#set -o xtrace
+
+PKG="/usr/bin/pkg"
+>>>>>>> other
KEYDIR=/var/pkg/ssl
# If we weren't passed at least two arguments, exit now.
(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE
-zone=
-init_zone zone "$1" "$2"
-# Set ZONEPATH, etc.
-eval $(bind_legacy_zone_globals zone)
+ZONENAME="$1"
+ZONEPATH="$2"
+# XXX shared/common script currently uses lower case zonename & zonepath
+zonename="$ZONENAME"
+zonepath="$ZONEPATH"
shift; shift # remove ZONENAME and ZONEPATH from arguments array
+ZONEROOT="$ZONEPATH/root"
logdir="$ZONEROOT/var/log"
#
@@ -161,7 +164,184 @@
typeset gz_incorporations=""
#
+<<<<<<< local
verbose=""
+=======
+# Gather the zone publisher details. $1 is the location of the image we
+# are processing and $2 is an associative array used to store publisher
+# details.
+#
+gather_zone_publisher_details() {
+ STORED_IMAGE=$PKG_IMAGE
+ PKG_IMAGE=$1;export PKG_IMAGE
+ typeset -n publishers=$2
+ typeset -li publisher_count=0
+ typeset -li url_count=0
+ typeset line=
+ typeset name=
+ typeset mirror=
+ typeset origin=
+ typeset opublisher=
+
+ #
+ # Store publisher, origin and security details. It is assumed
+ # that mirrors all use the same key as the origins.
+ #
+ for line in $(get_publisher_urls all origin); do
+ print $line | IFS="=" read name origin
+ # When a publisher has multiple origins, the
+ # additional origins don't contain the publisher
+ # name. Correct for this by checking if origin is not
+ # set by get_publisher_urls() and, if so, use the
+ # "name" as the origin and set the name to the value
+ # we have already saved.
+ if [[ -z $origin ]]; then
+ origin=$name
+ name=${publisher.name}
+ elif [[ "$origin" == "None" ]]; then
+ # Publisher with no origins.
+ origin=""
+ fi
+
+ # Use a compound variable to store all the data
+ # relating to a publisher.
+ if [[ -z ${publishers[$name]} ]]; then
+ typeset -C publisher_$publisher_count
+ typeset -n publisher=publisher_$publisher_count
+ typeset publisher.sticky=""
+ typeset publisher.preferred=""
+ typeset publisher.enabled=""
+ typeset -a publisher.origins=""
+ typeset -a publisher.mirrors=""
+ typeset publisher.name=$name
+ typeset publisher.keyfile=""
+ typeset publisher.certfile=""
+
+ get_publisher_attrs ${publisher.name} origin | \
+ IFS=" " read publisher.sticky publisher.preferred \
+ publisher.enabled
+ if [[ -n "$origin" ]]; then
+ get_pub_secinfo ${publisher.name} | \
+ read publisher.keyfile publisher.certfile
+ [[ ${publisher.keyfile} != "None" && \
+ ! -f ${PKG_IMAGE}/${publisher.keyfile} ]] && \
+ fail_usage "$f_nosuch_key" \
+ ${publisher.keyfile}
+ [[ ${publisher.certfile} != "None" && \
+ ! -f ${PKG_IMAGE}/${publisher.certfile} ]] && \
+ fail_usage "$f_nosuch_cert" \
+ ${publisher.certfile}
+ else
+ # Publisher has no origins.
+ publisher.keyfile="None"
+ publisher.certfile="None"
+ fi
+ publisher_count=publisher_count+1
+ url_count=0
+ fi
+ publisher.origins[$url_count]=$origin
+ publishers[$name]=${publisher}
+ url_count=url_count+1
+ done
+
+ #
+ # Store mirror details
+ #
+ url_count=0
+ for line in $(get_publisher_urls all mirror); do
+ print $line | IFS="=" read name mirror
+ if [[ -z $mirror ]]; then
+ mirror=$name
+ name=${publisher.name}
+ fi
+ if [[ -z $opublisher || $opublisher != $name ]]; then
+ opublisher=$name
+ eval publisher="${publishers[$name]}"
+ url_count=0
+ fi
+ publisher.mirrors[$url_count]=$mirror
+ publishers[$name]=${publisher}
+ url_count=url_count+1
+ done
+
+ PKG_IMAGE=$STORED_IMAGE;export PKG_IMAGE
+}
+
+#
+# $1 is an associative array of publishers. Search this array and
+# return the preferred publisher.
+#
+get_preferred_publisher() {
+ typeset -n publishers=$1
+ typeset publisher=
+
+ for key in ${!publishers[*]}; do
+ eval publisher="${publishers[$key]}"
+ if [[ ${publisher.preferred} == "true" ]]; then
+ print ${key}
+ return 0
+ fi
+ done
+ return 1
+}
+
+#
+# $1 is an empty string to be populated with a list of incorporation
+# fmris.
+#
+gather_incorporations() {
+ typeset -n incorporations=$1
+ typeset p=
+
+ for p in \
+ $(LC_ALL=C $PKG search -Hl -o pkg.name \
+ ':pkg.depend.install-hold:core-os*');do
+ incorporations="$incorporations $(get_pkg_fmri $p)"
+ done
+}
+
+#
+# Print the pkg(1) command which defines a publisher. $1 is an associative
+# array of publisher details and $2 is the publisher to be printed.
+#
+print_publisher_pkg_defn() {
+ typeset -n publishers=$1
+ typeset pname=$2
+ typeset publisher=
+ typeset args=""
+ typeset origin=
+ typeset mirror=
+
+ eval publisher="${publishers[$pname]}"
+
+ if [[ ${publisher.preferred} == "true" ]]; then
+ args="$args -P"
+ fi
+
+ for origin in ${publisher.origins[*]}; do
+ args="$args -g $origin"
+ done
+
+ for mirror in ${publisher.mirrors[*]}; do
+ args="$args -m $mirror"
+ done
+
+ if [[ ${publisher.sticky} == "true" ]]; then
+ args="$args --sticky"
+ else
+ args="$args --non-sticky"
+ fi
+
+ if [[ ${publisher.enabled} == "true" ]]; then
+ args="$args --enable"
+ else
+ args="$args --disable"
+ fi
+
+ echo "$args"
+}
+
+>>>>>>> other
# Other brand attach options are invalid for this brand.
while getopts "a:d:n:r:uv" opt; do
case $opt in
@@ -224,17 +404,125 @@
exit $ZONE_SUBPROC_NOTCOMPLETE
fi
-LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp ${zone.name}.attach_log.XXXXXX)
+LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $ZONENAME.attach_log.XXXXXX)
if [[ -z "$LOGFILE" ]]; then
fatal "$e_tmpfile"
fi
exec 2>>"$LOGFILE"
+
log "$m_attach_log" "$LOGFILE"
-# Remember what was mounted on the zone root in case the attach fails.
-get_ds_from_path "${zone.root}" ACTIVE_DS
-attach_datasets -t "$inst_type" -m "$install_media" zone
-migrate_export zone
+#
+# TODO - once sxce is gone, move the following block into
+# usr/lib/brand/shared/common.ksh code to share with other brands using
+# the same zfs dataset logic for attach. This currently uses get_current_gzbe
+# so we can't move it yet since beadm isn't in sxce.
+#
+
+# Validate that the zonepath is not in the root dataset.
+pdir=`dirname $ZONEPATH`
+get_zonepath_ds $pdir
+fail_zonepath_in_rootds $ZONEPATH_DS
+
+EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
+
+if [[ "$install_media" == "-" ]]; then
+ #
+ # Since we're using a pre-existing dataset, the dataset currently
+ # mounted on the {zonepath}/root becomes the active dataset. We
+ # can't depend on the usual dataset attributes to detect this since
+ # the dataset could be a detached zone or one that the user set up by
+ # hand and lacking the proper attributes. However, since the zone is
+ # not attached yet, the 'install_media == -' means the dataset must be
+ # mounted at this point.
+ #
+ ACTIVE_DS=`mount -p | nawk -v zroot=$ZONEROOT '{
+ if ($3 == zroot && $4 == "zfs")
+ print $1
+ }'`
+
+ [[ -z "$ACTIVE_DS" ]] && fatal "$f_no_active_ds_mounted" $ZONEROOT
+
+ # Set up proper attributes on the ROOT dataset.
+ get_zonepath_ds $ZONEPATH
+ zfs list -H -t filesystem -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1
+ (( $? != 0 )) && fatal "$f_no_active_ds"
+
+ # need to ensure zoned is off to set mountpoint=legacy.
+ zfs set zoned=off $ZONEPATH_DS/ROOT
+ (( $? != 0 )) && fatal "$f_ds_config" $ZONEPATH_DS/ROOT "zoned=off"
+
+ zfs set mountpoint=legacy $ZONEPATH_DS/ROOT
+ (( $? != 0 )) && fatal "$f_ds_config" $ZONEPATH_DS/ROOT \
+ "mountpoint=legacy"
+ zfs set zoned=on $ZONEPATH_DS/ROOT
+ (( $? != 0 )) && fatal "$f_ds_config" $ZONEPATH_DS/ROOT "zoned=on"
+
+ #
+ # We're typically using a pre-existing mounted dataset so setting the
+ # following propery changes will cause the {zonepath}/root dataset to
+ # be unmounted. However, a p2v with an update-on-attach will have
+ # created the dataset with the correct properties, so setting these
+ # attributes won't unmount the dataset. Thus, we check the mount
+ # and attempt the remount if necessary.
+ #
+ get_current_gzbe
+ zfs set $PROP_PARENT=$CURRENT_GZBE $ACTIVE_DS
+ (( $? != 0 )) && fatal "$f_ds_config" $ACTIVE_DS \
+ "$PROP_PARENT=$CURRENT_GZBE"
+ zfs set $PROP_ACTIVE=on $ACTIVE_DS
+ (( $? != 0 )) && fatal "$f_ds_config" $ACTIVE_DS "$PROP_ACTIVE=on"
+ zfs set canmount=noauto $ACTIVE_DS
+ (( $? != 0 )) && fatal "$f_ds_config" $ACTIVE_DS "canmount=noauto"
+ zfs set zoned=off $ACTIVE_DS
+ (( $? != 0 )) && fatal "$f_ds_config" $ACTIVE_DS "zoned=off"
+ zfs inherit mountpoint $ACTIVE_DS
+ (( $? != 0 )) && fatal "$f_ds_config" $ACTIVE_DS "'inherit mountpoint'"
+ zfs inherit zoned $ACTIVE_DS
+ (( $? != 0 )) && fatal "$f_ds_config" $ACTIVE_DS "'inherit zoned'"
+
+ mounted_ds=`mount -p | nawk -v zroot=$ZONEROOT '{
+ if ($3 == zroot && $4 == "zfs")
+ print $1
+ }'`
+
+ if [[ -z $mounted_ds ]]; then
+ mount -F zfs $ACTIVE_DS $ZONEROOT || fatal "$f_zfs_mount"
+ fi
+else
+ #
+ # Since we're not using a pre-existing ZFS dataset layout, create
+ # the zone datasets and mount them. Start by creating the zonepath
+ # dataset, similar to what zoneadm would do for an initial install.
+ #
+ zds=$(zfs list -H -t filesystem -o name $pdir 2>/dev/null)
+ if (( $? == 0 )); then
+ pnm=$(/usr/bin/basename $ZONEPATH)
+ # The zonepath dataset might already exist.
+ zfs list -H -t filesystem -o name $zds/$pnm >/dev/null 2>&1
+ if (( $? != 0 )); then
+ zfs create "$zds/$pnm"
+ (( $? != 0 )) && fatal "$f_zfs_create"
+ vlog "$m_zfs"
+ fi
+ fi
+
+ create_active_ds
+fi
+
+#
+# The zone's datasets are now in place.
+#
+
+log "$m_attach_root" "$ZONEROOT"
+# note \n to add whitespace
+log "$m_attach_ds\n" "$ACTIVE_DS"
+
+install_image "$inst_type" "$install_media"
+
+#
+# End of TODO block to move to common code.
+#
#
# Perform a sanity check to confirm that the image is not a global zone.
--- a/src/brand/clone Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/clone Wed Jun 01 13:11:09 2011 +0100
@@ -19,7 +19,9 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
. /usr/lib/brand/ipkg/common.ksh
@@ -30,7 +32,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
@@ -38,39 +40,108 @@
exit $ZONE_SUBPROC_INCOMPLETE
}
-# Source and destination zones
-typeset src dst
+# Set up ZFS dataset hierarchy for the zone.
+
+ROOT="rpool/ROOT"
+
# Other brand clone options are invalid for this brand.
while getopts "R:z:" opt; do
case $opt in
- R) opt_R="$OPTARG" ;;
- z) opt_z="$OPTARG" ;;
+ R) ZONEPATH="$OPTARG" ;;
+ z) ZONENAME="$OPTARG" ;;
*) fail_usage "";;
esac
done
shift $((OPTIND-1))
-if (($# != 1)); then
+if [ $# -ne 1 ]; then
fail_usage "";
fi
-init_zone dst "$opt_z" "$opt_R"
-init_zone src "$1"
+sourcezone=$1
+
+# Find the active source zone dataset to clone.
+sourcezonepath=`/usr/sbin/zoneadm -z $sourcezone list -p | awk -F: '{print $4}'`
+if [ -z "$sourcezonepath" ]; then
+ fail_fatal "$f_nosource"
+fi
get_current_gzbe
-get_active_be src || fatal "$e_no_active_be"
+get_zonepath_ds $sourcezonepath
+get_active_ds $CURRENT_GZBE $ZONEPATH_DS
+
+#
+# Now set up the zone's datasets
+#
+
+#
+# First make the top-level dataset.
+#
+
+pdir=`/usr/bin/dirname $ZONEPATH`
+zpname=`/usr/bin/basename $ZONEPATH`
-# From here on out the global variables referenced are for the destination zone
-eval $(bind_legacy_zone_globals dst)
+get_zonepath_ds $pdir
+zpds=$ZONEPATH_DS
+
+fail_zonepath_in_rootds $zpds
+
+#
+# We need to tolerate errors while creating the datasets and making the
+# mountpoint, since these could already exist from some other BE.
+#
+
+/usr/sbin/zfs create $zpds/$zpname
+
+/usr/sbin/zfs create -o mountpoint=legacy -o zoned=on $zpds/$zpname/ROOT
-# Make dataset snapshots
-snapshot_zone_rpool src "${dst}_snap%02d" snapname \
- || fail_incomplete "$f_zfs_snapshot"
+# make snapshot
+SNAPNAME=${ZONENAME}_snap
+SNAPNUM=0
+while [ $SNAPNUM -lt 100 ]; do
+ /usr/sbin/zfs snapshot $ACTIVE_DS@$SNAPNAME
+ if [ $? = 0 ]; then
+ break
+ fi
+ SNAPNUM=`expr $SNAPNUM + 1`
+ SNAPNAME="${ZONENAME}_snap$SNAPNUM"
+done
+
+if [ $SNAPNUM -ge 100 ]; then
+ fail_fatal "$f_zfs_create"
+fi
-# Make dataset clones
-clone_zone_rpool src dst "$snapname" || fail_incomplete "$f_zone_clone"
+# do clone
+BENAME=zbe
+BENUM=0
+while [ $BENUM -lt 100 ]; do
+ /usr/sbin/zfs clone $ACTIVE_DS@$SNAPNAME $zpds/$zpname/ROOT/$BENAME
+ if [ $? = 0 ]; then
+ break
+ fi
+ BENUM=`expr $BENUM + 1`
+ BENAME="zbe-$BENUM"
+done
+
+if [ $BENUM -ge 100 ]; then
+ fail_fatal "$f_zfs_create"
+fi
-ZONE_IS_MOUNTED=1
+/usr/sbin/zfs set $PROP_ACTIVE=on $zpds/$zpname/ROOT/$BENAME || \
+ fail_incomplete "$f_zfs_create"
+
+/usr/sbin/zfs set $PROP_PARENT=$CURRENT_GZBE $zpds/$zpname/ROOT/$BENAME || \
+ fail_incomplete "$f_zfs_create"
+
+/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
+fi
+
+ZONE_IS_MOUNTED=0
trap trap_exit EXIT
#
--- a/src/brand/common.ksh Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/common.ksh Wed Jun 01 13:11:09 2011 +0100
@@ -23,20 +23,14 @@
# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
#
-#
-# Only change PATH if you give full consideration to GNU or other variants
-# of common commands having different arguments and output. Setting PATH is
-# and not using the full path to executables provides a performance improvement
-# by using the ksh builtin equivalent of many common commands.
-#
-export PATH=/usr/bin:/usr/sbin
unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
. /usr/lib/brand/shared/common.ksh
PROP_PARENT="org.opensolaris.libbe:parentbe"
PROP_ACTIVE="org.opensolaris.libbe:active"
-PROP_BE_HANDLE="com.oracle.libbe:nbe_handle"
f_incompat_options=$(gettext "cannot specify both %s and %s options")
f_sanity_detail=$(gettext "Missing %s at %s")
@@ -46,8 +40,10 @@
sanity_fail_vers=$(gettext " Sanity Check: the Solaris image (release %s) is not an OpenSolaris image and cannot be installed in this type of branded zone.")
install_fail=$(gettext " Result: *** Installation FAILED ***")
f_zfs_in_root=$(gettext "Installing a zone inside of the root pool's 'ROOT' dataset is unsupported.")
+f_zfs_create=$(gettext "Unable to create the zone's ZFS dataset.")
f_root_create=$(gettext "Unable to create the zone's ZFS dataset mountpoint.")
f_no_gzbe=$(gettext "unable to determine global zone boot environment.")
+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")
@@ -77,8 +73,23 @@
m_postnote=$(gettext " Next Steps: Boot the zone, then log into the zone console (zlogin -C)")
m_postnote2=$(gettext " to complete the configuration process.")
+fail_incomplete() {
+ printf "ERROR: " 1>&2
+ printf "$@" 1>&2
+ printf "\n" 1>&2
+ exit $ZONE_SUBPROC_NOTCOMPLETE
+}
+
+fail_usage() {
+ printf "$@" 1>&2
+ printf "\n" 1>&2
+ printf "$m_brnd_usage" 1>&2
+ printf "$m_usage\n" 1>&2
+ exit $ZONE_SUBPROC_USAGE
+}
+
is_brand_labeled() {
- if [[ -z $ALTROOT ]]; then
+ if [ -z $ALTROOT ]; then
AR_OPTIONS=""
else
AR_OPTIONS="-R $ALTROOT"
@@ -135,7 +146,7 @@
vlog "$sanity_ok"
}
-function get_current_gzbe {
+get_current_gzbe() {
#
# If there is no alternate root (normal case) then set the
# global zone boot environment by finding the boot environment
@@ -143,97 +154,156 @@
# If a zone exists in a boot environment mounted on an alternate root,
# then find the boot environment where the alternate root is mounted.
#
- CURRENT_GZBE=$(beadm list -H | nawk -v alt=$ALTROOT -F\; '{
- if (length(alt) == 0) {
- # Field 3 is the BE status. 'N' is the active BE.
- if ($3 !~ "N")
- next
- } else {
- # Field 4 is the BE mountpoint.
- if ($4 != alt)
- next
+ if [ -x /usr/sbin/beadm ]; then
+ CURRENT_GZBE=`/usr/sbin/beadm list -H | /usr/bin/nawk \
+ -v alt=$ALTROOT -F\; '{
+ if (length(alt) == 0) {
+ # Field 3 is the BE status. 'N' is the active BE.
+ if ($3 !~ "N")
+ next
+ } else {
+ # Field 4 is the BE mountpoint.
+ if ($4 != alt)
+ next
+ }
+ # Field 2 is the BE UUID
+ print $2
+ }'`
+ else
+ # If there is no beadm command then the system doesn't really
+ # support multiple boot environments. We still want zones to
+ # work so simulate the existence of a single boot environment.
+ CURRENT_GZBE="opensolaris"
+ fi
+
+ if [ -z "$CURRENT_GZBE" ]; then
+ fail_fatal "$f_no_gzbe"
+ fi
+}
+
+# Find the active dataset under the zonepath dataset to mount on zonepath/root.
+# $1 CURRENT_GZBE
+# $2 ZONEPATH_DS
+get_active_ds() {
+ ACTIVE_DS=`/usr/sbin/zfs list -H -r -t filesystem \
+ -o name,$PROP_PARENT,$PROP_ACTIVE $2/ROOT | \
+ /usr/bin/nawk -v gzbe=$1 ' {
+ if ($1 ~ /ROOT\/[^\/]+$/ && $2 == gzbe && $3 == "on") {
+ print $1
+ if (found == 1)
+ exit 1
+ found = 1
}
- # Field 2 is the BE UUID
- print $2
- }')
- if [ -z "$CURRENT_GZBE" ]; then
- return 1
+ }'`
+
+ if [ $? -ne 0 ]; then
+ fail_fatal "$f_multiple_ds"
+ fi
+
+ if [ -z "$ACTIVE_DS" ]; then
+ fail_fatal "$f_no_active_ds"
fi
- return 0
+}
+
+# Check that zone is not in the ROOT dataset.
+fail_zonepath_in_rootds() {
+ case $1 in
+ rpool/ROOT/*)
+ fail_fatal "$f_zfs_in_root"
+ break;
+ ;;
+ *)
+ break;
+ ;;
+ esac
}
#
-# get_active_be zone
-#
-# Finds the active boot environment for the given zone.
-#
-# Arguments:
-#
-# zone zone structure initialized with init_zone
-#
-# Globals:
-#
-# CURRENT_GZBE Current global zone boot environment. If not already set,
-# it will be set.
-#
-# Returns:
-#
-# 0 on success, else 1.
+# 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.
#
-function get_active_be {
- typeset -n zone=$1
- typeset active_ds=
- typeset tab=$(printf "\t")
-
- [[ -z "$CURRENT_GZBE" ]] && get_current_gzbe
-
- typeset name parent active
- zfs list -H -r -d 1 -t filesystem -o name,$PROP_PARENT,$PROP_ACTIVE \
- ${zone.ROOT_ds} | while IFS=$tab read name parent active ; do
- [[ $parent == "$CURRENT_GZBE" ]] || continue
- [[ $active == on ]] || continue
- vlog "Found active dataset %s" "$name"
- if [[ -n "$active_ds" ]] ; then
- error "$f_multiple_ds"
- return 1
+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
- active_ds=$name
- done
- if [[ -z $active_ds ]]; then
- error "$f_no_active_ds"
- return 1
fi
- zone.active_ds=$active_ds
+ # 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"
}
-function set_active_be {
- typeset -n zone="$1"
- typeset be="$2"
+#
+# Set up ZFS dataset hierarchy for the zone root dataset.
+#
+create_active_ds() {
+ get_current_gzbe
- [[ -z "$CURRENT_GZBE" ]] && get_current_gzbe
+ #
+ # Find the zone's current dataset. This should have been created by
+ # zoneadm.
+ #
+ get_zonepath_ds $zonepath
+
+ # Check that zone is not in the ROOT dataset.
+ fail_zonepath_in_rootds $ZONEPATH_DS
+
+ #
+ # From here on, errors should cause the zone to be incomplete.
+ #
+ int_code=$ZONE_SUBPROC_FATAL
#
- # Turn off the active property on BE's with the same GZBE
+ # We need to tolerate errors while creating the datasets and making the
+ # mountpoint, since these could already exist from some other BE.
#
- zfs list -H -r -d 1 -t filesystem -o name,$PROP_PARENT,$PROP_ACTIVE \
- ${zone.ROOT_ds} | while IFS=$tab read name parent active ; do
- [[ $parent == "$CURRENT_GZBE" ]] || continue
- [[ $active == on ]] || continue
- [[ $name == "${zone.ROOT_ds}/$be" ]] && continue
- vlog "Deactivating active dataset %s" "$name"
- zfs set $PROP_ACTIVE=off "$name" || return 1
+
+ /usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1
+ if (( $? != 0 )); then
+ /usr/sbin/zfs create -o mountpoint=legacy \
+ -o zoned=on $ZONEPATH_DS/ROOT
+ if (( $? != 0 )); then
+ fail_fatal "$f_zfs_create"
+ fi
+ fi
+
+ BENAME=zbe
+ BENUM=0
+ # Try 100 different names before giving up.
+ while [ $BENUM -lt 100 ]; do
+ /usr/sbin/zfs create -o $PROP_ACTIVE=on \
+ -o $PROP_PARENT=$CURRENT_GZBE \
+ -o canmount=noauto $ZONEPATH_DS/ROOT/$BENAME >/dev/null 2>&1
+ if (( $? == 0 )); then
+ break
+ fi
+ BENUM=`expr $BENUM + 1`
+ BENAME="zbe-$BENUM"
done
- zone.active_ds="${zone.ROOT_ds}/$be"
+ if [ $BENUM -ge 100 ]; then
+ fail_fatal "$f_zfs_create"
+ fi
- zfs set "$PROP_PARENT=$CURRENT_GZBE" ${zone.active_ds} \
- || return 1
- zfs set "$PROP_ACTIVE=on" ${zone.active_ds} || return 1
+ if [ ! -d $ZONEROOT ]; then
+ /usr/bin/mkdir $ZONEROOT
+ fi
- zfs set "$PROP_BE_HANDLE=on" "${zone.rpool_ds}" || return 1
-
- return 0
+ /usr/sbin/mount -F zfs $ZONEPATH_DS/ROOT/$BENAME $ZONEROOT || \
+ fail_incomplete "$f_zfs_mount"
}
#
--- a/src/brand/detach Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/detach Wed Jun 01 13:11:09 2011 +0100
@@ -24,33 +24,61 @@
# Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
#
+
. /usr/lib/brand/ipkg/common.ksh
m_usage=$(gettext "detach [-n ].")
+f_mount=$(gettext "Error: error mounting zone root dataset.")
+f_ds_config=$(gettext "Failed to configure dataset %s: could not set %s.")
+
noexecute=0
# Other brand detach options are invalid for this brand.
while getopts "nR:z:" opt; do
case $opt in
n) noexecute=1 ;;
- R) ZONEPATH="$OPTARG" ;;
- z) ZONENAME="$OPTARG" ;;
+ R) zonepath="$OPTARG" ;;
+ z) zonename="$OPTARG" ;;
?) fail_usage "" ;;
*) fail_usage "";;
esac
done
shift $((OPTIND-1))
-init_zone zone "$ZONENAME" "$ZONEPATH"
-eval $(bind_legacy_zone_globals zone)
-
-if (( $noexecute == 1 )); then
- cat /etc/zones/$ZONENAME.xml
+if [ $noexecute -eq 1 ]; then
+ # dry-run - output zone's config and exit
+ cat /etc/zones/$zonename.xml
exit $ZONE_SUBPROC_OK
fi
-# All of the hard stuff is done in commmon code.
-detach_zone zone
+#
+# Detaching
+#
+# Leave the active dataset mounted on the zone's rootpath for ease of
+# migration.
+#
+get_current_gzbe
+get_zonepath_ds $zonepath
+get_active_ds $CURRENT_GZBE $ZONEPATH_DS
+
+/usr/sbin/zfs set zoned=off $ACTIVE_DS || \
+ fail_incomplete "$f_ds_config" "$ACTIVE_DS" "zoned=off"
+
+/usr/sbin/zfs set canmount=on $ACTIVE_DS || \
+ fail_incomplete "$f_ds_config" "$ACTIVE_DS" "canmount=on"
+
+#
+# This mounts the dataset.
+# XXX do we have to worry about subsidiary datasets?
+#
+/usr/sbin/zfs set mountpoint=$zonepath/root $ACTIVE_DS || \
+ fail_incomplete "$f_ds_config" "$ACTIVE_DS" "mountpoint=$zonepath/root"
+
+#
+# There is no sw inventory in an ipkg branded zone, so just use the original
+# xml file.
+#
+cp /etc/zones/$zonename.xml $zonepath/SUNWdetached.xml
exit $ZONE_SUBPROC_OK
--- a/src/brand/image_install Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/image_install Wed Jun 01 13:11:09 2011 +0100
@@ -19,9 +19,8 @@
#
# CDDL HEADER END
#
-
-#
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
#
@@ -101,8 +100,14 @@
# If we weren't passed at least two arguments, exit now.
(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE
-init_zone zone "$1" "$2"
-eval $(bind_legacy_zone_globals zone)
+ZONENAME="$1"
+ZONEPATH="$2"
+# XXX shared/common script currently uses lower case zonename & zonepath
+zonename="$ZONENAME"
+zonepath="$ZONEPATH"
+
+ZONEROOT="$ZONEPATH/root"
+
shift; shift # remove zonename and zonepath from arguments array
unset inst_type
@@ -202,7 +207,8 @@
if (( $p2v_result != 0 )); then
log "$p2v_fail"
- log "\n$install_fail"
+ log ""
+ log "$install_fail"
log "$install_log" "$LOGFILE"
exit $ZONE_SUBPROC_FATAL
fi
@@ -221,9 +227,10 @@
# Mount active dataset on the root.
is_brand_labeled
-(( $? == 0 )) && mount_active_be -c zone
+(( $? == 0 )) && mount_active_ds
-log "\n$m_complete" ${SECONDS}
+log ""
+log "$m_complete" ${SECONDS}
printf "$install_log\n" "$ZONEROOT/var/log/$ZONENAME.install$$.log"
printf "$m_postnote\n"
printf "$m_postnote2\n"
--- a/src/brand/p2v Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/p2v Wed Jun 01 13:11:09 2011 +0100
@@ -28,13 +28,9 @@
# zone, so care should be taken to validate any modifications so that they
# are safe.
-#
-# Only change PATH if you give full consideration to GNU or other variants
-# of common commands having different arguments and output. Setting PATH is
-# and not using the full path to executables provides a performance improvement
-# by using the ksh builtin equivalent of many common commands.
-#
-export PATH=/usr/bin:/usr/sbin
+# Restrict executables to /usr/bin and /usr/sbin
+PATH=/usr/bin:/usr/sbin
+export PATH
unset LD_LIBRARY_PATH
. /usr/lib/brand/ipkg/common.ksh
@@ -355,8 +351,10 @@
(( $# != 2 )) && exit 1
[[ -n $LOGFILE ]] && exec 2>>$LOGFILE
-init_zone zone "$1" "$2"
-eval $(bind_legacy_zone_globals zone)
+
+ZONENAME=$1
+ZONEPATH=$2
+ZONEROOT=$ZONEPATH/root
e_badinfo=$(gettext "Failed to get '%s' zone resource")
e_badfile=$(gettext "Invalid '%s' file within the zone")
@@ -468,7 +466,7 @@
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_be zone
+ mount_active_ds
fi
#
@@ -504,7 +502,7 @@
[[ -n $OPT_U ]] && unconfigure_zone
-(( $brand_labeled == 1 )) && mount_active_be zone
+(( $brand_labeled == 1 )) && mount_active_ds
trap - EXIT
vlog "$v_exitgood"
--- a/src/brand/pkgcreatezone Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/pkgcreatezone Wed Jun 01 13:11:09 2011 +0100
@@ -58,10 +58,10 @@
trap_cleanup() {
print "$f_interrupted"
- exit $EXIT_CODE
+ exit $int_code
}
-EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
+int_code=$ZONE_SUBPROC_NOTCOMPLETE
trap trap_cleanup INT
extra_packages=""
@@ -109,13 +109,17 @@
print -u2 "Brand error: No zone path or name"
exit $ZONE_SUBPROC_USAGE
fi
-zone=
-init_zone zone "$ZONENAME" "$ZONEPATH"
-eval $(bind_legacy_zone_globals zone)
+
+# XXX shared/common script currently uses lower case zonename & zonepath
+zonename="$ZONENAME"
+zonepath="$ZONEPATH"
is_brand_labeled
brand_labeled=$?
+ZONEROOT=$ZONEPATH/root
+secinfo=""
+
# An image install can't use both -a AND -d...
[[ -n "$install_archive" && -n "$source_dir" ]] &&
fail_usage "$f_incompat_options" "-a" "-d"
@@ -153,8 +157,7 @@
# Before installing the zone, set up ZFS dataset hierarchy for the zone root
# dataset.
#
-create_active_ds zone || fail_fatal "$f_no_ds"
-mount_active_be -c zone || fail_fatal "$f_no_ds"
+create_active_ds
#
# If we're installing from an image, branch off to that installer.
--- a/src/brand/poststate Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/poststate Wed Jun 01 13:11:09 2011 +0100
@@ -21,7 +21,7 @@
#
#
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
#
. /usr/lib/brand/ipkg/common.ksh
@@ -48,20 +48,17 @@
cmd=$4
ALTROOT=$5
-typeset zone
-init_zone zone "$ZONENAME" "$ZONEPATH"
-eval $(bind_legacy_zone_globals zone)
-
# If we're not halting the zone, then just return.
if [ $cmd -eq 4 ]; then
- is_brand_labeled # Note: return value is C-style, not shell-style
+ is_brand_labeled
if (( $? == 0 )); then
- # Leave the active boot environment mounted after halting (this
- # might be a different dataset than what was mounted).
- mount_active_be -c zone
+ # 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.
- unmount_be zone
+ zoneroot="$ZONEPATH/root"
+ umount $zoneroot || printf "$f_zfs_unmount" "$zoneroot"
fi
fi
--- a/src/brand/prestate Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/prestate Wed Jun 01 13:11:09 2011 +0100
@@ -18,10 +18,9 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
-#
#
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
#
. /usr/lib/brand/ipkg/common.ksh
@@ -48,15 +47,10 @@
cmd=$4
ALTROOT=$5
-typeset zone
-init_zone zone "$ZONENAME" "$ZONEPATH"
-eval $(bind_legacy_zone_globals zone)
-
# If we're not readying the zone, then just return.
-case $cmd in
- 0)
- mount_active_be zone || exit $ZONE_SUBPROC_NOTCOMPLETE
- ;;
-esac
+if [ $cmd -eq 0 ]; then
+ # Mount active dataset on the root.
+ mount_active_ds
+fi
exit $ZONE_SUBPROC_OK
--- a/src/brand/sysboot Wed Jun 01 13:04:21 2011 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-#!/bin/ksh -p
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-. /usr/lib/brand/ipkg/common.ksh
-
-typeset zone
-init_zone zone "$1" "$2" || {
- error "Usage: %s zone zonepath" "$0"
- exit $ZONE_SUBPROC_USAGE
-}
-
-# Mount the active boot environment on the zoneroot.
-mount_active_be -c zone || exit $ZONE_SUBPROC_NOTCOMPLETE
-
-enable_zones_services || exit $ZONE_SUBPROC_NOTCOMPLETE
-
-exit $ZONE_SUBPROC_OK
--- a/src/brand/uninstall Wed Jun 01 13:04:21 2011 +0100
+++ b/src/brand/uninstall Wed Jun 01 13:11:09 2011 +0100
@@ -19,10 +19,15 @@
#
# CDDL HEADER END
#
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
#
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# get script name (bname) and path (dname)
#
+bname=`basename $0`
#
# common shell script functions
@@ -33,13 +38,16 @@
#
# options processing
#
-
-# If we weren't passed at least two arguments, exit now.
-(( $# < 2 )) && fail_fatal "$f_abort"
-
-typeset zone
-init_zone zone "$1" "$2"
-eval $(bind_legacy_zone_globals zone)
+zonename=$1
+if [ -z "$zonename" ]; then
+ printf "$f_abort\n" >&2
+ exit $ZONE_SUBPROC_FATAL
+fi
+zonepath=$2
+if [ -z "$zonepath" ]; then
+ printf "$f_abort" >&2
+ exit $ZONE_SUBPROC_FATAL
+fi
shift 2
options="FhHnv"
@@ -93,6 +101,7 @@
#
# main
#
+zoneroot=$zonepath/root
nop=""
if [[ -n "$opt_n" ]]; then
@@ -104,28 +113,49 @@
ZONE_SUBPROC_OK=$ZONE_SUBPROC_FATAL
fi
-# get_current_gzbe
-get_current_gzbe || fail_fatal "$f_no_gzbe"
+#
+# We want uninstall to work in the face of various problems, such as a
+# zone with no delegated root dataset or multiple active datasets, so we
+# don't use the common functions. Instead, we do our own work here and
+# are tolerant of errors.
+#
-# find all the zone BEs associated with this global zone BE.
-typeset -a belist
-if [[ -n "$CURRENT_GZBE" ]]; then
- zfs list -H -t filesystem -o $PROP_PARENT,name -r -d 1 \
- ${zone.ROOT_ds} 2>/dev/null | while IFS=$'\t' read uid fs; do
+# get_current_gzbe
+CURRENT_GZBE=`/sbin/beadm list -H | /bin/nawk -F\; '{
+ # Field 3 is the BE status. 'N' is the active BE.
+ if ($3 ~ "N")
+ # Field 2 is the BE UUID
+ print $2
+ }'`
+
+if [ -z "$CURRENT_GZBE" ]; then
+ print "$f_no_gzbe"
+fi
- # Skip the ROOT dataset
- [[ "$fs" == "${zone.ROOT_ds}" ]] && continue
+uninstall_get_zonepath_ds
+uninstall_get_zonepath_root_ds
+
+# find all the zone BEs datasets associated with this global zone BE.
+unset fs_all
+(( fs_all_c = 0 ))
+if [ -n "$CURRENT_GZBE" ]; then
+ /sbin/zfs list -H -t filesystem -o $PROP_PARENT,name \
+ -r $ZONEPATH_RDS |
+ while IFS=" " read uid fs; do
- #
- # match by PROP_PARENT uuid. If the uuid is not set ("-"), the
- # BE is invalid (interrupted install?) and should be deleted.
- #
- if [[ $uid == "-" || $uid == "${CURRENT_GZBE}" ]] ; then
- a_push belist "$(basename "$fs")"
- fi
+ # only look at filesystems directly below $ZONEPATH_RDS
+ [[ "$fs" != ~()($ZONEPATH_RDS/+([^/])) ]] &&
+ continue
+
+ # match by PROP_PARENT uuid
+ [[ "$uid" != ${CURRENT_GZBE} ]] &&
+ continue
+
+ fs_all[$fs_all_c]=$fs
+ (( fs_all_c = $fs_all_c + 1 ))
done
fi
-destroy_zone_datasets zone -b belist
+destroy_zone_datasets
exit $ZONE_SUBPROC_OK
--- a/src/pkg/manifests/system%2Fzones%2Fbrand%2Fipkg.p5m Wed Jun 01 13:04:21 2011 +0100
+++ b/src/pkg/manifests/system%2Fzones%2Fbrand%2Fipkg.p5m Wed Jun 01 13:11:09 2011 +0100
@@ -18,7 +18,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
set name=pkg.fmri value=pkg:/system/zones/brand/ipkg@$(PKGVERS)
@@ -53,7 +53,6 @@
file path=usr/lib/brand/ipkg/prestate mode=0755
file path=usr/lib/brand/ipkg/smf_disable.lst
file path=usr/lib/brand/ipkg/support mode=0755
-file path=usr/lib/brand/ipkg/sysboot mode=0755
file path=usr/lib/brand/ipkg/uninstall mode=0755
license cr_Oracle license=cr_Oracle
legacy pkg=SUNWipkg-brand version=0.0.0