xref: /illumos-gate/usr/src/cmd/boot/scripts/root_archive.ksh (revision b1593d50e783f7d66722dde093752b74ffa95176)
1#!/bin/ksh -p
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 2009 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26
27# utility to pack and unpack a boot/root archive
28# both ufs and hsfs (iso9660) format archives are unpacked
29# only ufs archives are generated
30#
31# usage: pack   <archive> <root>
32#        unpack <archive> <root>
33#        packmedia   <solaris_image> <root>
34#        unpackmedia <solaris_image> <root>
35#
36#   Where <root> is the directory to unpack to and will be cleaned out
37#   if it exists.
38#
39#   In the case of (un)packmedia, the image is packed or unpacked to/from
40#   Solaris media and all the things that don't go into the ramdisk image
41#   are (un)cpio'd as well
42#
43
44usage()
45{
46	printf "usage: root_archive pack <archive> <root>\n"
47	printf "       root_archive unpack <archive> <root>\n"
48	printf "       root_archive packmedia   <solaris_image> <root>\n"
49	printf "       root_archive unpackmedia <solaris_image> <root>\n"
50}
51
52cleanup()
53{
54	if [ -d $MNT ] ; then
55		umount $MNT 2> /dev/null
56		rmdir $MNT
57	fi
58
59	lofiadm -d "$TMR" 2>/dev/null
60        if [ "$REALTHING" != true ] ; then
61		rm -f "$TMR"
62	fi
63	rm -f "$TMR.gz"
64	rm -f /tmp/flist$$
65}
66
67preload_Gnome()
68{
69	MEDIA="$1"
70	MINIROOT="$2"
71
72
73	(
74		# Prepopulate the gconf database. This needs to be done and
75		# done first for several reasons. 1) Archiving out the gnome
76		# libraries and binaries causes the gconftool-2 to not run
77		# appropriately at boot time. 2) The binaries and libraries
78		# needed to run this are big and thus we want to archive
79		# them separately. 3) Having schemas prepopluated in the
80		# miniroot means faster boot times.
81		#
82
83		cd "$MINIROOT"
84		HOME="./tmp/root"
85		export HOME
86		umask 0022
87		mumble=.tmp_proto/root/etc/gconf/gconf.xml.defaults
88		GCONF_CONFIG_SOURCE="xml:merged:$MINIROOT/$mumble"
89		export GCONF_CONFIG_SOURCE
90		SCHEMADIR="$MINIROOT/.tmp_proto/root/etc/gconf/schemas"
91		export SCHEMADIR
92		/usr/bin/gconftool-2 --makefile-install-rule \
93		    $SCHEMADIR/*.schemas >/dev/null 2>&1
94		echo '
95		xml:readwrite:/tmp/root/.gconf
96		xml:readonly:/etc/gconf/gconf.xml.defaults
97		' > /"$MINIROOT"/.tmp_proto/root/etc/gconf/2/path
98	)
99}
100
101archive_Gnome()
102{
103	MEDIA="$1"
104	MINIROOT="$2"
105
106	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
107	RELEASE=`basename "$RELEASE"`
108	CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
109
110	# Create the gnome archive
111	#
112	(
113		# usr/share gnome stuff
114		cd "$MINIROOT"
115		find usr/share/GConf usr/share/application-registry \
116		    usr/share/autostart usr/share/dbus-1 usr/share/dtds \
117		    usr/share/emacs usr/share/gnome usr/share/gnome-2.0 \
118		    usr/share/gnome-background-properties \
119		    usr/share/gtk-engines usr/share/gui-install \
120		    usr/share/icon-naming-utils usr/share/control-center \
121		    usr/share/icons usr/share/locale usr/share/metacity \
122		    usr/share/mime usr/share/mime-info usr/share/pixmaps \
123		    usr/share/scrollkeeper usr/share/sgml usr/share/themes \
124		    usr/share/xml \
125		    -print > /tmp/gnome_share.$$ 2>/dev/null
126
127		if [ ! -f /tmp/gnome_share.$$ ] ; then
128			echo "/tmp/gnome_share.$$ file list not found."
129			return
130		fi
131
132		# usr/lib gnome stuff
133
134		find usr/lib/libgnome*\.so\.* \
135		    usr/lib/libgst*\.so\.* usr/lib/libgconf*\.so\.* \
136		    usr/lib/libgdk*\.so\.* usr/lib/libgtk*\.so\.* \
137		    usr/lib/libglade*\.so\.* usr/lib/libmetacity*\.so\.* \
138		    usr/lib/libfontconfig*\.so\.* usr/lib/libgmodule*\.so\.* \
139		    usr/lib/libgobject*\.so\.* usr/lib/libgthread*\.so\.* \
140		    usr/lib/libpopt*\.so\.* usr/lib/libstartup*\.so\.* \
141		    usr/lib/libexif*\.so\.* usr/lib/libtiff*\.so\.* \
142		    usr/lib/libdbus*\.so\.* usr/lib/libstartup*\.so\.* \
143		    usr/lib/libexif*\.so\.* usr/lib/libORBit*\.so\.* \
144	 	    usr/lib/libmlib*\.so\.* usr/lib/libxsl*\.so\.* \
145		    usr/lib/libpango*\.so\.* usr/lib/libpng*\.so\.* \
146		    usr/lib/liboil*\.so\.* usr/lib/libbonobo*\.so\.* \
147		    usr/lib/libart*\.so\.* usr/lib/libcairo*\.so\.* \
148		    usr/lib/libjpeg*\.so\.* \
149		    usr/lib/libpolkit*\.so\.* \
150			-print | egrep -v '\.so\.[0]$' > \
151		       /tmp/gnome_lib.$$ 2>/dev/null
152
153		find usr/lib/nautilus usr/lib/pango usr/lib/iconv \
154		    usr/lib/metacity-dialog usr/lib/window-manager-settings \
155		    usr/lib/bonobo-2.0 usr/lib/bononbo usr/lib/gtk-2.0 \
156		    usr/lib/GConf usr/lib/bonobo-activation-server \
157		    usr/lib/python2.4 usr/lib/gstreamer-0.10 \
158		    usr/lib/gconf-sanity-check-2 usr/lib/gconfd \
159		    usr/lib/gnome-vfs-2.0 usr/lib/dbus-daemon \
160		    usr/lib/gnome-vfs-daemon usr/lib/gnome-settings-daemon \
161		    usr/lib/gnome_segv2 usr/lib/orbit-2.0 \
162		    usr/lib/libmlib \
163		    print > /tmp/gnome_libdir.$$ 2>/dev/null
164
165		if [ ! -f /tmp/gnome_lib.$$  -a ! -f gnome_libdir.$$ ] ; then
166			echo "/tmp/gnome_lib.$$ file list not found."
167			return
168		fi
169
170		# /usr/sfw gnome stuff
171		find usr/sfw/bin usr/sfw/include usr/sfw/share usr/sfw/src \
172		    -print > /tmp/gnome_sfw.$$ 2>/dev/null
173
174		if [ ! -f /tmp/gnome_sfw.$$ ] ; then
175			echo "/tmp/gnome_sfw.$$ file list not found."
176			return
177		fi
178
179		# gnome app binaries usr/bin
180		find usr/bin/gnome* usr/bin/gui-install usr/bin/bonobo* \
181		    usr/bin/gtk-* usr/bin/fax* usr/bin/gdk* usr/bin/gif2tiff \
182		    usr/bin/install-lan \
183		    usr/bin/metacity* usr/bin/gst-* usr/bin/gconftool-2 \
184		    usr/bin/pango* usr/bin/desktop* usr/bin/djpeg \
185		    usr/bin/notify-send usr/bin/oil-bugreport \
186		    usr/bin/bmp2tiff usr/bin/thembus-theme-applier \
187		    usr/bin/thumbnail usr/lib/update-* \
188		    usr/bin/ras2tiff usr/bin/raw2tiff usr/bin/rdjpgcom \
189		    usr/bin/thumbnail usr/bin/dbus* \
190		    usr/bin/tiff* usr/bin/rgb2ycbcr \
191		    usr/bin/fc-cache usr/bin/fc-list \
192			-print > /tmp/gnome_bin.$$ 2>/dev/null
193
194		if [ ! -f /tmp/gnome_bin.$$ ] ; then
195			echo "/tmp/gnome_bin.$$ file list not found."
196			return
197		fi
198
199		# Cat all the files together and create the gnome archive
200		#
201
202		cat /tmp/gnome_libdir.$$ /tmp/gnome_lib.$$ \
203		     /tmp/gnome_share.$$ /tmp/gnome_sfw.$$ /tmp/gnome_bin.$$ \
204		    > /tmp/gnome.$$
205
206		if [ ! -f /tmp/gnome.$$ ] ; then
207			echo "/tmp/gnome.$$ file not found."
208			return
209		fi
210		# Save off this file in the miniroot for use later
211		# when unpacking. Clean up old cruft if there.
212		#
213
214		if [ -f .tmp_proto/gnome_saved ]; then
215			rm -f .tmp_proto/gnome_saved
216		fi
217
218		cp /tmp/gnome.$$ .tmp_proto/gnome_saved
219
220		# Create gnome archive
221		#
222
223		cpio -ocmPuB < /tmp/gnome.$$ 2>/dev/null | bzip2 > \
224		    "$CPIO_DIR/gnome.cpio.bz2"
225
226		# Remove files from miniroot that are in archive.
227		# Create symlinks for files in archive
228
229		rm -rf `cat /tmp/gnome_share.$$`
230
231		for i in `cat /tmp/gnome_share.$$`
232		do
233			ln -s /tmp/root/$i $i 2>/dev/null
234		done
235
236		rm -rf `cat /tmp/gnome_lib.$$`
237		for i in `cat /tmp/gnome_lib.$$`
238		do
239			ln -s /tmp/root/$i $i 2>/dev/null
240		done
241
242		rm -rf `cat /tmp/gnome_libdir.$$`
243		for i in `cat /tmp/gnome_libdir.$$`
244		do
245			ln -s /tmp/root/$i $i 2>/dev/null
246		done
247
248		rm -rf `cat /tmp/gnome_sfw.$$`
249		for i in `cat /tmp/gnome_sfw.$$`
250		do
251			ln -s /tmp/root/$i $i 2>/dev/null
252		done
253
254		rm -rf `cat /tmp/gnome_bin.$$`
255		for i in `cat /tmp/gnome_bin.$$`
256		do
257			ln -s /tmp/root/$i $i 2>/dev/null
258		done
259		rm -f /tmp/gnome_share.$$
260		rm -f /tmp/gnome_lib.$$
261		rm -f /tmp/gnome_libdir.$$
262		rm -f /tmp/gnome_bin.$$
263	)
264}
265
266archive_JavaGUI()
267{
268	MEDIA="$1"
269	MINIROOT="$2"
270
271	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
272	RELEASE=`basename "$RELEASE"`
273
274	CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
275
276	# Archive the java wizard components that are only used in the
277	# non developer express path.
278	#
279	(
280		# path is usr/lib/install/data
281		cd "$MINIROOT"
282		find usr/lib/install/data/wizards \
283		    -print > /tmp/java_ui.$$ 2>/dev/null
284
285		if [ ! -f /tmp/java_ui.$$ ] ; then
286			echo "/tmp/java_ui.$$ file list not found."
287			return
288		fi
289
290		cpio -ocmPuB < /tmp/java_ui.$$ 2>/dev/null | bzip2 > \
291		    "$CPIO_DIR/javaui.cpio.bz2"
292
293		rm -rf `cat /tmp/java_ui.$$`
294		ln -s /tmp/root/usr/lib/install/data/wizards \
295		    usr/lib/install/data/wizards 2>/dev/null
296
297		rm -f /tmp/java_ui.$$
298
299	)
300}
301
302archive_Misc()
303{
304	MEDIA="$1"
305	MINIROOT="$2"
306
307	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
308	RELEASE=`basename "$RELEASE"`
309
310	CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
311
312	# Archive misc stuff that is needed by non devex installer
313	#
314	(
315		# usr/lib stuff
316		cd "$MINIROOT"
317		find usr/lib/lp -print > /tmp/lp.$$ 2>/dev/null
318		if [ ! -f /tmp/lp.$$ ] ; then
319			echo "/tmp/lp.$$ file list not found."
320			return
321		fi
322
323		cpio -ocmPuB < /tmp/lp.$$ 2>/dev/null | bzip2 > \
324		    "$CPIO_DIR/lpmisc.cpio.bz2"
325
326		rm -rf `cat /tmp/lp.$$`
327		ln -s /tmp/root/usr/lib/lp usr/lib/lp 2>/dev/null
328
329		rm -f /tmp/lp.$$
330	)
331
332}
333
334archive_Perl()
335{
336	MEDIA="$1"
337	MINIROOT="$2"
338
339	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
340	RELEASE=`basename "$RELEASE"`
341
342	CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
343
344	# Archive perl, it is only needed by gnome gui.
345	#
346	(
347		# in usr
348		cd "$MINIROOT"
349		find usr/perl5 -print > /tmp/perl.$$ 2>/dev/null
350
351		if [ ! -f /tmp/perl.$$ ] ; then
352			echo "/tmp/perl.$$ file list not found."
353			return
354		fi
355		cpio -ocmPuB < /tmp/perl.$$ 2>/dev/null | bzip2 > \
356		    "$CPIO_DIR/perl.cpio.bz2"
357
358		rm -rf `cat /tmp/perl.$$` 2>/dev/null
359		ln -s /tmp/root/usr/perl5 usr/perl5 2>/dev/null
360
361		rm -f /tmp/perl.$$
362	)
363}
364archive_X()
365{
366	MEDIA="$1"
367	MINIROOT="$2"
368
369	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
370	RELEASE=`basename "$RELEASE"`
371
372	CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
373
374	# create the graphics and non-graphics X archive
375	#
376	(
377		cd "$MINIROOT"
378		find usr/openwin usr/dt usr/X11 -print 2> /dev/null |\
379		    cpio -ocmPuB 2> /dev/null | bzip2 > "$CPIO_DIR/X.cpio.bz2"
380
381		find usr/openwin/bin/mkfontdir \
382		     usr/openwin/lib/installalias \
383		     usr/openwin/server/lib/libfont.so.1 \
384		     usr/openwin/server/lib/libtypesclr.so.0 \
385			 -print | cpio -ocmPuB 2> /dev/null | bzip2 > \
386			 "$CPIO_DIR/X_small.cpio.bz2"
387
388		rm -rf usr/dt usr/openwin usr/X11
389		ln -s /tmp/root/usr/dt usr/dt
390		ln -s /tmp/root/usr/openwin usr/openwin
391		ln -s /tmp/root/usr/X11 usr/X11
392	)
393}
394
395archive_lu()
396{
397	MEDIA="$1"
398	MINIROOT="$2"
399
400	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
401	RELEASE=`basename "$RELEASE"`
402
403	CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
404
405	(
406		cd "$MINIROOT"
407		find usr/lib/install usr/snadm usr/sbin \
408		    boot/grub boot/solaris/bootenv.rc \
409		    tmp/root/boot/grub tmp/root/boot/solaris/bootenv.rc \
410		    2> /dev/null | cpio -ocmPuB 2> /dev/null | bzip2 \
411		    > "$CPIO_DIR"/lu.cpio.bz2
412		ls platform > "$CPIO_DIR/lu.platforms"
413	)
414}
415
416cleanout_pkgdata()
417{
418	rm -Rf tmp/root/var/sadm/install tmp/root/var/sadm/pkg
419}
420
421packmedia()
422{
423	MEDIA="$1"
424	MINIROOT="$2"
425
426	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
427	RELEASE=`basename "$RELEASE"`
428	ARCHIVES="X X_small perl lpmisc javaui gnome"
429
430	mkdir -p "$MEDIA/$RELEASE/Tools/Boot"
431
432	if [ -d "$MINIROOT/platform/i86pc" ] ; then
433		mkdir -p "$MEDIA/boot/amd64"
434		mkdir -p "$MEDIA/boot/platform/i86pc/kernel"
435		mkdir -p "$MEDIA/boot/platform/i86pc/kernel/amd64"
436		mkdir -p "$MEDIA/boot/platform/i86xpv/kernel"
437		mkdir -p "$MEDIA/boot/platform/i86xpv/kernel/amd64"
438		cp "$MINIROOT/platform/i86pc/multiboot" "$MEDIA/boot"
439		cp "$MINIROOT/platform/i86pc/kernel/unix" \
440		    "$MEDIA/boot/platform/i86pc/kernel/unix"
441		cp "$MINIROOT/platform/i86pc/kernel/amd64/unix" \
442		    "$MEDIA/boot/platform/i86pc/kernel/amd64/unix"
443		cp "$MINIROOT/platform/i86xpv/kernel/unix" \
444		    "$MEDIA/boot/platform/i86xpv/kernel/unix"
445		cp "$MINIROOT/platform/i86xpv/kernel/amd64/unix" \
446		    "$MEDIA/boot/platform/i86xpv/kernel/amd64/unix"
447		(
448			cd "$MEDIA/$RELEASE/Tools/Boot"
449			ln -sf ../../../boot/x86.miniroot
450			ln -sf ../../../boot/multiboot
451			ln -sf ../../../boot/platform/i86pc/kernel/unix
452			ln -sf ../../../boot/platform/i86pc/kernel/amd64/unix
453			ln -sf ../../../boot/platform/i86xpv/kernel/unix
454			ln -sf ../../../boot/platform/i86xpv/kernel/amd64/unix
455			ln -sf ../../../boot/grub/pxegrub
456		)
457	fi
458
459	if [ -d "$MINIROOT/platform/sun4u" ] ; then
460		mkdir -p "$MEDIA/boot"
461		dd if="$MINIROOT/platform/sun4u/lib/fs/hsfs/bootblk" \
462		    of="$MEDIA/boot/hsfs.bootblock" \
463		    bs=1b oseek=1 count=15 conv=sync 2> /dev/null
464	fi
465
466	for arch in sun4u sun4v ; do
467		if [ -d "$MINIROOT/platform/$arch" ] ; then
468			archdir="$MEDIA/$RELEASE/Tools/Boot/platform/$arch"
469			mkdir -p $archdir
470			ln -sf ../../../../../boot/sparc.miniroot \
471			    "$archdir/boot_archive"
472			cp "$MINIROOT/usr/platform/$arch/lib/fs/nfs/inetboot" \
473			    "$archdir"
474			cp "$MINIROOT/platform/$arch/wanboot" \
475			    "$archdir"
476			mkdir -p "$MEDIA/platform/$arch"
477			ln -sf ../../boot/sparc.miniroot \
478			    "$MEDIA/platform/$arch/boot_archive"
479			ln -sf ../../$RELEASE/Tools/Boot/platform/$arch/wanboot \
480			    "$MEDIA/platform/$arch/wanboot"
481		fi
482	done
483
484	# archive package databases to conserve memory
485	#
486	(
487		cd "$MINIROOT"
488		find tmp/root/var/sadm/install tmp/root/var/sadm/pkg -print | \
489		    cpio -ocmPuB 2> /dev/null | bzip2 > \
490		    "$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2"
491
492		cleanout_pkgdata
493	)
494
495	archive_lu "$MEDIA" "$MINIROOT"
496
497	archive_X "$MEDIA" "$MINIROOT"
498
499	# Take out the gnome and java parts of the installer from
500	# the miniroot. These are not required to boot the system
501	# and start the installers.
502
503	if [ -d "$MINIROOT/platform/i86pc" ] ; then
504		preload_Gnome "$MEDIA" "$MINIROOT"
505		archive_Gnome "$MEDIA" "$MINIROOT"
506		archive_JavaGUI "$MEDIA" "$MINIROOT"
507		archive_Misc "$MEDIA" "$MINIROOT"
508		archive_Perl "$MEDIA" "$MINIROOT"
509		MR="$MEDIA/boot/amd64/x86.miniroot"
510		pack
511
512        	# Now that the 64-bit archives & miniroot have been created,
513        	# restore the files from archives and save the 64-bit
514        	# archives. Strip the 64-bit objects and create the
515		# 32-bit archives and miniroot
516
517		unpackmedia "$MEDIA" "$MINIROOT"
518		cleanout_pkgdata
519		mkdir -p "$MEDIA/$RELEASE/Tools/Boot/amd64"
520		for i in $ARCHIVES; do
521			mv "$MEDIA/$RELEASE/Tools/Boot/${i}.cpio.bz2" \
522				"$MEDIA/$RELEASE/Tools/Boot/amd64"
523		done
524		if [ -z "$STRIP_AMD64" ]; then
525			strip_amd64
526		fi
527
528		archive_X "$MEDIA" "$MINIROOT"
529		archive_Gnome "$MEDIA" "$MINIROOT"
530		archive_JavaGUI "$MEDIA" "$MINIROOT"
531		archive_Perl "$MEDIA" "$MINIROOT"
532		archive_Misc "$MEDIA" "$MINIROOT"
533		MR="$MEDIA/boot/x86.miniroot"
534	fi
535
536	# copy the install menu to menu.lst so we have a menu
537	# on the install media
538	#
539	if [ -f "$MINIROOT/boot/grub/install_menu" ] ; then
540		cp $MINIROOT/boot/grub/install_menu \
541		    $MEDIA/boot/grub/menu.lst
542	fi
543
544	#
545	# jumpstart utilities in usr/sbin/install.d
546	#
547	if [ -d "$MINIROOT/usr/sbin/install.d" ] ; then
548		(
549		cd ${MINIROOT}
550		find usr/sbin/install.d/chkprobe \
551		    -print | cpio -ocmPuB 2> /dev/null | bzip2 > \
552		    ${MEDIA}/${RELEASE}/Tools/Boot/usr_sbin_install_d.cpio.bz2
553		)
554	fi
555}
556
557unarchive_X()
558{
559	MEDIA="$1"
560	UNPACKED_ROOT="$2"
561
562	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
563	RELEASE=`basename "$RELEASE"`
564
565	CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
566
567	# unpack X
568	#
569	(
570		cd "$UNPACKED_ROOT"
571		rm -rf usr/dt usr/openwin usr/X11
572		bzcat "$CPIO_DIR/X.cpio.bz2" | cpio -icdmu 2> /dev/null
573	)
574}
575
576unpackmedia()
577{
578	MEDIA="$1"
579	UNPACKED_ROOT="$2"
580
581	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
582	RELEASE=`basename "$RELEASE"`
583
584	unarchive_X "$MEDIA" "$UNPACKED_ROOT"
585
586	# unpack package databases
587	#
588	(
589		cd "$UNPACKED_ROOT"
590		bzcat "$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2" |
591		    cpio -icdmu 2> /dev/null
592
593		if [ -d "$MINIROOT/platform/i86pc" ] ; then
594
595			# unpack gnome, perl, java and misc
596			# Remove symlinks left from unpacking x86.miniroot
597			# so that unpacking subsequent archives will populate
598			# appropriately.
599			#
600			rm -rf usr/perl5
601			rm -rf usr/lib/install/data/wizards
602			rm -rf usr/lib/lp
603
604			# Gnome list saved off from packmedia
605			for i in `cat .tmp_proto/gnome_saved`
606			do
607				rm -rf $i
608			done
609
610			bzcat "$MEDIA/$RELEASE/Tools/Boot/gnome.cpio.bz2" |
611			    cpio -icdmu 2>/dev/null
612			bzcat "$MEDIA/$RELEASE/Tools/Boot/javaui.cpio.bz2" |
613			    cpio -icdmu 2>/dev/null
614			bzcat "$MEDIA/$RELEASE/Tools/Boot/lpmisc.cpio.bz2" |
615			    cpio -icdmu 2>/dev/null
616			bzcat "$MEDIA/$RELEASE/Tools/Boot/perl.cpio.bz2" |
617			    cpio -icdmu 2>/dev/null
618		fi
619	)
620}
621
622do_unpack()
623{
624	rm -rf "$UNPACKED_ROOT"
625	mkdir -p "$UNPACKED_ROOT"
626	(
627		cd $MNT
628		find . -print | cpio -pdum "$UNPACKED_ROOT" 2> /dev/null
629	)
630	umount $MNT
631}
632
633unpack()
634{
635
636	if [ ! -f "$MR" ] ; then
637		usage
638		exit 1
639	fi
640
641	if [ `uname -i` = i86pc ] ; then
642		gzcat "$MR" > $TMR
643	else
644		REALTHING=true ; export REALTHING
645		TMR="$MR"
646	fi
647
648	LOFIDEV=`/usr/sbin/lofiadm -a $TMR`
649	if [ $? != 0 ] ; then
650		echo lofi plumb failed
651		exit 2
652	fi
653
654	mkdir -p $MNT
655
656	FSTYP=`fstyp $LOFIDEV`
657
658	if [ "$FSTYP" = ufs ] ; then
659		/usr/sbin/mount -o ro,nologging $LOFIDEV $MNT
660		do_unpack
661	elif [ "$FSTYP" = hsfs ] ; then
662		/usr/sbin/mount -F hsfs -o ro $LOFIDEV $MNT
663		do_unpack
664	else
665		printf "invalid root archive\n"
666	fi
667
668
669	rmdir $MNT
670	lofiadm -d $TMR ; LOFIDEV=
671	if [ "$REALTHING" != true ] ; then
672		rm $TMR
673	fi
674}
675
676compress()
677{
678	SRC=$1
679	DST=$2
680
681	(
682		cd $SRC
683		filelist=`find .`
684
685		for file in $filelist ; do
686
687			file=`echo $file | sed s#^./##`
688
689			# copy all files over to preserve hard links
690			#
691			echo $file | cpio -pdum $DST 2> /dev/null
692
693			if [ -f $file ] && [ -s $file ] && [ ! -h $file ] ; then
694				fiocompress -mc $file $DST/$file &
695			fi
696
697		done
698
699		wait `pgrep fiocompress`
700
701		# now re-copy a couple of uncompressed files
702
703		if [ -d "$SRC/platform/i86pc" ] ; then
704			find `cat boot/solaris/filelist.ramdisk` -type file \
705			    -print 2> /dev/null > /tmp/flist$$
706			find usr/kernel -type file -print 2> /dev/null \
707			    >> /tmp/flist$$
708			# some of the files are replaced with links into
709			# tmp/root on the miniroot, so find the backing files
710			# from there as well and add them to the list ti
711			# be copied uncompressed
712			(
713				cd $SRC/tmp/root
714				find `cat ../../boot/solaris/filelist.ramdisk` \
715				    -type file -print 2> /dev/null | \
716				    sed 's#^#tmp/root/#' >> /tmp/flist$$
717			)
718			flist=`cat /tmp/flist$$`
719			(
720				cd $DST
721				rm -f $flist
722			)
723			for file in $flist ; do
724				echo $file | cpio -pdum $DST 2> /dev/null
725			done
726		else
727			find kernel platform -name unix | \
728			    cpio -pdum $DST 2> /dev/null
729			find kernel platform -name genunix | cpio -pdum $DST \
730			    2> /dev/null
731			find kernel platform -name platmod | cpio -pdum $DST \
732			    2> /dev/null
733			find `find kernel platform -name cpu` | \
734			    cpio -pdum $DST 2> /dev/null
735			find `find kernel platform -name kmdb\*` | \
736				cpio -pdum $DST 2> /dev/null
737			find kernel/misc/sparcv9/ctf kernel/fs/sparcv9/dcfs \
738			    kernel/misc/ctf kernel/fs/dcfs \
739			    etc/system etc/name_to_major etc/path_to_inst \
740			    etc/name_to_sysnum | cpio -pdum $DST 2> /dev/null
741		fi
742	)
743}
744
745root_is_ramdisk()
746{
747	grep -v "set root_is_ramdisk=" "$UNPACKED_ROOT"/etc/system | \
748	    grep -v "set ramdisk_size=" > /tmp/system.$$
749	cat /tmp/system.$$ > "$UNPACKED_ROOT"/etc/system
750	rm /tmp/system.$$
751
752	echo set root_is_ramdisk=1 >> "$UNPACKED_ROOT"/etc/system
753	echo set ramdisk_size=$1 >> "$UNPACKED_ROOT"/etc/system
754}
755
756pack()
757{
758	if [ ! -d "$UNPACKED_ROOT" -o -z "$MR" ] ; then
759		usage
760		exit 1
761	fi
762
763	# always compress if fiocompress exists
764	#
765	if [ -x /usr/sbin/fiocompress ] ; then
766		COMPRESS=true
767	fi
768
769	# Estimate image size and add %10 overhead for ufs stuff.
770	# Note, we can't use du here in case $UNPACKED_ROOT is on a filesystem,
771	# e.g. zfs, in which the disk usage is less than the sum of the file
772	# sizes.  The nawk code
773	#
774	#	{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
775	#
776	# below rounds up the size of a file/directory, in bytes, to the
777	# next multiple of 1024.  This mimics the behavior of ufs especially
778	# with directories.  This results in a total size that's slightly
779	# bigger than if du was called on a ufs directory.
780	#
781	# if the operation in turn is compressing the files the amount
782	# of typical shrinkage is used to come up with a useful archive
783	# size
784	size=$(find "$UNPACKED_ROOT" -ls | nawk '
785	    {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
786	    END {print int(t * 1.10 / 1024)}')
787	if [ "$COMPRESS" = true ] ; then
788		size=`echo $size | nawk '{s = $1} END {print int(s * 0.6)}'`
789	fi
790
791	/usr/sbin/mkfile ${size}k "$TMR"
792
793	LOFIDEV=`/usr/sbin/lofiadm -a "$TMR"`
794	if [ $? != 0 ] ; then
795		echo lofi plumb failed
796		exit 2
797	fi
798
799	RLOFIDEV=`echo $LOFIDEV | sed s/lofi/rlofi/`
800	newfs $RLOFIDEV < /dev/null 2> /dev/null
801	mkdir -p $MNT
802	mount -o nologging $LOFIDEV $MNT
803	rmdir $MNT/lost+found
804
805	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
806		root_is_ramdisk $size
807	fi
808
809	(
810		cd "$UNPACKED_ROOT"
811		if [ "$COMPRESS" = true ] ; then
812			compress . $MNT
813		else
814			find . -print | cpio -pdum $MNT 2> /dev/null
815		fi
816	)
817	lockfs -f $MNT
818	umount $MNT
819	rmdir $MNT
820
821	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
822		"$UNPACKED_ROOT/usr/sbin/installboot" \
823		    "$UNPACKED_ROOT/platform/sun4u/lib/fs/ufs/bootblk" \
824		    $RLOFIDEV
825	fi
826
827	lofiadm -d $LOFIDEV
828	LOFIDEV=
829
830	rm -f "$TMR.gz"
831
832	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
833		mv "$TMR" "$MR"
834	else
835		gzip -f "$TMR"
836		mv "$TMR.gz" "$MR"
837	fi
838
839	chmod a+r "$MR"
840}
841
842strip_amd64()
843{
844	find "$UNPACKED_ROOT" -name amd64 -type directory | xargs rm -rf
845}
846
847# main
848#
849
850EXTRA_SPACE=0
851STRIP_AMD64=
852COMPRESS=
853
854PATH=/usr/sbin:/usr/bin:/opt/sfw/bin ; export PATH
855
856while getopts s:6c opt ; do
857	case $opt in
858	s)	EXTRA_SPACE="$OPTARG"
859		;;
860	6)	STRIP_AMD64=false
861		;;
862	c)	COMPRESS=true
863		;;
864	*)	usage
865		exit 1
866		;;
867	esac
868done
869shift `expr $OPTIND - 1`
870
871if [ $# != 3 ] ; then
872	usage
873	exit 1
874fi
875
876UNPACKED_ROOT="$3"
877BASE="`pwd`"
878MNT=/tmp/mnt$$
879TMR=/tmp/mr$$
880LOFIDEV=
881MR="$2"
882
883if [ "`dirname $MR`" = . ] ; then
884	MR="$BASE/$MR"
885fi
886if [ "`dirname $UNPACKED_ROOT`" = . ] ; then
887	UNPACKED_ROOT="$BASE/$UNPACKED_ROOT"
888fi
889
890
891MEDIA="$MR"
892
893trap cleanup EXIT
894
895case $1 in
896	packmedia)
897		if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
898			ARCHIVE=sparc.miniroot
899		else
900			ARCHIVE=x86.miniroot
901		fi
902		MR="$MEDIA/boot/$ARCHIVE"
903
904		packmedia "$MEDIA" "$UNPACKED_ROOT"
905		pack
906
907		;;
908	unpackmedia)
909		if [ -f "$MEDIA/boot/sparc.miniroot" ] ; then
910			ARCHIVE=sparc.miniroot
911		else
912			ARCHIVE=x86.miniroot
913		fi
914		MR="$MEDIA/boot/$ARCHIVE"
915		unpack
916		unpackmedia "$MEDIA" "$UNPACKED_ROOT"
917		;;
918	pack)	pack
919		;;
920	unpack)	unpack
921		;;
922	*)	usage
923		;;
924esac
925