10Sstevel@tonic-gate#!/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
62334Ssetje# Common Development and Distribution License (the "License").
72334Ssetje# 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
23*8735SEnrico.Perla@Sun.COM# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate# Use is subject to license terms.
250Sstevel@tonic-gate
260Sstevel@tonic-gateformat=ufs
270Sstevel@tonic-gateALT_ROOT=
286319SjgEXTRACT_ARGS=
293446Smrjcompress=yes
303446SmrjSPLIT=unknown
313446SmrjERROR=0
324213Srscottdirsize32=0
334213Srscottdirsize64=0
340Sstevel@tonic-gate
356319Sjgusage() {
366319Sjg	echo "This utility is a component of the bootadm(1M) implementation"
376319Sjg	echo "and it is not recommended for stand-alone use."
386319Sjg	echo "Please use bootadm(1M) instead."
396319Sjg	echo ""
406319Sjg	echo "Usage: ${0##*/}: [-R \<root\>] [-p \<platform\>] [--nocompress]"
416319Sjg	echo "where \<platform\> is one of i86pc, sun4u or sun4v"
426319Sjg	exit
436319Sjg}
446319Sjg
456319Sjg# default platform is what we're running on
466319SjgPLATFORM=`uname -m`
470Sstevel@tonic-gate
485648Ssetje#
495648Ssetje# set path, but inherit /tmp/bfubin if owned by
505648Ssetje# same uid executing this process, which must be root.
515648Ssetje#
525648Ssetjeif [ "`echo $PATH | cut -f 1 -d :`" = /tmp/bfubin ] && \
535648Ssetje    [ -O /tmp/bfubin ] ; then
545734Ssetje	export PATH=/tmp/bfubin
555734Ssetje	export GZIP_CMD=/tmp/bfubin/gzip
565648Ssetjeelse
575648Ssetje	export PATH=/usr/sbin:/usr/bin:/sbin
585734Ssetje	export GZIP_CMD=/usr/bin/gzip
595648Ssetjefi
605648Ssetje
615648SsetjeEXTRACT_FILELIST="/boot/solaris/bin/extract_boot_filelist"
620Sstevel@tonic-gate
630Sstevel@tonic-gate#
640Sstevel@tonic-gate# Parse options
650Sstevel@tonic-gate#
663446Smrjwhile [ "$1" != "" ]
670Sstevel@tonic-gatedo
683446Smrj        case $1 in
693446Smrj        -R)	shift
703446Smrj		ALT_ROOT="$1"
710Sstevel@tonic-gate		if [ "$ALT_ROOT" != "/" ]; then
725734Ssetje			echo "Creating boot_archive for $ALT_ROOT"
736319Sjg			EXTRACT_ARGS="${EXTRACT_ARGS} -R ${ALT_ROOT}"
745648Ssetje			EXTRACT_FILELIST="${ALT_ROOT}${EXTRACT_FILELIST}"
750Sstevel@tonic-gate		fi
760Sstevel@tonic-gate		;;
773467Srscott	-n|--nocompress) compress=no
783467Srscott		;;
796319Sjg	-p)	shift
806319Sjg		PLATFORM="$1"
816319Sjg		EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}"
826319Sjg		;;
836319Sjg        *)      usage
843467Srscott		;;
850Sstevel@tonic-gate        esac
863446Smrj	shift
870Sstevel@tonic-gatedone
880Sstevel@tonic-gate
890Sstevel@tonic-gateif [ -x /usr/bin/mkisofs -o -x /tmp/bfubin/mkisofs ] ; then
900Sstevel@tonic-gate	format=isofs
910Sstevel@tonic-gatefi
920Sstevel@tonic-gate
93621Svikram#
94621Svikram# mkisofs on s8 doesn't support functionality used by GRUB boot.
95621Svikram# Use ufs format for boot archive instead.
96621Svikram#
97621Svikramrelease=`uname -r`
98621Svikramif [ "$release" = "5.8" ]; then
993446Smrj	format=ufs
100621Svikramfi
101621Svikram
1020Sstevel@tonic-gateshift `expr $OPTIND - 1`
1030Sstevel@tonic-gate
1040Sstevel@tonic-gateif [ $# -eq 1 ]; then
1052334Ssetje	ALT_ROOT="$1"
1065734Ssetje	echo "Creating boot_archive for $ALT_ROOT"
1070Sstevel@tonic-gatefi
1080Sstevel@tonic-gate
1096319Sjgcase $PLATFORM in
1106319Sjgi386)	PLATFORM=i86pc
1116319Sjg	ISA=i386
1126319Sjg	ARCH64=amd64
1136319Sjg	;;
1146319Sjgi86pc)	ISA=i386
1156319Sjg	ARCH64=amd64
1166319Sjg	;;
1176319Sjgsun4u)	ISA=sparc
1186319Sjg	ARCH64=sparcv9
1196319Sjg	;;
1206319Sjgsun4v)	ISA=sparc
1216319Sjg	ARCH64=sparcv9
1226319Sjg	;;
1236319Sjg*)	usage
1246319Sjg	;;
1256319Sjgesac
1266319Sjg
1276319SjgBOOT_ARCHIVE=platform/$PLATFORM/boot_archive
1286319SjgBOOT_ARCHIVE_64=platform/$PLATFORM/$ARCH64/boot_archive
1296319Sjg
1306319Sjgif [ $PLATFORM = i86pc ] ; then
1316638Sjg	if [ ! -x "$ALT_ROOT"/boot/solaris/bin/symdef ]; then
1326638Sjg		# no dboot implies combined archives for example
1336638Sjg		# live-upgrade from s9 to s10u6 is multiboot-only
1345648Ssetje		echo "Creating single archive at $ALT_ROOT/$BOOT_ARCHIVE"
1355648Ssetje		SPLIT=no
1365648Ssetje		compress=no
1376638Sjg	else
1385648Ssetje		SPLIT=yes
1395648Ssetje	fi
1405648Ssetjeelse			# must be sparc
1415648Ssetje	SPLIT=no	# there's only 64-bit (sparcv9), so don't split
1425648Ssetje	compress=no
1433446Smrjfi
1443446Smrj
1455734Ssetje[ -x $GZIP_CMD ] || compress=no
1463446Smrj
1472334Ssetjefunction cleanup
1482334Ssetje{
1493446Smrj	umount -f "$rdmnt32" 2>/dev/null
1503446Smrj	umount -f "$rdmnt64" 2>/dev/null
1513446Smrj	lofiadm -d "$rdfile32" 2>/dev/null
1523446Smrj	lofiadm -d "$rdfile64" 2>/dev/null
1534213Srscott	[ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null
1544213Srscott	[ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null
1550Sstevel@tonic-gate}
1560Sstevel@tonic-gate
1572334Ssetjefunction getsize
1582334Ssetje{
1594213Srscott	# Estimate image size and add 10% overhead for ufs stuff.
1602511Sjongkis	# Note, we can't use du here in case we're on a filesystem, e.g. zfs,
1612511Sjongkis	# in which the disk usage is less than the sum of the file sizes.
1622511Sjongkis	# The nawk code
1632511Sjongkis	#
1644213Srscott	#	{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1652511Sjongkis	#
1662511Sjongkis	# below rounds up the size of a file/directory, in bytes, to the
1672511Sjongkis	# next multiple of 1024.  This mimics the behavior of ufs especially
1682511Sjongkis	# with directories.  This results in a total size that's slightly
1692511Sjongkis	# bigger than if du was called on a ufs directory.
1705648Ssetje	size32=$(cat "$list32" | xargs -I {} ls -lLd "{}" 2> /dev/null |
1715648Ssetje		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1724213Srscott		END {print int(t * 1.10 / 1024)}')
1734213Srscott	(( size32 += dirsize32 ))
1745648Ssetje	size64=$(cat "$list64" | xargs -I {} ls -lLd "{}" 2> /dev/null |
1755648Ssetje		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1764213Srscott		END {print int(t * 1.10 / 1024)}')
1774213Srscott	(( size64 += dirsize64 ))
1784213Srscott	(( total_size = size32 + size64 ))
1795648Ssetje
1805648Ssetje	if [ $compress = yes ] ; then
1815648Ssetje		total_size=`echo $total_size | nawk '{print int($1 / 2)}'`
1825648Ssetje	fi
1830Sstevel@tonic-gate}
1840Sstevel@tonic-gate
1853446Smrj#
1864213Srscott# Copies all desired files to a target directory.  One argument should be
1874213Srscott# passed: the file containing the list of files to copy.  This function also
1884213Srscott# depends on several variables that must be set before calling:
1893555Srscott#
1903555Srscott# $ALT_ROOT - the target directory
1913555Srscott# $compress - whether or not the files in the archives should be compressed
1923555Srscott# $rdmnt - the target directory
1933555Srscott#
1944213Srscottfunction copy_files
1953555Srscott{
1964213Srscott	list="$1"
1973555Srscott
1983555Srscott	#
1993555Srscott	# If compress is set, the files are gzip'd and put in the correct
2003555Srscott	# location in the loop.  Nothing is printed, so the pipe and cpio
2013555Srscott	# at the end is a nop.
2023555Srscott	#
2033555Srscott	# If compress is not set, the file names are printed, which causes
2043555Srscott	# the cpio at the end to do the copy.
2053555Srscott	#
2064213Srscott	while read path
2073555Srscott	do
2084213Srscott		if [ $compress = yes ]; then
2094213Srscott			dir="${path%/*}"
2106006Sdminer			[ -d "$rdmnt/$dir" ] || mkdir -p "$rdmnt/$dir"
2115734Ssetje			$GZIP_CMD -c "$path" > "$rdmnt/$path"
2123555Srscott		else
2134213Srscott			print "$path"
2143555Srscott		fi
2154213Srscott	done <"$list" | cpio -pdum "$rdmnt" 2>/dev/null
2165648Ssetje
2176319Sjg	if [ $ISA = sparc ] ; then
2185648Ssetje		# copy links
2195648Ssetje		find $filelist -type l -print 2>/dev/null |\
2205648Ssetje		    cpio -pdum "$rdmnt" 2>/dev/null
2215648Ssetje		if [ $compress = yes ] ; then
2225648Ssetje			# always copy unix uncompressed
2235648Ssetje			find $filelist -name unix -type f -print 2>/dev/null |\
2245648Ssetje			    cpio -pdum "$rdmnt" 2>/dev/null
2255648Ssetje		fi
2265648Ssetje	fi
2275648Ssetje
2283555Srscott}
2293555Srscott
2303555Srscott#
2313446Smrj# The first argument can be:
2323446Smrj#
2333446Smrj# "both" - create an archive with both 32-bit and 64-bit binaries
2343446Smrj# "32-bit" - create an archive with only 32-bit binaries
2353446Smrj# "64-bit" - create an archive with only 64-bit binaries
2363446Smrj#
2370Sstevel@tonic-gatefunction create_ufs
2380Sstevel@tonic-gate{
2393446Smrj	which=$1
2403446Smrj	archive=$2
2413446Smrj	lofidev=$3
2420Sstevel@tonic-gate
2433446Smrj	# should we exclude amd64 binaries?
2443446Smrj	if [ "$which" = "32-bit" ]; then
2453446Smrj		rdfile="$rdfile32"
2463446Smrj		rdmnt="$rdmnt32"
2474213Srscott		list="$list32"
2483446Smrj	elif [ "$which" = "64-bit" ]; then
2493446Smrj		rdfile="$rdfile64"
2503446Smrj		rdmnt="$rdmnt64"
2514213Srscott		list="$list64"
2523446Smrj	else
2533446Smrj		rdfile="$rdfile32"
2543446Smrj		rdmnt="$rdmnt32"
2554213Srscott		list="$list32"
2563446Smrj	fi
2573446Smrj
2582334Ssetje	newfs $lofidev < /dev/null 2> /dev/null
2592334Ssetje	mkdir "$rdmnt"
2600Sstevel@tonic-gate	mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
2616942Ssetje	mount -F ufs -o nologging $lofidev "$rdmnt"
2623446Smrj	files=
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate	# do the actual copy
2654213Srscott	copy_files "$list"
266*8735SEnrico.Perla@Sun.COM	umount -f "$rdmnt"
2672334Ssetje	rmdir "$rdmnt"
2682334Ssetje
2696319Sjg	if [ $ISA = sparc ] ; then
2705648Ssetje		rlofidev=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"`
2716319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk"
2726319Sjg		# installboot is not available on all platforms
2736319Sjg		dd if=$bb of=$rlofidev bs=1b oseek=1 count=15 conv=sync 2>&1
2745648Ssetje	fi
2755648Ssetje
2763446Smrj	#
2772334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
2782334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
2792334Ssetje	# pick it up from bfubin or something like that if needed.
2802334Ssetje	#
2813446Smrj	# If compress is set, the individual files in the archive are
2823446Smrj	# compressed, and the final compression will accomplish very
2833446Smrj	# little.  To save time, we skip the gzip in this case.
2843446Smrj	#
2856319Sjg	if [ $ISA = i386 ] && [ $compress = no ] && \
2865734Ssetje	    [ -x $GZIP_CMD ] ; then
2873446Smrj		gzip -c "$rdfile" > "${archive}-new"
2882334Ssetje	else
2893446Smrj		cat "$rdfile" > "${archive}-new"
2902334Ssetje	fi
291*8735SEnrico.Perla@Sun.COM
292*8735SEnrico.Perla@Sun.COM	if [ $? -ne 0 ] ; then
293*8735SEnrico.Perla@Sun.COM		rm -f "${archive}-new"
294*8735SEnrico.Perla@Sun.COM	fi
2950Sstevel@tonic-gate}
2960Sstevel@tonic-gate
2973446Smrj#
2983446Smrj# The first argument can be:
2993446Smrj#
3003446Smrj# "both" - create an archive with both 32-bit and 64-bit binaries
3013446Smrj# "32-bit" - create an archive with only 32-bit binaries
3023446Smrj# "64-bit" - create an archive with only 64-bit binaries
3033446Smrj#
3040Sstevel@tonic-gatefunction create_isofs
3050Sstevel@tonic-gate{
3063446Smrj	which=$1
3073446Smrj	archive=$2
3083446Smrj
3090Sstevel@tonic-gate	# should we exclude amd64 binaries?
3103446Smrj	if [ "$which" = "32-bit" ]; then
3113446Smrj		rdmnt="$rdmnt32"
3123446Smrj		errlog="$errlog32"
3134213Srscott		list="$list32"
3143446Smrj	elif [ "$which" = "64-bit" ]; then
3153446Smrj		rdmnt="$rdmnt64"
3163446Smrj		errlog="$errlog64"
3174213Srscott		list="$list64"
3183446Smrj	else
3193446Smrj		rdmnt="$rdmnt32"
3203446Smrj		errlog="$errlog32"
3214213Srscott		list="$list32"
3223446Smrj	fi
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate	# create image directory seed with graft points
3252334Ssetje	mkdir "$rdmnt"
3260Sstevel@tonic-gate	files=
3273446Smrj	isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames"
3283446Smrj
3296319Sjg	if [ $ISA = sparc ] ; then
3306319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
3315648Ssetje		isocmd="$isocmd -G \"$bb\""
3325648Ssetje	fi
3335648Ssetje
3344213Srscott	copy_files "$list"
3352334Ssetje	isocmd="$isocmd \"$rdmnt\""
3362334Ssetje	rm -f "$errlog"
3372334Ssetje
3383446Smrj	#
3392334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
3402334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
3412334Ssetje	# pick it up from bfubin or something like that if needed.
3422334Ssetje	#
3433446Smrj	# If compress is set, the individual files in the archive are
3443446Smrj	# compressed, and the final compression will accomplish very
3453446Smrj	# little.  To save time, we skip the gzip in this case.
3463446Smrj	#
347*8735SEnrico.Perla@Sun.COM	mkiso_ret=0
348*8735SEnrico.Perla@Sun.COM
3496319Sjg	if [ $ISA = i386 ] &&[ $compress = no ] && [ -x $GZIP_CMD ]
3505648Ssetje	then
3512334Ssetje		ksh -c "$isocmd" 2> "$errlog" | \
3523446Smrj		    gzip > "${archive}-new"
3532334Ssetje	else
3543446Smrj		ksh -c "$isocmd" 2> "$errlog" > "${archive}-new"
3552334Ssetje	fi
3562334Ssetje
357*8735SEnrico.Perla@Sun.COM	if [ $? -ne 0 ]; then
358*8735SEnrico.Perla@Sun.COM		cat "$errlog"
359*8735SEnrico.Perla@Sun.COM		rm -f "${archive}-new" 2> /dev/null
360*8735SEnrico.Perla@Sun.COM		rm -f "$errlog" 2> /dev/null
361*8735SEnrico.Perla@Sun.COM		return
362*8735SEnrico.Perla@Sun.COM	fi
363*8735SEnrico.Perla@Sun.COM
3645734Ssetje	dd_ret=0
3656319Sjg	if [ $ISA = sparc ] ; then
3666319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
3675734Ssetje		dd if="$bb" of="${archive}-new" bs=1b oseek=1 count=15 \
3685734Ssetje		    conv=notrunc conv=sync >> "$errlog" 2>&1
3695734Ssetje		dd_ret=$?
3705648Ssetje	fi
3715648Ssetje
3725734Ssetje	if [ -s "$errlog" ] || [ $dd_ret -ne 0 ] ; then
3732334Ssetje		grep Error: "$errlog" >/dev/null 2>&1
3745734Ssetje		if [ $? -eq 0 ] || [ $dd_ret -ne 0 ] ; then
3755734Ssetje			cat "$errlog"
3763446Smrj			rm -f "${archive}-new"
377174Sjg		fi
378174Sjg	fi
3792334Ssetje	rm -f "$errlog"
3800Sstevel@tonic-gate}
3810Sstevel@tonic-gate
3823446Smrjfunction create_archive
3833446Smrj{
3843446Smrj	which=$1
3853446Smrj	archive=$2
3863446Smrj	lofidev=$3
3873446Smrj
3885648Ssetje	echo "updating $archive"
3893446Smrj
3903446Smrj	if [ "$format" = "ufs" ]; then
3913446Smrj		create_ufs "$which" "$archive" "$lofidev"
3923446Smrj	else
3933446Smrj		create_isofs "$which" "$archive"
3943446Smrj	fi
3953446Smrj
3963446Smrj	# sanity check the archive before moving it into place
3973446Smrj	#
398*8735SEnrico.Perla@Sun.COM	ARCHIVE_SIZE=`ls -l "${archive}-new" 2> /dev/null | nawk '{ print $5 }'`
3996319Sjg	if [ $compress = yes ] || [ $ISA = sparc ] ; then
4003446Smrj		#
4013446Smrj		# 'file' will report "English text" for uncompressed
4023446Smrj		# boot_archives.  Checking for that doesn't seem stable,
4033446Smrj		# so we just check that the file exists.
4043446Smrj		#
4053446Smrj		ls "${archive}-new" >/dev/null 2>&1
4063446Smrj	else
4073446Smrj		#
4083446Smrj		# the file type check also establishes that the
4093446Smrj		# file exists at all
4103446Smrj		#
4113614Ssetje		LC_MESSAGES=C file "${archive}-new" | grep gzip > /dev/null
4123446Smrj	fi
4133446Smrj
414*8735SEnrico.Perla@Sun.COM	if [ $? = 1 ] && [ -x $GZIP_CMD ] || [ "$ARCHIVE_SIZE" -lt 10000 ]
4153446Smrj	then
4163446Smrj		#
4173446Smrj		# Two of these functions may be run in parallel.  We
4183446Smrj		# need to allow the other to clean up, so we can't
4193446Smrj		# exit immediately.  Instead, we set a flag.
4203446Smrj		#
4213446Smrj		echo "update of $archive failed"
4223446Smrj		ERROR=1
4233446Smrj	else
4243446Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
4253446Smrj		mv "${archive}-new" "$archive"
4263446Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
4273446Smrj	fi
4283446Smrj
4293446Smrj}
4303446Smrj
4314213Srscottfunction fatal_error
4324213Srscott{
4334213Srscott	print -u2 $*
4344213Srscott	exit 1
4354213Srscott}
4364213Srscott
4370Sstevel@tonic-gate#
4380Sstevel@tonic-gate# get filelist
4390Sstevel@tonic-gate#
4403555Srscottif [ ! -f "$ALT_ROOT/boot/solaris/filelist.ramdisk" ] &&
4413555Srscott    [ ! -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]
4422851Sjongkisthen
4432851Sjongkis	print -u2 "Can't find filelist.ramdisk"
4442851Sjongkis	exit 1
4450Sstevel@tonic-gatefi
4466319Sjgfilelist=$($EXTRACT_FILELIST $EXTRACT_ARGS \
4476319Sjg	/boot/solaris/filelist.ramdisk \
4486319Sjg	/etc/boot/solaris/filelist.ramdisk \
4496319Sjg		2>/dev/null | sort -u)
4500Sstevel@tonic-gate
4514213Srscott#
4524213Srscott# We use /tmp/ for scratch space now.  This may be changed later if there
4534213Srscott# is insufficient space in /tmp/.
4544213Srscott#
4554213Srscottrddir="/tmp/create_ramdisk.$$.tmp"
4564213Srscottnew_rddir=
4574213Srscottrm -rf "$rddir"
4584213Srscottmkdir "$rddir" || fatal_error "Could not create temporary directory $rddir"
4594213Srscott
4604213Srscott# Clean up upon exit.
4614213Srscotttrap 'cleanup' EXIT
4624213Srscott
4634213Srscottlist32="$rddir/filelist.32"
4644213Srscottlist64="$rddir/filelist.64"
4654213Srscott
4665648Ssetjetouch $list32 $list64
4675648Ssetje
4684213Srscott#
4694213Srscott# This loop creates the 32-bit and 64-bit lists of files.  The 32-bit list
4704213Srscott# is written to stdout, which is redirected at the end of the loop.  The
4714213Srscott# 64-bit list is appended with each write.
4724213Srscott#
4734213Srscottcd "/$ALT_ROOT"
4744213Srscottfind $filelist -print 2>/dev/null | while read path
4754213Srscottdo
4764213Srscott	if [ $SPLIT = no ]; then
4774213Srscott		print "$path"
4784213Srscott	elif [ -d "$path" ]; then
4794213Srscott		if [ $format = ufs ]; then
4804213Srscott			size=`ls -lLd "$path" | nawk '
4814213Srscott			    {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'`
4824213Srscott			if [ `basename "$path"` != "amd64" ]; then
4834213Srscott				(( dirsize32 += size ))
4844213Srscott			fi
4854213Srscott			(( dirsize64 += size ))
4864213Srscott		fi
4874213Srscott	else
4886006Sdminer		case `LC_MESSAGES=C /usr/bin/file -m /dev/null "$path" 2>/dev/null` in
4896006Sdminer		*ELF\ 64-bit*)
4904213Srscott			print "$path" >> "$list64"
4916006Sdminer			;;
4926006Sdminer		*ELF\ 32-bit*)
4934213Srscott			print "$path"
4946006Sdminer			;;
4956006Sdminer		*)
4964213Srscott			# put in both lists
4974213Srscott			print "$path"
4984213Srscott			print "$path" >> "$list64"
4996006Sdminer		esac
5004213Srscott	fi
5014213Srscottdone >"$list32"
5022334Ssetje
5032334Ssetjeif [ $format = ufs ] ; then
5042334Ssetje	# calculate image size
5052334Ssetje	getsize
5062334Ssetje
5072334Ssetje	# check to see if there is sufficient space in tmpfs
5082334Ssetje	#
5092334Ssetje	tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
5107659SJerry.Gilliam@Sun.COM	(( tmp_free = tmp_free / 3 ))
5117659SJerry.Gilliam@Sun.COM	if [ $SPLIT = yes ]; then
5127659SJerry.Gilliam@Sun.COM		(( tmp_free = tmp_free / 2 ))
5137659SJerry.Gilliam@Sun.COM	fi
5142334Ssetje
5154213Srscott	if [ $total_size -gt $tmp_free  ] ; then
5162334Ssetje		# assumes we have enough scratch space on $ALT_ROOT
5177659SJerry.Gilliam@Sun.COM		new_rddir="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp"
5184213Srscott		rm -rf "$new_rddir"
5194213Srscott		mkdir "$new_rddir" || fatal_error \
5204213Srscott		    "Could not create temporary directory $new_rddir"
5214213Srscott
5224213Srscott		# Save the file lists
5234213Srscott		mv "$list32" "$new_rddir"/
5244213Srscott		mv "$list64" "$new_rddir"/
5254213Srscott		list32="/$new_rddir/filelist.32"
5264213Srscott		list64="/$new_rddir/filelist.64"
5274213Srscott
5284213Srscott		# Remove the old $rddir and set the new value of rddir
5294213Srscott		rm -rf "$rddir"
5304213Srscott		rddir="$new_rddir"
5314213Srscott		new_rddir=
5322334Ssetje	fi
5332334Ssetjefi
5342334Ssetje
5353446Smrjrdfile32="$rddir/rd.file.32"
5363446Smrjrdfile64="$rddir/rd.file.64"
5373446Smrjrdmnt32="$rddir/rd.mount.32"
5383446Smrjrdmnt64="$rddir/rd.mount.64"
5393446Smrjerrlog32="$rddir/rd.errlog.32"
5403446Smrjerrlog64="$rddir/rd.errlog.64"
5413446Smrjlofidev32=""
5423446Smrjlofidev64=""
5432334Ssetje
5443446Smrjif [ $SPLIT = yes ]; then
5453446Smrj	#
5463446Smrj	# We can't run lofiadm commands in parallel, so we have to do
5473446Smrj	# them here.
5483446Smrj	#
5493446Smrj	if [ "$format" = "ufs" ]; then
5504213Srscott		mkfile ${size32}k "$rdfile32"
5513446Smrj		lofidev32=`lofiadm -a "$rdfile32"`
5524213Srscott		mkfile ${size64}k "$rdfile64"
5533446Smrj		lofidev64=`lofiadm -a "$rdfile64"`
5543446Smrj	fi
5553446Smrj	create_archive "32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 &
5563446Smrj	create_archive "64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64
5573446Smrj	wait
5583446Smrj	if [ "$format" = "ufs" ]; then
5593446Smrj		lofiadm -d "$rdfile32"
5603446Smrj		lofiadm -d "$rdfile64"
5613446Smrj	fi
5620Sstevel@tonic-gateelse
5633446Smrj	if [ "$format" = "ufs" ]; then
5643446Smrj		mkfile ${total_size}k "$rdfile32"
5653446Smrj		lofidev32=`lofiadm -a "$rdfile32"`
5663446Smrj	fi
5673446Smrj	create_archive "both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32
5683446Smrj	[ "$format" = "ufs" ] && lofiadm -d "$rdfile32"
5690Sstevel@tonic-gatefi
5703446Smrjif [ $ERROR = 1 ]; then
5713446Smrj	cleanup
572174Sjg	exit 1
573174Sjgfi
574174Sjg
5750Sstevel@tonic-gate#
5760Sstevel@tonic-gate# For the diskless case, hardlink archive to /boot to make it
5770Sstevel@tonic-gate# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
5783446Smrj# NOTE: this script must work on both client and server.
5790Sstevel@tonic-gate#
5802334Ssetjegrep "[	 ]/[	 ]*nfs[	 ]" "$ALT_ROOT/etc/vfstab" > /dev/null
5810Sstevel@tonic-gateif [ $? = 0 ]; then
5823446Smrj	rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive"
5832334Ssetje	ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
5846319Sjg	if [ $SPLIT = yes ]; then
5856319Sjg		ln "$ALT_ROOT/$BOOT_ARCHIVE_64" \
5866319Sjg		    "$ALT_ROOT/boot/amd64/boot_archive"
5876319Sjg	fi
5880Sstevel@tonic-gatefi
5894213Srscott[ -n "$rddir" ] && rm -rf "$rddir"
590