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
6*2334Ssetje# Common Development and Distribution License (the "License").
7*2334Ssetje# 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*2334Ssetje# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate# Use is subject to license terms.
250Sstevel@tonic-gate
26*2334Ssetje# ident	"%Z%%M%	%I%	%E% SMI"
27174Sjg
280Sstevel@tonic-gateformat=ufs
290Sstevel@tonic-gateALT_ROOT=
300Sstevel@tonic-gateNO_AMD64=
310Sstevel@tonic-gate
320Sstevel@tonic-gateBOOT_ARCHIVE=platform/i86pc/boot_archive
330Sstevel@tonic-gate
34*2334Ssetjeexport PATH=$PATH:/usr/sbin:/usr/bin:/sbin
350Sstevel@tonic-gate
360Sstevel@tonic-gate#
370Sstevel@tonic-gate# Parse options
380Sstevel@tonic-gate#
390Sstevel@tonic-gatewhile getopts R: OPT 2> /dev/null
400Sstevel@tonic-gatedo
410Sstevel@tonic-gate        case $OPT in
420Sstevel@tonic-gate        R)      ALT_ROOT="$OPTARG"
430Sstevel@tonic-gate		if [ "$ALT_ROOT" != "/" ]; then
44*2334Ssetje			echo "Creating ram disk for $ALT_ROOT"
450Sstevel@tonic-gate		fi
460Sstevel@tonic-gate		;;
470Sstevel@tonic-gate        ?)      echo Usage: ${0##*/}: [-R \<root\>]
480Sstevel@tonic-gate		exit ;;
490Sstevel@tonic-gate        esac
500Sstevel@tonic-gatedone
510Sstevel@tonic-gate
520Sstevel@tonic-gateif [ -x /usr/bin/mkisofs -o -x /tmp/bfubin/mkisofs ] ; then
530Sstevel@tonic-gate	format=isofs
540Sstevel@tonic-gatefi
550Sstevel@tonic-gate
56621Svikram#
57621Svikram# mkisofs on s8 doesn't support functionality used by GRUB boot.
58621Svikram# Use ufs format for boot archive instead.
59621Svikram#
60621Svikramrelease=`uname -r`
61621Svikramif [ "$release" = "5.8" ]; then
62621Svikram   format=ufs
63621Svikramfi
64621Svikram
650Sstevel@tonic-gateshift `expr $OPTIND - 1`
660Sstevel@tonic-gate
670Sstevel@tonic-gateif [ $# -eq 1 ]; then
68*2334Ssetje	ALT_ROOT="$1"
69*2334Ssetje	echo "Creating ram disk for $ALT_ROOT"
700Sstevel@tonic-gatefi
710Sstevel@tonic-gate
72*2334Ssetjefunction cleanup
73*2334Ssetje{
74*2334Ssetje	umount -f "$rdmnt" 2>/dev/null
75*2334Ssetje	lofiadm -d "$rdfile" 2>/dev/null
76*2334Ssetje	rm -fr "$rddir" 2> /dev/null
770Sstevel@tonic-gate}
780Sstevel@tonic-gate
79*2334Ssetjefunction getsize
80*2334Ssetje{
810Sstevel@tonic-gate	# Estimate image size, add %10 overhead for ufs stuff
820Sstevel@tonic-gate	total_size=0
830Sstevel@tonic-gate	for file in $filelist
840Sstevel@tonic-gate	do
85*2334Ssetje		if [ -e "$ALT_ROOT/$file" ] ; then
86*2334Ssetje			du -sk "$ALT_ROOT/$file" | read size name
87820Ssetje			(( total_size += size ))
88820Ssetje		fi
890Sstevel@tonic-gate	done
900Sstevel@tonic-gate	(( total_size += total_size * 10 / 100 ))
910Sstevel@tonic-gate}
920Sstevel@tonic-gate
930Sstevel@tonic-gatefunction create_ufs
940Sstevel@tonic-gate{
950Sstevel@tonic-gate	# should we exclude amd64 binaries?
960Sstevel@tonic-gate	[ $is_amd64 -eq 0 ] && NO_AMD64="-name amd64 -prune"
970Sstevel@tonic-gate
980Sstevel@tonic-gate
99*2334Ssetje	mkfile ${total_size}k "$rdfile"
100*2334Ssetje	lofidev=`lofiadm -a "$rdfile"`
101*2334Ssetje	newfs $lofidev < /dev/null 2> /dev/null
102*2334Ssetje	mkdir "$rdmnt"
1030Sstevel@tonic-gate	mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
104*2334Ssetje	mount -o nologging $lofidev "$rdmnt"
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate	# do the actual copy
107*2334Ssetje	cd "/$ALT_ROOT"
108*2334Ssetje
109*2334Ssetje	find $filelist -print $NO_AMD64 2> /dev/null | \
110*2334Ssetje	     cpio -pdum "$rdmnt" 2> /dev/null
111*2334Ssetje	umount "$rdmnt"
112*2334Ssetje	lofiadm -d "$rdfile"
113*2334Ssetje	rmdir "$rdmnt"
114*2334Ssetje
115*2334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
116*2334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
117*2334Ssetje	# pick it up from bfubin or something like that if needed.
118*2334Ssetje	#
119*2334Ssetje	if [ -x /usr/bin/gzip ] ; then
120*2334Ssetje		gzip -c "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
121*2334Ssetje	else
122*2334Ssetje		cat "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
123*2334Ssetje	fi
1240Sstevel@tonic-gate}
1250Sstevel@tonic-gate
1260Sstevel@tonic-gatefunction create_isofs
1270Sstevel@tonic-gate{
1280Sstevel@tonic-gate	# should we exclude amd64 binaries?
1290Sstevel@tonic-gate	[ $is_amd64 = 0 ] && NO_AMD64="-m amd64"
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate	# create image directory seed with graft points
132*2334Ssetje	mkdir "$rdmnt"
1330Sstevel@tonic-gate	files=
134*2334Ssetje	isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames $NO_AMD64"
1350Sstevel@tonic-gate	for path in $filelist
1360Sstevel@tonic-gate	do
137*2334Ssetje		if [ -d "$ALT_ROOT/$path" ]; then
138*2334Ssetje			isocmd="$isocmd $path/=\"$ALT_ROOT/$path\""
139*2334Ssetje			mkdir -p "$rdmnt/$path"
140*2334Ssetje		elif [ -f "$ALT_ROOT/$path" ]; then
1410Sstevel@tonic-gate			files="$files $path"
1420Sstevel@tonic-gate		fi
1430Sstevel@tonic-gate	done
144*2334Ssetje	cd "/$ALT_ROOT"
145*2334Ssetje	find $files 2> /dev/null | cpio -pdum "$rdmnt" 2> /dev/null
146*2334Ssetje	isocmd="$isocmd \"$rdmnt\""
147*2334Ssetje	rm -f "$errlog"
148*2334Ssetje
149*2334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
150*2334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
151*2334Ssetje	# pick it up from bfubin or something like that if needed.
152*2334Ssetje	#
153*2334Ssetje	if [ -x /usr/bin/gzip ] ; then
154*2334Ssetje		ksh -c "$isocmd" 2> "$errlog" | \
155*2334Ssetje		    gzip > "$ALT_ROOT/$BOOT_ARCHIVE-new"
156*2334Ssetje	else
157*2334Ssetje		ksh -c "$isocmd" 2> "$errlog" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
158*2334Ssetje	fi
159*2334Ssetje
160*2334Ssetje	if [ -s "$errlog" ]; then
161*2334Ssetje		grep Error: "$errlog" >/dev/null 2>&1
162174Sjg		if [ $? -eq 0 ]; then
163*2334Ssetje			grep Error: "$errlog"
164*2334Ssetje			rm -f "$ALT_ROOT/$BOOT_ARCHIVE-new"
165174Sjg		fi
166174Sjg	fi
167*2334Ssetje	rm -f "$errlog"
1680Sstevel@tonic-gate}
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate#
1710Sstevel@tonic-gate# get filelist
1720Sstevel@tonic-gate#
173*2334Ssetjefiles="$ALT_ROOT/boot/solaris/filelist.ramdisk"
174*2334Ssetjeif [ -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]; then
175*2334Ssetje	files="$files \"$ALT_ROOT/etc/boot/solaris/filelist.ramdisk\""
1760Sstevel@tonic-gatefi
177*2334Ssetjefilelist=`cat "$files" | sort -u`
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate#
1800Sstevel@tonic-gate# decide if cpu is amd64 capable
1810Sstevel@tonic-gate#
1820Sstevel@tonic-gateprtconf -v /devices | grep CPU_not_amd64 > /dev/null 2>&1
1830Sstevel@tonic-gateis_amd64=$?
1840Sstevel@tonic-gate
185*2334Ssetjescratch=tmp
186*2334Ssetje
187*2334Ssetjeif [ $format = ufs ] ; then
188*2334Ssetje	# calculate image size
189*2334Ssetje	getsize
190*2334Ssetje
191*2334Ssetje	# check to see if there is sufficient space in tmpfs
192*2334Ssetje	#
193*2334Ssetje	tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
194*2334Ssetje	(( tmp_free = tmp_free / 2 ))
195*2334Ssetje
196*2334Ssetje	if [ $total_size -gt $tmp_free  ] ; then
197*2334Ssetje		# assumes we have enough scratch space on $ALT_ROOT
198*2334Ssetje        	scratch="$ALT_ROOT"
199*2334Ssetje	fi
200*2334Ssetjefi
201*2334Ssetje
202*2334Ssetjerddir="/$scratch/create_ramdisk.$$.tmp"
203*2334Ssetjerdfile="$rddir/rd.file"
204*2334Ssetjerdmnt="$rddir/rd.mount"
205*2334Ssetjeerrlog="$rddir/rd.errlog"
206*2334Ssetje
207*2334Ssetje# make directory for temp files safely
208*2334Ssetjerm -rf "$rddir"
209*2334Ssetjemkdir "$rddir"
210*2334Ssetje
211*2334Ssetje# Clean up upon exit.
212*2334Ssetjetrap 'cleanup' EXIT
213*2334Ssetje
214*2334Ssetjeecho "updating $ALT_ROOT/$BOOT_ARCHIVE...this may take a minute"
2150Sstevel@tonic-gate
2160Sstevel@tonic-gateif [ $format = "ufs" ]; then
2170Sstevel@tonic-gate	create_ufs
2180Sstevel@tonic-gateelse
2190Sstevel@tonic-gate	create_isofs
2200Sstevel@tonic-gatefi
2210Sstevel@tonic-gate
222*2334Ssetje# sanity check the archive before moving it into place
223*2334Ssetje# the file type check also establishes that the file exists at all
224*2334Ssetje#
225*2334SsetjeARCHIVE_SIZE=`du -k "$ALT_ROOT/$BOOT_ARCHIVE-new" | cut -f 1`
226*2334Ssetjefile "$ALT_ROOT/$BOOT_ARCHIVE-new" | grep gzip > /dev/null
227*2334Ssetje
228*2334Ssetjeif [ $? = 1 ] && [ -x /usr/bin/gzip ] || [ $ARCHIVE_SIZE -lt 5000 ]; then
229*2334Ssetje	echo "update of $ALT_ROOT/$BOOT_ARCHIVE failed"
230*2334Ssetje	rm -rf "$rddir"
231174Sjg	exit 1
232174Sjgfi
233174Sjg
2340Sstevel@tonic-gate#
2350Sstevel@tonic-gate# For the diskless case, hardlink archive to /boot to make it
2360Sstevel@tonic-gate# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
2370Sstevel@tonic-gate# NOTE: this script must work on both client and server
2380Sstevel@tonic-gate#
239*2334Ssetjegrep "[	 ]/[	 ]*nfs[	 ]" "$ALT_ROOT/etc/vfstab" > /dev/null
2400Sstevel@tonic-gateif [ $? = 0 ]; then
241*2334Ssetje	mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE"
242*2334Ssetje	rm -f "$ALT_ROOT/boot/boot_archive"
243*2334Ssetje	ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
244*2334Ssetje	rm -rf "$rddir"
2450Sstevel@tonic-gate	exit
2460Sstevel@tonic-gatefi
2470Sstevel@tonic-gate
248*2334Ssetjelockfs -f "/$ALT_ROOT"
249*2334Ssetjemv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE"
250*2334Ssetjelockfs -f "/$ALT_ROOT"
251174Sjg
252*2334Ssetjerm -rf "$rddir"
253