# # 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 #!/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