6793 p2v support for ipkg-branded zones
4513 need option to attach existing dataset
7345 zone attach should verify image is an IPS-based zone booted
8345 failed zoneadm attach leaves an zone root dataset active
8468 zoneadm install fails with "no zonepath dataset
9359 zoneadm attach should create zonepath dataset if necessary
--- a/src/brand/Makefile Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/Makefile Tue Nov 10 14:40:37 2009 -0700
@@ -31,6 +31,7 @@
ROOT = ../../proto/root_${MACH}
ROOTETC = $(ROOT)/etc
ROOTETCZONES = $(ROOT)/etc/zones
+ROOTETCBRAND = $(ROOT)/etc/brand/ipkg
ROOTUSRLIB = $(ROOT)/usr/lib
ROOTBRAND = $(ROOTUSRLIB)/brand
ROOTBRANDPKG = $(ROOTBRAND)/ipkg
@@ -40,12 +41,15 @@
ROOTDIRS = \
$(ROOT) \
$(ROOTETC) \
+ $(ROOTETCBRAND) \
$(ROOTETCZONES) \
$(ROOTUSRLIB) \
$(ROOTBRAND) \
$(ROOTBRANDPKG)
ROOTFILES = \
+ $(ROOTETCBRAND)/pkgrm.conf \
+ $(ROOTETCBRAND)/smf_disable.conf \
$(ROOTETCZONES)/SUNWipkg.xml \
$(ROOTBRANDPKG)/config.xml \
$(ROOTBRANDPKG)/platform.xml \
@@ -54,10 +58,13 @@
$(ROOTBRANDPKG)/common.ksh \
$(ROOTBRANDPKG)/detach \
$(ROOTBRANDPKG)/fmri_compare \
+ $(ROOTBRANDPKG)/image_install \
+ $(ROOTBRANDPKG)/p2v \
$(ROOTBRANDPKG)/pkgcreatezone \
+ $(ROOTBRANDPKG)/pkgrm.lst \
$(ROOTBRANDPKG)/poststate \
$(ROOTBRANDPKG)/prestate \
- $(ROOTBRANDPKG)/query \
+ $(ROOTBRANDPKG)/smf_disable.lst \
$(ROOTBRANDPKG)/support \
$(ROOTBRANDPKG)/uninstall
@@ -94,17 +101,24 @@
# repository's working copy's versions of the commands and modules.
PWD:sh = pwd
link:
+ mkdir -p /etc/brand/ipkg
mkdir -p /usr/lib/brand/ipkg
+ ln -sf $(PWD)/pkgrm.conf /etc/brand/ipkg/pkgrm.conf
+ ln -sf $(PWD)/smf_disable.conf /etc/brand/ipkg/smf_disable.conf
+ ln -sf $(PWD)/pkgrm.lst /usr/lib/brand/ipkg/pkgrm.lst
+ ln -sf $(PWD)/smf_disable.lst /usr/lib/brand/ipkg/smf_disable.lst
+ ln -sf $(PWD)/smf_disable.conf /usr/lib/brand/ipkg/smf_disable.conf
ln -sf $(PWD)/config.xml /usr/lib/brand/ipkg/config.xml
ln -sf $(PWD)/platform.xml /usr/lib/brand/ipkg/platform.xml
ln -sf $(PWD)/attach /usr/lib/brand/ipkg/attach
ln -sf $(PWD)/clone /usr/lib/brand/ipkg/clone
ln -sf $(PWD)/common.ksh /usr/lib/brand/ipkg/common.ksh
ln -sf $(PWD)/detach /usr/lib/brand/ipkg/detach
+ ln -sf $(PWD)/image_install /usr/lib/brand/ipkg/image_install
+ ln -sf $(PWD)/p2v /usr/lib/brand/ipkg/p2v
ln -sf $(PWD)/pkgcreatezone /usr/lib/brand/ipkg/pkgcreatezone
ln -sf $(PWD)/poststate /usr/lib/brand/ipkg/poststate
ln -sf $(PWD)/prestate /usr/lib/brand/ipkg/prestate
- ln -sf $(PWD)/query /usr/lib/brand/ipkg/query
ln -sf $(PWD)/support /usr/lib/brand/ipkg/support
ln -sf $(PWD)/uninstall /usr/lib/brand/ipkg/uninstall
ln -sf $(PWD)/SUNWipkg.xml /etc/zones/SUNWipkg.xml
@@ -112,10 +126,15 @@
link-clean:
rm -rf /usr/lib/brand/ipkg
rm -f /etc/zones/SUNWipkg.xml
+ rm -rf /etc/brand/ipkg
-$(ROOT) $(ROOTETC) $(ROOTETCZONES) $(ROOTUSRLIB) $(ROOTBRAND) $(ROOTBRANDPKG):
+$(ROOT) $(ROOTETC) $(ROOTETCBRAND) $(ROOTETCZONES) $(ROOTUSRLIB) \
+ $(ROOTBRAND) $(ROOTBRANDPKG):
mkdir -p $@
+$(ROOTETCBRAND)/%: $(ROOTETCBRAND) %
+ rm -f $@; $(INSTALL) -f $(ROOTETCBRAND) -m 0644 $<
+
$(ROOTETCZONES)/%: $(ROOTETCZONES) %
rm -f $@; $(INSTALL) -f $(ROOTETCZONES) -m 0444 $<
--- a/src/brand/attach Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/attach Tue Nov 10 14:40:37 2009 -0700
@@ -24,8 +24,12 @@
# Use is subject to license terms.
#
-m_installing=$(gettext "Installing...")
-m_usage=$(gettext "ipkg brand attach arguments [-a archive] [-d dataset] [-n] [-r zfs-recv] [-u]\n\tThe -a archive option specifies a tar file or cpio archive.\n\tThe -d dataset option specifies an existing dataset.\n\tThe -r zfs-recv option receives the output of a 'zfs send' command\n\tof an existing zone root dataset.\n\tThe -u option indicates that the software should be updated to match\n\tthe current host.")
+. /usr/lib/brand/ipkg/common.ksh
+
+m_attach_log=$(gettext "Log File: %s")
+m_zfs=$(gettext "A ZFS file system was created for the zone.")
+m_attaching=$(gettext "Attaching...")
+m_usage=$(gettext "attach [-a archive] [-d dataset] [-n] [-r zfs-recv] [-u]\n\tThe -a archive option specifies a tar file or cpio archive.\n\tThe -d dataset option specifies an existing dataset.\n\tThe -r zfs-recv option receives the output of a 'zfs send' command\n\tof an existing zone root dataset.\n\tThe -u option indicates that the software should be updated to match\n\tthe current host.")
m_gzinc=$( gettext " Global zone version: %s")
m_zinc=$( gettext " Non-Global zone version: %s")
m_insync=$(gettext " Evaluation: Packages in %s are in sync with global zone.")
@@ -41,17 +45,10 @@
m_sync_done=$(gettext " Updating non-global zone: Zone updated to %s")
m_complete=$(gettext "Attach complete.")
-f_option_no_ds=$(gettext "The -a, -d or -r option is required when there is no active root dataset.")
-f_option_ds=$(gettext "The -a, -d or -r option is invalid when there is already an active root dataset.")
-f_bad_archive=$(gettext "Unknown archive format.")
-f_unpack=$(gettext "Unable to install the archive.")
-f_bad_dataset=$(gettext "Non-existent or invalid zone root dataset.")
-f_nogzinc=$(gettext "Could not find 'entire' incorporation for global zone.")
-f_nozinc=$(gettext "Could not find 'entire' incorporation for attaching zone.")
+sanity_fail_global=$(gettext " Sanity Check: FAILED, the image is from the global zone.")
f_downrev=$(gettext "Zone is downrev of global zone. Specify -u to update it.")
f_uprev=$(gettext "Zone is uprev of global zone. Global zone will need to be updated before attach can proceed.")
f_update=$(gettext "Could not update attaching zone")
-f_bad_publisher=$(gettext "Syntax error in publisher information.\n")
f_gz_entire=$(gettext "Could not find 'entire' incorporation for global zone.")
f_zone_entire=$(gettext "Could not find 'entire' incorporation for non-global zone.")
f_fmri_compare=$(gettext "Failed to compare 'entire' FMRIs")
@@ -62,18 +59,67 @@
f_nosuch_key=$(gettext "Failed to find key %s for global zone publisher")
f_nosuch_cert=$(gettext "Failed to find cert %s for global zone publisher")
+# Clean up on interrupt
+trap_cleanup()
+{
+ msg=$(gettext "Installation cancelled due to interrupt.")
+ log "$msg"
+
+ # umount any mounted file systems
+ umnt_fs
+
+ trap_exit
+}
+
+# If the attach failed then clean up the ZFS datasets we created.
+trap_exit()
+{
+ if [[ $EXIT_CODE == $ZONE_SUBPROC_OK ]]; then
+ # unmount the zoneroot
+ umount $ZONEROOT > /dev/null 2>&1
+ else
+ if [[ "$install_media" != "-" ]]; then
+ /usr/lib/brand/ipkg/uninstall $ZONENAME $ZONEPATH -F
+ else
+ # Restore the zone properties for the pre-existing
+ # dataset.
+ if [[ -n "$ACTIVE_DS" ]]; then
+ zfs set zoned=off $ACTIVE_DS >/dev/null 2>&1
+ zfs set canmount=on $ACTIVE_DS >/dev/null 2>&1
+ zfs set mountpoint=$ZONEROOT $ACTIVE_DS \
+ >/dev/null 2>&1
+ fi
+ fi
+ fi
+
+ exit $EXIT_CODE
+}
+
+EXIT_CODE=$ZONE_SUBPROC_USAGE
+install_media="-"
+
+trap trap_cleanup INT
+trap trap_exit EXIT
#set -o xtrace
-. /usr/lib/brand/ipkg/common.ksh
-
-# Setup i18n output
-TEXTDOMAIN="SUNW_OST_OSCMD"
-export TEXTDOMAIN
-
PKG="/usr/bin/pkg"
KEYDIR=/var/pkg/ssl
+# If we weren't passed at least two arguments, exit now.
+(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE
+
+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"
+
#
# Resetting GZ_IMAGE to something besides slash allows for simplified
# debugging of various global zone image configurations-- simply make
@@ -83,355 +129,178 @@
PKG_IMAGE=$GZ_IMAGE
export PKG_IMAGE
-aarg=0
-darg=0
noexecute=0
-rarg=0
+
+unset inst_type
# Other brand attach options are invalid for this brand.
-while getopts "a:d:nR:r:uz:" opt; do
+while getopts "a:d:nr:u" opt; do
case $opt in
- a) ARCHIVE="$OPTARG"
- if [ $darg -eq 1 -o $rarg -eq 1 ]; then
- fail_usage "$m_usage"
+ a)
+ if [[ -n "$inst_type" ]]; then
+ fatal "$incompat_options" "$m_usage"
fi
- aarg=1
+ inst_type="archive"
+ install_media="$OPTARG"
;;
- d) DATASET="$OPTARG"
- if [ $aarg -eq 1 -o $rarg -eq 1 ]; then
- fail_usage "$m_usage"
+ d)
+ if [[ -n "$inst_type" ]]; then
+ fatal "$incompat_options" "$m_usage"
fi
- darg=1
+ inst_type="directory"
+ install_media="$OPTARG"
;;
n) noexecute=1 ;;
- R) zonepath="$OPTARG" ;;
- r) ZFSRCV="$OPTARG"
- if [ $aarg -eq 1 -o $darg -eq 1 ]; then
- fail_usage "$m_usage"
+ r)
+ if [[ -n "$inst_type" ]]; then
+ fatal "$incompat_options" "$m_usage"
fi
- rarg=1
+ inst_type="stdin"
+ install_media="$OPTARG"
;;
u) allow_update=1 ;;
- z) zonename="$OPTARG" ;;
- ?) fail_usage "$m_usage" ;;
- *) fail_usage "$m_usage";;
+ ?) fail_usage "" ;;
+ *) fail_usage "";;
esac
done
shift $((OPTIND-1))
-zoneroot=$zonepath/root
+if [[ $noexecute == 1 && -n "$inst_type" ]]; then
+ fatal "$m_usage"
+fi
+
+[[ -z "$inst_type" ]] && inst_type="directory"
if [ $noexecute -eq 1 ]; then
#
# The zone doesn't have to exist when the -n option is used, so do
# this work early.
#
- if [ $aarg -eq 1 -o $rarg -eq 1 -o $allow_update -eq 1 ]; then
- fail_usage "$m_usage";
- fi
# XXX There is no sw validation for IPS right now, so just pretend
# everything will be ok.
- exit 0
+ EXIT_CODE=$ZONE_SUBPROC_OK
+ exit $ZONE_SUBPROC_OK
fi
-get_current_gzbe
+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"
#
-# XXX we can't do the following since 'zoneadm verify' depends on the zonepath
-# already existing - maybe we can fix this in zoneadm in the future.
-#
-# First make the top-level zonepath dataset and be sure to tolerate errors
-# since this dataset could already exist from a different BE.
-#
-#pdir=`/usr/bin/dirname $zonepath`
-#zpname=`/usr/bin/basename $zonepath`
-#
-#get_zonepath_ds $pdir
-#zpds=$ZONEPATH_DS
-#
-# Note, this dataset might already exist so tolerate an error.
-#/usr/sbin/zfs create $zpds/$zpname
+# 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.
#
-fail_zonepath_in_rootds $zpds
+# 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"
+
+ # 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"
+
+ zfs set mountpoint=legacy $ZONEPATH_DS/ROOT >/dev/null 2>&1
+ zfs set zoned=on $ZONEPATH_DS/ROOT >/dev/null 2>&1
-# Top-level zonepath dataset should now exist.
-get_zonepath_ds $zonepath
+ #
+ # 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 >/dev/null 2>&1
+ zfs set $PROP_ACTIVE=on $ACTIVE_DS >/dev/null 2>&1
+ zfs set canmount=noauto $ACTIVE_DS >/dev/null 2>&1
+ zfs inherit mountpoint $ACTIVE_DS >/dev/null 2>&1
+ zfs inherit zoned $ACTIVE_DS >/dev/null 2>&1
+
+ 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
#
-# Note that the root dataset might already exist and be populated from either
-# a SNAP clone or from an earlier attach that failed because the sw was
-# out of sync but the -u option was not provided. The user might be
-# re-running the attach with the -u option this time. We need to be sure
-# to handle this case gracefully.
+# The zone's datasets are now in place.
+#
+
+log "$m_attaching"
+install_image "$inst_type" "$install_media"
+
+#
+# End of TODO block to move to common code.
#
#
-# We first want to see if there is a pre-existing active root dataset, but
-# we can't call get_active_ds() since it errors out if there is no active
-# dataset.
+# Perform a final sanity check to confirm the image is not of the global zone.
+# Check for a few well-known global zone only svcs.
#
-ACTIVE_DS=`/usr/sbin/zfs list -H -r -t filesystem \
- -o name,$PROP_PARENT,$PROP_ACTIVE $ZONEPATH_DS/ROOT | \
- /usr/bin/nawk -v gzbe=$CURRENT_GZBE ' {
- if ($1 ~ /ROOT\/[^\/]+$/ && $2 == gzbe && $3 == "on") {
- print $1
- if (found == 1)
- exit 1
- found = 1
- }
- }'`
-
-if [ $? -ne 0 ]; then
- fail_fatal "$f_multiple_ds"
-fi
-
-if [ ! -d $zoneroot ]; then
- /usr/bin/mkdir -p $zoneroot
- /usr/bin/chmod 700 $zonepath
-fi
-
-if [ -z "$ACTIVE_DS" ]; then
- #
- # There is no pre-existing active dataset. In this case we need either
- # the -a or -r option to populate a newly created dataset or the -d
- # option to use a pre-existing dataset.
- #
- if [ $aarg -eq 1 -o $rarg -eq 1 ]; then
- /usr/sbin/zfs create -o mountpoint=legacy -o zoned=on \
- $ZONEPATH_DS/ROOT
-
- 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
- if [ $? = 0 ]; then
- break
- fi
- BENUM=`expr $BENUM + 1`
- BENAME="zbe-$BENUM"
- done
-
- if [ $BENUM -ge 100 ]; then
- fail_fatal "$f_zfs_create"
- fi
-
- ACTIVE_DS=$ZONEPATH_DS/ROOT/$BENAME
-
- elif [ $darg -eq 1 ]; then
- #
- # Verify that the dataset exists
- #
- /usr/sbin/zfs list -H -o name $DATASET >/dev/null 2>&1
- if [ $? -ne 0 ]; then
- fail_fatal "$f_bad_dataset"
- fi
-
- #
- # Verify that the dataset looks like it contains a zone root.
- #
- oldmnt=`/usr/sbin/zfs list -H -o mountpoint $DATASET`
-
- if [ "$oldmnt" = "legacy" ]; then
- mntpnt=`/usr/sbin/mount -p | \
- /usr/bin/nawk -v fs=$DATASET \
- '{if ($1 == fs) print $3}'`
-
- if [ -n "$mntpnt" ]; then
- /usr/sbin/umount $mntpnt
- fi
- else
- /usr/sbin/zfs set mountpoint=legacy $DATASET || \
- fail_fatal "$f_zfs_create"
- fi
-
- /usr/sbin/mount -F zfs $DATASET $zoneroot
- if [ $? -ne 0 ]; then
- /usr/sbin/zfs set mountpoint=$oldmnt $DATASET
- if [ "$oldmnt" = "legacy" -a -n "$mntpnt" ]; then
- /usr/sbin/mount -F zfs $DATASET $mntpnt
- fi
- fail_fatal "$f_zfs_mount"
- fi
-
- if [ ! -d $zoneroot/etc -o ! -d $zoneroot/usr ]; then
- /usr/sbin/umount $zoneroot
- /usr/sbin/zfs set mountpoint=$oldmnt $DATASET
- if [ "$oldmnt" = "legacy" -a -n "$mntpnt" ]; then
- /usr/sbin/mount -F zfs $DATASET $mntpnt
- fi
- fail_fatal "$f_bad_dataset"
- fi
-
- #
- # The dataset seems reasonable, make it the active dataset.
- #
- /usr/sbin/umount $zoneroot
-
- /usr/sbin/zfs set zoned=on $DATASET || \
- fail_fatal "$f_zfs_create"
-
- /usr/sbin/zfs set canmount=noauto $DATASET || \
- fail_fatal "$f_zfs_create"
-
- /usr/sbin/zfs set $PROP_ACTIVE=on $DATASET || \
- fail_fatal "$f_zfs_create"
-
- /usr/sbin/zfs set $PROP_PARENT=$CURRENT_GZBE $DATASET || \
- fail_fatal "$f_zfs_create"
-
- ACTIVE_DS=$DATASET
-
- else
- #
- # There is no pre-existing active dataset and no
- # -a, -d or -r option so this is an error.
- #
- fail_fatal "$f_option_no_ds"
- fi
-
-elif [ $aarg -eq 1 -o $darg -eq 1 -o $rarg -eq 1 ]; then
- #
- # We already have an active root dataset. In this case the -a, -d or -r
- # option is invalid (XXX unless we want to overwrite the contents of
- # the pre-existing dataset).
- #
- fail_fatal "$f_option_ds"
-fi
-
-if [ $aarg -eq 1 ]; then
- #
- # Given a tar or cpio archive, unpack the archive into the dataset.
- #
- ftype="`LC_ALL=C file $ARCHIVE | cut -d: -f 2`"
- case "$ftype" in
- *cpio*) filetype="cpio"
- stage1="cat"
- filetypename="cpio archive"
- ;;
- *bzip2*) filetype="cpio"
- stage1="bzcat"
- filetypename="bzipped cpio archive"
- ;;
- *gzip*) filetype="cpio"
- stage1="gzcat"
- filetypename="gzipped cpio archive"
- ;;
- *USTAR\ tar\ archive)
- filetype="tar"
- filetypename="tar archive"
- ;;
- *USTAR\ tar\ archive\ extended\ format*)
- filetype="xustar"
- filetypename="pax (xustar) archive"
- ;;
- *) fail_fatal "$f_bad_archive"
- ;;
- esac
-
- if [ ! -d $zoneroot ]; then
- /usr/bin/mkdir -p $zoneroot
- /usr/bin/chmod 700 $zonepath
- fi
-
- /usr/sbin/mount -F zfs $ACTIVE_DS $zoneroot || fail_fatal "$f_zfs_mount"
-
- echo $m_installing
- echo $filetypename
-
- #
- # XXX What does the archive contain? Do we just get stuff under
- # zonepath/root or do we get zonepath? For zfs send, we send the
- # zonepath/root dataset, so maybe we should assume only zonepath/root
- # here as well?
- #
-
- unpack_result=0
- if [[ "$filetype" = "cpio" ]]; then
- cpioopts="-idm"
- (cd "$zonepath" && $stage1 "$ARCHIVE" | cpio $cpioopts)
- unpack_result=$?
-
- elif [[ "$filetype" = "tar" ]]; then
- (cd "$zonepath" && tar -xf "$ARCHIVE")
- unpack_result=$?
-
- elif [[ "$filetype" = "xustar" ]]; then
- (cd "$zonepath" && pax -r -f "$ARCHIVE")
- unpack_result=$?
- fi
-
- /usr/sbin/umount $zoneroot
-
- if [[ $unpack_result -ne 0 ]]; then
- fail_fatal "$f_unpack"
- fi
-
-elif [ $rarg -eq 1 ]; then
- #
- # Given 'zfs send' output, receive the snapshot into the new dataset.
- # XXX handle piped input
- #
- /usr/sbin/zfs receive -F $ACTIVE_DS < $ZFSRCV || \
- fail_fatal "$f_zfs_create"
-
-else
- #
- # If neither of the -a or -r options are provided, assume
- # detach/attach behavior with an existing SNAP clone dataset already
- # in existence, or we're using one from an earlier detach that was
- # specified with -d, or possibly the dataset exists from a previous
- # attach run that did not finish successfully because the sw was not
- # updated (due to missing -u option).
- #
-
- #
- # We know we already have a valid dataset from earlier validation.
- #
-
- #
- # If we are attaching a zone that was previously detached on this
- # system, then the dataset is not zoned and is mounted at this point.
- # Look to see if the dataset is in this state.
- #
- zoned=`/usr/sbin/zfs list -H -o zoned $ACTIVE_DS`
-
- if [ "$zoned" = "off" ]; then
- #
- # When we detached the SNAP clone zone, we changed some of the
- # properties and then left it mounted. Undo that work now.
- #
- /usr/sbin/umount $zonepath/root >/dev/null 2>&1
-
- /usr/sbin/zfs set zoned=on $ACTIVE_DS || \
- fail_fatal "$f_zfs_create"
-
- /usr/sbin/zfs set mountpoint=legacy $ACTIVE_DS || \
- fail_incomplete "$f_zfs_create"
-
- /usr/sbin/zfs set canmount=noauto $ACTIVE_DS || \
- fail_fatal "$f_zfs_create"
- fi
-fi
-
-
-/usr/sbin/mount -F zfs $ACTIVE_DS $zoneroot || fail_fatal "$f_zfs_mount"
-#
-# unmount the zoneroot and clean up our temp files if anything goes wrong
-#
-trap "/usr/sbin/umount $zoneroot > /dev/null 2>&1" EXIT
-
+[[ -f $ZONEROOT/var/svc/manifest/system/sysevent.xml ]] && \
+ fatal "$sanity_fail_global"
+[[ -f $ZONEROOT/var/svc/manifest/system/zones.xml ]] && \
+ fatal "$sanity_fail_global"
+[[ -f $ZONEROOT/var/svc/manifest/system/dumpadm.xml ]] && \
+ fatal "$sanity_fail_global"
#
# Look for the 'entire' incorporation's FMRI in the current image; due to users
# doing weird machinations with their publishers, we strip off the publisher
# from the FMRI if it is present.
#
-gz_entire_fmri=$(get_entire_incorp) || fail_fatal "$f_gz_entire"
+gz_entire_fmri=$(get_entire_incorp) || fatal "$f_gz_entire"
#
# Get publisher information for global zone.
@@ -456,7 +325,7 @@
# We're done with the global zone: switch images to the non-global
# zone.
#
-PKG_IMAGE="$zoneroot"
+PKG_IMAGE="$ZONEROOT"
#
# Get publisher information for non global zone.
@@ -464,13 +333,13 @@
#
get_preferred_publisher | IFS=" " read zone_publisher zone_publisher_url
-[[ -z $zone_publisher ]] && fail_usage "$f_no_pref_publisher" $zonename
-[[ -z $zone_publisher_url ]] && fail_usage "$f_no_pref_publisher" $zonename
+[[ -z $zone_publisher ]] && fail_usage "$f_no_pref_publisher" $ZONENAME
+[[ -z $zone_publisher_url ]] && fail_usage "$f_no_pref_publisher" $ZONENAME
#
# Get entire incorp for non-global zone
#
-zone_entire_fmri=$(get_entire_incorp) || fail_fatal "$f_zone_entire"
+zone_entire_fmri=$(get_entire_incorp) || fatal "$f_zone_entire"
printf "$m_gzinc\n" $gz_entire_fmri
printf "$m_zinc\n" $zone_entire_fmri
@@ -479,16 +348,17 @@
#
comp=$(/usr/lib/brand/ipkg/fmri_compare $zone_entire_fmri $gz_entire_fmri)
if [[ $? -ne 0 ]]; then
- fail_fatal "$f_fmri_compare"
+ fatal "$f_fmri_compare"
fi
if [[ $comp = "=" ]]; then
- printf "$m_insync\n" $zonename
+ printf "$m_insync\n" $ZONENAME
echo $m_complete
+ EXIT_CODE=$ZONE_SUBPROC_OK
exit $ZONE_SUBPROC_OK
fi
if [[ $comp = ">" ]]; then
- printf "$m_uprev\n" $zonename
- fail_fatal "$f_uprev"
+ printf "$m_uprev\n" $ZONENAME
+ fatal "$f_uprev"
fi
#
@@ -496,8 +366,8 @@
#
if [ -z $allow_update ]; then
# zone is downrev
- printf "$m_dnrev\n" $zonename
- fail_fatal "$f_downrev"
+ printf "$m_dnrev\n" $ZONENAME
+ fatal "$f_downrev"
fi
#
@@ -515,31 +385,31 @@
printf "$m_resetpub2\n" $gz_entire_fmri
printf "$m_resetpub3\n"
- safe_dir $zoneroot/var
- safe_dir $zoneroot/var/pkg
+ safe_dir var
+ safe_dir var/pkg
# Copy credentials from global zone.
secinfo=""
if [[ $gzkeyfile != "None" || $gzcertfile != "None" ]]; then
- if [[ -e $zoneroot/$KEYDIR ]]; then
- safe_dir $zoneroot/$KEYDIR
+ if [[ -e $ZONEROOT/$KEYDIR ]]; then
+ safe_dir $KEYDIR
else
- mkdir -m 755 $zoneroot/$KEYDIR
+ mkdir -m 755 $ZONEROOT/$KEYDIR
fi
fi
if [[ $gzkeyfile != None ]]; then
newlocation="$KEYDIR/attach_$(basename $gzkeyfile)"
- safe_copy $gzkeyfile $zoneroot/$newlocation
- chmod 644 $zoneroot/$newkeylocation
- chown -h root:root $zoneroot/$newkeylocation
+ safe_copy $gzkeyfile $ZONEROOT/$newlocation
+ chmod 644 $ZONEROOT/$newkeylocation
+ chown -h root:root $ZONEROOT/$newkeylocation
secinfo="$secinfo -k $newlocation"
fi
if [[ $gzcertfile != None ]]; then
newlocation="$KEYDIR/attach_$(basename $gzcertfile)"
- safe_copy $gzcertfile $zoneroot/$newlocation
- chmod 644 $zoneroot/$newkeylocation
- chown -h root:root $zoneroot/$newkeylocation
+ safe_copy $gzcertfile $ZONEROOT/$newlocation
+ chmod 644 $ZONEROOT/$newkeylocation
+ chown -h root:root $ZONEROOT/$newkeylocation
secinfo="$secinfo -c $newlocation"
fi
@@ -547,7 +417,7 @@
# catalog to be updated.
$PKG set-publisher -P -O $gz_publisher_url $secinfo $gz_publisher
if [[ $? -ne 0 ]]; then
- fail_fatal "$f_reset_pub"
+ fatal "$f_reset_pub"
fi
zone_publisher=$gz_publisher
zone_publisher_url=$gz_publisher_url
@@ -570,7 +440,7 @@
#
$PKG install $gz_entire_fmri
if [ $? -ne 0 ]; then
- fail_fatal "$f_update"
+ fatal "$f_update"
fi
printf "$m_updating2\n"
@@ -585,15 +455,16 @@
zone_pkgs=$(LC_ALL=C $PKG list --no-refresh -H "pkg://$zone_publisher/*" | \
awk '{print $1}' | egrep -v '^entire$')
if [[ $? -ne 0 ]]; then
- fail_fatal "$f_pkg_list"
+ fatal "$f_pkg_list"
fi
$PKG install $zone_pkgs
if [ $? -ne 0 ]; then
- fail_fatal "$f_update"
+ fatal "$f_update"
fi
printf "$m_sync_done\n" $gz_entire_fmri
printf "$m_complete\n"
+EXIT_CODE=$ZONE_SUBPROC_OK
exit $ZONE_SUBPROC_OK
--- a/src/brand/clone Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/clone Tue Nov 10 14:40:37 2009 -0700
@@ -26,6 +26,7 @@
. /usr/lib/brand/ipkg/common.ksh
+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.")
@@ -39,13 +40,13 @@
case $opt in
R) zonepath="$OPTARG" ;;
z) zonename="$OPTARG" ;;
- *) fail_usage "$0 {sourcezone}";;
+ *) fail_usage "";;
esac
done
shift $((OPTIND-1))
if [ $# -ne 1 ]; then
- fail_usage "$0 {sourcezone}";
+ fail_usage "";
fi
sourcezone=$1
--- a/src/brand/common.ksh Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/common.ksh Tue Nov 10 14:40:37 2009 -0700
@@ -23,27 +23,41 @@
# Use is subject to license terms.
#
-ZONE_SUBPROC_OK=0
-ZONE_SUBPROC_USAGE=253
-ZONE_SUBPROC_INCOMPLETE=254
-ZONE_SUBPROC_FATAL=255
+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"
+f_incompat_options=$(gettext "cannot specify both %s and %s options")
+f_sanity_detail=$(gettext "Missing %s at %s")
+f_sanity_sparse=$(gettext "Is this a sparse zone image? The image must be whole-root.")
+sanity_ok=$(gettext " Sanity Check: Passed. Looks like an OpenSolaris system.")
+sanity_fail=$(gettext " Sanity Check: FAILED (see log for details).")
+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 in the ROOT pool 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 "Error: unable to determine global zone boot environment.")
-f_no_ds=$(gettext "Error: no zonepath dataset.")
-f_multiple_ds=$(gettext "Error: multiple active datasets.")
-f_no_active_ds=$(gettext "Error: no active dataset.")
+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_mount=$(gettext "Unable to mount the zone's ZFS dataset.")
f_safedir=$(gettext "Expected %s to be a directory.")
f_cp=$(gettext "Failed to cp %s %s.")
f_cp_unsafe=$(gettext "Failed to safely copy %s to %s.")
+m_brnd_usage=$(gettext "brand-specific usage: ")
+
+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.")
+
fail_incomplete() {
printf "ERROR: " 1>&2
printf "$@" 1>&2
@@ -51,16 +65,59 @@
exit $ZONE_SUBPROC_INCOMPLETE
}
-fail_fatal() {
- printf "ERROR: " 1>&2
+fail_usage() {
printf "$@" 1>&2
printf "\n" 1>&2
- exit $ZONE_SUBPROC_FATAL
+ printf "$m_brnd_usage" 1>&2
+ printf "$m_usage\n" 1>&2
+ exit $ZONE_SUBPROC_USAGE
}
-fail_usage() {
- print "Usage: $1"
- exit $ZONE_SUBPROC_USAGE
+sanity_check()
+{
+ typeset dir="$1"
+ shift
+ res=0
+
+ #
+ # Check for some required directories and make sure this isn't a
+ # sparse zone image from SXCE.
+ #
+ checks="etc etc/svc var var/svc"
+ for x in $checks; do
+ if [[ ! -e $dir/$x ]]; then
+ log "$f_sanity_detail" "$x" "$dir"
+ res=1
+ fi
+ done
+ if (( $res != 0 )); then
+ log "$f_sanity_sparse"
+ log "$sanity_fail"
+ fatal "$install_fail" "$ZONENAME"
+ fi
+
+ # Check for existence of pkg command.
+ if [[ ! -x $dir/usr/bin/pkg ]]; then
+ log "$f_sanity_detail" "usr/bin/pkg" "$dir"
+ log "$sanity_fail"
+ fatal "$install_fail" "$ZONENAME"
+ fi
+
+ #
+ # XXX There should be a better way to do this.
+ # Check image release. We only work on the same minor release as the
+ # system is running. The INST_RELEASE file doesn't exist with IPS on
+ # OpenSolaris, so its presence means we have an earlier Solaris
+ # (i.e. non-OpenSolaris) image.
+ #
+ if [[ -f "$dir/var/sadm/system/admin/INST_RELEASE" ]]; then
+ image_vers=$(nawk -F= '{if ($1 == "VERSION") print $2}' \
+ $dir/var/sadm/system/admin/INST_RELEASE)
+ vlog "$sanity_fail_vers" "$image_vers"
+ fatal "$install_fail" "$ZONENAME"
+ fi
+
+ vlog "$sanity_ok"
}
get_current_gzbe() {
@@ -85,19 +142,6 @@
fi
}
-# Find the dataset mounted on the zonepath.
-get_zonepath_ds() {
- ZONEPATH_DS=`/usr/sbin/zfs list -H -t filesystem -o name,mountpoint | \
- /usr/bin/nawk -v zonepath=$1 '{
- if ($2 == zonepath)
- print $1
- }'`
-
- if [ -z "$ZONEPATH_DS" ]; then
- fail_fatal "$f_no_ds"
- fi
-}
-
# Find the active dataset under the zonepath dataset to mount on zonepath/root.
# $1 CURRENT_GZBE
# $2 ZONEPATH_DS
@@ -136,6 +180,66 @@
}
#
+# Set up ZFS dataset hierarchy for the zone root dataset.
+#
+create_active_ds() {
+ 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
+
+ #
+ # 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 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
+
+ if [ $BENUM -ge 100 ]; then
+ fail_fatal "$f_zfs_create"
+ fi
+
+ if [ ! -d $ZONEROOT ]; then
+ /usr/bin/mkdir $ZONEROOT
+ fi
+
+ /usr/sbin/mount -F zfs $ZONEPATH_DS/ROOT/$BENAME $ZONEROOT || \
+ fail_incomplete "$f_zfs_mount"
+}
+
+#
# Emits to stdout the entire incorporation for this image,
# stripped of publisher name and other junk.
#
@@ -172,26 +276,3 @@
nawk -F': ' '/SSL Cert/ {print $2; exit 0}')
print $key $cert
}
-
-# Validate that the directory is safe.
-# n.b.: this is diverged from the shared/common.ksh version.
-safe_dir()
-{
- typeset dir="$1"
-
- [[ -h $dir || ! -d $dir ]] && fail_fatal "$f_safedir"
-}
-
-# Make a copy even if the destination already exists.
-# n.b.: this is diverged from the shared/common.ksh version.
-safe_copy()
-{
- typeset src="$1"
- typeset dst="$2"
-
- if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then
- /usr/bin/cp -p $src $dst || fail_fatal "$f_cp" "$src" "$dst"
- else
- fail_fatal "$f_cp_unsafe" "$src" "$dst"
- fi
-}
--- a/src/brand/config.xml Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/config.xml Tue Nov 10 14:40:37 2009 -0700
@@ -38,20 +38,20 @@
<!-- We may not be able to do the create in pkg(1) proper. -->
<install>/usr/lib/brand/ipkg/pkgcreatezone -z %z -R %R</install>
- <installopts>a:P:e:c:k:h</installopts>
+ <installopts>a:c:d:e:hk:P:p:suv</installopts>
<boot></boot>
<halt></halt>
<verify_cfg>/usr/lib/brand/ipkg/support verify</verify_cfg>
<verify_adm></verify_adm>
<postclone></postclone>
<postinstall></postinstall>
- <attach>/usr/lib/brand/ipkg/attach -z %z -R %R</attach>
+ <attach>/usr/lib/brand/ipkg/attach %z %R</attach>
<detach>/usr/lib/brand/ipkg/detach -z %z -R %R</detach>
<clone>/usr/lib/brand/ipkg/clone -z %z -R %R</clone>
<uninstall>/usr/lib/brand/ipkg/uninstall %z %R</uninstall>
<prestatechange>/usr/lib/brand/ipkg/prestate %z %R</prestatechange>
<poststatechange>/usr/lib/brand/ipkg/poststate %z %R</poststatechange>
- <query>/usr/lib/brand/ipkg/query %z %R</query>
+ <query>/usr/lib/brand/shared/query %z %R</query>
<privilege set="default" name="contract_event" />
<privilege set="default" name="contract_identity" />
--- a/src/brand/detach Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/detach Tue Nov 10 14:40:37 2009 -0700
@@ -20,13 +20,13 @@
# 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
-m_usage=$(gettext "ipkg brand detach arguments [-n ].")
+m_usage=$(gettext "detach [-n ].")
f_mount=$(gettext "Error: error mounting zone root dataset.")
@@ -38,8 +38,8 @@
n) noexecute=1 ;;
R) zonepath="$OPTARG" ;;
z) zonename="$OPTARG" ;;
- ?) fail_usage "$m_usage" ;;
- *) fail_usage "$m_usage";;
+ ?) fail_usage "" ;;
+ *) fail_usage "";;
esac
done
shift $((OPTIND-1))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/image_install Tue Nov 10 14:40:37 2009 -0700
@@ -0,0 +1,231 @@
+#!/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 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# image_install is used when installing a zone in a 'p2v' scenario. In
+# this case the zone install hook will branch off to this script which
+# is responsible for setting up the physical system image in the zonepath
+# and performing the various modifications necessary to enable a physical
+# system image to run inside a zone. This script sets up the image in the
+# zonepath then calls the p2v script to modify the image to run in a zone.
+#
+
+. /usr/lib/brand/ipkg/common.ksh
+
+m_usage=$(gettext "\n install {-a archive|-d path} {-p|-u} [-s|-v]")
+install_log=$(gettext " Log File: %s")
+
+p2ving=$(gettext "Postprocessing: This may take a while...")
+p2v_prog=$(gettext " Postprocess: ")
+p2v_done=$(gettext " Result: Postprocessing complete.")
+p2v_fail=$(gettext " Result: Postprocessing failed.")
+m_postnote3=$(gettext " Make any other adjustments, such as disabling SMF services\n that are no longer needed.")
+
+media_missing=\
+$(gettext "%s: you must specify an installation source using '-a' or '-d'.")
+cfgchoice_missing=\
+$(gettext "you must specify -u (sys-unconfig) or -p (preserve identity).")
+
+# Clean up on interrupt
+trap_cleanup()
+{
+ msg=$(gettext "Installation cancelled due to interrupt.")
+ log "$msg"
+
+ trap_exit
+}
+
+# If the install failed then clean up the ZFS datasets we created.
+trap_exit()
+{
+ # umount any mounted file systems
+ [[ -n "$fstmpfile" ]] && umnt_fs
+
+ if (( $zone_is_mounted != 0 )); then
+ error "$v_unmount"
+ zoneadm -z $ZONENAME unmount
+ zone_is_mounted=0
+ fi
+
+ if (( $EXIT_CODE != $ZONE_SUBPROC_OK )); then
+ /usr/lib/brand/ipkg/uninstall $ZONENAME $ZONEPATH -F
+ fi
+
+ exit $EXIT_CODE
+}
+
+#
+# The main body of the script starts here.
+#
+# This script should never be called directly by a user but rather should
+# only be called by pkgcreatezone to install an OpenSolaris system image into
+# a zone.
+#
+
+#
+# Exit code to return if install is interrupted or exit code is otherwise
+# unspecified.
+#
+EXIT_CODE=$ZONE_SUBPROC_USAGE
+
+zone_is_mounted=0
+trap trap_cleanup INT
+trap trap_exit EXIT
+
+# If we weren't passed at least two arguments, exit now.
+(( $# < 2 )) && exit $ZONE_SUBPROC_USAGE
+
+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
+unset msg
+unset silent_mode
+unset verbose_mode
+
+#
+# It is worth noting here that we require the end user to pick one of
+# -u (sys-unconfig) or -p (preserve config). This is because we can't
+# really know in advance which option makes a better default. Forcing
+# the user to pick one or the other means that they will consider their
+# choice and hopefully not be surprised or disappointed with the result.
+#
+unset unconfig_zone
+unset preserve_zone
+
+while getopts "a:d:psuv" opt
+do
+ case "$opt" in
+ a)
+ if [[ -n "$inst_type" ]]; then
+ fatal "$both_kinds" "zoneadm install"
+ fi
+ inst_type="archive"
+ install_media="$OPTARG"
+ ;;
+ d)
+ if [[ -n "$inst_type" ]]; then
+ fatal "$both_kinds" "zoneadm install"
+ fi
+ inst_type="directory"
+ install_media="$OPTARG"
+ ;;
+ p) preserve_zone="-p";;
+ s) silent_mode=1;;
+ u) unconfig_zone="-u";;
+ v) verbose_mode="-v";;
+ *) exit $ZONE_SUBPROC_USAGE;;
+ esac
+done
+shift OPTIND-1
+
+# The install can't be both verbose AND silent...
+[[ -n $silent_mode && -n $verbose_mode ]] && \
+ fatal "$f_incompat_options" "-s" "-v"
+
+[[ -z $install_media ]] && fatal "$media_missing" "zoneadm install"
+
+# The install can't both preserve and unconfigure
+[[ -n $unconfig_zone && -n $preserve_zone ]] && \
+ fatal "$f_incompat_options" "-u" "-p"
+
+# Must pick one or the other.
+[[ -z $unconfig_zone && -z $preserve_zone ]] && fail_usage "$cfgchoice_missing"
+
+LOGFILE=$(/usr/bin/mktemp -t -p /var/tmp $ZONENAME.install_log.XXXXXX)
+[[ -z "$LOGFILE" ]] && fatal "$e_tmpfile"
+exec 2>>"$LOGFILE"
+log "$install_log" "$LOGFILE"
+
+vlog "Starting pre-installation tasks."
+
+#
+# From here on out, an unspecified exit or interrupt should exit with
+# ZONE_SUBPROC_NOTCOMPLETE, meaning a user will need to do an uninstall before
+# attempting another install, as we've modified the directories we were going
+# to install to in some way.
+#
+EXIT_CODE=$ZONE_SUBPROC_NOTCOMPLETE
+
+# ZONEROOT was created by our caller (pkgcreatezone)
+
+vlog "Installation started for zone \"$ZONENAME\""
+install_image "$inst_type" "$install_media"
+
+#
+# Run p2v.
+#
+# Getting the output to the right places is a little tricky because what
+# we want is for p2v to output in the same way the installer does: verbose
+# messages to the log file always, and verbose messages printed to the
+# user if the user passes -v. This rules out simple redirection. And
+# we can't use tee or other tricks because they cause us to lose the
+# return value from the p2v script due to the way shell pipelines work.
+#
+# The simplest way to do this seems to be to hand off the management of
+# the log file to the p2v script. So we run p2v with -l to tell it where
+# to find the log file and then reopen the log (O_APPEND) when p2v is done.
+#
+log "$p2ving"
+vlog "running: p2v $verbose_mode $unconfig_zone $ZONENAME $ZONEPATH"
+/usr/lib/brand/ipkg/p2v -l "$LOGFILE" $verbose_mode $unconfig_zone $ZONENAME \
+ $ZONEPATH
+p2v_result=$?
+exec 2>>$LOGFILE
+
+if (( $p2v_result != 0 )); then
+ log "$p2v_fail"
+ log ""
+ log "$install_fail"
+ log "$install_log" "$LOGFILE"
+ exit $ZONE_SUBPROC_FATAL
+fi
+vlog "$p2v_done"
+
+zone_is_mounted=1
+zoneadm -z $ZONENAME mount -f || fatal "$e_badmount"
+
+safe_copy $LOGFILE $ZONEPATH/lu/a/var/log/$ZONENAME.install$$.log
+
+zoneadm -z $ZONENAME unmount || fatal "$e_badunmount"
+zone_is_mounted=0
+
+trap - EXIT
+rm -f $LOGFILE
+log ""
+log "$m_complete" ${SECONDS}
+printf "$install_log\n" "$ZONEROOT/var/log/$ZONENAME.install$$.log"
+printf "$m_postnote\n"
+printf "$m_postnote2\n"
+printf "$m_postnote3\n"
+
+exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/p2v Tue Nov 10 14:40:37 2009 -0700
@@ -0,0 +1,516 @@
+#!/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 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# NOTE: this script runs in the global zone and touches the non-global
+# zone, so care should be taken to validate any modifications so that they
+# are safe.
+
+# 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
+
+LOGFILE=
+EXIT_CODE=1
+
+# Clean up on failure
+trap_exit()
+{
+ if (( $zone_is_mounted != 0 )); then
+ error "$v_unmount"
+ zoneadm -z $ZONENAME unmount
+ fi
+
+ exit $EXIT_CODE
+}
+
+#
+# For an exclusive stack zone, fix up the network configuration files.
+# We need to do this even if unconfiguring the zone so sys-unconfig works
+# correctly.
+#
+fix_net()
+{
+ [[ "$STACK_TYPE" == "shared" ]] && return
+
+ NETIF_CNT=0
+ for i in $ZONEROOT/etc/hostname.* $ZONEROOT/etc/dhcp.*
+ do
+ if [[ -f "$i" ]]; then
+ NETIF_CNT=$(expr $NETIF_CNT + 1)
+ OLD_HOSTNET="$i"
+ fi
+ done
+ if (( $NETIF_CNT != 1 )); then
+ vlog "$v_nonetfix"
+ return
+ fi
+
+ NET=$(LC_ALL=C zonecfg -z $ZONENAME info net)
+ if (( $? != 0 )); then
+ error "$e_badinfo" "net"
+ return
+ fi
+
+ NETIF=$(echo $NET | nawk '{
+ for (i = 1; i < NF; i++) {
+ if ($i == "physical:") {
+ if (length(net) == 0) {
+ i++
+ net = $i
+ } else {
+ multiple=1
+ }
+ }
+ }
+ }
+ END { if (!multiple)
+ print net
+ }')
+
+ if [[ -z "$NETIF" ]]; then
+ vlog "$v_nonetfix"
+ return
+ fi
+
+ NEWHOSTNET=${OLD_HOSTNET%*.*}
+ if [[ "$OLD_HOSTNET" != "$NEWHOSTNET.$NETIF" ]]; then
+ safe_move $OLD_HOSTNET $NEWHOSTNET.$NETIF
+ fi
+}
+
+#
+# Disable all of the shares since the zone cannot be an NFS server.
+# Note that we disable the various instances of the svc:/network/shares/group
+# SMF service in the fix_smf function.
+#
+fix_nfs()
+{
+ zonedfs=$ZONEROOT/etc/dfs
+
+ if [[ -h $zonedfs/dfstab || ! -f $zonedfs/dfstab ]]; then
+ error "$e_badfile" "/etc/dfs/dfstab"
+ return
+ fi
+
+ tmpfile=$(mktemp -t)
+ if [[ -z "$tmpfile" ]]; then
+ error "$e_tmpfile"
+ return
+ fi
+
+ nawk '{
+ if (substr($1, 0, 1) == "#") {
+ print $0
+ } else {
+ print "#", $0
+ modified=1
+ }
+ }
+ END {
+ if (modified == 1) {
+ printf("# Modified by p2v ")
+ system("/usr/bin/date")
+ exit 0
+ }
+ exit 1
+ }' $zonedfs/dfstab >>$tmpfile
+
+ if (( $? == 0 )); then
+ if [[ ! -f $zonedfs/dfstab.pre_p2v ]]; then
+ safe_copy $zonedfs/dfstab $zonedfs/dfstab.pre_p2v
+ fi
+ safe_copy $tmpfile $zonedfs/dfstab
+ fi
+ rm -f $tmpfile
+}
+
+#
+# Comment out most of the old mounts since they are either unneeded or
+# likely incorrect within a zone. Specific mounts can be manually
+# reenabled if the corresponding device is added to the zone.
+#
+fix_vfstab()
+{
+ if [[ -h $ZONEROOT/etc/vfstab || ! -f $ZONEROOT/etc/vfstab ]]; then
+ error "$e_badfile" "/etc/vfstab"
+ return
+ fi
+
+ tmpfile=$(mktemp -t)
+ if [[ -z "$tmpfile" ]]; then
+ error "$e_tmpfile"
+ return
+ fi
+
+ nawk '{
+ if (substr($1, 0, 1) == "#") {
+ print $0
+ } else if ($1 == "fd" || $1 == "/proc" || $1 == "swap" ||
+ $1 == "ctfs" || $1 == "objfs" || $1 == "sharefs" ||
+ $4 == "nfs" || $4 == "lofs") {
+ print $0
+ } else {
+ print "#", $0
+ modified=1
+ }
+ }
+ END {
+ if (modified == 1) {
+ printf("# Modified by p2v ")
+ system("/usr/bin/date")
+ exit 0
+ }
+ exit 1
+ }' $ZONEROOT/etc/vfstab >>$tmpfile
+
+ if (( $? == 0 )); then
+ if [[ ! -f $ZONEROOT/etc/vfstab.pre_p2v ]]; then
+ safe_copy $ZONEROOT/etc/vfstab \
+ $ZONEROOT/etc/vfstab.pre_p2v
+ fi
+ safe_copy $tmpfile $ZONEROOT/etc/vfstab
+ fi
+ rm -f $tmpfile
+}
+
+#
+# Delete or disable SMF services.
+#
+fix_smf()
+{
+ SMF_UPGRADE=/a/var/svc/profile/upgrade
+
+ #
+ # Fix network services if shared stack.
+ #
+ if [[ "$STACK_TYPE" == "shared" ]]; then
+ vlog "$v_fixnetsvcs"
+
+ NETPHYSDEF="svc:/network/physical:default"
+ NETPHYSNWAM="svc:/network/physical:nwam"
+
+ vlog "$v_enblsvc" "$NETPHYSDEF"
+ zlogin -S $ZONENAME "echo /usr/sbin/svcadm enable $NETPHYSDEF \
+ >>$SMF_UPGRADE" </dev/null
+
+ vlog "$v_dissvc" "$NETPHYSNWAM"
+ zlogin -S $ZONENAME \
+ "echo /usr/sbin/svcadm disable $NETPHYSNWAM \
+ >>$SMF_UPGRADE" </dev/null
+
+ # Disable routing svcs.
+ vlog "$v_dissvc" 'svc:/network/routing/*'
+ zlogin -S $ZONENAME \
+ "echo /usr/sbin/svcadm disable 'svc:/network/routing/*' \
+ >>$SMF_UPGRADE" </dev/null
+ fi
+
+ #
+ # Disable well-known services that don't run in a zone.
+ #
+ vlog "$v_rminvalidsvcs"
+ for i in $(egrep -hv "^#" \
+ /usr/lib/brand/ipkg/smf_disable.lst \
+ /etc/brand/ipkg/smf_disable.conf)
+ do
+ # Disable the svc.
+ vlog "$v_dissvc" "$i"
+ zlogin -S $ZONENAME \
+ "echo /usr/sbin/svcadm disable $i >>$SMF_UPGRADE" </dev/null
+ done
+
+ #
+ # Since zones can't be NFS servers, disable all of the instances of
+ # the shares svc.
+ #
+ vlog "$v_dissvc" 'svc:/network/shares/*'
+ zlogin -S $ZONENAME \
+ "echo /usr/sbin/svcadm disable 'svc:/network/shares/*' \
+ >>$SMF_UPGRADE" </dev/null
+}
+
+#
+# Remove well-known pkgs that do not work inside a zone.
+#
+rm_pkgs()
+{
+ for i in $(egrep -hv "^#" /usr/lib/brand/ipkg/pkgrm.lst \
+ /etc/brand/ipkg/pkgrm.conf)
+ do
+ pkg info $i >/dev/null 2>&1
+ if (( $? != 0 )); then
+ continue
+ fi
+
+ vlog "$v_rmpkg" "$i"
+ zlogin -S $ZONENAME LC_ALL=C \
+ /usr/bin/pkg -R /a uninstall -r $i </dev/null >&2 || \
+ error "$e_rmpkg" $i
+ done
+}
+
+#
+# Zoneadmd writes a one-line index file into the zone when the zone boots,
+# so any information about installed zones from the original system will
+# be lost at that time. Here we'll warn the sysadmin about any pre-existing
+# zones that they might want to clean up by hand, but we'll leave the zonepaths
+# in place in case they're on shared storage and will be migrated to
+# a new host.
+#
+warn_zones()
+{
+ zoneconfig=$ZONEROOT/etc/zones
+
+ if [[ -h $zoneconfig/index || ! -f $zoneconfig/index ]]; then
+ error "$e_badfile" "/etc/zones/index"
+ return
+ fi
+
+ NGZ=$(nawk -F: '{
+ if (substr($1, 0, 1) == "#" || $1 == "global")
+ continue
+
+ if ($2 == "installed")
+ printf("%s ", $1)
+ }' $zoneconfig/index)
+
+ # Return if there are no installed zones to warn about.
+ [[ -z "$NGZ" ]] && return
+
+ log "$v_rmzones" "$NGZ"
+
+ NGZP=$(nawk -F: '{
+ if (substr($1, 0, 1) == "#" || $1 == "global")
+ continue
+
+ if ($2 == "installed")
+ printf("%s ", $3)
+ }' $zoneconfig/index)
+
+ log "$v_rmzonepaths"
+
+ for i in $NGZP
+ do
+ log " %s" "$i"
+ done
+}
+
+#
+# failure should unmount the zone if necessary;
+#
+zone_is_mounted=0
+trap trap_exit EXIT
+
+#
+# Parse the command line options.
+#
+OPT_U=
+OPT_V=
+OPT_L=
+while getopts "b:uvl:" opt
+do
+ case "$opt" in
+ u) OPT_U="-u";;
+ v) OPT_V="-v";;
+ l) LOGFILE="$OPTARG"; OPT_L="-l \"$OPTARG\"";;
+ *) exit 1;;
+ esac
+done
+shift OPTIND-1
+
+(( $# != 2 )) && exit 1
+
+[[ -n $LOGFILE ]] && exec 2>>$LOGFILE
+
+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")
+e_tmpfile=$(gettext "Unable to create temporary file")
+v_mkdirs=$(gettext "Creating mount points")
+v_nonetfix=$(gettext "Cannot update /etc/hostname.{net} file")
+v_change_var=$(gettext "Changing the pkg variant to nonglobal...")
+e_change_var=$(gettext "Changing the pkg variant to nonglobal failed")
+v_update=$(gettext "Updating the zone software to match the global zone...")
+v_updatedone=$(gettext "Zone software update complete")
+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")
+v_collectingsmf=$(gettext "Collecting SMF svc data")
+v_delsvc=$(gettext "Delete SMF svc '%s'")
+e_delsvc=$(gettext "deleting SMF svc '%s'")
+v_enblsvc=$(gettext "Enable SMF svc '%s'")
+e_enblsvc=$(gettext "enabling SMF svc '%s'")
+v_dissvc=$(gettext "Disable SMF svc '%s'")
+e_adminf=$(gettext "Unable to create admin file")
+v_rmpkg=$(gettext "Remove package '%s'")
+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
+#
+safe_dir etc
+safe_dir etc/dfs
+safe_dir etc/zones
+safe_dir var
+safe_dir var/log
+safe_dir var/pkg
+
+# Now do the work to update the zone.
+
+# Before booting the zone we may need to create a few mnt points, just in
+# case they don't exist for some reason.
+#
+# Whenever we reach into the zone while running in the global zone we
+# need to validate that none of the interim directories are symlinks
+# that could cause us to inadvertently modify the global zone.
+vlog "$v_mkdirs"
+if [[ ! -f $ZONEROOT/tmp && ! -d $ZONEROOT/tmp ]]; then
+ mkdir -m 1777 -p $ZONEROOT/tmp || exit $EXIT_CODE
+fi
+if [[ ! -f $ZONEROOT/var/run && ! -d $ZONEROOT/var/run ]]; then
+ mkdir -m 1755 -p $ZONEROOT/var/run || exit $EXIT_CODE
+fi
+if [[ ! -h $ZONEROOT/etc && ! -f $ZONEROOT/etc/mnttab ]]; then
+ touch $ZONEROOT/etc/mnttab || exit $EXIT_CODE
+ chmod 444 $ZONEROOT/etc/mnttab || exit $EXIT_CODE
+fi
+if [[ ! -f $ZONEROOT/proc && ! -d $ZONEROOT/proc ]]; then
+ mkdir -m 755 -p $ZONEROOT/proc || exit $EXIT_CODE
+fi
+if [[ ! -f $ZONEROOT/dev && ! -d $ZONEROOT/dev ]]; then
+ mkdir -m 755 -p $ZONEROOT/dev || exit $EXIT_CODE
+fi
+if [[ ! -h $ZONEROOT/etc && ! -h $ZONEROOT/etc/svc && ! -d $ZONEROOT/etc/svc ]]
+then
+ mkdir -m 755 -p $ZONEROOT/etc/svc/volatile || exit $EXIT_CODE
+fi
+
+# Check for zones inside of image.
+warn_zones
+
+STACK_TYPE=$(zoneadm -z $ZONENAME list -p | nawk -F: '{print $7}')
+if (( $? != 0 )); then
+ error "$e_badinfo" "stacktype"
+fi
+vlog "$v_stacktype" "$STACK_TYPE"
+
+# Note that we're doing this before update-on-attach has run.
+fix_net
+fix_nfs
+fix_vfstab
+
+#
+# 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
+zoneadm -z $ZONENAME mount -f || fatal "$e_badmount"
+
+#
+# Any errors in these functions are not considered fatal. The zone can be
+# be fixed up manually afterwards and it may need some additional manual
+# cleanup in any case.
+#
+
+log "$v_adjust"
+# cleanup SMF services
+fix_smf
+# remove invalid pkgs
+rm_pkgs
+
+vlog "$v_unmount"
+zoneadm -z $ZONENAME unmount || fatal "$e_badunmount"
+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"
+
+# Change the pkging variant from global zone to non-global zone.
+log "$v_change_var"
+pkg -R $ZONEROOT change-variant variant.opensolaris.zone=nonglobal || \
+ fatal "$e_change_var"
+
+#
+# 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.
+# 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.
+#
+log "$v_update"
+zoneadm -z $ZONENAME attach -U >&2 || fatal "$e_badupdate"
+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"
+
+ /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
+
+trap - EXIT
+vlog "$v_exitgood"
+exit 0
--- a/src/brand/pkgcreatezone Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/pkgcreatezone Tue Nov 10 14:40:37 2009 -0700
@@ -35,12 +35,15 @@
. /usr/lib/brand/ipkg/common.ksh
+f_a_obs=$(gettext "-a publisher=uri option is obsolete, use -P instead.")
f_pkg5_missing=$(gettext "pkg(5) does not seem to be present on this system.\n")
-f_no_pref_publisher=$(gettext "Unable to get global zone preferred publisher information, and none was supplied.\nYou must specify one using the -P option.\n")
+f_no_pref_publisher=$(gettext "Unable to get global zone preferred publisher information, and none was supplied.\nYou must specify one using the -P option.")
+f_key_file=$(gettext "Key file not allowed without -P")
+f_cert_file=$(gettext "Cert file not allowed without -P")
f_img=$(gettext "failed to create image\n")
f_pkg=$(gettext "failed to install package\n")
f_interrupted=$(gettext "Installation cancelled due to interrupt.\n")
-f_bad_publisher=$(gettext "Syntax error in publisher information.\n")
+f_bad_publisher=$(gettext "Syntax error in publisher information.")
f_no_entire=$(gettext "Unable to find 'entire' incorporation in the global zone image.\n")
f_no_entire_in_pref=$(gettext "Unable to locate the incorporation '%s' in the preferred publisher '%s'.\nUse -P to supply a publisher which contains this package.\n")
f_key_prop=$(gettext "Unable to propagate key %s to %s")
@@ -60,17 +63,14 @@
m_smf=$(gettext " Postinstall: Copying SMF seed repository ...")
m_more_brokenness=$(gettext " Postinstall: Applying workarounds.")
m_mannote=$(gettext " Note: Man pages can be obtained by installing SUNWman")
-m_complete=$(gettext " Done: Installation completed in %s seconds.")
-m_postnote=$(gettext " Next Steps: Boot the zone, then log into the zone console")
-m_postnote2=$(gettext " (zlogin -C) to complete the configuration process")
-m_usage=$(gettext "$0: [-h] [-P publisher=uri] [-e extrapkg [...]]")
+m_usage=$(gettext "\n install [-h]\n install [-c certificate_file] [-k key_file] [-P publisher=uri]\n [-e extrapkg [...]]\n install {-a archive|-d path} {-p|-u} [-s|-v]")
m_done=$(gettext " done.")
is_brand_labeled() {
brand_labeled=0
- brand=$(/usr/sbin/zoneadm -z $zonename list -p | awk -F: '{print $6}')
+ brand=$(/usr/sbin/zoneadm -z $ZONENAME list -p | awk -F: '{print $6}')
if [[ $brand == "labeled" ]]; then
brand_labeled=1
fi
@@ -85,8 +85,8 @@
trap trap_cleanup INT
extra_packages=""
-zonename=""
-zonepath=""
+ZONENAME=""
+ZONEPATH=""
pub_and_url=""
# Setup i18n output
@@ -103,33 +103,83 @@
certfile="None"
keyfile="None"
-while getopts "a:P:z:R:h:e:c:k:" opt; do
+unset install_archive
+unset source_dir
+unset msg
+unset silent_mode
+unset verbose_mode
+
+while getopts "a:c:d:e:hk:P:pR:suvz:" opt; do
case $opt in
- h) fail_usage "$m_usage";;
- R) zonepath="$OPTARG" ;;
- z) zonename="$OPTARG" ;;
- a) pub_and_url="$OPTARG";
- print -u2 \
- "WARNING: -a is deprecated. Use -P instead." ;;
+ a) # We're expecting a path to an archive
+ if [[ ! -f $OPTARG ]]; then
+ # If old style 'pub=uri' parameter then error.
+ echo $OPTARG | egrep -s =
+ if (( $? == 0 )); then
+ fail_usage "$f_a_obs"
+ fi
+ fi
+ install_archive="-a $OPTARG";;
+ c) certfile="$OPTARG" ;;
+ d) source_dir="-d $OPTARG";;
+ e) extra_packages="$extra_packages $OPTARG" ;;
+ h) fail_usage "";;
+ k) keyfile="$OPTARG" ;;
P) pub_and_url="$OPTARG" ;;
- c) certfile="$OPTARG" ;;
- k) keyfile="$OPTARG" ;;
- e) extra_packages="$extra_packages $OPTARG" ;;
- *) fail_usage "$m_usage";;
+ p) preserve_zone="-p";;
+ R) ZONEPATH="$OPTARG" ;;
+ s) silent_mode=1;;
+ u) unconfig_zone="-u";;
+ v) verbose_mode="-v";;
+ z) ZONENAME="$OPTARG" ;;
+ *) fail_usage "";;
esac
done
shift $((OPTIND-1))
-if [[ -z $zonepath || -z $zonename ]]; then
+if [[ -z $ZONEPATH || -z $ZONENAME ]]; then
print -u2 "Brand error: No zone path or name"
exit $ZONE_SUBPROC_USAGE
fi
+# XXX shared/common script currently uses lower case zonename & zonepath
+zonename="$ZONENAME"
+zonepath="$ZONEPATH"
+
is_brand_labeled
-zoneroot=$zonepath/root
+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"
+
+# The install can't be both verbose AND silent...
+[[ -n $silent_mode && -n $verbose_mode ]] && \
+ fail_usage "$f_incompat_options" "-s" "-v"
+
+# The install can't both preserve and unconfigure
+[[ -n $unconfig_zone && -n $preserve_zone ]] && \
+ fail_usage "$f_incompat_options" "-u" "-p"
+
+# IPS options aren't allowed when installing from a system image.
+if [[ -n "$install_archive" || -n "$source_dir" ]]; then
+ [[ -n $pub_and_url ]] && fail_usage "$f_incompat_options" "-a|-d" "-P"
+ [[ -n "$extra_packages" ]] && \
+ fail_usage "$f_incompat_options" "-a|-d" "-e"
+ [[ "$certfile" != "None" ]] && \
+ fail_usage "$f_incompat_options" "-a|-d" "-c"
+ [[ "$keyfile" != "None" ]] && \
+ fail_usage "$f_incompat_options" "-a|-d" "-k"
+fi
+
+# p2v options aren't allowed when installing from a repo.
+if [[ -z $install_archive && -z $source_dir ]]; then
+ [[ -n $preserve_zone || -n $unconfig_zone ]] && \
+ fail_usage "$f_incompat_options" "default" "-p|-u"
+fi
+
#
# If the user didn't give us a publisher, and there's a preferred publisher set
# for the system, set that as the default.
@@ -138,10 +188,10 @@
propagate_extra=
if [[ -z $pub_and_url ]]; then
if [[ $keyfile != "None" ]]; then
- fail_usage "Key file not allowed without -P"
+ fail_usage "$f_key_file"
fi
if [[ $certfile != "None" ]]; then
- fail_usage "Cert file not allowed without -P"
+ fail_usage "$f_cert_file"
fi
# We look for a preferred online origin.
@@ -226,66 +276,29 @@
# Before installing the zone, set up ZFS dataset hierarchy for the zone root
# dataset.
#
-
-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
+create_active_ds
#
-# From here on, errors should cause the zone to be incomplete.
-#
-int_code=$ZONE_SUBPROC_FATAL
-
-#
-# We need to tolerate errors while creating the datasets and making the
-# mountpoint, since these could already exist from some other BE.
+# If we're installing from an image, branch off to that installer.
#
+if [[ -n $install_archive || -n $source_dir ]]; then
+ /usr/lib/brand/ipkg/image_install $ZONENAME $ZONEPATH \
+ $install_archive $source_dir $verbose_mode $silent_mode \
+ $unconfig_zone $preserve_zone
+ ii_result=$?
-/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"
+ if (( $ii_result != 0 )); then
+ exit $ZONE_SUBPROC_NOTCOMPLETE
fi
+ exit $ZONE_SUBPROC_OK
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
-
-if [ $BENUM -ge 100 ]; then
- fail_fatal "$f_zfs_create"
-fi
-
-if [ ! -d $zoneroot ]; then
- /usr/bin/mkdir $zoneroot
-fi
-
-/usr/sbin/mount -F zfs $ZONEPATH_DS/ROOT/$BENAME $zoneroot || \
- fail_incomplete "$f_zfs_mount"
-
-#
-# Done setting up the zone's datasets.
-#
printf "$m_publisher\n" $publisher $publisherurl
echo "$publishers_extra" | while IFS== read publisher publisherurl; do
[ -z "$publisher" ] && break
printf "$m_publisher\n" $publisher $publisherurl
done
-printf "$m_image\n" $zoneroot
+printf "$m_image\n" $ZONEROOT
#
# We copy the credentials from the global zone into the new image
@@ -295,19 +308,19 @@
newkeylocation="$KEYDIR/$(basename $keyfile)"
secinfo="$secinfo -k $newkeylocation"
printf "$m_key_prop\n" $(basename $keyfile)
- mkdir -p -m 755 $zoneroot/$KEYDIR || fail_fatal "$f_key_prop"
- cp $keyfile $zoneroot/$newkeylocation || fail_fatal "$f_key_prop"
- chmod 644 $zoneroot/$newkeylocation
- chown -h root:root $zoneroot/$newkeylocation
+ mkdir -p -m 755 $ZONEROOT/$KEYDIR || fail_fatal "$f_key_prop"
+ cp $keyfile $ZONEROOT/$newkeylocation || fail_fatal "$f_key_prop"
+ chmod 644 $ZONEROOT/$newkeylocation
+ chown -h root:root $ZONEROOT/$newkeylocation
fi
if [[ $certfile != "None" ]]; then
newcertlocation="$KEYDIR/$(basename $certfile)"
secinfo="$secinfo -c $newcertlocation"
printf "$m_cert_prop\n" $(basename $certfile)
- mkdir -p -m 755 $zoneroot/$KEYDIR || fail_fatal "$f_cert_prop"
- cp $certfile $zoneroot/$newcertlocation || fail_fatal "$f_cert_prop"
- chmod 644 $zoneroot/$newkeylocation
- chown -h root:root $zoneroot/$newkeylocation
+ mkdir -p -m 755 $ZONEROOT/$KEYDIR || fail_fatal "$f_cert_prop"
+ cp $certfile $ZONEROOT/$newcertlocation || fail_fatal "$f_cert_prop"
+ chmod 644 $ZONEROOT/$newkeylocation
+ chown -h root:root $ZONEROOT/$newkeylocation
fi
#
@@ -318,10 +331,10 @@
# XXX in the future, we can create the image --no-refresh, then
# set the publisher. But image-create --no-refresh is broken right now.
#
-$PKG image-create -f --zone --full -p "$pub_and_url" $secinfo $zoneroot || \
+$PKG image-create -f --zone --full -p "$pub_and_url" $secinfo $ZONEROOT || \
fail_incomplete "$f_img"
-PKG_IMAGE="$zoneroot"
+PKG_IMAGE="$ZONEROOT"
export PKG_IMAGE
# add extra publishers
@@ -433,35 +446,35 @@
printf "\n$m_mannote\n"
printf "$m_smf"
-ln -s ns_files.xml $zoneroot/var/svc/profile/name_service.xml
-ln -s generic_limited_net.xml $zoneroot/var/svc/profile/generic.xml
-ln -s inetd_generic.xml $zoneroot/var/svc/profile/inetd_services.xml
-ln -s platform_none.xml $zoneroot/var/svc/profile/platform.xml
+ln -s ns_files.xml $ZONEROOT/var/svc/profile/name_service.xml
+ln -s generic_limited_net.xml $ZONEROOT/var/svc/profile/generic.xml
+ln -s inetd_generic.xml $ZONEROOT/var/svc/profile/inetd_services.xml
+ln -s platform_none.xml $ZONEROOT/var/svc/profile/platform.xml
# This was formerly done in i.manifest
-repfile=$zoneroot/etc/svc/repository.db
-cp $zoneroot/lib/svc/seed/nonglobal.db $repfile
+repfile=$ZONEROOT/etc/svc/repository.db
+cp $ZONEROOT/lib/svc/seed/nonglobal.db $repfile
chmod 0600 $repfile
chown root:sys $repfile
printf "$m_done\n"
# Clean up root as a role and jack if needed
-if grep "^root::::type=role;" $zoneroot/etc/user_attr >/dev/null 2>&1; then
+if grep "^root::::type=role;" $ZONEROOT/etc/user_attr >/dev/null 2>&1; then
printf "$m_brokenness\n"
#
# Remove "jack" user.
#
- print "/^jack:/d\nw" | ed -s $zoneroot/etc/passwd
- chmod u+w $zoneroot/etc/shadow
- print "/^jack:/d\nw" | ed -s $zoneroot/etc/shadow
- chmod u-w $zoneroot/etc/shadow
+ print "/^jack:/d\nw" | ed -s $ZONEROOT/etc/passwd
+ chmod u+w $ZONEROOT/etc/shadow
+ print "/^jack:/d\nw" | ed -s $ZONEROOT/etc/shadow
+ chmod u-w $ZONEROOT/etc/shadow
#
# Set root from a role back to... not a role. Grr.
#
print "s/^root::::type=role;/root::::/\nw" |
- ed -s $zoneroot/etc/user_attr
+ ed -s $ZONEROOT/etc/user_attr
fi
#
@@ -470,11 +483,11 @@
# See http://defect.opensolaris.org/bz/show_bug.cgi?id=741
#
printf "$m_more_brokenness\n"
-/usr/sbin/sysidconfig -b $zoneroot -a /lib/svc/method/sshd
-touch $zoneroot/etc/.UNCONFIGURED
+/usr/sbin/sysidconfig -b $ZONEROOT -a /lib/svc/method/sshd
+touch $ZONEROOT/etc/.UNCONFIGURED
# Umount the dataset on the root.
-/usr/sbin/umount $zoneroot
+/usr/sbin/umount $ZONEROOT
printf "$m_complete\n\n" ${SECONDS}
if [ $brand_labeled -eq 0 ]; then
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/pkgrm.conf Tue Nov 10 14:40:37 2009 -0700
@@ -0,0 +1,29 @@
+#
+# 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 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# This is a list of IPS packages which should be removed when installing
+# a zone from an image of a physical system (that is, only when installing
+# with the zoneadm -d or -a option). Site-specific packages which must be
+# removed should be listed in this file. During the zone installation, the
+# packages will be removed if they existed on the original physical system.
+#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/pkgrm.lst Tue Nov 10 14:40:37 2009 -0700
@@ -0,0 +1,30 @@
+#
+# 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 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# This is a list of IPS packages which should be removed when installing
+# a zone from an image of a physical system (that is, only when installing
+# with the zoneadm -d or -a option). Do not edit this file. Site-specific
+# packages which must be removed should be listed in the
+# /etc/brand/native/pkgrm.conf file. During the zone installation, the
+# packages will be removed if they existed on the original physical system.
+#
--- a/src/brand/query Tue Nov 10 15:49:19 2009 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +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 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-. /usr/lib/brand/ipkg/common.ksh
-
-zonename=$1
-zonepath=$2
-cmd=$3
-
-if [ $3 == "datasets" ]; then
- get_zonepath_ds $zonepath
-
- DS=`/usr/sbin/zfs list -H -t filesystem -o name $ZONEPATH_DS/ROOT`
- if [ ! -z "$DS" ]; then
- echo "$DS\c"
- else
- fail_fatal "$f_no_ds"
- fi
-fi
-
-exit $ZONE_SUBPROC_OK
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/smf_disable.conf Tue Nov 10 14:40:37 2009 -0700
@@ -0,0 +1,29 @@
+#
+# 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 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# This is a list of SMF services which should be disabled when installing
+# a zone from an image of a physical system (that is, only when installing
+# with the zoneadm -d or -a option). Site-specific services which must be
+# disabled should be listed in this file. During the zone installation, the
+# services will be disabled if they existed on the original physical system.
+#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/smf_disable.lst Tue Nov 10 14:40:37 2009 -0700
@@ -0,0 +1,30 @@
+#
+# 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 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# This is a list of SMF services which should be disabled when installing
+# a zone from an image of a physical system (that is, only when installing
+# with the zoneadm -d or -a option). Do not edit this file. Site-specific
+# services which must be disabled should be listed in the
+# /etc/brand/native/smf_disable.conf file. During the zone installation, the
+# services will be disabled if they existed on the original physical system.
+#
--- a/src/brand/uninstall Tue Nov 10 15:49:19 2009 +0000
+++ b/src/brand/uninstall Tue Nov 10 14:40:37 2009 -0700
@@ -33,219 +33,7 @@
# common shell script functions
#
. /usr/lib/brand/ipkg/common.ksh
-
-#
-# error messages
-#
-m_usage=$(gettext "Usage: %s: [-hFn]")
-
-m_1_zfs_promote=$(gettext "promoting '%s'.")
-m_1_zfs_destroy=$(gettext "destroying '%s'.")
-m_2_zfs_rename=$(gettext "renaming '%s' to '%s'.")
-m_3_zfs_set=$(gettext "setting property %s='%s' for '%s'.")
-m_rm_r=$(gettext "recursively deleting '%s'.")
-m_rm=$(gettext "deleting '%s'.")
-
-w_no_ds=$(gettext "Warning: no zonepath dataset found.")
-
-f_usage_err=$(gettext "Error: invalid usage")
-f_abort=$(gettext "Error: internal error detected, aborting.")
-f_1_zfs_promote=$(gettext "Error: promoting ZFS dataset '%s'.")
-f_2_zfs_rename=$(gettext "Error: renaming ZFS dataset '%s' to '%s'.")
-f_3_zfs_set=$(gettext "Error: setting ZFS propery %s='%s' for '%s'.")
-f_1_zfs_destroy=$(gettext "Error: destroying ZFS dataset.")
-f_2_zfs_get=$(gettext "Error: reading ZFS dataset property '%s' from '%s'.")
-f_user_snap=$(gettext "Error: user snapshot(s) detected.")
-f_stray_snap=$(gettext "Error: uncloned snapshot(s) detected.")
-f_stray_clone=$(gettext "Error: cloned zone datasets found outsize of zone.")
-f_rm_snap=$(gettext "Error: please delete snapshot(s) and retry uninstall.")
-f_rm_clone=$(gettext "Error: please delete clone(s) and retry uninstall.")
-f_iu_clone=$(gettext "Error: cloned zone dataset(s) in use.")
-f_dis_clone=$(gettext "Error: please stop using clone(s) and retry uninstall.")
-
-#
-# functions
-#
-print_array()
-{
- typeset -n pa_array=$1
-
- (( pa_i = 0 ))
- while (( $pa_i < ${#pa_array[@]} )); do
- printf "\t${pa_array[$pa_i]}\n"
- (( pa_i = $pa_i + 1 ))
- done
-}
-
-usage()
-{
- printf "$m_usage\n" "$bname"
- exit $ZONE_SUBPROC_USAGE
-}
-
-usage_err()
-{
- printf "$f_usage_err\n" >&2
- usage >&2
-}
-
-rm_zonepath()
-{
- # cleanup stuff we know about and leave any user data alone
-
- [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
- printf "$m_rm\n" "$zonepath/SUNWattached.xml"
- $nop /bin/rm -f "$zonepath/SUNWattached.xml"
-
- [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
- printf "$m_rm_r\n" "$zonepath/lu"
- $nop /bin/rm -rf "$zonepath/lu"
-
- [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
- printf "$m_rm_r\n" "$zonepath/dev"
- $nop /bin/rm -rf "$zonepath/dev"
-
- [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
- printf "$m_rm_r\n" "$zonepath/root"
- $nop /bin/rm -rf "$zonepath/root"
-
- [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
- printf "$m_rm\n" "$zonepath"
- $nop /bin/rmdir "$zonepath" 2>/dev/null
-}
-
-zfs_destroy()
-{
- zd_fs1="$1"
-
- # first figure out if the target fs has an origin snapshot
- zd_origin=`/sbin/zfs get -H -o value origin "$zd_fs1"`
- if [[ $? != 0 ]]; then
- printf "$f_2_zfs_get\n" origin "$zd_fs1" >&2
- exit $ZONE_SUBPROC_FATAL
- fi
-
- [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
- printf "$m_1_zfs_destroy\n" "$zd_fs1"
-
- #
- # note that we specify the '-r' flag so that we destroy any
- # descendants (filesystems and snapshot) of the specified
- # filesystem.
- #
- $nop /sbin/zfs destroy -r "$zd_fs1"
- if [[ $? != 0 ]]; then
- printf "$f_1_zfs_destroy\n" "$zd_fs1" >&2
- exit $ZONE_SUBPROC_FATAL
- fi
-
- [[ "$zd_origin" == "-" ]] && return
-
- [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
- printf "$m_1_zfs_destroy\n" "$zd_origin"
-
- $nop /sbin/zfs destroy "$zd_origin" 2>/dev/null
- #
- # we ignore errors while trying to destroy the origin since
- # the origin could have been used as the source for other
- # clones
- #
-}
-
-zfs_promote()
-{
- zp_fs1="$1"
-
- [[ -z "$opt_n" ]] &&
- printf "$m_1_zfs_promote\n" "$zp_fs1"
-
- $nop /sbin/zfs promote "$zp_fs1"
- if [[ $? != 0 ]]; then
- printf "$f_1_zfs_promote\n" "$zp_fs1" >&2
- exit $ZONE_SUBPROC_FATAL
- fi
-}
-
-zfs_rename()
-{
- zr_fs1="$1"
- zr_fs2="$2"
-
- [[ -z "$opt_n" ]] &&
- printf "$m_2_zfs_rename\n" "$zr_fs1" "$zr_fs2"
-
- $nop /sbin/zfs rename "$zr_fs1" "$zr_fs2"
- if [[ $? != 0 ]]; then
- printf "$f_2_zfs_rename\n" "$zr_fs1" "$zr_fs2" >&2
- return 1
- fi
- return 0
-}
-
-zfs_set()
-{
- zs_prop=$1
- zs_value=$2
- zs_fs1=$3
-
- [[ -z "$opt_n" ]] && [[ -n "$opt_v" ]] &&
- printf "$m_3_zfs_set\n" "$zs_prop" "$zs_value" "$zs_fs1"
-
- $nop /sbin/zfs set "$zs_prop"="$zs_value" "$zs_fs1"
- if [[ $? != 0 ]]; then
- printf "$f_3_zfs_set\n" "$zs_prop" "$zs_value" "$zs_fs1"
- return 1
- fi
- return 0
-}
-
-zfs_set_array()
-{
- zsa_prop=$1
- zsa_value=$2
- typeset -n zsa_array=$3
- zsa_ignore_errors=$4
-
- (( zsa_i = 0 ))
- while (( $zsa_i < ${#zsa_array[@]} )); do
- zfs_set "$zsa_prop" "$zsa_value" "${zsa_array[$zsa_i]}"
- [[ $? != 0 ]] && [[ -z "$zsa_ignore_errors" ]] &&
- return 1
- (( zsa_i = $zsa_i + 1 ))
- done
- return 0
-}
-
-
-(( snap_rename_zbe_i = 1 ))
-(( snap_rename_snap_i = 1 ))
-snap_rename_init()
-{
- (( snap_rename_zbe_i = 1 ))
- (( snap_rename_snap_i = 1 ))
-}
-
-snap_rename()
-{
- eval sr_fs=\${$1}
- eval sr_snap=\${$2}
-
- if [[ "$sr_snap" == ~(Elr)(zbe-[0-9][0-9]*) ]]; then
- sr_snap="zbe-$snap_rename_zbe_i"
- (( snap_rename_zbe_i = $snap_rename_zbe_i + 1 ))
- elif [[ "$sr_snap" == ~(Er)(_snap[0-9]*) ]]; then
- sr_snap=${sr_snap##~(Er)([0-9]*)}
- sr_snap="${sr_snap}${snap_rename_snap_i}"
- (( snap_rename_snap_i = $snap_rename_snap_i + 1 ))
- else
- printf "$f_user_snap\n" >&2
- printf "\t$sr_fs@$sr_snap\n" >&2
- printf "$f_rm_snap\n" >&2
- exit $ZONE_SUBPROC_FATAL
- fi
-
- eval $2="$sr_snap"
-}
+. /usr/lib/brand/shared/uninstall.ksh
#
# options processing
@@ -344,33 +132,8 @@
print "$f_no_gzbe"
fi
-# find the dataset associated with $zonepath
-ZONEPATH_DS=`/sbin/zfs list -t filesystem -o name,mountpoint | \
- /bin/nawk -v zonepath=$zonepath '{
- if ($2 == zonepath)
- print $1
-}'`
-
-if [ -z "$ZONEPATH_DS" ]; then
- # there is no $zonepath dataset
- rm_zonepath
- exit $ZONE_SUBPROC_OK
-fi
-
-# find the dataset associated with $ZONEPATH_DS/ROOT
-ZONEPATH_RDS=`/sbin/zfs list -H -t filesystem -o name \
- $ZONEPATH_DS/ROOT 2>/dev/null`
-
-if [ -z "$ZONEPATH_RDS" ]; then
- # there is no $ZONEPATH_DS/ROOT dataset
- c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_DS | wc -l`
- if [ $c = 1 ]; then
- # $zonepath dataset has no descendents
- zfs_destroy "$ZONEPATH_DS"
- fi
- rm_zonepath
- exit $ZONE_SUBPROC_OK
-fi
+uninstall_get_zonepath_ds
+uninstall_get_zonepath_root_ds
# find all the zone BEs datasets associated with this global zone BE.
unset fs_all
@@ -393,428 +156,6 @@
done
fi
-# Destroy the zone BEs datasets one by one.
-(( i = 0 ))
-while (( $i < $fs_all_c )); do
- fs=${fs_all[$i]}
- pool=${fs%%/*}
-
- # Fastpath. if there are no snapshots of $fs then just delete it.
- c=`/sbin/zfs list -H -t snapshot -o name -r $fs | grep "^$fs@" |
- LC_ALL=C LANG=C wc -l`
- if (( $c == 0 )) ; then
- zfs_destroy "$fs"
- (( i = $i + 1 ))
- continue
- fi
-
- #
- # This zone BE has snapshots. This can happen if a zone has
- # multiple BEs (in which case we have snapshots named "zbe-XXX"),
- # if this zone has been used as the source for a clone of
- # another zone (in which case we have snapshots named
- # "XXX_snap"), or if an administrator has been doing manual
- # snapshotting.
- #
- # To be able to destroy this dataset (which we'll call the
- # origin) we need to get rid of all it's snapshots. The "easiest"
- # way to do this is to:
- #
- # - delete any uncloned origin snapshots
- # - find the oldest clone of the youngest origin snapshot (which
- # we'll call the oldest clone)
- # - check if there are any snapshots naming conflicts between
- # the origin and the oldest clone.
- # - if so, find any clones of those conflicting origin snapshots
- # - make sure that those clones are not zoned an in-use.
- # - if any of those clones are zoned, unzone them.
- # - rename origin snapshots to eliminate naming conflicts
- # - for any clones that we unzoned, rezone them.
- # - promote the oldest clone
- # - destroy the origin and all it's descendants
- #
-
- #
- # Get a list of all the cloned datasets within the zpool
- # containing the origin filesystem. Filter out any filesystems
- # that are descendants of origin because we are planning to
- # destroy them anyway.
- #
- unset clones clones_origin
- (( clones_c = 0 ))
- pool=${fs%%/*}
- LANG=C LC_ALL=C /sbin/zfs list -H -t filesystem -s creation \
- -o name,origin -r "$pool" |
- while IFS=" " read name origin; do
-
- # skip non-clone filesystems
- [[ "$origin" == "-" ]] &&
- continue
-
- # skip desendents of the origin we plan to destroy
- [[ "$name" == ~()(${fs}/*) ]] &&
- continue
-
- # record this clone and it's origin
- clones[$clones_c]="$name"
- clones_origin[$clones_c]="$origin"
- (( clones_c = $clones_c + 1 ))
- done
-
- #
- # Now do a sanity check. Search for clones of a child datasets
- # of the dataset we want to destroy, that are not themselves
- # children of the dataset we're going to destroy). This should
- # really never happen unless the global zone admin has cloned a
- # snapshot of a zone filesystem to a location outside of that
- # zone. bad admin...
- #
- unset stray_clones
- (( stray_clones_c = 0 ))
- (( j = 0 ))
- while (( $j < $clones_c )); do
- # is the clone origin a descendant of $fs?
- if [[ "${clones_origin[$j]}" != ~()(${fs}/*) ]]; then
- # we don't care.
- (( j = $j + 1 ))
- continue
- fi
- stray_clones[$stray_clones_c]=${clones[$j]}
- (( stray_clones_c = $stray_clones_c + 1 ))
- (( j = $j + 1 ))
- done
- if (( stray_clones_c > 0 )); then
- #
- # sigh. the admin has done something strange.
- # tell them to clean it up and retry.
- #
- printf "$f_stray_clone\n" >&2
- print_array stray_clones >&2
- printf "$f_rm_clone\n" >&2
- exit $ZONE_SUBPROC_FATAL
- fi
-
- # Find all the snapshots of the origin filesystem.
- unset s_origin
- (( s_origin_c = 0 ))
- /sbin/zfs list -H -t snapshot -s creation -o name -r $fs |
- grep "^$fs@" | while read name; do
- s_origin[$s_origin_c]=$name
- (( s_origin_c = $s_origin_c + 1 ))
- done
-
- #
- # Now go through the origin snapshots and find those which don't
- # have clones. We're going to explicity delete these snapshots
- # before we do the promotion.
- #
- unset s_delete
- (( s_delete_c = 0 ))
- (( j = 0 ))
- while (( $j < $s_origin_c )); do
- (( k = 0 ))
- while (( $k < $clones_c )); do
- # if we have a match then break out of this loop
- [[ "${s_origin[$j]}" == "${clones_origin[$k]}" ]] &&
- break
- (( k = $k + 1 ))
- done
- if (( $k != $clones_c )); then
- # this snapshot has a clone, move on to the next one
- (( j = $j + 1 ))
- continue
- fi
-
- # snapshot has no clones so add it to our delete list
- s_delete[$s_delete_c]=${s_origin[$j]}
- (( s_delete_c = $s_delete_c + 1 ))
- # remove it from the origin snapshot list
- (( k = $j + 1 ))
- while (( $k < $s_origin_c )); do
- s_origin[(( $k - 1 ))]=${s_origin[$k]}
- (( k = $k + 1 ))
- done
- (( s_origin_c = $s_origin_c - 1 ))
- done
-
- #
- # Fastpath. If there are no remaining snapshots then just
- # delete the origin filesystem (and all it's descendents) and
- # move onto the next zone BE.
- #
- if (( $s_origin_c == 0 )); then
- zfs_destroy "$fs"
- (( i = $i + 1 ))
- continue
- fi
-
- # find the youngest snapshot of $fs
- s_youngest=${s_origin[(( $s_origin_c - 1 ))]}
-
- # Find the oldest clone of the youngest snapshot of $fs
- unset s_clone
- (( j = $clones_c - 1 ))
- while (( $j >= 0 )); do
- if [[ "$s_youngest" == "${clones_origin[$j]}" ]]; then
- s_clone=${clones[$j]}
- break
- fi
- (( j = $j - 1 ))
- done
- if [[ -z "$s_clone" ]]; then
- # uh oh. something has gone wrong. bail.
- printf "$f_stray_snap\n" >&2
- printf "\t$s_youngest\n" >&2
- printf "$f_rm_snap\n" >&2
- exit $ZONE_SUBPROC_FATAL
- fi
-
- # create an array of clone snapshot names
- unset s_clone_s
- (( s_clone_s_c = 0 ))
- /sbin/zfs list -H -t snapshot -s creation -o name -r $s_clone |
- grep "^$s_clone@" | while read name; do
- s_clone_s[$s_clone_s_c]=${name##*@}
- (( s_clone_s_c = $s_clone_s_c + 1 ))
- done
-
- # create an arrays of possible origin snapshot renames
- unset s_origin_snap
- unset s_rename
- (( j = 0 ))
- while (( $j < $s_origin_c )); do
- s_origin_snap[$j]=${s_origin[$j]##*@}
- s_rename[$j]=${s_origin[$j]##*@}
- (( j = $j + 1 ))
- done
-
- #
- # Search for snapshot name collisions between the origin and
- # oldest clone. If we find one, generate a new name for the
- # origin snapshot and re-do the collision check.
- #
- snap_rename_init
- (( j = 0 ))
- while (( $j < $s_origin_c )); do
- (( k = 0 ))
- while (( $k < $s_clone_s_c )); do
-
- # if there's no naming conflict continue
- if [[ "${s_rename[$j]}" != "${s_clone_s[$k]}" ]]; then
- (( k = $k + 1 ))
- continue
- fi
+destroy_zone_datasets
- #
- # The origin snapshot conflicts with a clone
- # snapshot. Choose a new name and then restart
- # then check that against clone snapshot names.
- #
- snap_rename fs "s_rename[$j]"
- (( k = 0 ))
- continue;
- done
-
- # if we didn't rename this snapshot then continue
- if [[ "${s_rename[$j]}" == "${s_origin_snap[$j]}" ]]; then
- (( j = $j + 1 ))
- continue
- fi
-
- #
- # We need to rename this origin snapshot because it
- # conflicts with a clone snapshot name. So above we
- # chose a name that didn't conflict with any other clone
- # snapshot names. But we also have to avoid naming
- # conflicts with any other origin snapshot names. So
- # check for that now.
- #
- (( k = 0 ))
- while (( $k < $s_origin_c )); do
-
- # don't compare against ourself
- if (( $j == $k )); then
- (( k = $k + 1 ))
- continue
- fi
-
- # if there's no naming conflict continue
- if [[ "${s_rename[$j]}" != "${s_rename[$k]}" ]]; then
- (( k = $k + 1 ))
- continue
- fi
-
- #
- # The new origin snapshot name conflicts with
- # another origin snapshot name. Choose a new
- # name and then go back to check the new name
- # for uniqueness against all the clone snapshot
- # names.
- #
- snap_rename fs "s_rename[$j]"
- continue 2;
- done
-
- #
- # A new unique name has been chosen. Move on to the
- # next origin snapshot.
- #
- (( j = $j + 1 ))
- snap_rename_init
- done
-
- #
- # So now we know what snapshots need to be renamed before the
- # promotion. But there's an additional problem. If any of the
- # filesystems cloned from these snapshots have the "zoned"
- # attribute set (which is highly likely) or if they are in use
- # (and can't be unmounted and re-mounted) then the snapshot
- # rename will fail. So now we'll search for all the clones of
- # snapshots we plan to rename and look for ones that are zoned.
- #
- # We'll ignore any snapshot clones that may be in use but are
- # not zoned. If these clones are in-use, the rename will fail
- # and we'll abort, there's not much else we can do about it.
- # But if they are not in use the snapshot rename will unmount
- # and remount the clone. This is ok because when the zoned
- # attribute is off, we know that the clone was originally
- # mounted from the global zone. (So unmounting and remounting
- # it from the global zone is ok.)
- #
- # But we'll abort this whole operation if we find any clones
- # that that are zoned and in use. (This can happen if another
- # zone has been cloned from this one and is now booted.) The
- # reason we do this is because those zoned filesystems could
- # have originally mounted from within the zone. So if we
- # cleared the zone attribute and did the rename, we'd be
- # remounting the filesystem from the global zone. This would
- # result in the zone losing the ability to unmount the
- # filesystem, which would be bad.
- #
- unset zoned_clones zoned_iu_clones
- (( zoned_clones_c = 0 ))
- (( zoned_iu_clones_c = 0 ))
- (( j = 0 ))
- # walk through all the clones
- while (( $j < $clones_c )); do
- # walk through all the origin snapshots
- (( k = 0 ))
- while (( $k < $s_origin_c )); do
- #
- # check if this clone originated from a snapshot that
- # we need to rename.
- #
- [[ "${clones_origin[$j]}" == "${s_origin[$k]}" ]] &&
- [[ "${s_origin_snap[$k]}" != "${s_rename[$k]}" ]] &&
- break
- (( k = $k + 1 ))
- continue
- done
- if (( $k == $s_origin_c )); then
- # This isn't a clone of a snapshot we want to rename.
- (( j = $j + 1 ))
- continue;
- fi
-
- # get the zoned attr for this clone.
- zoned=`LC_ALL=C LANG=C \
- /sbin/zfs get -H -o value zoned ${clones[$j]}`
- if [[ "$zoned" != on ]]; then
- # This clone isn't zoned so ignore it.
- (( j = $j + 1 ))
- continue
- fi
-
- # remember this clone so we can muck with it's zoned attr.
- zoned_clones[$zoned_clones_c]=${clones[$j]}
- (( zoned_clones_c = $zoned_clones_c + 1 ))
-
- # check if it's in use
- mounted=`LC_ALL=C LANG=C \
- /sbin/zfs get -H -o value mounted ${clones[$j]}`
- if [[ "$mounted" != yes ]]; then
- # Good news. This clone isn't in use.
- (( j = $j + 1 ))
- continue
- fi
-
- # Sigh. This clone is in use so we're destined to fail.
- zoned_iu_clones[$zoned_iu_clones_c]=${clones[$j]}
- (( zoned_iu_clones_c = $zoned_iu_clones_c + 1 ))
-
- # keep looking for errors so we can report them all at once.
- (( j = $j + 1 ))
- done
- if (( zoned_iu_clones_c > 0 )); then
- #
- # Tell the admin
- #
- printf "$f_iu_clone\n" >&2
- print_array zoned_iu_clones >&2
- printf "$f_dis_clone\n" >&2
- exit $ZONE_SUBPROC_FATAL
- fi
-
- #
- # Ok. So we're finally done with planning and we can do some
- # damage. We're going to:
- # - destroy unused snapshots
- # - unzone clones which originate from snapshots we need to rename
- # - rename conflicting snapshots
- # - rezone any clones which we unzoned
- # - promote the oldest clone of the youngest snapshot
- # - finally destroy the origin filesystem.
- #
-
- # delete any unsed snapshot
- (( j = 0 ))
- while (( $j < $s_delete_c )); do
- zfs_destroy "${s_delete[$j]}"
- (( j = $j + 1 ))
- done
-
- # unzone clones
- zfs_set_array zoned off zoned_clones ||
- zfs_set_array zoned on zoned_clones 1
-
- # rename conflicting snapshots
- (( j = 0 ))
- while (( $j < $s_origin_c )); do
- if [[ "${s_origin_snap[$j]}" != "${s_rename[$j]}" ]]; then
- zfs_rename "${s_origin[$j]}" "$fs@${s_rename[$j]}"
- if [[ $? != 0 ]]; then
- # re-zone the clones before aborting
- zfs_set_array zoned on zoned_clones 1
- exit $ZONE_SUBPROC_FATAL
- fi
- fi
- (( j = $j + 1 ))
- done
-
- # re-zone the clones
- zfs_set_array zoned on zoned_clones 1
-
- # promote the youngest clone of the oldest snapshot
- zfs_promote "$s_clone"
-
- # destroy the origin filesystem and it's descendants
- zfs_destroy "$fs"
-
- (( i = $i + 1 ))
-done
-
-#
-# Check if there are any other datasets left. There may be datasets
-# associated with other GZ BEs, so we need to leave things alone in that case.
-#
-c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_RDS | wc -l`
-if [ $c = 1 ]; then
- zfs_destroy "$ZONEPATH_RDS"
-fi
-c=`/sbin/zfs list -H -t filesystem -r $ZONEPATH_DS | wc -l`
-if [ $c = 1 ]; then
- zfs_destroy "$ZONEPATH_DS"
-fi
-
-rm_zonepath
exit $ZONE_SUBPROC_OK
--- a/src/pkgdefs/Makefile Tue Nov 10 15:49:19 2009 +0000
+++ b/src/pkgdefs/Makefile Tue Nov 10 14:40:37 2009 -0700
@@ -63,7 +63,13 @@
PROTOS = $(SUBDIRS:%=%/prototype)
+#
+# The pkgproto command in the protoproto target does not generate editable
+# (e) file entries so we need to change any editable entries into simple
+# file entries for the subsequent comparison to suceed.
+#
pkgproto: $(PROTOS)
- nawk '$$1 ~ /[sdf]/ {print $$1, $$3}' $(PROTOS) | sort +1 -u > $@
+ nawk '$$1 ~ /[sdef]/ {print $$1, $$3}' $(PROTOS) | sed 's/^e/f/' | \
+ sort +1 -u > $@
FRC:
--- a/src/pkgdefs/SUNWipkg-brand/prototype Tue Nov 10 15:49:19 2009 +0000
+++ b/src/pkgdefs/SUNWipkg-brand/prototype Tue Nov 10 14:40:37 2009 -0700
@@ -1,6 +1,10 @@
i pkginfo
i copyright
d none etc 755 root sys
+d none etc/brand 755 root sys
+d none etc/brand/ipkg 755 root sys
+e none etc/brand/ipkg/pkgrm.conf 644 root bin
+e none etc/brand/ipkg/smf_disable.conf 644 root bin
d none etc/zones 755 root sys
f none etc/zones/SUNWipkg.xml 444 root bin
d none usr 755 root sys
@@ -13,10 +17,13 @@
f none usr/lib/brand/ipkg/config.xml 444 root bin
f none usr/lib/brand/ipkg/detach 755 root bin
f none usr/lib/brand/ipkg/fmri_compare 755 root bin
+f none usr/lib/brand/ipkg/image_install 755 root bin
+f none usr/lib/brand/ipkg/p2v 755 root bin
f none usr/lib/brand/ipkg/pkgcreatezone 755 root bin
+f none usr/lib/brand/ipkg/pkgrm.lst 444 root bin
f none usr/lib/brand/ipkg/platform.xml 444 root bin
f none usr/lib/brand/ipkg/poststate 755 root bin
f none usr/lib/brand/ipkg/prestate 755 root bin
-f none usr/lib/brand/ipkg/query 755 root bin
+f none usr/lib/brand/ipkg/smf_disable.lst 444 root bin
f none usr/lib/brand/ipkg/support 755 root bin
f none usr/lib/brand/ipkg/uninstall 755 root bin
--- a/src/setup.py Tue Nov 10 15:49:19 2009 +0000
+++ b/src/setup.py Tue Nov 10 14:40:37 2009 -0700
@@ -164,6 +164,7 @@
resource_dir = 'usr/share/lib/pkg'
smf_dir = 'var/svc/manifest/application'
zones_dir = 'etc/zones'
+etcbrand_dir = 'etc/brand/ipkg'
brand_dir = 'usr/lib/brand/ipkg'
scripts_sunos = {
@@ -276,10 +277,13 @@
'brand/detach',
'brand/prestate',
'brand/poststate',
- 'brand/query',
'brand/uninstall',
'brand/common.ksh',
]
+etcbrand_files = [
+ 'brand/pkgrm.conf',
+ 'brand/smf_disable.conf',
+ ]
smf_files = [
'svc/pkg-server.xml',
'svc/pkg-update.xml',
@@ -821,6 +825,7 @@
data_files += [
(zones_dir, zones_files),
(brand_dir, brand_files),
+ (etcbrand_dir, etcbrand_files),
(smf_dir, smf_files),
]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util/distro-import/128/config.xml Tue Nov 10 14:40:37 2009 -0700
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+
+<!--
+ 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 2009 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ DO NOT EDIT THIS FILE.
+-->
+
+<!DOCTYPE brand PUBLIC "-//Sun Microsystems Inc//DTD Brands//EN"
+ "file:///usr/share/lib/xml/dtd/brand.dtd.1">
+
+<brand name="labeled">
+ <modname></modname>
+
+ <initname>/sbin/init</initname>
+ <login_cmd>/usr/bin/login -z %Z -f %u</login_cmd>
+ <user_cmd>/usr/bin/getent passwd %u</user_cmd>
+
+ <!-- We may not be able to do the create in pkg(1) proper. -->
+ <install>/usr/lib/brand/ipkg/pkgcreatezone -z %z -R %R</install>
+ <installopts>a:c:d:e:hk:P:p:suv</installopts>
+ <boot></boot>
+ <halt></halt>
+ <verify_cfg>/usr/lib/brand/ipkg/support verify</verify_cfg>
+ <verify_adm></verify_adm>
+ <postclone></postclone>
+ <postinstall></postinstall>
+ <attach>/usr/lib/brand/ipkg/attach %z %R</attach>
+ <detach>/usr/lib/brand/ipkg/detach -z %z -R %R</detach>
+ <clone>/usr/lib/brand/ipkg/clone -z %z -R %R</clone>
+ <uninstall>/usr/lib/brand/ipkg/uninstall %z %R</uninstall>
+ <prestatechange>/usr/lib/brand/ipkg/prestate %z %R</prestatechange>
+ <poststatechange>/usr/lib/brand/ipkg/poststate %z %R</poststatechange>
+ <query>/usr/lib/brand/shared/query %z %R</query>
+
+ <privilege set="default" name="contract_event" />
+ <privilege set="default" name="contract_identity" />
+ <privilege set="default" name="contract_observer" />
+ <privilege set="default" name="file_chown" />
+ <privilege set="default" name="file_chown_self" />
+ <privilege set="default" name="file_dac_execute" />
+ <privilege set="default" name="file_dac_read" />
+ <privilege set="default" name="file_dac_search" />
+ <privilege set="default" name="file_dac_write" />
+ <privilege set="default" name="file_owner" />
+ <privilege set="default" name="file_setid" />
+ <privilege set="default" name="ipc_dac_read" />
+ <privilege set="default" name="ipc_dac_write" />
+ <privilege set="default" name="ipc_owner" />
+ <privilege set="default" name="net_bindmlp" />
+ <privilege set="default" name="net_icmpaccess" />
+ <privilege set="default" name="net_mac_aware" />
+ <privilege set="default" name="net_privaddr" />
+ <privilege set="default" name="net_rawaccess" ip-type="exclusive" />
+ <privilege set="default" name="proc_chroot" />
+ <privilege set="default" name="sys_audit" />
+ <privilege set="default" name="proc_audit" />
+ <privilege set="default" name="proc_lock_memory" />
+ <privilege set="default" name="proc_owner" />
+ <privilege set="default" name="proc_setid" />
+ <privilege set="default" name="proc_taskid" />
+ <privilege set="default" name="sys_acct" />
+ <privilege set="default" name="sys_admin" />
+ <privilege set="default" name="sys_ip_config" ip-type="exclusive" />
+ <privilege set="default" name="sys_mount" />
+ <privilege set="default" name="sys_nfs" />
+ <privilege set="default" name="sys_resource" />
+
+ <privilege set="prohibited" name="dtrace_kernel" />
+ <privilege set="prohibited" name="proc_zone" />
+ <privilege set="prohibited" name="sys_config" />
+ <privilege set="prohibited" name="sys_devices" />
+ <privilege set="prohibited" name="sys_ip_config" ip-type="shared" />
+ <privilege set="prohibited" name="sys_linkdir" />
+ <privilege set="prohibited" name="sys_net_config" />
+ <privilege set="prohibited" name="sys_res_config" />
+ <privilege set="prohibited" name="sys_suser_compat" />
+ <privilege set="prohibited" name="xvm_control" />
+ <privilege set="prohibited" name="virt_manage" />
+
+ <privilege set="required" name="proc_exec" />
+ <privilege set="required" name="proc_fork" />
+ <privilege set="required" name="sys_ip_config" ip-type="exclusive" />
+ <privilege set="required" name="sys_mount" />
+</brand>