summaryrefslogtreecommitdiff
path: root/usr/src/tools/scripts/mkbfu.sh
blob: c5980fd64527dbbe28c5f3cbb505347ffc936852 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/bin/ksh
#
# 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"
#
# 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

CLASS=`uname -m`

[ -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
	if [ "$CLASS" = "i86pc" ]; then
		ARCHIVECLASS="$CLASS"
	else
		ARCHIVECLASS="generic"
	fi
	( find boot -depth -print | create_archive $ARCHIVECLASS boot ) \
	    2>$CPIODIR/$ARCHIVECLASS.boot.err &
	bgcheck
fi

# If there are any background jobs left, then gather them now.
if [ $bgctr -gt 0 ]; then
	bgmax=0
	bgcheck
fi