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
232dc23587SToomas Soome# Copyright 2016 Toomas Soome <tsoome@me.com>
2448847494SEnrico Perla - Sun Microsystems# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
257c478bd9Sstevel@tonic-gate# Use is subject to license terms.
262dc23587SToomas Soome#
277c478bd9Sstevel@tonic-gate
28a76660dbSGeorge Wilson#
29a76660dbSGeorge Wilson# Copyright (c) 2014 by Delphix. All rights reserved.
3075383e32SAndy Fiddaman# Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
31a76660dbSGeorge Wilson#
32a76660dbSGeorge Wilson
337c478bd9Sstevel@tonic-gateALT_ROOT=
34d876c67dSjgEXTRACT_ARGS=
3575383e32SAndy FiddamanFORMAT=
3675383e32SAndy Fiddamanformat_set=0
37ae115bc7Smrjcompress=yes
3875383e32SAndy Fiddamandirsize=0
397c478bd9Sstevel@tonic-gate
40d876c67dSjgusage() {
4175383e32SAndy Fiddaman	cat <<- EOM
42*bbf21555SRichard LoweThis utility is a component of the bootadm(8) implementation and it is not
43*bbf21555SRichard Lowerecommended for stand-alone use. Please use bootadm(8) instead.
4475383e32SAndy Fiddaman
4575383e32SAndy FiddamanUsage: ${0##*/}: [-R <root>] [-p <platform>] [ -f <format> ] [--nocompress]
4675383e32SAndy Fiddamanwhere <platform> is one of i86pc, sun4u or sun4v
4775383e32SAndy Fiddaman  and <format> is one of ufs, ufs-nocompress or cpio
4875383e32SAndy Fiddaman	EOM
49d876c67dSjg	exit
50d876c67dSjg}
51d876c67dSjg
52d876c67dSjg# default platform is what we're running on
53d876c67dSjgPLATFORM=`uname -m`
54986fd29aSsetje
5587bdc129SToomas Soomeexport PATH=/usr/sbin:/usr/bin:/sbin
5687bdc129SToomas Soomeexport GZIP_CMD=/usr/bin/gzip
5775383e32SAndy Fiddamanexport CPIO_CMD=/usr/bin/cpio
587c478bd9Sstevel@tonic-gate
59986fd29aSsetjeEXTRACT_FILELIST="/boot/solaris/bin/extract_boot_filelist"
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate#
627c478bd9Sstevel@tonic-gate# Parse options
637c478bd9Sstevel@tonic-gate#
6475383e32SAndy Fiddamanwhile [ -n "$1" ]; do
65ae115bc7Smrj        case $1 in
6675383e32SAndy Fiddaman	-f)	shift
6775383e32SAndy Fiddaman		FORMAT="$1"
6875383e32SAndy Fiddaman		format_set=1
6975383e32SAndy Fiddaman		;;
7075383e32SAndy Fiddaman	-n|--nocompress) compress=no
7175383e32SAndy Fiddaman		;;
7275383e32SAndy Fiddaman	-p)	shift
7375383e32SAndy Fiddaman		PLATFORM="$1"
7475383e32SAndy Fiddaman		EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}"
7575383e32SAndy Fiddaman		;;
76ae115bc7Smrj        -R)	shift
77ae115bc7Smrj		ALT_ROOT="$1"
787c478bd9Sstevel@tonic-gate		if [ "$ALT_ROOT" != "/" ]; then
7979538500Ssetje			echo "Creating boot_archive for $ALT_ROOT"
80d876c67dSjg			EXTRACT_ARGS="${EXTRACT_ARGS} -R ${ALT_ROOT}"
81986fd29aSsetje			EXTRACT_FILELIST="${ALT_ROOT}${EXTRACT_FILELIST}"
827c478bd9Sstevel@tonic-gate		fi
837c478bd9Sstevel@tonic-gate		;;
84d876c67dSjg        *)      usage
850d69385cSrscott		;;
867c478bd9Sstevel@tonic-gate        esac
87ae115bc7Smrj	shift
887c478bd9Sstevel@tonic-gatedone
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gateshift `expr $OPTIND - 1`
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gateif [ $# -eq 1 ]; then
9358091fd8Ssetje	ALT_ROOT="$1"
9479538500Ssetje	echo "Creating boot_archive for $ALT_ROOT"
957c478bd9Sstevel@tonic-gatefi
967c478bd9Sstevel@tonic-gate
9775383e32SAndy Fiddamanif [ -z "$FORMAT" ]; then
9875383e32SAndy Fiddaman	if [ -n "$ALT_ROOT" ]; then
9975383e32SAndy Fiddaman		SVCCFG_DTD=/$ALT_ROOT/usr/share/lib/xml/dtd/service_bundle.dtd.1
10075383e32SAndy Fiddaman		SVCCFG_REPOSITORY=/$ALT_ROOT/etc/svc/repository.db
10175383e32SAndy Fiddaman		export SVCCFG_DTD SVCCFG_REPOSITORY
10275383e32SAndy Fiddaman	fi
10375383e32SAndy Fiddaman	FORMAT=`svccfg -s system/boot-archive listprop config/format \
10475383e32SAndy Fiddaman	    | awk '{print $3}'`
10575383e32SAndy Fiddamanfi
106d876c67dSjg
10775383e32SAndy Fiddamanif [ $format_set -eq 0 -a "$FORMAT" = hsfs ]; then
10875383e32SAndy Fiddaman	if /sbin/bootadm update-archive -R ${ALT_ROOT:-/} -f -L -F hsfs; then
10975383e32SAndy Fiddaman		exit 0
11075383e32SAndy Fiddaman	else
11175383e32SAndy Fiddaman		echo "Failed to create HSFS archive, falling back."
11275383e32SAndy Fiddaman	fi
113ae115bc7Smrjfi
114ae115bc7Smrj
11575383e32SAndy Fiddaman[[ "$FORMAT" =~ ^(cpio|ufs|ufs-nocompress)$ ]] || FORMAT=ufs
11675383e32SAndy Fiddaman
11775383e32SAndy Fiddamancase $PLATFORM in
11875383e32SAndy Fiddamani386|i86pc)	PLATFORM=i86pc
11975383e32SAndy Fiddaman		ISA=i386
12075383e32SAndy Fiddaman		ARCH64=amd64
12175383e32SAndy Fiddaman		BOOT_ARCHIVE_SUFFIX=$ARCH64/boot_archive
12275383e32SAndy Fiddaman		;;
12375383e32SAndy Fiddamansun4u|sun4v)	ISA=sparc
12475383e32SAndy Fiddaman		ARCH64=sparcv9
12575383e32SAndy Fiddaman		BOOT_ARCHIVE_SUFFIX=boot_archive
12675383e32SAndy Fiddaman		compress=no
12775383e32SAndy Fiddaman		;;
12875383e32SAndy Fiddaman*)		usage
12975383e32SAndy Fiddaman		;;
13075383e32SAndy Fiddamanesac
13175383e32SAndy Fiddaman
13275383e32SAndy FiddamanBOOT_ARCHIVE=platform/$PLATFORM/$BOOT_ARCHIVE_SUFFIX
133ae115bc7Smrj
13475383e32SAndy Fiddamanfunction fatal_error
13558091fd8Ssetje{
13675383e32SAndy Fiddaman	print -u2 $*
13775383e32SAndy Fiddaman	exit 1
1387c478bd9Sstevel@tonic-gate}
1397c478bd9Sstevel@tonic-gate
14075383e32SAndy Fiddaman[ -x $GZIP_CMD ] || compress=no
141986fd29aSsetje
14275383e32SAndy Fiddamancase $FORMAT in
14375383e32SAndy Fiddamancpio)		[ -x $CPIO_CMD ] || FORMAT=ufs ;;
14475383e32SAndy Fiddamanufs-nocompress)	FORMAT=ufs; compress=no ;;
14575383e32SAndy Fiddamanufs)		;;
14675383e32SAndy Fiddamanesac
1477c478bd9Sstevel@tonic-gate
148fe33b55dSrscott#
1496bb08588Srscott# Copies all desired files to a target directory.  One argument should be
1506bb08588Srscott# passed: the file containing the list of files to copy.  This function also
1516bb08588Srscott# depends on several variables that must be set before calling:
152fe33b55dSrscott#
153fe33b55dSrscott# $ALT_ROOT - the target directory
154fe33b55dSrscott# $compress - whether or not the files in the archives should be compressed
155fe33b55dSrscott# $rdmnt - the target directory
156fe33b55dSrscott#
1576bb08588Srscottfunction copy_files
158fe33b55dSrscott{
15975383e32SAndy Fiddaman	typeset listfile="$1"
160fe33b55dSrscott
161fe33b55dSrscott	#
162fe33b55dSrscott	# If compress is set, the files are gzip'd and put in the correct
163fe33b55dSrscott	# location in the loop.  Nothing is printed, so the pipe and cpio
164fe33b55dSrscott	# at the end is a nop.
165fe33b55dSrscott	#
166fe33b55dSrscott	# If compress is not set, the file names are printed, which causes
167fe33b55dSrscott	# the cpio at the end to do the copy.
168fe33b55dSrscott	#
16975383e32SAndy Fiddaman	while read path; do
1706bb08588Srscott		if [ $compress = yes ]; then
1716bb08588Srscott			dir="${path%/*}"
172a916d99cSdminer			[ -d "$rdmnt/$dir" ] || mkdir -p "$rdmnt/$dir"
17379538500Ssetje			$GZIP_CMD -c "$path" > "$rdmnt/$path"
174fe33b55dSrscott		else
1756bb08588Srscott			print "$path"
176fe33b55dSrscott		fi
17775383e32SAndy Fiddaman	done <"$listfile" | cpio -pdum "$rdmnt" 2>/dev/null
178986fd29aSsetje
179d876c67dSjg	if [ $ISA = sparc ] ; then
180986fd29aSsetje		# copy links
181986fd29aSsetje		find $filelist -type l -print 2>/dev/null |\
182986fd29aSsetje		    cpio -pdum "$rdmnt" 2>/dev/null
183986fd29aSsetje		if [ $compress = yes ] ; then
184986fd29aSsetje			# always copy unix uncompressed
185986fd29aSsetje			find $filelist -name unix -type f -print 2>/dev/null |\
186986fd29aSsetje			    cpio -pdum "$rdmnt" 2>/dev/null
187986fd29aSsetje		fi
188986fd29aSsetje	fi
189986fd29aSsetje
190fe33b55dSrscott}
191fe33b55dSrscott
19275383e32SAndy Fiddamanfunction ufs_cleanup
1937c478bd9Sstevel@tonic-gate{
19475383e32SAndy Fiddaman	umount -f "$rdmnt" 2>/dev/null
19575383e32SAndy Fiddaman	lofiadm -d "$rdfile" 2>/dev/null
19675383e32SAndy Fiddaman	[ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null
19775383e32SAndy Fiddaman	[ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null
19875383e32SAndy Fiddaman}
19975383e32SAndy Fiddaman
20075383e32SAndy Fiddamanfunction ufs_getsize
20175383e32SAndy Fiddaman{
20275383e32SAndy Fiddaman	# Estimate image size and add 10% overhead for ufs stuff.
20375383e32SAndy Fiddaman	# Note, we can't use du here in case we're on a filesystem, e.g. zfs,
20475383e32SAndy Fiddaman	# in which the disk usage is less than the sum of the file sizes.
20575383e32SAndy Fiddaman	# The nawk code
20675383e32SAndy Fiddaman	#
20775383e32SAndy Fiddaman	#	{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
20875383e32SAndy Fiddaman	#
20975383e32SAndy Fiddaman	# below rounds up the size of a file/directory, in bytes, to the
21075383e32SAndy Fiddaman	# next multiple of 1024.  This mimics the behavior of ufs especially
21175383e32SAndy Fiddaman	# with directories.  This results in a total size that's slightly
21275383e32SAndy Fiddaman	# bigger than if du was called on a ufs directory.
21375383e32SAndy Fiddaman	size=$(cat "$list" | xargs -I {} ls -lLd "{}" 2> /dev/null |
21475383e32SAndy Fiddaman		nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
21575383e32SAndy Fiddaman		END {print int(t * 1.10 / 1024)}')
21675383e32SAndy Fiddaman	(( size += dirsize ))
21775383e32SAndy Fiddaman	(( total_size = size ))
21875383e32SAndy Fiddaman	# If compression is enabled, then each file within the archive will
21975383e32SAndy Fiddaman	# be individually compressed. The compression ratio is around 60%
22075383e32SAndy Fiddaman	# across the archive so make the image smaller.
22175383e32SAndy Fiddaman	[ $compress = yes ] && (( total_size = total_size / 2 ))
22275383e32SAndy Fiddaman}
22375383e32SAndy Fiddaman
224cb6ebde4SToomas Soomefunction calculate_sizes_and_locations
22575383e32SAndy Fiddaman{
22675383e32SAndy Fiddaman	find $filelist -print 2>/dev/null | while read path; do
22775383e32SAndy Fiddaman		if [ -d "$path" ]; then
22875383e32SAndy Fiddaman			size=`ls -lLd "$path" | nawk '
22975383e32SAndy Fiddaman		    {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'`
23075383e32SAndy Fiddaman			(( dirsize += size / 1024 ))
23175383e32SAndy Fiddaman		else
23275383e32SAndy Fiddaman			print "$path"
23375383e32SAndy Fiddaman		fi
23475383e32SAndy Fiddaman	done >"$list"
23575383e32SAndy Fiddaman
23675383e32SAndy Fiddaman	# calculate image size
23775383e32SAndy Fiddaman	ufs_getsize
23875383e32SAndy Fiddaman
23975383e32SAndy Fiddaman	# check to see if there is sufficient space in tmpfs
24075383e32SAndy Fiddaman	#
24175383e32SAndy Fiddaman	tmp_free=`df -b /tmp | tail -1 | awk '{ print $2 }'`
24275383e32SAndy Fiddaman	(( tmp_free = tmp_free / 3 ))
24375383e32SAndy Fiddaman
24475383e32SAndy Fiddaman	if [ $total_size -gt $tmp_free ] ; then
24575383e32SAndy Fiddaman		echo "Insufficient space in /tmp, using $ALT_ROOT/var/tmp"
24675383e32SAndy Fiddaman		# assumes we have enough scratch space on $ALT_ROOT
24775383e32SAndy Fiddaman		new_rddir="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp"
24875383e32SAndy Fiddaman		rm -rf "$new_rddir"
24975383e32SAndy Fiddaman		mkdir "$new_rddir" || fatal_error \
25075383e32SAndy Fiddaman		    "Could not create temporary directory $new_rddir"
25175383e32SAndy Fiddaman
25275383e32SAndy Fiddaman		# Save the file lists
25375383e32SAndy Fiddaman		mv "$list" "$new_rddir"/
25475383e32SAndy Fiddaman		list="/$new_rddir/filelist"
25575383e32SAndy Fiddaman
25675383e32SAndy Fiddaman		# Remove the old $rddir and set the new value of rddir
25775383e32SAndy Fiddaman		rm -rf "$rddir"
25875383e32SAndy Fiddaman		rddir="$new_rddir"
25975383e32SAndy Fiddaman		new_rddir=
260ae115bc7Smrj	fi
261cb6ebde4SToomas Soome}
262cb6ebde4SToomas Soome
263cb6ebde4SToomas Soomefunction create_ufs_archive
264cb6ebde4SToomas Soome{
265cb6ebde4SToomas Soome	typeset archive="$ALT_ROOT/$BOOT_ARCHIVE"
266cb6ebde4SToomas Soome
267cb6ebde4SToomas Soome	[ "$compress" = yes ] && \
268cb6ebde4SToomas Soome	    echo "updating $archive (UFS)" || \
269cb6ebde4SToomas Soome	    echo "updating $archive (UFS-nocompress)"
270cb6ebde4SToomas Soome
271cb6ebde4SToomas Soome	#
272cb6ebde4SToomas Soome	# We use /tmp/ for scratch space now.  This will be changed later to
273cb6ebde4SToomas Soome	# $ALT_ROOT/var/tmp if there is insufficient space in /tmp/.
274cb6ebde4SToomas Soome	#
275cb6ebde4SToomas Soome	rddir="/tmp/create_ramdisk.$$.tmp"
276cb6ebde4SToomas Soome	new_rddir=
277cb6ebde4SToomas Soome	rm -rf "$rddir"
278cb6ebde4SToomas Soome	mkdir "$rddir" || fatal_error "Could not create directory $rddir"
279cb6ebde4SToomas Soome
280cb6ebde4SToomas Soome	# Clean up upon exit.
281cb6ebde4SToomas Soome	trap 'ufs_cleanup' EXIT
282cb6ebde4SToomas Soome
283cb6ebde4SToomas Soome	list="$rddir/filelist"
284cb6ebde4SToomas Soome
285cb6ebde4SToomas Soome	cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT"
286cb6ebde4SToomas Soome	calculate_sizes_and_locations
2877c478bd9Sstevel@tonic-gate
28875383e32SAndy Fiddaman	rdfile="$rddir/rd.file"
28975383e32SAndy Fiddaman	rdmnt="$rddir/rd.mount"
29075383e32SAndy Fiddaman	errlog="$rddir/rd.errlog"
29175383e32SAndy Fiddaman	lofidev=""
29275383e32SAndy Fiddaman
29375383e32SAndy Fiddaman	mkfile ${total_size}k "$rdfile" || \
29475383e32SAndy Fiddaman	    fatal_error "Could not create backing file"
29575383e32SAndy Fiddaman	lofidev=`lofiadm -a "$rdfile"` || \
29675383e32SAndy Fiddaman	    fatal_error "Could not create lofi device"
29775383e32SAndy Fiddaman
29875383e32SAndy Fiddaman	NOINUSE_CHECK=1 newfs -m 0 $lofidev < /dev/null 2> /dev/null
29958091fd8Ssetje	mkdir "$rdmnt"
3007c478bd9Sstevel@tonic-gate	mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
3017ce430bdSsetje	mount -F ufs -o nologging $lofidev "$rdmnt"
30275383e32SAndy Fiddaman	rm -rf "$rdmnt/lost+found"
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate	# do the actual copy
3056bb08588Srscott	copy_files "$list"
30648847494SEnrico Perla - Sun Microsystems	umount -f "$rdmnt"
30758091fd8Ssetje	rmdir "$rdmnt"
30858091fd8Ssetje
309d876c67dSjg	if [ $ISA = sparc ] ; then
31075383e32SAndy Fiddaman		rlofidev="${lofidev/lofi/rlofi}"
31175383e32SAndy Fiddaman		bb="/$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk"
312d876c67dSjg		# installboot is not available on all platforms
313d876c67dSjg		dd if=$bb of=$rlofidev bs=1b oseek=1 count=15 conv=sync 2>&1
314986fd29aSsetje	fi
315986fd29aSsetje
31675383e32SAndy Fiddaman	lofiadm -d "$rdfile"
31775383e32SAndy Fiddaman
318ae115bc7Smrj	#
31958091fd8Ssetje	# Check if gzip exists in /usr/bin, so we only try to run gzip
32058091fd8Ssetje	# on systems that have gzip. Then run gzip out of the patch to
32158091fd8Ssetje	# pick it up from bfubin or something like that if needed.
32258091fd8Ssetje	#
323ae115bc7Smrj	# If compress is set, the individual files in the archive are
324ae115bc7Smrj	# compressed, and the final compression will accomplish very
325ae115bc7Smrj	# little.  To save time, we skip the gzip in this case.
326ae115bc7Smrj	#
32775383e32SAndy Fiddaman	if [ $ISA = i386 ] && [ $compress = no ] && [ -x $GZIP_CMD ] ; then
32875383e32SAndy Fiddaman		$GZIP_CMD -c "$rdfile" > "${archive}-new"
32958091fd8Ssetje	else
330ae115bc7Smrj		cat "$rdfile" > "${archive}-new"
33158091fd8Ssetje	fi
33275383e32SAndy Fiddaman
33348847494SEnrico Perla - Sun Microsystems	if [ $? -ne 0 ] ; then
33448847494SEnrico Perla - Sun Microsystems		rm -f "${archive}-new"
33548847494SEnrico Perla - Sun Microsystems	fi
336ae115bc7Smrj
337ae115bc7Smrj	# sanity check the archive before moving it into place
338ae115bc7Smrj	#
33948847494SEnrico Perla - Sun Microsystems	ARCHIVE_SIZE=`ls -l "${archive}-new" 2> /dev/null | nawk '{ print $5 }'`
340d876c67dSjg	if [ $compress = yes ] || [ $ISA = sparc ] ; then
341ae115bc7Smrj		#
342ae115bc7Smrj		# 'file' will report "English text" for uncompressed
343ae115bc7Smrj		# boot_archives.  Checking for that doesn't seem stable,
344ae115bc7Smrj		# so we just check that the file exists.
345ae115bc7Smrj		#
346ae115bc7Smrj		ls "${archive}-new" >/dev/null 2>&1
347ae115bc7Smrj	else
348ae115bc7Smrj		#
349ae115bc7Smrj		# the file type check also establishes that the
350ae115bc7Smrj		# file exists at all
351ae115bc7Smrj		#
352ece420edSsetje		LC_MESSAGES=C file "${archive}-new" | grep gzip > /dev/null
353ae115bc7Smrj	fi
354ae115bc7Smrj
35548847494SEnrico Perla - Sun Microsystems	if [ $? = 1 ] && [ -x $GZIP_CMD ] || [ "$ARCHIVE_SIZE" -lt 10000 ]
356ae115bc7Smrj	then
35775383e32SAndy Fiddaman		fatal_error "update of $archive failed"
358ae115bc7Smrj	else
359ae115bc7Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
3602dc23587SToomas Soome		rm -f "$archive.hash"
36175383e32SAndy Fiddaman		mv "${archive}-new" "$archive"
36275383e32SAndy Fiddaman		digest -a sha1 "$rdfile" > "$archive.hash"
363ae115bc7Smrj		lockfs -f "/$ALT_ROOT" 2>/dev/null
364ae115bc7Smrj	fi
36575383e32SAndy Fiddaman	[ -n "$rddir" ] && rm -rf "$rddir"
36675383e32SAndy Fiddaman}
367ae115bc7Smrj
36875383e32SAndy Fiddamanfunction cpio_cleanup
36975383e32SAndy Fiddaman{
370cb6ebde4SToomas Soome	rm -f "$tarchive" "$tarchive.cpio" "$tarchive.hash" "$tarchive.head"
371cb6ebde4SToomas Soome	[ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null
372cb6ebde4SToomas Soome}
373cb6ebde4SToomas Soome
374cb6ebde4SToomas Soomefunction create_hash
375cb6ebde4SToomas Soome{
376cb6ebde4SToomas Soome	[ -x /usr/bin/digest ] \
377cb6ebde4SToomas Soome	    && /usr/bin/digest -a sha1 "$tarchive.cpio" > "$tarchive.hash" \
378cb6ebde4SToomas Soome	    || print -u2 "Failed to create sha1 hash of $tarchive"
379ae115bc7Smrj}
380ae115bc7Smrj
38175383e32SAndy Fiddamanfunction create_cpio_archive
3826bb08588Srscott{
38375383e32SAndy Fiddaman	typeset archive="$ALT_ROOT/$BOOT_ARCHIVE"
38475383e32SAndy Fiddaman
38575383e32SAndy Fiddaman	echo "updating $archive (CPIO)"
38675383e32SAndy Fiddaman
387cb6ebde4SToomas Soome	rddir="/tmp/create_ramdisk.$$.tmp"
38875383e32SAndy Fiddaman	tarchive="$archive.$$.new"
389cb6ebde4SToomas Soome	rm -rf "$rddir"
390cb6ebde4SToomas Soome	mkdir "$rddir" || fatal_error "Could not create directory $rddir"
39175383e32SAndy Fiddaman
39275383e32SAndy Fiddaman	# Clean up upon exit.
39375383e32SAndy Fiddaman	trap 'cpio_cleanup' EXIT
39475383e32SAndy Fiddaman
39575383e32SAndy Fiddaman	cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT"
39675383e32SAndy Fiddaman
39775383e32SAndy Fiddaman	touch "$tarchive" \
39875383e32SAndy Fiddaman	    || fatal_error "Cannot create temporary archive $tarchive"
39975383e32SAndy Fiddaman
400cb6ebde4SToomas Soome	if [ $ISA = sparc ] ; then
401cb6ebde4SToomas Soome		# compression does not work (yet?).
402cb6ebde4SToomas Soome		# The krtld does not support gzip but fiocompress
403cb6ebde4SToomas Soome		# does not seem to work either.
404cb6ebde4SToomas Soome		compress="no"
405cb6ebde4SToomas Soome		list="$rddir/filelist"
406cb6ebde4SToomas Soome
407cb6ebde4SToomas Soome		calculate_sizes_and_locations
408cb6ebde4SToomas Soome
409cb6ebde4SToomas Soome		rdmnt="$rddir/rd.mount"
410cb6ebde4SToomas Soome		mkdir "$rdmnt"
411cb6ebde4SToomas Soome
412cb6ebde4SToomas Soome		copy_files "$list"
413cb6ebde4SToomas Soome
414cb6ebde4SToomas Soome		cd "$rdmnt"
415cb6ebde4SToomas Soome		find . 2>/dev/null | \
416cb6ebde4SToomas Soome		    cpio -qo -H odc > "$tarchive.cpio" \
417cb6ebde4SToomas Soome		    || fatal_error "Problem creating archive"
418cb6ebde4SToomas Soome		cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT"
419cb6ebde4SToomas Soome
420cb6ebde4SToomas Soome		bb="/$ALT_ROOT/platform/$PLATFORM/lib/fs/cpio/bootblk"
421cb6ebde4SToomas Soome
422cb6ebde4SToomas Soome		# The SPARC boot code is assuming 8KB of boot data.
423cb6ebde4SToomas Soome		# This is originating from disk layout and UFS limits.
424cb6ebde4SToomas Soome		# Therefore we have 512B reserved space for disk label,
425cb6ebde4SToomas Soome		# and 7.5KB for boot program. With 512B blocks, this is
426cb6ebde4SToomas Soome		# 1 + 15 blocks.
427cb6ebde4SToomas Soome		dd if=/dev/zero of="$tarchive.head" bs=512 count=16 2>&1 \
428cb6ebde4SToomas Soome		    || fatal_error "Cannot create header"
429cb6ebde4SToomas Soome		dd if=$bb of="$tarchive.head" bs=512 oseek=1 count=15 \
430cb6ebde4SToomas Soome		    conv=sync 2>&1 \
431cb6ebde4SToomas Soome		    || fatal_error "Cannot install boot block"
432cb6ebde4SToomas Soome		cat "$tarchive.head" "$tarchive.cpio" > "$tarchive" \
433cb6ebde4SToomas Soome		    || fatal_error "Cannot update boot archive"
434cb6ebde4SToomas Soome		rm -f "$tarchive.head" "$tarchive.cpio"
43575383e32SAndy Fiddaman	else
436cb6ebde4SToomas Soome		find $filelist 2>/dev/null | \
437cb6ebde4SToomas Soome		    cpio -qo -H odc > "$tarchive.cpio" \
438cb6ebde4SToomas Soome		    || fatal_error "Problem creating archive"
439cb6ebde4SToomas Soome
440cb6ebde4SToomas Soome		# If hash is supported, it must be created before gzipping the archive.
441cb6ebde4SToomas Soome		# The boot loader will uncompress the archive, and the hash
442cb6ebde4SToomas Soome		# will be verified against the uncompressed data.
443cb6ebde4SToomas Soome		create_hash
444cb6ebde4SToomas Soome
445cb6ebde4SToomas Soome		if [ -x "$GZIP_CMD" ]; then
446cb6ebde4SToomas Soome			$GZIP_CMD -c "$tarchive.cpio" > "$tarchive"
447cb6ebde4SToomas Soome			rm -f "$tarchive.cpio"
448cb6ebde4SToomas Soome		else
449cb6ebde4SToomas Soome			mv "$tarchive.cpio" "$tarchive"
450cb6ebde4SToomas Soome		fi
45175383e32SAndy Fiddaman	fi
45275383e32SAndy Fiddaman
45375383e32SAndy Fiddaman	# Move new archive into place
45475383e32SAndy Fiddaman	[ -f "$archive.hash" ] && rm -f "$archive.hash"
45575383e32SAndy Fiddaman	mv "$tarchive" "$archive"
45675383e32SAndy Fiddaman	[ $? -eq 0 -a  -f "$tarchive.hash" ] \
45775383e32SAndy Fiddaman	    && mv "$tarchive.hash" "$archive.hash"
4586bb08588Srscott}
4596bb08588Srscott
4607c478bd9Sstevel@tonic-gate#
4617c478bd9Sstevel@tonic-gate# get filelist
4627c478bd9Sstevel@tonic-gate#
463fe33b55dSrscottif [ ! -f "$ALT_ROOT/boot/solaris/filelist.ramdisk" ] &&
464fe33b55dSrscott    [ ! -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]
465e482cb0aSjongkisthen
466e482cb0aSjongkis	print -u2 "Can't find filelist.ramdisk"
467e482cb0aSjongkis	exit 1
4687c478bd9Sstevel@tonic-gatefi
469d876c67dSjgfilelist=$($EXTRACT_FILELIST $EXTRACT_ARGS \
470d876c67dSjg	/boot/solaris/filelist.ramdisk \
471d876c67dSjg	/etc/boot/solaris/filelist.ramdisk \
472d876c67dSjg		2>/dev/null | sort -u)
4737c478bd9Sstevel@tonic-gate
47475383e32SAndy Fiddaman# Now that we have the list of files, we can create the archive.
47558091fd8Ssetje
47675383e32SAndy Fiddamancase "$FORMAT" in
47775383e32SAndy Fiddaman	cpio)	create_cpio_archive ;;
47875383e32SAndy Fiddaman	ufs)	create_ufs_archive ;;
47975383e32SAndy Fiddaman	*)	print -u2 "Unknown boot archive format, $FORMAT"
48075383e32SAndy Fiddaman		exit 1
48175383e32SAndy Fiddaman		;;
48275383e32SAndy Fiddamanesac
483847671deSjg
4847c478bd9Sstevel@tonic-gate#
4857c478bd9Sstevel@tonic-gate# For the diskless case, hardlink archive to /boot to make it
4867c478bd9Sstevel@tonic-gate# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
487ae115bc7Smrj# NOTE: this script must work on both client and server.
4887c478bd9Sstevel@tonic-gate#
48958091fd8Ssetjegrep "[	 ]/[	 ]*nfs[	 ]" "$ALT_ROOT/etc/vfstab" > /dev/null
4907c478bd9Sstevel@tonic-gateif [ $? = 0 ]; then
49175383e32SAndy Fiddaman	rm -f "$ALT_ROOT/boot/$BOOT_ARCHIVE_SUFFIX"
49275383e32SAndy Fiddaman	mkdir -p "$ALT_ROOT/boot/`dirname $BOOT_ARCHIVE_SUFFIX`"
49375383e32SAndy Fiddaman	ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/$BOOT_ARCHIVE_SUFFIX"
4947c478bd9Sstevel@tonic-gatefi
495