Whamcloud - gitweb
b=13639
[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 ftp.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://ftp.lustre.org/kernels/$target/old/$srpm..."
381     if ! wget -nv "http://ftp.lustre.org/kernels/$target/old/$srpm" \
382         -O "$KERNELDIR/$srpm" ; then
383         fatal 1 "Could not download target $kernel_file's kernel SRPM $srpm from ftp.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://ftp.lustre.org/kernels/$CANONICAL_TARGET/old/$KERNEL..."
424                     if ! wget -nv "http://ftp.lustre.org/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     fi
434
435     if [ "$SERIES" ] ; then
436         for series in $SERIES ; do
437             for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches" ; do
438                 [ -r "$patchesdir/series/$series" ] && continue 2
439             done
440             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."
441         done
442     fi
443
444     if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config ]; then
445     CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config"
446     fi
447     local smptype
448     for smptype in $SMPTYPES; do
449         [ "$smptype" = "''" ] && smptype=
450         if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH-${smptype}.config ]; then
451         CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH-${smptype}.config"
452         KERNCONFSMPTYPE=$smptype
453     fi
454     done
455
456     local lnxrelnew=$( echo ${lnxrel} | sed s/-/_/g )
457
458     [ -f "$CONFIG_FILE" ] || \
459         fatal 1 "Config file for target $TARGET missing from $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
460     if [ "$EXTRA_VERSION_save" ] ; then
461         EXTRA_VERSION="$EXTRA_VERSION_save"
462     elif ! $RELEASE; then
463         # if there is no patch series, then this is not a lustre specific
464         # kernel.  don't make it look like one
465         if [ -n "$SERIES" ]; then
466             #remove the @VERSION@ (lustre version)
467 #            EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
468 #            EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
469             ! ( $PATCHLESS ) && EXTRA_VERSION="${EXTRA_VERSION}.${TIMESTAMP}"
470         fi
471     fi
472     # EXTRA_VERSION=${EXTRA_VERSION//-/_}
473
474     [ -z $REUSEDKERNELMASK ] && \
475         # create mask for kernel RPM/builddir which could be reused
476         if $NORPM; then
477             REUSEDKERNELMASK=${KERNCONFSMPTYPE}-${lnxmaj}-${lnxrelnew}_lustre.${LUSTRE_VERSION}.*${TARGET_ARCH}
478         elif $RELEASE; then
479             REUSEDKERNELMASK=${KERNCONFSMPTYPE}-${lnxmaj}-${lnxrelnew}_lustre.${LUSTRE_VERSION}.${TARGET_ARCH}
480         else
481             REUSEDKERNELMASK=${KERNCONFSMPTYPE}-${lnxmaj}-${lnxrelnew}_lustre.${LUSTRE_VERSION}.${TIMESTAMP}.${TARGET_ARCH}
482         fi
483         # kernel-lustre-smp-2.6.9-55.0.2.EL_lustre.1.6.1.i686.rpm 
484
485     ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $BIGSMP_ARCHS $PSERIES64_ARCHS $UP_ARCHS"
486
487     BUILD_ARCHS=
488     for arch in $(uniqify "$ALL_ARCHS") ; do
489         if [ -z "$TARGET_ARCHS" ] || echo "$TARGET_ARCHS" | grep "$arch" >/dev/null 2>/dev/null ; then
490             BUILD_ARCHS="$BUILD_ARCHS $arch"
491         fi
492     done
493     [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
494     echo "Building for: $BUILD_ARCHS"
495 }
496
497 tarflags()
498 {
499     case "$1" in
500         '')
501             fatal 1 "tarflags(): File name argument missing."
502             ;;
503         *.tar.gz | *.tgz)
504             echo 'zxf'
505             ;;
506         *.tar.bz2)
507             echo 'jxf'
508             ;;
509         *.tar)
510             echo 'xf'
511             ;;
512         *)
513             fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
514             ;;
515     esac
516 }
517
518 untar()
519 {
520     echo "Untarring ${1##*/}..."
521     tar $(tarflags "$1") "$1"
522 }
523
524 unpack_lustre()
525 {
526     DIRNAME="lustre-$TAG-$TIMESTAMP"
527     if [ "$LUSTRE" ] ; then
528         untar "$LUSTRE"
529         [ -d lustre ] || ln -sf lustre-[0-9].[0-9]* lustre
530     else
531         if [ "$USE_DATESTAMP" ]; then
532             DATESTAMP="-D '$DATE'"
533         else
534             DATESTAMP=""
535         fi            
536
537         cvs -d "$CVSROOT" -qz3 co $DATESTAMP -d "$DIRNAME" lustre || \
538             fatal 1 "There was an error checking out toplevel Lustre from CVS."
539         pushd "$DIRNAME" > /dev/null
540         ./lustrecvs "$TAG" || \
541             fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
542         echo "Creating lustre tarball..."
543         sh autogen.sh || fatal 1 "There was an error running autogen.sh."
544         ./configure --disable-{modules,utils,liblustre,tests,doc} || \
545             fatal 1 "There was an error running ./configure to create makefiles."
546         make dist || fatal 1 "There was an error running 'make dist'."
547         popd > /dev/null
548         fname=$(basename $DIRNAME/lustre-*.tar.gz)
549         cp $DIRNAME/$fname . || fatal 1 "There was an error copying lustre tarball."
550         LUSTRE="$PWD/$fname"
551         ln -sf "$DIRNAME" lustre
552     fi
553 }
554
555 unpack_linux()
556 {
557     untar "$KERNEL_FILE"
558     [ -d linux ] || ln -sf linux* linux
559 }
560
561 patch_linux()
562 {
563     [ "$SERIES" ] || return 0
564     FULL_PATCH="$PWD/lustre-kernel-${TARGET}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}.patch"
565     [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
566     pushd linux >/dev/null
567     for series in $SERIES ; do
568         echo -n "Applying series $series:"
569         for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches" ; do
570             [ -r "$patchesdir/series/$series" ] || continue
571             SERIES_FILE="$patchesdir/series/$series"
572             for patch in $(<"$SERIES_FILE") ; do
573                 echo -n " $patch"
574                 PATCH_FILE="$patchesdir/patches/$patch"
575                 [ -r "$PATCH_FILE" ] || \
576                     fatal 1 "Patch $patch does not exist in Lustre tree."
577                 cat "$PATCH_FILE" >> "$FULL_PATCH" || \
578                     fatal 1 "Error adding patch $patch to full patch."
579                 patch -s -p1 < "$PATCH_FILE" || fatal 1 "Error applying patch $patch."
580             done
581             break
582         done
583         echo
584     done
585     popd >/dev/null
586     echo "Full patch has been saved in ${FULL_PATCH##*/}."
587     echo "Replacing .config files..."
588     [ -d linux/configs ] || mkdir linux/configs || \
589         fatal 1 "Error creating configs directory."
590     rm -f linux/configs/*
591     copysuccess=0
592     for patchesdir in "$EXTERNAL_PATCHES" "lustre/lustre/kernel_patches" ; do
593         [ "$patchesdir" ] && \
594             cp -v $patchesdir/kernel_configs/kernel-${VERSION}-${TARGET}*.config linux/configs/ >/dev/null && copysuccess=1
595     done
596     [ "$copysuccess" = "1" ] || \
597         fatal 1 "Error copying in kernel configs."
598 }
599
600 pack_linux()
601 {
602     TARBALL="$(readlink linux)-$EXTRA_VERSION.tar.gz"
603     echo "Creating patched linux tarball $TARBALL..."
604     tar zcf "$TARBALL" "$(readlink linux)" \
605         --exclude "CVS" --exclude ".cvsignore" || \
606         --exclude "*.orig" --exclude "*~" --exclude "*.rej" || \
607         fatal 1 "Error creating patched Linux tarball."
608 }
609
610 clean_linux()
611 {
612     [ -d linux ] || return 0
613     echo "Cleaning linux..."
614     [ -L linux ] && rm -rf $(readlink linux)
615     rm -rf linux
616 }
617
618 prep_kernel_build()
619 {
620     # make .spec file
621     ENABLE_INIT_SCRIPTS=""
622     sed \
623         -e "s^@BASE_ARCHS@^$BASE_ARCHS^g" \
624         -e "s^@BIGMEM_ARCHS@^$BIGMEM_ARCHS^g" \
625         -e "s^@BIGSMP_ARCHS@^$BIGSMP_ARCHS^g" \
626         -e "s^@BOOT_ARCHS@^$BOOT_ARCHS^g" \
627         -e "s^@CONFIGURE_FLAGS@^$CONFIGURE_FLAGS^g" \
628         -e "s^@ENABLE_INIT_SCRIPTS@^$ENABLE_INIT_SCRIPTS^g" \
629         -e "s^@JENSEN_ARCHS@^$BOOT_ARCHS^g" \
630         -e "s^@KERNEL_EXTRA_VERSION@^$EXTRA_VERSION^g" \
631         -e "s^@KERNEL_EXTRA_VERSION_DELIMITER@^$EXTRA_VERSION_DELIMITER^g" \
632         -e "s^@KERNEL_RELEASE@^${EXTRA_VERSION//-/_}^g" \
633         -e "s^@KERNEL_SOURCE@^$KERNEL^g" \
634         -e "s^@KERNEL_VERSION@^$VERSION^g" \
635         -e "s^@LINUX26@^$LINUX26^g" \
636         -e "s^@LUSTRE_SOURCE@^${LUSTRE##*/}^g" \
637         -e "s^@LUSTRE_TARGET@^$TARGET^g" \
638         -e "s^@PSERIES64_ARCHS@^$PSERIES64_ARCHS^g" \
639         -e "s^@RHBUILD@^$RHBUILD^g" \
640         -e "s^@SMP_ARCHS@^$SMP_ARCHS^g" \
641         -e "s^@SUSEBUILD@^$SUSEBUILD^g" \
642         -e "s^@UP_ARCHS@^$UP_ARCHS^g" \
643         < $TOPDIR/lustre/build/lustre-kernel-2.4.spec.in \
644         > lustre-kernel-2.4.spec
645     [ -d SRPMS ] || mkdir SRPMS
646     [ -d RPMS ] || mkdir RPMS
647     [ -d BUILD ] || mkdir BUILD
648     [ -d SOURCES ] || mkdir SOURCES
649     for script in linux-{rhconfig.h,merge-config.awk,merge-modules.awk} \
650         suse-{functions.sh,post.sh,postun.sh,trigger-script.sh.in} \
651         sles8-{pre,post,postun,update_{INITRD_MODULES,rcfile_setting}}.sh ; do
652         cp $TOPDIR/lustre/build/$script SOURCES
653     done
654     cp "$LUSTRE" "$KERNEL_FILE" SOURCES
655     if [ "$EXTERNAL_PATCHES" -a -d "$EXTERNAL_PATCHES" ] ; then
656         tar zcf SOURCES/external-patches.tar.gz -C "$EXTERNAL_PATCHES" series targets patches kernel_configs
657     else
658         touch SOURCES/external-patches.tar.gz
659     fi
660 }
661
662 clean_lustre()
663 {
664     [ -d lustre ] || return 0
665     echo "Cleaning Lustre..."
666     [ -L lustre ] && rm -rf $(readlink lustre)
667     rm -rf lustre
668 }
669
670 build_kernel()
671 {
672     echo "Building kernel + Lustre RPMs for: $BUILD_ARCHS..."
673     targets=
674     for arch in $BUILD_ARCHS ; do
675         targets="--target $arch $targets"
676     done
677
678     local rpmbuildopt='-bb'
679 #    if $NORPM; then
680 #        rpmbuildopt='-bc'
681 #        echo NORPM mode. Only compiling.
682 #        echo "XXX: need to fix lmake - add options to do rpmbuild -bc instead of -bb"
683 #    fi
684
685     $RPMBUILD $targets $rpmbuildopt lustre-kernel-2.4.spec \
686         --define "_tmppath $TMPDIR" \
687         --define "_topdir $TOPDIR" || \
688         fatal 1 "Error building rpms for $BUILD_ARCHS."
689
690     if (( $DO_SRC )) ; then
691         $RPMBUILD -bs lustre-kernel-2.4.spec \
692             --define "_tmppath $TMPDIR" \
693             --define "_topdir $TOPDIR" || \
694             fatal 1 "Error building .src.rpm."
695     fi
696
697     ( $(skeep_ldiskfs_rpm $TAG) ) && return
698
699     pushd $TOPDIR/BUILD/lustre*/ldiskfs || return 255
700     make dist
701     if [ "$?" != "0" ] ; then
702         popd
703         return 255
704     fi
705     cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
706
707     gen_lustre_version
708
709     local ldiskfs_spec=lustre-ldiskfs.spec
710     [ -f "$ldiskfs_spec" ] && sed \
711     -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
712     < $ldiskfs_spec \
713     > ../lustre-ldiskfs.spec
714
715     $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
716         --define "_tmppath /var/tmp" \
717         --define "_topdir $TOPDIR"
718     if [ "$?" != "0" ] ; then
719         popd
720         return 255
721     fi
722
723     if (( $DO_SRC )) ; then
724             $RPMBUILD -bs ../lustre-ldiskfs.spec \
725             --define "_tmppath /var/tmp" \
726             --define "_topdir $TOPDIR"
727         if [ "$?" != "0" ] ; then
728             popd
729             return 255
730         fi
731     fi
732     popd
733 }
734
735 build_lustre()
736 {
737     [ -d SRPMS ] || mkdir SRPMS
738     [ -d RPMS ] || mkdir RPMS
739     [ -d BUILD ] || mkdir BUILD
740     [ -d SOURCES ] || mkdir SOURCES
741
742     cp "$LUSTRE" SOURCES
743
744     pushd lustre >/dev/null
745
746     echo "Building Lustre RPMs for: $BUILD_ARCHS..."
747     targets=
748     for arch in $BUILD_ARCHS ; do
749         targets="--target $arch $targets"
750     done
751
752     local confoptions="--with-linux=${LINUX}"
753     if $PATCHLESS; then
754         confoptions="--with-linux=${LINUX} --disable-server"
755     fi
756     if [ ! "$LINUXOBJ" = "" ]; then
757         confoptions="$confoptions --with-linux-obj=${LINUXOBJ}" 
758     fi
759     
760     ./configure $confoptions ${CONFIGURE_FLAGS}
761     if [ "$?" != "0" ] ; then
762         local saved_config="../config.log.$(date +%s)"
763         cp config.log $saved_config
764         chmod a+r $saved_config
765         echo "Saved config.log is at $saved_config"
766         popd
767         return 255
768     fi
769
770     gen_lustre_version
771
772     # hack. Somebody move build/lustre.spec to lustre.spec for b1_6
773     local lustre_spec=
774     [ -f lustre.spec ] && lustre_spec=lustre.spec
775     [ -f build/lustre.spec ] && lustre_spec=build/lustre.spec
776
777     [ -f "$lustre_spec" ] && sed \
778         -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
779         < $lustre_spec \
780         > ../lustre.spec
781
782     local rpmbuildopt='-bb'
783     if $NORPM; then
784         rpmbuildopt='-bc'
785         echo NORPM mode. Only compiling.
786     fi
787
788     $RPMBUILD $targets $rpmbuildopt ../lustre.spec \
789         --define "_tmppath $TMPDIR" \
790         --define "_topdir $TOPDIR" || \
791         fatal 1 "Error building rpms for $BUILD_ARCHS."
792
793     popd >/dev/null
794     ( $(skeep_ldiskfs_rpm $TAG) ) && return
795
796     pushd lustre/ldiskfs || return 255
797     make dist
798     if [ "$?" != "0" ] ; then
799         popd
800         return 255
801     fi
802     cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
803
804     gen_lustre_version
805
806     local ldiskfs_spec=lustre-ldiskfs.spec
807     [ -f "$ldiskfs_spec" ] && sed \
808     -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
809     < $ldiskfs_spec \
810     > ../lustre-ldiskfs.spec
811
812     $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
813         --define "_tmppath /var/tmp" \
814         --define "_topdir $TOPDIR"
815     if [ "$?" != "0" ] ; then
816         popd
817         return 255
818     fi
819
820     if (( $DO_SRC )) ; then
821             $RPMBUILD -bs ../lustre-ldiskfs.spec \
822             --define "_tmppath /var/tmp" \
823             --define "_topdir $TOPDIR"
824         if [ "$?" != "0" ] ; then
825             popd
826             return 255
827         fi
828     fi
829     popd
830 }
831
832 stage()
833 {
834     [ "$STAGEDIR" ] || return 0
835
836     for arch in $BUILD_ARCHS ; do
837         rpmdir="${STAGEDIR}/${CANONICAL_TARGET}-${arch}"
838         echo "${0##*/}: Copying RPMs into ${rpmdir}"
839         mkdir -p "${rpmdir}"
840         cp -v RPMS/${arch}/*.rpm "${rpmdir}"
841         if [ -d RPMS/noarch ] ; then
842             cp -v RPMS/noarch/*.rpm "${rpmdir}"
843         fi
844     done
845
846     cp -v "$LUSTRE" "$STAGEDIR"
847 }
848
849 #check if we need to build separate ldiskfs RPM
850 skeep_ldiskfs_rpm()
851 {
852         local tag=$1
853         local skip=false
854         if ! $LDISKFSRPM; then
855             skip=true
856         elif $PATCHLESS; then
857             skip=true
858         else
859             for skiptag in $SKIPLDISKFSRPM; do
860                 [[ $tag == $skiptag ]] && skip=true && break
861             done
862         fi
863         echo $skip
864 }
865
866 #get date of last changed target/config/series/patches
867 get_last_source_date()
868 {
869     local filelist="${TOPDIR}/lustre/lustre/kernel_patches/series/${SERIES} \
870         $CONFIG_FILE"
871     local TOPDIRnew=$(echo ${TOPDIR} | sed -e s/\\//\\\\\\//g)
872     filelist="$filelist $( \
873         cat ${TOPDIR}/lustre/lustre/kernel_patches/series/${SERIES} | \
874         sed -e s/^/${TOPDIRnew}\\/lustre\\/lustre\\/kernel_patches\\/patches\\// 2>&1)"
875     local sourcelastdate=$( find ${filelist} -name CVS -prune -o \
876                 -type f -printf "%T@\n" 2>&1 | sort | tail -1 )
877     is_integer $sourcelastdate && echo $sourcelastdate
878 }
879
880 #check if variable is integer
881 is_integer()
882 {
883     local invariable=$1
884     [ "$invariable" = "" ] && return 255
885     local invariableint=$( echo $invariable | sed -e s/[^0-9]//g )
886     [ "$invariable" = "$invariableint" ] || return 255
887 }
888
889 #generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
890 gen_lustre_version()
891 {
892     local smptype=smp
893     [ "$KERNCONFSMPTYPE" = "" ] || smptype=$KERNCONFSMPTYPE
894     [ "$RPMSMPTYPE" = "" ] || smptype=$RPMSMPTYPE
895
896     LUSTRE_EXTRA_VERSION="${lnxmaj}-${EXTRA_VERSION}"
897     if [ "$PATCHLESS" = "true" -a  "$DISTRO" = "sles10" ]; then
898         LUSTRE_EXTRA_VERSION="${LUSTRE_EXTRA_VERSION}-${smptype}"
899     else
900         LUSTRE_EXTRA_VERSION="${LUSTRE_EXTRA_VERSION}${smptype}"
901     fi
902     LUSTRE_EXTRA_VERSION=$( echo $LUSTRE_EXTRA_VERSION | sed -e "s^-^_^g" )
903 }
904
905 #store RPMs and/or BUILD dir for feature reuse
906 store_for_reuse()
907 {
908     local rpmonly=$1
909     if [ ! "$REUSEBUILD" = "" ] && [ -d  "/$REUSEBUILD/" ] ; then
910         [ -d "${REUSEBUILD}/${TIMESTAMP}" ] || mkdir "${REUSEBUILD}/${TIMESTAMP}"
911         [ -d "${REUSEBUILD}/${TIMESTAMP}" ] || return 255
912     else
913         return 255
914     fi
915
916     local lnxrelnew=$( echo ${lnxrel} | sed s/-/_/g )
917         local EXTRA_VERSIONnew=$( echo ${EXTRA_VERSION} | sed s/-/_/g )
918         local KERNELRPMnew=$(basename "$KERNELRPM")
919     if [ ! "$rpmonly" = "rpmonly" ]; then
920             local builddir=
921         if [ ! "$KERNELCOMPILEDIR" = "" ]; then
922             builddir="$KERNELCOMPILEDIR"
923         else
924             builddir="BUILD/lustre-kernel-${lnxmaj}/lustre/linux-${lnxmaj}"
925                 [ "$KERNELCOMPILEDIR" = "" ] || builddir="$KERNELCOMPILEDIR"
926             [ -d "$builddir" ] || builddir="BUILD/lustre-kernel-${lnxmaj}/lustre/linux-${lnxmaj}.${lnxrel}"
927             [ -d "$builddir" ] || builddir="BUILD/lustre-kernel-${lnxmaj}/lustre/linux-${lnxmaj}-${lnxrel}"
928                 if [ ! -d "$builddir" ]; then
929                 pushd "BUILD/lustre-kernel-${lnxmaj}/lustre/" || return 255
930                 local basebuilddir=$(ls -d linux-${lnxmaj}* | head -1)
931                 [ "$basebuilddir" = "" ] || builddir="BUILD/lustre-kernel-${lnxmaj}/lustre/${basebuilddir}"
932                 popd
933                 fi
934         fi
935         [ -d "$builddir" ] || return 255
936             local dstdir="${REUSEBUILD}/${TIMESTAMP}/linux-${KERNCONFSMPTYPE}-${lnxmaj}-${EXTRA_VERSIONnew}.${TARGET_ARCH}"
937             ( $PATCHLESS ) && dstdir="${REUSEBUILD}/${TIMESTAMP}/linux-$KERNELRPMnew" && \
938                     dstdir="${dstdir%.rpm}"
939             [ -d "$dstdir" ] && rm -rf "$dstdir"
940         mv "${builddir}" "$dstdir" || return 255
941     fi
942     #store kernel rpm
943     local kernelrpmname="kernel-lustre-${KERNCONFSMPTYPE}-${lnxmaj}-${EXTRA_VERSIONnew}.${TARGET_ARCH}.rpm"
944     [ -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" ] || kernelrpmname="kernel-${KERNCONFSMPTYPE}-${lnxmaj}-${EXTRA_VERSNnew}.${TARGET_ARCH}.rpm"
945         ( $PATCHLESS ) && [ -f "$KERNELRPM" ] && kernelrpmname="$KERNELRPMnew"
946     if [ "$rpmonly" = "rpmonly" ] && [ -f "${REUSEBUILD}/${TIMESTAMP}/${kernelrpmname}" ]; then
947         echo "RPM already exist in store directory tree"
948     else
949         [ -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" ] && cp -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" "${REUSEBUILD}/${TIMESTAMP}/"
950     fi
951     #store kernel source rpm
952     kernelrpmname="kernel-lustre-source-${lnxmaj}-${EXTRA_VERSIONnew}.${TARGET_ARCH}.rpm"
953     [ -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" ] || kernelrpmname="kernel-source-${lnxmaj}-${EXTRA_VERSIONnew}.${TARGET_ARCH}.rpm"
954     ( $PATCHLESS ) && [ -f "$KERNELSOURCERPM" ] && kernelrpmname=$(basename "$KERNELSOURCERPM")
955     if [ "$rpmonly" = "rpmonly" ] && [ -f "${REUSEBUILD}/${TIMESTAMP}/${kernelrpmname}" ]; then
956         echo "RPM already exist in store directory tree"
957     else
958             [ -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" ] && cp -f "RPMS/${TARGET_ARCH}/${kernelrpmname}" "${REUSEBUILD}/${TIMESTAMP}/"
959     fi
960 }
961
962 #unpack kernel(/source/devel) RPM
963 unpack_linux_rpm()
964 {
965     local prefix=$1
966     local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
967     local kernelbinaryrpm=
968     [ -d $pathtorpms ] || return 255
969     local rpmfile=
970     local smptype=
971     for arch in $TARGET_ARCHS_ALL; do
972         for smptype in $SMPTYPES; do
973             [ "$smptype" = "''" ] && smptype=
974             [ "$smptype" = "" ] || smptype="-${smptype}"
975             case "$DISTRO" in
976                 sles10)
977                     rpmfile="kernel${smptype}${prefix}-${lnxmaj}.${lnxrel}.${arch}.rpm"
978                     kernelbinaryrpm="kernel${smptype}-${lnxmaj}.${lnxrel}.${arch}.rpm"
979                 ;;
980                 *)
981                     rpmfile="kernel${smptype}${prefix}-${lnxmaj}-${lnxrel}.${arch}.rpm"
982                     kernelbinaryrpm="kernel${smptype}-${lnxmaj}-${lnxrel}.${arch}.rpm"
983                 ;;
984             esac
985             [ -f "${pathtorpms}/${arch}/${kernelbinaryrpm}" ] && KERNELRPM="${pathtorpms}/${arch}/${kernelbinaryrpm}"
986             [ -f "${pathtorpms}/${arch}/${rpmfile}" ] && RPMSMPTYPE=${smptype/-/} && break
987         done
988         [ -f "${pathtorpms}/${arch}/${kernelbinaryrpm}" ] && KERNELRPM="${pathtorpms}/${arch}/${kernelbinaryrpm}"
989         [ -f "${pathtorpms}/${arch}/${rpmfile}" ] && TARGET_ARCH="$arch" && BUILD_ARCHS="$arch"
990         [ -f "${pathtorpms}/${arch}/${rpmfile}" ] && break
991     done
992     [ -f "${pathtorpms}/${TARGET_ARCH}/${rpmfile}" ] || return 255
993     [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused
994     pushd $TOPDIR/reused || return 255
995     rpm2cpio < "${pathtorpms}/${TARGET_ARCH}/${rpmfile}" | cpio -idc > /dev/null 2>&1
996     if [ ${PIPESTATUS[0]} -eq 0 ]; then
997         local path2source=$(ls usr/src/kernels/ | grep ${lnxmaj})
998         [ -d "usr/src/kernels/${path2source}" ] && LINUX="$(pwd)/usr/src/kernels/${path2source}"
999     else
1000         popd
1001         return 255
1002     fi
1003     popd
1004 }
1005
1006 #look for kernel source RPM
1007 find_linux_source_rpm()
1008 {
1009     local rpmfile=
1010     local findarch=true
1011     local arch=
1012     local pathtorpms=
1013     [ ! "$TARGET_ARCH" = "" ] && arch=$TARGET_ARCH && findarch=false
1014     
1015     if ! $findarch; then
1016         pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}/${arch}"
1017         [ -d $pathtorpms ] || return 255
1018         case "$DISTRO" in
1019             rhel4)
1020                 rpmfile="kernel-${lnxmaj}-${lnxrel}.src.rpm"
1021             ;;
1022             sles10)
1023                 rpmfile="kernel-source-${lnxmaj}.${lnxrel}.${arch}.rpm"
1024             ;;
1025             *)
1026                 rpmfile="kernel-source-${lnxmaj}-${lnxrel}.${arch}.rpm"
1027             ;;
1028         esac
1029         [ -f "${pathtorpms}/${rpmfile}" ] || return 255
1030         KERNELSOURCERPM="${pathtorpms}/${rpmfile}"
1031     else
1032         for arch in $TARGET_ARCHS_ALL; do
1033         pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}/${arch}"
1034         [ -d $pathtorpms ] || continue
1035         case "$DISTRO" in
1036             rhel4)
1037                 rpmfile="kernel-${lnxmaj}-${lnxrel}.src.rpm"
1038             ;;
1039             sles10)
1040                 rpmfile="kernel-source-${lnxmaj}.${lnxrel}.${arch}.rpm"
1041             ;;
1042             *)
1043                 rpmfile="kernel-source-${lnxmaj}-${lnxrel}.${arch}.rpm"
1044             ;;
1045         esac
1046         [ -f "${pathtorpms}/${rpmfile}" ] || continue
1047         KERNELSOURCERPM="${pathtorpms}/${rpmfile}"
1048         TARGET_ARCH=${arch}
1049         break
1050         done
1051     fi
1052     [ -f "${KERNELSOURCERPM}" ] || return 255
1053 }
1054
1055 #unpack and make symlinks for reusing kernel RPM
1056 reuse_kernel_rpm()
1057 {
1058     local pathtorpm=$1
1059     [ "$pathtorpm" = "" ] && return 255
1060     [ -f "$pathtorpm" ] || return 255
1061     [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused
1062     pushd $TOPDIR/reused || return 255
1063
1064     rpm2cpio < $pathtorpm | cpio -idc
1065     [ ${PIPESTATUS[0]} -eq 0 ] || return 255
1066
1067     local smptype=
1068     if pushd usr/src/linux-*-obj/${TARGET_ARCH}; then
1069         local smptypes="$SMPTYPES"
1070         [ "$RPMSMPTYPE" = "" ] || smptypes=$RPMSMPTYPE
1071         ( ! $PATCHLESS ) && [ ! "$KERNCONFSMPTYPE" = "" ] && smptypes="$KERNCONFSMPTYPE"
1072         local cursmptype=
1073         for cursmptype in $smptypes; do
1074             [ "$cursmptype" = "''" ] && continue
1075             [ -d $cursmptype ] && smptype=$cursmptype
1076             [ -d $smptype ] && break
1077         done
1078         popd
1079     fi
1080     if [ "${smptype}" = "" ]; then
1081         popd
1082         return 255 # cannot detect smp type
1083     fi
1084     if pushd usr/src/linux-*-obj/${TARGET_ARCH}/$smptype/include2; then
1085         local base=$(readlink asm)
1086         if [ ! -d "/${base}/" ]; then
1087             rm -f asm
1088             base=$(basename "$base")
1089             if pushd ../../../../linux-*/include; then
1090                 local lsrc=$(pwd)
1091                 popd
1092                 [ -d "$lsrc/${base}" ] && ln -s $lsrc/${base} asm
1093             fi
1094         fi
1095         popd
1096         read a b < <(echo $(pwd)/usr/src/linux-*)
1097         if [[ $a == $(pwd)/* && $b = $(pwd)/* ]]; then
1098             cp -f $a/include/linux/config.h $b/${TARGET_ARCH}/$smptype/include/linux/
1099             cp $b/${TARGET_ARCH}/$smptype/.config $a/
1100             [ -f "$b/${TARGET_ARCH}/$smptype/.config" ] && KERNELRPMCONFIG="$b/${TARGET_ARCH}/$smptype/.config"
1101             cp $b/${TARGET_ARCH}/$smptype/.kernelrelease $a/
1102             [ -f "$b/${TARGET_ARCH}/$smptype/.kernelrelease" ] && KERNELRPMRELEASE="$b/${TARGET_ARCH}/$smptype/.kernelrelease"
1103             LINUX=$a
1104             LINUXOBJ=$b/${TARGET_ARCH}/$smptype
1105 #            local fname=$(basename $kernel_rpm)
1106 #            KERNELRPMSDIR=${kernel_rpm%$fname}
1107         fi
1108     fi
1109     popd
1110     [ "$LINUX" = "" ] && return 255
1111     [ -d "$LINUX" ] || return 255
1112 }
1113
1114 #build linux kernel rpm
1115 build_linux_rpm()
1116 {
1117     pushd $LINUX || return 255
1118     make binrpm-pkg || ( popd ; return 255 )
1119     local addlnxrel=
1120     [ -f ".version" ] && addlnxrel="-$(cat .version)"
1121     popd
1122     local arch=
1123     for arch in $TARGET_ARCHS_ALL; do
1124         [ -f "/usr/src/rpm/RPMS/$arch/kernel-$lnxmaj.${lnxrel}${addlnxrel}.$arch.rpm" ] && \
1125             KERNELRPM="/usr/src/rpm/RPMS/$arch/kernel-$lnxmaj.${lnxrel}${addlnxrel}.$arch.rpm" && \
1126             TARGET_ARCH="$arch"
1127         [ -f "/usr/src/packages/RPMS/$arch/kernel-$lnxmaj.${lnxrel}${addlnxrel}.$arch.rpm" ] && \
1128             KERNELRPM="/usr/src/packages/RPMS/$arch/kernel-$lnxmaj.${lnxrel}${addlnxrel}.$arch.rpm" && \
1129             TARGET_ARCH="$arch"
1130     done
1131     [ "$KERNELRPM" = "" ] || return
1132     return 255
1133 }
1134
1135 #build linux kernel
1136 build_linux()
1137 {
1138     local nofullmake=$1
1139     local nocopykernel=$2
1140     pushd $LINUX || fatal 1 "Kernel source not found"
1141     [ "$nofullmake" = "nofullmake" ] || make mrproper
1142     [ "$nofullmake" = "nofullmake" ] || rm -f rpm-release
1143 #    [ "$nocopykernel" = "copyrpmkernel" ] || rm -f localversion-*
1144     [ "$nocopykernel" = "copykernel" ] && [ -f "$CONFIG_FILE" ] && cp $CONFIG_FILE .config
1145     if [ "$nocopykernel" = "copyrpmkernel" ]; then
1146         [ -f "$KERNELRPMCONFIG" ] && cp $KERNELRPMCONFIG .config
1147         if [ -f "$KERNELRPMRELEASE" ]; then
1148             cp $KERNELRPMRELEASE .
1149         else
1150             sed -e "s/^EXTRAVERSION\s\+=\s\+.*$/EXTRAVERSION = -${lnxrel}/" < Makefile > Makefile.new
1151             [ -f "Makefile.new" ] && mv Makefile.new Makefile
1152         fi
1153     fi
1154     [ -f ".config" ] || ( popd ; echo "Cannot find .config file"; return 255 )
1155     make oldconfig || ( popd ; return 255 )
1156     make include/linux/version.h
1157     if [ ! "$nofullmake" = "nofullmake" ]; then
1158         make || ( popd ; return 255 )
1159     fi
1160     popd
1161     return
1162 }
1163
1164 #build patchless lustre
1165 patchless_build_sequence()
1166 {
1167     #try to build from kernel-devel RPM (RHEL)
1168     LINUX=
1169     TARGET_ARCH=
1170     local rpmfound=false
1171     local buildsuccess=false
1172     local storeforreuse=false
1173     if [ "$KERNELRPMSBASE" = "" ] || [ ! -d "$KERNELRPMSBASE" ]; then
1174         return 255
1175     fi
1176     [ -d $TOPDIR/reused ] && rm -rf $TOPDIR/reused
1177     unpack_linux_rpm "-devel" && rpmfound=true
1178     ( $rpmfound ) && build_lustre && buildsuccess=true && find_linux_source_rpm
1179
1180     if ! $buildsuccess; then
1181         # cannot build from -devel. Try to build from kernel source RPM without rebuilding kernel
1182         KERNELSOURCERPM=
1183         # first unpack kernel binary RPM
1184         rpmfound=false
1185         [ -d $TOPDIR/reused ] && rm -rf $TOPDIR/reused
1186         unpack_linux_rpm && rpmfound=true
1187         ! ( $rpmfound ) && echo "Cannot find kernel RPM"
1188
1189         if ! $rpmfound; then #kernel RPM not found.
1190             # try to reuse
1191             build_sequence_reuse && buildsuccess=true
1192             if ! $buildsuccess; then
1193                 # reuse failed. Try to build from tarbal
1194                 KERNELRPM=
1195                 KERNELSOURCERPM=
1196                 unpack_linux && LINUX="$TOPDIR/linux" && \
1197                     build_linux fullmake copykernel && build_linux_rpm
1198                 ! [ "$KERNELRPM" = "" ] && build_lustre && storeforreuse=true && buildsuccess=true
1199             fi
1200         else
1201             # next find and unpack source RPM
1202             rpmfound=false
1203             find_linux_source_rpm && rpmfound=true
1204             ( $rpmfound ) && \
1205                 reuse_kernel_rpm "$KERNELSOURCERPM" && build_linux nofullmake copyrpmkernel && build_lustre && buildsuccess=true
1206         fi
1207     fi
1208
1209     if ! $buildsuccess && $rpmfound; then
1210         # build wrong. try to build kernel first
1211         REUSEDKERNELMASK=$(basename $KERNELRPM | sed s/\\.rpm//)
1212         build_sequence_reuse && buildsuccess=true
1213     fi
1214     
1215     if ! $buildsuccess && $rpmfound; then
1216         build_linux fullmake copyrpmkernel && build_lustre && buildsuccess=true && storeforreuse=true
1217     fi
1218
1219     if $buildsuccess; then
1220             [ -d "RPMS/${TARGET_ARCH}" ] && [ -f "$KERNELRPM" ] && \
1221                     cp "$KERNELRPM" RPMS/${TARGET_ARCH}/
1222             [ -d "RPMS/${TARGET_ARCH}" ] && [ -f "$KERNELSOURCERPM" ] && \
1223                     cp "$KERNELSOURCERPM" RPMS/${TARGET_ARCH}/
1224             KERNELCOMPILEDIR="$LINUX"
1225         if $storeforreuse; then
1226             store_for_reuse || echo "Cannot store for feature reuse"
1227         fi
1228         return
1229     fi
1230
1231     # patchless build filed
1232     return 255
1233 }
1234
1235 #check timestamp value. should bi 14-digits string
1236 check_timestamp()
1237 {
1238     local invalue=$1
1239     local timestampnodig=$(echo $invalue | sed -e s/[0-9]*//g)
1240     [ "$timestampnodig" = "" ] || return 255
1241     local timestamplength="${#invalue}"
1242     [ $timestamplength -eq 14 ] || return 255
1243 }
1244
1245 # get list of suitable directories with potential reused staff
1246 get_reuse_dir_list()
1247 {
1248     local rpmonly=$1
1249     local reusedkernelmasknew=$2
1250     local buildtimestamp=
1251     local dirsforreuse=
1252     local sourcelastdate=$(get_last_source_date)
1253     for buildtimestamp in $(ls "$REUSEBUILD/" 2>&1); do
1254         [ -d "$REUSEBUILD/$buildtimestamp" ] || continue
1255         check_timestamp "$buildtimestamp" || continue
1256         local buildtimestampstr=$(echo $buildtimestamp | \
1257             sed -e "s^\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)^\1-\2-\3 \4:\5:\6 GMT^g")
1258         local buildtimestampepoch=$(date --date="$buildtimestampstr"  +%s )
1259         #check for suitable date
1260             if ! $PATCHLESS; then
1261             [ $buildtimestampepoch -ge $sourcelastdate ] || continue
1262             fi
1263         #check for suitable version
1264         if [ "$rpmonly" = "rpmonly" ]; then
1265             local reusedkernelprefix="kernel-lustre-"
1266             ( $PATCHLESS ) && reusedkernelprefix=
1267             local rpmmask="${reusedkernelprefix}${REUSEDKERNELMASK}"
1268             [ "$reusedkernelmasknew" = "" ] || rpmmask="$reusedkernelmasknew"
1269             [ -f $REUSEBUILD/$buildtimestamp/${rpmmask}.rpm ] && \
1270                 dirsforreuse="$dirsforreuse $REUSEBUILD/$buildtimestamp"
1271         else
1272             local rpmmask="$REUSEDKERNELMASK"
1273             [ "$reusedkernelmasknew" = "" ] || rpmmask="$reusedkernelmasknew"
1274             pushd $REUSEBUILD/$buildtimestamp/linux-${rpmmask} > /dev/null 2>&1 || continue
1275             local curdir=$(pwd)
1276             dirsforreuse="$dirsforreuse $curdir"
1277             popd
1278         fi
1279     done
1280     echo "$dirsforreuse"
1281 }
1282
1283 #try to reuse old RPM
1284 build_sequence_rpm_reuse()
1285 {
1286     local sourcerpm=$1
1287     [ "$REUSERPM" = "" ] && [ "$REUSEBUILD" = "" ] && return 255
1288     local dirsforreuse=
1289     if ! [ "$REUSEBUILD" = "" ] && [ -d "$REUSEBUILD" ]; then #try to reuse RPM
1290         local REUSEDKERNELMASKnew=$(echo $REUSEDKERNELMASK | sed -e "s/^[^0-9]*//")
1291         REUSEDKERNELMASKnew="kernel-lustre-source-${REUSEDKERNELMASKnew}"
1292         local dirsforreuse="$(get_reuse_dir_list rpmonly $REUSEDKERNELMASKnew)"
1293         local buildsuccess=false
1294         LINUXOBJ=
1295         for curdir in $(echo $dirsforreuse); do
1296             [ -d "$curdir" ] || continue
1297             local reusedkernelprefix="kernel-lustre-"
1298             local reusedkernelrpm=
1299             [ -f ${curdir}/${reusedkernelprefix}${REUSEDKERNELMASK}.rpm ] && \
1300                 reusedkernelrpm=$(ls ${curdir}/${reusedkernelprefix}${REUSEDKERNELMASK}.rpm | head -1 )
1301             [ -f "$reusedkernelrpm" ] || continue
1302
1303             local reusedkernelsourcerpm=
1304             [ -f ${curdir}/${REUSEDKERNELMASKnew}.rpm ] && \
1305                 reusedkernelsourcerpm=$(ls ${curdir}/${REUSEDKERNELMASKnew}.rpm | head -1 )
1306             [ -f "$reusedkernelsourcerpm" ] || continue
1307
1308             [ -d $TOPDIR/reused ] && rm -rf $TOPDIR/reused
1309             reuse_kernel_rpm "$reusedkernelsourcerpm" && build_linux nofullmake copyrpmkernel && build_lustre && buildsuccess=true
1310             ( $buildsuccess ) || continue
1311             if ( ! $NORPM ) && ( ! $PATCHLESS ) ; then
1312                 [ -f "$reusedkernelrpm" ] && \
1313                     cp -f  "$reusedkernelrpm"  RPMS/${TARGET_ARCH}/ > /dev/null 2>&1
1314  
1315                 [ -f "$reusedkernelsourcerpm" ] && \
1316                     cp -f  "$reusedkernelsourcerpm"  RPMS/${TARGET_ARCH}/ > /dev/null 2>&1 && \
1317                     touch RPMS/${TARGET_ARCH}/kernel_was_reused
1318             fi
1319             return
1320         done
1321     fi
1322     return 255
1323 }
1324
1325 #try to reuse old BUILD dir
1326 build_sequence_reuse()
1327 {
1328     local sourcerpm=$1
1329     [ "$REUSERPM" = "" ] && [ "$REUSEBUILD" = "" ] && return 255
1330     local dirsforreuse=
1331     if [ ! "$REUSEBUILD" = "" ] && [ -d "$REUSEBUILD" ]; then #try to reuse old kernel build directory
1332         local dirsforreuse="$(get_reuse_dir_list)"
1333         local buildsuccess=false
1334         LINUXOBJ=
1335         local REUSEDKERNELMASKnew=$(echo $REUSEDKERNELMASK | sed -e "s/^[^0-9]*//")
1336         for curdir in $(echo $dirsforreuse); do
1337             local reusedkernelrpm=
1338             local reusedkernelsourcerpm=
1339             [ -d "$curdir" ] || continue
1340             local reusedkernelprefix="kernel-lustre-"
1341             ( $PATCHLESS ) && reusedkernelprefix=
1342             [ -f ${curdir}/../${reusedkernelprefix}${REUSEDKERNELMASK}.rpm ] && \
1343                 reusedkernelrpm=$(ls ${curdir}/../${reusedkernelprefix}${REUSEDKERNELMASK}.rpm | head -1 )
1344             reusedkernelprefix="kernel-lustre-source-"
1345             [ -f ${curdir}/../${reusedkernelprefix}${REUSEDKERNELMASKnew}.rpm ] && \
1346                 reusedkernelsourcerpm=$(ls ${curdir}/../${reusedkernelprefix}${REUSEDKERNELMASKnew}.rpm | head -1 ) 
1347             if ! ( $NORPM ) && ! [ -f "$reusedkernelrpm" ]; then #kernel rpm not found. Build all
1348                 continue
1349             fi
1350             if ! ( $NORPM ) && ! [ -f "$reusedkernelsourcerpm" ]; then #kernel source rpm not found. Build all
1351                 continue
1352             fi
1353             LINUX="$curdir"
1354             build_lustre || continue
1355             touch "$curdir/../"
1356             buildsuccess=true
1357             if ( ! $NORPM ) && ( ! $PATCHLESS ) ; then
1358                 [ -f "$reusedkernelrpm" ] && \
1359                     cp -f  "$reusedkernelrpm"  RPMS/${TARGET_ARCH}/ > /dev/null 2>&1 && \
1360                     touch RPMS/${TARGET_ARCH}/kernel_was_reused
1361                 [ -f "$reusedkernelsourcerpm" ] && \
1362                     cp -f  "$reusedkernelsourcerpm"  RPMS/${TARGET_ARCH}/ > /dev/null 2>&1
1363             fi
1364             return
1365         done
1366     fi
1367     return 255
1368 }
1369
1370
1371 build_sequence()
1372 {
1373     if (( $DO_SRC )) ; then
1374         unpack_linux
1375         patch_linux
1376         pack_linux
1377         clean_linux
1378     fi
1379     prep_kernel_build || return 255
1380     clean_lustre || return 255
1381
1382     build_kernel || return 255
1383 }
1384
1385 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
1386
1387 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: -- "$@")
1388
1389 if [ $? != 0 ] ; then
1390     usage 1
1391 fi
1392
1393 eval set -- "$options"
1394     
1395 while [ "$1" ] ; do
1396     case "$1" in
1397         '')
1398             usage 1
1399             ;;
1400         --ccache)
1401             CCACHE='ccache'
1402             shift
1403             ;;
1404         -d)
1405             CVSROOT=$2
1406             shift 2
1407             ;;
1408         -D)
1409             DATE=$2
1410             shift 2
1411             ;;
1412         --external-patches)
1413             EXTERNAL_PATCHES=$2
1414             shift 2
1415             ;;
1416         --extraversion)
1417             EXTRA_VERSION=$2
1418             shift 2
1419             ;;
1420         --help | -h)
1421             usage 0
1422             ;;
1423         --kerneldir)
1424             KERNELDIR=$2
1425             shift 2
1426             ;;
1427         --kerneltree)
1428             KERNELTREE=$2
1429             shift 2
1430             ;;
1431         --linux | --with-linux)
1432             LINUX=$2
1433             shift 2
1434             ;;
1435         --distro)
1436             DISTRO=$2
1437             shift 2
1438             ;;
1439         --reuserpm)
1440             REUSERPM=$2
1441             shift 2
1442             ;;
1443         --reusebuild)
1444             REUSEBUILD=$2
1445             shift 2
1446             ;;
1447         --norpm)
1448             NORPM=true
1449             shift
1450             ;;
1451         --ldiskfs)
1452             LDISKFSRPM=true
1453             shift
1454             ;;
1455         --patchless)
1456             PATCHLESS=true
1457             shift
1458             ;;
1459         --kernelrpm)
1460             KERNELRPMSBASE=$2
1461             shift 2
1462             ;;
1463         --timestamp)
1464             TIMESTAMP=$2
1465             shift 2
1466             ;;
1467         --lustre)
1468             LUSTRE=$2
1469             shift 2
1470             ;;
1471         --nodownload)
1472             DOWNLOAD=0
1473             shift 1
1474             ;;
1475         --nosrc)
1476             DO_SRC=0
1477             shift 1
1478             ;;
1479         --publish)
1480             shift
1481             ;;
1482         --release)
1483             RELEASE=true
1484             shift
1485             ;;
1486         --src)
1487             DO_SRC=1
1488             shift 1
1489             ;;
1490         --stage)
1491             STAGEDIR=$2
1492             shift 2
1493             ;;
1494         --tag)
1495             TAG=$2
1496             shift 2
1497             ;;
1498         --target)
1499             TARGET=$2
1500             shift 2
1501             ;;
1502         --target-archs)
1503             TARGET_ARCHS=$2
1504             shift 2
1505             ;;
1506         --disable-datestamp)
1507             USE_DATESTAMP=
1508             shift
1509             ;;
1510         --)
1511             shift
1512             CONFIGURE_FLAGS=$@
1513             CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
1514             break
1515             ;; 
1516         *)
1517             usage 1 "Unrecognized option: $1"
1518             ;;
1519     esac
1520 done
1521
1522 check_options
1523
1524 unpack_lustre
1525
1526 load_target
1527 EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
1528
1529 build_success=false
1530 if $PATCHLESS; then
1531     patchless_build_sequence && build_success=true 
1532 elif [ -z "$LINUX" ] ; then
1533     [ "$DISTRO" = "sles9" ] && build_sequence_rpm_reuse && build_success=true
1534     if ! $build_success; then
1535         build_sequence_reuse && build_success=true
1536         if ! $build_success; then
1537             build_sequence && build_success=true
1538             if $build_success; then
1539                 store_for_reuse || echo "Cannot store for feature reuse"
1540             fi
1541         fi
1542     fi
1543 else
1544     build_lustre
1545 fi
1546 ( $build_success ) || fatal 1 "Cannot build lustre"
1547
1548 stage