3 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
10 # CVSROOT is inherited from the environment
15 # XXX - some recent hacking has pretty much neutered this option.
16 # search through this file (and lbuild.old_school -- but that will
17 # be going away soon) for "-bb" and see how many places
18 # simply don't account for this option
24 TARGET_ARCH=$(uname -m)
26 TARGET_ARCHS_ALL=$TARGET_ARCH
27 [ "$TARGET_ARCH" = "i686" ] && TARGET_ARCHS_ALL="i686 i586 i386"
33 TMPDIR=${TMPDIR:-"/var/tmp"}
35 # XXX - i think these two parameters/arguments/variables need to be
36 # cleaned up and merged. they effectively do the same thing
39 # what does this do exactly? does it imply no kernel build?
42 SKIPLDISKFSRPM="v1_4_* b1_4"
43 SMPTYPES="smp bigsmp default ''"
49 # default to not adding -lustre- into the kernel RPM package names
50 KERNEL_LUSTRE_NAMING=false
67 # not in the target file any more
79 # Readlink is not present on some older distributions: emulate it.
83 if [ -L "$path" ]; then
84 ll="$(LC_ALL=C ls -l "$path" 2> /dev/null)" &&
99 [ -n "$msg" ] && echo -e "\n${0##*/}: $msg" >&2
113 Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
116 Specifies the CVS Root to use when pulling files from CVS. The
117 environment variable \$CVSROOT is used if this option is not
120 --external-patches=EXTERNAL_PATCHES
121 Directory similar to lustre/lustre/kernel_patches/ that lbuild should
122 look for seres and config files in before looking in the lustre
125 --extraversion=EXTRAVERSION
126 Text to use for the rpm release and kernel extraversion.
128 --timestamp=TIMESTAMP
129 Date of building lustre in format YYYYMMDDhhmmss
132 Try to reuse old kernel RPMs from DIR
135 Try to reuse old kernel builds from DIR
138 Path to distro kernel RPM collection
144 Do not build RPMs (compile only mode)
147 Build lustre client only
150 Which distro using. Autodetect by default
152 --kerneldir=KERNELDIR
153 Directory containing Linux source tarballs referenced by target
156 --kerneltree=KERNELTREE
157 Directory containing dirs with Linux source tarballs referenced by target
158 files. Dir names in format kernel version ('2.6.9', etc.)
160 --linux=LINUX --with-linux=LINUX
161 Directory of Linux kernel sources. When this option is used, only
162 Lustre modules and userspace are built.
165 Path to an existing lustre source tarball to use instead of
169 Do not try to download a kernel from downloads.lustre.org
172 Do not build a .src.rpm, a full kernel patch, or a patched kernel
176 Do ldiskfs RPM. Now true by default
182 Specifies that the files generated do not include timestamps, and
183 that this is an official release.
186 Build a .src.rpm, a full kernel patch, and a patched kernel tarball.
189 Directory used to stage packages for release. RPMs will be placed
190 more or less in DIR/<target>-<arch>, and the tarball will be
194 A CVS branch/tag name to build from when pulling from CVS.
197 The name of the target to build. The available targets are listed
200 --target-archs=TARGET_ARCHS
201 A (space delimited) list of architectures to build. By default,
202 all of the archs supported by the TARGET will be built, in
203 addition to a .src.rpm. This option can limit those, for machines
204 that can only build certain archs or if you only want a certain
205 arch built (for testing, or a one-off kernel).
207 Also note that by using a non-"base" arch (eg, i386) only kernels
208 will be built - there will be no lustre-lite-utils package.
211 Prevents the datestamp flag (-D) from being passed to cvs for
212 checkouts. This is a workaround for a problem encountered when
213 using lbuild with tinderbox.
216 Builds a Xen domX kernel.
225 # canonicalize a relative path
229 if [ ! -d "$PATH" ]; then
233 pushd "$PATH" >/dev/null || return 1
243 if [ "$LUSTRE" ]; then
244 [ -r "$LUSTRE" ] || \
245 usage 1 "Could not find Lustre source tarball '$LUSTRE'."
248 usage 1 "Either specify a CVS Root with -d, or a Lustre source tarball with --lustre."
250 usage 1 "A branch/tag name must be specified with --tag when not building from a tarball."
253 if [ -z "$LINUX" ]; then
254 [ "$KERNELDIR" -o "$KERNELTREE" ] || \
255 usage 1 "A kernel directory must be specified with --kerneldir or --kerneltree."
257 [ -d "$KERNELDIR" -o -d "$KERNELTREE" ] || \
258 usage 1 "$KERNELDIR and $KERNELTREE are not a directory."
262 usage 1 "When building a snapshot, a tag name must be used."
265 [ "$TARGET" ] || usage 1 "A target must be specified with --target."
266 # TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
267 # [ -r "$TARGET_FILE" ] || \
268 # usage 1 "Target '$TARGET' was not found."
273 CANONICAL_TARGET="rhel5"
276 CANONICAL_TARGET="rhel-2.6"
279 CANONICAL_TARGET="sles-2.6"
282 CANONICAL_TARGET="sles10-2.6"
285 CANONICAL_TARGET="sles11"
288 CANONICAL_TARGET="hp-pnnl-2.4"
296 CANONICAL_TARGET="$TARGET"
300 local timestampnodig=$(echo $TIMESTAMP | sed -e s/[0-9]*//g)
301 [ "$timestampnodig" = "" ] || TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
302 local timestamplength="${#TIMESTAMP}"
303 if [ $timestamplength -eq 12 ]; then
304 TIMESTAMP="${TIMESTAMP}00"
305 elif [ $timestamplength -ne 14 ]; then
306 TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
309 RPMBUILD=$(which rpmbuild 2>/dev/null | head -1)
310 if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
311 RPMBUILD=$(which rpm 2>/dev/null | head -1)
312 if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
313 usage 1 "Could not find binary for making rpms (tried rpmbuild and rpm)."
317 if [ -n "$CCACHE" ]; then
318 which "$DISTCC" 2>/dev/null && export DISTCC RPM_BUILD_NCPUS
320 if which "$CCACHE" 2>/dev/null; then
321 local ccache=$(which "$CCACHE")
322 local bindir="$TOPDIR/bin"
324 [ -d $bindir ] || mkdir -p $bindir
325 if [ -d $bindir ]; then
326 rm ${bindir}/* > /dev/null 2>&1
327 ln -s "$ccache" ${bindir}/ccache
328 ln -s "$ccache" ${bindir}/cc
329 ln -s "$ccache" ${bindir}/$CC
330 export PATH=$bindir:$PATH
332 export CCACHE && export CC="ccache $CC"
333 # zero the cache so we can see how effective we are being with it
338 [ -z "$DISTRO" ] && DISTRO=$(autodetect_distro)
341 # autodetect used Distro
342 autodetect_distro() {
347 if [ -f /etc/SuSE-release ]; then
349 version=$(grep ^VERSION /etc/SuSE-release)
350 version=${version#*= }
351 elif [ -f /etc/redhat-release ]; then
352 name=$(head -1 /etc/redhat-release)
353 version=$(echo "$distroname" |
354 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ \.].*//')
356 if [ -z "$name" -o -z "$version" ]; then
357 fatal 1 "I don't know how to determine distro type/version.\n" \
358 "Either update autodetect_distro() or use the --distro argument"
361 echo ${name}${version}
368 echo $(echo "$*" | xargs -n 1 | sort -u)
375 local force="${3:-false}"
377 if $force || [ ! -r "$KERNELDIR/$srpm" ] ||
378 [ ! -s "$KERNELDIR/$srpm" ]; then
380 local location="http://downloads.lustre.org/public/kernels/$target/old"
381 echo "Downloading $location/$srpm..."
382 if ! wget -nv "$location/$srpm" -O "$KERNELDIR/$srpm" ||
383 [ ! -s "$KERNELDIR/$srpm" ]; then
384 rm -f $KERNELDIR/$srpm
385 fatal 1 "Could not download target $target's kernel SRPM" \
386 "$srpm from $location."
389 fatal 1 "$srpm not found in directory $KERNELDIR."
396 local force="${1:-false}"
398 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ] &&
399 ( $force || [ ! -r "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ||
400 [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ); then
402 local location="http://downloads.lustre.org/public/OFED/"
403 echo "Downloading $location/OFED-${OFED_VERSION}.tgz..."
404 if ! wget -nv "$location/OFED-${OFED_VERSION}.tgz" \
405 -O "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ||
406 [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ]; then
407 rm -f $KERNELTREE/OFED-${OFED_VERSION}.tgz
408 fatal 1 "Could not download OFED-${OFED_VERSION}.tgz" \
409 "from downloads.lustre.org."
412 fatal 1 "OFED-${OFED_VERSION}.tgz not found in kernel" \
413 "directory $KERNELTREE."
421 EXTRA_VERSION_save="$EXTRA_VERSION"
422 for patchesdir in "$EXTERNAL_PATCHES" \
423 "$TOPDIR/lustre/lustre/kernel_patches"; do
424 TARGET_FILE="$patchesdir/targets/$TARGET.target"
425 [ -r "$TARGET_FILE" ] && break
427 [ -r "$TARGET_FILE" ] || fatal 1 "Target $TARGET was not found."
429 echo "Loading target config file $TARGET.target..."
433 # doesn't make any sense to build OFED for xen domX's
438 # XXX - set_rpm_smp_type is an ugly undeterministic hack. it needs to
439 # go away and the target just specify the $RPMSMPTYPE
440 [ -z "$RPMSMPTYPE" ] && set_rpm_smp_type
442 # CC might have been overwriten in TARGET_FILE
443 if [[ $CC != ccache\ * ]] && which "$CCACHE" 2>/dev/null; then
444 export CCACHE && export CC="ccache $CC"
447 if [ ! "$KERNELTREE" = "" ] && [ -d "$KERNELTREE" ]; then
448 KERNELDIR="$KERNELTREE/${lnxmaj}"
449 [ -d "$KERNELDIR" ] || mkdir "$KERNELDIR"
452 # verify the series is available
453 if [ "$SERIES" ]; then
454 for series in $SERIES; do
455 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
456 [ -r "$patchesdir/series/$series" ] && continue 2
458 fatal 1 "Target $TARGET's series $SERIES could not be" \
459 "found.\nSearched:\n\t$EXTERNAL_PATCHES/series\n" \
460 "\t$TOPDIR/lustre/lustre/kernel_patches/series."
464 # set the location of the .config file
470 if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config ]; then
471 CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET$XENPOSTFIX-$TARGET_ARCH${RPMSMPTYPE:+-}${RPMSMPTYPE}.config"
474 local lnxrelnew=${lnxrel//-/_}
476 # remember the EXTRA_VERSION before we diddle it here
477 # XXX - we really should not diddle with any values read in from the
478 # target file. if we want to modify a value, we should create
480 PRISTINE_EXTRA_VERSION=$EXTRA_VERSION
482 if ! $PATCHLESS && [ ! -f "$CONFIG_FILE" ]; then
483 fatal 1 "Config file for target $TARGET missing from" \
484 "$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
487 if [ "$EXTRA_VERSION_save" ]; then
488 EXTRA_VERSION="$EXTRA_VERSION_save"
489 elif ! $RELEASE; then
490 # if there is no patch series, then this is not a lustre specific
491 # kernel. don't make it look like one
492 if [ -n "$SERIES" ]; then
493 #remove the @VERSION@ (lustre version)
494 # EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
495 # EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
496 ! ( $PATCHLESS ) && EXTRA_VERSION="${EXTRA_VERSION}.${TIMESTAMP}"
499 # EXTRA_VERSION=${EXTRA_VERSION//-/_}
501 ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $BIGSMP_ARCHS $PSERIES64_ARCHS $UP_ARCHS"
504 for arch in $(uniqify "$ALL_ARCHS"); do
505 if [ -z "$TARGET_ARCHS" ] ||
506 [[ \ $TARGET_ARCHS\ = *\ $arch\ * ]]; then
507 BUILD_ARCHS="$BUILD_ARCHS $arch"
510 [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
511 echo "Building for: $BUILD_ARCHS"
519 fatal 1 "tarflags(): File name argument missing."
531 fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
540 echo "Untarring ${file##*/}..."
541 tar $(tarflags "$file") "$file"
547 if ! untar "$KERNELTREE/OFED-${OFED_VERSION}.tgz"; then
550 [ -d OFED ] || ln -sf OFED-[0-9].[0-9]* OFED
556 if [ -z "$LUSTRE" ]; then
559 if [ -n "$USE_DATESTAMP" ]; then
560 DATESTAMP="-D '$DATE'"
563 local DIRNAME="lustre-$TAG-$TIMESTAMP"
565 cvs -d "$CVSROOT" -qz3 co $DATESTAMP -d "$DIRNAME" lustre || \
566 fatal 1 "There was an error checking out toplevel Lustre from CVS."
567 pushd "$DIRNAME" > /dev/null
568 ./lustrecvs "$TAG" || \
569 fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
570 echo "Creating lustre tarball..."
571 sh autogen.sh || fatal 1 "There was an error running autogen.sh."
572 ./configure --disable-{modules,utils,liblustre,tests,doc} || \
573 fatal 1 "There was an error running ./configure to create makefiles."
574 make dist || fatal 1 "There was an error running 'make dist'."
575 LUSTRE=$PWD/lustre-*.tar.gz
579 untar "$LUSTRE" || fatal 1 "Error unpacking Lustre tarball"
580 [ -d lustre ] || ln -sf lustre-[0-9].[0-9]* lustre
586 local do_patch=${1:-true}
588 FULL_PATCH="$PWD/lustre-kernel-${TARGET}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}.patch"
589 [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
590 $do_patch && pushd linux >/dev/null
591 for series in $SERIES; do
592 echo -n "Applying series $series:"
593 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
594 [ -r "$patchesdir/series/$series" ] || continue
595 SERIES_FILE="$patchesdir/series/$series"
596 for patch in $(<"$SERIES_FILE"); do
598 PATCH_FILE="$patchesdir/patches/$patch"
599 [ -r "$PATCH_FILE" ] || \
600 fatal 1 "Patch $patch does not exist in Lustre tree."
601 cat "$PATCH_FILE" >> "$FULL_PATCH" || {
603 fatal 1 "Error adding patch $patch to full patch."
606 patch -s -p1 < "$PATCH_FILE" || {
608 fatal 1 "Error applying patch $patch."
616 $do_patch && popd >/dev/null
617 echo "Full patch has been saved in ${FULL_PATCH##*/}."
625 pushd lustre >/dev/null
627 echo "Building Lustre RPMs for: $BUILD_ARCHS..."
629 for arch in $BUILD_ARCHS; do
630 targets="--target $arch $targets"
633 local confoptions="--with-linux=${LINUX}"
635 confoptions="--with-linux=${LINUX} --disable-server"
637 if [ ! "$LINUXOBJ" = "" ]; then
638 confoptions="$confoptions --with-linux-obj=${LINUXOBJ}"
641 ./configure $confoptions ${CONFIGURE_FLAGS}
642 if [ "$?" != "0" ]; then
643 local saved_config="../config.log.$(date +%s)"
644 cp config.log $saved_config
645 chmod a+r $saved_config
646 echo "Saved config.log is at $saved_config"
650 echo "config.log contents:"
658 # hack. Somebody move build/lustre.spec to lustre.spec for b1_6
660 [ -f lustre.spec ] && lustre_spec=lustre.spec
661 [ -f build/lustre.spec ] && lustre_spec=build/lustre.spec
663 [ -f "$lustre_spec" ] && sed \
664 -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
668 local rpmbuildopt='-bb'
671 echo NORPM mode. Only compiling.
674 # convert the $PATCHLESS boolean to an empty/no-empty boolean
675 # as silly as this seems, it makes the syntax of the rpmbuild command
676 # simpler and not need an eval to deal with the quotes in the quotes
677 local is_patchless=""
681 $RPMBUILD $targets $rpmbuildopt ../lustre.spec \
682 ${is_patchless:+--define "lustre_name lustre-client"} \
683 --define "_tmppath $TMPDIR" \
684 --define "_topdir $TOPDIR" || \
685 fatal 1 "Error building rpms for $BUILD_ARCHS."
688 ( $(skeep_ldiskfs_rpm $TAG) ) && return
690 pushd lustre/ldiskfs || return 255
692 if [ "$?" != "0" ]; then
696 cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
700 local ldiskfs_spec=lustre-ldiskfs.spec
701 [ -f "$ldiskfs_spec" ] && sed \
702 -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
704 > ../lustre-ldiskfs.spec
706 $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
707 --define "_tmppath /var/tmp" \
708 --define "_topdir $TOPDIR"
709 if [ "$?" != "0" ]; then
715 $RPMBUILD -bs ../lustre-ldiskfs.spec \
716 --define "_tmppath /var/tmp" \
717 --define "_topdir $TOPDIR"
718 if [ "$?" != "0" ]; then
729 [ "$STAGEDIR" ] || return 0
731 for arch in $BUILD_ARCHS; do
732 rpmdir="${STAGEDIR}/${CANONICAL_TARGET}-${arch}"
733 echo "${0##*/}: Copying RPMs into ${rpmdir}"
735 cp -v RPMS/${arch}/*.rpm "${rpmdir}"
736 if [ -d RPMS/noarch ]; then
737 cp -v RPMS/noarch/*.rpm "${rpmdir}"
741 cp -v "$LUSTRE" "$STAGEDIR"
745 #check if we need to build separate ldiskfs RPM
746 skeep_ldiskfs_rpm() {
751 if ! $LDISKFSRPM; then
753 elif $PATCHLESS; then
756 for skiptag in $SKIPLDISKFSRPM; do
757 [[ $tag == $skiptag ]] && skip=true && break
761 pushd $TOPDIR/BUILD/lustre-[1-9]* >/dev/null
762 grep -q '^SERVER_TRUE[ \t]=[ \t]#$' autoMakefile && skip=true
769 #generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
770 gen_lustre_version() {
772 LUSTRE_EXTRA_VERSION="${lnxmaj}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}${TARGET_DELIMITER}${RPMSMPTYPE}"
773 LUSTRE_EXTRA_VERSION=${LUSTRE_EXTRA_VERSION//-/_}
779 local infact_arch="${TARGET_ARCH}"
782 [ "$infact_arch" == "i586" ] && infact_arch="i686"
785 for smp_type in $SMP_ARCHS; do
786 [ $infact_arch == $smp_type ] && RPMSMPTYPE=smp && break
789 for smp_type in $BIGSMP_ARCHS; do
790 [ $infact_arch == $smp_type ] && RPMSMPTYPE=bigsmp && break
793 for smp_type in $DEFAULT_ARCHS; do
794 [ $infact_arch == $smp_type ] && RPMSMPTYPE=default && break
799 # This function takes a linux source pool and digs out the linux release
801 find_linux_release() {
804 local LINUXRELEASEHEADER=$SRCDIR/include/linux/version.h
805 if [ -s $SRCDIR/include/linux/utsrelease.h ]; then
806 LINUXRELEASEHEADER=$SRCDIR/include/linux/utsrelease.h
809 sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' $LINUXRELEASEHEADER
813 # XXX this needs to be re-written as a wrapper around find_rpm
814 # or just gotten rid of. :-)
817 local delimiter=${2:-"-"}
819 local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
820 [ -d $pathtorpms ] || return 255
822 local kernelbinaryrpm rpmfile
823 local wanted_kernel="${lnxmaj}${delimiter}${lnxrel}"
826 for arch in $TARGET_ARCHS_ALL; do
827 local found_rpm="" rpm
828 for rpm in ${pathtorpms}/${arch}/*.rpm; do
829 if rpm -q --provides -p "$rpm" | grep -q "kernel${prefix} = $wanted_kernel"; then
835 [ -f "$found_rpm" ] && break
843 # unpack kernel(/source/devel) RPM
845 # This function and it's setting of $LINUX and $LINUXOBJ is a total hack that
846 # needs to completely refactored. It completely ingores that $BUILD_ARCHS may
847 # contain a list of arches for which rpmbuild commands (including the one for
849 unpack_linux_devel_rpm() {
850 local kernelrpm="${1}"
851 # it's worth noting that neither sles10 nor rhel5 appear to use their
852 # extra_version delimiter for the dirname under /usr/src, so we could
853 # probably just get rid of this parameter
854 local delimiter=${2:-"-"}
856 [ -f "$kernelrpm" ] || return 255
857 [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
859 pushd $TOPDIR/reused || return 255
861 if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
865 # call a distro specific hook, if available
866 if type -p unpack_linux_devel_rpm-$DISTRO; then
867 unpack_linux_devel_rpm-$DISTRO "$kernelrpm"
872 find_linux_devel_paths $TOPDIR/reused
878 # XXX - this rhel/sles goop needs abstracting out into the
879 # lbuild-{rhel5,sles10} method files
880 find_linux_devel_paths() {
886 # RHEL-style and SLES-style rpms
887 # XXX - until bug 19336 cleans this up, we need to extricate the
888 # ${lnxmin}- from the $lnxrel
889 local paths="kernels/${lnxmaj}${lnxmin}${delimiter}${lnxrel}-${TARGET_ARCH} linux-${lnxmaj}${lnxmin}${delimiter}${lnxrel##${lnxmin#.}-}"
892 for path in $paths; do
895 if [ -d "$src/$path/" ]; then
896 LINUX="$(pwd)/$src/$path"
898 # SLES has a separate -obj tree
899 if [ -d "$src/${path}-obj" ]; then
900 local src="$src/${path}-obj"
901 local objects="$TARGET_ARCH/$RPMSMPTYPE"
903 # Novell, are you *TRYING* to make life hard for me?
904 if [ -d "$src/powerpc" ]; then
905 objects="powerpc/$TARGET_ARCH"
906 elif [ $TARGET_ARCH == 'i686' ]; then
907 objects="i386/$RPMSMPTYPE"
910 LINUXOBJ="$(pwd)/$src/$objects"
913 if [ -z "$LINUX" ]; then
916 # dig out the release version
917 LINUXRELEASE=$(find_linux_release ${LINUXOBJ:-$LINUX})
918 if [ -z "$LINUXRELEASE" ]; then
919 echo "Failed to find linux release in ${LINUXOBJ:-$LINUX}"
928 # build kernel-ib{,-devel}
929 # some I/B drivers are architecture dependent and kernel-ib's configure
930 # does not figure it out for us ~sigh~
931 local configure_options=""
932 case "$TARGET_ARCH" in
934 configure_options="--with-ipath_inf-mod"
937 configure_options="--with-ipath_inf-mod --with-ehca-mod"
941 # ofed 1.3 had a bug in the rpm spec
942 if [ "$OFED_VERSION" = "1.3" ]; then
945 $RPMBUILD --rebuild --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
946 --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
947 --define "KVERSION ${LINUXRELEASE}" \
948 --define "$K_SRC ${LINUXOBJ:-${LINUX}}" \
949 --define "LIB_MOD_DIR /lib/modules/${LINUXRELEASE}/updates" \
950 --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-mlx4_en-mod --with-cxgb3-mod --with-nes-mod --with-ipoib-mod --with-sdp-mod --with-srp-mod --with-rds-mod --with-iser-mod --with-qlgc_vnic-mod --with-madeye-mod $configure_options" ${TOPDIR}/OFED/SRPMS/ofa_kernel-*.src.rpm
952 if [ ${PIPESTATUS[0]} != 0 ]; then
953 fatal 1 "Error building kernel-ib"
970 location="$location"/"$signature"/"$module"
972 # the cleanup script removes any directory that doesn't have a
973 # .lastused, so let's try to prevent that as soon as we can
974 # this solution still slightly racy with the cleanup script
975 # but the race is a lot tighter now
976 touch -t 197001010000 "$location/.lastused"
977 ## use eval/echo here to make sure shell expansions are performed
978 #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
980 for article in $(eval echo $articles); do
981 if ! cp -a${linkflag} "$article" "$location"; then
982 error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
983 # rename the cache location so that it's not cached
984 # product, but is around for analysis
985 mv "$location"{,-bad-$(date +%s)} ||
986 error "failed to clean up a failed cache attempt" \
987 "in \"$location\" -- manual cleanup will be" \
993 # flag the cache as complete (i.e. in case lbuild was previously
994 # interrupted while caching)
995 touch "$location/.lastused"
1004 local use_links="${3:-false}"
1005 local signature="$4"
1007 if [ -n "$REUSEBUILD" ] && [ -d "$REUSEBUILD/$signature/$module" ]; then
1008 if [ ! -f "$REUSEBUILD/$signature/$module/.lastused" ]; then
1009 # the .lastused flag is populated at the end of the caching to
1010 # signal that the caching was completeld. if that flag is not
1011 # there, then the cache is invalid (and should be removed in fact)
1012 mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} ||
1013 fatal 1 "failed to clean up a bad cache in location" \
1014 "\"$REUSEBUILD/$signature/$module\" -- manual cleanup" \
1019 # so that we know how stale this entry is
1020 touch $REUSEBUILD/$signature/$module/.lastused
1023 if ls $REUSEBUILD/$signature/$module/* >/dev/null 2>&1; then
1024 cp -al $REUSEBUILD/$signature/$module/* $dest/
1027 # copying is pretty heavy
1028 # cp -a $REUSEBUILD/$signature/$module/* $dest/
1029 # do some creative symlinking instead
1031 for dir in BUILD SRPMS SPECS; do
1032 if ls $REUSEBUILD/$signature/$module/$dir/* >/dev/null 2>&1; then
1033 ln -s $REUSEBUILD/$signature/$module/$dir/* $dest/$dir
1036 # sources have to be copied by file because we need SOURCES to
1037 # be a dir we can write into
1038 # could overrun ls's arg list here
1039 #ls $REUSEBUILD/$signature/$module/SOURCES/* |
1040 find $REUSEBUILD/$signature/$module/SOURCES/ -type f |
1041 xargs ln -t $dest/SOURCES -s
1043 # same for RPMS/* dirs
1044 # could overrun ls's arg list here
1045 #ls $REUSEBUILD/$signature/$module/RPMS/$TARGET_ARCH/* |
1047 for dir in $REUSEBUILD/$signature/$module/RPMS/*; do
1048 mkdir -p $dest/RPMS/${dir##*/}
1050 xargs ln -t $dest/RPMS/${dir##*/} -s
1063 if [[ $arch = i[3456]86 ]]; then
1072 # in a given directory, find the first rpm matching given requirements
1076 local match_type="$2"
1079 pushd "$dir" > /dev/null || \
1080 fatal 1 "Unable to chdir to directory \"$dir\" in find_rpm()"
1083 for file in $(ls *.rpm); do
1084 if [ ! -f "$file" ]; then
1087 case "$match_type" in
1089 # match is any valid ERE (i.e. given to egrep) match
1090 if rpm -q --provides -p "$file" | egrep -q "$match"; then
1098 fatal 1 "Unknown match type \"$match_type\" given to find_rpm()"
1107 build_kernel_with_srpm() {
1109 # need to generate the patch for this target
1110 do_patch_linux false >&2 # sets global $FULL_PATCH (yeah, yuck)
1112 # get an md5sum of the kernel patch + config for reuse check
1113 # XXX really, there needs to be a signature and a CONFIG_FILE per arch
1115 local REUSE_SIGNATURE=$({ echo $BUILD_GEN; cat $CONFIG_FILE $TARGET_FILE $FULL_PATCH; } | md5sum | cut -d" " -f1)
1117 # see if we can link to the reuse pool
1118 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1119 local CAN_LINK_FOR_REUSE=false
1120 touch $REUSEBUILD/$$
1121 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1122 CAN_LINK_FOR_REUSE=true
1126 # the extra version string to use for the kernel (which might be a reused
1128 local kernel_extra_version=""
1129 if $REUSERPM && ! reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1130 "$REUSE_SIGNATURE"; then
1131 # nothing cached, build from scratch
1132 if [ ! -r "$KERNELDIR/$KERNEL_SRPM" ]; then
1133 download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&2
1136 if ! rpm -ivh $KERNELDIR/$KERNEL_SRPM \
1137 --define "_topdir $TOPDIR" >&2; then
1138 # should we clean this up or leave it for analysis?
1140 fatal 1 "Error installing kernel SRPM."
1143 # put the Lustre kernel patch into the RPM build tree
1144 cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
1145 prepare_and_build_srpm >&2
1147 # store the resulting kernel RPM build tree for future use
1148 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1149 "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1150 "$CAN_LINK_FOR_REUSE"; then
1151 error "Failed to store kernel RPMS for reuse"
1157 # figure out the EXTRA_VERSION of the kernel we built or are re-using
1159 if ! KERNEL_RPM=$(find_rpm "$TOPDIR/RPMS/$TARGET_ARCH/" provides "^kernel ="); then
1160 fatal 1 "Failed to find a kernel RPM in $TOPDIR/RPMS/$TARGET_ARCH/"
1162 kernel_extra_version=$(rpm -q --queryformat "%{RELEASE}" -p $TOPDIR/RPMS/$TARGET_ARCH/$KERNEL_RPM)
1164 # should now have the following RPMs
1165 # $TOPDIR/RPMS/$arch/kernel-lustre-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1166 # $TOPDIR/RPMS/$arch/kernel-lustre-devel-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1167 # $TOPDIR/RPMS/$arch/kernel-lustre-headers-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1168 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-common-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1169 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1171 echo $kernel_extra_version
1178 if ! $PATCHLESS; then
1179 local kernel_extra_version
1180 if ! kernel_extra_version=$(build_kernel_with_srpm); then
1181 fatal 1 "Failed to build the kernel from it's SRPM"
1184 for arch in $BUILD_ARCHS; do
1186 local kernel_devel_rpm
1187 if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/$arch/" provides "^$(devel_kernel_name $KERNEL_LUSTRE_NAMING) ="); then
1188 fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/$arch/"
1191 # install the -devel RPM in preparation for the lustre build
1192 # note that the EXTRA_VERSION_DELIMITER is *NOT* used in the
1193 # version of the directory name under /usr/src
1194 if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
1195 "$TOPDIR/RPMS/$arch/$kernel_devel_rpm" "-"; then
1196 fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/$arch/$kernel_devel_rpm"
1200 # need to find and unpack the vendor's own kernel-devel for patchless
1203 if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE" ${EXTRA_VERSION_DELIMITER:-"-"}); then
1204 fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in ${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
1206 if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
1207 fatal 1 "Could not find the Linux tree in $kernelrpm"
1211 # before lustre, build kernel-ib
1212 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1213 # see if we can link to the reuse pool
1214 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1215 local CAN_LINK_FOR_REUSE=false
1216 touch $REUSEBUILD/$$
1217 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1218 CAN_LINK_FOR_REUSE=true
1222 local REUSE_SIGNATURE=$({ echo "$OFED_VERSION"; echo "$(find_linux_release ${LINUXOBJ:-$LINUX})"; cat "${LINUXOBJ:-${LINUX}}/include/linux/autoconf.h"; } | md5sum | cut -d" " -f1)
1223 if ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1224 "$REUSE_SIGNATURE"; then
1225 # stash away the existing built articles for a moment
1227 mv {BUILD,{S,}RPMS,S{OURCE,PEC}S} bak
1230 find . | cpio -pudlm ..
1234 create_rpmbuild_dirs
1237 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1238 "ofed" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1239 "$CAN_LINK_FOR_REUSE"; then
1240 error "Failed to store OFED RPMS for reuse"
1244 # put the stuff we stashed away back
1248 pushd "$TOPDIR" >/dev/null
1249 rm -rf kernel-ib-devel
1250 mkdir kernel-ib-devel
1252 # the actual ofed RPMs don't have the -rc$n or -$date string appened that
1253 # might be present on the file
1254 local ofed_version=$(echo $OFED_VERSION |
1255 sed -re 's/-(20[0-9]{6,6}-[0-9]{4,4}|rc[0-9]*)$//')
1256 local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version}-${LINUXRELEASE//-/_}.*.rpm)
1257 rpm2cpio -itv < $rpm | cpio -id
1258 CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
1263 if build_lustre; then
1264 # the build worked. resolve any symlinked files (i.e. from reuse)
1265 # in RPMS/$arch to real files so that that that huge mess of
1266 # complication knows as LTS can copy them yet somewhere else.
1267 # is it any wonder this whole process is so damn so? anyone ever
1268 # heard of hardlinks? it this cool new thing that allows you save
1269 # tons of time and space by creating... well you can go read about
1270 # them if you have not heard about them yet.
1271 # can i say how much the implemenation of all of this really impedes
1273 pushd RPMS/$TARGET_ARCH
1275 if [ -h $file ]; then
1287 create_rpmbuild_dirs() {
1289 [ -d RPMS ] || mkdir RPMS
1290 for arch in $BUILD_ARCHS; do
1291 if [[ $arch = i?86 ]]; then
1292 # some stupidity in the sles11 kernel spec requires an RPMS/i386
1293 # even if the target arch is i686
1294 [ -d RPMS/i386 ] || mkdir RPMS/i386
1296 [ -d RPMS/$arch ] || mkdir RPMS/$arch
1298 [ -d BUILD ] || mkdir BUILD
1299 [ -d SOURCES ] || mkdir SOURCES
1300 [ -d SPECS ] || mkdir SPECS
1301 [ -d SRPMS ] || mkdir SRPMS
1323 [[ $list\ == *\ $item\ * ]]
1327 #########################################################################
1328 # Generate a backtrace through the call stack.
1332 #########################################################################
1336 local funcname="" sourcefile="" lineno="" n
1338 echo "Call stack: (most recent first)"
1339 for (( n = $strip ; n < ${#FUNCNAME[@]} ; ++n )) ; do
1340 funcname=${FUNCNAME[$n - 1]}
1341 sourcefile=$(basename ${BASH_SOURCE[$n]})
1342 lineno=${BASH_LINENO[$n - 1]}
1343 # Display function arguments
1344 if [[ ! -z "${BASH_ARGV[@]}" ]]; then
1345 local args newarg j p=0
1346 for (( j = ${BASH_ARGC[$n - 1]}; j > 0; j-- )); do
1347 newarg=${BASH_ARGV[$j + $p - 1]}
1348 args="${args:+${args} }'${newarg}'"
1350 let p+=${BASH_ARGC[$n - 1]}
1352 echo " ${funcname} ${args:+${args} }at ${sourcefile}:${lineno}"
1356 echo "BEGIN BACKTRACE"
1358 #echo ${BASH_LINENO[*]}
1359 #echo ${BASH_SOURCE[*]}
1360 #echo ${FUNCNAME[*]}
1361 local i=$((${#FUNCNAME[@]} - 1))
1362 while [ $i -ge 0 ]; do
1363 local SOURCELINE="${BASH_SOURCE[$i + 1]}:${BASH_LINENO[$i]}"
1364 # Can't figure out how to get function args from other frames...
1365 local FUNCTION="${FUNCNAME[$i]}()"
1366 echo "$SOURCELINE:$FUNCTION"
1370 echo "END BACKTRACE"
1376 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
1378 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:,xen -- "$@")
1380 if [ $? != 0 ]; then
1384 eval set -- "$options"
1419 if ! KERNELTREE=$(canon_path "$2"); then
1420 fatal 1 "Could not determine the canonical location of $2"
1424 --linux | --with-linux)
1425 if ! LINUX=$(canon_path "$2"); then
1426 fatal 1 "Could not determine the canonical location of $2"
1439 if ! REUSEBUILD=$(canon_path "$2"); then
1440 fatal 1 "Could not determine the canonical location of $2"
1457 if ! KERNELRPMSBASE=$(canon_path "$2"); then
1458 fatal 1 "Could not determine the canonical location of $2"
1505 --disable-datestamp)
1516 CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
1520 usage 1 "Unrecognized option: $1"
1530 EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
1532 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1534 unpack_ofed || fatal 1 "Error unpacking OFED tarball"
1537 # make sure the RPM build environment is set up
1538 create_rpmbuild_dirs
1540 trap '[ -n "$CCACHE" ] && ccache -s' EXIT
1542 # if an unpacked kernel source tree was given on the command line
1543 # just build lustre with it (nothing distro kernel specific here)
1544 if [ -n "$LINUX" ]; then
1547 if [ -f "${0%/*}/lbuild-$DISTRO" ]; then
1548 seen_list=$(new_list)
1549 trap '(echo "Untrapped error"
1551 # have we seen this one
1552 echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
1554 if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
1555 echo "seen this one already"
1557 seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
1563 ) | tee >(mail -s "Untrapped error at ${BASH_SOURCE[0]##*/}:${BASH_LINENO[0]} on $HOSTNAME" brian@sun.com) >&2' ERR
1566 source ${0%/*}/lbuild-$DISTRO
1568 build_with_srpm || fatal 1 "Failed to build_with_srpm"
1570 source ${0%/*}/lbuild.old_school
1572 old_school_download_kernel
1576 patchless_build_sequence && build_success=true
1578 [ "$DISTRO" = "sles9" ] && build_sequence_rpm_reuse && build_success=true
1579 if ! $build_success; then
1580 build_sequence_reuse && build_success=true
1581 if ! $build_success; then
1582 build_sequence && build_success=true
1583 if $build_success; then
1584 store_for_reuse || echo "Cannot store for future reuse"
1589 ( $build_success ) || fatal 1 "Cannot build lustre"