Whamcloud - gitweb
b=15316
[fs/lustre-release.git] / build / lbuild
1 #!/bin/bash
2
3 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
4
5 #set -x
6
7 TOPDIR=$PWD
8
9 # CVSROOT is inherited from the environment
10 KERNELDIR=
11 LINUX=
12 LUSTRE=
13 RELEASE=false
14 DO_SRC=0
15 DOWNLOAD=1
16 TAG=
17 CANONICAL_TARGET=
18 TARGET=
19 TARGET_ARCH=$(uname -m)
20 TARGET_ARCHS=
21 TARGET_ARCHS_ALL=$TARGET_ARCH
22 [ "$TARGET_ARCH" = "i686" ] && TARGET_ARCHS_ALL="i686 i586 i386"
23 CONFIGURE_FLAGS=
24 EXTERNAL_PATCHES=
25 EXTRA_VERSION=
26 LUSTRE_EXTRA_VERSION=
27 STAGEDIR=
28 TMPDIR=${TMPDIR:-"/var/tmp"}
29 TIMESTAMP=
30 REUSERPM=
31 REUSEBUILD=
32 NORPM=false
33 LDISKFSRPM=true
34 SKIPLDISKFSRPM="v1_4_* b1_4"
35 SMPTYPES="smp bigsmp default ''"
36 KERNCONFSMPTYPE=
37 PATCHLESS=false
38 LINUXOBJ=
39 REUSEDKERNELMASK=
40 DISTRO=
41 KERNELTREE=
42
43 # patchless build
44 KERNELRPMSBASE=
45 KERNELRPM=
46 KERNELSOURCERPM=
47 RPMSMPTYPE=
48 KERNELRPMCONFIG=
49 KERNELRPMRELEASE=
50 KERNELCOMPILEDIR=
51
52 # from target file
53 KERNEL=
54 SERIES=
55 CONFIG=
56 VERSION=
57
58 RHBUILD=0
59 SUSEBUILD=0
60 LINUX26=0
61 SUSEBUILD=0
62
63 BASE_ARCHS=
64 BIGMEM_ARCHS=
65 BOOT_ARCHS=
66 JENSEN_ARCHS=
67 SMP_ARCHS=
68 BIGSMP_ARCHS=
69 PSERIES64_ARCHS=
70 UP_ARCHS=
71
72 DATE=$(date)
73
74 USE_DATESTAMP=1
75 RPMBUILD=
76
77 export CC=${CC:-gcc}
78
79 # Readlink is not present on some older distributions: emulate it.
80 readlink() {
81     local path=$1 ll
82
83     if [ -L "$path" ]; then
84         ll="$(LC_ALL=C ls -l "$path" 2> /dev/null)" &&
85         echo "${ll/* -> }"
86     else
87         return 1
88     fi
89 }
90
91 cleanup()
92 {
93     true
94 }
95
96 error()
97 {
98     [ "$1" ] && echo -e "\n${0##*/}: $1"
99 }
100
101 fatal()
102 {
103     cleanup
104     error "$2"
105     exit $1
106 }
107
108 list_targets()
109 {
110     echo -n "Available targets:"
111     for target in $TOPDIR/lustre/lustre/kernel_patches/targets/*.target ; do
112         target_file=${target##*/}
113         echo -n " ${target_file%%.target}"
114     done
115     echo
116 }
117
118 usage()
119 {
120     cat <<EOF
121 Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
122
123   -d CVSROOT
124     Specifies the CVS Root to use when pulling files from CVS.  The
125     environment variable \$CVSROOT is used if this option is not
126     present.
127
128   --external-patches=EXTERNAL_PATCHES
129     Directory similar to lustre/lustre/kernel_patches/ that lbuild should
130     look for seres and config files in before looking in the lustre
131     tree.
132
133   --extraversion=EXTRAVERSION
134     Text to use for the rpm release and kernel extraversion.
135
136   --kerneldir=KERNELDIR
137     Directory containing Linux source tarballs referenced by target
138     files.
139
140   --timestamp=TIMESTAMP
141     Date of building lustre in format YYYYMMDDhhmmss
142
143   --reuserpm=DIR
144     Try to reuse old kernel RPMs from DIR
145
146   --reusebuild=DIR
147     Try to reuse old kernel builds from DIR
148
149   --kernelrpm=DIR
150     Path to distro kernel RPM collection
151
152   --ccache
153     Use ccache
154
155   --norpm
156     Do not build RPMs (compile only mode)
157
158   --patchless
159     Build lustre client only
160
161   --distro=DISTRO
162     Which distro using. Autodetect by default
163
164   --kerneltree=KERNELTREE
165     Directory containing dirs with Linux source tarballs referenced by target
166     files. Dir names in format kernel version ('2.6.9', etc.)
167
168   --linux=LINUX
169     Directory of Linux kernel sources.  When this option is used, only
170     Lustre modules and userspace are built.
171
172   --lustre=LUSTRE
173     Path to an existing lustre source tarball to use instead of
174     pulling from CVS.
175
176   --nodownload
177     Do not try to download a kernel from downloads.lustre.org
178
179   --nosrc
180     Do not build a .src.rpm, a full kernel patch, or a patched kernel
181     tarball.
182
183   --ldiskfs
184     Do ldiskfs RPM. Now true by default
185
186   --publish
187     Unused.
188
189   --release
190     Specifies that the files generated do not include timestamps, and
191     that this is an official release.
192
193   --src
194     Build a .src.rpm, a full kernel patch, and a patched kernel tarball.
195
196   --stage=DIR
197     Directory used to stage packages for release.  RPMs will be placed
198     more or less in DIR/<target>-<arch>, and the tarball will be
199     placed in DIR.
200
201   --tag=TAG
202     A CVS branch/tag name to build from when pulling from CVS.
203
204   --target=TARGET
205     The name of the target to build.  The available targets are listed
206     below.
207
208   --target-archs=TARGET_ARCHS
209     A (space delimited) list of architectures to build.  By default,
210     all of the archs supported by the TARGET will be built, in
211     addition to a .src.rpm.  This option can limit those, for machines
212     that can only build certain archs or if you only want a certain
213     arch built (for testing, or a one-off kernel).
214
215     Also note that by using a non-"base" arch (eg, i386) only kernels
216     will be built - there will be no lustre-lite-utils package.
217
218   --disable-datestamp
219     Prevents the datestamp flag (-D) from being passed to cvs for 
220     checkouts. This is a workaround for a problem encountered when 
221     using lbuild with tinderbox.
222
223 EOF
224
225 #   list_targets
226
227     fatal "$1" "$2"
228 }
229
230 check_options()
231 {
232     if [ "$LUSTRE" ] ; then
233         [ -r "$LUSTRE" ] || \
234             usage 1 "Could not find Lustre source tarball '$LUSTRE'."
235     else
236         [ "$CVSROOT" ] || \
237             usage 1 "Either specify a CVS Root with -d, or a Lustre source tarball with --lustre."
238         [ "$TAG" ] || \
239             usage 1 "A branch/tag name must be specified with --tag when not building from a tarball."
240     fi
241
242     if [ -z "$LINUX" ] ; then
243         [ "$KERNELDIR" -o "$KERNELTREE" ] || \
244             usage 1 "A kernel directory must be specified with --kerneldir or --kerneltree."
245
246         [ -d "$KERNELDIR" -o -d "$KERNELTREE" ] || \
247             usage 1 "$KERNELDIR and $KERNELTREE are not a directory."
248
249         if ! $RELEASE; then
250             [ "$TAG" ] || \
251                 usage 1 "When building a snapshot, a tag name must be used."
252         fi
253
254         [ "$TARGET" ] || usage 1 "A target must be specified with --target."
255 #       TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
256 #       [ -r "$TARGET_FILE" ] || \
257 #               usage 1 "Target '$TARGET' was not found."
258     fi
259
260     case $TARGET in
261         2.6-rhel5)
262             CANONICAL_TARGET="rhel5"
263             ;;
264         2.6-rhel4)
265             CANONICAL_TARGET="rhel-2.6"
266             ;;
267         2.6-suse)
268             CANONICAL_TARGET="sles-2.6"
269             ;;
270         2.6-sles10)
271             CANONICAL_TARGET="sles10-2.6"
272             ;;
273         hp_pnnl-2.4)
274             CANONICAL_TARGET="hp-pnnl-2.4"
275             ;;
276         2.6-vanilla \
277             | suse-2.4.21-2 \
278             | rh-2.4 \
279             | rhel-2.4 \
280             | sles-2.4 \
281             | 2.6-patchless)
282                 CANONICAL_TARGET="$TARGET"
283                 ;;
284     esac
285
286     local timestampnodig=$(echo $TIMESTAMP | sed -e s/[0-9]*//g)
287     [ "$timestampnodig" = "" ] || TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
288     local timestamplength="${#TIMESTAMP}"
289     if [ $timestamplength -eq 12 ]; then
290         TIMESTAMP="${TIMESTAMP}00"
291     elif [ $timestamplength -ne 14 ]; then
292         TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
293     fi
294
295     RPMBUILD=$(which rpmbuild 2>/dev/null | head -1)
296     if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
297         RPMBUILD=$(which rpm 2>/dev/null | head -1)
298         if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
299             usage 1 "Could not find binary for making rpms (tried rpmbuild and rpm)."
300         fi
301     fi
302     
303     if [ -n "$CCACHE" ]; then 
304         which "$CCACHE" 2>/dev/null && export CCACHE && export CC="ccache gcc"
305         which "$DISTCC" 2>/dev/null && export DISTCC RPM_BUILD_NCPUS
306         local bindir="/cache/build/bin"
307         [ -d $bindir ] || mkdir -p $bindir
308         [ -d $bindir ] && rm ${bindir}/* > /dev/null 2>&1
309         which "$CCACHE" 2>/dev/null && [ -d $bindir ] && ln -s `which "$CCACHE"` ${bindir}/ccache
310         which "$CCACHE" 2>/dev/null && [ -d $bindir ] && ln -s `which "$CCACHE"` ${bindir}/cc
311         which "$CCACHE" 2>/dev/null && [ -d $bindir ] && ln -s `which "$CCACHE"` ${bindir}/gcc
312         [ -d $bindir ] && export PATH=$bindir:$PATH
313     fi
314
315     [ -z "$DISTRO" ] && autodetect_distro
316 }
317
318 #autodetect used Distro
319 autodetect_distro()
320 {
321     if [ -f /etc/SuSE-release ]; then
322         DISTRO=sles10
323     elif [ -f /etc/redhat-release ]; then
324         local distroname=$(head -1 /etc/redhat-release | grep -e "CentOS\|Red")
325         if [ ! "$distroname" = "" ]; then
326             local version=$(echo "$distroname" | sed -e s/[^0-9.]*//g | sed -e s/\\..*// )
327             distroname="rhel"
328             [ "$version" = "" ] || DISTRO="${distroname}${version}"
329         fi
330     fi
331     [ "$DISTRO" = "" ] && DISTRO="sles9" #default distro
332 }
333
334 uniqify()
335 {
336     echo $(echo "$*" | xargs -n 1 | sort -u)
337 }
338
339 build_tarball() {
340     local TARGET=$1
341     local SRPM=$2
342
343     if [ "$TARGET" = "rhel-2.6" -o "$TARGET" = "rhel-2.4" ]; then
344         local SPEC=""
345         if [ "$TARGET" = "rhel-2.6" ]; then
346             SPEC=kernel-2.6.spec
347             OLDCONFIG=nonint_oldconfig
348         elif [ "$TARGET" = "rhel-2.4" ]; then
349             SPEC=kernel-2.4.spec
350             OLDCONFIG=oldconfig
351         fi
352
353         RPMTOPDIR=$(mktemp -d $KERNELDIR/rpm_XXXXXX)
354         mkdir $RPMTOPDIR/BUILD/
355         rpm -ivh $KERNELDIR/$SRPM --define "_topdir $RPMTOPDIR" || \
356             { rm -rf $RPMTOPDIR; fatal 1 "Error installing kernel SRPM."; }
357         $RPMBUILD -bp --nodeps --target i686 $RPMTOPDIR/SPECS/$SPEC --define "_topdir $RPMTOPDIR"
358         pushd $RPMTOPDIR/BUILD/kernel-${lnxmaj}/linux-${lnxmaj} && {
359             make mrproper
360             cp configs/kernel-${lnxmaj}-i686-smp.config .config
361             if ! make $OLDCONFIG > /dev/null; then
362                 fatal 1 "error trying to make $OLDCONFIG while building a tarball from SRPM."
363             fi
364             make include/linux/version.h 
365             rm -f .config
366             cd ..
367             tar cjf $KERNEL_FILE linux-${lnxmaj}
368         }
369         popd
370         rm -rf $RPMTOPDIR
371     fi
372 }
373
374 download_and_build_tarball() {
375     local target=$1
376     local kernel_file=$2
377
378     local srpm=kernel-${lnxmaj}-${lnxrel}.src.rpm
379
380     echo "Downloading http://downloads.lustre.org/public/kernels/$target/old/$srpm..."
381     if ! wget -nv "http://downloads.lustre.org/public/kernels/$target/old/$srpm" \
382         -O "$KERNELDIR/$srpm" ; then
383         fatal 1 "Could not download target $kernel_file's kernel SRPM $srpm from downloads.lustre.org."
384     fi
385
386     build_tarball $target $srpm
387 }
388
389 load_target()
390 {
391     EXTRA_VERSION_save="$EXTRA_VERSION"
392     for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches" ; do
393         TARGET_FILE="$patchesdir/targets/$TARGET.target"
394         [ -r "$TARGET_FILE" ] && break
395     done
396     [ -r "$TARGET_FILE" ] || \
397         fatal 1 "Target $TARGET was not found."
398
399     echo "Loading target config file $TARGET.target..."        
400
401     . "$TARGET_FILE"
402
403     [ "$KERNEL"  ] || fatal 1 "Target $TARGET did not specify a kernel."
404     [ "$VERSION" ] || fatal 1 "Target $TARGET did not specify a kernel version."
405
406     #CC was overwriten in TARGET_FILE
407     which "$CCACHE" 2>/dev/null && export CCACHE && export CC="ccache gcc"
408
409     if [ ! "$KERNELTREE" = "" ] && [ -d "$KERNELTREE" ]; then
410         KERNELDIR="$KERNELTREE/${lnxmaj}"
411         [ -d "$KERNELDIR" ] || mkdir "$KERNELDIR"
412     fi
413
414     if [ "$KERNELDIR" ] ; then
415         KERNEL_FILE="$KERNELDIR/$KERNEL"
416         if [ ! -r "$KERNEL_FILE" ] ; then
417             # see if we have an SRPM we can build a tarball for
418             KERNEL_SRPM=kernel-${lnxmaj}-${lnxrel}.src.rpm
419             if [ -r "$KERNELDIR/$KERNEL_SRPM" ] ; then
420                 build_tarball $CANONICAL_TARGET $KERNEL_SRPM
421             else
422                 if (( $DOWNLOAD )) ; then
423                     echo "Downloading http://downloads.lustre.org/public/kernels/$CANONICAL_TARGET/old/$KERNEL..."
424                     if ! wget -nv "http://downloads.lustre.org/public/kernels/$CANONICAL_TARGET/old/$KERNEL" -O "$KERNELDIR/$KERNEL" ; then
425                         # see if we can do it with an SRPM from the download site
426                         download_and_build_tarball $CANONICAL_TARGET $KERNEL_FILE
427                     fi
428                 else
429                     fatal 1 "Target $TARGET's kernel file $KERNEL not found in kernel directory $KERNELDIR."
430                 fi
431             fi
432         fi
433         if [ -n "$OFED_VERSION" ] && \
434            [ ! -r "$KERNELTREE/../OFED-${OFED_VERSION}.tgz" ] ; then
435             if (( $DOWNLOAD )) ; then
436                 local location="http://downloads.lustre.org/public/OFED/"
437                 echo "Downloading $location/OFED-${OFED_VERSION}.tgz..."
438                 if ! wget -nv "$location/OFED-${OFED_VERSION}.tgz" \
439                     -O "$KERNELTREE/../OFED-${OFED_VERSION}.tgz" ; then
440                     fatal 1 "Could not download OFED-${OFED_VERSION}.tgz from downloads.lustre.org."
441                 fi
442             else
443                 fatal 1 "OFED-${OFED_VERSION}.tgz not found in kernel directory $KERNELDIR."
444             fi
445         fi
446     fi
447
448     if [ "$SERIES" ] ; then
449         for series in $SERIES ; do
450             for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches" ; do
451                 [ -r "$patchesdir/series/$series" ] && continue 2
452             done
453             fatal 1 "Target $TARGET's series $SERIES could not be found.\nSearched:\n\t$EXTERNAL_PATCHES/series\n\t$TOPDIR/lustre/lustre/kernel_patches/series."
454         done
455     fi
456
457     if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config ]; then
458     CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config"
459     fi
460     local smptype
461     for smptype in $SMPTYPES; do
462         [ "$smptype" = "''" ] && smptype=
463         if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH-${smptype}.config ]; then
464         CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH-${smptype}.config"
465         KERNCONFSMPTYPE=$smptype
466     fi
467     done
468
469     local lnxrelnew=$( echo ${lnxrel} | sed s/-/_/g )
470
471     [ -f "$CONFIG_FILE" ] || \
472         fatal 1 "Config file for target $TARGET missing from $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
473     if [ "$EXTRA_VERSION_save" ] ; then
474         EXTRA_VERSION="$EXTRA_VERSION_save"
475     elif ! $RELEASE; then
476         # if there is no patch series, then this is not a lustre specific
477         # kernel.  don't make it look like one
478         if [ -n "$SERIES" ]; then
479             #remove the @VERSION@ (lustre version)
480 #            EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
481 #            EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
482             ! ( $PATCHLESS ) && EXTRA_VERSION="${EXTRA_VERSION}.${TIMESTAMP}"
483         fi
484     fi
485     # EXTRA_VERSION=${EXTRA_VERSION//-/_}
486
487     [ -z $REUSEDKERNELMASK ] && \
488         # create mask for kernel RPM/builddir which could be reused
489         if $NORPM; then
490             REUSEDKERNELMASK=${KERNCONFSMPTYPE}-${lnxmaj}-${lnxrelnew}_lustre.${LUSTRE_VERSION}.*${TARGET_ARCH}
491         elif $RELEASE; then
492             REUSEDKERNELMASK=${KERNCONFSMPTYPE}-${lnxmaj}-${lnxrelnew}_lustre.${LUSTRE_VERSION}.${TARGET_ARCH}
493         else
494             REUSEDKERNELMASK=${KERNCONFSMPTYPE}-${lnxmaj}-${lnxrelnew}_lustre.${LUSTRE_VERSION}.${TIMESTAMP}.${TARGET_ARCH}
495         fi
496         # kernel-lustre-smp-2.6.9-55.0.2.EL_lustre.1.6.1.i686.rpm 
497
498     ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $BIGSMP_ARCHS $PSERIES64_ARCHS $UP_ARCHS"
499
500     BUILD_ARCHS=
501     for arch in $(uniqify "$ALL_ARCHS") ; do
502         if [ -z "$TARGET_ARCHS" ] || echo "$TARGET_ARCHS" | grep "$arch" >/dev/null 2>/dev/null ; then
503             BUILD_ARCHS="$BUILD_ARCHS $arch"
504         fi
505     done
506     [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
507     echo "Building for: $BUILD_ARCHS"
508 }
509
510 tarflags()
511 {
512     case "$1" in
513         '')
514             fatal 1 "tarflags(): File name argument missing."
515             ;;
516         *.tar.gz | *.tgz)
517             echo 'zxf'
518             ;;
519         *.tar.bz2)
520             echo 'jxf'
521             ;;
522         *.tar)
523             echo 'xf'
524             ;;
525         *)
526             fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
527             ;;
528     esac
529 }
530
531 untar()
532 {
533     echo "Untarring ${1##*/}..."
534     tar $(tarflags "$1") "$1"
535 }
536
537 unpack_ofed()
538 {
539     untar "$KERNELTREE/../OFED-${OFED_VERSION}.tgz"
540     [ -d OFED ] || ln -sf OFED-[0-9].[0-9]* OFED
541     pwd
542     ls -ld OFED OFED-[0-9].[0-9]*
543     ls -l OFED OFED-[0-9].[0-9]*
544 }
545
546 unpack_lustre()
547 {
548     DIRNAME="lustre-$TAG-$TIMESTAMP"
549     if [ "$LUSTRE" ] ; then
550         untar "$LUSTRE"
551         [ -d lustre ] || ln -sf lustre-[0-9].[0-9]* lustre
552     else
553         if [ "$USE_DATESTAMP" ]; then
554             DATESTAMP="-D '$DATE'"
555         else
556             DATESTAMP=""
557         fi            
558
559         cvs -d "$CVSROOT" -qz3 co $DATESTAMP -d "$DIRNAME" lustre || \
560             fatal 1 "There was an error checking out toplevel Lustre from CVS."
561         pushd "$DIRNAME" > /dev/null
562         ./lustrecvs "$TAG" || \
563             fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
564         echo "Creating lustre tarball..."
565         sh autogen.sh || fatal 1 "There was an error running autogen.sh."
566         ./configure --disable-{modules,utils,liblustre,tests,doc} || \
567             fatal 1 "There was an error running ./configure to create makefiles."
568         make dist || fatal 1 "There was an error running 'make dist'."
569         popd > /dev/null
570         fname=$(basename $DIRNAME/lustre-*.tar.gz)
571         cp $DIRNAME/$fname . || fatal 1 "There was an error copying lustre tarball."
572         LUSTRE="$PWD/$fname"
573         ln -sf "$DIRNAME" lustre
574     fi
575 }
576
577 unpack_linux()
578 {
579     untar "$KERNEL_FILE"
580     [ -d linux ] || ln -sf linux* linux
581 }
582
583 patch_linux()
584 {
585     [ "$SERIES" ] || return 0
586     FULL_PATCH="$PWD/lustre-kernel-${TARGET}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}.patch"
587     [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
588     pushd linux >/dev/null
589     for series in $SERIES ; do
590         echo -n "Applying series $series:"
591         for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches" ; do
592             [ -r "$patchesdir/series/$series" ] || continue
593             SERIES_FILE="$patchesdir/series/$series"
594             for patch in $(<"$SERIES_FILE") ; do
595                 echo -n " $patch"
596                 PATCH_FILE="$patchesdir/patches/$patch"
597                 [ -r "$PATCH_FILE" ] || \
598                     fatal 1 "Patch $patch does not exist in Lustre tree."
599                 cat "$PATCH_FILE" >> "$FULL_PATCH" || \
600                     fatal 1 "Error adding patch $patch to full patch."
601                 patch -s -p1 < "$PATCH_FILE" || fatal 1 "Error applying patch $patch."
602             done
603             break
604         done
605         echo
606     done
607     popd >/dev/null
608     echo "Full patch has been saved in ${FULL_PATCH##*/}."
609     echo "Replacing .config files..."
610     [ -d linux/configs ] || mkdir linux/configs || \
611         fatal 1 "Error creating configs directory."
612     rm -f linux/configs/*
613     copysuccess=0
614     for patchesdir in "$EXTERNAL_PATCHES" "lustre/lustre/kernel_patches" ; do
615         [ "$patchesdir" ] && \
616             cp -v $patchesdir/kernel_configs/kernel-${VERSION}-${TARGET}*.config linux/configs/ >/dev/null && copysuccess=1
617     done
618     [ "$copysuccess" = "1" ] || \
619         fatal 1 "Error copying in kernel configs."
620 }
621
622 pack_linux()
623 {
624     TARBALL="$(readlink linux)-$EXTRA_VERSION.tar.gz"
625     echo "Creating patched linux tarball $TARBALL..."
626     tar zcf "$TARBALL" "$(readlink linux)" \
627         --exclude "CVS" --exclude ".cvsignore" || \
628         --exclude "*.orig" --exclude "*~" --exclude "*.rej" || \
629         fatal 1 "Error creating patched Linux tarball."
630 }
631
632 clean_linux()
633 {
634     [ -d linux ] || return 0
635     echo "Cleaning linux..."
636     [ -L linux ] && rm -rf $(readlink linux)
637     rm -rf linux
638 }
639
640 prep_kernel_build()
641 {
642     # make .spec file
643     ENABLE_INIT_SCRIPTS=""
644     sed \
645         -e "s^@BASE_ARCHS@^$BASE_ARCHS^g" \
646         -e "s^@BIGMEM_ARCHS@^$BIGMEM_ARCHS^g" \
647         -e "s^@BIGSMP_ARCHS@^$BIGSMP_ARCHS^g" \
648         -e "s^@BOOT_ARCHS@^$BOOT_ARCHS^g" \
649         -e "s^@CONFIGURE_FLAGS@^$CONFIGURE_FLAGS^g" \
650         -e "s^@ENABLE_INIT_SCRIPTS@^$ENABLE_INIT_SCRIPTS^g" \
651         -e "s^@JENSEN_ARCHS@^$BOOT_ARCHS^g" \
652         -e "s^@KERNEL_EXTRA_VERSION@^$EXTRA_VERSION^g" \
653         -e "s^@KERNEL_EXTRA_VERSION_DELIMITER@^$EXTRA_VERSION_DELIMITER^g" \
654         -e "s^@KERNEL_TARGET_DELIMITER@^$TARGET_DELIMITER^g" \
655         -e "s^@KERNEL_RELEASE@^${EXTRA_VERSION//-/_}^g" \
656         -e "s^@KERNEL_SOURCE@^$KERNEL^g" \
657         -e "s^@KERNEL_VERSION@^$VERSION^g" \
658         -e "s^@LINUX26@^$LINUX26^g" \
659         -e "s^@LUSTRE_SOURCE@^${LUSTRE##*/}^g" \
660         -e "s^@LUSTRE_TARGET@^$TARGET^g" \
661         -e "s^@PSERIES64_ARCHS@^$PSERIES64_ARCHS^g" \
662         -e "s^@RHBUILD@^$RHBUILD^g" \
663         -e "s^@SMP_ARCHS@^$SMP_ARCHS^g" \
664         -e "s^@SUSEBUILD@^$SUSEBUILD^g" \
665         -e "s^@UP_ARCHS@^$UP_ARCHS^g" \
666         < $TOPDIR/lustre/build/lustre-kernel-2.4.spec.in \
667         > lustre-kernel-2.4.spec
668     [ -d SRPMS ] || mkdir SRPMS
669     [ -d RPMS ] || mkdir RPMS
670     [ -d BUILD ] || mkdir BUILD
671     [ -d SOURCES ] || mkdir SOURCES
672     for script in linux-{rhconfig.h,merge-config.awk,merge-modules.awk} \
673         suse-{functions.sh,post.sh,postun.sh,trigger-script.sh.in} \
674         sles8-{pre,post,postun,update_{INITRD_MODULES,rcfile_setting}}.sh ; do
675         cp $TOPDIR/lustre/build/$script SOURCES
676     done
677     cp "$LUSTRE" "$KERNEL_FILE" SOURCES
678     if [ "$EXTERNAL_PATCHES" -a -d "$EXTERNAL_PATCHES" ] ; then
679         tar zcf SOURCES/external-patches.tar.gz -C "$EXTERNAL_PATCHES" series targets patches kernel_configs
680     else
681         touch SOURCES/external-patches.tar.gz
682     fi
683 }
684
685 clean_lustre()
686 {
687     [ -d lustre ] || return 0
688     echo "Cleaning Lustre..."
689     [ -L lustre ] && rm -rf $(readlink lustre)
690     rm -rf lustre
691 }
692
693 build_kernel()
694 {
695     echo "Building kernel + Lustre RPMs for: $BUILD_ARCHS..."
696     targets=
697     for arch in $BUILD_ARCHS ; do
698         targets="--target $arch $targets"
699     done
700
701     local rpmbuildopt='-bb'
702 #    if $NORPM; then
703 #        rpmbuildopt='-bc'
704 #        echo NORPM mode. Only compiling.
705 #        echo "XXX: need to fix lmake - add options to do rpmbuild -bc instead of -bb"
706 #    fi
707
708     $RPMBUILD $targets $rpmbuildopt lustre-kernel-2.4.spec \
709         --define "_tmppath $TMPDIR" \
710         --define "_topdir $TOPDIR" || \
711         fatal 1 "Error building rpms for $BUILD_ARCHS."
712
713     if (( $DO_SRC )) ; then
714         $RPMBUILD -bs lustre-kernel-2.4.spec \
715             --define "_tmppath $TMPDIR" \
716             --define "_topdir $TOPDIR" || \
717             fatal 1 "Error building .src.rpm."
718     fi
719
720     ( $(skeep_ldiskfs_rpm $TAG) ) && return
721
722     pushd $TOPDIR/BUILD/lustre*/ldiskfs || return 255
723     make dist
724     if [ "$?" != "0" ] ; then
725         popd
726         return 255
727     fi
728     cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
729
730     gen_lustre_version
731
732     local ldiskfs_spec=lustre-ldiskfs.spec
733     [ -f "$ldiskfs_spec" ] && sed \
734     -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
735     < $ldiskfs_spec \
736     > ../lustre-ldiskfs.spec
737
738     $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
739         --define "_tmppath /var/tmp" \
740         --define "_topdir $TOPDIR"
741     if [ "$?" != "0" ] ; then
742         popd
743         return 255
744     fi
745
746     if (( $DO_SRC )) ; then
747             $RPMBUILD -bs ../lustre-ldiskfs.spec \
748             --define "_tmppath /var/tmp" \
749             --define "_topdir $TOPDIR"
750         if [ "$?" != "0" ] ; then
751             popd
752             return 255
753         fi
754     fi
755     popd
756 }
757
758 build_lustre()
759 {
760     [ -d SRPMS ] || mkdir SRPMS
761     [ -d RPMS ] || mkdir RPMS
762     [ -d BUILD ] || mkdir BUILD
763     [ -d SOURCES ] || mkdir SOURCES
764
765     cp "$LUSTRE" SOURCES
766
767     pushd lustre >/dev/null
768
769     echo "Building Lustre RPMs for: $BUILD_ARCHS..."
770     targets=
771     for arch in $BUILD_ARCHS ; do
772         targets="--target $arch $targets"
773     done
774
775     local confoptions="--with-linux=${LINUX}"
776     if $PATCHLESS; then
777         confoptions="--with-linux=${LINUX} --disable-server"
778     fi
779     if [ ! "$LINUXOBJ" = "" ]; then
780         confoptions="$confoptions --with-linux-obj=${LINUXOBJ}" 
781     fi
782     
783     ./configure $confoptions ${CONFIGURE_FLAGS}
784     if [ "$?" != "0" ] ; then
785         local saved_config="../config.log.$(date +%s)"
786         cp config.log $saved_config
787         chmod a+r $saved_config
788         echo "Saved config.log is at $saved_config"
789         popd
790         return 255
791     fi
792
793     gen_lustre_version
794
795     # hack. Somebody move build/lustre.spec to lustre.spec for b1_6
796     local lustre_spec=
797     [ -f lustre.spec ] && lustre_spec=lustre.spec
798     [ -f build/lustre.spec ] && lustre_spec=build/lustre.spec
799
800     [ -f "$lustre_spec" ] && sed \
801         -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
802         < $lustre_spec \
803         > ../lustre.spec
804
805     local rpmbuildopt='-bb'
806     if $NORPM; then
807         rpmbuildopt='-bc'
808         echo NORPM mode. Only compiling.
809     fi
810
811     $RPMBUILD $targets $rpmbuildopt ../lustre.spec \
812         --define "_tmppath $TMPDIR" \
813         --define "_topdir $TOPDIR" || \
814         fatal 1 "Error building rpms for $BUILD_ARCHS."
815
816     popd >/dev/null
817     ( $(skeep_ldiskfs_rpm $TAG) ) && return
818
819     pushd lustre/ldiskfs || return 255
820     make dist
821     if [ "$?" != "0" ] ; then
822         popd
823         return 255
824     fi
825     cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
826
827     gen_lustre_version
828
829     local ldiskfs_spec=lustre-ldiskfs.spec
830     [ -f "$ldiskfs_spec" ] && sed \
831     -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
832     < $ldiskfs_spec \
833     > ../lustre-ldiskfs.spec
834
835     $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
836         --define "_tmppath /var/tmp" \
837         --define "_topdir $TOPDIR"
838     if [ "$?" != "0" ] ; then
839         popd
840         return 255
841     fi
842
843     if (( $DO_SRC )) ; then
844             $RPMBUILD -bs ../lustre-ldiskfs.spec \
845             --define "_tmppath /var/tmp" \
846             --define "_topdir $TOPDIR"
847         if [ "$?" != "0" ] ; then
848             popd
849             return 255
850         fi
851     fi
852     popd
853 }
854
855 stage()
856 {
857     [ "$STAGEDIR" ] || return 0
858
859     for arch in $BUILD_ARCHS ; do
860         rpmdir="${STAGEDIR}/${CANONICAL_TARGET}-${arch}"
861         echo "${0##*/}: Copying RPMs into ${rpmdir}"
862         mkdir -p "${rpmdir}"
863         cp -v RPMS/${arch}/*.rpm "${rpmdir}"
864         if [ -d RPMS/noarch ] ; then
865             cp -v RPMS/noarch/*.rpm "${rpmdir}"
866         fi
867     done
868
869     cp -v "$LUSTRE" "$STAGEDIR"
870 }
871
872 #check if we need to build separate ldiskfs RPM
873 skeep_ldiskfs_rpm()
874 {
875         local tag=$1
876         local skip=false
877         if ! $LDISKFSRPM; then
878             skip=true
879         elif $PATCHLESS; then
880             skip=true
881         else
882             for skiptag in $SKIPLDISKFSRPM; do
883                 [[ $tag == $skiptag ]] && skip=true && break
884             done
885         fi
886         echo $skip
887 }
888
889 #get date of last changed target/config/series/patches
890 get_last_source_date()
891 {
892     local filelist="${TOPDIR}/lustre/lustre/kernel_patches/series/${SERIES} \
893         $CONFIG_FILE"
894     local TOPDIRnew=$(echo ${TOPDIR} | sed -e s/\\//\\\\\\//g)
895     filelist="$filelist $( \
896         cat ${TOPDIR}/lustre/lustre/kernel_patches/series/${SERIES} | \
897         sed -e s/^/${TOPDIRnew}\\/lustre\\/lustre\\/kernel_patches\\/patches\\// 2>&1)"
898     local sourcelastdate=$( find ${filelist} -name CVS -prune -o \
899                 -type f -printf "%T@\n" 2>&1 | sort | tail -1 )
900     is_integer $sourcelastdate && echo $sourcelastdate
901 }
902
903 #check if variable is integer
904 is_integer()
905 {
906     local invariable=$1
907     [ "$invariable" = "" ] && return 255
908     local invariableint=$( echo $invariable | sed -e s/[^0-9]//g )
909     [ "$invariable" = "$invariableint" ] || return 255
910 }
911
912 #generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
913 gen_lustre_version()
914 {
915     local smptype=smp
916     [ "$KERNCONFSMPTYPE" = "" ] || smptype=$KERNCONFSMPTYPE
917     [ "$RPMSMPTYPE" = "" ] || smptype=$RPMSMPTYPE
918
919     LUSTRE_EXTRA_VERSION="${lnxmaj}-${EXTRA_VERSION}"
920     if [ "$PATCHLESS" = "true" -a  "$DISTRO" = "sles10" ]; then
921         LUSTRE_EXTRA_VERSION="${LUSTRE_EXTRA_VERSION}-${smptype}"
922     else
923         LUSTRE_EXTRA_VERSION="${LUSTRE_EXTRA_VERSION}${smptype}"
924     fi
925     LUSTRE_EXTRA_VERSION=$( echo $LUSTRE_EXTRA_VERSION | sed -e "s^-^_^g" )
926 }
927
928 #store RPMs and/or BUILD dir for future reuse
929 store_for_reuse()
930 {
931     local rpmonly=$1
932     if [ ! "$REUSEBUILD" = "" ] && [ -d  "/$REUSEBUILD/" ] ; then
933         [ -d "${REUSEBUILD}/${TIMESTAMP}" ] || mkdir "${REUSEBUILD}/${TIMESTAMP}"
934         [ -d "${REUSEBUILD}/${TIMESTAMP}" ] || return 255
935     else
936         return 255
937     fi
938
939     local lnxrelnew=$( echo ${lnxrel} | sed s/-/_/g )
940         local EXTRA_VERSIONnew=$( echo ${EXTRA_VERSION} | sed s/-/_/g )
941         local KERNELRPMnew=$(basename "$KERNELRPM")
942     if [ ! "$rpmonly" = "rpmonly" ]; then
943             local builddir=
944         if [ ! "$KERNELCOMPILEDIR" = "" ]; then
945             builddir="$KERNELCOMPILEDIR"
946         else
947             builddir="BUILD/lustre-kernel-${lnxmaj}/lustre/linux-${lnxmaj}"
948                 [ "$KERNELCOMPILEDIR" = "" ] || builddir="$KERNELCOMPILEDIR"
949             [ -d "$builddir" ] || builddir="BUILD/lustre-kernel-${lnxmaj}/lustre/linux-${lnxmaj}.${lnxrel}"
950             [ -d "$builddir" ] || builddir="BUILD/lustre-kernel-${lnxmaj}/lustre/linux-${lnxmaj}-${lnxrel}"
951                 if [ ! -d "$builddir" ]; then
952                 pushd "BUILD/lustre-kernel-${lnxmaj}/lustre/" || return 255
953                 local basebuilddir=$(ls -d linux-${lnxmaj}* | head -1)
954                 [ "$basebuilddir" = "" ] || builddir="BUILD/lustre-kernel-${lnxmaj}/lustre/${basebuilddir}"
955                 popd
956                 fi
957         fi
958         [ -d "$builddir" ] || return 255
959             local dstdir="${REUSEBUILD}/${TIMESTAMP}/linux-${KERNCONFSMPTYPE}-${lnxmaj}-${EXTRA_VERSIONnew}.${TARGET_ARCH}"
960             ( $PATCHLESS ) && dstdir="${REUSEBUILD}/${TIMESTAMP}/linux-$KERNELRPMnew" && \
961                     dstdir="${dstdir%.rpm}"
962             [ -d "$dstdir" ] && rm -rf "$dstdir"
963         mv "${builddir}" "$dstdir" || return 255
964     fi
965     #store kernel rpm
966     local kernelrpmname="kernel-lustre-${KERNCONFSMPTYPE}-${lnxmaj}-${EXTRA_VERSIONnew}.${TARGET_ARCH}.rpm"
967     [ -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" ] || kernelrpmname="kernel-${KERNCONFSMPTYPE}-${lnxmaj}-${EXTRA_VERSNnew}.${TARGET_ARCH}.rpm"
968         ( $PATCHLESS ) && [ -f "$KERNELRPM" ] && kernelrpmname="$KERNELRPMnew"
969     if [ "$rpmonly" = "rpmonly" ] && [ -f "${REUSEBUILD}/${TIMESTAMP}/${kernelrpmname}" ]; then
970         echo "RPM already exist in store directory tree"
971     else
972         [ -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" ] && cp -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" "${REUSEBUILD}/${TIMESTAMP}/"
973     fi
974     #store kernel source rpm
975     kernelrpmname="kernel-lustre-source-${lnxmaj}-${EXTRA_VERSIONnew}.${TARGET_ARCH}.rpm"
976     [ -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" ] || kernelrpmname="kernel-source-${lnxmaj}-${EXTRA_VERSIONnew}.${TARGET_ARCH}.rpm"
977     ( $PATCHLESS ) && [ -f "$KERNELSOURCERPM" ] && kernelrpmname=$(basename "$KERNELSOURCERPM")
978     if [ "$rpmonly" = "rpmonly" ] && [ -f "${REUSEBUILD}/${TIMESTAMP}/${kernelrpmname}" ]; then
979         echo "RPM already exist in store directory tree"
980     else
981             [ -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" ] && cp -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" "${REUSEBUILD}/${TIMESTAMP}/"
982     fi
983 }
984
985 set_rpm_smp_type()
986 {
987     RPMSMPTYPE=default
988     for smp_type in $SMP_ARCHS; do
989         [ $TARGET_ARCH == $smp_type ] && RPMSMPTYPE=smp && break
990     done
991
992     for smp_type in $BIGSMP_ARCHS; do
993         [ $TARGET_ARCH == $smp_type ] && RPMSMPTYPE=bigsmp && break
994     done
995 }
996
997 #unpack kernel(/source/devel) RPM
998 unpack_linux_rpm()
999 {
1000     local prefix=$1
1001     local delimiter=${2:-"-"}
1002     local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
1003     local kernelbinaryrpm=
1004     [ -d $pathtorpms ] || return 255
1005     local rpmfile=
1006     local wanted_kernel="${lnxmaj}${delimiter}${lnxrel}"
1007     for arch in $TARGET_ARCHS_ALL; do
1008         for rpm in ${pathtorpms}/${arch}/*.rpm; do
1009             local provides=$(rpm -q --provides -p $rpm)
1010             if (echo $provides | grep -q "kernel${prefix} = $wanted_kernel"); then
1011                 KERNELRPM=$rpm
1012             fi
1013         done
1014         [ -f "$KERNELRPM" ] && TARGET_ARCH="$arch" && BUILD_ARCHS="$arch" && break
1015     done
1016
1017     # bleah
1018     set_rpm_smp_type
1019
1020     [ -f "$KERNELRPM" ] || return 255
1021     [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused
1022     pushd $TOPDIR/reused || return 255
1023     RC=0
1024     rpm2cpio < "$KERNELRPM" | cpio -idc > /dev/null 2>&1
1025     if [ ${PIPESTATUS[0]} -eq 0 ]; then
1026         # RHEL-style and SLES-style rpms
1027         local paths="kernels/${lnxmaj}${delimiter}${lnxrel}-${TARGET_ARCH} linux-${lnxmaj}${delimiter}${lnxrel}"
1028
1029         for path in $paths; do
1030             local src='usr/src'
1031
1032             if [ -d "$src/$path/" ]; then
1033                 LINUX="$(pwd)/$src/$path"
1034             fi
1035             # SLES has a separate -obj tree
1036             if [ -d "$src/${path}-obj" ]; then
1037                 src="$src/${path}-obj"
1038                 local objects="$TARGET_ARCH/$RPMSMPTYPE"
1039
1040                 # Novell, are you *TRYING* to make life hard for me?
1041                 if [ -d "$src/powerpc" ]; then
1042                     objects="powerpc/$TARGET_ARCH"
1043                 elif [ $TARGET_ARCH == 'i686' ]; then
1044                     objects="i386/$RPMSMPTYPE"
1045                 fi
1046
1047                 LINUXOBJ="$(pwd)/$src/$objects"
1048             fi
1049         done
1050         if [ -z "$LINUX" ]; then
1051             RC=255
1052         else
1053             # dig out the release version
1054             local LINUXRELEASEHEADER=version.h
1055             if test -s ${LINUXOBJ:-$LINUX}/include/linux/utsrelease.h ; then
1056                 LINUXRELEASEHEADER=utsrelease.h
1057             fi
1058             LINUXRELEASE=$(sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' ${LINUXOBJ:-$LINUX}/include/linux/$LINUXRELEASEHEADER)
1059             if [ -z "$LINUXRELEASE" ]; then
1060                 echo "Failed to find linux release in ${LINUXOBJ:-$LINUX}/include/linux/$LINUXRELEASEHEADER"
1061                 RC=255
1062             fi
1063         fi
1064     else
1065         RC=255
1066     fi
1067     popd
1068     return $RC
1069 }
1070
1071 #look for kernel source RPM
1072 find_linux_source_rpm()
1073 {
1074     local rpmfile=
1075     local findarch=true
1076     local arch=
1077     local pathtorpms=
1078     [ ! "$TARGET_ARCH" = "" ] && arch=$TARGET_ARCH && findarch=false
1079     
1080     if ! $findarch; then
1081         pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}/${arch}"
1082         [ -d $pathtorpms ] || return 255
1083         case "$DISTRO" in
1084             rhel4)
1085                 rpmfile="kernel-${lnxmaj}-${lnxrel}.src.rpm"
1086             ;;
1087             sles10)
1088                 rpmfile="kernel-source-${lnxmaj}.${lnxrel}.${arch}.rpm"
1089             ;;
1090             *)
1091                 rpmfile="kernel-source-${lnxmaj}-${lnxrel}.${arch}.rpm"
1092             ;;
1093         esac
1094         [ -f "${pathtorpms}/${rpmfile}" ] || return 255
1095         KERNELSOURCERPM="${pathtorpms}/${rpmfile}"
1096     else
1097         for arch in $TARGET_ARCHS_ALL; do
1098         pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}/${arch}"
1099         [ -d $pathtorpms ] || continue
1100         case "$DISTRO" in
1101             rhel4)
1102                 rpmfile="kernel-${lnxmaj}-${lnxrel}.src.rpm"
1103             ;;
1104             sles10)
1105                 rpmfile="kernel-source-${lnxmaj}.${lnxrel}.${arch}.rpm"
1106             ;;
1107             *)
1108                 rpmfile="kernel-source-${lnxmaj}-${lnxrel}.${arch}.rpm"
1109             ;;
1110         esac
1111         [ -f "${pathtorpms}/${rpmfile}" ] || continue
1112         KERNELSOURCERPM="${pathtorpms}/${rpmfile}"
1113         TARGET_ARCH=${arch}
1114         break
1115         done
1116     fi
1117     [ -f "${KERNELSOURCERPM}" ] || return 255
1118 }
1119
1120 #unpack and make symlinks for reusing kernel RPM
1121 reuse_kernel_rpm()
1122 {
1123     local pathtorpm=$1
1124     [ "$pathtorpm" = "" ] && return 255
1125     [ -f "$pathtorpm" ] || return 255
1126     [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused
1127     pushd $TOPDIR/reused || return 255
1128
1129     rpm2cpio < $pathtorpm | cpio -idc
1130     [ ${PIPESTATUS[0]} -eq 0 ] || return 255
1131
1132     local smptype=
1133     if pushd usr/src/linux-*-obj/${TARGET_ARCH}; then
1134         local smptypes="$SMPTYPES"
1135         [ "$RPMSMPTYPE" = "" ] || smptypes=$RPMSMPTYPE
1136         ( ! $PATCHLESS ) && [ ! "$KERNCONFSMPTYPE" = "" ] && smptypes="$KERNCONFSMPTYPE"
1137         local cursmptype=
1138         for cursmptype in $smptypes; do
1139             [ "$cursmptype" = "''" ] && continue
1140             [ -d $cursmptype ] && smptype=$cursmptype
1141             [ -d $smptype ] && break
1142         done
1143         popd
1144     fi
1145     if [ "${smptype}" = "" ]; then
1146         popd
1147         return 255 # cannot detect smp type
1148     fi
1149     if pushd usr/src/linux-*-obj/${TARGET_ARCH}/$smptype/include2; then
1150         local base=$(readlink asm)
1151         if [ ! -d "/${base}/" ]; then
1152             rm -f asm
1153             base=$(basename "$base")
1154             if pushd ../../../../linux-*/include; then
1155                 local lsrc=$(pwd)
1156                 popd
1157                 [ -d "$lsrc/${base}" ] && ln -s $lsrc/${base} asm
1158             fi
1159         fi
1160         popd
1161         read a b < <(echo $(pwd)/usr/src/linux-*)
1162         if [[ $a == $(pwd)/* && $b = $(pwd)/* ]]; then
1163             cp -f $a/include/linux/config.h $b/${TARGET_ARCH}/$smptype/include/linux/
1164             cp $b/${TARGET_ARCH}/$smptype/.config $a/
1165             [ -f "$b/${TARGET_ARCH}/$smptype/.config" ] && KERNELRPMCONFIG="$b/${TARGET_ARCH}/$smptype/.config"
1166             cp $b/${TARGET_ARCH}/$smptype/.kernelrelease $a/
1167             [ -f "$b/${TARGET_ARCH}/$smptype/.kernelrelease" ] && KERNELRPMRELEASE="$b/${TARGET_ARCH}/$smptype/.kernelrelease"
1168             LINUX=$a
1169             LINUXOBJ=$b/${TARGET_ARCH}/$smptype
1170 #            local fname=$(basename $kernel_rpm)
1171 #            KERNELRPMSDIR=${kernel_rpm%$fname}
1172         fi
1173     fi
1174     popd
1175     [ "$LINUX" = "" ] && return 255
1176     [ -d "$LINUX" ] || return 255
1177 }
1178
1179 #build linux kernel rpm
1180 build_linux_rpm()
1181 {
1182     pushd $LINUX || return 255
1183     make binrpm-pkg || ( popd ; return 255 )
1184     local addlnxrel=
1185     [ -f ".version" ] && addlnxrel="-$(cat .version)"
1186     popd
1187     local arch=
1188     for arch in $TARGET_ARCHS_ALL; do
1189         [ -f "/usr/src/rpm/RPMS/$arch/kernel-$lnxmaj.${lnxrel}${addlnxrel}.$arch.rpm" ] && \
1190             KERNELRPM="/usr/src/rpm/RPMS/$arch/kernel-$lnxmaj.${lnxrel}${addlnxrel}.$arch.rpm" && \
1191             TARGET_ARCH="$arch"
1192         [ -f "/usr/src/packages/RPMS/$arch/kernel-$lnxmaj.${lnxrel}${addlnxrel}.$arch.rpm" ] && \
1193             KERNELRPM="/usr/src/packages/RPMS/$arch/kernel-$lnxmaj.${lnxrel}${addlnxrel}.$arch.rpm" && \
1194             TARGET_ARCH="$arch"
1195     done
1196     [ "$KERNELRPM" = "" ] || return
1197     return 255
1198 }
1199
1200 #build linux kernel
1201 build_linux()
1202 {
1203     local nofullmake=$1
1204     local nocopykernel=$2
1205     pushd $LINUX || fatal 1 "Kernel source not found"
1206     [ "$nofullmake" = "nofullmake" ] || make mrproper
1207     [ "$nofullmake" = "nofullmake" ] || rm -f rpm-release
1208 #    [ "$nocopykernel" = "copyrpmkernel" ] || rm -f localversion-*
1209     [ "$nocopykernel" = "copykernel" ] && [ -f "$CONFIG_FILE" ] && cp $CONFIG_FILE .config
1210     if [ "$nocopykernel" = "copyrpmkernel" ]; then
1211         [ -f "$KERNELRPMCONFIG" ] && cp $KERNELRPMCONFIG .config
1212         if [ -f "$KERNELRPMRELEASE" ]; then
1213             cp $KERNELRPMRELEASE .
1214         else
1215             sed -e "s/^EXTRAVERSION\s\+=\s\+.*$/EXTRAVERSION = -${lnxrel}/" < Makefile > Makefile.new
1216             [ -f "Makefile.new" ] && mv Makefile.new Makefile
1217         fi
1218     fi
1219     [ -f ".config" ] || ( popd ; echo "Cannot find .config file"; return 255 )
1220     make oldconfig || ( popd ; return 255 )
1221     make include/linux/version.h
1222     if [ ! "$nofullmake" = "nofullmake" ]; then
1223         make || ( popd ; return 255 )
1224     fi
1225     popd
1226     return
1227 }
1228
1229 build_kernel_ib()
1230 {
1231     # build kernel-ib{,-devel}
1232     # some I/B drivers are architecture dependent and kernel-ib's configure
1233     # does not figure it out for us ~sigh~
1234     local configure_options=""
1235     case "$TARGET_ARCH" in
1236         x86_64 | ia64)
1237             configure_options="--with-ipath_inf-mod"
1238             ;;
1239         ppc64)
1240             configure_options="--with-ipath_inf-mod --with-ehca-mod"
1241             ;;
1242     esac
1243     $RPMBUILD --rebuild --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
1244               --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
1245               --define "KVERSION ${LINUXRELEASE}" \
1246               --define "KSRC ${LINUXOBJ:-${LINUX}}" \
1247               --define "LIB_MOD_DIR /lib/modules/${LINUXRELEASE}/updates" \
1248               --define "configure_options --without-quilt --with-core-mod --with-user_mad-mod --with-user_access-mod --with-addr_trans-mod --with-srp-target-mod --with-core-mod --with-mthca-mod --with-mlx4-mod --with-cxgb3-mod --with-nes-mod --with-ipoib-mod --with-sdp-mod --with-srp-mod --without-srp-target-mod --with-rds-mod --with-iser-mod --with-qlgc_vnic-mod --with-madeye-mod $configure_options" ${TOPDIR}/OFED/SRPMS/ofa_kernel-${OFED_VERSION}-ofed${OFED_VERSION}.src.rpm
1249
1250     if [ ${PIPESTATUS[0]} != 0 ]; then
1251         fatal 1 "Error building kernel-ib"
1252     fi
1253
1254     pushd "$TOPDIR" >/dev/null
1255     rm -rf kernel-ib-devel
1256     mkdir kernel-ib-devel
1257     cd kernel-ib-devel
1258     local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${OFED_VERSION}-${LINUXRELEASE//-/_}.*.rpm)
1259     rpm2cpio -itv < $rpm | cpio -id
1260     CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
1261     popd >/dev/null
1262 }
1263
1264 #build patchless lustre
1265 patchless_build_sequence()
1266 {
1267     #try to build from kernel-devel RPM (RHEL)
1268     LINUX=
1269     TARGET_ARCH=
1270     local rpmfound=false
1271     local buildsuccess=false
1272     local storeforreuse=false
1273     if [ "$KERNELRPMSBASE" = "" ] || [ ! -d "$KERNELRPMSBASE" ]; then
1274         return 255
1275     fi
1276     [ -d $TOPDIR/reused ] && rm -rf $TOPDIR/reused
1277
1278     local delimiter=${EXTRA_VERSION_DELIMITER:-"-"}
1279     # default to source type -source and special case below
1280     local type=-source
1281     case "$DISTRO" in
1282         rhel*)
1283             type=-devel
1284             ;;
1285     esac
1286
1287     unpack_linux_rpm $type $delimiter && rpmfound=true
1288
1289     [ -d SRPMS ] || mkdir SRPMS
1290     [ -d RPMS ] || mkdir RPMS
1291     [ -d BUILD ] || mkdir BUILD
1292     [ -d SOURCES ] || mkdir SOURCES
1293
1294     # first build kernel-ib
1295     if [ -n "$OFED_VERSION" ]; then
1296         $rpmfound && build_kernel_ib
1297     fi
1298     ( $rpmfound ) && build_lustre && buildsuccess=true && find_linux_source_rpm
1299
1300     if $buildsuccess; then
1301         [ -d "RPMS/${TARGET_ARCH}" ] && [ -f "$KERNELRPM" ] && \
1302             cp "$KERNELRPM" RPMS/${TARGET_ARCH}/
1303         [ -d "RPMS/${TARGET_ARCH}" ] && [ -f "$KERNELSOURCERPM" ] && \
1304             cp "$KERNELSOURCERPM" RPMS/${TARGET_ARCH}/
1305         KERNELCOMPILEDIR="$LINUX"
1306         if $storeforreuse; then
1307             store_for_reuse || echo "Cannot store for feature reuse"
1308         fi
1309
1310         return
1311     elif ! $rpmfound; then
1312         echo "COULD NOT FIND VENDOR -devel or -source RPM for $DISTRO/$TARGET_ARCH: $lnxmaj-$lnxrel in $KERNELRPMSBASE"
1313         return 255
1314     else
1315         echo "Patchless build failed."
1316         return 255
1317     fi
1318 }
1319
1320 #check timestamp value. should bi 14-digits string
1321 check_timestamp()
1322 {
1323     local invalue=$1
1324     local timestampnodig=$(echo $invalue | sed -e s/[0-9]*//g)
1325     [ "$timestampnodig" = "" ] || return 255
1326     local timestamplength="${#invalue}"
1327     [ $timestamplength -eq 14 ] || return 255
1328 }
1329
1330 # get list of suitable directories with potential reused staff
1331 get_reuse_dir_list()
1332 {
1333     local rpmonly=$1
1334     local reusedkernelmasknew=$2
1335     local buildtimestamp=
1336     local dirsforreuse=
1337     local sourcelastdate=$(get_last_source_date)
1338     for buildtimestamp in $(ls "$REUSEBUILD/" 2>&1); do
1339         [ -d "$REUSEBUILD/$buildtimestamp" ] || continue
1340         check_timestamp "$buildtimestamp" || continue
1341         local buildtimestampstr=$(echo $buildtimestamp | \
1342             sed -e "s^\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)^\1-\2-\3 \4:\5:\6 GMT^g")
1343         local buildtimestampepoch=$(date --date="$buildtimestampstr"  +%s )
1344         #check for suitable date
1345             if ! $PATCHLESS; then
1346             [ $buildtimestampepoch -ge $sourcelastdate ] || continue
1347             fi
1348         #check for suitable version
1349         if [ "$rpmonly" = "rpmonly" ]; then
1350             local reusedkernelprefix="kernel-lustre-"
1351             ( $PATCHLESS ) && reusedkernelprefix=
1352             local rpmmask="${reusedkernelprefix}${REUSEDKERNELMASK}"
1353             [ "$reusedkernelmasknew" = "" ] || rpmmask="$reusedkernelmasknew"
1354             [ -f $REUSEBUILD/$buildtimestamp/${rpmmask}.rpm ] && \
1355                 dirsforreuse="$dirsforreuse $REUSEBUILD/$buildtimestamp"
1356         else
1357             local rpmmask="$REUSEDKERNELMASK"
1358             [ "$reusedkernelmasknew" = "" ] || rpmmask="$reusedkernelmasknew"
1359             pushd $REUSEBUILD/$buildtimestamp/linux-${rpmmask} > /dev/null 2>&1 || continue
1360             local curdir=$(pwd)
1361             dirsforreuse="$dirsforreuse $curdir"
1362             popd
1363         fi
1364     done
1365     echo "$dirsforreuse"
1366 }
1367
1368 #try to reuse old RPM
1369 build_sequence_rpm_reuse()
1370 {
1371     local sourcerpm=$1
1372     [ "$REUSERPM" = "" ] && [ "$REUSEBUILD" = "" ] && return 255
1373     local dirsforreuse=
1374     if ! [ "$REUSEBUILD" = "" ] && [ -d "$REUSEBUILD" ]; then #try to reuse RPM
1375         local REUSEDKERNELMASKnew=$(echo $REUSEDKERNELMASK | sed -e "s/^[^0-9]*//")
1376         REUSEDKERNELMASKnew="kernel-lustre-source-${REUSEDKERNELMASKnew}"
1377         local dirsforreuse="$(get_reuse_dir_list rpmonly $REUSEDKERNELMASKnew)"
1378         local buildsuccess=false
1379         LINUXOBJ=
1380         for curdir in $(echo $dirsforreuse); do
1381             [ -d "$curdir" ] || continue
1382             local reusedkernelprefix="kernel-lustre-"
1383             local reusedkernelrpm=
1384             [ -f ${curdir}/${reusedkernelprefix}${REUSEDKERNELMASK}.rpm ] && \
1385                 reusedkernelrpm=$(ls ${curdir}/${reusedkernelprefix}${REUSEDKERNELMASK}.rpm | head -1 )
1386             [ -f "$reusedkernelrpm" ] || continue
1387
1388             local reusedkernelsourcerpm=
1389             [ -f ${curdir}/${REUSEDKERNELMASKnew}.rpm ] && \
1390                 reusedkernelsourcerpm=$(ls ${curdir}/${REUSEDKERNELMASKnew}.rpm | head -1 )
1391             [ -f "$reusedkernelsourcerpm" ] || continue
1392
1393             [ -d $TOPDIR/reused ] && rm -rf $TOPDIR/reused
1394             reuse_kernel_rpm "$reusedkernelsourcerpm" && build_linux nofullmake copyrpmkernel && build_lustre && buildsuccess=true
1395             ( $buildsuccess ) || continue
1396             if ( ! $NORPM ) && ( ! $PATCHLESS ) ; then
1397                 [ -f "$reusedkernelrpm" ] && \
1398                     cp -f  "$reusedkernelrpm"  RPMS/${TARGET_ARCH}/ > /dev/null 2>&1
1399  
1400                 [ -f "$reusedkernelsourcerpm" ] && \
1401                     cp -f  "$reusedkernelsourcerpm"  RPMS/${TARGET_ARCH}/ > /dev/null 2>&1 && \
1402                     touch RPMS/${TARGET_ARCH}/kernel_was_reused
1403             fi
1404             return
1405         done
1406     fi
1407     return 255
1408 }
1409
1410 #try to reuse old BUILD dir
1411 build_sequence_reuse()
1412 {
1413     local sourcerpm=$1
1414     [ "$REUSERPM" = "" ] && [ "$REUSEBUILD" = "" ] && return 255
1415     local dirsforreuse=
1416     if [ ! "$REUSEBUILD" = "" ] && [ -d "$REUSEBUILD" ]; then #try to reuse old kernel build directory
1417         local dirsforreuse="$(get_reuse_dir_list)"
1418         local buildsuccess=false
1419         LINUXOBJ=
1420         local REUSEDKERNELMASKnew=$(echo $REUSEDKERNELMASK | sed -e "s/^[^0-9]*//")
1421         for curdir in $(echo $dirsforreuse); do
1422             local reusedkernelrpm=
1423             local reusedkernelsourcerpm=
1424             [ -d "$curdir" ] || continue
1425             local reusedkernelprefix="kernel-lustre-"
1426             ( $PATCHLESS ) && reusedkernelprefix=
1427             [ -f ${curdir}/../${reusedkernelprefix}${REUSEDKERNELMASK}.rpm ] && \
1428                 reusedkernelrpm=$(ls ${curdir}/../${reusedkernelprefix}${REUSEDKERNELMASK}.rpm | head -1 )
1429             reusedkernelprefix="kernel-lustre-source-"
1430             [ -f ${curdir}/../${reusedkernelprefix}${REUSEDKERNELMASKnew}.rpm ] && \
1431                 reusedkernelsourcerpm=$(ls ${curdir}/../${reusedkernelprefix}${REUSEDKERNELMASKnew}.rpm | head -1 ) 
1432             if ! ( $NORPM ) && ! [ -f "$reusedkernelrpm" ]; then #kernel rpm not found. Build all
1433                 continue
1434             fi
1435             if ! ( $NORPM ) && ! [ -f "$reusedkernelsourcerpm" ]; then #kernel source rpm not found. Build all
1436                 continue
1437             fi
1438             LINUX="$curdir"
1439             build_lustre || continue
1440             touch "$curdir/../"
1441             buildsuccess=true
1442             if ( ! $NORPM ) && ( ! $PATCHLESS ) ; then
1443                 [ -f "$reusedkernelrpm" ] && \
1444                     cp -f  "$reusedkernelrpm"  RPMS/${TARGET_ARCH}/ > /dev/null 2>&1 && \
1445                     touch RPMS/${TARGET_ARCH}/kernel_was_reused
1446                 [ -f "$reusedkernelsourcerpm" ] && \
1447                     cp -f  "$reusedkernelsourcerpm"  RPMS/${TARGET_ARCH}/ > /dev/null 2>&1
1448             fi
1449             return
1450         done
1451     fi
1452     return 255
1453 }
1454
1455
1456 build_sequence()
1457 {
1458     if (( $DO_SRC )) ; then
1459         unpack_linux
1460         patch_linux
1461         pack_linux
1462         clean_linux
1463     fi
1464     prep_kernel_build || return 255
1465     clean_lustre || return 255
1466
1467     build_kernel || return 255
1468 }
1469
1470 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
1471
1472 options=$(getopt -o d:D:h -l kerneltree:,distro:,kernelrpm:,reusebuild:,patchless,ldiskfs,ccache,reuse:,norpm,disable-datestamp,external-patches:,timestamp:,extraversion:,kerneldir:,linux:,lustre:,nodownload,nosrc,publish,release,src,stage:,tag:,target:,target-archs:,with-linux: -- "$@")
1473
1474 if [ $? != 0 ] ; then
1475     usage 1
1476 fi
1477
1478 eval set -- "$options"
1479     
1480 while [ "$1" ] ; do
1481     case "$1" in
1482         '')
1483             usage 1
1484             ;;
1485         --ccache)
1486             CCACHE='ccache'
1487             shift
1488             ;;
1489         -d)
1490             CVSROOT=$2
1491             shift 2
1492             ;;
1493         -D)
1494             DATE=$2
1495             shift 2
1496             ;;
1497         --external-patches)
1498             EXTERNAL_PATCHES=$2
1499             shift 2
1500             ;;
1501         --extraversion)
1502             EXTRA_VERSION=$2
1503             shift 2
1504             ;;
1505         --help | -h)
1506             usage 0
1507             ;;
1508         --kerneldir)
1509             KERNELDIR=$2
1510             shift 2
1511             ;;
1512         --kerneltree)
1513             KERNELTREE=$2
1514             shift 2
1515             ;;
1516         --linux | --with-linux)
1517             LINUX=$2
1518             shift 2
1519             ;;
1520         --distro)
1521             DISTRO=$2
1522             shift 2
1523             ;;
1524         --reuserpm)
1525             REUSERPM=$2
1526             shift 2
1527             ;;
1528         --reusebuild)
1529             REUSEBUILD=$2
1530             shift 2
1531             ;;
1532         --norpm)
1533             NORPM=true
1534             shift
1535             ;;
1536         --ldiskfs)
1537             LDISKFSRPM=true
1538             shift
1539             ;;
1540         --patchless)
1541             PATCHLESS=true
1542             shift
1543             ;;
1544         --kernelrpm)
1545             KERNELRPMSBASE=$2
1546             shift 2
1547             ;;
1548         --timestamp)
1549             TIMESTAMP=$2
1550             shift 2
1551             ;;
1552         --lustre)
1553             LUSTRE=$2
1554             shift 2
1555             ;;
1556         --nodownload)
1557             DOWNLOAD=0
1558             shift 1
1559             ;;
1560         --nosrc)
1561             DO_SRC=0
1562             shift 1
1563             ;;
1564         --publish)
1565             shift
1566             ;;
1567         --release)
1568             RELEASE=true
1569             shift
1570             ;;
1571         --src)
1572             DO_SRC=1
1573             shift 1
1574             ;;
1575         --stage)
1576             STAGEDIR=$2
1577             shift 2
1578             ;;
1579         --tag)
1580             TAG=$2
1581             shift 2
1582             ;;
1583         --target)
1584             TARGET=$2
1585             shift 2
1586             ;;
1587         --target-archs)
1588             TARGET_ARCHS=$2
1589             shift 2
1590             ;;
1591         --disable-datestamp)
1592             USE_DATESTAMP=
1593             shift
1594             ;;
1595         --)
1596             shift
1597             CONFIGURE_FLAGS=$@
1598             CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
1599             break
1600             ;; 
1601         *)
1602             usage 1 "Unrecognized option: $1"
1603             ;;
1604     esac
1605 done
1606
1607 check_options
1608
1609 unpack_lustre
1610
1611 load_target
1612 EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
1613
1614 if [ -n "$OFED_VERSION" ]; then
1615     unpack_ofed
1616 fi
1617
1618 build_success=false
1619 if $PATCHLESS; then
1620     patchless_build_sequence && build_success=true 
1621 elif [ -z "$LINUX" ] ; then
1622     [ "$DISTRO" = "sles9" ] && build_sequence_rpm_reuse && build_success=true
1623     if ! $build_success; then
1624         build_sequence_reuse && build_success=true
1625         if ! $build_success; then
1626             build_sequence && build_success=true
1627             if $build_success; then
1628                 store_for_reuse || echo "Cannot store for feature reuse"
1629             fi
1630         fi
1631     fi
1632 else
1633     build_lustre
1634 fi
1635 ( $build_success ) || fatal 1 "Cannot build lustre"
1636
1637 stage