3454 initial ipkg brand enhancements for SNAP support
author<gerald.jelinek@sun.com>
Tue, 23 Sep 2008 07:41:08 -0600
changeset 547 9a267e76a197
parent 546 c60f410079a0
child 548 c68ba094f48d
3454 initial ipkg brand enhancements for SNAP support
src/brand/Makefile
src/brand/clone
src/brand/common.ksh
src/brand/config.xml
src/brand/pkgcreatezone
src/brand/platform.xml
src/brand/poststate
src/brand/prestate
src/brand/query
src/brand/uninstall
src/pkgdefs/SUNWipkg-brand/Makefile
--- a/src/brand/Makefile	Tue Sep 23 15:18:27 2008 -0700
+++ b/src/brand/Makefile	Tue Sep 23 07:41:08 2008 -0600
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 
-# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 
@@ -49,7 +49,13 @@
 	$(ROOTETCZONES)/SUNWipkg.xml \
 	$(ROOTBRANDPKG)/config.xml \
 	$(ROOTBRANDPKG)/platform.xml \
-	$(ROOTBRANDPKG)/pkgcreatezone
+	$(ROOTBRANDPKG)/clone \
+	$(ROOTBRANDPKG)/common.ksh \
+	$(ROOTBRANDPKG)/pkgcreatezone \
+	$(ROOTBRANDPKG)/poststate \
+	$(ROOTBRANDPKG)/prestate \
+	$(ROOTBRANDPKG)/query \
+	$(ROOTBRANDPKG)/uninstall
 
 all := TARGET = all
 link := TARGET = link
@@ -71,7 +77,13 @@
 	mkdir -p /usr/lib/brand/ipkg
 	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)/clone /usr/lib/brand/ipkg/clone
+	ln -sf $(PWD)/common.ksh /usr/lib/brand/ipkg/common.ksh
 	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)/uninstall /usr/lib/brand/ipkg/uninstall
 	ln -sf $(PWD)/SUNWipkg.xml /etc/zones/SUNWipkg.xml
 
 link-clean:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/clone	Tue Sep 23 07:41:08 2008 -0600
