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=
306319SjgEXTRACT_ARGS=
313446Smrjcompress=yes
323446SmrjSPLIT=unknown
333446SmrjERROR=0
344213Srscottdirsize32=0
354213Srscottdirsize64=0
360Sstevel@tonic-gate
376319Sjgusage() {
386319Sjg	echo "This utility is a component of the bootadm(1M) implementation"
396319Sjg	echo "and it is not recommended for stand-alone use."
406319Sjg	echo "Please use bootadm(1M) instead."
416319Sjg	echo ""
426319Sjg	echo "Usage: ${0##*/}: [-R \<root\>] [-p \<platform\>] [--nocompress]"
436319Sjg	echo "where \<platform\> is one of i86pc, sun4u or sun4v"
446319Sjg	exit
456319Sjg}
466319Sjg
476319Sjg# default platform is what we're running on
486319SjgPLATFORM=`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"
756319Sjg			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		;;
816319Sjg	-p)	shift
826319Sjg		PLATFORM="$1"
836319Sjg		EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}"
846319Sjg		;;
856319Sjg        *)      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
1116319Sjgcase $PLATFORM in
1126319Sjgi386)	PLATFORM=i86pc
1136319Sjg	ISA=i386
1146319Sjg	ARCH64=amd64
1156319Sjg	;;
1166319Sjgi86pc)	ISA=i386
1176319Sjg	ARCH64=amd64
1186319Sjg	;;
1196319Sjgsun4u)	ISA=sparc
1206319Sjg	ARCH64=sparcv9
1216319Sjg	;;
1226319Sjgsun4v)	ISA=sparc
1236319Sjg	ARCH64=sparcv9
1246319Sjg	;;
1256319Sjg*)	usage
1266319Sjg	;;
1276319Sjgesac
1286319Sjg
1296319SjgBOOT_ARCHIVE=platform/$PLATFORM/boot_archive
1306319SjgBOOT_ARCHIVE_64=platform/$PLATFORM/$ARCH64/boot_archive
1316319Sjg
1326319Sjgif [ $PLATFORM = i86pc ] ; then
133*6638Sjg	if [ ! -x "$ALT_ROOT"/boot/solaris/bin/symdef ]; then
134*6638Sjg		# no dboot implies combined archives for example
135*6638Sjg		# live-upgrade from s9 to s10u6 is multiboot-only
1365648Ssetje		echo "Creating single archive at $ALT_ROOT/$BOOT_ARCHIVE"
1375648Ssetje		SPLIT=no
1385648Ssetje		compress=no
139*6638Sjg	else
1405648Ssetje		SPLIT=yes
1415648Ssetje	fi
1425648Ssetjeelse			# must be sparc
1435648Ssetje	SPLIT=no	# there's only 64-bit (sparcv9), so don't split
1445648Ssetje	compress=no
1453446Smrjfi
1463446Smrj
1475734Ssetje[ -x $GZIP_CMD ] || compress=no
1483446Smrj
1492334Ssetjefunction cleanup
1502334Ssetje{
1513446Smrj	umount -f "$rdmnt32" 2>/dev/null
1523446Smrj	umount -f "$rdmnt64" 2>/dev/null
1533446Smrj	lofiadm -d "$rdfile32" 2>/dev/null
1543446Smrj	lofiadm -d "$rdfile64" 2>/dev/null
1554213Srscott	[ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null
1564213Srscott	[ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null
1570Sstevel@tonic-gate}
1580Sstevel@tonic-gate
1592334Ssetjefunction getsize
1602334Ssetje{
1614213Srscott	# Estimate image size and add 10% overhead for ufs stuff.
1622511Sjongkis	# Note, we can't use du here in case we're on a filesystem, e.g. zfs,
1632511Sjongkis	# in which the disk usage is less than the sum of the file sizes.
1642511Sjongkis	# The nawk code
1652511Sjongkis	#
1664213Srscott	#	{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1672511Sjongkis	#
1682511Sjongkis	# below rounds up the size of a file/directory, in bytes, to the
1692511Sjongkis	# next multiple of 1024.  This mimics the behavior of ufs especially
1702511Sjongkis	# with directories.  This results in a total size that's slightly
1712511Sjongkis	# bigger than if du was called on a ufs directory.
1725648Ssetje	size32=$(cat "$list32" | xargs -I {} ls -lLd "{}" 2> /dev/null |
1735648Ssetje		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1744213Srscott		END {print int(t * 1.10 / 1024)}')
1754213Srscott	(( size32 += dirsize32 ))
1765648Ssetje	size64=$(cat "$list64" | xargs -I {} ls -lLd "{}" 2> /dev/null |
1775648Ssetje		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1784213Srscott		END {print int(t * 1.10 / 1024)}')
1794213Srscott	(( size64 += dirsize64 ))
1804213Srscott	(( total_size = size32 + size64 ))
1815648Ssetje
1825648Ssetje	if [ $compress = yes ] ; then
1835648Ssetje		total_size=`echo $total_size | nawk '{print int($1 / 2)}'`
1845648Ssetje	fi
1850Sstevel@tonic-gate}
1860Sstevel@tonic-gate
1873446Smrj#
1884213Srscott# Copies all desired files to a target directory.  One argument should be
1894213Srscott# passed: the file containing the list of files to copy.  This function also
1904213Srscott# depends on several variables that must be set before calling:
1913555Srscott#
1923555Srscott# $ALT_ROOT - the target directory
1933555Srscott# $compress - whether or not the files in the archives should be compressed
1943555Srscott# $rdmnt - the target directory
1953555Srscott#
1964213Srscottfunction copy_files
1973555Srscott{
1984213Srscott	list="$1"
1993555Srscott
2003555Srscott	#
2013555Srscott	# If compress is set, the files are gzip'd and put in the correct
2023555Srscott	# location in the loop.  Nothing is printed, so the pipe and cpio
2033555Srscott	# at the end is a nop.
2043555Srscott	#
2053555Srscott	# If compress is not set, the file names are printed, which causes
2063555Srscott	# the cpio at the end to do the copy.
2073555Srscott	#
2084213Srscott	while read path
2093555Srscott	do
2104213Srscott		if [ $compress = yes ]; then
2114213Srscott			dir="${path%/*}"
2126006Sdminer			[ -d "$rdmnt/$dir" ] || mkdir -p "$rdmnt/$dir"
2135734Ssetje			$GZIP_CMD -c "$path" > "$rdmnt/$path"
2143555Srscott		else
2154213Srscott			print "$path"
2163555Srscott		fi
2174213Srscott	done <"$list" | cpio -pdum "$rdmnt" 2>/dev/null
2185648Ssetje
2196319Sjg	if [ $ISA = sparc ] ; then
2205648Ssetje		# copy links
2215648Ssetje		find $filelist -type l -print 2>/dev/null |\
2225648Ssetje		    cpio -pdum "$rdmnt" 2>/dev/null
2235648Ssetje		if [ $compress = yes ] ; then
2245648Ssetje			# always copy unix uncompressed
2255648Ssetje			find $filelist -name unix -type f -print 2>/dev/null |\
2265648Ssetje			    cpio -pdum "$rdmnt" 2>/dev/null
2275648Ssetje		fi
2285648Ssetje	fi
2295648Ssetje
2303555Srscott}
2313555Srscott
2323555Srscott#
2333446Smrj# The first argument can be:
2343446Smrj#
2353446Smrj# "both" - create an archive with both 32-bit and 64-bit binaries
2363446Smrj# "32-bit" - create an archive with only 32-bit binaries
2373446Smrj# "64-bit" - create an archive with only 64-bit binaries
2383446Smrj#
2390Sstevel@tonic-gatefunction create_ufs
2400Sstevel@tonic-gate{
2413446Smrj	which=$1
2423446Smrj	archive=$2
2433446Smrj	lofidev=$3
2440Sstevel@tonic-gate
2453446Smrj	# should we exclude amd64 binaries?
2463446Smrj	if [ "$which" = "32-bit" ]; then
2473446Smrj		rdfile="$rdfile32"
2483446Smrj		rdmnt="$rdmnt32"
2494213Srscott		list="$list32"
2503446Smrj	elif [ "$which" = "64-bit" ]; then
2513446Smrj		rdfile="$rdfile64"
2523446Smrj		rdmnt="$rdmnt64"
2534213Srscott		list="$list64"
2543446Smrj	else
2553446Smrj		rdfile="$rdfile32"
2563446Smrj		rdmnt="$rdmnt32"
2574213Srscott		list="$list32"
2583446Smrj	fi
2593446Smrj
2602334Ssetje	newfs $lofidev < /dev/null 2> /dev/null
2612334Ssetje	mkdir "$rdmnt"
2620Sstevel@tonic-gate	mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
2632334Ssetje	mount -o nologging $lofidev "$rdmnt"
2643446Smrj	files=
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate	# do the actual copy
2674213Srscott	copy_files "$list"
2682334Ssetje	umount "$rdmnt"
2692334Ssetje	rmdir "$rdmnt"
2702334Ssetje
2716319Sjg	if [ $ISA = sparc ] ; then
2725648Ssetje		rlofidev=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"`
2736319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk"
2746319Sjg		# installboot is not available on all platforms
2756319Sjg		dd if=$bb of=$rlofidev bs=1b oseek=1 count=15 conv=sync 2>&1
2765648Ssetje	fi
2775648Ssetje
2783446Smrj	#
2792334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
2802334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
2812334Ssetje	# pick it up from bfubin or something like that if needed.
2822334Ssetje	#
2833446Smrj	# If compress is set, the individual files in the archive are
2843446Smrj	# compressed, and the final compression will accomplish very
2853446Smrj	# little.  To save time, we skip the gzip in this case.
2863446Smrj	#
2876319Sjg	if [ $ISA = i386 ] && [ $compress = no ] && \
2885734Ssetje	    [ -x $GZIP_CMD ] ; then
2893446Smrj		gzip -c "$rdfile" > "${archive}-new"
2902334Ssetje	else
2913446Smrj		cat "$rdfile" > "${archive}-new"
2922334Ssetje	fi
2930Sstevel@tonic-gate}
2940Sstevel@tonic-gate
2953446Smrj#
2963446Smrj# The first argument can be:
2973446Smrj#
2983446Smrj# "both" - create an archive with both 32-bit and 64-bit binaries
2993446Smrj# "32-bit" - create an archive with only 32-bit binaries
3003446Smrj# "64-bit" - create an archive with only 64-bit binaries
3013446Smrj#
3020Sstevel@tonic-gatefunction create_isofs
3030Sstevel@tonic-gate{
3043446Smrj	which=$1
3053446Smrj	archive=$2
3063446Smrj
3070Sstevel@tonic-gate	# should we exclude amd64 binaries?
3083446Smrj	if [ "$which" = "32-bit" ]; then
3093446Smrj		rdmnt="$rdmnt32"
3103446Smrj		errlog="$errlog32"
3114213Srscott		list="$list32"
3123446Smrj	elif [ "$which" = "64-bit" ]; then
3133446Smrj		rdmnt="$rdmnt64"
3143446Smrj		errlog="$errlog64"
3154213Srscott		list="$list64"
3163446Smrj	else
3173446Smrj		rdmnt="$rdmnt32"
3183446Smrj		errlog="$errlog32"
3194213Srscott		list="$list32"
3203446Smrj	fi
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate	# create image directory seed with graft points
3232334Ssetje	mkdir "$rdmnt"
3240Sstevel@tonic-gate	files=
3253446Smrj	isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames"
3263446Smrj
3276319Sjg	if [ $ISA = sparc ] ; then
3286319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
3295648Ssetje		isocmd="$isocmd -G \"$bb\""
3305648Ssetje	fi
3315648Ssetje
3324213Srscott	copy_files "$list"
3332334Ssetje	isocmd="$isocmd \"$rdmnt\""
3342334Ssetje	rm -f "$errlog"
3352334Ssetje
3363446Smrj	#
3372334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
3382334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
3392334Ssetje	# pick it up from bfubin or something like that if needed.
3402334Ssetje	#
3413446Smrj	# If compress is set, the individual files in the archive are
3423446Smrj	# compressed, and the final compression will accomplish very
3433446Smrj	# little.  To save time, we skip the gzip in this case.
3443446Smrj	#
3456319Sjg	if [ $ISA = i386 ] &&[ $compress = no ] && [ -x $GZIP_CMD ]
3465648Ssetje	then
3472334Ssetje		ksh -c "$isocmd" 2> "$errlog" | \
3483446Smrj		    gzip > "${archive}-new"
3492334Ssetje	else
3503446Smrj		ksh -c "$isocmd" 2> "$errlog" > "${archive}-new"
3512334Ssetje	fi
3522334Ssetje
3535734Ssetje	dd_ret=0
3546319Sjg	if [ $ISA = sparc ] ; then
3556319Sjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
3565734Ssetje		dd if="$bb" of="${archive}-new" bs=1b oseek=1 count=15 \
3575734Ssetje		    conv=notrunc conv=sync >> "$errlog" 2>&1
3585734Ssetje		dd_ret=$?
3595648Ssetje	fi
3605648Ssetje
3615734Ssetje	if [ -s "$errlog" ] || [ $dd_ret -ne 0 ] ; then
3622334Ssetje		grep Error: "$errlog" >/dev/null 2>&1
3635734Ssetje		if [ $? -eq 0 ] || [ $dd_ret -ne 0 ] ; then
3645734Ssetje			cat "$errlog"
3653446Smrj			rm -f "${archive}-new"
366174Sjg		fi
367174Sjg	fi
3682334Ssetje	rm -f "$errlog"
3690Sstevel@tonic-gate}
3700Sstevel@tonic-gate
3713446Smrjfunction create_archive
3723446Smrj{
3733446Smrj	which=$1
3743446Smrj	archive=$2
3753446Smrj	lofidev=$3
3763446Smrj
3775648Ssetje	echo "updating $archive"
3783446Smrj
3793446Smrj	if [ "$format" = "ufs" ]; then
3803446Smrj		create_ufs "$which" "$archive" "$lofidev"
3813446Smrj	else
3823446Smrj		create_isofs "$which" "$archive"
3833446Smrj	fi
3843446Smrj
3853446Smrj	# sanity check the archive before moving it into place
3863446Smrj	#
3873555Srscott	ARCHIVE_SIZE=`ls -l "${archive}-new" | nawk '{ print $5 }'`
3886319Sjg	if [ $compress = yes ] || [ $ISA = sparc ] ; then
3893446Smrj		#
3903446Smrj		# 'file' will report "English text" for uncompressed
3913446Smrj		# boot_archives.  Checking for that doesn't seem stable,
3923446Smrj		# so we just check that the file exists.
3933446Smrj		#
3943446Smrj		ls "${archive}-new" >/dev/null 2>&1
3953446Smrj	else
3963446Smrj		#
3973446Smrj		# the file type check also establishes that the
3983446Smrj		# file exists at all
3993446Smrj		#
4003614Ssetje		LC_MESSAGES=C file "${archive}-new" | grep gzip > /dev/null
4013446Smrj	fi
4023446Smrj
4035734Ssetje	if [ $? = 1 ] && [ -x $GZIP_CMD ] || [ $ARCHIVE_SIZE -lt 5000 ]
4043446Smrj	then
4053446Smrj		#
4063446Smrj		# Two of these functions may be run in parallel.  We
4073446Smrj		# need to allow the other to clean up, so we can't
4083446Smrj		# exit immediately.  Instead, we set a flag.
4093446Smrj		#
4103446Smrj		echo "update of $archive failed"
4113446Smrj		ERROR=1
4123446Smrj	else
4133446Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
4143446Smrj		mv "${archive}-new" "$archive"
4153446Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
4163446Smrj	fi
4173446Smrj
4183446Smrj}
4193446Smrj
4204213Srscottfunction fatal_error
4214213Srscott{
4224213Srscott	print -u2 $*
4234213Srscott	exit 1
4244213Srscott}
4254213Srscott
4260Sstevel@tonic-gate#
4270Sstevel@tonic-gate# get filelist
4280Sstevel@tonic-gate#
4293555Srscottif [ ! -f "$ALT_ROOT/boot/solaris/filelist.ramdisk" ] &&
4303555Srscott    [ ! -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]
4312851Sjongkisthen
4322851Sjongkis	print -u2 "Can't find filelist.ramdisk"
4332851Sjongkis	exit 1
4340Sstevel@tonic-gatefi
4356319Sjgfilelist=$($EXTRACT_FILELIST $EXTRACT_ARGS \
4366319Sjg	/boot/solaris/filelist.ramdisk \
4376319Sjg	/etc/boot/solaris/filelist.ramdisk \
4386319Sjg		2>/dev/null | sort -u)
4390Sstevel@tonic-gate
4404213Srscott#
4414213Srscott# We use /tmp/ for scratch space now.  This may be changed later if there
4424213Srscott# is insufficient space in /tmp/.
4434213Srscott#
4444213Srscottrddir="/tmp/create_ramdisk.$$.tmp"
4454213Srscottnew_rddir=
4464213Srscottrm -rf "$rddir"
4474213Srscottmkdir "$rddir" || fatal_error "Could not create temporary directory $rddir"
4484213Srscott
4494213Srscott# Clean up upon exit.
4504213Srscotttrap 'cleanup' EXIT
4514213Srscott
4524213Srscottlist32="$rddir/filelist.32"
4534213Srscottlist64="$rddir/filelist.64"
4544213Srscott
4555648Ssetjetouch $list32 $list64
4565648Ssetje
4574213Srscott#
4584213Srscott# This loop creates the 32-bit and 64-bit lists of files.  The 32-bit list
4594213Srscott# is written to stdout, which is redirected at the end of the loop.  The
4604213Srscott# 64-bit list is appended with each write.
4614213Srscott#
4624213Srscottcd "/$ALT_ROOT"
4634213Srscottfind $filelist -print 2>/dev/null | while read path
4644213Srscottdo
4654213Srscott	if [ $SPLIT = no ]; then
4664213Srscott		print "$path"
4674213Srscott	elif [ -d "$path" ]; then
4684213Srscott		if [ $format = ufs ]; then
4694213Srscott			size=`ls -lLd "$path" | nawk '
4704213Srscott			    {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'`
4714213Srscott			if [ `basename "$path"` != "amd64" ]; then
4724213Srscott				(( dirsize32 += size ))
4734213Srscott			fi
4744213Srscott			(( dirsize64 += size ))
4754213Srscott		fi
4764213Srscott	else
4776006Sdminer		case `LC_MESSAGES=C /usr/bin/file -m /dev/null "$path" 2>/dev/null` in
4786006Sdminer		*ELF\ 64-bit*)
4794213Srscott			print "$path" >> "$list64"
4806006Sdminer			;;
4816006Sdminer		*ELF\ 32-bit*)
4824213Srscott			print "$path"
4836006Sdminer			;;
4846006Sdminer		*)
4854213Srscott			# put in both lists
4864213Srscott			print "$path"
4874213Srscott			print "$path" >> "$list64"
4886006Sdminer		esac
4894213Srscott	fi
4904213Srscottdone >"$list32"
4912334Ssetje
4922334Ssetjeif [ $format = ufs ] ; then
4932334Ssetje	# calculate image size
4942334Ssetje	getsize
4952334Ssetje
4962334Ssetje	# check to see if there is sufficient space in tmpfs
4972334Ssetje	#
4982334Ssetje	tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
4992334Ssetje	(( tmp_free = tmp_free / 2 ))
5002334Ssetje
5014213Srscott	if [ $total_size -gt $tmp_free  ] ; then
5022334Ssetje		# assumes we have enough scratch space on $ALT_ROOT
5034213Srscott		new_rddir="/$ALT_ROOT/create_ramdisk.$$.tmp"
5044213Srscott		rm -rf "$new_rddir"
5054213Srscott		mkdir "$new_rddir" || fatal_error \
5064213Srscott		    "Could not create temporary directory $new_rddir"
5074213Srscott
5084213Srscott		# Save the file lists
5094213Srscott		mv "$list32" "$new_rddir"/
5104213Srscott		mv "$list64" "$new_rddir"/
5114213Srscott		list32="/$new_rddir/filelist.32"
5124213Srscott		list64="/$new_rddir/filelist.64"
5134213Srscott
5144213Srscott		# Remove the old $rddir and set the new value of rddir
5154213Srscott		rm -rf "$rddir"
5164213Srscott		rddir="$new_rddir"
5174213Srscott		new_rddir=
5182334Ssetje	fi
5192334Ssetjefi
5202334Ssetje
5213446Smrjrdfile32="$rddir/rd.file.32"
5223446Smrjrdfile64="$rddir/rd.file.64"
5233446Smrjrdmnt32="$rddir/rd.mount.32"
5243446Smrjrdmnt64="$rddir/rd.mount.64"
5253446Smrjerrlog32="$rddir/rd.errlog.32"
5263446Smrjerrlog64="$rddir/rd.errlog.64"
5273446Smrjlofidev32=""
5283446Smrjlofidev64=""
5292334Ssetje
5303446Smrjif [ $SPLIT = yes ]; then
5313446Smrj	#
5323446Smrj	# We can't run lofiadm commands in parallel, so we have to do
5333446Smrj	# them here.
5343446Smrj	#
5353446Smrj	if [ "$format" = "ufs" ]; then
5364213Srscott		mkfile ${size32}k "$rdfile32"
5373446Smrj		lofidev32=`lofiadm -a "$rdfile32"`
5384213Srscott		mkfile ${size64}k "$rdfile64"
5393446Smrj		lofidev64=`lofiadm -a "$rdfile64"`
5403446Smrj	fi
5413446Smrj	create_archive "32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 &
5423446Smrj	create_archive "64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64
5433446Smrj	wait
5443446Smrj	if [ "$format" = "ufs" ]; then
5453446Smrj		lofiadm -d "$rdfile32"
5463446Smrj		lofiadm -d "$rdfile64"
5473446Smrj	fi
5480Sstevel@tonic-gateelse
5493446Smrj	if [ "$format" = "ufs" ]; then
5503446Smrj		mkfile ${total_size}k "$rdfile32"
5513446Smrj		lofidev32=`lofiadm -a "$rdfile32"`
5523446Smrj	fi
5533446Smrj	create_archive "both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32
5543446Smrj	[ "$format" = "ufs" ] && lofiadm -d "$rdfile32"
5550Sstevel@tonic-gatefi
5563446Smrjif [ $ERROR = 1 ]; then
5573446Smrj	cleanup
558174Sjg	exit 1
559174Sjgfi
560174Sjg
5610Sstevel@tonic-gate#
5620Sstevel@tonic-gate# For the diskless case, hardlink archive to /boot to make it
5630Sstevel@tonic-gate# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
5643446Smrj# NOTE: this script must work on both client and server.
5650Sstevel@tonic-gate#
5662334Ssetjegrep "[	 ]/[	 ]*nfs[	 ]" "$ALT_ROOT/etc/vfstab" > /dev/null
5670Sstevel@tonic-gateif [ $? = 0 ]; then
5683446Smrj	rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive"
5692334Ssetje	ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
5706319Sjg	if [ $SPLIT = yes ]; then
5716319Sjg		ln "$ALT_ROOT/$BOOT_ARCHIVE_64" \
5726319Sjg		    "$ALT_ROOT/boot/amd64/boot_archive"
5736319Sjg	fi
5740Sstevel@tonic-gatefi
5754213Srscott[ -n "$rddir" ] && rm -rf "$rddir"
576