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
232334Ssetje# Copyright 2006 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=
300Sstevel@tonic-gateNO_AMD64=
310Sstevel@tonic-gate
320Sstevel@tonic-gateBOOT_ARCHIVE=platform/i86pc/boot_archive
330Sstevel@tonic-gate
342334Ssetjeexport 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
442334Ssetje			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
682334Ssetje	ALT_ROOT="$1"
692334Ssetje	echo "Creating ram disk for $ALT_ROOT"
700Sstevel@tonic-gatefi
710Sstevel@tonic-gate
722334Ssetjefunction cleanup
732334Ssetje{
742334Ssetje	umount -f "$rdmnt" 2>/dev/null
752334Ssetje	lofiadm -d "$rdfile" 2>/dev/null
762334Ssetje	rm -fr "$rddir" 2> /dev/null
770Sstevel@tonic-gate}
780Sstevel@tonic-gate
792334Ssetjefunction getsize
802334Ssetje{
81*2511Sjongkis	# Estimate image size and add %10 overhead for ufs stuff.
82*2511Sjongkis	# Note, we can't use du here in case we're on a filesystem, e.g. zfs,
83*2511Sjongkis	# in which the disk usage is less than the sum of the file sizes.
84*2511Sjongkis	# The nawk code
85*2511Sjongkis	#
86*2511Sjongkis	#	{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
87*2511Sjongkis	#
88*2511Sjongkis	# below rounds up the size of a file/directory, in bytes, to the
89*2511Sjongkis	# next multiple of 1024.  This mimics the behavior of ufs especially
90*2511Sjongkis	# with directories.  This results in a total size that's slightly
91*2511Sjongkis	# bigger than if du was called on a ufs directory.
92*2511Sjongkis	total_size=$(find $filelist -ls 2>/dev/null | nawk '
93*2511Sjongkis	    {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
94*2511Sjongkis	    END {print int(t * 1.10 / 1024)}')
950Sstevel@tonic-gate}
960Sstevel@tonic-gate
970Sstevel@tonic-gatefunction create_ufs
980Sstevel@tonic-gate{
990Sstevel@tonic-gate	# should we exclude amd64 binaries?
1000Sstevel@tonic-gate	[ $is_amd64 -eq 0 ] && NO_AMD64="-name amd64 -prune"
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate
1032334Ssetje	mkfile ${total_size}k "$rdfile"
1042334Ssetje	lofidev=`lofiadm -a "$rdfile"`
1052334Ssetje	newfs $lofidev < /dev/null 2> /dev/null
1062334Ssetje	mkdir "$rdmnt"
1070Sstevel@tonic-gate	mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
1082334Ssetje	mount -o nologging $lofidev "$rdmnt"
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate	# do the actual copy
1112334Ssetje	cd "/$ALT_ROOT"
1122334Ssetje
1132334Ssetje	find $filelist -print $NO_AMD64 2> /dev/null | \
1142334Ssetje	     cpio -pdum "$rdmnt" 2> /dev/null
1152334Ssetje	umount "$rdmnt"
1162334Ssetje	lofiadm -d "$rdfile"
1172334Ssetje	rmdir "$rdmnt"
1182334Ssetje
1192334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
1202334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
1212334Ssetje	# pick it up from bfubin or something like that if needed.
1222334Ssetje	#
1232334Ssetje	if [ -x /usr/bin/gzip ] ; then
1242334Ssetje		gzip -c "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
1252334Ssetje	else
1262334Ssetje		cat "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
1272334Ssetje	fi
1280Sstevel@tonic-gate}
1290Sstevel@tonic-gate
1300Sstevel@tonic-gatefunction create_isofs
1310Sstevel@tonic-gate{
1320Sstevel@tonic-gate	# should we exclude amd64 binaries?
1330Sstevel@tonic-gate	[ $is_amd64 = 0 ] && NO_AMD64="-m amd64"
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate	# create image directory seed with graft points
1362334Ssetje	mkdir "$rdmnt"
1370Sstevel@tonic-gate	files=
1382334Ssetje	isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames $NO_AMD64"
1390Sstevel@tonic-gate	for path in $filelist
1400Sstevel@tonic-gate	do
1412334Ssetje		if [ -d "$ALT_ROOT/$path" ]; then
1422334Ssetje			isocmd="$isocmd $path/=\"$ALT_ROOT/$path\""
1432334Ssetje			mkdir -p "$rdmnt/$path"
1442334Ssetje		elif [ -f "$ALT_ROOT/$path" ]; then
1450Sstevel@tonic-gate			files="$files $path"
1460Sstevel@tonic-gate		fi
1470Sstevel@tonic-gate	done
1482334Ssetje	cd "/$ALT_ROOT"
1492334Ssetje	find $files 2> /dev/null | cpio -pdum "$rdmnt" 2> /dev/null
1502334Ssetje	isocmd="$isocmd \"$rdmnt\""
1512334Ssetje	rm -f "$errlog"
1522334Ssetje
1532334Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
1542334Ssetje	# on systems that have gzip. Then run gzip out of the patch to
1552334Ssetje	# pick it up from bfubin or something like that if needed.
1562334Ssetje	#
1572334Ssetje	if [ -x /usr/bin/gzip ] ; then
1582334Ssetje		ksh -c "$isocmd" 2> "$errlog" | \
1592334Ssetje		    gzip > "$ALT_ROOT/$BOOT_ARCHIVE-new"
1602334Ssetje	else
1612334Ssetje		ksh -c "$isocmd" 2> "$errlog" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
1622334Ssetje	fi
1632334Ssetje
1642334Ssetje	if [ -s "$errlog" ]; then
1652334Ssetje		grep Error: "$errlog" >/dev/null 2>&1
166174Sjg		if [ $? -eq 0 ]; then
1672334Ssetje			grep Error: "$errlog"
1682334Ssetje			rm -f "$ALT_ROOT/$BOOT_ARCHIVE-new"
169174Sjg		fi
170174Sjg	fi
1712334Ssetje	rm -f "$errlog"
1720Sstevel@tonic-gate}
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate#
1750Sstevel@tonic-gate# get filelist
1760Sstevel@tonic-gate#
1772345Ssetjefilelist=`cat "$ALT_ROOT/boot/solaris/filelist.ramdisk"`
1782334Ssetjeif [ -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]; then
1792345Ssetje	filelistI=`cat "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk"`
1800Sstevel@tonic-gatefi
1812345Ssetjefilelist=`echo $filelist $filelistI | sort -u`
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate#
1840Sstevel@tonic-gate# decide if cpu is amd64 capable
1850Sstevel@tonic-gate#
1860Sstevel@tonic-gateprtconf -v /devices | grep CPU_not_amd64 > /dev/null 2>&1
1870Sstevel@tonic-gateis_amd64=$?
1880Sstevel@tonic-gate
1892334Ssetjescratch=tmp
1902334Ssetje
1912334Ssetjeif [ $format = ufs ] ; then
1922334Ssetje	# calculate image size
1932334Ssetje	getsize
1942334Ssetje
1952334Ssetje	# check to see if there is sufficient space in tmpfs
1962334Ssetje	#
1972334Ssetje	tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
1982334Ssetje	(( tmp_free = tmp_free / 2 ))
1992334Ssetje
2002334Ssetje	if [ $total_size -gt $tmp_free  ] ; then
2012334Ssetje		# assumes we have enough scratch space on $ALT_ROOT
2022334Ssetje        	scratch="$ALT_ROOT"
2032334Ssetje	fi
2042334Ssetjefi
2052334Ssetje
2062334Ssetjerddir="/$scratch/create_ramdisk.$$.tmp"
2072334Ssetjerdfile="$rddir/rd.file"
2082334Ssetjerdmnt="$rddir/rd.mount"
2092334Ssetjeerrlog="$rddir/rd.errlog"
2102334Ssetje
2112334Ssetje# make directory for temp files safely
2122334Ssetjerm -rf "$rddir"
2132334Ssetjemkdir "$rddir"
2142334Ssetje
2152334Ssetje# Clean up upon exit.
2162334Ssetjetrap 'cleanup' EXIT
2172334Ssetje
2182334Ssetjeecho "updating $ALT_ROOT/$BOOT_ARCHIVE...this may take a minute"
2190Sstevel@tonic-gate
2200Sstevel@tonic-gateif [ $format = "ufs" ]; then
2210Sstevel@tonic-gate	create_ufs
2220Sstevel@tonic-gateelse
2230Sstevel@tonic-gate	create_isofs
2240Sstevel@tonic-gatefi
2250Sstevel@tonic-gate
2262334Ssetje# sanity check the archive before moving it into place
2272334Ssetje# the file type check also establishes that the file exists at all
2282334Ssetje#
229*2511SjongkisARCHIVE_SIZE=$(/bin/ls -l "$ALT_ROOT/$BOOT_ARCHIVE-new" |
230*2511Sjongkis	nawk '{print int($5 / 1024)}')
2312334Ssetjefile "$ALT_ROOT/$BOOT_ARCHIVE-new" | grep gzip > /dev/null
2322334Ssetje
2332334Ssetjeif [ $? = 1 ] && [ -x /usr/bin/gzip ] || [ $ARCHIVE_SIZE -lt 5000 ]; then
2342334Ssetje	echo "update of $ALT_ROOT/$BOOT_ARCHIVE failed"
2352334Ssetje	rm -rf "$rddir"
236174Sjg	exit 1
237174Sjgfi
238174Sjg
2390Sstevel@tonic-gate#
2400Sstevel@tonic-gate# For the diskless case, hardlink archive to /boot to make it
2410Sstevel@tonic-gate# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
2420Sstevel@tonic-gate# NOTE: this script must work on both client and server
2430Sstevel@tonic-gate#
2442334Ssetjegrep "[	 ]/[	 ]*nfs[	 ]" "$ALT_ROOT/etc/vfstab" > /dev/null
2450Sstevel@tonic-gateif [ $? = 0 ]; then
2462334Ssetje	mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE"
2472334Ssetje	rm -f "$ALT_ROOT/boot/boot_archive"
2482334Ssetje	ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
2492334Ssetje	rm -rf "$rddir"
2500Sstevel@tonic-gate	exit
2510Sstevel@tonic-gatefi
2520Sstevel@tonic-gate
2532334Ssetjelockfs -f "/$ALT_ROOT"
2542334Ssetjemv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE"
2552334Ssetjelockfs -f "/$ALT_ROOT"
256174Sjg
2572334Ssetjerm -rf "$rddir"
258