mkbfu.sh revision 7c478bd95313f5f23a4c958a745db2134aa03244
#!/bin/ksh
#
# 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.
#
# ident "%Z%%M% %I% %E% SMI"
#
# Make archives suitable for bfu
#
# The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout
# under certain circumstances, which can really screw things up; unset it.
#
unset CDPATH
fail() {
echo $* >&2
exit 1
}
# Place a limit on the number of background jobs we can produce at one
# time. The mechanism used is crude; we wait for all jobs to complete
# before continuing. It'd be nice if ksh actually had such a native
# facility.
bgcheck() {
bgctr=$((bgctr + 1))
if [ $bgctr -ge $bgmax ]; then
wait
bgctr=0
for outf in $CPIODIR/*.out; do
errf=${outf%.out}.err
if [ -s $errf ]; then
echo "Failed to create\c" >&2
cat $outf $errf >&2
else
echo "Creating\c"
cat $outf
fi
rm -f $outf $errf
done
fi
}
bgctr=0
bgmax=${DMAKE_MAX_JOBS:-1}
# Produce a named archive. Archives always have two names -- the
# first part is an identifier for the archive, the second part is
# 'root' or 'usr' or 'lib' or 'sbin' or 'kernel'.
create_archive() {
arc="$CPIODIR/$1.$2"
outf="${arc}.out"
cpioerr="${arc}.cpioerr"
echo " $1 $2 archive:\t\c" >$outf
eval $cpio >$arc$ext
awk '/^[0-9]* blocks$/ { blocks=1; print $0; next }
{ print $0 > "/dev/stderr" }
END {
if (!blocks) {
# Terminate the "echo \c" line above.
print
print "No cpio block count" > "/dev/stderr"
}
}' <$cpioerr >>$outf
rm -f $cpioerr
}
ext=
filter=
compressor=
usage="Usage: $0 [-f filter] [-z] proto-dir archive-dir"
prove_you_mean_it="\n\
\n\
Unless invoked directly by makebfu, this script will produce archives with\n\
incorrect permissions which will brickify a system if installed. You most\n\
likely wanted to run makebfu instead; if not, set\n\n\
\t\tI_REALLY_WANT_TO_RUN_MKBFU=YES\n\n\
in your environment and try again.\n\n\n"
[ -n "$I_REALLY_WANT_TO_RUN_MKBFU" ] || fail "$prove_you_mean_it"
[ "$I_REALLY_WANT_TO_RUN_MKBFU" = "YES" ] || fail "$prove_you_mean_it"
while getopts :f:z opt
do
case "$opt" in
f) filter="$OPTARG";;
z) compressor="gzip -c"
ext=".gz";;
*) fail "$usage";;
esac
done
shift $(($OPTIND - 1))
[ $# -eq 2 ] || fail "$usage"
# The extra subshell allows us to wait for cpio to exit completely (rather
# that merely closing stdout) before attempting to examine the stderr output
# file. Otherwise, we'll race with cpio's completion.
cpio='( ( cpio -ocB 2>$cpioerr ); true )'
if [ "$filter" ]; then
cpio="$cpio | $filter"
fi
if [ "$compressor" ]; then
cpio="$cpio | $compressor"
fi
PROTO=$1
CPIODIR=$2
PLATFORM=`uname -i`
[ -d $PROTO ] || fail "Proto directory $PROTO does not exist."
cd $PROTO
rm -rf $CPIODIR
mkdir -p $CPIODIR
# Create "new style" archives if Zones are present, with lib, sbin and kernel
# in their own archives; otherwise create "old style" archives with everything
# in generic.root
if [ -d etc/zones ]; then
( { FILELIST=`ls . | grep -v usr | grep -v platform |
grep -v kernel | grep -v boot | grep -v sbin |
grep -v lib | sed -e "s@^@./@"`
find $FILELIST -depth -print
echo "./usr"
echo "./platform"
echo "./lib"
echo "./sbin"
echo "./kernel"
} | create_archive generic root ) 2>$CPIODIR/generic.root.err &
bgcheck
( { FILELIST=`ls ./lib | sed -e "s@^@./lib/@"`
find $FILELIST -depth -print
} | create_archive generic lib ) 2>$CPIODIR/generic.lib.err &
bgcheck
( { FILELIST=`ls ./sbin | sed -e "s@^@./sbin/@"`
find $FILELIST -depth -print
} | create_archive generic sbin ) 2>$CPIODIR/generic.sbin.err &
bgcheck
( { FILELIST=`ls ./kernel | sed -e "s@^@./kernel/@"`
find $FILELIST -depth -print
} | create_archive generic kernel ) 2>$CPIODIR/generic.kernel.err &
bgcheck
else
( { FILELIST=`ls . | grep -v usr | grep -v platform |
grep -v boot | sed -e "s@^@./@"`
find $FILELIST -depth -print
echo "./usr"
echo "./platform"
} | create_archive generic root ) 2>$CPIODIR/generic.root.err &
bgcheck
fi
( { FILELIST=`ls ./usr | grep -v platform | sed -e "s@^@./usr/@"`
find $FILELIST -depth -print | egrep -v -e "./usr/share/src"
echo "./usr/platform"
} | create_archive generic usr ) 2>$CPIODIR/generic.usr.err &
bgcheck
for i in `cd platform; find * -prune \( -type d -o -type l \) -print`
do
( { FILELIST=`ls -1 ./platform | grep "$i$" |
sed -e "s@^@./platform/@"`
find $FILELIST -depth -print
} | create_archive $i root ) 2>$CPIODIR/${i}.root.err &
bgcheck
( { FILELIST=`ls -1 ./usr/platform | grep "$i$" |
sed -e "s@^@./usr/platform/@"`
find $FILELIST -depth -print
} | create_archive $i usr ) 2>$CPIODIR/${i}.usr.err &
bgcheck
done
if [ -d boot ]; then
( find boot -depth -print | create_archive $PLATFORM boot ) \
2>$CPIODIR/${PLATFORM}.boot.err &
bgcheck
fi
# If there are any background jobs left, then gather them now.
if [ $bgctr -gt 0 ]; then
bgmax=0
bgcheck
fi