@@ -0,0 +1,106 @@
+#!/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
+
+f_nosource=$(gettext "Error: unable to determine source zone dataset.")
+f_sysunconfig=$(gettext "Error: sys-unconfig failed.")
+
+# Set up ZFS dataset hierarchy for the zone.
+
+ROOT="rpool/ROOT"
+
+# Other brand clone options are invalid for this brand.
+while getopts "R:z:" opt; do
+	case $opt in
+		R)	zonepath="$OPTARG" ;;
+		z)	zonename="$OPTARG" ;;
+		*)	fail_usage "$0 {sourcezone}";;
+	esac
+done
+shift $((OPTIND-1))
+
+if [ $# -ne 1 ]; then
+	fail_usage "$0 {sourcezone}";
+fi
+
+sourcezone=$1
+
+# Find the active source zone dataset to clone.
+sourcezonepath=`/usr/sbin/zonecfg -z $sourcezone info zonepath | \
+    /usr/bin/cut -f2 -d' '`
+if [ -z "$sourcezonepath" ]; then
+	fail_fatal "$f_nosource"
+fi
+
+get_current_gzbe
+get_zonepath_ds $sourcezonepath
+get_active_ds $CURRENT_GZBE $ZONEPATH_DS
+
+#
+# Now set up the zone's datasets
+#
+
+#
+# First make the top-level dataset.
+#
+
+pdir=`/usr/bin/dirname $zonepath`
+zpname=`/usr/bin/basename $zonepath`
+
+get_zonepath_ds $pdir
+zpds=$ZONEPATH_DS
+
+fail_zonepath_in_rootds $zpds
+
+/usr/sbin/zfs create $zpds/$zpname || fail_fatal "$f_zfs_create"
+
+/usr/sbin/zfs create -o mountpoint=legacy -o zoned=on $zpds/$zpname/ROOT \
+	|| fail_fatal "$f_zfs_create"
+
+# make snapshot
+/usr/sbin/zfs snapshot $ACTIVE_DS@${zonename}_snap || fail_fatal "$f_zfs_create"
+
+# do clone
+/usr/sbin/zfs clone $ACTIVE_DS@${zonename}_snap $zpds/$zpname/ROOT/zbe || \
+	fail_incomplete "$f_zfs_create"
+
+/usr/sbin/zfs set $PROP_ACTIVE=on $zpds/$zpname/ROOT/zbe || \
+	fail_incomplete "$f_zfs_create"
+
+/usr/sbin/zfs set $PROP_PARENT=$CURRENT_GZBE $zpds/$zpname/ROOT/zbe || \
+	fail_incomplete "$f_zfs_create"
+
+/usr/bin/mkdir -p $zonepath/root || fail_incomplete "$f_root_create"
+/usr/bin/chmod 700 $zonepath
+/usr/sbin/mount -F zfs $zpds/$zpname/ROOT/zbe $zonepath/root || \
+	fail_incomplete "$f_zfs_mount"
+
+/usr/sbin/sys-unconfig -R $zonepath/root || fail_incomplete "$f_sysunconfig"
+
+/usr/sbin/umount $zonepath/root || fail_fatal "$f_umount"
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/common.ksh	Tue Sep 23 07:41:08 2008 -0600
@@ -0,0 +1,128 @@
+#
+# 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.
+#
+
+ZONE_SUBPROC_OK=0
+ZONE_SUBPROC_USAGE=253
+ZONE_SUBPROC_INCOMPLETE=254
+ZONE_SUBPROC_FATAL=255
+
+PROP_PARENT="org.opensolaris.libbe:parentbe"
+PROP_ACTIVE="org.opensolaris.libbe:active"
+
+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_zfs_mount=$(gettext "Unable to mount the zone's ZFS dataset.")
+
+fail_incomplete() {
+	print "$1"
+	exit $ZONE_SUBPROC_INCOMPLETE
+}
+
+fail_fatal() {
+	print "$1"
+	exit $ZONE_SUBPROC_FATAL
+}
+
+fail_usage() {
+	print "Usage: $1"
+	exit $ZONE_SUBPROC_USAGE
+}
+
+get_current_gzbe() {
+	#
+	# If there is no beadm command then the system doesn't really
+	# support multiple boot environments.  We still want zones to work,
+	# so simulate the existence of a single boot environment.
+	#
+	if [ -x /usr/sbin/beadm ]; then
+		CURRENT_GZBE=`/usr/sbin/beadm list -H | /usr/bin/nawk -F\; '{
+			# Field 3 is the BE status.  'N' is the active BE.
+			if ($3 ~ "N")
+				# Field 2 is the BE UUID
+				print $2
+		}'`
+	else
+		CURRENT_GZBE="opensolaris"
+	fi
+
+	if [ -z "$CURRENT_GZBE" ]; then
+		fail_fatal "$f_no_gzbe"
+	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
+get_active_ds() {
+	ACTIVE_DS=`/usr/sbin/zfs list -H -r -t filesystem \
+	    -o name,$PROP_PARENT,$PROP_ACTIVE $2/ROOT | \
+	    /usr/bin/nawk -v gzbe=$1 ' {
+		if ($1 ~ /ROOT\/[^\/]+$/ && $2 == gzbe && $3 == "on") {
+			print $1
+			if (found == 1)
+				exit 1
+			found = 1
+		}
+	    }'`
+
+	if [ $? -ne 0 ]; then
+		fail_fatal "$f_multiple_ds"
+	fi
+
+	if [ -z "$ACTIVE_DS" ]; then
+		fail_fatal "$f_no_active_ds"
+	fi
+}
+
+# Check that zone is not in the ROOT dataset.
+fail_zonepath_in_rootds() {
+	case $1 in
+		rpool/ROOT/*)
+			fail_fatal "$f_zfs_in_root"
+			break;
+			;;
+		*)
+			break;
+			;;
+	esac
+}
--- a/src/brand/config.xml	Tue Sep 23 15:18:27 2008 -0700
+++ b/src/brand/config.xml	Tue Sep 23 07:41:08 2008 -0600
@@ -20,7 +20,7 @@
 
  CDDL HEADER END
 
- Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  Use is subject to license terms.
 
  DO NOT EDIT THIS FILE.
@@ -37,7 +37,7 @@
 	<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>
+	<install>/usr/lib/brand/ipkg/pkgcreatezone -z %z -R %R</install>
 	<installopts>a:h</installopts>
 	<boot></boot>
 	<halt></halt>
@@ -45,6 +45,11 @@
 	<verify_adm></verify_adm>
 	<postclone></postclone>
 	<postinstall></postinstall>
+	<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>
 
 	<privilege set="default" name="contract_event" />
 	<privilege set="default" name="contract_identity" />
--- a/src/brand/pkgcreatezone	Tue Sep 23 15:18:27 2008 -0700
+++ b/src/brand/pkgcreatezone	Tue Sep 23 07:41:08 2008 -0600
@@ -24,10 +24,7 @@
 # Use is subject to license terms.
 #
 
-ZONE_SUBPROC_OK=0
-ZONE_SUBPROC_USAGE=253
-ZONE_SUBPROC_NOTCOMPLETE=254
-ZONE_SUBPROC_FATAL=255
+. /usr/lib/brand/ipkg/common.ksh
 
 f_img=$(gettext "failed to create image")
 f_pkg=$(gettext "failed to install package")
@@ -46,23 +43,6 @@
 
 m_done=$(gettext      " done.")
 
-
-fail_incomplete() {
-	print -u2 "$1"
-	exit $ZONE_SUBPROC_NOTCOMPLETE
-}
-
-fail_fatal() {
-	print -u2 "$1"
-	exit $ZONE_SUBPROC_FATAL
-}
-
-
-fail_usage() {
-	print "Usage: $0 [-h] [-a <authority>]"
-	exit $ZONE_SUBPROC_USAGE
-}
-
 trap_cleanup() {
 	print "$f_interrupted"
 	exit $int_code
@@ -94,11 +74,11 @@
 
 while getopts "a:z:R:h" opt; do
 	case $opt in
-		h)	fail_usage ;;
+		h)	fail_usage "$0 [-h] [-a <authority>]";;
 		R)	zonepath="$OPTARG" ;;
 		z)	zonename="$OPTARG" ;;
 		a)	authority="$OPTARG" ;;
-		*)	fail_usage ;;
+		*)	fail_usage "$0 [-h] [-a <authority>]";;
 	esac
 done
 shift $((OPTIND-1))
@@ -110,9 +90,35 @@
 
 zoneroot=$zonepath/root
 
+#
+# 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
+
+/usr/sbin/zfs create -o mountpoint=legacy -o zoned=on $ZONEPATH_DS/ROOT \
+	|| fail_fatal "$f_zfs_create"
+/usr/sbin/zfs create -o $PROP_ACTIVE=on -o $PROP_PARENT=$CURRENT_GZBE \
+	$ZONEPATH_DS/ROOT/zbe || fail_incomplete "$f_zfs_create"
+
+/usr/bin/mkdir $zoneroot || fail_incomplete "$f_root_create"
+/usr/sbin/mount -F zfs $ZONEPATH_DS/ROOT/zbe $zoneroot || \
+	fail_incomplete "$f_zfs_mount"
+
+#
+# Done setting up the zone's datasets.
+#
+
 printf "$m_authority" `echo $authority | cut -d= -f 2`
 printf "\n$m_image" $zoneroot
-pkg image-create -z -F -a "$authority" $zoneroot || fail_fatal $f_img
+pkg image-create -z -F -a "$authority" $zoneroot || fail_incomplete "$f_img"
 printf "$m_done\n"
 
 entire_fmri=$(pkg list -Hv entire | nawk '{print $1}')
@@ -208,6 +214,8 @@
 /usr/sbin/sysidconfig -b $zoneroot -a /lib/svc/method/sshd
 touch $zoneroot/etc/.UNCONFIGURED
 
+# Umount the dataset on the root.
+/usr/sbin/umount $zoneroot
 
 printf "$m_complete\n\n" ${SECONDS}
 printf "$m_postnote\n"
--- a/src/brand/platform.xml	Tue Sep 23 15:18:27 2008 -0700
+++ b/src/brand/platform.xml	Tue Sep 23 07:41:08 2008 -0600
@@ -20,7 +20,7 @@
 
  CDDL HEADER END
 
- Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  Use is subject to license terms.
 
  DO NOT EDIT THIS FILE.
@@ -33,7 +33,7 @@
 
 	<!-- Global filesystems to mount when booting the zone -->
 	<global_mount special="/dev" directory="/dev" type="dev"
-	    opt="attrdir=%R/dev"/>
+	    opt="attrdir=%R/root/dev"/>
 
 	<!-- Local filesystems to mount when booting the zone -->
 	<mount special="/proc" directory="/proc" type="proc" />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/poststate	Tue Sep 23 07:41:08 2008 -0600
@@ -0,0 +1,58 @@
+#!/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
+
+f_umount=$(gettext "Error: error unmounting zone root dataset.")
+
+# States
+# ZONE_STATE_CONFIGURED           0 (never see)
+# ZONE_STATE_INCOMPLETE           1 (never see)
+# ZONE_STATE_INSTALLED            2
+# ZONE_STATE_READY                3
+# ZONE_STATE_RUNNING              4
+# ZONE_STATE_SHUTTING_DOWN        5
+# ZONE_STATE_DOWN                 6
+# ZONE_STATE_MOUNTED              7
+
+# cmd
+#
+# ready			0
+# boot			1
+# halt			4
+
+zonename=$1
+zonepath=$2
+state=$3
+cmd=$4
+
+# If we're not halting the zone, then just return.
+if [ $cmd -eq 4 ]; then
+	# Umount dataset on the root.
+	/usr/sbin/umount $zonepath/root || fail_fatal "$f_umount"
+fi
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/prestate	Tue Sep 23 07:41:08 2008 -0600
@@ -0,0 +1,63 @@
+#!/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
+
+f_mount=$(gettext "Error: error mounting zone root dataset.")
+
+# States
+# ZONE_STATE_CONFIGURED           0 (never see)
+# ZONE_STATE_INCOMPLETE           1 (never see)
+# ZONE_STATE_INSTALLED            2
+# ZONE_STATE_READY                3
+# ZONE_STATE_RUNNING              4
+# ZONE_STATE_SHUTTING_DOWN        5
+# ZONE_STATE_DOWN                 6
+# ZONE_STATE_MOUNTED              7
+
+# cmd
+#
+# ready			0
+# boot			1
+# halt			4
+
+zonename=$1
+zonepath=$2
+state=$3
+cmd=$4
+
+# If we're not readying the zone, then just return.
+if [ $cmd -eq 0 ]; then
+	# Mount active dataset on the root.
+	get_current_gzbe
+	get_zonepath_ds $zonepath
+	get_active_ds $CURRENT_GZBE $ZONEPATH_DS
+
+	/usr/sbin/mount -F zfs $ACTIVE_DS $zonepath/root || \
+	    fail_fatal "$f_mount"
+fi
+
+exit $ZONE_SUBPROC_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/brand/query	Tue Sep 23 07:41:08 2008 -0600
@@ -0,0 +1,44 @@
+#!/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/uninstall	Tue Sep 23 07:41:08 2008 -0600
@@ -0,0 +1,173 @@
+#!/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
+
+f_promote=$(gettext "Error: promoting ZFS dataset.")
+f_destroy=$(gettext "Error: destroying ZFS dataset.")
+f_rmdir=$(gettext "Error: removing zonepath.")
+
+zonename=$1
+zonepath=$2
+
+zoneroot=$zonepath/root
+
+#
+# We want uninstall to work in the face of various problems, such as a
+# zone with no delegated root dataset or multiple active datasets, so we
+# don't use the common functions.  Instead, we do our own work here and
+# are tolerant of errors.
+#
+
+#
+# get_current_gzbe
+#
+CURRENT_GZBE=`/usr/sbin/beadm list -H | /usr/bin/nawk -F\; '{
+	# Field 3 is the BE status.  'N' is the active BE.
+	if ($3 ~ "N")
+		# Field 2 is the BE UUID
+		print $2
+	}'`
+
+if [ -z "$CURRENT_GZBE" ]; then
+	print "$f_no_gzbe"
+fi
+
+#
+# get_zonepath_ds $zonepath
+#
+ZONEPATH_DS=`/usr/sbin/zfs list -t filesystem -o name,mountpoint | \
+    /usr/bin/nawk -v zonepath=$zonepath '{
+	if ($2 == zonepath)
+		print $1
+}'`
+
+if [ -z "$ZONEPATH_DS" ]; then
+	print "$f_no_ds"
+fi
+
+#
+# Get the active dataset that is associated with the current global zone (GZ)
+# BE.
+#
+# get_active_ds $CURRENT_GZBE $ZONEPATH_DS
+
+if [ -n "$ZONEPATH_DS" -a -n "$CURRENT_GZBE" ]; then
+	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
+		print "$f_multiple_ds"
+		ACTIVE_DS=""
+	fi
+fi
+
+if [ -z "$ACTIVE_DS" ]; then
+	print "$f_no_active_ds"
+fi
+
+#
+# If the active dataset has dependents, need to promote them.
+#
+# This happens if we are booted back to an earlier GZ BE and are deleting the
+# zone on that BE.  In this case, we would have a snapshot of the current zone
+# dataset which is used for a clone by the later GZ BE.  We need to promote
+# that one before we try to delete the current one.
+#
+
+if [ -n "$ACTIVE_DS" ]; then
+	CLONES=`/usr/sbin/zfs list -H -r -t filesystem -o name,origin \
+	    $ZONEPATH_DS/ROOT | \
+	    /usr/bin/nawk -v zonepath=$ACTIVE_DS '
+		BEGIN {snapshot = "^" zonepath "@"}
+		{
+			if ($2 ~ snapshot)
+				print $1
+		}'`
+
+	for i in $CLONES
+	do
+		/usr/sbin/zfs promote $i || print "$f_promote"
+	done
+
+	# Delete the active dataset that is associated with the current GZ BE.
+	origin=`/usr/sbin/zfs get -H -o value origin $ACTIVE_DS 2>/dev/null`
+	/usr/sbin/zfs destroy -r $ACTIVE_DS
+
+	# Check for snapshot as origin and destroy it.
+	if [ $origin != "-" ]; then
+		/usr/sbin/zfs destroy $origin || print "$f_destroy"
+	fi
+fi
+
+#
+# Now find the rest of the datasets associated with the current GZ BE and
+# delete those, along with their snapshots.
+#
+if [ -n "$ZONEPATH_DS" -a -n "$CURRENT_GZBE" ]; then
+	DS=`/usr/sbin/zfs list -H -r -t filesystem \
+	    -o name,$PROP_PARENT $ZONEPATH_DS/ROOT | \
+	    /usr/bin/nawk -v gzbe=$CURRENT_GZBE ' {
+		if ($1 ~ /ROOT\/[^\/]+$/ && $2 == gzbe) {
+			print $1
+		}
+	    }'`
+
+	for i in $DS
+	do
+		/usr/sbin/zfs destroy -r $i || print "$f_destroy"
+	done
+fi
+
+#
+# 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.
+#
+if [ -n "$ZONEPATH_DS" ]; then
+	DS=`/usr/sbin/zfs list -H -r -t filesystem -o name $ZONEPATH_DS/ROOT | \
+	    /usr/bin/egrep "$ZONEPATH_DS/ROOT/"`
+	if [ -z "$DS" ]; then
+		# If not, destroy the ROOT dataset.
+		/usr/sbin/zfs destroy -r $ZONEPATH_DS/ROOT || print "$f_destroy"
+
+		# And its parent.
+		/usr/sbin/zfs destroy -r $ZONEPATH_DS || print "$f_destroy"
+
+		rm -rf $zonepath || print "$f_rmdir"
+	fi
+else
+	rm -rf $zonepath || print "$f_rmdir"
+fi
+
+exit $ZONE_SUBPROC_OK
--- a/src/pkgdefs/SUNWipkg-brand/Makefile	Tue Sep 23 15:18:27 2008 -0700
+++ b/src/pkgdefs/SUNWipkg-brand/Makefile	Tue Sep 23 07:41:08 2008 -0600
@@ -45,10 +45,13 @@
 			$$4 = "755" \
 		} \
 		$$1 == "f" { \
+			$$4 = "755" \
+		} \
+		$$1 == "f" && $$3 ~ /.*\.xml$$/ { \
 			$$4 = "444" \
 		} \
-		$$1 == "f" && $$3 ~ /usr\/lib\/brand\/ipkg\/pkgcreatezone/ { \
-			$$4 = "755" \
+		$$1 == "f" && $$3 ~ /usr\/lib\/brand\/ipkg\/common.ksh/ { \
+			$$4 = "444" \
 		} \
 		{ \
 			$$5 = "root"; \