#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
# Hammerhead: amd64-only, dispatch to Makefile.i386 (which includes Makefile.com)
all: TARGET= all
install: TARGET= install
clean: TARGET= clean
clobber: TARGET= clobber
check: TARGET= check
.KEEP_STATE:
all install clean clobber check:
$(MAKE) -f Makefile.i386 $(TARGET)
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
.SUFFIXES: .ksh
MANIFEST= boot-archive-update.xml
SVCMETHOD= boot-archive-update
sparc_BOOTPROG=
i386_BOOTPROG= \
create_diskmap
COMMON_BOOTPROG= \
create_ramdisk \
extract_boot_filelist
BOOTPROG= $(COMMON_BOOTPROG) $($(MACH)_BOOTPROG)
METHODPROG= boot-archive-update
PROG= root_archive
include ../Makefile.com
ROOTMANIFESTDIR= $(ROOTSVCSYSTEM)
$(ROOTMANIFEST) : FILEMODE= 444
ROOTBOOTSOLARISUSRSBINLINKS= $(PROG:%=$(ROOTBOOTSOLARISBIN)/%)
.KEEP_STATE:
all: $(BOOTPROG) $(METHODPROG) $(PROG)
check: $(CHKMANIFEST)
clean:
$(RM) $(BOOTPROG) $(METHODPROG) $(PROG)
lint _msg:
$(ROOTBOOTSOLARISUSRSBINLINKS):
$(RM) $@; $(SYMLINK) ../../../usr/sbin/$(@F) $@
# Default rule for building ksh scripts.
.ksh:
$(RM) $@
$(CAT) $< > $@
$(CHMOD) +x $@
include ../Makefile.targ
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
include Makefile.com
.KEEP_STATE:
install: all \
$(ROOTBOOTSOLARISBINPROG) \
$(ROOTMANIFEST) \
$(ROOTSVCMETHOD) \
$(ROOTUSRSBINPROG) .WAIT \
$(ROOTBOOTSOLARISUSRSBINLINKS)
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
include Makefile.com
.KEEP_STATE:
install: all \
$(ROOTBOOTSOLARISBINPROG) \
$(ROOTMANIFEST) \
$(ROOTSVCMETHOD) \
$(ROOTUSRSBINPROG)
# .WAIT \
# $(ROOTBOOTSOLARISUSRSBINLINKS)
#!/sbin/sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
# Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
# Copyright 2021 Oxide Computer Company
#
. /lib/svc/share/smf_include.sh
. /lib/svc/share/fs_include.sh
UPDATEFILE=/etc/svc/volatile/boot_archive_safefile_update
if smf_is_nonglobalzone || smf_root_is_ramdisk; then
#
# Boot archives only exist in the global zone of persistent root
# systems, but this is either a non-global zone or a system booted from
# a ramdisk image.
#
exit $SMF_EXIT_OK
fi
if [ `uname -p` = "amd64" ] || [ `uname -p` = "i386" ]; then
# on x86 get rid of transient reboot entry in the GRUB menu
if [ -f /stubboot/boot/grub/menu.lst ]; then
/sbin/bootadm -m update_temp -R /stubboot
else
/sbin/bootadm -m update_temp
fi
# Remove old platform-based archives if present.
for old_plat in /platform/i86pc /platform/amd64; do
[ -f $old_plat/boot_archive ] && rm -f $old_plat/boot_archive
[ -f $old_plat/boot_archive.hash ] && rm -f $old_plat/boot_archive.hash
[ -d $old_plat/archive_cache ] && rm -rf $old_plat/archive_cache
[ -f $old_plat/amd64/boot_archive ] && rm -f $old_plat/amd64/boot_archive
[ -f $old_plat/amd64/boot_archive.hash ] && rm -f $old_plat/amd64/boot_archive.hash
[ -d $old_plat/amd64/archive_cache ] && rm -rf $old_plat/amd64/archive_cache
done
fi
if [ -f $UPDATEFILE ] || [ -f /reconfigure ]; then
/usr/sbin/rtc -c > /dev/null 2>&1
/sbin/bootadm update-archive
rm -f $UPDATEFILE
fi
exit $SMF_EXIT_OK
update boot archive if necessary
This service updates the boot archive if
a non fatal file was out of sync or if this
is a reconfiguration boot.
#!/sbin/sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License"). You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# basic setup
#
GRUBDISKMAP=/var/run/solaris_grubdisk.map
/bin/rm -f "$GRUBDISKMAP"
/bin/touch "$GRUBDISKMAP"
/sbin/biosdev 2> /dev/null | while read diskno diskpath
do
devname=`/bin/ls -l /dev/rdsk/*p0 | /bin/grep $diskpath | /bin/nawk '{ print $9 }'`
ctdname=`echo $devname | /bin/sed "s#/dev/rdsk/##" | /bin/sed "s#p0##"`
grubdisk=`echo $diskno | /bin/sed "s/0x8//"`
echo "$grubdisk $ctdname $diskpath" >> "$GRUBDISKMAP"
done
# cleanup
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2016 Toomas Soome
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
# Copyright (c) 2014 by Delphix. All rights reserved.
# Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
#
ALT_ROOT=
EXTRACT_ARGS=
FORMAT=
format_set=0
compress=yes
dirsize=0
usage() {
cat <<- EOM
This utility is a component of the bootadm(8) implementation and it is not
recommended for stand-alone use. Please use bootadm(8) instead.
Usage: ${0##*/}: [-R ] [-p ] [ -f ] [--nocompress]
where is amd64
and is one of ufs, ufs-nocompress or cpio
EOM
exit
}
# default platform is what we're running on
PLATFORM=`uname -m`
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
export GZIP_CMD=/usr/bin/gzip
export CPIO_CMD=/usr/bin/cpio
EXTRACT_FILELIST="/boot/solaris/bin/extract_boot_filelist"
#
# Parse options
#
while [ -n "$1" ]; do
case $1 in
-f) shift
FORMAT="$1"
format_set=1
;;
-n|--nocompress) compress=no
;;
-p) shift
PLATFORM="$1"
EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}"
;;
-R) shift
ALT_ROOT="$1"
if [ "$ALT_ROOT" != "/" ]; then
echo "Creating boot_archive for $ALT_ROOT"
EXTRACT_ARGS="${EXTRACT_ARGS} -R ${ALT_ROOT}"
EXTRACT_FILELIST="${ALT_ROOT}${EXTRACT_FILELIST}"
fi
;;
*) usage
;;
esac
shift
done
shift `expr $OPTIND - 1`
if [ $# -eq 1 ]; then
ALT_ROOT="$1"
echo "Creating boot_archive for $ALT_ROOT"
fi
if [ -z "$FORMAT" ]; then
if [ -n "$ALT_ROOT" ]; then
SVCCFG_DTD=/$ALT_ROOT/usr/share/lib/xml/dtd/service_bundle.dtd.1
SVCCFG_REPOSITORY=/$ALT_ROOT/etc/svc/repository.db
export SVCCFG_DTD SVCCFG_REPOSITORY
fi
FORMAT=`svccfg -s system/boot-archive listprop config/format \
| awk '{print $3}'`
fi
if [ $format_set -eq 0 -a "$FORMAT" = hsfs ]; then
if /sbin/bootadm update-archive -R ${ALT_ROOT:-/} -f -L -F hsfs; then
exit 0
else
echo "Failed to create HSFS archive, falling back."
fi
fi
[[ "$FORMAT" =~ ^(cpio|ufs|ufs-nocompress)$ ]] || FORMAT=ufs
case $PLATFORM in
amd64)
PLATFORM=amd64
ISA=i386
ARCH64=amd64
;;
*) usage
;;
esac
BOOT_ARCHIVE_SUFFIX=boot_archive
BOOT_ARCHIVE=boot/$BOOT_ARCHIVE_SUFFIX
function fatal_error
{
print -u2 $*
exit 1
}
[ -x $GZIP_CMD ] || compress=no
case $FORMAT in
cpio) [ -x $CPIO_CMD ] || FORMAT=ufs ;;
ufs-nocompress) FORMAT=ufs; compress=no ;;
ufs) ;;
esac
#
# Copies all desired files to a target directory. One argument should be
# passed: the file containing the list of files to copy. This function also
# depends on several variables that must be set before calling:
#
# $ALT_ROOT - the target directory
# $compress - whether or not the files in the archives should be compressed
# $rdmnt - the target directory
#
function copy_files
{
typeset listfile="$1"
#
# If compress is set, the files are gzip'd and put in the correct
# location in the loop. Nothing is printed, so the pipe and cpio
# at the end is a nop.
#
# If compress is not set, the file names are printed, which causes
# the cpio at the end to do the copy.
#
while read path; do
if [ $compress = yes ]; then
dir="${path%/*}"
[ -d "$rdmnt/$dir" ] || mkdir -p "$rdmnt/$dir"
$GZIP_CMD -c "$path" > "$rdmnt/$path"
else
print "$path"
fi
done <"$listfile" | cpio -pdum "$rdmnt" 2>/dev/null
if [ $ISA = sparc ] ; then
# copy links
find $filelist -type l -print 2>/dev/null |\
cpio -pdum "$rdmnt" 2>/dev/null
if [ $compress = yes ] ; then
# always copy unix uncompressed
find $filelist -name unix -type f -print 2>/dev/null |\
cpio -pdum "$rdmnt" 2>/dev/null
fi
fi
}
function ufs_cleanup
{
umount -f "$rdmnt" 2>/dev/null
lofiadm -d "$rdfile" 2>/dev/null
[ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null
[ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null
}
function ufs_getsize
{
# Estimate image size and add 10% overhead for ufs stuff.
# Note, we can't use du here in case we're on a filesystem, e.g. zfs,
# in which the disk usage is less than the sum of the file sizes.
# The nawk code
#
# {t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
#
# below rounds up the size of a file/directory, in bytes, to the
# next multiple of 1024. This mimics the behavior of ufs especially
# with directories. This results in a total size that's slightly
# bigger than if du was called on a ufs directory.
size=$(cat "$list" | xargs -I {} ls -lLd "{}" 2> /dev/null |
nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
END {print int(t * 1.10 / 1024)}')
(( size += dirsize ))
(( total_size = size ))
# If compression is enabled, then each file within the archive will
# be individually compressed. The compression ratio is around 60%
# across the archive so make the image smaller.
[ $compress = yes ] && (( total_size = total_size / 2 ))
}
function calculate_sizes_and_locations
{
find $filelist -print 2>/dev/null | while read path; do
if [ -d "$path" ]; then
size=`ls -lLd "$path" | nawk '
{print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'`
(( dirsize += size / 1024 ))
else
print "$path"
fi
done >"$list"
# calculate image size
ufs_getsize
# check to see if there is sufficient space in tmpfs
#
tmp_free=`df -b /tmp | tail -1 | awk '{ print $2 }'`
(( tmp_free = tmp_free / 3 ))
if [ $total_size -gt $tmp_free ] ; then
echo "Insufficient space in /tmp, using $ALT_ROOT/var/tmp"
# assumes we have enough scratch space on $ALT_ROOT
new_rddir="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp"
rm -rf "$new_rddir"
mkdir "$new_rddir" || fatal_error \
"Could not create temporary directory $new_rddir"
# Save the file lists
mv "$list" "$new_rddir"/
list="/$new_rddir/filelist"
# Remove the old $rddir and set the new value of rddir
rm -rf "$rddir"
rddir="$new_rddir"
new_rddir=
fi
}
function create_ufs_archive
{
typeset archive="$ALT_ROOT/$BOOT_ARCHIVE"
[ "$compress" = yes ] && \
echo "updating $archive (UFS)" || \
echo "updating $archive (UFS-nocompress)"
#
# We use /tmp/ for scratch space now. This will be changed later to
# $ALT_ROOT/var/tmp if there is insufficient space in /tmp/.
#
rddir="/tmp/create_ramdisk.$$.tmp"
new_rddir=
rm -rf "$rddir"
mkdir "$rddir" || fatal_error "Could not create directory $rddir"
# Clean up upon exit.
trap 'ufs_cleanup' EXIT
list="$rddir/filelist"
cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT"
calculate_sizes_and_locations
rdfile="$rddir/rd.file"
rdmnt="$rddir/rd.mount"
errlog="$rddir/rd.errlog"
lofidev=""
mkfile ${total_size}k "$rdfile" || \
fatal_error "Could not create backing file"
lofidev=`lofiadm -a "$rdfile"` || \
fatal_error "Could not create lofi device"
NOINUSE_CHECK=1 newfs -m 0 $lofidev < /dev/null 2> /dev/null
mkdir "$rdmnt"
mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1
mount -F ufs -o nologging $lofidev "$rdmnt"
rm -rf "$rdmnt/lost+found"
# do the actual copy
copy_files "$list"
umount -f "$rdmnt"
rmdir "$rdmnt"
if [ $ISA = sparc ] ; then
rlofidev="${lofidev/lofi/rlofi}"
bb="/$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk"
# installboot is not available on all platforms
dd if=$bb of=$rlofidev bs=1b oseek=1 count=15 conv=sync 2>&1
fi
lofiadm -d "$rdfile"
#
# Check if gzip exists in /usr/bin, so we only try to run gzip
# on systems that have gzip. Then run gzip out of the patch to
# pick it up from bfubin or something like that if needed.
#
# If compress is set, the individual files in the archive are
# compressed, and the final compression will accomplish very
# little. To save time, we skip the gzip in this case.
#
if [ $ISA = i386 ] && [ $compress = no ] && [ -x $GZIP_CMD ] ; then
$GZIP_CMD -c "$rdfile" > "${archive}-new"
else
cat "$rdfile" > "${archive}-new"
fi
if [ $? -ne 0 ] ; then
rm -f "${archive}-new"
fi
# sanity check the archive before moving it into place
#
ARCHIVE_SIZE=`ls -l "${archive}-new" 2> /dev/null | nawk '{ print $5 }'`
if [ $compress = yes ] || [ $ISA = sparc ] ; then
#
# 'file' will report "English text" for uncompressed
# boot_archives. Checking for that doesn't seem stable,
# so we just check that the file exists.
#
ls "${archive}-new" >/dev/null 2>&1
else
#
# the file type check also establishes that the
# file exists at all
#
LC_MESSAGES=C file "${archive}-new" | grep gzip > /dev/null
fi
if [ $? = 1 ] && [ -x $GZIP_CMD ] || [ "$ARCHIVE_SIZE" -lt 10000 ]
then
fatal_error "update of $archive failed"
else
lockfs -f "/$ALT_ROOT" 2>/dev/null
rm -f "$archive.hash"
mv "${archive}-new" "$archive"
digest -a sha1 "$rdfile" > "$archive.hash"
lockfs -f "/$ALT_ROOT" 2>/dev/null
fi
[ -n "$rddir" ] && rm -rf "$rddir"
}
function cpio_cleanup
{
rm -f "$tarchive" "$tarchive.cpio" "$tarchive.hash" "$tarchive.head"
[ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null
}
function create_hash
{
[ -x /usr/bin/digest ] \
&& /usr/bin/digest -a sha1 "$tarchive.cpio" > "$tarchive.hash" \
|| print -u2 "Failed to create sha1 hash of $tarchive"
}
function create_cpio_archive
{
typeset archive="$ALT_ROOT/$BOOT_ARCHIVE"
echo "updating $archive (CPIO)"
rddir="/tmp/create_ramdisk.$$.tmp"
tarchive="$archive.$$.new"
rm -rf "$rddir"
mkdir "$rddir" || fatal_error "Could not create directory $rddir"
# Clean up upon exit.
trap 'cpio_cleanup' EXIT
cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT"
touch "$tarchive" \
|| fatal_error "Cannot create temporary archive $tarchive"
if [ $ISA = sparc ] ; then
# compression does not work (yet?).
# The krtld does not support gzip but fiocompress
# does not seem to work either.
compress="no"
list="$rddir/filelist"
calculate_sizes_and_locations
rdmnt="$rddir/rd.mount"
mkdir "$rdmnt"
copy_files "$list"
cd "$rdmnt"
find . 2>/dev/null | \
cpio -qo -H odc > "$tarchive.cpio" \
|| fatal_error "Problem creating archive"
cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT"
bb="/$ALT_ROOT/platform/$PLATFORM/lib/fs/cpio/bootblk"
# The SPARC boot code is assuming 8KB of boot data.
# This is originating from disk layout and UFS limits.
# Therefore we have 512B reserved space for disk label,
# and 7.5KB for boot program. With 512B blocks, this is
# 1 + 15 blocks.
dd if=/dev/zero of="$tarchive.head" bs=512 count=16 2>&1 \
|| fatal_error "Cannot create header"
dd if=$bb of="$tarchive.head" bs=512 oseek=1 count=15 \
conv=sync 2>&1 \
|| fatal_error "Cannot install boot block"
cat "$tarchive.head" "$tarchive.cpio" > "$tarchive" \
|| fatal_error "Cannot update boot archive"
rm -f "$tarchive.head" "$tarchive.cpio"
else
find $filelist 2>/dev/null | \
cpio -qo -H odc > "$tarchive.cpio" \
|| fatal_error "Problem creating archive"
# If hash is supported, it must be created before gzipping the archive.
# The boot loader will uncompress the archive, and the hash
# will be verified against the uncompressed data.
create_hash
if [ -x "$GZIP_CMD" ]; then
$GZIP_CMD -c "$tarchive.cpio" > "$tarchive"
rm -f "$tarchive.cpio"
else
mv "$tarchive.cpio" "$tarchive"
fi
fi
# Move new archive into place
[ -f "$archive.hash" ] && rm -f "$archive.hash"
mv "$tarchive" "$archive"
[ $? -eq 0 -a -f "$tarchive.hash" ] \
&& mv "$tarchive.hash" "$archive.hash"
}
#
# get filelist
#
if [ ! -f "$ALT_ROOT/boot/solaris/filelist.ramdisk" ] &&
[ ! -f "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" ]
then
print -u2 "Can't find filelist.ramdisk"
exit 1
fi
filelist=$($EXTRACT_FILELIST $EXTRACT_ARGS \
/boot/solaris/filelist.ramdisk \
/etc/boot/solaris/filelist.ramdisk \
2>/dev/null | sort -u)
# Now that we have the list of files, we can create the archive.
case "$FORMAT" in
cpio) create_cpio_archive ;;
ufs) create_ufs_archive ;;
*) print -u2 "Unknown boot archive format, $FORMAT"
exit 1
;;
esac
#
# For the diskless case, hardlink archive to /boot to make it
# visible via tftp. /boot is lofs mounted under /tftpboot/.
# NOTE: this script must work on both client and server.
#
grep "[ ]/[ ]*nfs[ ]" "$ALT_ROOT/etc/vfstab" > /dev/null
if [ $? = 0 ]; then
rm -f "$ALT_ROOT/boot/$BOOT_ARCHIVE_SUFFIX"
mkdir -p "$ALT_ROOT/boot/`dirname $BOOT_ARCHIVE_SUFFIX`"
ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/$BOOT_ARCHIVE_SUFFIX"
fi
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
# set path, but inherit /tmp/bfubin if it is sane
#
if [ "`echo $PATH | cut -f 1 -d :`" = /tmp/bfubin ] && \
[ -O /tmp/bfubin ] ; then
export PATH=/tmp/bfubin:/usr/sbin:/usr/bin:/sbin:/bin
else
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
fi
usage() {
echo "This utility is a component of the bootadm(8) implementation"
echo "and it is not recommended for stand-alone use."
echo "Please use bootadm(8) instead."
echo ""
echo "Usage: ${0##*/}: [-R ] [-p ] ..."
echo "where is amd64"
exit 2
}
build_platform() {
altroot=$1
(
cd $altroot/
if [ -z "$STRIP" ] ; then
ls -d platform/*/kernel
else
ls -d platform/*/kernel | grep -v $STRIP
fi
)
}
# default platform is what we're running on
PLATFORM=`uname -m`
altroot=""
filelists=
platform_provided=no
OPTIND=1
while getopts R:p: FLAG
do
case $FLAG in
R) if [ "$OPTARG" != "/" ]; then
altroot="$OPTARG"
fi
;;
p) platform_provided=yes
PLATFORM="$OPTARG"
;;
*) usage
;;
esac
done
shift `expr $OPTIND - 1`
if [ $# -eq 0 ]; then
usage
fi
filelists=$*
#
# If the target platform is provided, as is the case for diskless,
# or we're building an archive for this machine, we can build
# a smaller archive by not including unnecessary components.
#
filtering=no
if [ "$altroot" == "" ] || [ $platform_provided = yes ]; then
case $PLATFORM in
amd64)
STRIP=
;;
*)
STRIP=
;;
esac
fi
for list in $filelists
do
if [ -f $altroot/$list ]; then
grep ^platform$ $altroot/$list > /dev/null
if [ $? = 0 ] ; then
build_platform $altroot
if [ -z "$STRIP" ] ; then
cat $altroot/$list | grep -v ^platform$
else
cat $altroot/$list | grep -v ^platform$ | \
grep -v $STRIP
fi
else
if [ -z "$STRIP" ] ; then
cat $altroot/$list
else
cat $altroot/$list | grep -v $STRIP
fi
fi
fi
done
exit 0
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
# utility to pack and unpack a boot/root archive
# both ufs and hsfs (iso9660) format archives are unpacked
# only ufs archives are generated
#
# usage: pack
# unpack
#
# Where is the directory to unpack to and will be cleaned out
# if it exists.
#
usage()
{
printf "usage: root_archive pack \n"
printf " root_archive unpack \n"
exit 1
}
cleanup()
{
if [ -d $MNT ] ; then
umount $MNT 2> /dev/null
rmdir $MNT
fi
lofiadm -d "$TMR" 2>/dev/null
if [ "$REALTHING" != true ] ; then
rm -f "$TMR"
fi
rm -f "$TMR.gz"
rm -f /tmp/flist$$
}
do_unpack()
{
(
cd $MNT
find . -print | cpio -pdum "$UNPACKED_ROOT" 2> /dev/null
)
# increase the chances the unmount will succeed
umount -f $MNT
}
unpack()
{
MR=$1
if [ ! -f "$MR" ] ; then
printf "$MR: not found\n"
usage
fi
if [ `uname -i` = amd64 ] || [ `uname -p` = amd64 ] ; then
gzcat "$MR" > $TMR
else
REALTHING=true ; export REALTHING
TMR="$MR"
fi
LOFIDEV=`/usr/sbin/lofiadm -a $TMR`
if [ $? != 0 ] ; then
echo lofi plumb failed
exit 2
fi
mkdir -p $MNT
FSTYP=`fstyp $LOFIDEV`
if [ "$FSTYP" = ufs ] ; then
/sbin/mount -o ro,nologging $LOFIDEV $MNT
do_unpack
elif [ "$FSTYP" = hsfs ] ; then
/sbin/mount -F hsfs -o ro $LOFIDEV $MNT
do_unpack
else
printf "invalid root archive\n"
fi
rmdir $MNT
lofiadm -d $TMR ; LOFIDEV=
if [ "$REALTHING" != true ] ; then
rm $TMR
fi
}
compress()
{
SRC=$1
DST=$2
(
cd $SRC
filelist=`find .`
for file in $filelist ; do
file=`echo $file | sed s#^./##`
# copy all files over to preserve hard links
#
echo $file | cpio -pdum $DST 2> /dev/null
if [ -f $file ] && [ -s $file ] && [ ! -h $file ] ; then
fiocompress -mc $file $DST/$file &
fi
done
wait `pgrep fiocompress`
# now re-copy a couple of uncompressed files
if [ -d "$SRC/kernel" ] ; then
find `cat boot/solaris/filelist.ramdisk` -type file \
-print 2> /dev/null > /tmp/flist$$
find usr/kernel -type file -print 2> /dev/null \
>> /tmp/flist$$
# some of the files are replaced with links into
# tmp/root on the miniroot, so find the backing files
# from there as well and add them to the list ti
# be copied uncompressed
(
cd $SRC/tmp/root
find `cat ../../boot/solaris/filelist.ramdisk` \
-type file -print 2> /dev/null | \
sed 's#^#tmp/root/#' >> /tmp/flist$$
)
flist=`cat /tmp/flist$$`
(
cd $DST
rm -f $flist
)
for file in $flist ; do
echo $file | cpio -pdum $DST 2> /dev/null
done
else
find kernel platform -name unix | \
cpio -pdum $DST 2> /dev/null
find kernel platform -name genunix | cpio -pdum $DST \
2> /dev/null
find kernel platform -name platmod | cpio -pdum $DST \
2> /dev/null
find `find kernel platform -name cpu` | \
cpio -pdum $DST 2> /dev/null
find `find kernel platform -name kmdb\*` | \
cpio -pdum $DST 2> /dev/null
find kernel/misc/sparcv9/ctf kernel/fs/sparcv9/dcfs \
etc/system etc/name_to_major etc/path_to_inst \
etc/name_to_sysnum etc/driver_aliases \
etc/driver_classes etc/minor_perm | \
cpio -pdum $DST 2> /dev/null
fi
)
}
root_is_ramdisk()
{
grep -v "set root_is_ramdisk=" "$UNPACKED_ROOT"/etc/system | \
grep -v "set ramdisk_size=" > /tmp/system.$$
cat /tmp/system.$$ > "$UNPACKED_ROOT"/etc/system
rm /tmp/system.$$
echo set root_is_ramdisk=1 >> "$UNPACKED_ROOT"/etc/system
echo set ramdisk_size=$1 >> "$UNPACKED_ROOT"/etc/system
}
pack()
{
MR="$1"
[ -d "$UNPACKED_ROOT" ] || usage
# always compress if fiocompress exists
#
if [ -x /sbin/fiocompress ] ; then
COMPRESS=true
fi
# Estimate image size and add %10 overhead for ufs stuff.
# Note, we can't use du here in case $UNPACKED_ROOT is on a filesystem,
# e.g. zfs, in which the disk usage is less than the sum of the file
# sizes. The nawk code
#
# {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
#
# below rounds up the size of a file/directory, in bytes, to the
# next multiple of 1024. This mimics the behavior of ufs especially
# with directories. This results in a total size that's slightly
# bigger than if du was called on a ufs directory.
#
# if the operation in turn is compressing the files the amount
# of typical shrinkage is used to come up with a useful archive
# size
size=$(find "$UNPACKED_ROOT" -ls | nawk '
{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
END {print int(t * 1.10 / 1024)}')
if [ "$COMPRESS" = true ] ; then
size=`echo $size | nawk '{s = $1} END {print int(s * 0.6)}'`
fi
/usr/sbin/mkfile ${size}k "$TMR"
LOFIDEV=`/usr/sbin/lofiadm -a "$TMR"`
if [ $? != 0 ] ; then
echo lofi plumb failed
exit 2
fi
RLOFIDEV=`echo $LOFIDEV | sed s/lofi/rlofi/`
newfs $RLOFIDEV < /dev/null 2> /dev/null
mkdir -p $MNT
mount -o nologging $LOFIDEV $MNT
rmdir $MNT/lost+found
if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
root_is_ramdisk $size
fi
(
cd "$UNPACKED_ROOT"
if [ "$COMPRESS" = true ] ; then
compress . $MNT
else
find . -print | cpio -pdum $MNT 2> /dev/null
fi
)
lockfs -f $MNT
umount $MNT
rmdir $MNT
if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
"$UNPACKED_ROOT/usr/sbin/installboot" \
"$UNPACKED_ROOT/platform/sun4u/lib/fs/ufs/bootblk" \
$RLOFIDEV
fi
lofiadm -d $LOFIDEV
LOFIDEV=
rm -f "$TMR.gz"
if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
mv "$TMR" "$MR"
else
gzip -f "$TMR"
mv "$TMR.gz" "$MR"
fi
chmod a+r "$MR"
}
strip_amd64()
{
find "$UNPACKED_ROOT" -name amd64 -type directory | xargs rm -rf
}
# main
#
EXTRA_SPACE=0
STRIP_AMD64=
COMPRESS=
PATH=/bin:/sbin:/usr/bin:/usr/sbin ; export PATH
while getopts s:6c opt ; do
case $opt in
s) EXTRA_SPACE="$OPTARG"
;;
6) STRIP_AMD64=false
;;
c) COMPRESS=true
;;
*) usage
;;
esac
done
shift `expr $OPTIND - 1`
[ $# == 3 ] || usage
UNPACKED_ROOT="$3"
BASE="`pwd`"
MNT=/tmp/mnt$$
TMR=/tmp/mr$$
LOFIDEV=
MR="$2"
# sanity check
[ "$UNPACKED_ROOT" != "/" ] || usage
if [ "`dirname $MR`" = . ] ; then
MR="$BASE/$MR"
fi
if [ "`dirname $UNPACKED_ROOT`" = . ] ; then
UNPACKED_ROOT="$BASE/$UNPACKED_ROOT"
fi
trap cleanup EXIT
# always unpack into a fresh root
case $1 in
unpack)
rm -rf "$UNPACKED_ROOT"
mkdir -p "$UNPACKED_ROOT"
;;
esac
[ -d "$UNPACKED_ROOT" ] || usage
case $1 in
pack) pack "$MR"
;;
unpack) unpack "$MR"
;;
*) usage
;;
esac