xref: /titanic_50/usr/src/cmd/boot/scripts/root_archive.ksh (revision a0eaab1e06dab1229b6ef0e9b67c737cc9ba9c25)
1e482cb0aSjongkis#!/bin/ksh -p
27c478bd9Sstevel@tonic-gate#
37c478bd9Sstevel@tonic-gate# CDDL HEADER START
47c478bd9Sstevel@tonic-gate#
57c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6781dc622Ssetje# Common Development and Distribution License (the "License").
7781dc622Ssetje# You may not use this file except in compliance with the License.
87c478bd9Sstevel@tonic-gate#
97c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate# and limitations under the License.
137c478bd9Sstevel@tonic-gate#
147c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate#
207c478bd9Sstevel@tonic-gate# CDDL HEADER END
217c478bd9Sstevel@tonic-gate#
227c478bd9Sstevel@tonic-gate
23d07682faSAbhinandan Ekande# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate# Use is subject to license terms.
257c478bd9Sstevel@tonic-gate#
26*a0eaab1eSAlexander Eremin# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate# utility to pack and unpack a boot/root archive
297c478bd9Sstevel@tonic-gate# both ufs and hsfs (iso9660) format archives are unpacked
307c478bd9Sstevel@tonic-gate# only ufs archives are generated
317c478bd9Sstevel@tonic-gate#
327c478bd9Sstevel@tonic-gate# usage: pack   <archive> <root>
337c478bd9Sstevel@tonic-gate#        unpack <archive> <root>
347c478bd9Sstevel@tonic-gate#
357c478bd9Sstevel@tonic-gate#   Where <root> is the directory to unpack to and will be cleaned out
367c478bd9Sstevel@tonic-gate#   if it exists.
377c478bd9Sstevel@tonic-gate#
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gateusage()
407c478bd9Sstevel@tonic-gate{
417c478bd9Sstevel@tonic-gate	printf "usage: root_archive pack <archive> <root>\n"
427c478bd9Sstevel@tonic-gate	printf "       root_archive unpack <archive> <root>\n"
43f0778428SJerry Gilliam	exit 1
447c478bd9Sstevel@tonic-gate}
457c478bd9Sstevel@tonic-gate
4658091fd8Ssetjecleanup()
4758091fd8Ssetje{
4858091fd8Ssetje	if [ -d $MNT ] ; then
4958091fd8Ssetje		umount $MNT 2> /dev/null
5058091fd8Ssetje		rmdir $MNT
5158091fd8Ssetje	fi
5258091fd8Ssetje
53e482cb0aSjongkis	lofiadm -d "$TMR" 2>/dev/null
54986fd29aSsetje        if [ "$REALTHING" != true ] ; then
55986fd29aSsetje		rm -f "$TMR"
56986fd29aSsetje	fi
57986fd29aSsetje	rm -f "$TMR.gz"
58342440ecSPrasad Singamsetty	rm -f /tmp/flist$$
5958091fd8Ssetje}
6058091fd8Ssetje
617c478bd9Sstevel@tonic-gatedo_unpack()
627c478bd9Sstevel@tonic-gate{
63e482cb0aSjongkis	(
647c478bd9Sstevel@tonic-gate		cd $MNT
65781dc622Ssetje		find . -print | cpio -pdum "$UNPACKED_ROOT" 2> /dev/null
66e482cb0aSjongkis	)
67f0778428SJerry Gilliam	# increase the chances the unmount will succeed
68f0778428SJerry Gilliam	umount -f $MNT
697c478bd9Sstevel@tonic-gate}
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gateunpack()
727c478bd9Sstevel@tonic-gate{
73f0778428SJerry Gilliam	MR=$1
74781dc622Ssetje	if [ ! -f "$MR" ] ; then
75f0778428SJerry Gilliam		printf "$MR: not found\n"
767c478bd9Sstevel@tonic-gate		usage
777c478bd9Sstevel@tonic-gate	fi
787c478bd9Sstevel@tonic-gate
79342440ecSPrasad Singamsetty	if [ `uname -i` = i86pc ] ; then
80781dc622Ssetje		gzcat "$MR" > $TMR
81986fd29aSsetje	else
82986fd29aSsetje		REALTHING=true ; export REALTHING
83986fd29aSsetje		TMR="$MR"
84986fd29aSsetje	fi
857c478bd9Sstevel@tonic-gate
8658091fd8Ssetje	LOFIDEV=`/usr/sbin/lofiadm -a $TMR`
877c478bd9Sstevel@tonic-gate	if [ $? != 0 ] ; then
887c478bd9Sstevel@tonic-gate		echo lofi plumb failed
897c478bd9Sstevel@tonic-gate		exit 2
907c478bd9Sstevel@tonic-gate	fi
917c478bd9Sstevel@tonic-gate
92781dc622Ssetje	mkdir -p $MNT
937c478bd9Sstevel@tonic-gate
9458091fd8Ssetje	FSTYP=`fstyp $LOFIDEV`
957c478bd9Sstevel@tonic-gate
96781dc622Ssetje	if [ "$FSTYP" = ufs ] ; then
9758091fd8Ssetje		/usr/sbin/mount -o ro,nologging $LOFIDEV $MNT
987c478bd9Sstevel@tonic-gate		do_unpack
99781dc622Ssetje	elif [ "$FSTYP" = hsfs ] ; then
10058091fd8Ssetje		/usr/sbin/mount -F hsfs -o ro $LOFIDEV $MNT
1017c478bd9Sstevel@tonic-gate		do_unpack
1027c478bd9Sstevel@tonic-gate	else
1037c478bd9Sstevel@tonic-gate		printf "invalid root archive\n"
1047c478bd9Sstevel@tonic-gate	fi
1057c478bd9Sstevel@tonic-gate
106986fd29aSsetje
1077c478bd9Sstevel@tonic-gate	rmdir $MNT
108e482cb0aSjongkis	lofiadm -d $TMR ; LOFIDEV=
109986fd29aSsetje	if [ "$REALTHING" != true ] ; then
1107c478bd9Sstevel@tonic-gate		rm $TMR
111986fd29aSsetje	fi
112986fd29aSsetje}
113986fd29aSsetje
114986fd29aSsetjecompress()
115986fd29aSsetje{
116986fd29aSsetje	SRC=$1
117986fd29aSsetje	DST=$2
118986fd29aSsetje
119986fd29aSsetje	(
120986fd29aSsetje		cd $SRC
121986fd29aSsetje		filelist=`find .`
122986fd29aSsetje
123986fd29aSsetje		for file in $filelist ; do
124986fd29aSsetje
125986fd29aSsetje			file=`echo $file | sed s#^./##`
126986fd29aSsetje
127986fd29aSsetje			# copy all files over to preserve hard links
128986fd29aSsetje			#
129986fd29aSsetje			echo $file | cpio -pdum $DST 2> /dev/null
130986fd29aSsetje
131986fd29aSsetje			if [ -f $file ] && [ -s $file ] && [ ! -h $file ] ; then
132986fd29aSsetje				fiocompress -mc $file $DST/$file &
133986fd29aSsetje			fi
134986fd29aSsetje
135986fd29aSsetje		done
136986fd29aSsetje
137342440ecSPrasad Singamsetty		wait `pgrep fiocompress`
138986fd29aSsetje
139342440ecSPrasad Singamsetty		# now re-copy a couple of uncompressed files
140342440ecSPrasad Singamsetty
141342440ecSPrasad Singamsetty		if [ -d "$SRC/platform/i86pc" ] ; then
142342440ecSPrasad Singamsetty			find `cat boot/solaris/filelist.ramdisk` -type file \
143342440ecSPrasad Singamsetty			    -print 2> /dev/null > /tmp/flist$$
144342440ecSPrasad Singamsetty			find usr/kernel -type file -print 2> /dev/null \
145342440ecSPrasad Singamsetty			    >> /tmp/flist$$
146342440ecSPrasad Singamsetty			# some of the files are replaced with links into
147342440ecSPrasad Singamsetty			# tmp/root on the miniroot, so find the backing files
148342440ecSPrasad Singamsetty			# from there as well and add them to the list ti
149342440ecSPrasad Singamsetty			# be copied uncompressed
150342440ecSPrasad Singamsetty			(
151342440ecSPrasad Singamsetty				cd $SRC/tmp/root
152342440ecSPrasad Singamsetty				find `cat ../../boot/solaris/filelist.ramdisk` \
153342440ecSPrasad Singamsetty				    -type file -print 2> /dev/null | \
154342440ecSPrasad Singamsetty				    sed 's#^#tmp/root/#' >> /tmp/flist$$
155342440ecSPrasad Singamsetty			)
156342440ecSPrasad Singamsetty			flist=`cat /tmp/flist$$`
157342440ecSPrasad Singamsetty			(
158342440ecSPrasad Singamsetty				cd $DST
159342440ecSPrasad Singamsetty				rm -f $flist
160342440ecSPrasad Singamsetty			)
161342440ecSPrasad Singamsetty			for file in $flist ; do
162342440ecSPrasad Singamsetty				echo $file | cpio -pdum $DST 2> /dev/null
163342440ecSPrasad Singamsetty			done
164342440ecSPrasad Singamsetty		else
165342440ecSPrasad Singamsetty			find kernel platform -name unix | \
166342440ecSPrasad Singamsetty			    cpio -pdum $DST 2> /dev/null
167986fd29aSsetje			find kernel platform -name genunix | cpio -pdum $DST \
168986fd29aSsetje			    2> /dev/null
169986fd29aSsetje			find kernel platform -name platmod | cpio -pdum $DST \
170986fd29aSsetje			    2> /dev/null
171342440ecSPrasad Singamsetty			find `find kernel platform -name cpu` | \
172342440ecSPrasad Singamsetty			    cpio -pdum $DST 2> /dev/null
173342440ecSPrasad Singamsetty			find `find kernel platform -name kmdb\*` | \
174342440ecSPrasad Singamsetty				cpio -pdum $DST 2> /dev/null
175986fd29aSsetje			find kernel/misc/sparcv9/ctf kernel/fs/sparcv9/dcfs \
176986fd29aSsetje			    etc/system etc/name_to_major etc/path_to_inst \
1773bef9c63Sxun ni - Sun Microsystems - Beijing China			    etc/name_to_sysnum  etc/driver_aliases \
1783bef9c63Sxun ni - Sun Microsystems - Beijing China			    etc/driver_classes etc/minor_perm | \
1793bef9c63Sxun ni - Sun Microsystems - Beijing China			    cpio -pdum $DST 2> /dev/null
180342440ecSPrasad Singamsetty		fi
181986fd29aSsetje	)
182986fd29aSsetje}
183986fd29aSsetje
184986fd29aSsetjeroot_is_ramdisk()
185986fd29aSsetje{
186986fd29aSsetje	grep -v "set root_is_ramdisk=" "$UNPACKED_ROOT"/etc/system | \
187986fd29aSsetje	    grep -v "set ramdisk_size=" > /tmp/system.$$
188986fd29aSsetje	cat /tmp/system.$$ > "$UNPACKED_ROOT"/etc/system
189986fd29aSsetje	rm /tmp/system.$$
190986fd29aSsetje
191986fd29aSsetje	echo set root_is_ramdisk=1 >> "$UNPACKED_ROOT"/etc/system
192986fd29aSsetje	echo set ramdisk_size=$1 >> "$UNPACKED_ROOT"/etc/system
1937c478bd9Sstevel@tonic-gate}
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gatepack()
1967c478bd9Sstevel@tonic-gate{
197f0778428SJerry Gilliam	MR="$1"
198f0778428SJerry Gilliam	[ -d "$UNPACKED_ROOT" ] || usage
1997c478bd9Sstevel@tonic-gate
200342440ecSPrasad Singamsetty	# always compress if fiocompress exists
201986fd29aSsetje	#
202342440ecSPrasad Singamsetty	if [ -x /usr/sbin/fiocompress ] ; then
203986fd29aSsetje		COMPRESS=true
204986fd29aSsetje	fi
205986fd29aSsetje
2064681df02Sjongkis	# Estimate image size and add %10 overhead for ufs stuff.
2074681df02Sjongkis	# Note, we can't use du here in case $UNPACKED_ROOT is on a filesystem,
2084681df02Sjongkis	# e.g. zfs, in which the disk usage is less than the sum of the file
2094681df02Sjongkis	# sizes.  The nawk code
2104681df02Sjongkis	#
2114681df02Sjongkis	#	{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
2124681df02Sjongkis	#
2134681df02Sjongkis	# below rounds up the size of a file/directory, in bytes, to the
2144681df02Sjongkis	# next multiple of 1024.  This mimics the behavior of ufs especially
2154681df02Sjongkis	# with directories.  This results in a total size that's slightly
2164681df02Sjongkis	# bigger than if du was called on a ufs directory.
217986fd29aSsetje	#
218986fd29aSsetje	# if the operation in turn is compressing the files the amount
219986fd29aSsetje	# of typical shrinkage is used to come up with a useful archive
220986fd29aSsetje	# size
2214681df02Sjongkis	size=$(find "$UNPACKED_ROOT" -ls | nawk '
2224681df02Sjongkis	    {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
2234681df02Sjongkis	    END {print int(t * 1.10 / 1024)}')
224986fd29aSsetje	if [ "$COMPRESS" = true ] ; then
225342440ecSPrasad Singamsetty		size=`echo $size | nawk '{s = $1} END {print int(s * 0.6)}'`
226986fd29aSsetje	fi
2277c478bd9Sstevel@tonic-gate
22858091fd8Ssetje	/usr/sbin/mkfile ${size}k "$TMR"
22958091fd8Ssetje
23058091fd8Ssetje	LOFIDEV=`/usr/sbin/lofiadm -a "$TMR"`
2317c478bd9Sstevel@tonic-gate	if [ $? != 0 ] ; then
2327c478bd9Sstevel@tonic-gate		echo lofi plumb failed
2337c478bd9Sstevel@tonic-gate		exit 2
2347c478bd9Sstevel@tonic-gate	fi
2357c478bd9Sstevel@tonic-gate
23658091fd8Ssetje	RLOFIDEV=`echo $LOFIDEV | sed s/lofi/rlofi/`
23758091fd8Ssetje	newfs $RLOFIDEV < /dev/null 2> /dev/null
238781dc622Ssetje	mkdir -p $MNT
23958091fd8Ssetje	mount -o nologging $LOFIDEV $MNT
240781dc622Ssetje	rmdir $MNT/lost+found
241986fd29aSsetje
242986fd29aSsetje	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
243986fd29aSsetje		root_is_ramdisk $size
244986fd29aSsetje	fi
245986fd29aSsetje
246e482cb0aSjongkis	(
247781dc622Ssetje		cd "$UNPACKED_ROOT"
248986fd29aSsetje		if [ "$COMPRESS" = true ] ; then
249986fd29aSsetje			compress . $MNT
250986fd29aSsetje		else
2517c478bd9Sstevel@tonic-gate			find . -print | cpio -pdum $MNT 2> /dev/null
252986fd29aSsetje		fi
253e482cb0aSjongkis	)
2547c478bd9Sstevel@tonic-gate	lockfs -f $MNT
2557c478bd9Sstevel@tonic-gate	umount $MNT
2567c478bd9Sstevel@tonic-gate	rmdir $MNT
257986fd29aSsetje
258986fd29aSsetje	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
259986fd29aSsetje		"$UNPACKED_ROOT/usr/sbin/installboot" \
260d876c67dSjg		    "$UNPACKED_ROOT/platform/sun4u/lib/fs/ufs/bootblk" \
261986fd29aSsetje		    $RLOFIDEV
262986fd29aSsetje	fi
263986fd29aSsetje
26458091fd8Ssetje	lofiadm -d $LOFIDEV
265e482cb0aSjongkis	LOFIDEV=
2667c478bd9Sstevel@tonic-gate
26758091fd8Ssetje	rm -f "$TMR.gz"
268986fd29aSsetje
269986fd29aSsetje	if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
270986fd29aSsetje		mv "$TMR" "$MR"
271986fd29aSsetje	else
27258091fd8Ssetje		gzip -f "$TMR"
27358091fd8Ssetje		mv "$TMR.gz" "$MR"
274986fd29aSsetje	fi
275986fd29aSsetje
276781dc622Ssetje	chmod a+r "$MR"
2777c478bd9Sstevel@tonic-gate}
2787c478bd9Sstevel@tonic-gate
2791437d1e8Ssetjestrip_amd64()
2801437d1e8Ssetje{
2811437d1e8Ssetje	find "$UNPACKED_ROOT" -name amd64 -type directory | xargs rm -rf
2821437d1e8Ssetje}
2831437d1e8Ssetje
2847c478bd9Sstevel@tonic-gate# main
2857c478bd9Sstevel@tonic-gate#
2867c478bd9Sstevel@tonic-gate
28758091fd8SsetjeEXTRA_SPACE=0
288e482cb0aSjongkisSTRIP_AMD64=
289986fd29aSsetjeCOMPRESS=
29058091fd8Ssetje
291986fd29aSsetjePATH=/usr/sbin:/usr/bin:/opt/sfw/bin ; export PATH
292986fd29aSsetje
293986fd29aSsetjewhile getopts s:6c opt ; do
29458091fd8Ssetje	case $opt in
29558091fd8Ssetje	s)	EXTRA_SPACE="$OPTARG"
29658091fd8Ssetje		;;
29758091fd8Ssetje	6)	STRIP_AMD64=false
29858091fd8Ssetje		;;
299986fd29aSsetje	c)	COMPRESS=true
300986fd29aSsetje		;;
30158091fd8Ssetje	*)	usage
30258091fd8Ssetje		;;
30358091fd8Ssetje	esac
30458091fd8Ssetjedone
30558091fd8Ssetjeshift `expr $OPTIND - 1`
30658091fd8Ssetje
307f0778428SJerry Gilliam[ $# == 3 ] || usage
3087c478bd9Sstevel@tonic-gate
309781dc622SsetjeUNPACKED_ROOT="$3"
310781dc622SsetjeBASE="`pwd`"
3117c478bd9Sstevel@tonic-gateMNT=/tmp/mnt$$
31258091fd8SsetjeTMR=/tmp/mr$$
31358091fd8SsetjeLOFIDEV=
314781dc622SsetjeMR="$2"
3157c478bd9Sstevel@tonic-gate
316f0778428SJerry Gilliam# sanity check
317f0778428SJerry Gilliam[ "$UNPACKED_ROOT" != "/" ] || usage
318f0778428SJerry Gilliam
3197c478bd9Sstevel@tonic-gateif [ "`dirname $MR`" = . ] ; then
320781dc622Ssetje	MR="$BASE/$MR"
3217c478bd9Sstevel@tonic-gatefi
3227c478bd9Sstevel@tonic-gateif [ "`dirname $UNPACKED_ROOT`" = . ] ; then
323781dc622Ssetje	UNPACKED_ROOT="$BASE/$UNPACKED_ROOT"
3247c478bd9Sstevel@tonic-gatefi
3257c478bd9Sstevel@tonic-gate
32658091fd8Ssetjetrap cleanup EXIT
32758091fd8Ssetje
328f0778428SJerry Gilliam# always unpack into a fresh root
329f0778428SJerry Gilliamcase $1 in
330*a0eaab1eSAlexander Eremin	unpack)
331f0778428SJerry Gilliam		rm -rf "$UNPACKED_ROOT"
332f0778428SJerry Gilliam		mkdir -p "$UNPACKED_ROOT"
333f0778428SJerry Gilliam		;;
334f0778428SJerry Gilliamesac
335f0778428SJerry Gilliam[ -d "$UNPACKED_ROOT" ] || usage
336f0778428SJerry Gilliam
3377c478bd9Sstevel@tonic-gatecase $1 in
338f0778428SJerry Gilliam	pack)	pack "$MR"
339986fd29aSsetje		;;
340f0778428SJerry Gilliam	unpack)	unpack "$MR"
341986fd29aSsetje		;;
342986fd29aSsetje	*)	usage
343986fd29aSsetje		;;
3447c478bd9Sstevel@tonic-gateesac
345