1e482cb0aSjongkis#!/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 6781dc622Ssetje# Common Development and Distribution License (the "License"). 7781dc622Ssetje# 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 23d07682faSAbhinandan Ekande# Copyright 2010 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate# Use is subject to license terms. 257c478bd9Sstevel@tonic-gate# 26*a0eaab1eSAlexander Eremin# Copyright 2012 Nexenta Systems, Inc. All rights reserved. 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate# utility to pack and unpack a boot/root archive 297c478bd9Sstevel@tonic-gate# both ufs and hsfs (iso9660) format archives are unpacked 307c478bd9Sstevel@tonic-gate# only ufs archives are generated 317c478bd9Sstevel@tonic-gate# 327c478bd9Sstevel@tonic-gate# usage: pack <archive> <root> 337c478bd9Sstevel@tonic-gate# unpack <archive> <root> 347c478bd9Sstevel@tonic-gate# 357c478bd9Sstevel@tonic-gate# Where <root> is the directory to unpack to and will be cleaned out 367c478bd9Sstevel@tonic-gate# if it exists. 377c478bd9Sstevel@tonic-gate# 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gateusage() 407c478bd9Sstevel@tonic-gate{ 417c478bd9Sstevel@tonic-gate printf "usage: root_archive pack <archive> <root>\n" 427c478bd9Sstevel@tonic-gate printf " root_archive unpack <archive> <root>\n" 43f0778428SJerry Gilliam exit 1 447c478bd9Sstevel@tonic-gate} 457c478bd9Sstevel@tonic-gate 4658091fd8Ssetjecleanup() 4758091fd8Ssetje{ 4858091fd8Ssetje if [ -d $MNT ] ; then 4958091fd8Ssetje umount $MNT 2> /dev/null 5058091fd8Ssetje rmdir $MNT 5158091fd8Ssetje fi 5258091fd8Ssetje 53e482cb0aSjongkis lofiadm -d "$TMR" 2>/dev/null 54986fd29aSsetje if [ "$REALTHING" != true ] ; then 55986fd29aSsetje rm -f "$TMR" 56986fd29aSsetje fi 57986fd29aSsetje rm -f "$TMR.gz" 58342440ecSPrasad Singamsetty rm -f /tmp/flist$$ 5958091fd8Ssetje} 6058091fd8Ssetje 617c478bd9Sstevel@tonic-gatedo_unpack() 627c478bd9Sstevel@tonic-gate{ 63e482cb0aSjongkis ( 647c478bd9Sstevel@tonic-gate cd $MNT 65781dc622Ssetje find . -print | cpio -pdum "$UNPACKED_ROOT" 2> /dev/null 66e482cb0aSjongkis ) 67f0778428SJerry Gilliam # increase the chances the unmount will succeed 68f0778428SJerry Gilliam umount -f $MNT 697c478bd9Sstevel@tonic-gate} 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gateunpack() 727c478bd9Sstevel@tonic-gate{ 73f0778428SJerry Gilliam MR=$1 74781dc622Ssetje if [ ! -f "$MR" ] ; then 75f0778428SJerry Gilliam printf "$MR: not found\n" 767c478bd9Sstevel@tonic-gate usage 777c478bd9Sstevel@tonic-gate fi 787c478bd9Sstevel@tonic-gate 79342440ecSPrasad Singamsetty if [ `uname -i` = i86pc ] ; then 80781dc622Ssetje gzcat "$MR" > $TMR 81986fd29aSsetje else 82986fd29aSsetje REALTHING=true ; export REALTHING 83986fd29aSsetje TMR="$MR" 84986fd29aSsetje fi 857c478bd9Sstevel@tonic-gate 8658091fd8Ssetje LOFIDEV=`/usr/sbin/lofiadm -a $TMR` 877c478bd9Sstevel@tonic-gate if [ $? != 0 ] ; then 887c478bd9Sstevel@tonic-gate echo lofi plumb failed 897c478bd9Sstevel@tonic-gate exit 2 907c478bd9Sstevel@tonic-gate fi 917c478bd9Sstevel@tonic-gate 92781dc622Ssetje mkdir -p $MNT 937c478bd9Sstevel@tonic-gate 9458091fd8Ssetje FSTYP=`fstyp $LOFIDEV` 957c478bd9Sstevel@tonic-gate 96781dc622Ssetje if [ "$FSTYP" = ufs ] ; then 9758091fd8Ssetje /usr/sbin/mount -o ro,nologging $LOFIDEV $MNT 987c478bd9Sstevel@tonic-gate do_unpack 99781dc622Ssetje elif [ "$FSTYP" = hsfs ] ; then 10058091fd8Ssetje /usr/sbin/mount -F hsfs -o ro $LOFIDEV $MNT 1017c478bd9Sstevel@tonic-gate do_unpack 1027c478bd9Sstevel@tonic-gate else 1037c478bd9Sstevel@tonic-gate printf "invalid root archive\n" 1047c478bd9Sstevel@tonic-gate fi 1057c478bd9Sstevel@tonic-gate 106986fd29aSsetje 1077c478bd9Sstevel@tonic-gate rmdir $MNT 108e482cb0aSjongkis lofiadm -d $TMR ; LOFIDEV= 109986fd29aSsetje if [ "$REALTHING" != true ] ; then 1107c478bd9Sstevel@tonic-gate rm $TMR 111986fd29aSsetje fi 112986fd29aSsetje} 113986fd29aSsetje 114986fd29aSsetjecompress() 115986fd29aSsetje{ 116986fd29aSsetje SRC=$1 117986fd29aSsetje DST=$2 118986fd29aSsetje 119986fd29aSsetje ( 120986fd29aSsetje cd $SRC 121986fd29aSsetje filelist=`find .` 122986fd29aSsetje 123986fd29aSsetje for file in $filelist ; do 124986fd29aSsetje 125986fd29aSsetje file=`echo $file | sed s#^./##` 126986fd29aSsetje 127986fd29aSsetje # copy all files over to preserve hard links 128986fd29aSsetje # 129986fd29aSsetje echo $file | cpio -pdum $DST 2> /dev/null 130986fd29aSsetje 131986fd29aSsetje if [ -f $file ] && [ -s $file ] && [ ! -h $file ] ; then 132986fd29aSsetje fiocompress -mc $file $DST/$file & 133986fd29aSsetje fi 134986fd29aSsetje 135986fd29aSsetje done 136986fd29aSsetje 137342440ecSPrasad Singamsetty wait `pgrep fiocompress` 138986fd29aSsetje 139342440ecSPrasad Singamsetty # now re-copy a couple of uncompressed files 140342440ecSPrasad Singamsetty 141342440ecSPrasad Singamsetty if [ -d "$SRC/platform/i86pc" ] ; then 142342440ecSPrasad Singamsetty find `cat boot/solaris/filelist.ramdisk` -type file \ 143342440ecSPrasad Singamsetty -print 2> /dev/null > /tmp/flist$$ 144342440ecSPrasad Singamsetty find usr/kernel -type file -print 2> /dev/null \ 145342440ecSPrasad Singamsetty >> /tmp/flist$$ 146342440ecSPrasad Singamsetty # some of the files are replaced with links into 147342440ecSPrasad Singamsetty # tmp/root on the miniroot, so find the backing files 148342440ecSPrasad Singamsetty # from there as well and add them to the list ti 149342440ecSPrasad Singamsetty # be copied uncompressed 150342440ecSPrasad Singamsetty ( 151342440ecSPrasad Singamsetty cd $SRC/tmp/root 152342440ecSPrasad Singamsetty find `cat ../../boot/solaris/filelist.ramdisk` \ 153342440ecSPrasad Singamsetty -type file -print 2> /dev/null | \ 154342440ecSPrasad Singamsetty sed 's#^#tmp/root/#' >> /tmp/flist$$ 155342440ecSPrasad Singamsetty ) 156342440ecSPrasad Singamsetty flist=`cat /tmp/flist$$` 157342440ecSPrasad Singamsetty ( 158342440ecSPrasad Singamsetty cd $DST 159342440ecSPrasad Singamsetty rm -f $flist 160342440ecSPrasad Singamsetty ) 161342440ecSPrasad Singamsetty for file in $flist ; do 162342440ecSPrasad Singamsetty echo $file | cpio -pdum $DST 2> /dev/null 163342440ecSPrasad Singamsetty done 164342440ecSPrasad Singamsetty else 165342440ecSPrasad Singamsetty find kernel platform -name unix | \ 166342440ecSPrasad Singamsetty cpio -pdum $DST 2> /dev/null 167986fd29aSsetje find kernel platform -name genunix | cpio -pdum $DST \ 168986fd29aSsetje 2> /dev/null 169986fd29aSsetje find kernel platform -name platmod | cpio -pdum $DST \ 170986fd29aSsetje 2> /dev/null 171342440ecSPrasad Singamsetty find `find kernel platform -name cpu` | \ 172342440ecSPrasad Singamsetty cpio -pdum $DST 2> /dev/null 173342440ecSPrasad Singamsetty find `find kernel platform -name kmdb\*` | \ 174342440ecSPrasad Singamsetty cpio -pdum $DST 2> /dev/null 175986fd29aSsetje find kernel/misc/sparcv9/ctf kernel/fs/sparcv9/dcfs \ 176986fd29aSsetje etc/system etc/name_to_major etc/path_to_inst \ 1773bef9c63Sxun ni - Sun Microsystems - Beijing China etc/name_to_sysnum etc/driver_aliases \ 1783bef9c63Sxun ni - Sun Microsystems - Beijing China etc/driver_classes etc/minor_perm | \ 1793bef9c63Sxun ni - Sun Microsystems - Beijing China cpio -pdum $DST 2> /dev/null 180342440ecSPrasad Singamsetty fi 181986fd29aSsetje ) 182986fd29aSsetje} 183986fd29aSsetje 184986fd29aSsetjeroot_is_ramdisk() 185986fd29aSsetje{ 186986fd29aSsetje grep -v "set root_is_ramdisk=" "$UNPACKED_ROOT"/etc/system | \ 187986fd29aSsetje grep -v "set ramdisk_size=" > /tmp/system.$$ 188986fd29aSsetje cat /tmp/system.$$ > "$UNPACKED_ROOT"/etc/system 189986fd29aSsetje rm /tmp/system.$$ 190986fd29aSsetje 191986fd29aSsetje echo set root_is_ramdisk=1 >> "$UNPACKED_ROOT"/etc/system 192986fd29aSsetje echo set ramdisk_size=$1 >> "$UNPACKED_ROOT"/etc/system 1937c478bd9Sstevel@tonic-gate} 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gatepack() 1967c478bd9Sstevel@tonic-gate{ 197f0778428SJerry Gilliam MR="$1" 198f0778428SJerry Gilliam [ -d "$UNPACKED_ROOT" ] || usage 1997c478bd9Sstevel@tonic-gate 200342440ecSPrasad Singamsetty # always compress if fiocompress exists 201986fd29aSsetje # 202342440ecSPrasad Singamsetty if [ -x /usr/sbin/fiocompress ] ; then 203986fd29aSsetje COMPRESS=true 204986fd29aSsetje fi 205986fd29aSsetje 2064681df02Sjongkis # Estimate image size and add %10 overhead for ufs stuff. 2074681df02Sjongkis # Note, we can't use du here in case $UNPACKED_ROOT is on a filesystem, 2084681df02Sjongkis # e.g. zfs, in which the disk usage is less than the sum of the file 2094681df02Sjongkis # sizes. The nawk code 2104681df02Sjongkis # 2114681df02Sjongkis # {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7} 2124681df02Sjongkis # 2134681df02Sjongkis # below rounds up the size of a file/directory, in bytes, to the 2144681df02Sjongkis # next multiple of 1024. This mimics the behavior of ufs especially 2154681df02Sjongkis # with directories. This results in a total size that's slightly 2164681df02Sjongkis # bigger than if du was called on a ufs directory. 217986fd29aSsetje # 218986fd29aSsetje # if the operation in turn is compressing the files the amount 219986fd29aSsetje # of typical shrinkage is used to come up with a useful archive 220986fd29aSsetje # size 2214681df02Sjongkis size=$(find "$UNPACKED_ROOT" -ls | nawk ' 2224681df02Sjongkis {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7} 2234681df02Sjongkis END {print int(t * 1.10 / 1024)}') 224986fd29aSsetje if [ "$COMPRESS" = true ] ; then 225342440ecSPrasad Singamsetty size=`echo $size | nawk '{s = $1} END {print int(s * 0.6)}'` 226986fd29aSsetje fi 2277c478bd9Sstevel@tonic-gate 22858091fd8Ssetje /usr/sbin/mkfile ${size}k "$TMR" 22958091fd8Ssetje 23058091fd8Ssetje LOFIDEV=`/usr/sbin/lofiadm -a "$TMR"` 2317c478bd9Sstevel@tonic-gate if [ $? != 0 ] ; then 2327c478bd9Sstevel@tonic-gate echo lofi plumb failed 2337c478bd9Sstevel@tonic-gate exit 2 2347c478bd9Sstevel@tonic-gate fi 2357c478bd9Sstevel@tonic-gate 23658091fd8Ssetje RLOFIDEV=`echo $LOFIDEV | sed s/lofi/rlofi/` 23758091fd8Ssetje newfs $RLOFIDEV < /dev/null 2> /dev/null 238781dc622Ssetje mkdir -p $MNT 23958091fd8Ssetje mount -o nologging $LOFIDEV $MNT 240781dc622Ssetje rmdir $MNT/lost+found 241986fd29aSsetje 242986fd29aSsetje if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then 243986fd29aSsetje root_is_ramdisk $size 244986fd29aSsetje fi 245986fd29aSsetje 246e482cb0aSjongkis ( 247781dc622Ssetje cd "$UNPACKED_ROOT" 248986fd29aSsetje if [ "$COMPRESS" = true ] ; then 249986fd29aSsetje compress . $MNT 250986fd29aSsetje else 2517c478bd9Sstevel@tonic-gate find . -print | cpio -pdum $MNT 2> /dev/null 252986fd29aSsetje fi 253e482cb0aSjongkis ) 2547c478bd9Sstevel@tonic-gate lockfs -f $MNT 2557c478bd9Sstevel@tonic-gate umount $MNT 2567c478bd9Sstevel@tonic-gate rmdir $MNT 257986fd29aSsetje 258986fd29aSsetje if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then 259986fd29aSsetje "$UNPACKED_ROOT/usr/sbin/installboot" \ 260d876c67dSjg "$UNPACKED_ROOT/platform/sun4u/lib/fs/ufs/bootblk" \ 261986fd29aSsetje $RLOFIDEV 262986fd29aSsetje fi 263986fd29aSsetje 26458091fd8Ssetje lofiadm -d $LOFIDEV 265e482cb0aSjongkis LOFIDEV= 2667c478bd9Sstevel@tonic-gate 26758091fd8Ssetje rm -f "$TMR.gz" 268986fd29aSsetje 269986fd29aSsetje if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then 270986fd29aSsetje mv "$TMR" "$MR" 271986fd29aSsetje else 27258091fd8Ssetje gzip -f "$TMR" 27358091fd8Ssetje mv "$TMR.gz" "$MR" 274986fd29aSsetje fi 275986fd29aSsetje 276781dc622Ssetje chmod a+r "$MR" 2777c478bd9Sstevel@tonic-gate} 2787c478bd9Sstevel@tonic-gate 2791437d1e8Ssetjestrip_amd64() 2801437d1e8Ssetje{ 2811437d1e8Ssetje find "$UNPACKED_ROOT" -name amd64 -type directory | xargs rm -rf 2821437d1e8Ssetje} 2831437d1e8Ssetje 2847c478bd9Sstevel@tonic-gate# main 2857c478bd9Sstevel@tonic-gate# 2867c478bd9Sstevel@tonic-gate 28758091fd8SsetjeEXTRA_SPACE=0 288e482cb0aSjongkisSTRIP_AMD64= 289986fd29aSsetjeCOMPRESS= 29058091fd8Ssetje 291986fd29aSsetjePATH=/usr/sbin:/usr/bin:/opt/sfw/bin ; export PATH 292986fd29aSsetje 293986fd29aSsetjewhile getopts s:6c opt ; do 29458091fd8Ssetje case $opt in 29558091fd8Ssetje s) EXTRA_SPACE="$OPTARG" 29658091fd8Ssetje ;; 29758091fd8Ssetje 6) STRIP_AMD64=false 29858091fd8Ssetje ;; 299986fd29aSsetje c) COMPRESS=true 300986fd29aSsetje ;; 30158091fd8Ssetje *) usage 30258091fd8Ssetje ;; 30358091fd8Ssetje esac 30458091fd8Ssetjedone 30558091fd8Ssetjeshift `expr $OPTIND - 1` 30658091fd8Ssetje 307f0778428SJerry Gilliam[ $# == 3 ] || usage 3087c478bd9Sstevel@tonic-gate 309781dc622SsetjeUNPACKED_ROOT="$3" 310781dc622SsetjeBASE="`pwd`" 3117c478bd9Sstevel@tonic-gateMNT=/tmp/mnt$$ 31258091fd8SsetjeTMR=/tmp/mr$$ 31358091fd8SsetjeLOFIDEV= 314781dc622SsetjeMR="$2" 3157c478bd9Sstevel@tonic-gate 316f0778428SJerry Gilliam# sanity check 317f0778428SJerry Gilliam[ "$UNPACKED_ROOT" != "/" ] || usage 318f0778428SJerry Gilliam 3197c478bd9Sstevel@tonic-gateif [ "`dirname $MR`" = . ] ; then 320781dc622Ssetje MR="$BASE/$MR" 3217c478bd9Sstevel@tonic-gatefi 3227c478bd9Sstevel@tonic-gateif [ "`dirname $UNPACKED_ROOT`" = . ] ; then 323781dc622Ssetje UNPACKED_ROOT="$BASE/$UNPACKED_ROOT" 3247c478bd9Sstevel@tonic-gatefi 3257c478bd9Sstevel@tonic-gate 32658091fd8Ssetjetrap cleanup EXIT 32758091fd8Ssetje 328f0778428SJerry Gilliam# always unpack into a fresh root 329f0778428SJerry Gilliamcase $1 in 330*a0eaab1eSAlexander Eremin unpack) 331f0778428SJerry Gilliam rm -rf "$UNPACKED_ROOT" 332f0778428SJerry Gilliam mkdir -p "$UNPACKED_ROOT" 333f0778428SJerry Gilliam ;; 334f0778428SJerry Gilliamesac 335f0778428SJerry Gilliam[ -d "$UNPACKED_ROOT" ] || usage 336f0778428SJerry Gilliam 3377c478bd9Sstevel@tonic-gatecase $1 in 338f0778428SJerry Gilliam pack) pack "$MR" 339986fd29aSsetje ;; 340f0778428SJerry Gilliam unpack) unpack "$MR" 341986fd29aSsetje ;; 342986fd29aSsetje *) usage 343986fd29aSsetje ;; 3447c478bd9Sstevel@tonic-gateesac 345