Home | History | Annotate | Download | only in scripts
      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