xref: /illumos-gate/usr/src/cmd/boot/scripts/root_archive.ksh (revision 0173c38a73f34277e0c97a19fedfd25d81ba8380)
1#!/bin/ksh
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26# ident	"%Z%%M%	%I%	%E% SMI"
27
28# utility to pack and unpack a boot/root archive
29# both ufs and hsfs (iso9660) format archives are unpacked
30# only ufs archives are generated
31#
32# usage: pack   <archive> <root>
33#        unpack <archive> <root>
34#        packmedia   <solaris_image> <root>
35#        unpackmedia <solaris_image> <root>
36#
37#   Where <root> is the directory to unpack to and will be cleaned out
38#   if it exists.
39#
40#   In the case of (un)packmedia, the image is packed or unpacked to/from
41#   Solaris media and all the things that don't go into the ramdisk image
42#   are (un)cpio'd as well
43#
44# This utility is also used to pack parts (in essence the window system,
45# usr/dt and usr/openwin) of the non ramdisk SPARC
46# miniroot. (un)packmedia will recognize that they are being run a SPARC
47# miniroot and do the appropriate work.
48#
49
50usage()
51{
52	printf "usage: root_archive pack <archive> <root>\n"
53	printf "       root_archive unpack <archive> <root>\n"
54	printf "       root_archive packmedia   <solaris_image> <root>\n"
55	printf "       root_archive unpackmedia <solaris_image> <root>\n"
56}
57
58cleanup()
59{
60	if [ -d $MNT ] ; then
61		umount $MNT 2> /dev/null
62		rmdir $MNT
63	fi
64
65	if [ -f $TMR ] ; then
66		rm $TMR
67	fi
68
69	if [ $LOFIDEV ] ; then
70		lofiadm -d $LOFIDEV
71	fi
72}
73
74archive_X()
75{
76	MEDIA="$1"
77	MINIROOT="$2"
78
79	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
80	RELEASE=`basename "$RELEASE"`
81
82	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
83		CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
84		mkdir -p "$CPIO_DIR"
85	else
86		CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
87	fi
88
89	# create the graphics and non-graphics X archive
90	#
91	cd "$MINIROOT/usr"
92	find openwin dt X11 -print 2> /dev/null |\
93	    cpio -ocmPuB 2> /dev/null | bzip2 > "$CPIO_DIR/X.cpio.bz2"
94
95	find openwin/bin/mkfontdir \
96	     openwin/lib/installalias \
97	     openwin/server/lib/libfont.so.1 \
98	     openwin/server/lib/libtypesclr.so.0 \
99	         -print | cpio -ocmPuB 2> /dev/null | bzip2 > \
100	         "$CPIO_DIR/X_small.cpio.bz2"
101
102	rm -rf dt openwin X11
103	ln -s ../tmp/root/usr/dt
104	ln -s ../tmp/root/usr/openwin
105	ln -s ../tmp/root/usr/X11
106	cd ../..
107}
108
109packmedia()
110{
111	MEDIA="$1"
112	MINIROOT="$2"
113
114	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
115	RELEASE=`basename "$RELEASE"`
116
117	mkdir -p "$MEDIA/$RELEASE/Tools/Boot"
118	mkdir -p "$MEDIA/boot"
119
120	cd "$MINIROOT"
121
122	# archive package databases to conserve memory
123	#
124	find tmp/root/var/sadm/install tmp/root/var/sadm/pkg -print | \
125	    cpio -ocmPuB 2> /dev/null | bzip2 > \
126	    "$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2"
127
128	rm -rf "$MINIROOT/tmp/root/var/sadm/install"
129	rm -rf "$MINIROOT/tmp/root/var/sadm/pkg"
130
131	archive_X "$MEDIA" "$MINIROOT"
132
133	# clear out 64 bit support to conserve memory
134	#
135	if [ STRIP_AMD64 != false ] ; then
136		find "$MINIROOT" -name amd64 -type directory | xargs rm -rf
137	fi
138
139	cp "$MINIROOT/platform/i86pc/multiboot" "$MEDIA/boot"
140
141	# copy the install menu to menu.lst so we have a menu
142	# on the install media
143	#
144	if [ -f "${MINIROOT}/boot/grub/install_menu" ] ; then
145		cp ${MINIROOT}/boot/grub/install_menu \
146		    ${MEDIA}/boot/grub/menu.lst
147	fi
148
149	cd "$MEDIA/$RELEASE/Tools/Boot"
150	ln -sf ../../../boot/x86.miniroot
151	ln -sf ../../../boot/multiboot
152	ln -sf ../../../boot/grub/pxegrub
153}
154
155unarchive_X()
156{
157	MEDIA="$1"
158	UNPACKED_ROOT="$2"
159
160	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
161	RELEASE=`basename "$RELEASE"`
162
163	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
164		CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
165	else
166		CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
167	fi
168
169	# unpack X
170	#
171	cd "$UNPACKED_ROOT/usr"
172	rm -rf dt openwin X11
173	bzcat "$CPIO_DIR/X.cpio.bz2" | cpio -icdmu 2> /dev/null
174}
175
176unpackmedia()
177{
178	MEDIA="$1"
179	UNPACKED_ROOT="$2"
180
181	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
182	RELEASE=`basename "$RELEASE"`
183
184	unarchive_X "$MEDIA" "$UNPACKED_ROOT"
185
186	# unpack package databases
187	#
188	cd "$UNPACKED_ROOT"
189	bzcat "$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2" | cpio -icdmu \
190	    2> /dev/null
191}
192
193do_unpack()
194{
195	rm -rf "$UNPACKED_ROOT"
196	mkdir -p "$UNPACKED_ROOT"
197	cd $MNT
198	find . -print | cpio -pdum "$UNPACKED_ROOT" 2> /dev/null
199	cd "$BASE"
200	umount $MNT
201}
202
203unpack()
204{
205
206	if [ ! -f "$MR" ] ; then
207		usage
208		exit 1
209	fi
210
211	gzcat "$MR" > $TMR
212
213	LOFIDEV=`/usr/sbin/lofiadm -a $TMR`
214	if [ $? != 0 ] ; then
215		echo lofi plumb failed
216		exit 2
217	fi
218
219	mkdir -p $MNT
220
221	FSTYP=`fstyp $LOFIDEV`
222
223	if [ "$FSTYP" = ufs ] ; then
224		/usr/sbin/mount -o ro,nologging $LOFIDEV $MNT
225		do_unpack
226	elif [ "$FSTYP" = hsfs ] ; then
227		/usr/sbin/mount -F hsfs -o ro $LOFIDEV $MNT
228		do_unpack
229	else
230		printf "invalid root archive\n"
231	fi
232
233	rmdir $MNT
234	lofiadm -d $TMR ; LOFIDEV=""
235	rm $TMR
236}
237
238pack()
239{
240	if [ ! -d "$UNPACKED_ROOT" -o -z "$MR" ] ; then
241		usage
242		exit 1
243	fi
244
245	# Estimate image size and add %10 overhead for ufs stuff.
246	# Note, we can't use du here in case $UNPACKED_ROOT is on a filesystem,
247	# e.g. zfs, in which the disk usage is less than the sum of the file
248	# sizes.  The nawk code
249	#
250	#	{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
251	#
252	# below rounds up the size of a file/directory, in bytes, to the
253	# next multiple of 1024.  This mimics the behavior of ufs especially
254	# with directories.  This results in a total size that's slightly
255	# bigger than if du was called on a ufs directory.
256	size=$(find "$UNPACKED_ROOT" -ls | nawk '
257	    {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
258	    END {print int(t * 1.10 / 1024)}')
259
260	/usr/sbin/mkfile ${size}k "$TMR"
261
262	LOFIDEV=`/usr/sbin/lofiadm -a "$TMR"`
263	if [ $? != 0 ] ; then
264		echo lofi plumb failed
265		exit 2
266	fi
267
268	RLOFIDEV=`echo $LOFIDEV | sed s/lofi/rlofi/`
269	newfs $RLOFIDEV < /dev/null 2> /dev/null
270	mkdir -p $MNT
271	mount -o nologging $LOFIDEV $MNT
272	rmdir $MNT/lost+found
273	cd "$UNPACKED_ROOT"
274	find . -print | cpio -pdum $MNT 2> /dev/null
275	lockfs -f $MNT
276	umount $MNT
277	rmdir $MNT
278	lofiadm -d $LOFIDEV
279	LOFIDEV=""
280
281	cd "$BASE"
282
283	rm -f "$TMR.gz"
284	gzip -f "$TMR"
285	mv "$TMR.gz" "$MR"
286	chmod a+r "$MR"
287}
288
289# main
290#
291
292EXTRA_SPACE=0
293
294while getopts s:6 opt ; do
295	case $opt in
296	s)	EXTRA_SPACE="$OPTARG"
297		;;
298	6)	STRIP_AMD64=false
299		;;
300	*)	usage
301		exit 1
302		;;
303	esac
304done
305shift `expr $OPTIND - 1`
306
307if [ $# != 3 ] ; then
308	usage
309	exit 1
310fi
311
312UNPACKED_ROOT="$3"
313BASE="`pwd`"
314MNT=/tmp/mnt$$
315TMR=/tmp/mr$$
316LOFIDEV=
317MR="$2"
318
319if [ "`dirname $MR`" = . ] ; then
320	MR="$BASE/$MR"
321fi
322if [ "`dirname $UNPACKED_ROOT`" = . ] ; then
323	UNPACKED_ROOT="$BASE/$UNPACKED_ROOT"
324fi
325
326trap cleanup EXIT
327
328case $1 in
329	packmedia)
330		MEDIA="$MR"
331		MR="$MR/boot/x86.miniroot"
332
333		if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
334			archive_X "$MEDIA" "$UNPACKED_ROOT"
335		else
336			packmedia "$MEDIA" "$UNPACKED_ROOT"
337			pack
338		fi ;;
339	unpackmedia)
340		MEDIA="$MR"
341		MR="$MR/boot/x86.miniroot"
342
343		if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
344			unarchive_X "$MEDIA" "$UNPACKED_ROOT"
345		else
346			unpack
347			unpackmedia "$MEDIA" "$UNPACKED_ROOT"
348		fi ;;
349	pack)	pack ;;
350	unpack)	unpack ;;
351	*)	usage ;;
352esac
353