1edfa49f<gerald.jelinek@sun.com>#
2edfa49f<gerald.jelinek@sun.com># CDDL HEADER START
3edfa49f<gerald.jelinek@sun.com>#
4edfa49f<gerald.jelinek@sun.com># The contents of this file are subject to the terms of the
5edfa49f<gerald.jelinek@sun.com># Common Development and Distribution License (the "License").
6edfa49f<gerald.jelinek@sun.com># You may not use this file except in compliance with the License.
7edfa49f<gerald.jelinek@sun.com>#
8edfa49f<gerald.jelinek@sun.com># You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9edfa49f<gerald.jelinek@sun.com># or http://www.opensolaris.org/os/licensing.
10edfa49f<gerald.jelinek@sun.com># See the License for the specific language governing permissions
11edfa49f<gerald.jelinek@sun.com># and limitations under the License.
12edfa49f<gerald.jelinek@sun.com>#
13edfa49f<gerald.jelinek@sun.com># When distributing Covered Code, include this CDDL HEADER in each
14edfa49f<gerald.jelinek@sun.com># file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15edfa49f<gerald.jelinek@sun.com># If applicable, add the following below this CDDL HEADER, with the
16edfa49f<gerald.jelinek@sun.com># fields enclosed by brackets "[]" replaced with your own identifying
17edfa49f<gerald.jelinek@sun.com># information: Portions Copyright [yyyy] [name of copyright owner]
18edfa49f<gerald.jelinek@sun.com>#
19edfa49f<gerald.jelinek@sun.com># CDDL HEADER END
20edfa49f<gerald.jelinek@sun.com>#
216e1ae2aGary Pennington# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
22edfa49f<gerald.jelinek@sun.com>#
23edfa49f<gerald.jelinek@sun.com>
24edfa49f<gerald.jelinek@sun.com>#
25edfa49f<gerald.jelinek@sun.com># Send the error message to the screen and to the logfile.
26edfa49f<gerald.jelinek@sun.com>#
27edfa49f<gerald.jelinek@sun.com>error()
28edfa49f<gerald.jelinek@sun.com>{
29edfa49f<gerald.jelinek@sun.com>        typeset fmt="$1"
30edfa49f<gerald.jelinek@sun.com>        shift
31edfa49f<gerald.jelinek@sun.com>
32edfa49f<gerald.jelinek@sun.com>        printf "${MSG_PREFIX}ERROR: ${fmt}\n" "$@"
33edfa49f<gerald.jelinek@sun.com>        [[ -n $LOGFILE ]] && printf "[$(date)] ERROR: ${fmt}\n" "$@" >&2
34edfa49f<gerald.jelinek@sun.com>}
35edfa49f<gerald.jelinek@sun.com>
36edfa49f<gerald.jelinek@sun.com>fatal()
37edfa49f<gerald.jelinek@sun.com>{
38edfa49f<gerald.jelinek@sun.com>        typeset fmt="$1"
39edfa49f<gerald.jelinek@sun.com>        shift
40edfa49f<gerald.jelinek@sun.com>
41edfa49f<gerald.jelinek@sun.com>	error "$fmt" "$@"
42edfa49f<gerald.jelinek@sun.com>	exit $EXIT_CODE
43edfa49f<gerald.jelinek@sun.com>}
44edfa49f<gerald.jelinek@sun.com>
45e71ca95Gerald Jelinekfail_fatal() {
4619b7790<gerald.jelinek@sun.com>        typeset fmt="$1"
4719b7790<gerald.jelinek@sun.com>        shift
4819b7790<gerald.jelinek@sun.com>
4919b7790<gerald.jelinek@sun.com>	error "$fmt" "$@"
50e71ca95Gerald Jelinek	exit $ZONE_SUBPROC_FATAL
51e71ca95Gerald Jelinek}
52e71ca95Gerald Jelinek
53edfa49f<gerald.jelinek@sun.com>#
54edfa49f<gerald.jelinek@sun.com># Send the provided printf()-style arguments to the screen and to the logfile.
55edfa49f<gerald.jelinek@sun.com>#
56edfa49f<gerald.jelinek@sun.com>log()
57edfa49f<gerald.jelinek@sun.com>{
58edfa49f<gerald.jelinek@sun.com>        typeset fmt="$1"
59edfa49f<gerald.jelinek@sun.com>        shift
60edfa49f<gerald.jelinek@sun.com>
61edfa49f<gerald.jelinek@sun.com>        printf "${MSG_PREFIX}${fmt}\n" "$@"
62edfa49f<gerald.jelinek@sun.com>        [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2
63edfa49f<gerald.jelinek@sun.com>}
64edfa49f<gerald.jelinek@sun.com>
65edfa49f<gerald.jelinek@sun.com>#
66edfa49f<gerald.jelinek@sun.com># Print provided text to the screen if the shell variable "OPT_V" is set.
67edfa49f<gerald.jelinek@sun.com># The text is always sent to the logfile.
68edfa49f<gerald.jelinek@sun.com>#
69edfa49f<gerald.jelinek@sun.com>vlog()
70edfa49f<gerald.jelinek@sun.com>{
71edfa49f<gerald.jelinek@sun.com>        typeset fmt="$1"
72edfa49f<gerald.jelinek@sun.com>        shift
73edfa49f<gerald.jelinek@sun.com>
74edfa49f<gerald.jelinek@sun.com>        [[ -n $OPT_V ]] && printf "${MSG_PREFIX}${fmt}\n" "$@"
75edfa49f<gerald.jelinek@sun.com>        [[ -n $LOGFILE ]] && printf "[$(date)] ${MSG_PREFIX}${fmt}\n" "$@" >&2
76edfa49f<gerald.jelinek@sun.com>}
77edfa49f<gerald.jelinek@sun.com>
78e71ca95Gerald Jelinek#
79edfa49f<gerald.jelinek@sun.com># Validate that the directory is safe.
80e71ca95Gerald Jelinek#
81e71ca95Gerald Jelinek# It is possible for a malicious zone root user to modify a zone's filesystem
82e71ca95Gerald Jelinek# so that modifications made to the zone's filesystem by administrators in the
83e71ca95Gerald Jelinek# global zone modify the global zone's filesystem.  We can prevent this by
84e71ca95Gerald Jelinek# ensuring that all components of paths accessed by scripts are real (i.e.,
85e71ca95Gerald Jelinek# non-symlink) directories.
86e71ca95Gerald Jelinek#
87e71ca95Gerald Jelinek# NOTE: The specified path should be an absolute path as would be seen from
88e71ca95Gerald Jelinek# within the zone.  Also, this function does not check parent directories.
89e71ca95Gerald Jelinek# If, for example, you need to ensure that every component of the path
90e71ca95Gerald Jelinek# '/foo/bar/baz' is a directory and not a symlink, then do the following:
91e71ca95Gerald Jelinek#
92e71ca95Gerald Jelinek#	safe_dir /foo
93e71ca95Gerald Jelinek#	safe_dir /foo/bar
94e71ca95Gerald Jelinek#	safe_dir /foo/bar/baz
95e71ca95Gerald Jelinek#
96edfa49f<gerald.jelinek@sun.com>safe_dir()
97edfa49f<gerald.jelinek@sun.com>{
98edfa49f<gerald.jelinek@sun.com>	typeset dir="$1"
99edfa49f<gerald.jelinek@sun.com>
100edfa49f<gerald.jelinek@sun.com>	if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then
101edfa49f<gerald.jelinek@sun.com>		fatal "$e_baddir" "$dir"
102edfa49f<gerald.jelinek@sun.com>	fi
103edfa49f<gerald.jelinek@sun.com>}
104edfa49f<gerald.jelinek@sun.com>
105e71ca95Gerald Jelinek# Like safe_dir except the dir doesn't have to exist.
106e71ca95Gerald Jelineksafe_opt_dir()
107e71ca95Gerald Jelinek{
108e71ca95Gerald Jelinek	typeset dir="$1"
109e71ca95Gerald Jelinek
110e71ca95Gerald Jelinek	[[ ! -e $ZONEROOT/$dir ]] && return
111e71ca95Gerald Jelinek
112e71ca95Gerald Jelinek	if [[ -h $ZONEROOT/$dir || ! -d $ZONEROOT/$dir ]]; then
113e71ca95Gerald Jelinek		fatal "$e_baddir" "$dir"
114e71ca95Gerald Jelinek	fi
115e71ca95Gerald Jelinek}
116e71ca95Gerald Jelinek
117edfa49f<gerald.jelinek@sun.com># Only make a copy if we haven't already done so.
118edfa49f<gerald.jelinek@sun.com>safe_backup()
119edfa49f<gerald.jelinek@sun.com>{
120edfa49f<gerald.jelinek@sun.com>	typeset src="$1"
121edfa49f<gerald.jelinek@sun.com>	typeset dst="$2"
122edfa49f<gerald.jelinek@sun.com>
123edfa49f<gerald.jelinek@sun.com>	if [[ ! -h $src && ! -h $dst && ! -d $dst && ! -f $dst ]]; then
124edfa49f<gerald.jelinek@sun.com>		/usr/bin/cp -p $src $dst || fatal "$e_badfile" "$src"
125edfa49f<gerald.jelinek@sun.com>	fi
126edfa49f<gerald.jelinek@sun.com>}
127edfa49f<gerald.jelinek@sun.com>
128edfa49f<gerald.jelinek@sun.com># Make a copy even if the destination already exists.
129edfa49f<gerald.jelinek@sun.com>safe_copy()
130edfa49f<gerald.jelinek@sun.com>{
131edfa49f<gerald.jelinek@sun.com>	typeset src="$1"
132edfa49f<gerald.jelinek@sun.com>	typeset dst="$2"
133edfa49f<gerald.jelinek@sun.com>
134edfa49f<gerald.jelinek@sun.com>	if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then
135edfa49f<gerald.jelinek@sun.com>		/usr/bin/cp -p $src $dst || fatal "$e_badfile" "$src"
136edfa49f<gerald.jelinek@sun.com>	fi
137edfa49f<gerald.jelinek@sun.com>}
138edfa49f<gerald.jelinek@sun.com>
139edfa49f<gerald.jelinek@sun.com># Move a file
140edfa49f<gerald.jelinek@sun.com>safe_move()
141edfa49f<gerald.jelinek@sun.com>{
142edfa49f<gerald.jelinek@sun.com>	typeset src="$1"
143edfa49f<gerald.jelinek@sun.com>	typeset dst="$2"
144edfa49f<gerald.jelinek@sun.com>
145edfa49f<gerald.jelinek@sun.com>	if [[ ! -h $src && ! -h $dst && ! -d $dst ]]; then
146edfa49f<gerald.jelinek@sun.com>		/usr/bin/mv $src $dst || fatal "$e_badfile" "$src"
147edfa49f<gerald.jelinek@sun.com>	fi
148edfa49f<gerald.jelinek@sun.com>}
149edfa49f<gerald.jelinek@sun.com>
150e71ca95Gerald Jelineksafe_rm()
151e71ca95Gerald Jelinek{
152e71ca95Gerald Jelinek	if [[ ! -h $ZONEROOT/$1 && -f $ZONEROOT/$1 ]]; then
153e71ca95Gerald Jelinek		rm -f "$ZONEROOT/$1"
154e71ca95Gerald Jelinek	fi
155e71ca95Gerald Jelinek}
156e71ca95Gerald Jelinek
157e71ca95Gerald Jelinek#
158e71ca95Gerald Jelinek# Replace the file with a wrapper pointing to the native brand code.
159e71ca95Gerald Jelinek# However, we only do the replacement if the file hasn't already been
160e71ca95Gerald Jelinek# replaced with our wrapper.  This function expects the cwd to be the
161e71ca95Gerald Jelinek# location of the file we're replacing.
162e71ca95Gerald Jelinek#
163e71ca95Gerald Jelinek# Some of the files we're replacing are hardlinks to isaexec so we need to 'rm'
164e71ca95Gerald Jelinek# the file before we setup the wrapper while others are hardlinks to rc scripts
165e71ca95Gerald Jelinek# that we need to maintain.
166e71ca95Gerald Jelinek#
167e71ca95Gerald Jelineksafe_replace()
168e71ca95Gerald Jelinek{
169e71ca95Gerald Jelinek	typeset filename="$1"
170e71ca95Gerald Jelinek	typeset runname="$2"
171e71ca95Gerald Jelinek	typeset mode="$3"
172e71ca95Gerald Jelinek	typeset own="$4"
173e71ca95Gerald Jelinek	typeset rem="$5"
174e71ca95Gerald Jelinek
175e71ca95Gerald Jelinek	if [ -h $filename -o ! -f $filename ]; then
176e71ca95Gerald Jelinek		return
177e71ca95Gerald Jelinek	fi
178e71ca95Gerald Jelinek
179e71ca95Gerald Jelinek	egrep -s "Solaris Brand Replacement" $filename
180e71ca95Gerald Jelinek	if [ $? -eq 0 ]; then
181e71ca95Gerald Jelinek		return
182e71ca95Gerald Jelinek	fi
183e71ca95Gerald Jelinek
184e71ca95Gerald Jelinek	safe_backup $filename $filename.pre_p2v
185e71ca95Gerald Jelinek	if [ $rem = "remove" ]; then
186e71ca95Gerald Jelinek		rm -f $filename
187e71ca95Gerald Jelinek	fi
188e71ca95Gerald Jelinek
189e71ca95Gerald Jelinek	cat <<-END >$filename || exit 1
1901022fd2<gerald.jelinek@sun.com>	#!/bin/sh -p
191e71ca95Gerald Jelinek	#
192e71ca95Gerald Jelinek	# Solaris Brand Replacement
193e71ca95Gerald Jelinek	#
194e71ca95Gerald Jelinek	# Attention.  This file has been replaced with a new version for
195e71ca95Gerald Jelinek	# use in a virtualized environment.  Modification of this script is not
196e71ca95Gerald Jelinek	# supported and all changes will be lost upon reboot.  The
197e71ca95Gerald Jelinek	# {name}.pre_p2v version of this file is a backup copy of the
198e71ca95Gerald Jelinek	# original and should not be deleted.
199e71ca95Gerald Jelinek	#
200e71ca95Gerald Jelinek	END
201e71ca95Gerald Jelinek
202e71ca95Gerald Jelinek	echo ". $runname \"\$@\"" >>$filename || exit 1
203e71ca95Gerald Jelinek
204e71ca95Gerald Jelinek	chmod $mode $filename
205e71ca95Gerald Jelinek	chown $own $filename
206e71ca95Gerald Jelinek}
207e71ca95Gerald Jelinek
208ae10493Jonathan Adamssafe_wrap()
209ae10493Jonathan Adams{
210ae10493Jonathan Adams	typeset filename="$1"
211ae10493Jonathan Adams	typeset runname="$2"
212ae10493Jonathan Adams	typeset mode="$3"
213ae10493Jonathan Adams	typeset own="$4"
214ae10493Jonathan Adams
215ae10493Jonathan Adams	if [ -f $filename ]; then
216ae10493Jonathan Adams		log "$e_cannot_wrap" "$filename"
217ae10493Jonathan Adams		exit 1
218ae10493Jonathan Adams	fi
219ae10493Jonathan Adams
220ae10493Jonathan Adams	cat <<-END >$filename || exit 1
221ae10493Jonathan Adams	#!/bin/sh
222ae10493Jonathan Adams	#
223ae10493Jonathan Adams	# Solaris Brand Wrapper
224ae10493Jonathan Adams	#
225ae10493Jonathan Adams	# Attention.  This file has been created for use in a
226ae10493Jonathan Adams	# virtualized environment.  Modification of this script
227ae10493Jonathan Adams	# is not supported and all changes will be lost upon reboot.
228ae10493Jonathan Adams	#
229ae10493Jonathan Adams	END
230ae10493Jonathan Adams
231ae10493Jonathan Adams	echo ". $runname \"\$@\"" >>$filename || exit 1
232ae10493Jonathan Adams
233ae10493Jonathan Adams	chmod $mode $filename
234ae10493Jonathan Adams	chown $own $filename
235ae10493Jonathan Adams}
236ae10493Jonathan Adams
237edfa49f<gerald.jelinek@sun.com>#
2386e1ae2aGary Pennington# Read zonecfg fs entries and save the relevant data, one entry per
239edfa49f<gerald.jelinek@sun.com># line.
240edfa49f<gerald.jelinek@sun.com># This assumes the properties from the zonecfg output, e.g.:
241edfa49f<gerald.jelinek@sun.com>#	fs:
242edfa49f<gerald.jelinek@sun.com>#		dir: /opt
243edfa49f<gerald.jelinek@sun.com>#		special: /opt
244edfa49f<gerald.jelinek@sun.com>#		raw not specified
245edfa49f<gerald.jelinek@sun.com>#		type: lofs
246edfa49f<gerald.jelinek@sun.com>#		options: [noexec,ro,noatime]
247edfa49f<gerald.jelinek@sun.com>#
2486e1ae2aGary Pennington# and it assumes the order of the fs properties as above.
249edfa49f<gerald.jelinek@sun.com>#
250edfa49f<gerald.jelinek@sun.com>get_fs_info()
251edfa49f<gerald.jelinek@sun.com>{
252edfa49f<gerald.jelinek@sun.com>	zonecfg -z $zonename info fs | nawk '{
253edfa49f<gerald.jelinek@sun.com>		if ($1 == "options:") {
254edfa49f<gerald.jelinek@sun.com>			# Remove brackets.
255edfa49f<gerald.jelinek@sun.com>			options=substr($2, 2, length($2) - 2);
256edfa49f<gerald.jelinek@sun.com>			printf("%s %s %s %s\n", dir, type, special, options);
257edfa49f<gerald.jelinek@sun.com>		} else if ($1 == "dir:") {
258edfa49f<gerald.jelinek@sun.com>			dir=$2;
259edfa49f<gerald.jelinek@sun.com>		} else if ($1 == "special:") {
260edfa49f<gerald.jelinek@sun.com>			special=$2;
261edfa49f<gerald.jelinek@sun.com>		} else if ($1 == "type:") {
262edfa49f<gerald.jelinek@sun.com>			type=$2
263edfa49f<gerald.jelinek@sun.com>		}
264edfa49f<gerald.jelinek@sun.com>	}' >> $fstmpfile
265edfa49f<gerald.jelinek@sun.com>}
266edfa49f<gerald.jelinek@sun.com>
267edfa49f<gerald.jelinek@sun.com>#
268edfa49f<gerald.jelinek@sun.com># Mount zonecfg fs entries into the zonepath.
269edfa49f<gerald.jelinek@sun.com>#
270edfa49f<gerald.jelinek@sun.com>mnt_fs()
271edfa49f<gerald.jelinek@sun.com>{
272edfa49f<gerald.jelinek@sun.com>	if [ ! -s $fstmpfile ]; then
273edfa49f<gerald.jelinek@sun.com>		return;
274edfa49f<gerald.jelinek@sun.com>	fi
275edfa49f<gerald.jelinek@sun.com>
276edfa49f<gerald.jelinek@sun.com>	# Sort the fs entries so we can handle nested mounts.
277edfa49f<gerald.jelinek@sun.com>	sort $fstmpfile | nawk -v zonepath=$zonepath '{
278edfa49f<gerald.jelinek@sun.com>		if (NF == 4)
279edfa49f<gerald.jelinek@sun.com>			options="-o " $4;
280edfa49f<gerald.jelinek@sun.com>		else
281edfa49f<gerald.jelinek@sun.com>			options=""
282edfa49f<gerald.jelinek@sun.com>
283edfa49f<gerald.jelinek@sun.com>		# Create the mount point.  Ignore errors since we might have
284edfa49f<gerald.jelinek@sun.com>		# a nested mount with a pre-existing mount point.
285edfa49f<gerald.jelinek@sun.com>		cmd="/usr/bin/mkdir -p " zonepath "/root" $1 " >/dev/null 2>&1"
286edfa49f<gerald.jelinek@sun.com>		system(cmd);
287edfa49f<gerald.jelinek@sun.com>
288edfa49f<gerald.jelinek@sun.com>		cmd="/usr/sbin/mount -F " $2 " " options " " $3 " " \
289edfa49f<gerald.jelinek@sun.com>		    zonepath "/root" $1;
290edfa49f<gerald.jelinek@sun.com>		if (system(cmd) != 0) {
291edfa49f<gerald.jelinek@sun.com>			printf("command failed: %s\n", cmd);
292edfa49f<gerald.jelinek@sun.com>			exit 1;
293edfa49f<gerald.jelinek@sun.com>		}
294edfa49f<gerald.jelinek@sun.com>	}' >>$LOGFILE
295edfa49f<gerald.jelinek@sun.com>}
296edfa49f<gerald.jelinek@sun.com>
297edfa49f<gerald.jelinek@sun.com>#
298edfa49f<gerald.jelinek@sun.com># Unmount zonecfg fs entries from the zonepath.
299edfa49f<gerald.jelinek@sun.com>#
300edfa49f<gerald.jelinek@sun.com>umnt_fs()
301edfa49f<gerald.jelinek@sun.com>{
302edfa49f<gerald.jelinek@sun.com>	if [ ! -s $fstmpfile ]; then
303edfa49f<gerald.jelinek@sun.com>		return;
304edfa49f<gerald.jelinek@sun.com>	fi
305edfa49f<gerald.jelinek@sun.com>
306edfa49f<gerald.jelinek@sun.com>	# Reverse sort the fs entries so we can handle nested unmounts.
307edfa49f<gerald.jelinek@sun.com>	sort -r $fstmpfile | nawk -v zonepath=$zonepath '{
308edfa49f<gerald.jelinek@sun.com>		cmd="/usr/sbin/umount " zonepath "/root" $1
309edfa49f<gerald.jelinek@sun.com>		if (system(cmd) != 0) {
310edfa49f<gerald.jelinek@sun.com>			printf("command failed: %s\n", cmd);
311edfa49f<gerald.jelinek@sun.com>		}
312edfa49f<gerald.jelinek@sun.com>	}' >>$LOGFILE
313edfa49f<gerald.jelinek@sun.com>}
314edfa49f<gerald.jelinek@sun.com>
315e71ca95Gerald Jelinek# Find the dataset mounted on the zonepath.
316e71ca95Gerald Jelinekget_zonepath_ds() {
317e71ca95Gerald Jelinek	ZONEPATH_DS=`/usr/sbin/zfs list -H -t filesystem -o name,mountpoint | \
318e71ca95Gerald Jelinek	    /usr/bin/nawk -v zonepath=$1 '{
319e71ca95Gerald Jelinek		if ($2 == zonepath)
320e71ca95Gerald Jelinek			print $1
321e71ca95Gerald Jelinek	}'`
322e71ca95Gerald Jelinek
323e71ca95Gerald Jelinek	if [ -z "$ZONEPATH_DS" ]; then
324e71ca95Gerald Jelinek		fail_fatal "$f_no_ds"
325e71ca95Gerald Jelinek	fi
326e71ca95Gerald Jelinek}
327e71ca95Gerald Jelinek
328edfa49f<gerald.jelinek@sun.com>#
32919b7790<gerald.jelinek@sun.com># Perform validation and cleanup in the zoneroot after unpacking the archive.
330eba0099<gerald.jelinek@sun.com>#
331eba0099<gerald.jelinek@sun.com>post_unpack()
332eba0099<gerald.jelinek@sun.com>{
33319b7790<gerald.jelinek@sun.com>	#
33419b7790<gerald.jelinek@sun.com>	# Check if the image was created with a valid libc.so.1.
33519b7790<gerald.jelinek@sun.com>	#
33619b7790<gerald.jelinek@sun.com>	hwcap=`moe -v -32 $ZONEROOT/lib/libc.so.1 2>&1`
33719b7790<gerald.jelinek@sun.com>	if (( $? != 0 )); then
33819b7790<gerald.jelinek@sun.com>		vlog "$f_hwcap_info" "$hwcap"
33919b7790<gerald.jelinek@sun.com>		fail_fatal "$f_sanity_hwcap"
34019b7790<gerald.jelinek@sun.com>	fi
34119b7790<gerald.jelinek@sun.com>
342eba0099<gerald.jelinek@sun.com>	( cd "$ZONEROOT" && \
343eba0099<gerald.jelinek@sun.com>	    find . \( -type b -o -type c \) -exec rm -f "{}" \; )
344eba0099<gerald.jelinek@sun.com>}
345eba0099<gerald.jelinek@sun.com>
346eba0099<gerald.jelinek@sun.com>#
347edfa49f<gerald.jelinek@sun.com># Determine flar compression style from identification file.
348edfa49f<gerald.jelinek@sun.com>#
349edfa49f<gerald.jelinek@sun.com>get_compression()
350edfa49f<gerald.jelinek@sun.com>{
351edfa49f<gerald.jelinek@sun.com>	typeset ident=$1
352edfa49f<gerald.jelinek@sun.com>	typeset line=$(grep "^files_compressed_method=" $ident)
353edfa49f<gerald.jelinek@sun.com>
354edfa49f<gerald.jelinek@sun.com>	print ${line##*=}
355edfa49f<gerald.jelinek@sun.com>}
356edfa49f<gerald.jelinek@sun.com>
357edfa49f<gerald.jelinek@sun.com>#
358edfa49f<gerald.jelinek@sun.com># Determine flar archive style from identification file.
359edfa49f<gerald.jelinek@sun.com>#
360edfa49f<gerald.jelinek@sun.com>get_archiver()
361edfa49f<gerald.jelinek@sun.com>{
362edfa49f<gerald.jelinek@sun.com>        typeset ident=$1
363edfa49f<gerald.jelinek@sun.com>        typeset line=$(grep "^files_archived_method=" $ident)
364edfa49f<gerald.jelinek@sun.com>
365edfa49f<gerald.jelinek@sun.com>        print ${line##*=}
366edfa49f<gerald.jelinek@sun.com>}
367edfa49f<gerald.jelinek@sun.com>
368edfa49f<gerald.jelinek@sun.com>#
369edfa49f<gerald.jelinek@sun.com># Unpack flar into current directory (which should be zoneroot).  The flash
370edfa49f<gerald.jelinek@sun.com># archive is standard input.  See flash_archive(4) man page.
371edfa49f<gerald.jelinek@sun.com># 
372edfa49f<gerald.jelinek@sun.com># We can't use "flar split" since it will only unpack into a directory called
373edfa49f<gerald.jelinek@sun.com># "archive".  We need to unpack in place in order to properly handle nested
374edfa49f<gerald.jelinek@sun.com># fs mounts within the zone root.  This function does the unpacking into the
375edfa49f<gerald.jelinek@sun.com># current directory.
376edfa49f<gerald.jelinek@sun.com>#
377edfa49f<gerald.jelinek@sun.com># This code is derived from the gen_split() function in /usr/sbin/flar so
378edfa49f<gerald.jelinek@sun.com># we keep the same style as the original.
379edfa49f<gerald.jelinek@sun.com>#
380edfa49f<gerald.jelinek@sun.com>install_flar()
381edfa49f<gerald.jelinek@sun.com>{
382edfa49f<gerald.jelinek@sun.com>	typeset result
383edfa49f<gerald.jelinek@sun.com>        typeset archiver_command
384edfa49f<gerald.jelinek@sun.com>        typeset archiver_arguments
385edfa49f<gerald.jelinek@sun.com>
38674bbcaa<gerald.jelinek@sun.com>	vlog "cd $ZONEROOT && $stage1 "$insrc" | install_flar"
387edfa49f<gerald.jelinek@sun.com>
388edfa49f<gerald.jelinek@sun.com>	# Read cookie
389edfa49f<gerald.jelinek@sun.com>	read -r input_line
390edfa49f<gerald.jelinek@sun.com>	if (( $? != 0 )); then
391edfa49f<gerald.jelinek@sun.com>		log "$not_readable" "$install_media"
392edfa49f<gerald.jelinek@sun.com>		return 1
393edfa49f<gerald.jelinek@sun.com>	fi
394edfa49f<gerald.jelinek@sun.com>	# The cookie has format FlAsH-aRcHiVe-m.n where m and n are integers.
395edfa49f<gerald.jelinek@sun.com>	if [[ ${input_line%%-[0-9]*.[0-9]*} != "FlAsH-aRcHiVe" ]]; then
396edfa49f<gerald.jelinek@sun.com>		log "$not_flar"
397edfa49f<gerald.jelinek@sun.com>		return 1
398edfa49f<gerald.jelinek@sun.com>	fi
399edfa49f<gerald.jelinek@sun.com>
400edfa49f<gerald.jelinek@sun.com>	while [ true ]
401edfa49f<gerald.jelinek@sun.com>	do
402edfa49f<gerald.jelinek@sun.com>		# We should always be at the start of a section here
403edfa49f<gerald.jelinek@sun.com>		read -r input_line
404edfa49f<gerald.jelinek@sun.com>		if [[ ${input_line%%=*} != "section_begin" ]]; then
405edfa49f<gerald.jelinek@sun.com>			log "$bad_flar"
406edfa49f<gerald.jelinek@sun.com>			return 1
407edfa49f<gerald.jelinek@sun.com>		fi
408edfa49f<gerald.jelinek@sun.com>		section_name=${input_line##*=}
409edfa49f<gerald.jelinek@sun.com>
410edfa49f<gerald.jelinek@sun.com>		# If we're at the archive, we're done skipping sections.
411edfa49f<gerald.jelinek@sun.com>		if [[ "$section_name" == "archive" ]]; then
412edfa49f<gerald.jelinek@sun.com>			break
413edfa49f<gerald.jelinek@sun.com>		fi
414edfa49f<gerald.jelinek@sun.com>		
415edfa49f<gerald.jelinek@sun.com>		#
416edfa49f<gerald.jelinek@sun.com>		# Save identification section to a file so we can determine
417edfa49f<gerald.jelinek@sun.com>		# how to unpack the archive.
418edfa49f<gerald.jelinek@sun.com>		#
419edfa49f<gerald.jelinek@sun.com>		if [[ "$section_name" == "identification" ]]; then
420edfa49f<gerald.jelinek@sun.com>			/usr/bin/rm -f identification
421edfa49f<gerald.jelinek@sun.com>			while read -r input_line
422edfa49f<gerald.jelinek@sun.com>			do
423edfa49f<gerald.jelinek@sun.com>				if [[ ${input_line%%=*} == \
424edfa49f<gerald.jelinek@sun.com>				    "section_begin" ]]; then
425edfa49f<gerald.jelinek@sun.com>					/usr/bin/rm -f identification
426edfa49f<gerald.jelinek@sun.com>					log "$bad_flar"
427edfa49f<gerald.jelinek@sun.com>					return 1
428edfa49f<gerald.jelinek@sun.com>				fi
429edfa49f<gerald.jelinek@sun.com>
430edfa49f<gerald.jelinek@sun.com>				if [[ $input_line == \
431edfa49f<gerald.jelinek@sun.com>				    "section_end=$section_name" ]]; then
432edfa49f<gerald.jelinek@sun.com>					break;
433edfa49f<gerald.jelinek@sun.com>				fi
434edfa49f<gerald.jelinek@sun.com>				echo $input_line >> identification
435edfa49f<gerald.jelinek@sun.com>			done
436edfa49f<gerald.jelinek@sun.com>
437edfa49f<gerald.jelinek@sun.com>			continue
438edfa49f<gerald.jelinek@sun.com>		fi
439edfa49f<gerald.jelinek@sun.com>
440edfa49f<gerald.jelinek@sun.com>		#
441edfa49f<gerald.jelinek@sun.com>		# Otherwise skip past this section; read lines until detecting
442edfa49f<gerald.jelinek@sun.com>		# section_end.  According to flash_archive(4) we can have
443edfa49f<gerald.jelinek@sun.com>		# an arbitrary number of sections but the archive section
444edfa49f<gerald.jelinek@sun.com>		# must be last.
445edfa49f<gerald.jelinek@sun.com>		#
446edfa49f<gerald.jelinek@sun.com>		success=0
447edfa49f<gerald.jelinek@sun.com>		while read -r input_line
448edfa49f<gerald.jelinek@sun.com>		do
449edfa49f<gerald.jelinek@sun.com>			if [[ $input_line == "section_end=$section_name" ]];
450edfa49f<gerald.jelinek@sun.com>			then
451edfa49f<gerald.jelinek@sun.com>				success=1
452edfa49f<gerald.jelinek@sun.com>				break
453edfa49f<gerald.jelinek@sun.com>			fi
454edfa49f<gerald.jelinek@sun.com>			# Fail if we miss the end of the section
455edfa49f<gerald.jelinek@sun.com>			if [[ ${input_line%%=*} == "section_begin" ]]; then
456edfa49f<gerald.jelinek@sun.com>				/usr/bin/rm -f identification
457edfa49f<gerald.jelinek@sun.com>				log "$bad_flar"
458edfa49f<gerald.jelinek@sun.com>				return 1
459edfa49f<gerald.jelinek@sun.com>			fi
460edfa49f<gerald.jelinek@sun.com>		done
461edfa49f<gerald.jelinek@sun.com>		if (( $success == 0 )); then
462edfa49f<gerald.jelinek@sun.com>			#
463edfa49f<gerald.jelinek@sun.com>			# If we get here we read to the end of the file before
464edfa49f<gerald.jelinek@sun.com>			# seeing the end of the section we were reading.
465edfa49f<gerald.jelinek@sun.com>			#
466edfa49f<gerald.jelinek@sun.com>			/usr/bin/rm -f identification
467edfa49f<gerald.jelinek@sun.com>			log "$bad_flar"
468edfa49f<gerald.jelinek@sun.com>			return 1
469edfa49f<gerald.jelinek@sun.com>		fi
470edfa49f<gerald.jelinek@sun.com>	done
471edfa49f<gerald.jelinek@sun.com>
472cec6066<gerald.jelinek@sun.com>	# Check for an archive made from a ZFS root pool.
473cec6066<gerald.jelinek@sun.com>	egrep -s "^rootpool=" identification
474cec6066<gerald.jelinek@sun.com>        if (( $? == 0 )); then
475cec6066<gerald.jelinek@sun.com>		/usr/bin/rm -f identification
476cec6066<gerald.jelinek@sun.com>                log "$bad_zfs_flar"
477cec6066<gerald.jelinek@sun.com>                return 1
478cec6066<gerald.jelinek@sun.com>        fi
479cec6066<gerald.jelinek@sun.com>
480edfa49f<gerald.jelinek@sun.com>	# Get the information needed to unpack the archive.
481edfa49f<gerald.jelinek@sun.com>	archiver=$(get_archiver identification)
482edfa49f<gerald.jelinek@sun.com>	if [[ $archiver == "pax" ]]; then
483edfa49f<gerald.jelinek@sun.com>		# pax archiver specified
484edfa49f<gerald.jelinek@sun.com>		archiver_command="/usr/bin/pax"
4856e1ae2aGary Pennington		if [[ -s $fspaxfile ]]; then
486edfa49f<gerald.jelinek@sun.com>			archiver_arguments="-r -p e -c \
4876e1ae2aGary Pennington			    $(/usr/bin/cat $fspaxfile)"
488edfa49f<gerald.jelinek@sun.com>		else
489edfa49f<gerald.jelinek@sun.com>			archiver_arguments="-r -p e"
490edfa49f<gerald.jelinek@sun.com>		fi
491edfa49f<gerald.jelinek@sun.com>	elif [[ $archiver == "cpio" || -z $archiver ]]; then
492edfa49f<gerald.jelinek@sun.com>		# cpio archived specified OR no archiver specified - use default
493edfa49f<gerald.jelinek@sun.com>		archiver_command="/usr/bin/cpio"
4946e1ae2aGary Pennington		archiver_arguments="-icdumfE $fscpiofile"
495edfa49f<gerald.jelinek@sun.com>	else
496edfa49f<gerald.jelinek@sun.com>		# unknown archiver specified
497edfa49f<gerald.jelinek@sun.com>		log "$unknown_archiver" $archiver
498edfa49f<gerald.jelinek@sun.com>		return 1
499edfa49f<gerald.jelinek@sun.com>	fi
500edfa49f<gerald.jelinek@sun.com>
501edfa49f<gerald.jelinek@sun.com>	if [[ ! -x $archiver_command ]]; then
502edfa49f<gerald.jelinek@sun.com>		/usr/bin/rm -f identification
503edfa49f<gerald.jelinek@sun.com>		log "$cmd_not_exec" $archiver_command
504edfa49f<gerald.jelinek@sun.com>		return 1
505edfa49f<gerald.jelinek@sun.com>	fi 
506edfa49f<gerald.jelinek@sun.com>
507edfa49f<gerald.jelinek@sun.com>	compression=$(get_compression identification)
508edfa49f<gerald.jelinek@sun.com>
509edfa49f<gerald.jelinek@sun.com>	# We're done with the identification file
510edfa49f<gerald.jelinek@sun.com>	/usr/bin/rm -f identification
511edfa49f<gerald.jelinek@sun.com>
512edfa49f<gerald.jelinek@sun.com>	# Extract archive
513edfa49f<gerald.jelinek@sun.com>	if [[ $compression == "compress" ]]; then
514eba0099<gerald.jelinek@sun.com>		/usr/bin/zcat | \
515edfa49f<gerald.jelinek@sun.com>		    $archiver_command $archiver_arguments 2>/dev/null
516edfa49f<gerald.jelinek@sun.com>	else
517eba0099<gerald.jelinek@sun.com>		$archiver_command $archiver_arguments 2>/dev/null
518edfa49f<gerald.jelinek@sun.com>	fi
519edfa49f<gerald.jelinek@sun.com>	result=$?
520edfa49f<gerald.jelinek@sun.com>
521eba0099<gerald.jelinek@sun.com>	post_unpack
522eba0099<gerald.jelinek@sun.com>
523edfa49f<gerald.jelinek@sun.com>	(( $result != 0 )) && return 1
524edfa49f<gerald.jelinek@sun.com>
525edfa49f<gerald.jelinek@sun.com>	return 0 
526edfa49f<gerald.jelinek@sun.com>}
527edfa49f<gerald.jelinek@sun.com>
528edfa49f<gerald.jelinek@sun.com>#
5298c20418Gerald Jelinek# Get the archive base.
5308c20418Gerald Jelinek#
5318c20418Gerald Jelinek# We must unpack the archive in the right place within the zonepath so
5328c20418Gerald Jelinek# that files are installed into the various mounted filesystems that are set
5338c20418Gerald Jelinek# up in the zone's configuration.  These are already mounted for us by the
5348c20418Gerald Jelinek# mntfs function.
5358c20418Gerald Jelinek#
5368c20418Gerald Jelinek# Archives can be made of either a physical host's root file system or a
5378c20418Gerald Jelinek# zone's zonepath.  For a physical system, if the archive is made using an
5388c20418Gerald Jelinek# absolute path (/...) we can't use it.  For a zone the admin can make the
5398c20418Gerald Jelinek# archive from a variety of locations;
5408c20418Gerald Jelinek#
5418c20418Gerald Jelinek#   a) zonepath itself: This will be a single dir, probably named with the
5428c20418Gerald Jelinek#      zone name, it will contain a root dir and under the root we'll see all
5438c20418Gerald Jelinek#      the top level dirs; etc, var, usr...  We must be above the ZONEPATH
5448c20418Gerald Jelinek#      when we unpack the archive but this will only work if the the archive's
5458c20418Gerald Jelinek#      top-level dir name matches the ZONEPATH base-level dir name.  If not,
5468c20418Gerald Jelinek#      this is an error.
5478c20418Gerald Jelinek#
5488c20418Gerald Jelinek#   b) inside the zonepath: We'll see root and it will contain all the top
5498c20418Gerald Jelinek#      level dirs; etc, var, usr....  We must be in the ZONEPATH when we unpack
5508c20418Gerald Jelinek#      the archive.
5518c20418Gerald Jelinek#
5528c20418Gerald Jelinek#   c) inside the zonepath root: We'll see all the top level dirs, ./etc,
5538c20418Gerald Jelinek#      ./var, ./usr....  This is also the case we see when we get an archive
554d0b12b6Toomas Soome#      of a physical system.  We must be in ZONEROOT when we unpack the archive.
5558c20418Gerald Jelinek#
5568c20418Gerald Jelinek# Note that there can be a directory named "root" under the ZONEPATH/root
5578c20418Gerald Jelinek# directory.
5588c20418Gerald Jelinek#
5598c20418Gerald Jelinek# This function handles the above possibilities so that we reject absolute
5608c20418Gerald Jelinek# path archives and figure out where in the file system we need to be to
5618c20418Gerald Jelinek# properly unpack the archive into the zone.  It sets the ARCHIVE_BASE
5628c20418Gerald Jelinek# variable to the location where the achive should be unpacked.
5638c20418Gerald Jelinek#
5648c20418Gerald Jelinekget_archive_base()
5658c20418Gerald Jelinek{
5668c20418Gerald Jelinek	stage1=$1
5678c20418Gerald Jelinek	archive=$2
5688c20418Gerald Jelinek	stage2=$3
5698c20418Gerald Jelinek
5708c20418Gerald Jelinek	vlog "$m_analyse_archive"
5718c20418Gerald Jelinek
5728c20418Gerald Jelinek	base=`$stage1 $archive | $stage2 2>/dev/null | nawk -F/ '{
5738c20418Gerald Jelinek		# Check for an absolute path archive
5748c20418Gerald Jelinek		if (substr($0, 1, 1) == "/")
5758c20418Gerald Jelinek			exit 1
5768c20418Gerald Jelinek
5778c20418Gerald Jelinek		if ($1 != ".")
5788c20418Gerald Jelinek			dirs[$1] = 1
5798c20418Gerald Jelinek		else
5808c20418Gerald Jelinek			dirs[$2] = 1
5818c20418Gerald Jelinek	}
5828c20418Gerald Jelinek	END {
5838c20418Gerald Jelinek		for (d in dirs) {
5848c20418Gerald Jelinek			cnt++
5858c20418Gerald Jelinek			if (d == "bin")  sawbin = 1
5868c20418Gerald Jelinek			if (d == "etc")  sawetc = 1
5878c20418Gerald Jelinek			if (d == "root") sawroot = 1
5888c20418Gerald Jelinek			if (d == "var")  sawvar = 1
5898c20418Gerald Jelinek                }
5908c20418Gerald Jelinek
5918c20418Gerald Jelinek		if (cnt == 1) {
5928c20418Gerald Jelinek			# If only one top-level dir named root, we are in the
5938c20418Gerald Jelinek			# zonepath, otherwise this must be an archive *of*
5948c20418Gerald Jelinek			# the zonepath so print the top-level dir name.
5958c20418Gerald Jelinek			if (sawroot)
5968c20418Gerald Jelinek				print "*zonepath*"
5978c20418Gerald Jelinek			else
5988c20418Gerald Jelinek				for (d in dirs) print d
5998c20418Gerald Jelinek		} else {
6008c20418Gerald Jelinek			# We are either in the zonepath or in the zonepath/root
6018c20418Gerald Jelinek			# (or at the top level of a full system archive which
6028c20418Gerald Jelinek			# looks like the zonepath/root case).  Figure out which
6038c20418Gerald Jelinek			# one.
6048c20418Gerald Jelinek			if (sawroot && !sawbin && !sawetc && !sawvar)
6058c20418Gerald Jelinek				print "*zonepath*"
6068c20418Gerald Jelinek			else
6078c20418Gerald Jelinek				print "*zoneroot*"
6088c20418Gerald Jelinek		}
6098c20418Gerald Jelinek	}'`
6108c20418Gerald Jelinek
6118c20418Gerald Jelinek	if (( $? != 0 )); then
6128c20418Gerald Jelinek		umnt_fs
6138c20418Gerald Jelinek		fatal "$e_absolute_archive"
6148c20418Gerald Jelinek	fi
6158c20418Gerald Jelinek
6168c20418Gerald Jelinek	if [[ "$base" == "*zoneroot*" ]]; then
6178c20418Gerald Jelinek		ARCHIVE_BASE=$ZONEROOT
6188c20418Gerald Jelinek	elif [[ "$base" == "*zonepath*" ]]; then
6198c20418Gerald Jelinek		ARCHIVE_BASE=$ZONEPATH
6208c20418Gerald Jelinek	else
6218c20418Gerald Jelinek		# We need to be in the dir above the ZONEPATH but we need to
6228c20418Gerald Jelinek		# validate that $base matches the final component of ZONEPATH.
6238c20418Gerald Jelinek		bname=`basename $ZONEPATH`
6248c20418Gerald Jelinek
6258c20418Gerald Jelinek		if [[ "$bname" != "$base" ]]; then
6268c20418Gerald Jelinek			umnt_fs
6278c20418Gerald Jelinek			fatal "$e_mismatch_archive" "$base" "$bname"
6288c20418Gerald Jelinek		fi
6298c20418Gerald Jelinek		ARCHIVE_BASE=`dirname $ZONEPATH`
6308c20418Gerald Jelinek	fi
6318c20418Gerald Jelinek}
6328c20418Gerald Jelinek
6338c20418Gerald Jelinek#
634edfa49f<gerald.jelinek@sun.com># Unpack cpio archive into zoneroot.
635edfa49f<gerald.jelinek@sun.com>#
636edfa49f<gerald.jelinek@sun.com>install_cpio()
637edfa49f<gerald.jelinek@sun.com>{
638edfa49f<gerald.jelinek@sun.com>	stage1=$1
639edfa49f<gerald.jelinek@sun.com>	archive=$2
640edfa49f<gerald.jelinek@sun.com>
6418c20418Gerald Jelinek	get_archive_base "$stage1" "$archive" "cpio -it"
64262ac533<gerald.jelinek@sun.com>
6436e1ae2aGary Pennington	cpioopts="-idmfE $fscpiofile"
644edfa49f<gerald.jelinek@sun.com>
6458c20418Gerald Jelinek	vlog "cd \"$ARCHIVE_BASE\" && $stage1 \"$archive\" | cpio $cpioopts"
646eba0099<gerald.jelinek@sun.com>
647cec6066<gerald.jelinek@sun.com>	# Ignore errors from cpio since we expect some errors depending on
648cec6066<gerald.jelinek@sun.com>	# how the archive was made.
6498c20418Gerald Jelinek	( cd "$ARCHIVE_BASE" && $stage1 "$archive" | cpio $cpioopts )
650eba0099<gerald.jelinek@sun.com>
651eba0099<gerald.jelinek@sun.com>	post_unpack
652edfa49f<gerald.jelinek@sun.com>
653cec6066<gerald.jelinek@sun.com>	return 0
654edfa49f<gerald.jelinek@sun.com>}
655edfa49f<gerald.jelinek@sun.com>
656edfa49f<gerald.jelinek@sun.com>#
657edfa49f<gerald.jelinek@sun.com># Unpack pax archive into zoneroot.
658edfa49f<gerald.jelinek@sun.com>#
659edfa49f<gerald.jelinek@sun.com>install_pax()
660edfa49f<gerald.jelinek@sun.com>{
661edfa49f<gerald.jelinek@sun.com>	archive=$1
662edfa49f<gerald.jelinek@sun.com>
6638c20418Gerald Jelinek	get_archive_base "cat" "$archive" "pax"
66462ac533<gerald.jelinek@sun.com>
6656e1ae2aGary Pennington	if [[ -s $fspaxfile ]]; then
6666e1ae2aGary Pennington		filtopt="-c $(/usr/bin/cat $fspaxfile)"
667edfa49f<gerald.jelinek@sun.com>	fi
668edfa49f<gerald.jelinek@sun.com>
6698c20418Gerald Jelinek	vlog "cd \"$ARCHIVE_BASE\" && pax -r -f \"$archive\" $filtopt"
670edfa49f<gerald.jelinek@sun.com>
671cec6066<gerald.jelinek@sun.com>	# Ignore errors from pax since we expect some errors depending on
672cec6066<gerald.jelinek@sun.com>	# how the archive was made.
6738c20418Gerald Jelinek	( cd "$ARCHIVE_BASE" && pax -r -f "$archive" $filtopt )
674eba0099<gerald.jelinek@sun.com>
675eba0099<gerald.jelinek@sun.com>	post_unpack
676eba0099<gerald.jelinek@sun.com>
677cec6066<gerald.jelinek@sun.com>	return 0
678edfa49f<gerald.jelinek@sun.com>}
679edfa49f<gerald.jelinek@sun.com>
680edfa49f<gerald.jelinek@sun.com>#
681edfa49f<gerald.jelinek@sun.com># Unpack UFS dump into zoneroot.
682edfa49f<gerald.jelinek@sun.com>#
683edfa49f<gerald.jelinek@sun.com>install_ufsdump()
684edfa49f<gerald.jelinek@sun.com>{
685edfa49f<gerald.jelinek@sun.com>	archive=$1
686edfa49f<gerald.jelinek@sun.com>
687eba0099<gerald.jelinek@sun.com>	vlog "cd \"$ZONEROOT\" && ufsrestore rf \"$archive\""
688edfa49f<gerald.jelinek@sun.com>
689edfa49f<gerald.jelinek@sun.com>	#
690edfa49f<gerald.jelinek@sun.com>	# ufsrestore goes interactive if you ^C it.  To prevent that,
691edfa49f<gerald.jelinek@sun.com>	# we make sure its stdin is not a terminal.
692edfa49f<gerald.jelinek@sun.com>	#
693eba0099<gerald.jelinek@sun.com>	( cd "$ZONEROOT" && ufsrestore rf "$archive" < /dev/null )
694eba0099<gerald.jelinek@sun.com>	result=$?
695eba0099<gerald.jelinek@sun.com>
696eba0099<gerald.jelinek@sun.com>	post_unpack
697eba0099<gerald.jelinek@sun.com>
698eba0099<gerald.jelinek@sun.com>	return $result
699edfa49f<gerald.jelinek@sun.com>}
700edfa49f<gerald.jelinek@sun.com>
701edfa49f<gerald.jelinek@sun.com>#
702edfa49f<gerald.jelinek@sun.com># Copy directory hierarchy into zoneroot.
703edfa49f<gerald.jelinek@sun.com>#
704edfa49f<gerald.jelinek@sun.com>install_dir()
705edfa49f<gerald.jelinek@sun.com>{
706edfa49f<gerald.jelinek@sun.com>	source_dir=$1
707edfa49f<gerald.jelinek@sun.com>
708edfa49f<gerald.jelinek@sun.com>	cpioopts="-pdm"
709edfa49f<gerald.jelinek@sun.com>
710edfa49f<gerald.jelinek@sun.com>	first=1
7116e1ae2aGary Pennington	filt=$(for i in $(cat $fspaxfile)
712edfa49f<gerald.jelinek@sun.com>		do
713edfa49f<gerald.jelinek@sun.com>			echo $i | egrep -s "/" && continue
714edfa49f<gerald.jelinek@sun.com>			if [[ $first == 1 ]]; then
715edfa49f<gerald.jelinek@sun.com>				printf "^%s" $i
716edfa49f<gerald.jelinek@sun.com>				first=0
717edfa49f<gerald.jelinek@sun.com>			else
718edfa49f<gerald.jelinek@sun.com>				printf "|^%s" $i
719edfa49f<gerald.jelinek@sun.com>			fi
720edfa49f<gerald.jelinek@sun.com>		done)
721edfa49f<gerald.jelinek@sun.com>
722edfa49f<gerald.jelinek@sun.com>	list=$(cd "$source_dir" && ls -d * | egrep -v "$filt")
723edfa49f<gerald.jelinek@sun.com>	flist=$(for i in $list
724edfa49f<gerald.jelinek@sun.com>	do
725edfa49f<gerald.jelinek@sun.com>		printf "%s " "$i"
726edfa49f<gerald.jelinek@sun.com>	done)
727edfa49f<gerald.jelinek@sun.com>	findopts="-xdev ( -type d -o -type f -o -type l ) -print"
728edfa49f<gerald.jelinek@sun.com>
729edfa49f<gerald.jelinek@sun.com>	vlog "cd \"$source_dir\" && find $flist $findopts | "
730eba0099<gerald.jelinek@sun.com>	vlog "cpio $cpioopts \"$ZONEROOT\""
731edfa49f<gerald.jelinek@sun.com>
732cec6066<gerald.jelinek@sun.com>	# Ignore errors from cpio since we expect some errors depending on
733cec6066<gerald.jelinek@sun.com>	# how the archive was made.
734edfa49f<gerald.jelinek@sun.com>	( cd "$source_dir" && find $flist $findopts | \
735eba0099<gerald.jelinek@sun.com>	    cpio $cpioopts "$ZONEROOT" )
736eba0099<gerald.jelinek@sun.com>
737eba0099<gerald.jelinek@sun.com>	post_unpack
738eba0099<gerald.jelinek@sun.com>
739cec6066<gerald.jelinek@sun.com>	return 0
740edfa49f<gerald.jelinek@sun.com>}
741edfa49f<gerald.jelinek@sun.com>
74274bbcaa<gerald.jelinek@sun.com>#
74374bbcaa<gerald.jelinek@sun.com># This is a common function for laying down a zone image from a variety of
74474bbcaa<gerald.jelinek@sun.com># different sources.  This can be used to either install a fresh zone or as
74574bbcaa<gerald.jelinek@sun.com># part of zone migration during attach.
74674bbcaa<gerald.jelinek@sun.com>#
74774bbcaa<gerald.jelinek@sun.com># The first argument specifies the type of image: archive, directory or stdin.
74874bbcaa<gerald.jelinek@sun.com># The second argument specifies the image itself.  In the case of stdin, the
74974bbcaa<gerald.jelinek@sun.com># second argument specifies the format of the stream (cpio, flar, etc.).
75074bbcaa<gerald.jelinek@sun.com># Any validation or post-processing on the image is done elsewhere.
75174bbcaa<gerald.jelinek@sun.com>#
75274bbcaa<gerald.jelinek@sun.com># This function calls a 'sanity_check' function which must be provided by
75374bbcaa<gerald.jelinek@sun.com># the script which includes this code.
75474bbcaa<gerald.jelinek@sun.com>#
75574bbcaa<gerald.jelinek@sun.com>install_image()
75674bbcaa<gerald.jelinek@sun.com>{
75774bbcaa<gerald.jelinek@sun.com>	intype=$1
75874bbcaa<gerald.jelinek@sun.com>	insrc=$2
75974bbcaa<gerald.jelinek@sun.com>
76074bbcaa<gerald.jelinek@sun.com>	if [[ -z "$intype" || -z "$insrc" ]]; then
76174bbcaa<gerald.jelinek@sun.com>		return 1
76274bbcaa<gerald.jelinek@sun.com>	fi
76374bbcaa<gerald.jelinek@sun.com>
76474bbcaa<gerald.jelinek@sun.com>	filetype="unknown"
76574bbcaa<gerald.jelinek@sun.com>	filetypename="unknown"
76674bbcaa<gerald.jelinek@sun.com>	stage1="cat"
76774bbcaa<gerald.jelinek@sun.com>
76874bbcaa<gerald.jelinek@sun.com>	if [[ "$intype" == "directory" ]]; then
76974bbcaa<gerald.jelinek@sun.com>		if [[ "$insrc" == "-" ]]; then
77074bbcaa<gerald.jelinek@sun.com>			# Indicates that the existing zonepath is prepopulated.
77174bbcaa<gerald.jelinek@sun.com>			filetype="existing"
77274bbcaa<gerald.jelinek@sun.com>			filetypename="existing"
77374bbcaa<gerald.jelinek@sun.com>		else
77474bbcaa<gerald.jelinek@sun.com>			if [[ "$(echo $insrc | cut -c 1)" != "/" ]]; then
77574bbcaa<gerald.jelinek@sun.com>				fatal "$e_path_abs" "$insrc"
77674bbcaa<gerald.jelinek@sun.com>			fi
77774bbcaa<gerald.jelinek@sun.com>
77874bbcaa<gerald.jelinek@sun.com>			if [[ ! -e "$insrc" ]]; then
77974bbcaa<gerald.jelinek@sun.com>				log "$e_not_found" "$insrc"
78074bbcaa<gerald.jelinek@sun.com>				fatal "$e_install_abort"
78174bbcaa<gerald.jelinek@sun.com>			fi
78274bbcaa<gerald.jelinek@sun.com>
78374bbcaa<gerald.jelinek@sun.com>			if [[ ! -r "$insrc" ]]; then
78474bbcaa<gerald.jelinek@sun.com>				log "$e_not_readable" "$insrc"
78574bbcaa<gerald.jelinek@sun.com>				fatal "$e_install_abort"
78674bbcaa<gerald.jelinek@sun.com>			fi
78774bbcaa<gerald.jelinek@sun.com>
78874bbcaa<gerald.jelinek@sun.com>			if [[ ! -d "$insrc" ]]; then
78974bbcaa<gerald.jelinek@sun.com>				log "$e_not_dir"
79074bbcaa<gerald.jelinek@sun.com>				fatal "$e_install_abort"
79174bbcaa<gerald.jelinek@sun.com>			fi
79274bbcaa<gerald.jelinek@sun.com>
79374bbcaa<gerald.jelinek@sun.com>			sanity_check $insrc
79474bbcaa<gerald.jelinek@sun.com>
79574bbcaa<gerald.jelinek@sun.com>			filetype="directory"
79674bbcaa<gerald.jelinek@sun.com>			filetypename="directory"
79774bbcaa<gerald.jelinek@sun.com>		fi
79874bbcaa<gerald.jelinek@sun.com>
79974bbcaa<gerald.jelinek@sun.com>	else
80074bbcaa<gerald.jelinek@sun.com>		# Common code for both archive and stdin stream.
80174bbcaa<gerald.jelinek@sun.com>
80274bbcaa<gerald.jelinek@sun.com>		if [[ "$intype" == "archive" ]]; then
80374bbcaa<gerald.jelinek@sun.com>			if [[ ! -f "$insrc" ]]; then
80474bbcaa<gerald.jelinek@sun.com>				log "$e_unknown_archive"
80574bbcaa<gerald.jelinek@sun.com>				fatal "$e_install_abort"
80674bbcaa<gerald.jelinek@sun.com>			fi
80774bbcaa<gerald.jelinek@sun.com>			ftype="$(LC_ALL=C file $insrc | cut -d: -f 2)"
80874bbcaa<gerald.jelinek@sun.com>		else
80974bbcaa<gerald.jelinek@sun.com>			# For intype == stdin, the insrc parameter specifies
81074bbcaa<gerald.jelinek@sun.com>			# the stream format coming on stdin.
81174bbcaa<gerald.jelinek@sun.com>			ftype="$insrc"
81274bbcaa<gerald.jelinek@sun.com>			insrc="-"
81374bbcaa<gerald.jelinek@sun.com>		fi
81474bbcaa<gerald.jelinek@sun.com>
81574bbcaa<gerald.jelinek@sun.com>		# Setup vars for the archive type we have.
81674bbcaa<gerald.jelinek@sun.com>		case "$ftype" in
81774bbcaa<gerald.jelinek@sun.com>		*cpio*)		filetype="cpio"
81874bbcaa<gerald.jelinek@sun.com>				filetypename="cpio archive"
81974bbcaa<gerald.jelinek@sun.com>			;;
82074bbcaa<gerald.jelinek@sun.com>		*bzip2*)	filetype="bzip2"
82174bbcaa<gerald.jelinek@sun.com>				filetypename="bzipped cpio archive"
82274bbcaa<gerald.jelinek@sun.com>			;;
82374bbcaa<gerald.jelinek@sun.com>		*gzip*)		filetype="gzip"
82474bbcaa<gerald.jelinek@sun.com>				filetypename="gzipped cpio archive"
82574bbcaa<gerald.jelinek@sun.com>			;;
82674bbcaa<gerald.jelinek@sun.com>		*ufsdump*)	filetype="ufsdump"
82774bbcaa<gerald.jelinek@sun.com>				filetypename="ufsdump archive"
82874bbcaa<gerald.jelinek@sun.com>			;;
82974bbcaa<gerald.jelinek@sun.com>		"flar")
83074bbcaa<gerald.jelinek@sun.com>				filetype="flar"
83174bbcaa<gerald.jelinek@sun.com>				filetypename="flash archive"
83274bbcaa<gerald.jelinek@sun.com>			;;
83374bbcaa<gerald.jelinek@sun.com>		"flash")
83474bbcaa<gerald.jelinek@sun.com>				filetype="flar"
83574bbcaa<gerald.jelinek@sun.com>				filetypename="flash archive"
83674bbcaa<gerald.jelinek@sun.com>			;;
83774bbcaa<gerald.jelinek@sun.com>		*Flash\ Archive*)
83874bbcaa<gerald.jelinek@sun.com>				filetype="flar"
83974bbcaa<gerald.jelinek@sun.com>				filetypename="flash archive"
84074bbcaa<gerald.jelinek@sun.com>			;;
84174bbcaa<gerald.jelinek@sun.com>		"tar")
84274bbcaa<gerald.jelinek@sun.com>				filetype="tar"
84374bbcaa<gerald.jelinek@sun.com>				filetypename="tar archive"
84474bbcaa<gerald.jelinek@sun.com>			;;
84574bbcaa<gerald.jelinek@sun.com>		*USTAR\ tar\ archive)
84674bbcaa<gerald.jelinek@sun.com>				filetype="tar"
84774bbcaa<gerald.jelinek@sun.com>				filetypename="tar archive"
84874bbcaa<gerald.jelinek@sun.com>			;;
84974bbcaa<gerald.jelinek@sun.com>		"pax")
85074bbcaa<gerald.jelinek@sun.com>				filetype="xustar"
85174bbcaa<gerald.jelinek@sun.com>				filetypename="pax (xustar) archive"
85274bbcaa<gerald.jelinek@sun.com>			;;
85374bbcaa<gerald.jelinek@sun.com>		*USTAR\ tar\ archive\ extended\ format*)
85474bbcaa<gerald.jelinek@sun.com>				filetype="xustar"
85574bbcaa<gerald.jelinek@sun.com>				filetypename="pax (xustar) archive"
85674bbcaa<gerald.jelinek@sun.com>			;;
85774bbcaa<gerald.jelinek@sun.com>		"zfs")
85874bbcaa<gerald.jelinek@sun.com>				filetype="zfs"
85974bbcaa<gerald.jelinek@sun.com>				filetypename="ZFS send stream"
86074bbcaa<gerald.jelinek@sun.com>			;;
86174bbcaa<gerald.jelinek@sun.com>		*ZFS\ snapshot\ stream*)
86274bbcaa<gerald.jelinek@sun.com>				filetype="zfs"
86374bbcaa<gerald.jelinek@sun.com>				filetypename="ZFS send stream"
86474bbcaa<gerald.jelinek@sun.com>			;;
86574bbcaa<gerald.jelinek@sun.com>		*)		log "$e_unknown_archive"
86674bbcaa<gerald.jelinek@sun.com>				fatal "$e_install_abort"
86774bbcaa<gerald.jelinek@sun.com>			;;
86874bbcaa<gerald.jelinek@sun.com>		esac
86974bbcaa<gerald.jelinek@sun.com>	fi
87074bbcaa<gerald.jelinek@sun.com>
87174bbcaa<gerald.jelinek@sun.com>	vlog "$filetypename"
87274bbcaa<gerald.jelinek@sun.com>
87374bbcaa<gerald.jelinek@sun.com>	# Check for a non-empty root if no '-d -' option. 
87474bbcaa<gerald.jelinek@sun.com>	if [[ "$filetype" != "existing" ]]; then
87574bbcaa<gerald.jelinek@sun.com>		cnt=$(ls $ZONEROOT | wc -l)
87674bbcaa<gerald.jelinek@sun.com>		if (( $cnt != 0 )); then
87774bbcaa<gerald.jelinek@sun.com>			fatal "$e_root_full" "$ZONEROOT"
87874bbcaa<gerald.jelinek@sun.com>		fi
87974bbcaa<gerald.jelinek@sun.com>	fi
88074bbcaa<gerald.jelinek@sun.com>
88174bbcaa<gerald.jelinek@sun.com>	fstmpfile=$(/usr/bin/mktemp -t -p /var/tmp)
88274bbcaa<gerald.jelinek@sun.com>	if [[ -z "$fstmpfile" ]]; then
88374bbcaa<gerald.jelinek@sun.com>		fatal "$e_tmpfile"
88474bbcaa<gerald.jelinek@sun.com>	fi
88574bbcaa<gerald.jelinek@sun.com>
88674bbcaa<gerald.jelinek@sun.com>	# Make sure we always have the files holding the directories to filter
88774bbcaa<gerald.jelinek@sun.com>	# out when extracting from a CPIO or PAX archive.  We'll add the fs
8886e1ae2aGary Pennington	# entries to these files in get_fs_info()
8896e1ae2aGary Pennington	fscpiofile=$(/usr/bin/mktemp -t -p /var/tmp fs.cpio.XXXXXX)
8906e1ae2aGary Pennington	if [[ -z "$fscpiofile" ]]; then
89174bbcaa<gerald.jelinek@sun.com>		rm -f $fstmpfile
89274bbcaa<gerald.jelinek@sun.com>		fatal "$e_tmpfile"
89374bbcaa<gerald.jelinek@sun.com>	fi
89474bbcaa<gerald.jelinek@sun.com>
8956e1ae2aGary Pennington	# Filter out these directories.
8966e1ae2aGary Pennington	echo 'dev/*' >>$fscpiofile
8976e1ae2aGary Pennington	echo 'devices/*' >>$fscpiofile
8986e1ae2aGary Pennington	echo 'devices' >>$fscpiofile
8996e1ae2aGary Pennington	echo 'proc/*' >>$fscpiofile
9006e1ae2aGary Pennington	echo 'tmp/*' >>$fscpiofile
9016e1ae2aGary Pennington	echo 'var/run/*' >>$fscpiofile
9026e1ae2aGary Pennington	echo 'system/contract/*' >>$fscpiofile
9036e1ae2aGary Pennington	echo 'system/object/*' >>$fscpiofile
9046e1ae2aGary Pennington
9056e1ae2aGary Pennington	fspaxfile=$(/usr/bin/mktemp -t -p /var/tmp fs.pax.XXXXXX)
9066e1ae2aGary Pennington	if [[ -z "$fspaxfile" ]]; then
9076e1ae2aGary Pennington		rm -f $fstmpfile $fscpiofile
90874bbcaa<gerald.jelinek@sun.com>		fatal "$e_tmpfile"
90974bbcaa<gerald.jelinek@sun.com>	fi
91074bbcaa<gerald.jelinek@sun.com>
91174bbcaa<gerald.jelinek@sun.com>	printf "%s " \
91274bbcaa<gerald.jelinek@sun.com>	    "dev devices proc tmp var/run system/contract system/object" \
9136e1ae2aGary Pennington	    >>$fspaxfile
91474bbcaa<gerald.jelinek@sun.com>
91574bbcaa<gerald.jelinek@sun.com>	# Set up any fs mounts so the archive will install into the correct
91674bbcaa<gerald.jelinek@sun.com>	# locations.
91774bbcaa<gerald.jelinek@sun.com>	get_fs_info
91874bbcaa<gerald.jelinek@sun.com>	mnt_fs
91974bbcaa<gerald.jelinek@sun.com>	if (( $? != 0 )); then
92074bbcaa<gerald.jelinek@sun.com>		umnt_fs >/dev/null 2>&1
9216e1ae2aGary Pennington		rm -f $fstmpfile $fscpiofile $fspaxfile
92274bbcaa<gerald.jelinek@sun.com>		fatal "$mount_failed"
92374bbcaa<gerald.jelinek@sun.com>	fi
92474bbcaa<gerald.jelinek@sun.com>
92574bbcaa<gerald.jelinek@sun.com>	if [[ "$filetype" == "existing" ]]; then
92674bbcaa<gerald.jelinek@sun.com>		log "$no_installing"
92774bbcaa<gerald.jelinek@sun.com>	else
92874bbcaa<gerald.jelinek@sun.com>		log "$installing"
92974bbcaa<gerald.jelinek@sun.com>	fi
93074bbcaa<gerald.jelinek@sun.com>
93174bbcaa<gerald.jelinek@sun.com>	#
93274bbcaa<gerald.jelinek@sun.com>	# Install the image into the zonepath.
93374bbcaa<gerald.jelinek@sun.com>	#
93474bbcaa<gerald.jelinek@sun.com>	unpack_result=0
93574bbcaa<gerald.jelinek@sun.com>	stage1="cat"
93674bbcaa<gerald.jelinek@sun.com>	if [[ "$filetype" == "gzip" ]]; then
93774bbcaa<gerald.jelinek@sun.com>		stage1="gzcat"
93874bbcaa<gerald.jelinek@sun.com>		filetype="cpio"
93974bbcaa<gerald.jelinek@sun.com>	elif [[ "$filetype" == "bzip2" ]]; then
94074bbcaa<gerald.jelinek@sun.com>		stage1="bzcat"
94174bbcaa<gerald.jelinek@sun.com>		filetype="cpio"
94274bbcaa<gerald.jelinek@sun.com>	fi
94374bbcaa<gerald.jelinek@sun.com>
94474bbcaa<gerald.jelinek@sun.com>	if [[ "$filetype" == "cpio" ]]; then
94574bbcaa<gerald.jelinek@sun.com>		install_cpio "$stage1" "$insrc"
94674bbcaa<gerald.jelinek@sun.com>		unpack_result=$?
94774bbcaa<gerald.jelinek@sun.com>
94874bbcaa<gerald.jelinek@sun.com>	elif [[ "$filetype" == "flar" ]]; then
94974bbcaa<gerald.jelinek@sun.com>		( cd "$ZONEROOT" && $stage1 $insrc | install_flar )
95074bbcaa<gerald.jelinek@sun.com>		unpack_result=$?
95174bbcaa<gerald.jelinek@sun.com>
95274bbcaa<gerald.jelinek@sun.com>	elif [[ "$filetype" == "xustar" ]]; then
95374bbcaa<gerald.jelinek@sun.com>		install_pax "$insrc"
95474bbcaa<gerald.jelinek@sun.com>		unpack_result=$?
95574bbcaa<gerald.jelinek@sun.com>
95674bbcaa<gerald.jelinek@sun.com>	elif [[ "$filetype" = "tar" ]]; then
95774bbcaa<gerald.jelinek@sun.com>		vlog "cd \"$ZONEROOT\" && tar -xf \"$insrc\""
958cec6066<gerald.jelinek@sun.com>		# Ignore errors from tar since we expect some errors depending
959cec6066<gerald.jelinek@sun.com>		# on how the archive was made.
96074bbcaa<gerald.jelinek@sun.com>		( cd "$ZONEROOT" && tar -xf "$insrc" )
961cec6066<gerald.jelinek@sun.com>		unpack_result=0
96274bbcaa<gerald.jelinek@sun.com>		post_unpack
96374bbcaa<gerald.jelinek@sun.com>
96474bbcaa<gerald.jelinek@sun.com>	elif [[ "$filetype" == "ufsdump" ]]; then
96574bbcaa<gerald.jelinek@sun.com>		install_ufsdump "$insrc"
96674bbcaa<gerald.jelinek@sun.com>		unpack_result=$?
96774bbcaa<gerald.jelinek@sun.com>
96874bbcaa<gerald.jelinek@sun.com>	elif [[ "$filetype" == "directory" ]]; then
96974bbcaa<gerald.jelinek@sun.com>		install_dir "$insrc"
97074bbcaa<gerald.jelinek@sun.com>		unpack_result=$?
97174bbcaa<gerald.jelinek@sun.com>
97274bbcaa<gerald.jelinek@sun.com>	elif [[ "$filetype" == "zfs" ]]; then
97374bbcaa<gerald.jelinek@sun.com>		#
97474bbcaa<gerald.jelinek@sun.com>		# Given a 'zfs send' stream file, receive the snapshot into
97574bbcaa<gerald.jelinek@sun.com>		# the zone's dataset.  We're getting the original system's
97674bbcaa<gerald.jelinek@sun.com>		# zonepath dataset.  Destroy the existing dataset created
97774bbcaa<gerald.jelinek@sun.com>		# above since this recreates it.
97874bbcaa<gerald.jelinek@sun.com>		#
97974bbcaa<gerald.jelinek@sun.com>		if [[ -z "$DATASET" ]]; then
98074bbcaa<gerald.jelinek@sun.com>			fatal "$f_nodataset"
98174bbcaa<gerald.jelinek@sun.com>		fi
98274bbcaa<gerald.jelinek@sun.com>		/usr/sbin/zfs destroy "$DATASET"
98374bbcaa<gerald.jelinek@sun.com>		if (( $? != 0 )); then
98474bbcaa<gerald.jelinek@sun.com>			log "$f_zfsdestroy" "$DATASET"
98574bbcaa<gerald.jelinek@sun.com>		fi
98674bbcaa<gerald.jelinek@sun.com>
98774bbcaa<gerald.jelinek@sun.com>		vlog "$stage1 $insrc | zfs receive -F $DATASET"
98874bbcaa<gerald.jelinek@sun.com>		( $stage1 $insrc | /usr/sbin/zfs receive -F $DATASET )
98974bbcaa<gerald.jelinek@sun.com>		unpack_result=$?
99074bbcaa<gerald.jelinek@sun.com>	fi
99174bbcaa<gerald.jelinek@sun.com>
99274bbcaa<gerald.jelinek@sun.com>	# Clean up any fs mounts used during unpacking.
99374bbcaa<gerald.jelinek@sun.com>	umnt_fs
9946e1ae2aGary Pennington	rm -f $fstmpfile $fscpiofile $fspaxfile
99574bbcaa<gerald.jelinek@sun.com>
99674bbcaa<gerald.jelinek@sun.com>	chmod 700 $zonepath
99774bbcaa<gerald.jelinek@sun.com>
998cec6066<gerald.jelinek@sun.com>	(( $unpack_result != 0 )) && fatal "$f_unpack_failed"
999cec6066<gerald.jelinek@sun.com>
100074bbcaa<gerald.jelinek@sun.com>	# Verify this is a valid image.
100174bbcaa<gerald.jelinek@sun.com>	sanity_check $ZONEROOT
100274bbcaa<gerald.jelinek@sun.com>
100374bbcaa<gerald.jelinek@sun.com>	return 0
100474bbcaa<gerald.jelinek@sun.com>}
100574bbcaa<gerald.jelinek@sun.com>
1006edfa49f<gerald.jelinek@sun.com># Setup i18n output
1007edfa49f<gerald.jelinek@sun.com>TEXTDOMAIN="SUNW_OST_OSCMD"
1008edfa49f<gerald.jelinek@sun.com>export TEXTDOMAIN
1009edfa49f<gerald.jelinek@sun.com>
1010ae10493Jonathan Adamse_cannot_wrap=$(gettext "%s: error: wrapper file already exists")
1011edfa49f<gerald.jelinek@sun.com>e_baddir=$(gettext "Invalid '%s' directory within the zone")
1012edfa49f<gerald.jelinek@sun.com>e_badfile=$(gettext "Invalid '%s' file within the zone")
101374bbcaa<gerald.jelinek@sun.com>e_path_abs=$(gettext "Pathname specified to -a '%s' must be absolute.")
101474bbcaa<gerald.jelinek@sun.com>e_not_found=$(gettext "%s: error: file or directory not found.")
101574bbcaa<gerald.jelinek@sun.com>e_install_abort=$(gettext "Installation aborted.")
101674bbcaa<gerald.jelinek@sun.com>e_not_readable=$(gettext "Cannot read directory '%s'")
101774bbcaa<gerald.jelinek@sun.com>e_not_dir=$(gettext "Error: must be a directory")
101874bbcaa<gerald.jelinek@sun.com>e_unknown_archive=$(gettext "Error: Unknown archive format. Must be a flash archive, a cpio archive (can also be gzipped or bzipped), a pax XUSTAR archive, or a level 0 ufsdump archive.")
101962ac533<gerald.jelinek@sun.com>e_absolute_archive=$(gettext "Error: archive contains absolute paths instead of relative paths.")
10208c20418Gerald Jelineke_mismatch_archive=$(gettext "Error: the archive top-level directory (%s) does not match the zonepath (%s).")
102174bbcaa<gerald.jelinek@sun.com>e_tmpfile=$(gettext "Unable to create temporary file")
102274bbcaa<gerald.jelinek@sun.com>e_root_full=$(gettext "Zonepath root %s exists and contains data; remove or move aside prior to install.")
1023e71ca95Gerald Jelinekf_mkdir=$(gettext "Unable to create directory %s.")
1024e71ca95Gerald Jelinekf_chmod=$(gettext "Unable to chmod directory %s.")
1025e71ca95Gerald Jelinekf_chown=$(gettext "Unable to chown directory %s.")
102619b7790<gerald.jelinek@sun.com>f_hwcap_info=$(gettext "HWCAP: %s\n")
102719b7790<gerald.jelinek@sun.com>f_sanity_hwcap=$(gettext \
102819b7790<gerald.jelinek@sun.com>"The image was created with an incompatible libc.so.1 hwcap lofs mount.\n"\
102919b7790<gerald.jelinek@sun.com>"       The zone will not boot on this platform.  See the zone's\n"\
103019b7790<gerald.jelinek@sun.com>"       documentation for the recommended way to create the archive.")
103174bbcaa<gerald.jelinek@sun.com>
10328c20418Gerald Jelinekm_analyse_archive=$(gettext "Analysing the archive")
10338c20418Gerald Jelinek
103474bbcaa<gerald.jelinek@sun.com>not_readable=$(gettext "Cannot read file '%s'")
103574bbcaa<gerald.jelinek@sun.com>not_flar=$(gettext "Input is not a flash archive")
103674bbcaa<gerald.jelinek@sun.com>bad_flar=$(gettext "Flash archive is a corrupt")
1037cec6066<gerald.jelinek@sun.com>bad_zfs_flar=$(gettext "Flash archive contains a ZFS send stream.\n\tRecreate the flar using the -L option with cpio or pax.")
1038cec6066<gerald.jelinek@sun.com>f_unpack_failed=$(gettext "Unpacking the archive failed")
103974bbcaa<gerald.jelinek@sun.com>unknown_archiver=$(gettext "Archiver %s is not supported")
104074bbcaa<gerald.jelinek@sun.com>cmd_not_exec=$(gettext "Required command '%s' not executable!")
1041edfa49f<gerald.jelinek@sun.com>
1042edfa49f<gerald.jelinek@sun.com>#
1043edfa49f<gerald.jelinek@sun.com># Exit values used by the script, as #defined in <sys/zone.h>
1044edfa49f<gerald.jelinek@sun.com>#
1045edfa49f<gerald.jelinek@sun.com>#	ZONE_SUBPROC_OK
1046edfa49f<gerald.jelinek@sun.com>#	===============
1047edfa49f<gerald.jelinek@sun.com>#	Installation was successful
1048edfa49f<gerald.jelinek@sun.com>#
1049edfa49f<gerald.jelinek@sun.com>#	ZONE_SUBPROC_USAGE
1050edfa49f<gerald.jelinek@sun.com>#	==================
1051edfa49f<gerald.jelinek@sun.com>#	Improper arguments were passed, so print a usage message before exiting
1052edfa49f<gerald.jelinek@sun.com>#
1053edfa49f<gerald.jelinek@sun.com>#	ZONE_SUBPROC_NOTCOMPLETE
1054edfa49f<gerald.jelinek@sun.com>#	========================
1055edfa49f<gerald.jelinek@sun.com>#	Installation did not complete, but another installation attempt can be
1056edfa49f<gerald.jelinek@sun.com>#	made without an uninstall
1057edfa49f<gerald.jelinek@sun.com>#
1058edfa49f<gerald.jelinek@sun.com>#	ZONE_SUBPROC_FATAL
1059edfa49f<gerald.jelinek@sun.com>#	==================
1060edfa49f<gerald.jelinek@sun.com>#	Installation failed and an uninstall will be required before another
1061edfa49f<gerald.jelinek@sun.com>#	install can be attempted
1062edfa49f<gerald.jelinek@sun.com>#
1063edfa49f<gerald.jelinek@sun.com>ZONE_SUBPROC_OK=0
1064edfa49f<gerald.jelinek@sun.com>ZONE_SUBPROC_USAGE=253
1065edfa49f<gerald.jelinek@sun.com>ZONE_SUBPROC_NOTCOMPLETE=254
1066edfa49f<gerald.jelinek@sun.com>ZONE_SUBPROC_FATAL=255
1067edfa49f<gerald.jelinek@sun.com>
1068