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
236006Sdminer# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate# Use is subject to license terms.
250Sstevel@tonic-gate
262334Ssetje# ident	"%Z%%M%	%I%	%E% SMI"
27174Sjg
280Sstevel@tonic-gateformat=ufs
290Sstevel@tonic-gateALT_ROOT=
30*6319SjgEXTRACT_ARGS=
313446Smrjcompress=yes
323446SmrjSPLIT=unknown
333446SmrjERROR=0
344213Srscottdirsize32=0
354213Srscottdirsize64=0
360Sstevel@tonic-gate
37*6319Sjgusage() {
38*6319Sjg	echo "This utility is a component of the bootadm(1M) implementation"
39*6319Sjg	echo "and it is not recommended for stand-alone use."
40*6319Sjg	echo "Please use bootadm(1M) instead."
41*6319Sjg	echo ""
42*6319Sjg	echo "Usage: ${0##*/}: [-R \<root\>] [-p \<platform\>] [--nocompress]"
43*6319Sjg	echo "where \<platform\> is one of i86pc, sun4u or sun4v"
44*6319Sjg	exit
45*6319Sjg}
46*6319Sjg
47*6319Sjg# default platform is what we're running on
48*6319SjgPLATFORM=`uname -m`
490Sstevel@tonic-gate
505648Ssetje#
515648Ssetje# set path, but inherit /tmp/bfubin if owned by
525648Ssetje# same uid executing this process, which must be root.
535648Ssetje#
545648Ssetjeif [ "`echo $PATH | cut -f 1 -d :`" = /tmp/bfubin ] && \
555648Ssetje    [ -O /tmp/bfubin ] ; then
565734Ssetje	export PATH=/tmp/bfubin
575734Ssetje	export GZIP_CMD=/tmp/bfubin/gzip
585648Ssetjeelse
595648Ssetje	export PATH=/usr/sbin:/usr/bin:/sbin
605734Ssetje	export GZIP_CMD=/usr/bin/gzip
615648Ssetjefi
625648Ssetje
635648SsetjeEXTRACT_FILELIST="/boot/solaris/bin/extract_boot_filelist"
640Sstevel@tonic-gate
650Sstevel@tonic-gate#
660Sstevel@tonic-gate# Parse options
670Sstevel@tonic-gate#
683446Smrjwhile [ "$1" != "" ]
690Sstevel@tonic-gatedo
703446Smrj        case $1 in
713446Smrj        -R)	shift
723446Smrj		ALT_ROOT="$1"
730Sstevel@tonic-gate		if [ "$ALT_ROOT" != "/" ]; then
745734Ssetje			echo "Creating boot_archive for $ALT_ROOT"
75*6319Sjg			EXTRACT_ARGS="${EXTRACT_ARGS} -R ${ALT_ROOT}"
765648Ssetje			EXTRACT_FILELIST="${ALT_ROOT}${EXTRACT_FILELIST}"
770Sstevel@tonic-gate		fi
780Sstevel@tonic-gate		;;
793467Srscott	-n|--nocompress) compress=no
803467Srscott		;;
81*6319Sjg	-p)	shift
82*6319Sjg		PLATFORM="$1"
83*6319Sjg		EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}"
84*6319Sjg		;;
85*6319Sjg        *)      usage
863467Srscott		;;
870Sstevel@tonic-gate        esac
883446Smrj	shift
890Sstevel@tonic-gatedone
900Sstevel@tonic-gate
910Sstevel@tonic-gateif [ -x /usr/bin/mkisofs -o -x /tmp/bfubin/mkisofs ] ; then
920Sstevel@tonic-gate	format=isofs
930Sstevel@tonic-gatefi
940Sstevel@tonic-gate
95621Svikram#
96621Svikram# mkisofs on s8 doesn't support functionality used by GRUB boot.
97621Svikram# Use ufs format for boot archive instead.
98621Svikram#
99621Svikramrelease=`uname -r`
100621Svikramif [ "$release" = "5.8" ]; then
1013446Smrj	format=ufs
102621Svikramfi
103621Svikram
1040Sstevel@tonic-gateshift `expr $OPTIND - 1`
1050Sstevel@tonic-gate
1060Sstevel@tonic-gateif [ $# -eq 1 ]; then
1072334Ssetje	ALT_ROOT="$1"
1085734Ssetje	echo "Creating boot_archive for $ALT_ROOT"
1090Sstevel@tonic-gatefi
1100Sstevel@tonic-gate
111*6319Sjgcase $PLATFORM in
112*6319Sjgi386)	PLATFORM=i86pc
113*6319Sjg	ISA=i386
114*6319Sjg	ARCH64=amd64
115*6319Sjg	;;
116*6319Sjgi86pc)	ISA=i386
117*6319Sjg	ARCH64=amd64
118*6319Sjg	;;
119*6319Sjgsun4u)	ISA=sparc
120*6319Sjg	ARCH64=sparcv9
121*6319Sjg	;;
122*6319Sjgsun4v)	ISA=sparc
123*6319Sjg	ARCH64=sparcv9
124*6319Sjg	;;
125*6319Sjg*)	usage
126*6319Sjg	;;
127*6319Sjgesac
128*6319Sjg
129*6319SjgBOOT_ARCHIVE=platform/$PLATFORM/boot_archive
130*6319SjgBOOT_ARCHIVE_64=platform/$PLATFORM/$ARCH64/boot_archive
131*6319Sjg
132*6319Sjgif [ $PLATFORM = i86pc ] ; then
133*6319Sjg	NM=/bin/nm
134*6319Sjg	SYMDEF=/boot/solaris/bin/symdef
135*6319Sjg	if [ -x $NM ]; then
136*6319Sjg		$NM "$ALT_ROOT"/platform/i86pc/kernel/unix | \
137*6319Sjg		    grep dboot_image >/dev/null 2>&1
138*6319Sjg		if [ $? = 0 ]; then
139*6319Sjg			SPLIT=yes
140*6319Sjg		else
141*6319Sjg			SPLIT=no
142*6319Sjg			compress=no
143*6319Sjg		fi
144*6319Sjg	elif [ ! -x $SYMDEF ]; then
1455648Ssetje		# Shouldn't happen
146*6319Sjg		echo "Warning: both $NM and $SYMDEF not present."
1475648Ssetje		echo "Creating single archive at $ALT_ROOT/$BOOT_ARCHIVE"
1485648Ssetje		SPLIT=no
1495648Ssetje		compress=no
150*6319Sjg	elif $SYMDEF "$ALT_ROOT"/platform/i86pc/kernel/unix \
1515648Ssetje	    dboot_image 2>/dev/null; then
1525648Ssetje		SPLIT=yes
1535648Ssetje	else
154*6319Sjg		# no dboot
1555648Ssetje		SPLIT=no
1565648Ssetje		compress=no
1575648Ssetje	fi
1585648Ssetjeelse			# must be sparc
1595648Ssetje	SPLIT=no	# there's only 64-bit (sparcv9), so don't split
1605648Ssetje	compress=no
1613446Smrjfi
1623446Smrj
1635734Ssetje[ -x $GZIP_CMD ] || compress=no
1643446Smrj
1652334Ssetjefunction cleanup
1662334Ssetje{
1673446Smrj	umount -f "$rdmnt32" 2>/dev/null
1683446Smrj	umount -f "$rdmnt64" 2>/dev/null
1693446Smrj	lofiadm -d "$rdfile32" 2>/dev/null
1703446Smrj	lofiadm -d "$rdfile64" 2>/dev/null
1714213Srscott	[ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null
1724213Srscott	[ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null
1730Sstevel@tonic-gate}
1740Sstevel@tonic-gate
1752334Ssetjefunction getsize
1762334Ssetje{
1774213Srscott	# Estimate image size and add 10% overhead for ufs stuff.
1782511Sjongkis	# Note, we can't use du here in case we're on a filesystem, e.g. zfs,
1792511Sjongkis	# in which the disk usage is less than the sum of the file sizes.
1802511Sjongkis	# The nawk code
1812511Sjongkis	#
1824213Srscott	#	{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1832511Sjongkis	#
1842511Sjongkis	# below rounds up the size of a file/directory, in bytes, to the
1852511Sjongkis	# next multiple of 1024.  This mimics the behavior of ufs especially
1862511Sjongkis	# with directories.  This results in a total size that's slightly
1872511Sjongkis	# bigger than if du was called on a ufs directory.
1885648Ssetje	size32=$(cat "$list32" | xargs -I {} ls -lLd "{}" 2> /dev/null |
1895648Ssetje		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1904213Srscott		END {print int(t * 1.10 / 1024)}')
1914213Srscott	(( size32 += dirsize32 ))
1925648Ssetje	size64=$(cat "$list64" | xargs -I {} ls -lLd "{}" 2> /dev/null |
1935648Ssetje		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1944213Srscott		END {print int(t * 1.10 / 1024)}')
1954213Srscott	(( size64 += dirsize64 ))
1964213Srscott	(( total_size = size32 + size64 ))
1975648Ssetje
1985648Ssetje	if [ $compress = yes ] ; then
1995648Ssetje		total_size=`echo $total_size | nawk '{print int($1 / 2)}'`
2005648Ssetje	fi
2010Sstevel@tonic-gate}
2020Sstevel@tonic-gate
2033446Smrj#
2044213Srscott# Copies all desired files to a target directory.  One argument should be
2054213Srscott# passed: the file containing the list of files to copy.  This function also
2064213Srscott# depends on several variables that must be set before calling:
2073555Srscott#
2083555Srscott# $ALT_ROOT - the target directory
2093555Srscott# $compress - whether or not the files in the archives should be compressed
2103555Srscott# $rdmnt - the target directory
2113555Srscott#
2124213Srscottfunction copy_files
2133555Srscott{
2144213Srscott	list="$1"
2153555Srscott
2163555Srscott	#
2173555Srscott	# If compress is set, the files are gzip'd and put in the correct
2183555Srscott	# location in the loop.  Nothing is printed, so the pipe and cpio
2193555Srscott	# at the end is a nop.
2203555Srscott	#
2213555Srscott	# If compress is not set, the file names are printed, which causes
2223555Srscott	# the cpio at the end to do the copy.
2233555Srscott	#
2244213Srscott	while read path
2253555Srscott	do
2264213Srscott		if [ $compress = yes ]; then
2274213Srscott			dir="${path%/*}"
2286006Sdminer			[ -d "$rdmnt/$dir" ] || mkdir -p "$rdmnt/$dir"
2295734Ssetje			$GZIP_CMD -c "$path" > "$rdmnt/$path"
2303555Srscott		else
2314213Srscott			print "$path"
2323555Srscott		fi
2334213Srscott	done <"$list" | cpio -pdum "$rdmnt" 2>/dev/null
2345648Ssetje
235*6319Sjg	if [ $ISA = sparc ] ; then
2365648Ssetje		# copy links
2375648Ssetje		find $filelist -type l -print 2>/dev/null |\
2385648Ssetje		    cpio -pdum "$rdmnt" 2>/dev/null
2395648Ssetje		if [ $compress = yes ] ; then
2405648Ssetje			# always copy unix uncompressed
2415648Ssetje			find $filelist -name unix -type f -print 2>/dev/null |\
2425648Ssetje			    cpio -pdum "$rdmnt" 2>/dev/null
2435648Ssetje		fi
2445648Ssetje	fi
2455648Ssetje
2463555Srscott}
2473555Srscott
2483555Srscott#
2493446Smrj# The first argument can be:
2503446Smrj#
2513446Smrj# "both" - create an archive with both 32-bit and 64-bit binaries
2523446Smrj# "32-bit" - create an archive with only 32-bit binaries
2533446Smrj# "64-bit" - create an archive with only 64-bit binaries
2543446Smrj#
2550Sstevel@tonic-gatefunction create_ufs
2560Sstevel@tonic-gate{
2573446Smrj	which=$1
2583446Smrj	archive=$2
2593446Smrj	lofidev=$3
2600Sstevel@tonic-gate
2613446Smrj	# should we exclude amd64 binaries?
2623446Smrj	if [ "$which" = "32-bit" ]; then
2633446Smrj		rdfile="$rdfile32"
2643446Smrj		rdmnt="$rdmnt32"
2654213Srscott		list="$list32"
2663446Smrj	elif [ "$which" = "64-bit" ]; then
2673446Smrj		rdfile="$rdfile64"
2683446Smrj		rdmnt="$rdmnt64"
2694213Srscott		list="$list64"
2703446Smrj	else
2713446Smrj		rdfile="$rdfile32"
2723446Smrj		rdmnt="$rdmnt32"
2734213Srscott		list="$list32"
2743446Smrj	fi
2753446Smrj
2762334Ssetje	newfs $lofidev < /dev/null 2> /dev/null
2772334Ssetje	mkdir "$rdmnt"
2780Sstevel@tonic-gate	mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
2792334Ssetje	mount -o nologging $lofidev "$rdmnt"
2803446Smrj	files=
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate	# do the actual copy
2834213Srscott	copy_files "$list"
2842334Ssetje	umount "$rdmnt"
2852334Ssetje	rmdir "$rdmnt"
2862334Ssetje
287*6319Sjg	if [ $ISA = sparc ] ; then
2885648Ssetje		rlofidev=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"`
289*6319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk"
290*6319Sjg		# installboot is not available on all platforms
291*6319Sjg		dd if=$bb of=$rlofidev bs=1b oseek=1 count=15 conv=sync 2>&1
2925648Ssetje	fi
2935648Ssetje
2943446Smrj	#
2952334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
2962334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
2972334Ssetje	# pick it up from bfubin or something like that if needed.
2982334Ssetje	#
2993446Smrj	# If compress is set, the individual files in the archive are
3003446Smrj	# compressed, and the final compression will accomplish very
3013446Smrj	# little.  To save time, we skip the gzip in this case.
3023446Smrj	#
303*6319Sjg	if [ $ISA = i386 ] && [ $compress = no ] && \
3045734Ssetje	    [ -x $GZIP_CMD ] ; then
3053446Smrj		gzip -c "$rdfile" > "${archive}-new"
3062334Ssetje	else
3073446Smrj		cat "$rdfile" > "${archive}-new"
3082334Ssetje	fi
3090Sstevel@tonic-gate}
3100Sstevel@tonic-gate
3113446Smrj#
3123446Smrj# The first argument can be:
3133446Smrj#
3143446Smrj# "both" - create an archive with both 32-bit and 64-bit binaries
3153446Smrj# "32-bit" - create an archive with only 32-bit binaries
3163446Smrj# "64-bit" - create an archive with only 64-bit binaries
3173446Smrj#
3180Sstevel@tonic-gatefunction create_isofs
3190Sstevel@tonic-gate{
3203446Smrj	which=$1
3213446Smrj	archive=$2
3223446Smrj
3230Sstevel@tonic-gate	# should we exclude amd64 binaries?
3243446Smrj	if [ "$which" = "32-bit" ]; then
3253446Smrj		rdmnt="$rdmnt32"
3263446Smrj		errlog="$errlog32"
3274213Srscott		list="$list32"
3283446Smrj	elif [ "$which" = "64-bit" ]; then
3293446Smrj		rdmnt="$rdmnt64"
3303446Smrj		errlog="$errlog64"
3314213Srscott		list="$list64"
3323446Smrj	else
3333446Smrj		rdmnt="$rdmnt32"
3343446Smrj		errlog="$errlog32"
3354213Srscott		list="$list32"
3363446Smrj	fi
3370Sstevel@tonic-gate
3380Sstevel@tonic-gate	# create image directory seed with graft points
3392334Ssetje	mkdir "$rdmnt"
3400Sstevel@tonic-gate	files=
3413446Smrj	isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames"
3423446Smrj
343*6319Sjg	if [ $ISA = sparc ] ; then
344*6319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
3455648Ssetje		isocmd="$isocmd -G \"$bb\""
3465648Ssetje	fi
3475648Ssetje
3484213Srscott	copy_files "$list"
3492334Ssetje	isocmd="$isocmd \"$rdmnt\""
3502334Ssetje	rm -f "$errlog"
3512334Ssetje
3523446Smrj	#
3532334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
3542334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
3552334Ssetje	# pick it up from bfubin or something like that if needed.
3562334Ssetje	#
3573446Smrj	# If compress is set, the individual files in the archive are
3583446Smrj	# compressed, and the final compression will accomplish very
3593446Smrj	# little.  To save time, we skip the gzip in this case.
3603446Smrj	#
361*6319Sjg	if [ $ISA = i386 ] &&[ $compress = no ] && [ -x $GZIP_CMD ]
3625648Ssetje	then
3632334Ssetje		ksh -c "$isocmd" 2> "$errlog" | \
3643446Smrj		    gzip > "${archive}-new"
3652334Ssetje	else
3663446Smrj		ksh -c "$isocmd" 2> "$errlog" > "${archive}-new"
3672334Ssetje	fi
3682334Ssetje
3695734Ssetje	dd_ret=0
370*6319Sjg	if [ $ISA = sparc ] ; then
371*6319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
3725734Ssetje		dd if="$bb" of="${archive}-new" bs=1b oseek=1 count=15 \
3735734Ssetje		    conv=notrunc conv=sync >> "$errlog" 2>&1
3745734Ssetje		dd_ret=$?
3755648Ssetje	fi
3765648Ssetje
3775734Ssetje	if [ -s "$errlog" ] || [ $dd_ret -ne 0 ] ; then
3782334Ssetje		grep Error: "$errlog" >/dev/null 2>&1
3795734Ssetje		if [ $? -eq 0 ] || [ $dd_ret -ne 0 ] ; then
3805734Ssetje			cat "$errlog"
3813446Smrj			rm -f "${archive}-new"
382174Sjg		fi
383174Sjg	fi
3842334Ssetje	rm -f "$errlog"
3850Sstevel@tonic-gate}
3860Sstevel@tonic-gate
3873446Smrjfunction create_archive
3883446Smrj{
3893446Smrj	which=$1
3903446Smrj	archive=$2
3913446Smrj	lofidev=$3
3923446Smrj
3935648Ssetje	echo "updating $archive"
3943446Smrj
3953446Smrj	if [ "$format" = "ufs" ]; then
3963446Smrj		create_ufs "$which" "$archive" "$lofidev"
3973446Smrj	else
3983446Smrj		create_isofs "$which" "$archive"
3993446Smrj	fi
4003446Smrj
4013446Smrj	# sanity check the archive before moving it into place
4023446Smrj	#
4033555Srscott	ARCHIVE_SIZE=`ls -l "${archive}-new" | nawk '{ print $5 }'`
404*6319Sjg	if [ $compress = yes ] || [ $ISA = sparc ] ; then
4053446Smrj		#
4063446Smrj		# 'file' will report "English text" for uncompressed
4073446Smrj		# boot_archives.  Checking for that doesn't seem stable,
4083446Smrj		# so we just check that the file exists.
4093446Smrj		#
4103446Smrj		ls "${archive}-new" >/dev/null 2>&1
4113446Smrj	else
4123446Smrj		#
4133446Smrj		# the file type check also establishes that the
4143446Smrj		# file exists at all
4153446Smrj		#
4163614Ssetje		LC_MESSAGES=C file "${archive}-new" | grep gzip > /dev/null
4173446Smrj	fi
4183446Smrj
4195734Ssetje	if [ $? = 1 ] && [ -x $GZIP_CMD ] || [ $ARCHIVE_SIZE -lt 5000 ]
4203446Smrj	then
4213446Smrj		#
4223446Smrj		# Two of these functions may be run in parallel.  We
4233446Smrj		# need to allow the other to clean up, so we can't
4243446Smrj		# exit immediately.  Instead, we set a flag.
4253446Smrj		#
4263446Smrj		echo "update of $archive failed"
4273446Smrj		ERROR=1
4283446Smrj	else
4293446Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
4303446Smrj		mv "${archive}-new" "$archive"
4313446Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
4323446Smrj	fi
4333446Smrj
4343446Smrj}
4353446Smrj
4364213Srscottfunction fatal_error
4374213Srscott{
4384213Srscott	print -u2 $*
4394213Srscott	exit 1
4404213Srscott}
4414213Srscott
4420Sstevel@tonic-gate#
4430Sstevel@tonic-gate# get filelist
4440Sstevel@tonic-gate#
4453555Srscottif [ ! -f "$ALT_ROOT/boot/solaris/filelist.ramdisk" ] &&
4463555Srscott    [ ! -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]
4472851Sjongkisthen
4482851Sjongkis	print -u2 "Can't find filelist.ramdisk"
4492851Sjongkis	exit 1
4500Sstevel@tonic-gatefi
451*6319Sjgfilelist=$($EXTRACT_FILELIST $EXTRACT_ARGS \
452*6319Sjg	/boot/solaris/filelist.ramdisk \
453*6319Sjg	/etc/boot/solaris/filelist.ramdisk \
454*6319Sjg		2>/dev/null | sort -u)
4550Sstevel@tonic-gate
4564213Srscott#
4574213Srscott# We use /tmp/ for scratch space now.  This may be changed later if there
4584213Srscott# is insufficient space in /tmp/.
4594213Srscott#
4604213Srscottrddir="/tmp/create_ramdisk.$$.tmp"
4614213Srscottnew_rddir=
4624213Srscottrm -rf "$rddir"
4634213Srscottmkdir "$rddir" || fatal_error "Could not create temporary directory $rddir"
4644213Srscott
4654213Srscott# Clean up upon exit.
4664213Srscotttrap 'cleanup' EXIT
4674213Srscott
4684213Srscottlist32="$rddir/filelist.32"
4694213Srscottlist64="$rddir/filelist.64"
4704213Srscott
4715648Ssetjetouch $list32 $list64
4725648Ssetje
4734213Srscott#
4744213Srscott# This loop creates the 32-bit and 64-bit lists of files.  The 32-bit list
4754213Srscott# is written to stdout, which is redirected at the end of the loop.  The
4764213Srscott# 64-bit list is appended with each write.
4774213Srscott#
4784213Srscottcd "/$ALT_ROOT"
4794213Srscottfind $filelist -print 2>/dev/null | while read path
4804213Srscottdo
4814213Srscott	if [ $SPLIT = no ]; then
4824213Srscott		print "$path"
4834213Srscott	elif [ -d "$path" ]; then
4844213Srscott		if [ $format = ufs ]; then
4854213Srscott			size=`ls -lLd "$path" | nawk '
4864213Srscott			    {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'`
4874213Srscott			if [ `basename "$path"` != "amd64" ]; then
4884213Srscott				(( dirsize32 += size ))
4894213Srscott			fi
4904213Srscott			(( dirsize64 += size ))
4914213Srscott		fi
4924213Srscott	else
4936006Sdminer		case `LC_MESSAGES=C /usr/bin/file -m /dev/null "$path" 2>/dev/null` in
4946006Sdminer		*ELF\ 64-bit*)
4954213Srscott			print "$path" >> "$list64"
4966006Sdminer			;;
4976006Sdminer		*ELF\ 32-bit*)
4984213Srscott			print "$path"
4996006Sdminer			;;
5006006Sdminer		*)
5014213Srscott			# put in both lists
5024213Srscott			print "$path"
5034213Srscott			print "$path" >> "$list64"
5046006Sdminer		esac
5054213Srscott	fi
5064213Srscottdone >"$list32"
5072334Ssetje
5082334Ssetjeif [ $format = ufs ] ; then
5092334Ssetje	# calculate image size
5102334Ssetje	getsize
5112334Ssetje
5122334Ssetje	# check to see if there is sufficient space in tmpfs
5132334Ssetje	#
5142334Ssetje	tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
5152334Ssetje	(( tmp_free = tmp_free / 2 ))
5162334Ssetje
5174213Srscott	if [ $total_size -gt $tmp_free  ] ; then
5182334Ssetje		# assumes we have enough scratch space on $ALT_ROOT
5194213Srscott		new_rddir="/$ALT_ROOT/create_ramdisk.$$.tmp"
5204213Srscott		rm -rf "$new_rddir"
5214213Srscott		mkdir "$new_rddir" || fatal_error \
5224213Srscott		    "Could not create temporary directory $new_rddir"
5234213Srscott
5244213Srscott		# Save the file lists
5254213Srscott		mv "$list32" "$new_rddir"/
5264213Srscott		mv "$list64" "$new_rddir"/
5274213Srscott		list32="/$new_rddir/filelist.32"
5284213Srscott		list64="/$new_rddir/filelist.64"
5294213Srscott
5304213Srscott		# Remove the old $rddir and set the new value of rddir
5314213Srscott		rm -rf "$rddir"
5324213Srscott		rddir="$new_rddir"
5334213Srscott		new_rddir=
5342334Ssetje	fi
5352334Ssetjefi
5362334Ssetje
5373446Smrjrdfile32="$rddir/rd.file.32"
5383446Smrjrdfile64="$rddir/rd.file.64"
5393446Smrjrdmnt32="$rddir/rd.mount.32"
5403446Smrjrdmnt64="$rddir/rd.mount.64"
5413446Smrjerrlog32="$rddir/rd.errlog.32"
5423446Smrjerrlog64="$rddir/rd.errlog.64"
5433446Smrjlofidev32=""
5443446Smrjlofidev64=""
5452334Ssetje
5463446Smrjif [ $SPLIT = yes ]; then
5473446Smrj	#
5483446Smrj	# We can't run lofiadm commands in parallel, so we have to do
5493446Smrj	# them here.
5503446Smrj	#
5513446Smrj	if [ "$format" = "ufs" ]; then
5524213Srscott		mkfile ${size32}k "$rdfile32"
5533446Smrj		lofidev32=`lofiadm -a "$rdfile32"`
5544213Srscott		mkfile ${size64}k "$rdfile64"
5553446Smrj		lofidev64=`lofiadm -a "$rdfile64"`
5563446Smrj	fi
5573446Smrj	create_archive "32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 &
5583446Smrj	create_archive "64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64
5593446Smrj	wait
5603446Smrj	if [ "$format" = "ufs" ]; then
5613446Smrj		lofiadm -d "$rdfile32"
5623446Smrj		lofiadm -d "$rdfile64"
5633446Smrj	fi
5640Sstevel@tonic-gateelse
5653446Smrj	if [ "$format" = "ufs" ]; then
5663446Smrj		mkfile ${total_size}k "$rdfile32"
5673446Smrj		lofidev32=`lofiadm -a "$rdfile32"`
5683446Smrj	fi
5693446Smrj	create_archive "both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32
5703446Smrj	[ "$format" = "ufs" ] && lofiadm -d "$rdfile32"
5710Sstevel@tonic-gatefi
5723446Smrjif [ $ERROR = 1 ]; then
5733446Smrj	cleanup
574174Sjg	exit 1
575174Sjgfi
576174Sjg
5770Sstevel@tonic-gate#
5780Sstevel@tonic-gate# For the diskless case, hardlink archive to /boot to make it
5790Sstevel@tonic-gate# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
5803446Smrj# NOTE: this script must work on both client and server.
5810Sstevel@tonic-gate#
5822334Ssetjegrep "[	 ]/[	 ]*nfs[	 ]" "$ALT_ROOT/etc/vfstab" > /dev/null
5830Sstevel@tonic-gateif [ $? = 0 ]; then
5843446Smrj	rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive"
5852334Ssetje	ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
586*6319Sjg	if [ $SPLIT = yes ]; then
587*6319Sjg		ln "$ALT_ROOT/$BOOT_ARCHIVE_64" \
588*6319Sjg		    "$ALT_ROOT/boot/amd64/boot_archive"
589*6319Sjg	fi
5900Sstevel@tonic-gatefi
5914213Srscott[ -n "$rddir" ] && rm -rf "$rddir"
592