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.
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.
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]
23 # Copyright 2016 Toomas Soome <tsoome@me.com>
24 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
29 # Copyright (c) 2014 by Delphix. All rights reserved.
42 echo "This utility is a component of the bootadm(1M) implementation"
43 echo "and it is not recommended for stand-alone use."
44 echo "Please use bootadm(1M) instead."
46 echo "Usage: ${0##*/}: [-R \<root\>] [-p \<platform\>] [--nocompress]"
47 echo "where \<platform\> is one of i86pc, sun4u or sun4v"
51 # default platform is what we're running on
54 export PATH
=/usr
/sbin
:/usr
/bin
:/sbin
55 export GZIP_CMD
=/usr
/bin
/gzip
57 EXTRACT_FILELIST
="/boot/solaris/bin/extract_boot_filelist"
67 if [ "$ALT_ROOT" != "/" ]; then
68 echo "Creating boot_archive for $ALT_ROOT"
69 EXTRACT_ARGS
="${EXTRACT_ARGS} -R ${ALT_ROOT}"
70 EXTRACT_FILELIST
="${ALT_ROOT}${EXTRACT_FILELIST}"
73 -n|
--nocompress) compress=no
77 EXTRACT_ARGS
="${EXTRACT_ARGS} -p ${PLATFORM}"
85 if [ -x /usr
/bin
/mkisofs
] ; then
89 shift `expr $OPTIND - 1`
93 echo "Creating boot_archive for $ALT_ROOT"
114 BOOT_ARCHIVE
=platform
/$PLATFORM/boot_archive
115 BOOT_ARCHIVE_64
=platform
/$PLATFORM/$ARCH64/boot_archive
117 if [ $PLATFORM = i86pc
] ; then
118 if [ ! -x "$ALT_ROOT"/boot
/solaris
/bin
/symdef
]; then
119 # no dboot implies combined archives for example
120 # live-upgrade from s9 to s10u6 is multiboot-only
121 echo "Creating single archive at $ALT_ROOT/$BOOT_ARCHIVE"
128 SPLIT
=no
# there's only 64-bit (sparcv9), so don't split
132 [ -x $GZIP_CMD ] ||
compress=no
136 umount
-f "$rdmnt32" 2>/dev
/null
137 umount
-f "$rdmnt64" 2>/dev
/null
138 lofiadm
-d "$rdfile32" 2>/dev
/null
139 lofiadm
-d "$rdfile64" 2>/dev
/null
140 [ -n "$rddir" ] && rm -fr "$rddir" 2> /dev
/null
141 [ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev
/null
146 # Estimate image size and add 10% overhead for ufs stuff.
147 # Note, we can't use du here in case we're on a filesystem, e.g. zfs,
148 # in which the disk usage is less than the sum of the file sizes.
151 # {t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
153 # below rounds up the size of a file/directory, in bytes, to the
154 # next multiple of 1024. This mimics the behavior of ufs especially
155 # with directories. This results in a total size that's slightly
156 # bigger than if du was called on a ufs directory.
157 size32
=$
(cat "$list32" |
xargs -I {} ls -lLd "{}" 2> /dev
/null |
158 nawk
'{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
159 END {print int(t * 1.10 / 1024)}')
160 (( size32
+= dirsize32
))
161 size64
=$
(cat "$list64" |
xargs -I {} ls -lLd "{}" 2> /dev
/null |
162 nawk
'{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
163 END {print int(t * 1.10 / 1024)}')
164 (( size64
+= dirsize64
))
165 (( total_size
= size32
+ size64
))
167 if [ $compress = yes ] ; then
168 total_size
=`echo $total_size | nawk '{print int($1 / 2)}'`
173 # Copies all desired files to a target directory. One argument should be
174 # passed: the file containing the list of files to copy. This function also
175 # depends on several variables that must be set before calling:
177 # $ALT_ROOT - the target directory
178 # $compress - whether or not the files in the archives should be compressed
179 # $rdmnt - the target directory
186 # If compress is set, the files are gzip'd and put in the correct
187 # location in the loop. Nothing is printed, so the pipe and cpio
188 # at the end is a nop.
190 # If compress is not set, the file names are printed, which causes
191 # the cpio at the end to do the copy.
195 if [ $compress = yes ]; then
197 [ -d "$rdmnt/$dir" ] || mkdir
-p "$rdmnt/$dir"
198 $GZIP_CMD -c "$path" > "$rdmnt/$path"
202 done <"$list" |
cpio -pdum "$rdmnt" 2>/dev
/null
204 if [ $ISA = sparc
] ; then
206 find $filelist -type l
-print 2>/dev
/null |\
207 cpio -pdum "$rdmnt" 2>/dev
/null
208 if [ $compress = yes ] ; then
209 # always copy unix uncompressed
210 find $filelist -name unix
-type f
-print 2>/dev
/null |\
211 cpio -pdum "$rdmnt" 2>/dev
/null
218 # The first argument can be:
220 # "both" - create an archive with both 32-bit and 64-bit binaries
221 # "32-bit" - create an archive with only 32-bit binaries
222 # "64-bit" - create an archive with only 64-bit binaries
230 # should we exclude amd64 binaries?
231 if [ "$which" = "32-bit" ]; then
235 elif [ "$which" = "64-bit" ]; then
245 NOINUSE_CHECK
=1 newfs
$lofidev < /dev
/null
2> /dev
/null
247 mount
-F mntfs mnttab
/etc
/mnttab
> /dev
/null
2>&1
248 mount
-F ufs
-o nologging
$lofidev "$rdmnt"
256 if [ $ISA = sparc
] ; then
257 rlofidev
=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"`
258 bb
="$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk"
259 # installboot is not available on all platforms
260 dd if=$bb of
=$rlofidev bs
=1b oseek
=1 count
=15 conv
=sync
2>&1
264 # Check if gzip exists in /usr/bin, so we only try to run gzip
265 # on systems that have gzip. Then run gzip out of the patch to
266 # pick it up from bfubin or something like that if needed.
268 # If compress is set, the individual files in the archive are
269 # compressed, and the final compression will accomplish very
270 # little. To save time, we skip the gzip in this case.
272 if [ $ISA = i386
] && [ $compress = no
] && \
273 [ -x $GZIP_CMD ] ; then
274 gzip -c "$rdfile" > "${archive}-new"
276 cat "$rdfile" > "${archive}-new"
279 if [ $?
-ne 0 ] ; then
280 rm -f "${archive}-new"
285 # The first argument can be:
287 # "both" - create an archive with both 32-bit and 64-bit binaries
288 # "32-bit" - create an archive with only 32-bit binaries
289 # "64-bit" - create an archive with only 64-bit binaries
291 function create_isofs
296 # should we exclude amd64 binaries?
297 if [ "$which" = "32-bit" ]; then
301 elif [ "$which" = "64-bit" ]; then
311 # create image directory seed with graft points
314 isocmd
="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames"
316 if [ $ISA = sparc
] ; then
317 bb
="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
318 isocmd
="$isocmd -G \"$bb\""
322 isocmd
="$isocmd \"$rdmnt\""
326 # Check if gzip exists in /usr/bin, so we only try to run gzip
327 # on systems that have gzip. Then run gzip out of the patch to
328 # pick it up from bfubin or something like that if needed.
330 # If compress is set, the individual files in the archive are
331 # compressed, and the final compression will accomplish very
332 # little. To save time, we skip the gzip in this case.
336 if [ $ISA = i386
] &&[ $compress = no
] && [ -x $GZIP_CMD ]
338 ksh
-c "$isocmd" 2> "$errlog" | \
339 gzip > "${archive}-new"
341 ksh
-c "$isocmd" 2> "$errlog" > "${archive}-new"
344 if [ $?
-ne 0 ]; then
346 rm -f "${archive}-new" 2> /dev
/null
347 rm -f "$errlog" 2> /dev
/null
352 if [ $ISA = sparc
] ; then
353 bb
="$ALT_ROOT/platform/$PLATFORM/lib/fs/hsfs/bootblk"
354 dd if="$bb" of
="${archive}-new" bs
=1b oseek
=1 count
=15 \
355 conv
=notrunc conv
=sync
>> "$errlog" 2>&1
359 if [ -s "$errlog" ] ||
[ $dd_ret -ne 0 ] ; then
360 grep Error
: "$errlog" >/dev
/null
2>&1
361 if [ $?
-eq 0 ] ||
[ $dd_ret -ne 0 ] ; then
363 rm -f "${archive}-new"
369 function create_archive
375 echo "updating $archive"
377 if [ "$format" = "ufs" ]; then
378 create_ufs
"$which" "$archive" "$lofidev"
380 create_isofs
"$which" "$archive"
383 # sanity check the archive before moving it into place
385 ARCHIVE_SIZE
=`ls -l "${archive}-new" 2> /dev/null | nawk '{ print $5 }'`
386 if [ $compress = yes ] ||
[ $ISA = sparc
] ; then
388 # 'file' will report "English text" for uncompressed
389 # boot_archives. Checking for that doesn't seem stable,
390 # so we just check that the file exists.
392 ls "${archive}-new" >/dev
/null
2>&1
395 # the file type check also establishes that the
398 LC_MESSAGES
=C
file "${archive}-new" |
grep gzip > /dev
/null
401 if [ $?
= 1 ] && [ -x $GZIP_CMD ] ||
[ "$ARCHIVE_SIZE" -lt 10000 ]
404 # Two of these functions may be run in parallel. We
405 # need to allow the other to clean up, so we can't
406 # exit immediately. Instead, we set a flag.
408 echo "update of $archive failed"
411 lockfs
-f "/$ALT_ROOT" 2>/dev
/null
412 mv "${archive}-new" "$archive"
413 rm -f "$archive.hash"
414 digest
-a sha1
"$archive" > "$archive.hash"
415 lockfs
-f "/$ALT_ROOT" 2>/dev
/null
429 if [ ! -f "$ALT_ROOT/boot/solaris/filelist.ramdisk" ] &&
430 [ ! -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]
432 print
-u2 "Can't find filelist.ramdisk"
435 filelist
=$
($EXTRACT_FILELIST $EXTRACT_ARGS \
436 /boot
/solaris
/filelist.ramdisk \
437 /etc
/boot
/solaris
/filelist.ramdisk \
438 2>/dev
/null |
sort -u)
441 # We use /tmp/ for scratch space now. This may be changed later if there
442 # is insufficient space in /tmp/.
444 rddir
="/tmp/create_ramdisk.$$.tmp"
447 mkdir
"$rddir" || fatal_error
"Could not create temporary directory $rddir"
449 # Clean up upon exit.
452 list32
="$rddir/filelist.32"
453 list64
="$rddir/filelist.64"
455 touch $list32 $list64
458 # This loop creates the 32-bit and 64-bit lists of files. The 32-bit list
459 # is written to stdout, which is redirected at the end of the loop. The
460 # 64-bit list is appended with each write.
463 find $filelist -print 2>/dev
/null |
while read path
465 if [ $SPLIT = no
]; then
467 elif [ -d "$path" ]; then
468 if [ $format = ufs
]; then
469 size
=`ls -lLd "$path" | nawk '
470 {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'`
471 if [ `basename "$path"` != "amd64" ]; then
472 (( dirsize32
+= size
))
474 (( dirsize64
+= size
))
477 case `LC_MESSAGES=C /usr/bin/file -m /dev/null "$path" 2>/dev/null` in
479 print
"$path" >> "$list64"
487 print
"$path" >> "$list64"
492 if [ $format = ufs
] ; then
493 # calculate image size
496 # check to see if there is sufficient space in tmpfs
498 tmp_free
=`df -b /tmp | tail -1 | awk '{ printf ($2) }'`
499 (( tmp_free
= tmp_free
/ 3 ))
500 if [ $SPLIT = yes ]; then
501 (( tmp_free
= tmp_free
/ 2 ))
504 if [ $total_size -gt $tmp_free ] ; then
505 # assumes we have enough scratch space on $ALT_ROOT
506 new_rddir
="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp"
508 mkdir
"$new_rddir" || fatal_error \
509 "Could not create temporary directory $new_rddir"
511 # Save the file lists
512 mv "$list32" "$new_rddir"/
513 mv "$list64" "$new_rddir"/
514 list32
="/$new_rddir/filelist.32"
515 list64
="/$new_rddir/filelist.64"
517 # Remove the old $rddir and set the new value of rddir
524 rdfile32
="$rddir/rd.file.32"
525 rdfile64
="$rddir/rd.file.64"
526 rdmnt32
="$rddir/rd.mount.32"
527 rdmnt64
="$rddir/rd.mount.64"
528 errlog32
="$rddir/rd.errlog.32"
529 errlog64
="$rddir/rd.errlog.64"
533 if [ $SPLIT = yes ]; then
535 # We can't run lofiadm commands in parallel, so we have to do
538 if [ "$format" = "ufs" ]; then
539 mkfile
${size32}k
"$rdfile32"
540 lofidev32
=`lofiadm -a "$rdfile32"`
541 mkfile
${size64}k
"$rdfile64"
542 lofidev64
=`lofiadm -a "$rdfile64"`
544 create_archive
"32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 &
545 create_archive
"64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64
547 if [ "$format" = "ufs" ]; then
548 lofiadm
-d "$rdfile32"
549 lofiadm
-d "$rdfile64"
552 if [ "$format" = "ufs" ]; then
553 mkfile
${total_size}k
"$rdfile32"
554 lofidev32
=`lofiadm -a "$rdfile32"`
556 create_archive
"both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32
557 [ "$format" = "ufs" ] && lofiadm
-d "$rdfile32"
559 if [ $ERROR = 1 ]; then
565 # For the diskless case, hardlink archive to /boot to make it
566 # visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>.
567 # NOTE: this script must work on both client and server.
569 grep "[ ]/[ ]*nfs[ ]" "$ALT_ROOT/etc/vfstab" > /dev
/null
571 rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive"
572 ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive"
573 if [ $SPLIT = yes ]; then
574 ln "$ALT_ROOT/$BOOT_ARCHIVE_64" \
575 "$ALT_ROOT/boot/amd64/boot_archive"
578 [ -n "$rddir" ] && rm -rf "$rddir"