xref: /illumos-gate/usr/src/cmd/boot/scripts/create_ramdisk.ksh (revision 646e55b6807cdf761fecd1e4095d73116cdefdb5)
1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25
26# ident	"%Z%%M%	%I%	%E% SMI"
27
28format=ufs
29ALT_ROOT=
30NO_AMD64=
31
32BOOT_ARCHIVE=platform/i86pc/boot_archive
33
34export PATH=$PATH:/usr/sbin:/usr/bin:/sbin
35
36#
37# Parse options
38#
39while getopts R: OPT 2> /dev/null
40do
41        case $OPT in
42        R)      ALT_ROOT="$OPTARG"
43		if [ "$ALT_ROOT" != "/" ]; then
44			echo "Creating ram disk for $ALT_ROOT"
45		fi
46		;;
47        ?)      echo Usage: ${0##*/}: [-R \<root\>]
48		exit ;;
49        esac
50done
51
52if [ -x /usr/bin/mkisofs -o -x /tmp/bfubin/mkisofs ] ; then
53	format=isofs
54fi
55
56#
57# mkisofs on s8 doesn't support functionality used by GRUB boot.
58# Use ufs format for boot archive instead.
59#
60release=`uname -r`
61if [ "$release" = "5.8" ]; then
62   format=ufs
63fi
64
65shift `expr $OPTIND - 1`
66
67if [ $# -eq 1 ]; then
68	ALT_ROOT="$1"
69	echo "Creating ram disk for $ALT_ROOT"
70fi
71
72function cleanup
73{
74	umount -f "$rdmnt" 2>/dev/null
75	lofiadm -d "$rdfile" 2>/dev/null
76	rm -fr "$rddir" 2> /dev/null
77}
78
79function getsize
80{
81	# Estimate image size, add %10 overhead for ufs stuff
82	total_size=0
83	for file in $filelist
84	do
85		if [ -e "$ALT_ROOT/$file" ] ; then
86			du -sk "$ALT_ROOT/$file" | read size name
87			(( total_size += size ))
88		fi
89	done
90	(( total_size += total_size * 10 / 100 ))
91}
92
93function create_ufs
94{
95	# should we exclude amd64 binaries?
96	[ $is_amd64 -eq 0 ] && NO_AMD64="-name amd64 -prune"
97
98
99	mkfile ${total_size}k "$rdfile"
100	lofidev=`lofiadm -a "$rdfile"`
101	newfs $lofidev < /dev/null 2> /dev/null
102	mkdir "$rdmnt"
103	mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
104	mount -o nologging $lofidev "$rdmnt"
105
106	# do the actual copy
107	cd "/$ALT_ROOT"
108
109	find $filelist -print $NO_AMD64 2> /dev/null | \
110	     cpio -pdum "$rdmnt" 2> /dev/null
111	umount "$rdmnt"
112	lofiadm -d "$rdfile"
113	rmdir "$rdmnt"
114
115	# Check if gzip exists in /usr/bin, so we only try to run gzip
116	# on systems that have gzip. Then run gzip out of the patch to
117	# pick it up from bfubin or something like that if needed.
118	#
119	if [ -x /usr/bin/gzip ] ; then
120		gzip -c "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
121	else
122		cat "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
123	fi
124}
125
126function create_isofs
127{
128	# should we exclude amd64 binaries?
129	[ $is_amd64 = 0 ] && NO_AMD64="-m amd64"
130
131	# create image directory seed with graft points
132	mkdir "$rdmnt"
133	files=
134	isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames $NO_AMD64"
135	for path in $filelist
136	do
137		if [ -d "$ALT_ROOT/$path" ]; then
138			isocmd="$isocmd $path/=\"$ALT_ROOT/$path\""
139			mkdir -p "$rdmnt/$path"
140		elif [ -f "$ALT_ROOT/$path" ]; then
141			files="$files $path"
142		fi
143	done
144	cd "/$ALT_ROOT"
145	find $files 2> /dev/null | cpio -pdum "$rdmnt" 2> /dev/null
146	isocmd="$isocmd \"$rdmnt\""
147	rm -f "$errlog"
148
149	# Check if gzip exists in /usr/bin, so we only try to run gzip
150	# on systems that have gzip. Then run gzip out of the patch to
151	# pick it up from bfubin or something like that if needed.
152	#
153	if [ -x /usr/bin/gzip ] ; then
154		ksh -c "$isocmd" 2> "$errlog" | \
155		    gzip > "$ALT_ROOT/$BOOT_ARCHIVE-new"
156	else
157		ksh -c "$isocmd" 2> "$errlog" > "$ALT_ROOT/$BOOT_ARCHIVE-new"
158	fi
159
160	if [ -s "$errlog" ]; then
161		grep Error: "$errlog" >/dev/null 2>&1
162		if [ $? -eq 0 ]; then
163			grep Error: "$errlog"
164			rm -f "$ALT_ROOT/$BOOT_ARCHIVE-new"
165		fi
166	fi
167	rm -f "$errlog"
168}
169
170#
171# get filelist
172#
173filelist=`cat "$ALT_ROOT/boot/solaris/filelist.ramdisk"`
174if [ -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]; then
175	filelistI=`cat "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk"`
176fi
177filelist=`echo $filelist $filelistI | sort -u`
178
179#
180# decide if cpu is amd64 capable
181#
182prtconf -v /devices | grep CPU_not_amd64 > /dev/null 2>&1
183is_amd64=$?
184
185scratch=tmp
186
187if [ $format = ufs ] ; then
188	# calculate image size
189	getsize
190
191	# check to see if there is sufficient space in tmpfs
192	#
193	tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
194	(( tmp_free = tmp_free / 2 ))
195
196	if [ $total_size -gt $tmp_free  ] ; then
197		# assumes we have enough scratch space on $ALT_ROOT
198        	scratch="$ALT_ROOT"
199	fi
200fi
201
202rddir="/$scratch/create_ramdisk.$$.tmp"
203rdfile="$rddir/rd.file"
204rdmnt="$rddir/rd.mount"
205errlog="$rddir/rd.errlog"
206
207# make directory for temp files safely
208rm -rf "$rddir"
209mkdir "$rddir"
210
211# Clean up upon exit.
212trap 'cleanup' EXIT
213
214echo "updating $ALT_ROOT/$BOOT_ARCHIVE...this may take a minute"
215
216if [ $format = "ufs" ]; then
217	create_ufs
218else
219	create_isofs
220fi
221
222# sanity check the archive before moving it into place
223# the file type check also establishes that the file exists at all
224#
225ARCHIVE_SIZE=`du -k "$ALT_ROOT/$BOOT_ARCHIVE-new" | cut -f 1`
226file "$ALT_ROOT/$BOOT_ARCHIVE-new" | grep gzip > /dev/null
227
228if [ $? = 1 ] && [ -x /usr/bin/gzip ] || [ $ARCHIVE_SIZE -lt 5000 ]; then
229	echo "update of $ALT_ROOT/$BOOT_ARCHIVE failed"
230	rm -rf "$rddir"
231	exit 1
232fi
233
234#
235# For the diskless case, hardlink archive to /boot to make it
236# visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
237# NOTE: this script must work on both client and server
238#
239grep "[	 ]/[	 ]*nfs[	 ]" "$ALT_ROOT/etc/vfstab" > /dev/null
240if [ $? = 0 ]; then
241	mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE"
242	rm -f "$ALT_ROOT/boot/boot_archive"
243	ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
244	rm -rf "$rddir"
245	exit
246fi
247
248lockfs -f "/$ALT_ROOT"
249mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE"
250lockfs -f "/$ALT_ROOT"
251
252rm -rf "$rddir"
253