1 #!/bin/ksh 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 2007 Sun Microsystems, Inc. All rights reserved. 24 # Use is subject to license terms. 25 # 26 # ident "%Z%%M% %I% %E% SMI" 27 # 28 # Make archives suitable for bfu 29 30 # 31 # The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout 32 # under certain circumstances, which can really screw things up; unset it. 33 # 34 unset CDPATH 35 36 fail() { 37 echo $* >&2 38 exit 1 39 } 40 41 # Place a limit on the number of background jobs we can produce at one 42 # time. The mechanism used is crude; we wait for all jobs to complete 43 # before continuing. It'd be nice if ksh actually had such a native 44 # facility. 45 bgcheck() { 46 bgctr=$((bgctr + 1)) 47 if [ $bgctr -ge $bgmax ]; then 48 wait 49 bgctr=0 50 for outf in $CPIODIR/*.out; do 51 errf=${outf%.out}.err 52 if [ -s $errf ]; then 53 echo "Failed to create\c" >&2 54 cat $outf $errf >&2 55 else 56 echo "Creating\c" 57 cat $outf 58 fi 59 rm -f $outf $errf 60 done 61 fi 62 } 63 bgctr=0 64 bgmax=${DMAKE_MAX_JOBS:-1} 65 66 # Produce a named archive. Archives always have two names -- the 67 # first part is an identifier for the archive, the second part is 68 # 'root' or 'usr' or 'lib' or 'sbin' or 'kernel'. 69 create_archive() { 70 arc="$CPIODIR/$1.$2" 71 outf="${arc}.out" 72 cpioerr="${arc}.cpioerr" 73 echo " $1 $2 archive:\t\c" >$outf 74 eval $cpio >$arc$ext 75 awk '/^[0-9]* blocks$/ { blocks=1; print $0; next } 76 { print $0 > "/dev/stderr" } 77 END { 78 if (!blocks) { 79 # Terminate the "echo \c" line above. 80 print 81 print "No cpio block count" > "/dev/stderr" 82 } 83 }' <$cpioerr >>$outf 84 rm -f $cpioerr 85 } 86 87 ext= 88 filter= 89 compressor= 90 usage="Usage: $0 [-f filter] [-z] proto-dir archive-dir" 91 prove_you_mean_it="\n\ 92 \n\ 93 Unless invoked directly by makebfu, this script will produce archives with\n\ 94 incorrect permissions which will brickify a system if installed. You most\n\ 95 likely wanted to run makebfu instead; if not, set\n\n\ 96 \t\tI_REALLY_WANT_TO_RUN_MKBFU=YES\n\n\ 97 in your environment and try again.\n\n\n" 98 99 [ -n "$I_REALLY_WANT_TO_RUN_MKBFU" ] || fail "$prove_you_mean_it" 100 [ "$I_REALLY_WANT_TO_RUN_MKBFU" = "YES" ] || fail "$prove_you_mean_it" 101 102 while getopts :f:z opt 103 do 104 case "$opt" in 105 f) filter="$OPTARG";; 106 z) compressor="gzip -c" 107 ext=".gz";; 108 *) fail "$usage";; 109 esac 110 done 111 shift $(($OPTIND - 1)) 112 113 [ $# -eq 2 ] || fail "$usage" 114 115 # The extra subshell allows us to wait for cpio to exit completely (rather 116 # that merely closing stdout) before attempting to examine the stderr output 117 # file. Otherwise, we'll race with cpio's completion. 118 cpio='( ( cpio -ocB 2>$cpioerr ); true )' 119 if [ "$filter" ]; then 120 cpio="$cpio | $filter" 121 fi 122 if [ "$compressor" ]; then 123 cpio="$cpio | $compressor" 124 fi 125 126 PROTO=$1 127 CPIODIR=$2 128 129 CLASS=`uname -m` 130 131 [ -d $PROTO ] || fail "Proto directory $PROTO does not exist." 132 133 cd $PROTO 134 135 rm -rf $CPIODIR 136 mkdir -p $CPIODIR 137 138 # Create "new style" archives if Zones are present, with lib, sbin and kernel 139 # in their own archives; otherwise create "old style" archives with everything 140 # in generic.root 141 if [ -d etc/zones ]; then 142 ( { FILELIST=`ls . | grep -v usr | grep -v platform | 143 grep -v kernel | grep -v boot | grep -v sbin | 144 grep -v lib | sed -e "s@^@./@"` 145 find $FILELIST -depth -print 146 echo "./usr" 147 echo "./platform" 148 echo "./lib" 149 echo "./sbin" 150 echo "./kernel" 151 } | create_archive generic root ) 2>$CPIODIR/generic.root.err & 152 bgcheck 153 154 ( { FILELIST=`ls ./lib | sed -e "s@^@./lib/@"` 155 find $FILELIST -depth -print 156 } | create_archive generic lib ) 2>$CPIODIR/generic.lib.err & 157 bgcheck 158 159 ( { FILELIST=`ls ./sbin | sed -e "s@^@./sbin/@"` 160 find $FILELIST -depth -print 161 } | create_archive generic sbin ) 2>$CPIODIR/generic.sbin.err & 162 bgcheck 163 164 ( { FILELIST=`ls ./kernel | sed -e "s@^@./kernel/@"` 165 find $FILELIST -depth -print 166 } | create_archive generic kernel ) 2>$CPIODIR/generic.kernel.err & 167 bgcheck 168 else 169 ( { FILELIST=`ls . | grep -v usr | grep -v platform | 170 grep -v boot | sed -e "s@^@./@"` 171 find $FILELIST -depth -print 172 echo "./usr" 173 echo "./platform" 174 } | create_archive generic root ) 2>$CPIODIR/generic.root.err & 175 bgcheck 176 fi 177 178 ( { FILELIST=`ls ./usr | grep -v platform | sed -e "s@^@./usr/@"` 179 find $FILELIST -depth -print | egrep -v -e "./usr/share/src" 180 echo "./usr/platform" 181 } | create_archive generic usr ) 2>$CPIODIR/generic.usr.err & 182 bgcheck 183 184 for i in `cd platform; find * -prune \( -type d -o -type l \) -print` 185 do 186 ( { FILELIST=`ls -1 ./platform | grep "$i$" | 187 sed -e "s@^@./platform/@"` 188 find $FILELIST -depth -print 189 } | create_archive $i root ) 2>$CPIODIR/${i}.root.err & 190 bgcheck 191 192 ( { FILELIST=`ls -1 ./usr/platform | grep "$i$" | 193 sed -e "s@^@./usr/platform/@"` 194 find $FILELIST -depth -print 195 } | create_archive $i usr ) 2>$CPIODIR/${i}.usr.err & 196 bgcheck 197 done 198 199 if [ -d boot ]; then 200 if [ "$CLASS" = "i86pc" ]; then 201 ARCHIVECLASS="$CLASS" 202 else 203 ARCHIVECLASS="generic" 204 fi 205 ( find boot -depth -print | create_archive $ARCHIVECLASS boot ) \ 206 2>$CPIODIR/$ARCHIVECLASS.boot.err & 207 bgcheck 208 fi 209 210 # If there are any background jobs left, then gather them now. 211 if [ $bgctr -gt 0 ]; then 212 bgmax=0 213 bgcheck 214 fi 215