1e71ca95cSGerald Jelinek#
2e71ca95cSGerald Jelinek# CDDL HEADER START
3e71ca95cSGerald Jelinek#
4e71ca95cSGerald Jelinek# The contents of this file are subject to the terms of the
5e71ca95cSGerald Jelinek# Common Development and Distribution License (the "License").
6e71ca95cSGerald Jelinek# You may not use this file except in compliance with the License.
7e71ca95cSGerald Jelinek#
8e71ca95cSGerald Jelinek# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e71ca95cSGerald Jelinek# or http://www.opensolaris.org/os/licensing.
10e71ca95cSGerald Jelinek# See the License for the specific language governing permissions
11e71ca95cSGerald Jelinek# and limitations under the License.
12e71ca95cSGerald Jelinek#
13e71ca95cSGerald Jelinek# When distributing Covered Code, include this CDDL HEADER in each
14e71ca95cSGerald Jelinek# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15e71ca95cSGerald Jelinek# If applicable, add the following below this CDDL HEADER, with the
16e71ca95cSGerald Jelinek# fields enclosed by brackets "[]" replaced with your own identifying
17e71ca95cSGerald Jelinek# information: Portions Copyright [yyyy] [name of copyright owner]
18e71ca95cSGerald Jelinek#
19e71ca95cSGerald Jelinek# CDDL HEADER END
20e71ca95cSGerald Jelinek#
21e71ca95cSGerald Jelinek#
22ab5dfd5eS# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23e71ca95cSGerald Jelinek# Use is subject to license terms.
24e71ca95cSGerald Jelinek#
25e71ca95cSGerald Jelinek
26e71ca95cSGerald Jelinekunset LD_LIBRARY_PATH
27e71ca95cSGerald JelinekPATH=/usr/bin:/usr/sbin
28e71ca95cSGerald Jelinekexport PATH
29e71ca95cSGerald Jelinek
30e71ca95cSGerald Jelinek. /usr/lib/brand/shared/common.ksh
31e71ca95cSGerald Jelinek
32ab5dfd5eS# Values for service tags.
33ab5dfd5eSSTCLIENT=/usr/bin/stclient
34ab5dfd5eSST_PRODUCT_NAME="Solaris 10 Containers"
35ab5dfd5eSST_PRODUCT_REV="1.0"
36ab5dfd5eSST_PRODUCT_UUID="urn:uuid:2f459121-dec7-11de-9af7-080020a9ed93"
37ab5dfd5eS
38caaceb36Sw_sanity_detail=$(gettext "       WARNING: Skipping image sanity checks.")
39e71ca95cSGerald Jelinekf_sanity_detail=$(gettext  "Missing %s at %s")
40e71ca95cSGerald Jelinekf_sanity_sparse=$(gettext  "Is this a sparse zone image?  The image must be whole-root.")
41e71ca95cSGerald Jelinekf_sanity_vers=$(gettext  "The image release version must be 10 (got %s), the zone is not usable on this system.")
42e71ca95cSGerald Jelinekf_not_s10_image=$(gettext  "%s doesn't look like a Solaris 10 image.")
43e71ca95cSGerald Jelinekf_sanity_nopatch=$(gettext "Unable to determine the image's patch level.")
44e71ca95cSGerald Jelinekf_sanity_downrev=$(gettext "The image patch level is downrev for running in a solaris10 branded zone.\n(patchlist %s)")
45e71ca95cSGerald Jelinekf_need_newer_emul=$(gettext "The image requires a newer version of the solaris10 brand emulation.")
46e71ca95cSGerald Jelinekf_zfs_create=$(gettext "Unable to create the zone's ZFS dataset.")
47e71ca95cSGerald Jelinekf_no_ds=$(gettext "No zonepath dataset; the zonepath must be a ZFS dataset.")
48e71ca95cSGerald Jelinekf_multiple_ds=$(gettext "Multiple active datasets.")
49e71ca95cSGerald Jelinekf_no_active_ds=$(gettext "No active dataset; the zone's ZFS root dataset must be configured as\n\ta zone boot environment.")
50e71ca95cSGerald Jelinekf_zfs_unmount=$(gettext "Unable to unmount the zone's root ZFS dataset (%s).\nIs there a global zone process inside the zone root?\nThe current zone boot environment will remain mounted.\n")
51e71ca95cSGerald Jelinekf_zfs_mount=$(gettext "Unable to mount the zone's ZFS dataset.")
52e71ca95cSGerald Jelinekincompat_options=$(gettext "mutually exclusive options.\n%s")
53e71ca95cSGerald Jelinek
54e71ca95cSGerald Jelineksanity_ok=$(gettext     "  Sanity Check: Passed.  Looks like a Solaris 10 image.")
55e71ca95cSGerald Jelineksanity_fail=$(gettext   "  Sanity Check: FAILED (see log for details).")
56e71ca95cSGerald Jelinek
57e71ca95cSGerald Jelineke_badboot=$(gettext "Zone boot failed")
58e71ca95cSGerald Jelineke_nosingleuser=$(gettext "ERROR: zone did not finish booting to single-user.")
59e71ca95cSGerald Jelineke_unconfig=$(gettext "sys-unconfig failed")
60e71ca95cSGerald Jelinekv_unconfig=$(gettext "Performing zone sys-unconfig")
61e71ca95cSGerald Jelinek
62ab5dfd5eSv_no_tags=$(gettext "Service tags facility not present.")
63ab5dfd5eSe_bad_uuid=$(gettext "Failed to get zone UUID")
64ab5dfd5eSv_addtag=$(gettext "Adding service tag: %s")
65ab5dfd5eSv_deltag=$(gettext "Removing service tag: %s")
66ab5dfd5eSe_addtag_fail=$(gettext "Adding service tag failed (error: %s)")
67ab5dfd5eS
68e71ca95cSGerald Jelineksanity_check()
69e71ca95cSGerald Jelinek{
70e71ca95cSGerald Jelinek	typeset dir="$1"
71e71ca95cSGerald Jelinek	res=0
72e71ca95cSGerald Jelinek
73e71ca95cSGerald Jelinek	#
74e71ca95cSGerald Jelinek	# Check for some required directories and make sure this isn't a
75e71ca95cSGerald Jelinek	# sparse zone image.
76e71ca95cSGerald Jelinek	#
77e71ca95cSGerald Jelinek	checks="etc etc/svc var var/svc"
78e71ca95cSGerald Jelinek	for x in $checks; do
79e71ca95cSGerald Jelinek		if [[ ! -e $dir/$x ]]; then
80e71ca95cSGerald Jelinek			log "$f_sanity_detail" "$x" "$dir"
81e71ca95cSGerald Jelinek			res=1
82e71ca95cSGerald Jelinek		fi
83e71ca95cSGerald Jelinek	done
84e71ca95cSGerald Jelinek	# Files from SUNWcsr and SUNWcsu that are in sparse inherit-pkg-dirs.
85e71ca95cSGerald Jelinek	checks="lib/svc sbin/zonename usr/bin/chmod"
86e71ca95cSGerald Jelinek	for x in $checks; do
87e71ca95cSGerald Jelinek		if [[ ! -e $dir/$x ]]; then
88e71ca95cSGerald Jelinek			log "$f_sanity_detail" "$x" "$dir"
89e71ca95cSGerald Jelinek			log "$f_sanity_sparse"
90e71ca95cSGerald Jelinek			res=1
91e71ca95cSGerald Jelinek		fi
92e71ca95cSGerald Jelinek	done
93e71ca95cSGerald Jelinek
94caaceb36S	if (( $res != 0 )); then
95caaceb36S		log "$sanity_fail"
96caaceb36S		fatal "$install_fail" "$ZONENAME"
97caaceb36S	fi
98caaceb36S
99caaceb36S	if [[ "$SANITY_SKIP" == 1 ]]; then
100caaceb36S		log "$w_sanity_detail"
101caaceb36S		return
102caaceb36S	fi
103caaceb36S
104e71ca95cSGerald Jelinek	#
105e71ca95cSGerald Jelinek	# Check image release to be sure its S10.
106e71ca95cSGerald Jelinek	#
107e71ca95cSGerald Jelinek	image_vers="unknown"
108e71ca95cSGerald Jelinek	if [[ -f $dir/var/sadm/system/admin/INST_RELEASE ]]; then
109e71ca95cSGerald Jelinek		image_vers=$(nawk -F= '{if ($1 == "VERSION") print $2}' \
110e71ca95cSGerald Jelinek		    $dir/var/sadm/system/admin/INST_RELEASE)
111e71ca95cSGerald Jelinek	fi
112e71ca95cSGerald Jelinek
113e71ca95cSGerald Jelinek	if [[ "$image_vers" != "10" ]]; then
114e71ca95cSGerald Jelinek		log "$f_sanity_vers" "$image_vers"
115e71ca95cSGerald Jelinek		res=1
116e71ca95cSGerald Jelinek	fi
117e71ca95cSGerald Jelinek
118e71ca95cSGerald Jelinek	#
119e71ca95cSGerald Jelinek	# Make sure we have the minimal KU patch we support.  These are the
120e71ca95cSGerald Jelinek	# KUs for S10u8.
121e71ca95cSGerald Jelinek	#
122e71ca95cSGerald Jelinek	if [[ $(uname -p) == "i386" ]]; then
123e71ca95cSGerald Jelinek		req_patch="141445-09"
124e71ca95cSGerald Jelinek	else
125e71ca95cSGerald Jelinek		req_patch="141444-09"
126e71ca95cSGerald Jelinek	fi
127e71ca95cSGerald Jelinek
128e71ca95cSGerald Jelinek	for i in $dir/var/sadm/pkg/SUNWcakr*
129e71ca95cSGerald Jelinek	do
130e71ca95cSGerald Jelinek		if [[ ! -d $i || ! -f $i/pkginfo ]]; then
131e71ca95cSGerald Jelinek			log "$f_sanity_nopatch"
132e71ca95cSGerald Jelinek			res=1
133e71ca95cSGerald Jelinek		fi
134e71ca95cSGerald Jelinek	done
135e71ca95cSGerald Jelinek
136e71ca95cSGerald Jelinek	#
137e71ca95cSGerald Jelinek	# Check the core kernel pkg for the required KU patch.
138e71ca95cSGerald Jelinek	#
139e71ca95cSGerald Jelinek	found=0
140e71ca95cSGerald Jelinek	for i in $dir/var/sadm/pkg/SUNWcakr*/pkginfo
141e71ca95cSGerald Jelinek	do
142e71ca95cSGerald Jelinek		patches=$(nawk -F= '{if ($1 == "PATCHLIST") print $2}' $i)
143e71ca95cSGerald Jelinek		for patch in $patches
144e71ca95cSGerald Jelinek		do
145e71ca95cSGerald Jelinek			if [[ $patch == $req_patch ]]; then
146e71ca95cSGerald Jelinek				found=1
147e71ca95cSGerald Jelinek				break
148e71ca95cSGerald Jelinek			fi
149e71ca95cSGerald Jelinek		done
150e71ca95cSGerald Jelinek
151e71ca95cSGerald Jelinek		if (( $found == 1 )); then
152e71ca95cSGerald Jelinek			break
153e71ca95cSGerald Jelinek		fi
154e71ca95cSGerald Jelinek	done
155e71ca95cSGerald Jelinek
156e71ca95cSGerald Jelinek	if (( $found != 1 )); then
157e71ca95cSGerald Jelinek		log "$f_sanity_downrev" "$patches"
158e71ca95cSGerald Jelinek		res=1
159e71ca95cSGerald Jelinek	fi
160e71ca95cSGerald Jelinek
161e71ca95cSGerald Jelinek	#
162e71ca95cSGerald Jelinek	# Check the S10 image for a required version of the emulation.
163e71ca95cSGerald Jelinek	#
164e71ca95cSGerald Jelinek	VERS_FILE=/usr/lib/brand/solaris10/version
165e71ca95cSGerald Jelinek	s10vers_needs=0
166e71ca95cSGerald Jelinek	if [[ -f $dir/$VERS_FILE ]]; then
167e71ca95cSGerald Jelinek		s10vers_needs=$(/usr/bin/egrep -v "^#" $dir/$VERS_FILE)
168e71ca95cSGerald Jelinek	fi
169e71ca95cSGerald Jelinek
170e71ca95cSGerald Jelinek	# Now get the current emulation version.
171e71ca95cSGerald Jelinek	emul_vers=$(/usr/bin/egrep -v "^#" $VERS_FILE)
172e71ca95cSGerald Jelinek
173e71ca95cSGerald Jelinek	# Verify that the emulation can run this version of S10.
174e71ca95cSGerald Jelinek	if (( $s10vers_needs > $emul_vers )); then
175e71ca95cSGerald Jelinek		log "$f_need_newer_emul"
176e71ca95cSGerald Jelinek		res=1
177e71ca95cSGerald Jelinek	fi
178e71ca95cSGerald Jelinek
179e71ca95cSGerald Jelinek	if (( $res != 0 )); then
180e71ca95cSGerald Jelinek		log "$sanity_fail"
181e71ca95cSGerald Jelinek		fatal "$install_fail" "$ZONENAME"
182e71ca95cSGerald Jelinek	fi
183e71ca95cSGerald Jelinek
184e71ca95cSGerald Jelinek	vlog "$sanity_ok"
185e71ca95cSGerald Jelinek}
186e71ca95cSGerald Jelinek
187e71ca95cSGerald Jelinek# Find the active dataset under the zonepath dataset to mount on zonepath/root.
188e71ca95cSGerald Jelinek# $1 ZONEPATH_DS
189e71ca95cSGerald Jelinekget_active_ds() {
190*090f667dS	ACTIVE_DS=$1/ROOT/zbe-0
191e71ca95cSGerald Jelinek}
192e71ca95cSGerald Jelinek
193e71ca95cSGerald Jelinek#
194*090f667dS# Make sure the active dataset is mounted for the zone.
195e71ca95cSGerald Jelinek#
196e71ca95cSGerald Jelinekmount_active_ds() {
197e71ca95cSGerald Jelinek	get_zonepath_ds $zonepath
198e71ca95cSGerald Jelinek	get_active_ds $ZONEPATH_DS
199e71ca95cSGerald Jelinek
200*090f667dS	# If already mounted then we're done.
201*090f667dS	mnted=`zfs get -H mounted $ACTIVE_DS | cut -f3`
202*090f667dS	[[ $mnted = "yes" ]] && return
203*090f667dS
204*090f667dS	mount -F zfs $ACTIVE_DS $zonepath/root || fail_fatal "$f_zfs_mount"
205e71ca95cSGerald Jelinek}
206e71ca95cSGerald Jelinek
207e71ca95cSGerald Jelinek#
208e71ca95cSGerald Jelinek# Set up ZFS dataset hierarchy for the zone root dataset.
209e71ca95cSGerald Jelinek#
210e71ca95cSGerald Jelinekcreate_active_ds() {
211e71ca95cSGerald Jelinek	# Find the zone's current dataset.  This should have been created by
212e71ca95cSGerald Jelinek	# zoneadm (or the attach hook).
213e71ca95cSGerald Jelinek	get_zonepath_ds $zonepath
214e71ca95cSGerald Jelinek
215e71ca95cSGerald Jelinek	#
216e71ca95cSGerald Jelinek	# We need to tolerate errors while creating the datasets and making the
217e71ca95cSGerald Jelinek	# mountpoint, since these could already exist from an attach scenario.
218e71ca95cSGerald Jelinek	#
219e71ca95cSGerald Jelinek
220e71ca95cSGerald Jelinek	/usr/sbin/zfs list -H -o name $ZONEPATH_DS/ROOT >/dev/null 2>&1
221e71ca95cSGerald Jelinek	if (( $? != 0 )); then
222e71ca95cSGerald Jelinek		/usr/sbin/zfs create -o mountpoint=legacy -o zoned=on \
223e71ca95cSGerald Jelinek		    $ZONEPATH_DS/ROOT
224e71ca95cSGerald Jelinek		if (( $? != 0 )); then
225e71ca95cSGerald Jelinek			fail_fatal "$f_zfs_create"
226e71ca95cSGerald Jelinek		fi
227e71ca95cSGerald Jelinek	else
228e71ca95cSGerald Jelinek	       	/usr/sbin/zfs set mountpoint=legacy $ZONEPATH_DS/ROOT \
229e71ca95cSGerald Jelinek		    >/dev/null 2>&1
230e71ca95cSGerald Jelinek	       	/usr/sbin/zfs set zoned=on $ZONEPATH_DS/ROOT \
231e71ca95cSGerald Jelinek		    >/dev/null 2>&1
232e71ca95cSGerald Jelinek	fi
233e71ca95cSGerald Jelinek
234*090f667dS	get_active_ds $ZONEPATH_DS
235*090f667dS	zfs list -H -o name $ACTIVE_DS >/dev/null 2>&1
236e71ca95cSGerald Jelinek	if (( $? != 0 )); then
237*090f667dS	       	zfs create -o canmount=noauto $ACTIVE_DS
238*090f667dS		(( $? != 0 )) && fail_fatal "$f_zfs_create"
239e71ca95cSGerald Jelinek	else
240*090f667dS	       	zfs set canmount=noauto $ACTIVE_DS >/dev/null 2>&1
241*090f667dS	       	zfs inherit mountpoint $ACTIVE_DS >/dev/null 2>&1
242*090f667dS	       	zfs inherit zoned $ACTIVE_DS >/dev/null 2>&1
243e71ca95cSGerald Jelinek	fi
244e71ca95cSGerald Jelinek
245e71ca95cSGerald Jelinek	if [ ! -d $ZONEROOT ]; then
246e71ca95cSGerald Jelinek		/usr/bin/mkdir -m 0755 -p $ZONEROOT || \
247e71ca95cSGerald Jelinek		    fail_fatal "$f_mkdir" "$ZONEROOT"
248e71ca95cSGerald Jelinek	fi
249e71ca95cSGerald Jelinek	/usr/bin/chmod 700 $ZONEPATH || fail_fatal "$f_chmod" "$ZONEPATH"
250e71ca95cSGerald Jelinek
251*090f667dS	mount -F zfs $ACTIVE_DS $ZONEROOT || fail_fatal "$f_zfs_mount"
252e71ca95cSGerald Jelinek}
253e71ca95cSGerald Jelinek
254e71ca95cSGerald Jelinek#
255e71ca95cSGerald Jelinek# Before booting the zone we may need to create a few mnt points, just in
256e71ca95cSGerald Jelinek# case they don't exist for some reason.
257e71ca95cSGerald Jelinek#
258e71ca95cSGerald Jelinek# Whenever we reach into the zone while running in the global zone we
259e71ca95cSGerald Jelinek# need to validate that none of the interim directories are symlinks
260e71ca95cSGerald Jelinek# that could cause us to inadvertently modify the global zone.
261e71ca95cSGerald Jelinek#
262e71ca95cSGerald Jelinekmk_zone_dirs() {
263e71ca95cSGerald Jelinek	vlog "$v_mkdirs"
264e71ca95cSGerald Jelinek	if [[ ! -f $ZONEROOT/tmp && ! -d $ZONEROOT/tmp ]]; then
265e71ca95cSGerald Jelinek		mkdir -m 1777 -p $ZONEROOT/tmp || exit $EXIT_CODE
266e71ca95cSGerald Jelinek	fi
267e71ca95cSGerald Jelinek	if [[ ! -f $ZONEROOT/var/run && ! -d $ZONEROOT/var/run ]]; then
268e71ca95cSGerald Jelinek		mkdir -m 1755 -p $ZONEROOT/var/run || exit $EXIT_CODE
269e71ca95cSGerald Jelinek	fi
270e71ca95cSGerald Jelinek	if [[ ! -f $ZONEROOT/var/tmp && ! -d $ZONEROOT/var/tmp ]]; then
271e71ca95cSGerald Jelinek		mkdir -m 1777 -p $ZONEROOT/var/tmp || exit $EXIT_CODE
272e71ca95cSGerald Jelinek	fi
273e71ca95cSGerald Jelinek	if [[ ! -h $ZONEROOT/etc && ! -f $ZONEROOT/etc/mnttab ]]; then
274e71ca95cSGerald Jelinek		/usr/bin/touch $ZONEROOT/etc/mnttab || exit $EXIT_CODE
275e71ca95cSGerald Jelinek		/usr/bin/chmod 444 $ZONEROOT/etc/mnttab || exit $EXIT_CODE
276e71ca95cSGerald Jelinek	fi
277e71ca95cSGerald Jelinek	if [[ ! -f $ZONEROOT/proc && ! -d $ZONEROOT/proc ]]; then
278e71ca95cSGerald Jelinek		mkdir -m 755 -p $ZONEROOT/proc || exit $EXIT_CODE
279e71ca95cSGerald Jelinek	fi
280e71ca95cSGerald Jelinek	if [[ ! -f $ZONEROOT/dev && ! -d $ZONEROOT/dev ]]; then
281e71ca95cSGerald Jelinek		mkdir -m 755 -p $ZONEROOT/dev || exit $EXIT_CODE
282e71ca95cSGerald Jelinek	fi
283e71ca95cSGerald Jelinek	if [[ ! -h $ZONEROOT/etc && ! -h $ZONEROOT/etc/svc && \
284e71ca95cSGerald Jelinek	    ! -d $ZONEROOT/etc/svc ]]; then
285e71ca95cSGerald Jelinek		mkdir -m 755 -p $ZONEROOT/etc/svc/volatile || exit $EXIT_CODE
286e71ca95cSGerald Jelinek	fi
287e71ca95cSGerald Jelinek}
288e71ca95cSGerald Jelinek
289e71ca95cSGerald Jelinek#
290e71ca95cSGerald Jelinek# We're sys-unconfig-ing the zone.  This will normally halt the zone, however
291e71ca95cSGerald Jelinek# there are problems with sys-unconfig and it can hang when the zone is booted
292e71ca95cSGerald Jelinek# to milestone=none.  Sys-unconfig also sometimes hangs halting the zone.
293e71ca95cSGerald Jelinek# Thus, we take some care to workaround these sys-unconfig limitations.
294e71ca95cSGerald Jelinek#
295e71ca95cSGerald Jelinek# On entry we expect the zone to be booted.  We use sys-unconfig -R to make it
296e71ca95cSGerald Jelinek# think its working on an alternate root and let the caller halt the zone.
297e71ca95cSGerald Jelinek#
298e71ca95cSGerald Jelineksysunconfig_zone() {
299e71ca95cSGerald Jelinek	/usr/sbin/zlogin -S $ZONENAME /usr/sbin/sys-unconfig -R /./ \
300e71ca95cSGerald Jelinek	    >/dev/null 2>&1
301e71ca95cSGerald Jelinek	if (( $? != 0 )); then
302e71ca95cSGerald Jelinek		error "$e_unconfig"
303e71ca95cSGerald Jelinek		return 1
304e71ca95cSGerald Jelinek	fi
305e71ca95cSGerald Jelinek
306e71ca95cSGerald Jelinek	return 0
307e71ca95cSGerald Jelinek}
308ab5dfd5eS
309ab5dfd5eS#
310ab5dfd5eS# Get zone's uuid for service tag.
311ab5dfd5eS#
312ab5dfd5eSget_inst_uuid()
313ab5dfd5eS{
314ab5dfd5eS        typeset ZONENAME="$1"
315ab5dfd5eS
316ab5dfd5eS	ZONEUUID=`zoneadm -z $ZONENAME list -p | nawk -F: '{print $5}'`
317ab5dfd5eS	[[ $? -ne 0 || -z $ZONEUUID ]] && return 1
318ab5dfd5eS
319ab5dfd5eS	INSTANCE_UUID="urn:st:${ZONEUUID}"
320ab5dfd5eS	return 0
321ab5dfd5eS}
322ab5dfd5eS
323ab5dfd5eS#
324ab5dfd5eS# Add a service tag for a given zone.  We use two UUIDs-- the first,
325ab5dfd5eS# the Product UUID, comes from the Sun swoRDFish ontology.  The second
326ab5dfd5eS# is the UUID of the zone itself, which forms the instance UUID.
327ab5dfd5eS#
328ab5dfd5eSadd_svc_tag()
329ab5dfd5eS{
330ab5dfd5eS        typeset ZONENAME="$1"
331ab5dfd5eS        typeset SOURCE="$2"
332ab5dfd5eS
333ab5dfd5eS	if [ ! -x $STCLIENT ]; then
334ab5dfd5eS		vlog "$v_no_tags"
335ab5dfd5eS		return 0
336ab5dfd5eS	fi
337ab5dfd5eS
338ab5dfd5eS	get_inst_uuid "$ZONENAME" || (error "$e_bad_uuid"; return 1)
339ab5dfd5eS
340ab5dfd5eS	vlog "$v_addtag" "$INSTANCE_UUID"
341ab5dfd5eS	$STCLIENT -a \
342ab5dfd5eS	    -p "$ST_PRODUCT_NAME" \
343ab5dfd5eS	    -e "$ST_PRODUCT_REV" \
344ab5dfd5eS	    -t "$ST_PRODUCT_UUID" \
345ab5dfd5eS	    -i "$INSTANCE_UUID" \
346ab5dfd5eS	    -P "none" \
347ab5dfd5eS	    -m "Sun" \
348ab5dfd5eS	    -A `uname -p` \
349ab5dfd5eS	    -z "$ZONENAME" \
350ab5dfd5eS	    -S "$SOURCE" >/dev/null 2>&1
351ab5dfd5eS
352ab5dfd5eS	err=$?
353ab5dfd5eS
354ab5dfd5eS	# 226 means "duplicate record," which we can ignore.
355ab5dfd5eS	if [[ $err -ne 0 && $err -ne 226 ]]; then
356ab5dfd5eS		error "$e_addtag_fail" "$err"
357ab5dfd5eS		return 1
358ab5dfd5eS	fi
359ab5dfd5eS	return 0
360ab5dfd5eS}
361ab5dfd5eS
362ab5dfd5eS#
363ab5dfd5eS# Remove a service tag for a given zone.
364ab5dfd5eS#
365ab5dfd5eSdel_svc_tag()
366ab5dfd5eS{
367ab5dfd5eS        typeset ZONENAME="$1"
368ab5dfd5eS
369ab5dfd5eS	if [ ! -x $STCLIENT ]; then
370ab5dfd5eS		vlog "$v_no_tags"
371ab5dfd5eS		return 0
372ab5dfd5eS	fi
373ab5dfd5eS
374ab5dfd5eS	get_inst_uuid "$ZONENAME" || (error "$e_bad_uuid"; return 1)
375ab5dfd5eS
376ab5dfd5eS	vlog "$v_deltag" "$INSTANCE_UUID"
377ab5dfd5eS        $STCLIENT -d -i "$INSTANCE_UUID" >/dev/null 2>&1
378ab5dfd5eS	return 0
379ab5dfd5eS}
380