xref: /titanic_50/usr/src/cmd/boot/scripts/create_ramdisk.ksh (revision 488474949328b517188fdfc12c28c8e44e23a9f4)
17c478bd9Sstevel@tonic-gate#!/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
658091fd8Ssetje# Common Development and Distribution License (the "License").
758091fd8Ssetje# 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
23*48847494SEnrico Perla - Sun Microsystems# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate# Use is subject to license terms.
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gateformat=ufs
277c478bd9Sstevel@tonic-gateALT_ROOT=
28d876c67dSjgEXTRACT_ARGS=
29ae115bc7Smrjcompress=yes
30ae115bc7SmrjSPLIT=unknown
31ae115bc7SmrjERROR=0
326bb08588Srscottdirsize32=0
336bb08588Srscottdirsize64=0
347c478bd9Sstevel@tonic-gate
35d876c67dSjgusage() {
36d876c67dSjg	echo "This utility is a component of the bootadm(1M) implementation"
37d876c67dSjg	echo "and it is not recommended for stand-alone use."
38d876c67dSjg	echo "Please use bootadm(1M) instead."
39d876c67dSjg	echo ""
40d876c67dSjg	echo "Usage: ${0##*/}: [-R \<root\>] [-p \<platform\>] [--nocompress]"
41d876c67dSjg	echo "where \<platform\> is one of i86pc, sun4u or sun4v"
42d876c67dSjg	exit
43d876c67dSjg}
44d876c67dSjg
45d876c67dSjg# default platform is what we're running on
46d876c67dSjgPLATFORM=`uname -m`
477c478bd9Sstevel@tonic-gate
48986fd29aSsetje#
49986fd29aSsetje# set path, but inherit /tmp/bfubin if owned by
50986fd29aSsetje# same uid executing this process, which must be root.
51986fd29aSsetje#
52986fd29aSsetjeif [ "`echo $PATH | cut -f 1 -d :`" = /tmp/bfubin ] && \
53986fd29aSsetje    [ -O /tmp/bfubin ] ; then
5479538500Ssetje	export PATH=/tmp/bfubin
5579538500Ssetje	export GZIP_CMD=/tmp/bfubin/gzip
56986fd29aSsetjeelse
57986fd29aSsetje	export PATH=/usr/sbin:/usr/bin:/sbin
5879538500Ssetje	export GZIP_CMD=/usr/bin/gzip
59986fd29aSsetjefi
60986fd29aSsetje
61986fd29aSsetjeEXTRACT_FILELIST="/boot/solaris/bin/extract_boot_filelist"
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate#
647c478bd9Sstevel@tonic-gate# Parse options
657c478bd9Sstevel@tonic-gate#
66ae115bc7Smrjwhile [ "$1" != "" ]
677c478bd9Sstevel@tonic-gatedo
68ae115bc7Smrj        case $1 in
69ae115bc7Smrj        -R)	shift
70ae115bc7Smrj		ALT_ROOT="$1"
717c478bd9Sstevel@tonic-gate		if [ "$ALT_ROOT" != "/" ]; then
7279538500Ssetje			echo "Creating boot_archive for $ALT_ROOT"
73d876c67dSjg			EXTRACT_ARGS="${EXTRACT_ARGS} -R ${ALT_ROOT}"
74986fd29aSsetje			EXTRACT_FILELIST="${ALT_ROOT}${EXTRACT_FILELIST}"
757c478bd9Sstevel@tonic-gate		fi
767c478bd9Sstevel@tonic-gate		;;
770d69385cSrscott	-n|--nocompress) compress=no
780d69385cSrscott		;;
79d876c67dSjg	-p)	shift
80d876c67dSjg		PLATFORM="$1"
81d876c67dSjg		EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}"
82d876c67dSjg		;;
83d876c67dSjg        *)      usage
840d69385cSrscott		;;
857c478bd9Sstevel@tonic-gate        esac
86ae115bc7Smrj	shift
877c478bd9Sstevel@tonic-gatedone
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gateif [ -x /usr/bin/mkisofs -o -x /tmp/bfubin/mkisofs ] ; then
907c478bd9Sstevel@tonic-gate	format=isofs
917c478bd9Sstevel@tonic-gatefi
927c478bd9Sstevel@tonic-gate
9340541d5dSvikram#
9440541d5dSvikram# mkisofs on s8 doesn't support functionality used by GRUB boot.
9540541d5dSvikram# Use ufs format for boot archive instead.
9640541d5dSvikram#
9740541d5dSvikramrelease=`uname -r`
9840541d5dSvikramif [ "$release" = "5.8" ]; then
9940541d5dSvikram	format=ufs
10040541d5dSvikramfi
10140541d5dSvikram
1027c478bd9Sstevel@tonic-gateshift `expr $OPTIND - 1`
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gateif [ $# -eq 1 ]; then
10558091fd8Ssetje	ALT_ROOT="$1"
10679538500Ssetje	echo "Creating boot_archive for $ALT_ROOT"
1077c478bd9Sstevel@tonic-gatefi
1087c478bd9Sstevel@tonic-gate
109d876c67dSjgcase $PLATFORM in
110d876c67dSjgi386)	PLATFORM=i86pc
111d876c67dSjg	ISA=i386
112d876c67dSjg	ARCH64=amd64
113d876c67dSjg	;;
114d876c67dSjgi86pc)	ISA=i386
115d876c67dSjg	ARCH64=amd64
116d876c67dSjg	;;
117d876c67dSjgsun4u)	ISA=sparc
118d876c67dSjg	ARCH64=sparcv9
119d876c67dSjg	;;
120d876c67dSjgsun4v)	ISA=sparc
121d876c67dSjg	ARCH64=sparcv9
122d876c67dSjg	;;
123d876c67dSjg*)	usage
124d876c67dSjg	;;
125d876c67dSjgesac
126d876c67dSjg
127d876c67dSjgBOOT_ARCHIVE=platform/$PLATFORM/boot_archive
128d876c67dSjgBOOT_ARCHIVE_64=platform/$PLATFORM/$ARCH64/boot_archive
129d876c67dSjg
130d876c67dSjgif [ $PLATFORM = i86pc ] ; then
131d71f719dSjg	if [ ! -x "$ALT_ROOT"/boot/solaris/bin/symdef ]; then
132d71f719dSjg		# no dboot implies combined archives for example
133d71f719dSjg		# live-upgrade from s9 to s10u6 is multiboot-only
134986fd29aSsetje		echo "Creating single archive at $ALT_ROOT/$BOOT_ARCHIVE"
135ae115bc7Smrj		SPLIT=no
136ae115bc7Smrj		compress=no
137ae115bc7Smrj	else
138d71f719dSjg		SPLIT=yes
139ae115bc7Smrj	fi
140986fd29aSsetjeelse			# must be sparc
141986fd29aSsetje	SPLIT=no	# there's only 64-bit (sparcv9), so don't split
142986fd29aSsetje	compress=no
143986fd29aSsetjefi
144ae115bc7Smrj
14579538500Ssetje[ -x $GZIP_CMD ] || compress=no
146ae115bc7Smrj
14758091fd8Ssetjefunction cleanup
14858091fd8Ssetje{
149ae115bc7Smrj	umount -f "$rdmnt32" 2>/dev/null
150ae115bc7Smrj	umount -f "$rdmnt64" 2>/dev/null
151ae115bc7Smrj	lofiadm -d "$rdfile32" 2>/dev/null
152ae115bc7Smrj	lofiadm -d "$rdfile64" 2>/dev/null
1536bb08588Srscott	[ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null
1546bb08588Srscott	[ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null
1557c478bd9Sstevel@tonic-gate}
1567c478bd9Sstevel@tonic-gate
15758091fd8Ssetjefunction getsize
15858091fd8Ssetje{
1596bb08588Srscott	# Estimate image size and add 10% overhead for ufs stuff.
1604681df02Sjongkis	# Note, we can't use du here in case we're on a filesystem, e.g. zfs,
1614681df02Sjongkis	# in which the disk usage is less than the sum of the file sizes.
1624681df02Sjongkis	# The nawk code
1634681df02Sjongkis	#
1646bb08588Srscott	#	{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1654681df02Sjongkis	#
1664681df02Sjongkis	# below rounds up the size of a file/directory, in bytes, to the
1674681df02Sjongkis	# next multiple of 1024.  This mimics the behavior of ufs especially
1684681df02Sjongkis	# with directories.  This results in a total size that's slightly
1694681df02Sjongkis	# bigger than if du was called on a ufs directory.
170986fd29aSsetje	size32=$(cat "$list32" | xargs -I {} ls -lLd "{}" 2> /dev/null |
171986fd29aSsetje		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1724681df02Sjongkis		END {print int(t * 1.10 / 1024)}')
1736bb08588Srscott	(( size32 += dirsize32 ))
174986fd29aSsetje	size64=$(cat "$list64" | xargs -I {} ls -lLd "{}" 2> /dev/null |
175986fd29aSsetje		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
1766bb08588Srscott		END {print int(t * 1.10 / 1024)}')
1776bb08588Srscott	(( size64 += dirsize64 ))
1786bb08588Srscott	(( total_size = size32 + size64 ))
179986fd29aSsetje
180986fd29aSsetje	if [ $compress = yes ] ; then
181986fd29aSsetje		total_size=`echo $total_size | nawk '{print int($1 / 2)}'`
182986fd29aSsetje	fi
1837c478bd9Sstevel@tonic-gate}
1847c478bd9Sstevel@tonic-gate
185ae115bc7Smrj#
1866bb08588Srscott# Copies all desired files to a target directory.  One argument should be
1876bb08588Srscott# passed: the file containing the list of files to copy.  This function also
1886bb08588Srscott# depends on several variables that must be set before calling:
189fe33b55dSrscott#
190fe33b55dSrscott# $ALT_ROOT - the target directory
191fe33b55dSrscott# $compress - whether or not the files in the archives should be compressed
192fe33b55dSrscott# $rdmnt - the target directory
193fe33b55dSrscott#
1946bb08588Srscottfunction copy_files
195fe33b55dSrscott{
1966bb08588Srscott	list="$1"
197fe33b55dSrscott
198fe33b55dSrscott	#
199fe33b55dSrscott	# If compress is set, the files are gzip'd and put in the correct
200fe33b55dSrscott	# location in the loop.  Nothing is printed, so the pipe and cpio
201fe33b55dSrscott	# at the end is a nop.
202fe33b55dSrscott	#
203fe33b55dSrscott	# If compress is not set, the file names are printed, which causes
204fe33b55dSrscott	# the cpio at the end to do the copy.
205fe33b55dSrscott	#
2066bb08588Srscott	while read path
207fe33b55dSrscott	do
208fe33b55dSrscott		if [ $compress = yes ]; then
209fe33b55dSrscott			dir="${path%/*}"
210a916d99cSdminer			[ -d "$rdmnt/$dir" ] || mkdir -p "$rdmnt/$dir"
21179538500Ssetje			$GZIP_CMD -c "$path" > "$rdmnt/$path"
212fe33b55dSrscott		else
213fe33b55dSrscott			print "$path"
214fe33b55dSrscott		fi
2156bb08588Srscott	done <"$list" | cpio -pdum "$rdmnt" 2>/dev/null
216986fd29aSsetje
217d876c67dSjg	if [ $ISA = sparc ] ; then
218986fd29aSsetje		# copy links
219986fd29aSsetje		find $filelist -type l -print 2>/dev/null |\
220986fd29aSsetje		    cpio -pdum "$rdmnt" 2>/dev/null
221986fd29aSsetje		if [ $compress = yes ] ; then
222986fd29aSsetje			# always copy unix uncompressed
223986fd29aSsetje			find $filelist -name unix -type f -print 2>/dev/null |\
224986fd29aSsetje			    cpio -pdum "$rdmnt" 2>/dev/null
225986fd29aSsetje		fi
226986fd29aSsetje	fi
227986fd29aSsetje
228fe33b55dSrscott}
229fe33b55dSrscott
230fe33b55dSrscott#
231ae115bc7Smrj# The first argument can be:
232ae115bc7Smrj#
233ae115bc7Smrj# "both" - create an archive with both 32-bit and 64-bit binaries
234ae115bc7Smrj# "32-bit" - create an archive with only 32-bit binaries
235ae115bc7Smrj# "64-bit" - create an archive with only 64-bit binaries
236ae115bc7Smrj#
2377c478bd9Sstevel@tonic-gatefunction create_ufs
2387c478bd9Sstevel@tonic-gate{
239ae115bc7Smrj	which=$1
240ae115bc7Smrj	archive=$2
241ae115bc7Smrj	lofidev=$3
2427c478bd9Sstevel@tonic-gate
243ae115bc7Smrj	# should we exclude amd64 binaries?
244ae115bc7Smrj	if [ "$which" = "32-bit" ]; then
245ae115bc7Smrj		rdfile="$rdfile32"
246ae115bc7Smrj		rdmnt="$rdmnt32"
2476bb08588Srscott		list="$list32"
248ae115bc7Smrj	elif [ "$which" = "64-bit" ]; then
249ae115bc7Smrj		rdfile="$rdfile64"
250ae115bc7Smrj		rdmnt="$rdmnt64"
2516bb08588Srscott		list="$list64"
252ae115bc7Smrj	else
253ae115bc7Smrj		rdfile="$rdfile32"
254ae115bc7Smrj		rdmnt="$rdmnt32"
2556bb08588Srscott		list="$list32"
256ae115bc7Smrj	fi
257ae115bc7Smrj
25858091fd8Ssetje	newfs $lofidev < /dev/null 2> /dev/null
25958091fd8Ssetje	mkdir "$rdmnt"
2607c478bd9Sstevel@tonic-gate	mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
2617ce430bdSsetje	mount -F ufs -o nologging $lofidev "$rdmnt"
262ae115bc7Smrj	files=
2637c478bd9Sstevel@tonic-gate
2647c478bd9Sstevel@tonic-gate	# do the actual copy
2656bb08588Srscott	copy_files "$list"
266*48847494SEnrico Perla - Sun Microsystems	umount -f "$rdmnt"
26758091fd8Ssetje	rmdir "$rdmnt"
26858091fd8Ssetje
269d876c67dSjg	if [ $ISA = sparc ] ; then
270986fd29aSsetje		rlofidev=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"`
271d876c67dSjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk"
272d876c67dSjg		# installboot is not available on all platforms
273d876c67dSjg		dd if=$bb of=$rlofidev bs=1b oseek=1 count=15 conv=sync 2>&1
274986fd29aSsetje	fi
275986fd29aSsetje
276ae115bc7Smrj	#
27758091fd8Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
27858091fd8Ssetje	# on systems that have gzip. Then run gzip out of the patch to
27958091fd8Ssetje	# pick it up from bfubin or something like that if needed.
28058091fd8Ssetje	#
281ae115bc7Smrj	# If compress is set, the individual files in the archive are
282ae115bc7Smrj	# compressed, and the final compression will accomplish very
283ae115bc7Smrj	# little.  To save time, we skip the gzip in this case.
284ae115bc7Smrj	#
285d876c67dSjg	if [ $ISA = i386 ] && [ $compress = no ] && \
28679538500Ssetje	    [ -x $GZIP_CMD ] ; then
287ae115bc7Smrj		gzip -c "$rdfile" > "${archive}-new"
28858091fd8Ssetje	else
289ae115bc7Smrj		cat "$rdfile" > "${archive}-new"
29058091fd8Ssetje	fi
291*48847494SEnrico Perla - Sun Microsystems
292*48847494SEnrico Perla - Sun Microsystems	if [ $? -ne 0 ] ; then
293*48847494SEnrico Perla - Sun Microsystems		rm -f "${archive}-new"
294*48847494SEnrico Perla - Sun Microsystems	fi
2957c478bd9Sstevel@tonic-gate}
2967c478bd9Sstevel@tonic-gate
297ae115bc7Smrj#
298ae115bc7Smrj# The first argument can be:
299ae115bc7Smrj#
300ae115bc7Smrj# "both" - create an archive with both 32-bit and 64-bit binaries
301ae115bc7Smrj# "32-bit" - create an archive with only 32-bit binaries
302ae115bc7Smrj# "64-bit" - create an archive with only 64-bit binaries
303ae115bc7Smrj#
3047c478bd9Sstevel@tonic-gatefunction create_isofs
3057c478bd9Sstevel@tonic-gate{
306ae115bc7Smrj	which=$1
307ae115bc7Smrj	archive=$2
308ae115bc7Smrj
3097c478bd9Sstevel@tonic-gate	# should we exclude amd64 binaries?
310ae115bc7Smrj	if [ "$which" = "32-bit" ]; then
311ae115bc7Smrj		rdmnt="$rdmnt32"
312ae115bc7Smrj		errlog="$errlog32"
3136bb08588Srscott		list="$list32"
314ae115bc7Smrj	elif [ "$which" = "64-bit" ]; then
315ae115bc7Smrj		rdmnt="$rdmnt64"
316ae115bc7Smrj		errlog="$errlog64"
3176bb08588Srscott		list="$list64"
318ae115bc7Smrj	else
319ae115bc7Smrj		rdmnt="$rdmnt32"
320ae115bc7Smrj		errlog="$errlog32"
3216bb08588Srscott		list="$list32"
322ae115bc7Smrj	fi
3237c478bd9Sstevel@tonic-gate
3247c478bd9Sstevel@tonic-gate	# create image directory seed with graft points
32558091fd8Ssetje	mkdir "$rdmnt"
3267c478bd9Sstevel@tonic-gate	files=
327ae115bc7Smrj	isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames"
328ae115bc7Smrj
329d876c67dSjg	if [ $ISA = sparc ] ; then
330d876c67dSjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
331986fd29aSsetje		isocmd="$isocmd -G \"$bb\""
332986fd29aSsetje	fi
333986fd29aSsetje
3346bb08588Srscott	copy_files "$list"
33558091fd8Ssetje	isocmd="$isocmd \"$rdmnt\""
33658091fd8Ssetje	rm -f "$errlog"
33758091fd8Ssetje
338ae115bc7Smrj	#
33958091fd8Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
34058091fd8Ssetje	# on systems that have gzip. Then run gzip out of the patch to
34158091fd8Ssetje	# pick it up from bfubin or something like that if needed.
34258091fd8Ssetje	#
343ae115bc7Smrj	# If compress is set, the individual files in the archive are
344ae115bc7Smrj	# compressed, and the final compression will accomplish very
345ae115bc7Smrj	# little.  To save time, we skip the gzip in this case.
346ae115bc7Smrj	#
347*48847494SEnrico Perla - Sun Microsystems	mkiso_ret=0
348*48847494SEnrico Perla - Sun Microsystems
349d876c67dSjg	if [ $ISA = i386 ] &&[ $compress = no ] && [ -x $GZIP_CMD ]
350986fd29aSsetje	then
35158091fd8Ssetje		ksh -c "$isocmd" 2> "$errlog" | \
352ae115bc7Smrj		    gzip > "${archive}-new"
35358091fd8Ssetje	else
354ae115bc7Smrj		ksh -c "$isocmd" 2> "$errlog" > "${archive}-new"
35558091fd8Ssetje	fi
35658091fd8Ssetje
357*48847494SEnrico Perla - Sun Microsystems	if [ $? -ne 0 ]; then
358*48847494SEnrico Perla - Sun Microsystems		cat "$errlog"
359*48847494SEnrico Perla - Sun Microsystems		rm -f "${archive}-new" 2> /dev/null
360*48847494SEnrico Perla - Sun Microsystems		rm -f "$errlog" 2> /dev/null
361*48847494SEnrico Perla - Sun Microsystems		return
362*48847494SEnrico Perla - Sun Microsystems	fi
363*48847494SEnrico Perla - Sun Microsystems
36479538500Ssetje	dd_ret=0
365d876c67dSjg	if [ $ISA = sparc ] ; then
366d876c67dSjg		bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
36779538500Ssetje		dd if="$bb" of="${archive}-new" bs=1b oseek=1 count=15 \
36879538500Ssetje		    conv=notrunc conv=sync >> "$errlog" 2>&1
36979538500Ssetje		dd_ret=$?
370986fd29aSsetje	fi
371986fd29aSsetje
37279538500Ssetje	if [ -s "$errlog" ] || [ $dd_ret -ne 0 ] ; then
37358091fd8Ssetje		grep Error: "$errlog" >/dev/null 2>&1
37479538500Ssetje		if [ $? -eq 0 ] || [ $dd_ret -ne 0 ] ; then
37579538500Ssetje			cat "$errlog"
376ae115bc7Smrj			rm -f "${archive}-new"
377847671deSjg		fi
378847671deSjg	fi
37958091fd8Ssetje	rm -f "$errlog"
3807c478bd9Sstevel@tonic-gate}
3817c478bd9Sstevel@tonic-gate
382ae115bc7Smrjfunction create_archive
383ae115bc7Smrj{
384ae115bc7Smrj	which=$1
385ae115bc7Smrj	archive=$2
386ae115bc7Smrj	lofidev=$3
387ae115bc7Smrj
388986fd29aSsetje	echo "updating $archive"
389ae115bc7Smrj
390ae115bc7Smrj	if [ "$format" = "ufs" ]; then
391ae115bc7Smrj		create_ufs "$which" "$archive" "$lofidev"
392ae115bc7Smrj	else
393ae115bc7Smrj		create_isofs "$which" "$archive"
394ae115bc7Smrj	fi
395ae115bc7Smrj
396ae115bc7Smrj	# sanity check the archive before moving it into place
397ae115bc7Smrj	#
398*48847494SEnrico Perla - Sun Microsystems	ARCHIVE_SIZE=`ls -l "${archive}-new" 2> /dev/null | nawk '{ print $5 }'`
399d876c67dSjg	if [ $compress = yes ] || [ $ISA = sparc ] ; then
400ae115bc7Smrj		#
401ae115bc7Smrj		# 'file' will report "English text" for uncompressed
402ae115bc7Smrj		# boot_archives.  Checking for that doesn't seem stable,
403ae115bc7Smrj		# so we just check that the file exists.
404ae115bc7Smrj		#
405ae115bc7Smrj		ls "${archive}-new" >/dev/null 2>&1
406ae115bc7Smrj	else
407ae115bc7Smrj		#
408ae115bc7Smrj		# the file type check also establishes that the
409ae115bc7Smrj		# file exists at all
410ae115bc7Smrj		#
411ece420edSsetje		LC_MESSAGES=C file "${archive}-new" | grep gzip > /dev/null
412ae115bc7Smrj	fi
413ae115bc7Smrj
414*48847494SEnrico Perla - Sun Microsystems	if [ $? = 1 ] && [ -x $GZIP_CMD ] || [ "$ARCHIVE_SIZE" -lt 10000 ]
415ae115bc7Smrj	then
416ae115bc7Smrj		#
417ae115bc7Smrj		# Two of these functions may be run in parallel.  We
418ae115bc7Smrj		# need to allow the other to clean up, so we can't
419ae115bc7Smrj		# exit immediately.  Instead, we set a flag.
420ae115bc7Smrj		#
421ae115bc7Smrj		echo "update of $archive failed"
422ae115bc7Smrj		ERROR=1
423ae115bc7Smrj	else
424ae115bc7Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
425ae115bc7Smrj		mv "${archive}-new" "$archive"
426ae115bc7Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
427ae115bc7Smrj	fi
428ae115bc7Smrj
429ae115bc7Smrj}
430ae115bc7Smrj
4316bb08588Srscottfunction fatal_error
4326bb08588Srscott{
4336bb08588Srscott	print -u2 $*
4346bb08588Srscott	exit 1
4356bb08588Srscott}
4366bb08588Srscott
4377c478bd9Sstevel@tonic-gate#
4387c478bd9Sstevel@tonic-gate# get filelist
4397c478bd9Sstevel@tonic-gate#
440fe33b55dSrscottif [ ! -f "$ALT_ROOT/boot/solaris/filelist.ramdisk" ] &&
441fe33b55dSrscott    [ ! -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]
442e482cb0aSjongkisthen
443e482cb0aSjongkis	print -u2 "Can't find filelist.ramdisk"
444e482cb0aSjongkis	exit 1
4457c478bd9Sstevel@tonic-gatefi
446d876c67dSjgfilelist=$($EXTRACT_FILELIST $EXTRACT_ARGS \
447d876c67dSjg	/boot/solaris/filelist.ramdisk \
448d876c67dSjg	/etc/boot/solaris/filelist.ramdisk \
449d876c67dSjg		2>/dev/null | sort -u)
4507c478bd9Sstevel@tonic-gate
4516bb08588Srscott#
4526bb08588Srscott# We use /tmp/ for scratch space now.  This may be changed later if there
4536bb08588Srscott# is insufficient space in /tmp/.
4546bb08588Srscott#
4556bb08588Srscottrddir="/tmp/create_ramdisk.$$.tmp"
4566bb08588Srscottnew_rddir=
4576bb08588Srscottrm -rf "$rddir"
4586bb08588Srscottmkdir "$rddir" || fatal_error "Could not create temporary directory $rddir"
4596bb08588Srscott
4606bb08588Srscott# Clean up upon exit.
4616bb08588Srscotttrap 'cleanup' EXIT
4626bb08588Srscott
4636bb08588Srscottlist32="$rddir/filelist.32"
4646bb08588Srscottlist64="$rddir/filelist.64"
4656bb08588Srscott
466986fd29aSsetjetouch $list32 $list64
467986fd29aSsetje
4686bb08588Srscott#
4696bb08588Srscott# This loop creates the 32-bit and 64-bit lists of files.  The 32-bit list
4706bb08588Srscott# is written to stdout, which is redirected at the end of the loop.  The
4716bb08588Srscott# 64-bit list is appended with each write.
4726bb08588Srscott#
4736bb08588Srscottcd "/$ALT_ROOT"
4746bb08588Srscottfind $filelist -print 2>/dev/null | while read path
4756bb08588Srscottdo
4766bb08588Srscott	if [ $SPLIT = no ]; then
4776bb08588Srscott		print "$path"
4786bb08588Srscott	elif [ -d "$path" ]; then
4796bb08588Srscott		if [ $format = ufs ]; then
4806bb08588Srscott			size=`ls -lLd "$path" | nawk '
4816bb08588Srscott			    {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'`
4826bb08588Srscott			if [ `basename "$path"` != "amd64" ]; then
4836bb08588Srscott				(( dirsize32 += size ))
4846bb08588Srscott			fi
4856bb08588Srscott			(( dirsize64 += size ))
4866bb08588Srscott		fi
4876bb08588Srscott	else
488a916d99cSdminer		case `LC_MESSAGES=C /usr/bin/file -m /dev/null "$path" 2>/dev/null` in
489a916d99cSdminer		*ELF\ 64-bit*)
4906bb08588Srscott			print "$path" >> "$list64"
491a916d99cSdminer			;;
492a916d99cSdminer		*ELF\ 32-bit*)
4936bb08588Srscott			print "$path"
494a916d99cSdminer			;;
495a916d99cSdminer		*)
4966bb08588Srscott			# put in both lists
4976bb08588Srscott			print "$path"
4986bb08588Srscott			print "$path" >> "$list64"
499a916d99cSdminer		esac
5006bb08588Srscott	fi
5016bb08588Srscottdone >"$list32"
50258091fd8Ssetje
50358091fd8Ssetjeif [ $format = ufs ] ; then
50458091fd8Ssetje	# calculate image size
50558091fd8Ssetje	getsize
50658091fd8Ssetje
50758091fd8Ssetje	# check to see if there is sufficient space in tmpfs
50858091fd8Ssetje	#
50958091fd8Ssetje	tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
5107740ff5fSJerry Gilliam	(( tmp_free = tmp_free / 3 ))
5117740ff5fSJerry Gilliam	if [ $SPLIT = yes ]; then
51258091fd8Ssetje		(( tmp_free = tmp_free / 2 ))
5137740ff5fSJerry Gilliam	fi
51458091fd8Ssetje
5156bb08588Srscott	if [ $total_size -gt $tmp_free  ] ; then
51658091fd8Ssetje		# assumes we have enough scratch space on $ALT_ROOT
5177740ff5fSJerry Gilliam		new_rddir="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp"
5186bb08588Srscott		rm -rf "$new_rddir"
5196bb08588Srscott		mkdir "$new_rddir" || fatal_error \
5206bb08588Srscott		    "Could not create temporary directory $new_rddir"
5216bb08588Srscott
5226bb08588Srscott		# Save the file lists
5236bb08588Srscott		mv "$list32" "$new_rddir"/
5246bb08588Srscott		mv "$list64" "$new_rddir"/
5256bb08588Srscott		list32="/$new_rddir/filelist.32"
5266bb08588Srscott		list64="/$new_rddir/filelist.64"
5276bb08588Srscott
5286bb08588Srscott		# Remove the old $rddir and set the new value of rddir
5296bb08588Srscott		rm -rf "$rddir"
5306bb08588Srscott		rddir="$new_rddir"
5316bb08588Srscott		new_rddir=
53258091fd8Ssetje	fi
53358091fd8Ssetjefi
53458091fd8Ssetje
535ae115bc7Smrjrdfile32="$rddir/rd.file.32"
536ae115bc7Smrjrdfile64="$rddir/rd.file.64"
537ae115bc7Smrjrdmnt32="$rddir/rd.mount.32"
538ae115bc7Smrjrdmnt64="$rddir/rd.mount.64"
539ae115bc7Smrjerrlog32="$rddir/rd.errlog.32"
540ae115bc7Smrjerrlog64="$rddir/rd.errlog.64"
541ae115bc7Smrjlofidev32=""
542ae115bc7Smrjlofidev64=""
54358091fd8Ssetje
544ae115bc7Smrjif [ $SPLIT = yes ]; then
54558091fd8Ssetje	#
546ae115bc7Smrj	# We can't run lofiadm commands in parallel, so we have to do
547ae115bc7Smrj	# them here.
548ae115bc7Smrj	#
549ae115bc7Smrj	if [ "$format" = "ufs" ]; then
5506bb08588Srscott		mkfile ${size32}k "$rdfile32"
551ae115bc7Smrj		lofidev32=`lofiadm -a "$rdfile32"`
5526bb08588Srscott		mkfile ${size64}k "$rdfile64"
553ae115bc7Smrj		lofidev64=`lofiadm -a "$rdfile64"`
554ae115bc7Smrj	fi
555ae115bc7Smrj	create_archive "32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 &
556ae115bc7Smrj	create_archive "64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64
557ae115bc7Smrj	wait
558ae115bc7Smrj	if [ "$format" = "ufs" ]; then
559ae115bc7Smrj		lofiadm -d "$rdfile32"
560ae115bc7Smrj		lofiadm -d "$rdfile64"
561ae115bc7Smrj	fi
562ae115bc7Smrjelse
563ae115bc7Smrj	if [ "$format" = "ufs" ]; then
564ae115bc7Smrj		mkfile ${total_size}k "$rdfile32"
565ae115bc7Smrj		lofidev32=`lofiadm -a "$rdfile32"`
566ae115bc7Smrj	fi
567ae115bc7Smrj	create_archive "both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32
568ae115bc7Smrj	[ "$format" = "ufs" ] && lofiadm -d "$rdfile32"
569ae115bc7Smrjfi
570ae115bc7Smrjif [ $ERROR = 1 ]; then
571ae115bc7Smrj	cleanup
572847671deSjg	exit 1
573847671deSjgfi
574847671deSjg
5757c478bd9Sstevel@tonic-gate#
5767c478bd9Sstevel@tonic-gate# For the diskless case, hardlink archive to /boot to make it
5777c478bd9Sstevel@tonic-gate# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
578ae115bc7Smrj# NOTE: this script must work on both client and server.
5797c478bd9Sstevel@tonic-gate#
58058091fd8Ssetjegrep "[	 ]/[	 ]*nfs[	 ]" "$ALT_ROOT/etc/vfstab" > /dev/null
5817c478bd9Sstevel@tonic-gateif [ $? = 0 ]; then
582ae115bc7Smrj	rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive"
58358091fd8Ssetje	ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
584d876c67dSjg	if [ $SPLIT = yes ]; then
585d876c67dSjg		ln "$ALT_ROOT/$BOOT_ARCHIVE_64" \
586d876c67dSjg		    "$ALT_ROOT/boot/amd64/boot_archive"
587d876c67dSjg	fi
5887c478bd9Sstevel@tonic-gatefi
5896bb08588Srscott[ -n "$rddir" ] && rm -rf "$rddir"
590