10Sstevel@tonic-gate#!/bin/ksh
20Sstevel@tonic-gate#
30Sstevel@tonic-gate# CDDL HEADER START
40Sstevel@tonic-gate#
50Sstevel@tonic-gate# The contents of this file are subject to the terms of the
61777Ssetje# Common Development and Distribution License (the "License").
71777Ssetje# You may not use this file except in compliance with the License.
80Sstevel@tonic-gate#
90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate# See the License for the specific language governing permissions
120Sstevel@tonic-gate# and limitations under the License.
130Sstevel@tonic-gate#
140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate#
200Sstevel@tonic-gate# CDDL HEADER END
210Sstevel@tonic-gate#
220Sstevel@tonic-gate
231777Ssetje# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate# Use is subject to license terms.
250Sstevel@tonic-gate#
261777Ssetje# ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate
280Sstevel@tonic-gate# utility to pack and unpack a boot/root archive
290Sstevel@tonic-gate# both ufs and hsfs (iso9660) format archives are unpacked
300Sstevel@tonic-gate# only ufs archives are generated
310Sstevel@tonic-gate#
320Sstevel@tonic-gate# usage: pack   <archive> <root>
330Sstevel@tonic-gate#        unpack <archive> <root>
340Sstevel@tonic-gate#        packmedia   <solaris_image> <root>
350Sstevel@tonic-gate#        unpackmedia <solaris_image> <root>
360Sstevel@tonic-gate#
370Sstevel@tonic-gate#   Where <root> is the directory to unpack to and will be cleaned out
380Sstevel@tonic-gate#   if it exists.
390Sstevel@tonic-gate#
400Sstevel@tonic-gate#   In the case of (un)packmedia, the image is packed or unpacked to/from
410Sstevel@tonic-gate#   Solaris media and all the things that don't go into the ramdisk image
420Sstevel@tonic-gate#   are (un)cpio'd as well
430Sstevel@tonic-gate#
441777Ssetje# This utility is also used to pack parts (in essence the window system,
451777Ssetje# usr/dt and usr/openwin) of the non ramdisk SPARC
461777Ssetje# miniroot. (un)packmedia will recognize that they are being run a SPARC
471777Ssetje# miniroot and do the appropriate work.
481777Ssetje#
490Sstevel@tonic-gate
500Sstevel@tonic-gateusage()
510Sstevel@tonic-gate{
520Sstevel@tonic-gate	printf "usage: root_archive pack <archive> <root>\n"
530Sstevel@tonic-gate	printf "       root_archive unpack <archive> <root>\n"
540Sstevel@tonic-gate	printf "       root_archive packmedia   <solaris_image> <root>\n"
550Sstevel@tonic-gate	printf "       root_archive unpackmedia <solaris_image> <root>\n"
560Sstevel@tonic-gate}
570Sstevel@tonic-gate
582334Ssetjecleanup()
592334Ssetje{
602334Ssetje	if [ -d $MNT ] ; then
612334Ssetje		umount $MNT 2> /dev/null
622334Ssetje		rmdir $MNT
632334Ssetje	fi
642334Ssetje
652334Ssetje	if [ -f $TMR ] ; then
662334Ssetje		rm $TMR
672334Ssetje	fi
682334Ssetje
692334Ssetje	if [ $LOFIDEV ] ; then
702334Ssetje		lofiadm -d $LOFIDEV
712334Ssetje	fi
722334Ssetje}
732334Ssetje
741777Ssetjearchive_X()
750Sstevel@tonic-gate{
761777Ssetje	MEDIA="$1"
771777Ssetje	MINIROOT="$2"
780Sstevel@tonic-gate
791777Ssetje	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
801777Ssetje	RELEASE=`basename "$RELEASE"`
810Sstevel@tonic-gate
821777Ssetje	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
831777Ssetje		CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
841777Ssetje		mkdir -p "$CPIO_DIR"
851777Ssetje	else
861777Ssetje		CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
871777Ssetje	fi
880Sstevel@tonic-gate
890Sstevel@tonic-gate	# create the graphics and non-graphics X archive
900Sstevel@tonic-gate	#
911777Ssetje	cd "$MINIROOT/usr"
922334Ssetje	find openwin dt X11 -print 2> /dev/null |\
932334Ssetje	    cpio -ocmPuB 2> /dev/null | bzip2 > "$CPIO_DIR/X.cpio.bz2"
940Sstevel@tonic-gate
950Sstevel@tonic-gate	find openwin/bin/mkfontdir \
960Sstevel@tonic-gate	     openwin/lib/installalias \
970Sstevel@tonic-gate	     openwin/server/lib/libfont.so.1 \
980Sstevel@tonic-gate	     openwin/server/lib/libtypesclr.so.0 \
990Sstevel@tonic-gate	         -print | cpio -ocmPuB 2> /dev/null | bzip2 > \
1001777Ssetje	         "$CPIO_DIR/X_small.cpio.bz2"
1010Sstevel@tonic-gate
1022334Ssetje	rm -rf dt openwin X11
1030Sstevel@tonic-gate	ln -s ../tmp/root/usr/dt
1040Sstevel@tonic-gate	ln -s ../tmp/root/usr/openwin
1052334Ssetje	ln -s ../tmp/root/usr/X11
1060Sstevel@tonic-gate	cd ../..
1071777Ssetje}
1081777Ssetje
1091777Ssetjepackmedia()
1101777Ssetje{
1111777Ssetje	MEDIA="$1"
1121777Ssetje	MINIROOT="$2"
1131777Ssetje
1141777Ssetje	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
1151777Ssetje	RELEASE=`basename "$RELEASE"`
1161777Ssetje
1171777Ssetje	mkdir -p "$MEDIA/$RELEASE/Tools/Boot"
1181777Ssetje	mkdir -p "$MEDIA/boot"
1191777Ssetje
1201777Ssetje	cd "$MINIROOT"
1211777Ssetje
1221777Ssetje	# archive package databases to conserve memory
1231777Ssetje	#
1241777Ssetje	find tmp/root/var/sadm/install tmp/root/var/sadm/pkg -print | \
1251777Ssetje	    cpio -ocmPuB 2> /dev/null | bzip2 > \
1261777Ssetje	    "$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2"
1271777Ssetje
1281777Ssetje	rm -rf "$MINIROOT/tmp/root/var/sadm/install"
1291777Ssetje	rm -rf "$MINIROOT/tmp/root/var/sadm/pkg"
1301777Ssetje
1310Sstevel@tonic-gate	# clear out 64 bit support to conserve memory
1320Sstevel@tonic-gate	#
1332334Ssetje	if [ STRIP_AMD64 != false ] ; then
1342334Ssetje		find "$MINIROOT" -name amd64 -type directory | xargs rm -rf
1352334Ssetje	fi
1360Sstevel@tonic-gate
137*2595Ssetje	archive_X "$MEDIA" "$MINIROOT"
138*2595Ssetje
1391777Ssetje	cp "$MINIROOT/platform/i86pc/multiboot" "$MEDIA/boot"
1400Sstevel@tonic-gate
1411821Ssetje	# copy the install menu to menu.lst so we have a menu
1421821Ssetje	# on the install media
1431821Ssetje	#
1441821Ssetje	if [ -f "${MINIROOT}/boot/grub/install_menu" ] ; then
1451821Ssetje		cp ${MINIROOT}/boot/grub/install_menu \
1461821Ssetje		    ${MEDIA}/boot/grub/menu.lst
1471821Ssetje	fi
1481821Ssetje
1491777Ssetje	cd "$MEDIA/$RELEASE/Tools/Boot"
1500Sstevel@tonic-gate	ln -sf ../../../boot/x86.miniroot
1510Sstevel@tonic-gate	ln -sf ../../../boot/multiboot
1520Sstevel@tonic-gate	ln -sf ../../../boot/grub/pxegrub
1531777Ssetje}
1540Sstevel@tonic-gate
1551777Ssetjeunarchive_X()
1561777Ssetje{
1571777Ssetje	MEDIA="$1"
1581777Ssetje	UNPACKED_ROOT="$2"
1591777Ssetje
1601777Ssetje	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
1611777Ssetje	RELEASE=`basename "$RELEASE"`
1621777Ssetje
1631777Ssetje	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
1641777Ssetje		CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
1651777Ssetje	else
1661777Ssetje		CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
1670Sstevel@tonic-gate	fi
1681777Ssetje
1691777Ssetje	# unpack X
1701777Ssetje	#
1711777Ssetje	cd "$UNPACKED_ROOT/usr"
1722334Ssetje	rm -rf dt openwin X11
1731777Ssetje	bzcat "$CPIO_DIR/X.cpio.bz2" | cpio -icdmu 2> /dev/null
1740Sstevel@tonic-gate}
1750Sstevel@tonic-gate
1760Sstevel@tonic-gateunpackmedia()
1771777Ssetje{
1781777Ssetje	MEDIA="$1"
1791777Ssetje	UNPACKED_ROOT="$2"
1800Sstevel@tonic-gate
1811777Ssetje	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
1821777Ssetje	RELEASE=`basename "$RELEASE"`
1831777Ssetje
1841777Ssetje	unarchive_X "$MEDIA" "$UNPACKED_ROOT"
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate	# unpack package databases
1870Sstevel@tonic-gate	#
1881777Ssetje	cd "$UNPACKED_ROOT"
1891777Ssetje	bzcat "$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2" | cpio -icdmu \
1900Sstevel@tonic-gate	    2> /dev/null
1910Sstevel@tonic-gate}
1920Sstevel@tonic-gate
1930Sstevel@tonic-gatedo_unpack()
1940Sstevel@tonic-gate{
1951777Ssetje	rm -rf "$UNPACKED_ROOT"
1961777Ssetje	mkdir -p "$UNPACKED_ROOT"
1970Sstevel@tonic-gate	cd $MNT
1981777Ssetje	find . -print | cpio -pdum "$UNPACKED_ROOT" 2> /dev/null
1991777Ssetje	cd "$BASE"
2000Sstevel@tonic-gate	umount $MNT
2010Sstevel@tonic-gate}
2020Sstevel@tonic-gate
2030Sstevel@tonic-gateunpack()
2040Sstevel@tonic-gate{
2050Sstevel@tonic-gate
2061777Ssetje	if [ ! -f "$MR" ] ; then
2070Sstevel@tonic-gate		usage
2080Sstevel@tonic-gate		exit 1
2090Sstevel@tonic-gate	fi
2100Sstevel@tonic-gate
2111777Ssetje	gzcat "$MR" > $TMR
2120Sstevel@tonic-gate
2132334Ssetje	LOFIDEV=`/usr/sbin/lofiadm -a $TMR`
2140Sstevel@tonic-gate	if [ $? != 0 ] ; then
2150Sstevel@tonic-gate		echo lofi plumb failed
2160Sstevel@tonic-gate		exit 2
2170Sstevel@tonic-gate	fi
2180Sstevel@tonic-gate
2191777Ssetje	mkdir -p $MNT
2200Sstevel@tonic-gate
2212334Ssetje	FSTYP=`fstyp $LOFIDEV`
2220Sstevel@tonic-gate
2231777Ssetje	if [ "$FSTYP" = ufs ] ; then
2242334Ssetje		/usr/sbin/mount -o ro,nologging $LOFIDEV $MNT
2250Sstevel@tonic-gate		do_unpack
2261777Ssetje	elif [ "$FSTYP" = hsfs ] ; then
2272334Ssetje		/usr/sbin/mount -F hsfs -o ro $LOFIDEV $MNT
2280Sstevel@tonic-gate		do_unpack
2290Sstevel@tonic-gate	else
2300Sstevel@tonic-gate		printf "invalid root archive\n"
2310Sstevel@tonic-gate	fi
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate	rmdir $MNT
2342334Ssetje	lofiadm -d $TMR ; LOFIDEV=""
2350Sstevel@tonic-gate	rm $TMR
2360Sstevel@tonic-gate}
2370Sstevel@tonic-gate
2380Sstevel@tonic-gatepack()
2390Sstevel@tonic-gate{
2401777Ssetje	if [ ! -d "$UNPACKED_ROOT" -o -z "$MR" ] ; then
2410Sstevel@tonic-gate		usage
2420Sstevel@tonic-gate		exit 1
2430Sstevel@tonic-gate	fi
2440Sstevel@tonic-gate
2452511Sjongkis	# Estimate image size and add %10 overhead for ufs stuff.
2462511Sjongkis	# Note, we can't use du here in case $UNPACKED_ROOT is on a filesystem,
2472511Sjongkis	# e.g. zfs, in which the disk usage is less than the sum of the file
2482511Sjongkis	# sizes.  The nawk code
2492511Sjongkis	#
2502511Sjongkis	#	{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
2512511Sjongkis	#
2522511Sjongkis	# below rounds up the size of a file/directory, in bytes, to the
2532511Sjongkis	# next multiple of 1024.  This mimics the behavior of ufs especially
2542511Sjongkis	# with directories.  This results in a total size that's slightly
2552511Sjongkis	# bigger than if du was called on a ufs directory.
2562511Sjongkis	size=$(find "$UNPACKED_ROOT" -ls | nawk '
2572511Sjongkis	    {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
2582511Sjongkis	    END {print int(t * 1.10 / 1024)}')
2590Sstevel@tonic-gate
2602334Ssetje	/usr/sbin/mkfile ${size}k "$TMR"
2612334Ssetje
2622334Ssetje	LOFIDEV=`/usr/sbin/lofiadm -a "$TMR"`
2630Sstevel@tonic-gate	if [ $? != 0 ] ; then
2640Sstevel@tonic-gate		echo lofi plumb failed
2650Sstevel@tonic-gate		exit 2
2660Sstevel@tonic-gate	fi
2670Sstevel@tonic-gate
2682334Ssetje	RLOFIDEV=`echo $LOFIDEV | sed s/lofi/rlofi/`
2692334Ssetje	newfs $RLOFIDEV < /dev/null 2> /dev/null
2701777Ssetje	mkdir -p $MNT
2712334Ssetje	mount -o nologging $LOFIDEV $MNT
2721777Ssetje	rmdir $MNT/lost+found
2731777Ssetje	cd "$UNPACKED_ROOT"
2740Sstevel@tonic-gate	find . -print | cpio -pdum $MNT 2> /dev/null
2750Sstevel@tonic-gate	lockfs -f $MNT
2760Sstevel@tonic-gate	umount $MNT
2770Sstevel@tonic-gate	rmdir $MNT
2782334Ssetje	lofiadm -d $LOFIDEV
2792334Ssetje	LOFIDEV=""
2800Sstevel@tonic-gate
2811777Ssetje	cd "$BASE"
2820Sstevel@tonic-gate
2832334Ssetje	rm -f "$TMR.gz"
2842334Ssetje	gzip -f "$TMR"
2852334Ssetje	mv "$TMR.gz" "$MR"
2861777Ssetje	chmod a+r "$MR"
2870Sstevel@tonic-gate}
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate# main
2900Sstevel@tonic-gate#
2910Sstevel@tonic-gate
2922334SsetjeEXTRA_SPACE=0
2932334Ssetje
2942334Ssetjewhile getopts s:6 opt ; do
2952334Ssetje	case $opt in
2962334Ssetje	s)	EXTRA_SPACE="$OPTARG"
2972334Ssetje		;;
2982334Ssetje	6)	STRIP_AMD64=false
2992334Ssetje		;;
3002334Ssetje	*)	usage
3012334Ssetje		exit 1
3022334Ssetje		;;
3032334Ssetje	esac
3042334Ssetjedone
3052334Ssetjeshift `expr $OPTIND - 1`
3062334Ssetje
3070Sstevel@tonic-gateif [ $# != 3 ] ; then
3080Sstevel@tonic-gate	usage
3090Sstevel@tonic-gate	exit 1
3100Sstevel@tonic-gatefi
3110Sstevel@tonic-gate
3121777SsetjeUNPACKED_ROOT="$3"
3131777SsetjeBASE="`pwd`"
3140Sstevel@tonic-gateMNT=/tmp/mnt$$
3152334SsetjeTMR=/tmp/mr$$
3162334SsetjeLOFIDEV=
3171777SsetjeMR="$2"
3180Sstevel@tonic-gate
3190Sstevel@tonic-gateif [ "`dirname $MR`" = . ] ; then
3201777Ssetje	MR="$BASE/$MR"
3210Sstevel@tonic-gatefi
3220Sstevel@tonic-gateif [ "`dirname $UNPACKED_ROOT`" = . ] ; then
3231777Ssetje	UNPACKED_ROOT="$BASE/$UNPACKED_ROOT"
3240Sstevel@tonic-gatefi
3250Sstevel@tonic-gate
3262334Ssetjetrap cleanup EXIT
3272334Ssetje
3280Sstevel@tonic-gatecase $1 in
3290Sstevel@tonic-gate	packmedia)
3301777Ssetje		MEDIA="$MR"
3311777Ssetje		MR="$MR/boot/x86.miniroot"
3321777Ssetje
3331777Ssetje		if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
3341777Ssetje			archive_X "$MEDIA" "$UNPACKED_ROOT"
3351777Ssetje		else
3361777Ssetje			packmedia "$MEDIA" "$UNPACKED_ROOT"
3371777Ssetje			pack
3381777Ssetje		fi ;;
3390Sstevel@tonic-gate	unpackmedia)
3401777Ssetje		MEDIA="$MR"
3411777Ssetje		MR="$MR/boot/x86.miniroot"
3421777Ssetje
3431777Ssetje		if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
3441777Ssetje			unarchive_X "$MEDIA" "$UNPACKED_ROOT"
3451777Ssetje		else
3461777Ssetje			unpack
3471777Ssetje			unpackmedia "$MEDIA" "$UNPACKED_ROOT"
3481777Ssetje		fi ;;
3490Sstevel@tonic-gate	pack)	pack ;;
3500Sstevel@tonic-gate	unpack)	unpack ;;
3510Sstevel@tonic-gate	*)	usage ;;
3520Sstevel@tonic-gateesac
353