1*2851Sjongkis#!/bin/ksh -p
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
65*2851Sjongkis	lofiadm -d "$TMR" 2>/dev/null
66*2851Sjongkis	rm -f "$TMR" "$TMR.gz"
672334Ssetje}
682334Ssetje
691777Ssetjearchive_X()
700Sstevel@tonic-gate{
711777Ssetje	MEDIA="$1"
721777Ssetje	MINIROOT="$2"
730Sstevel@tonic-gate
741777Ssetje	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
751777Ssetje	RELEASE=`basename "$RELEASE"`
760Sstevel@tonic-gate
771777Ssetje	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
781777Ssetje		CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
791777Ssetje		mkdir -p "$CPIO_DIR"
801777Ssetje	else
811777Ssetje		CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
821777Ssetje	fi
830Sstevel@tonic-gate
840Sstevel@tonic-gate	# create the graphics and non-graphics X archive
850Sstevel@tonic-gate	#
86*2851Sjongkis	(
87*2851Sjongkis		cd "$MINIROOT/usr"
88*2851Sjongkis		find openwin dt X11 -print 2> /dev/null |\
89*2851Sjongkis		    cpio -ocmPuB 2> /dev/null | bzip2 > "$CPIO_DIR/X.cpio.bz2"
900Sstevel@tonic-gate
91*2851Sjongkis		find openwin/bin/mkfontdir \
92*2851Sjongkis		     openwin/lib/installalias \
93*2851Sjongkis		     openwin/server/lib/libfont.so.1 \
94*2851Sjongkis		     openwin/server/lib/libtypesclr.so.0 \
95*2851Sjongkis			 -print | cpio -ocmPuB 2> /dev/null | bzip2 > \
96*2851Sjongkis			 "$CPIO_DIR/X_small.cpio.bz2"
970Sstevel@tonic-gate
98*2851Sjongkis		rm -rf dt openwin X11
99*2851Sjongkis		ln -s ../tmp/root/usr/dt
100*2851Sjongkis		ln -s ../tmp/root/usr/openwin
101*2851Sjongkis		ln -s ../tmp/root/usr/X11
102*2851Sjongkis	)
1031777Ssetje}
1041777Ssetje
1051777Ssetjepackmedia()
1061777Ssetje{
1071777Ssetje	MEDIA="$1"
1081777Ssetje	MINIROOT="$2"
1091777Ssetje
1101777Ssetje	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
1111777Ssetje	RELEASE=`basename "$RELEASE"`
1121777Ssetje
1131777Ssetje	mkdir -p "$MEDIA/$RELEASE/Tools/Boot"
1141777Ssetje	mkdir -p "$MEDIA/boot"
1151777Ssetje
1161777Ssetje	# archive package databases to conserve memory
1171777Ssetje	#
118*2851Sjongkis	(
119*2851Sjongkis		cd "$MINIROOT"
120*2851Sjongkis		find tmp/root/var/sadm/install tmp/root/var/sadm/pkg -print | \
121*2851Sjongkis		    cpio -ocmPuB 2> /dev/null | bzip2 > \
122*2851Sjongkis		    "$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2"
123*2851Sjongkis	)
1241777Ssetje
1251777Ssetje	rm -rf "$MINIROOT/tmp/root/var/sadm/install"
1261777Ssetje	rm -rf "$MINIROOT/tmp/root/var/sadm/pkg"
1271777Ssetje
1280Sstevel@tonic-gate	# clear out 64 bit support to conserve memory
1290Sstevel@tonic-gate	#
130*2851Sjongkis	if [ "$STRIP_AMD64" != false ] ; then
1312334Ssetje		find "$MINIROOT" -name amd64 -type directory | xargs rm -rf
1322334Ssetje	fi
1330Sstevel@tonic-gate
1342595Ssetje	archive_X "$MEDIA" "$MINIROOT"
1352595Ssetje
1361777Ssetje	cp "$MINIROOT/platform/i86pc/multiboot" "$MEDIA/boot"
1370Sstevel@tonic-gate
1381821Ssetje	# copy the install menu to menu.lst so we have a menu
1391821Ssetje	# on the install media
1401821Ssetje	#
1411821Ssetje	if [ -f "${MINIROOT}/boot/grub/install_menu" ] ; then
1421821Ssetje		cp ${MINIROOT}/boot/grub/install_menu \
1431821Ssetje		    ${MEDIA}/boot/grub/menu.lst
1441821Ssetje	fi
1451821Ssetje
146*2851Sjongkis	(
147*2851Sjongkis		cd "$MEDIA/$RELEASE/Tools/Boot"
148*2851Sjongkis		ln -sf ../../../boot/x86.miniroot
149*2851Sjongkis		ln -sf ../../../boot/multiboot
150*2851Sjongkis		ln -sf ../../../boot/grub/pxegrub
151*2851Sjongkis	)
1521777Ssetje}
1530Sstevel@tonic-gate
1541777Ssetjeunarchive_X()
1551777Ssetje{
1561777Ssetje	MEDIA="$1"
1571777Ssetje	UNPACKED_ROOT="$2"
1581777Ssetje
1591777Ssetje	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
1601777Ssetje	RELEASE=`basename "$RELEASE"`
1611777Ssetje
1621777Ssetje	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
1631777Ssetje		CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
1641777Ssetje	else
1651777Ssetje		CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
1660Sstevel@tonic-gate	fi
1671777Ssetje
1681777Ssetje	# unpack X
1691777Ssetje	#
170*2851Sjongkis	(
171*2851Sjongkis		cd "$UNPACKED_ROOT/usr"
172*2851Sjongkis		rm -rf dt openwin X11
173*2851Sjongkis		bzcat "$CPIO_DIR/X.cpio.bz2" | cpio -icdmu 2> /dev/null
174*2851Sjongkis	)
1750Sstevel@tonic-gate}
1760Sstevel@tonic-gate
1770Sstevel@tonic-gateunpackmedia()
1781777Ssetje{
1791777Ssetje	MEDIA="$1"
1801777Ssetje	UNPACKED_ROOT="$2"
1810Sstevel@tonic-gate
1821777Ssetje	RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
1831777Ssetje	RELEASE=`basename "$RELEASE"`
1841777Ssetje
1851777Ssetje	unarchive_X "$MEDIA" "$UNPACKED_ROOT"
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate	# unpack package databases
1880Sstevel@tonic-gate	#
189*2851Sjongkis	(
190*2851Sjongkis		cd "$UNPACKED_ROOT"
191*2851Sjongkis		bzcat "$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2" |
192*2851Sjongkis		    cpio -icdmu 2> /dev/null
193*2851Sjongkis	)
1940Sstevel@tonic-gate}
1950Sstevel@tonic-gate
1960Sstevel@tonic-gatedo_unpack()
1970Sstevel@tonic-gate{
1981777Ssetje	rm -rf "$UNPACKED_ROOT"
1991777Ssetje	mkdir -p "$UNPACKED_ROOT"
200*2851Sjongkis	(
201*2851Sjongkis		cd $MNT
202*2851Sjongkis		find . -print | cpio -pdum "$UNPACKED_ROOT" 2> /dev/null
203*2851Sjongkis	)
2040Sstevel@tonic-gate	umount $MNT
2050Sstevel@tonic-gate}
2060Sstevel@tonic-gate
2070Sstevel@tonic-gateunpack()
2080Sstevel@tonic-gate{
2090Sstevel@tonic-gate
2101777Ssetje	if [ ! -f "$MR" ] ; then
2110Sstevel@tonic-gate		usage
2120Sstevel@tonic-gate		exit 1
2130Sstevel@tonic-gate	fi
2140Sstevel@tonic-gate
2151777Ssetje	gzcat "$MR" > $TMR
2160Sstevel@tonic-gate
2172334Ssetje	LOFIDEV=`/usr/sbin/lofiadm -a $TMR`
2180Sstevel@tonic-gate	if [ $? != 0 ] ; then
2190Sstevel@tonic-gate		echo lofi plumb failed
2200Sstevel@tonic-gate		exit 2
2210Sstevel@tonic-gate	fi
2220Sstevel@tonic-gate
2231777Ssetje	mkdir -p $MNT
2240Sstevel@tonic-gate
2252334Ssetje	FSTYP=`fstyp $LOFIDEV`
2260Sstevel@tonic-gate
2271777Ssetje	if [ "$FSTYP" = ufs ] ; then
2282334Ssetje		/usr/sbin/mount -o ro,nologging $LOFIDEV $MNT
2290Sstevel@tonic-gate		do_unpack
2301777Ssetje	elif [ "$FSTYP" = hsfs ] ; then
2312334Ssetje		/usr/sbin/mount -F hsfs -o ro $LOFIDEV $MNT
2320Sstevel@tonic-gate		do_unpack
2330Sstevel@tonic-gate	else
2340Sstevel@tonic-gate		printf "invalid root archive\n"
2350Sstevel@tonic-gate	fi
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate	rmdir $MNT
238*2851Sjongkis	lofiadm -d $TMR ; LOFIDEV=
2390Sstevel@tonic-gate	rm $TMR
2400Sstevel@tonic-gate}
2410Sstevel@tonic-gate
2420Sstevel@tonic-gatepack()
2430Sstevel@tonic-gate{
2441777Ssetje	if [ ! -d "$UNPACKED_ROOT" -o -z "$MR" ] ; then
2450Sstevel@tonic-gate		usage
2460Sstevel@tonic-gate		exit 1
2470Sstevel@tonic-gate	fi
2480Sstevel@tonic-gate
2492511Sjongkis	# Estimate image size and add %10 overhead for ufs stuff.
2502511Sjongkis	# Note, we can't use du here in case $UNPACKED_ROOT is on a filesystem,
2512511Sjongkis	# e.g. zfs, in which the disk usage is less than the sum of the file
2522511Sjongkis	# sizes.  The nawk code
2532511Sjongkis	#
2542511Sjongkis	#	{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
2552511Sjongkis	#
2562511Sjongkis	# below rounds up the size of a file/directory, in bytes, to the
2572511Sjongkis	# next multiple of 1024.  This mimics the behavior of ufs especially
2582511Sjongkis	# with directories.  This results in a total size that's slightly
2592511Sjongkis	# bigger than if du was called on a ufs directory.
2602511Sjongkis	size=$(find "$UNPACKED_ROOT" -ls | nawk '
2612511Sjongkis	    {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
2622511Sjongkis	    END {print int(t * 1.10 / 1024)}')
2630Sstevel@tonic-gate
2642334Ssetje	/usr/sbin/mkfile ${size}k "$TMR"
2652334Ssetje
2662334Ssetje	LOFIDEV=`/usr/sbin/lofiadm -a "$TMR"`
2670Sstevel@tonic-gate	if [ $? != 0 ] ; then
2680Sstevel@tonic-gate		echo lofi plumb failed
2690Sstevel@tonic-gate		exit 2
2700Sstevel@tonic-gate	fi
2710Sstevel@tonic-gate
2722334Ssetje	RLOFIDEV=`echo $LOFIDEV | sed s/lofi/rlofi/`
2732334Ssetje	newfs $RLOFIDEV < /dev/null 2> /dev/null
2741777Ssetje	mkdir -p $MNT
2752334Ssetje	mount -o nologging $LOFIDEV $MNT
2761777Ssetje	rmdir $MNT/lost+found
277*2851Sjongkis	(
278*2851Sjongkis		cd "$UNPACKED_ROOT"
279*2851Sjongkis		find . -print | cpio -pdum $MNT 2> /dev/null
280*2851Sjongkis	)
2810Sstevel@tonic-gate	lockfs -f $MNT
2820Sstevel@tonic-gate	umount $MNT
2830Sstevel@tonic-gate	rmdir $MNT
2842334Ssetje	lofiadm -d $LOFIDEV
285*2851Sjongkis	LOFIDEV=
2860Sstevel@tonic-gate
2872334Ssetje	rm -f "$TMR.gz"
2882334Ssetje	gzip -f "$TMR"
2892334Ssetje	mv "$TMR.gz" "$MR"
2901777Ssetje	chmod a+r "$MR"
2910Sstevel@tonic-gate}
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate# main
2940Sstevel@tonic-gate#
2950Sstevel@tonic-gate
2962334SsetjeEXTRA_SPACE=0
297*2851SjongkisSTRIP_AMD64=
2982334Ssetje
2992334Ssetjewhile getopts s:6 opt ; do
3002334Ssetje	case $opt in
3012334Ssetje	s)	EXTRA_SPACE="$OPTARG"
3022334Ssetje		;;
3032334Ssetje	6)	STRIP_AMD64=false
3042334Ssetje		;;
3052334Ssetje	*)	usage
3062334Ssetje		exit 1
3072334Ssetje		;;
3082334Ssetje	esac
3092334Ssetjedone
3102334Ssetjeshift `expr $OPTIND - 1`
3112334Ssetje
3120Sstevel@tonic-gateif [ $# != 3 ] ; then
3130Sstevel@tonic-gate	usage
3140Sstevel@tonic-gate	exit 1
3150Sstevel@tonic-gatefi
3160Sstevel@tonic-gate
3171777SsetjeUNPACKED_ROOT="$3"
3181777SsetjeBASE="`pwd`"
3190Sstevel@tonic-gateMNT=/tmp/mnt$$
3202334SsetjeTMR=/tmp/mr$$
3212334SsetjeLOFIDEV=
3221777SsetjeMR="$2"
3230Sstevel@tonic-gate
3240Sstevel@tonic-gateif [ "`dirname $MR`" = . ] ; then
3251777Ssetje	MR="$BASE/$MR"
3260Sstevel@tonic-gatefi
3270Sstevel@tonic-gateif [ "`dirname $UNPACKED_ROOT`" = . ] ; then
3281777Ssetje	UNPACKED_ROOT="$BASE/$UNPACKED_ROOT"
3290Sstevel@tonic-gatefi
3300Sstevel@tonic-gate
3312334Ssetjetrap cleanup EXIT
3322334Ssetje
3330Sstevel@tonic-gatecase $1 in
3340Sstevel@tonic-gate	packmedia)
3351777Ssetje		MEDIA="$MR"
3361777Ssetje		MR="$MR/boot/x86.miniroot"
3371777Ssetje
3381777Ssetje		if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
3391777Ssetje			archive_X "$MEDIA" "$UNPACKED_ROOT"
3401777Ssetje		else
3411777Ssetje			packmedia "$MEDIA" "$UNPACKED_ROOT"
3421777Ssetje			pack
3431777Ssetje		fi ;;
3440Sstevel@tonic-gate	unpackmedia)
3451777Ssetje		MEDIA="$MR"
3461777Ssetje		MR="$MR/boot/x86.miniroot"
3471777Ssetje
3481777Ssetje		if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
3491777Ssetje			unarchive_X "$MEDIA" "$UNPACKED_ROOT"
3501777Ssetje		else
3511777Ssetje			unpack
3521777Ssetje			unpackmedia "$MEDIA" "$UNPACKED_ROOT"
3531777Ssetje		fi ;;
3540Sstevel@tonic-gate	pack)	pack ;;
3550Sstevel@tonic-gate	unpack)	unpack ;;
3560Sstevel@tonic-gate	*)	usage ;;
3570Sstevel@tonic-gateesac
358