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 ''"
65 # not in the target file any more
77 # Readlink is not present on some older distributions: emulate it.
81 if [ -L "$path" ]; then
82 ll="$(LC_ALL=C ls -l "$path" 2> /dev/null)" &&
97 [ -n "$msg" ] && echo -e "\n${0##*/}: $msg" >&2
111 Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
114 Specifies the CVS Root to use when pulling files from CVS. The
115 environment variable \$CVSROOT is used if this option is not
118 --external-patches=EXTERNAL_PATCHES
119 Directory similar to lustre/lustre/kernel_patches/ that lbuild should
120 look for seres and config files in before looking in the lustre
123 --extraversion=EXTRAVERSION
124 Text to use for the rpm release and kernel extraversion.
126 --timestamp=TIMESTAMP
127 Date of building lustre in format YYYYMMDDhhmmss
130 Try to reuse old kernel RPMs from DIR
133 Try to reuse old kernel builds from DIR
136 Path to distro kernel RPM collection
142 Do not build RPMs (compile only mode)
145 Build lustre client only
148 Which distro using. Autodetect by default
150 --kerneldir=KERNELDIR
151 Directory containing Linux source tarballs referenced by target
154 --kerneltree=KERNELTREE
155 Directory containing dirs with Linux source tarballs referenced by target
156 files. Dir names in format kernel version ('2.6.9', etc.)
158 --linux=LINUX --with-linux=LINUX
159 Directory of Linux kernel sources. When this option is used, only
160 Lustre modules and userspace are built.
163 Path to an existing lustre source tarball to use instead of
167 Do not try to download a kernel from downloads.lustre.org
170 Do not build a .src.rpm, a full kernel patch, or a patched kernel
174 Do ldiskfs RPM. Now true by default
180 Specifies that the files generated do not include timestamps, and
181 that this is an official release.
184 Build a .src.rpm, a full kernel patch, and a patched kernel tarball.
187 Directory used to stage packages for release. RPMs will be placed
188 more or less in DIR/<target>-<arch>, and the tarball will be
192 A CVS branch/tag name to build from when pulling from CVS.
195 The name of the target to build. The available targets are listed
198 --target-archs=TARGET_ARCHS
199 A (space delimited) list of architectures to build. By default,
200 all of the archs supported by the TARGET will be built, in
201 addition to a .src.rpm. This option can limit those, for machines
202 that can only build certain archs or if you only want a certain
203 arch built (for testing, or a one-off kernel).
205 Also note that by using a non-"base" arch (eg, i386) only kernels
206 will be built - there will be no lustre-lite-utils package.
209 Prevents the datestamp flag (-D) from being passed to cvs for
210 checkouts. This is a workaround for a problem encountered when
211 using lbuild with tinderbox.
214 Builds a Xen domX kernel.
223 # canonicalize a relative path
227 if [ ! -d "$PATH" ]; then
231 pushd "$PATH" >/dev/null || return 1
241 if [ "$LUSTRE" ]; then
242 [ -r "$LUSTRE" ] || \
243 usage 1 "Could not find Lustre source tarball '$LUSTRE'."
246 usage 1 "Either specify a CVS Root with -d, or a Lustre source tarball with --lustre."
248 usage 1 "A branch/tag name must be specified with --tag when not building from a tarball."
251 if [ -z "$LINUX" ]; then
252 [ "$KERNELDIR" -o "$KERNELTREE" ] || \
253 usage 1 "A kernel directory must be specified with --kerneldir or --kerneltree."
255 [ -d "$KERNELDIR" -o -d "$KERNELTREE" ] || \
256 usage 1 "$KERNELDIR and $KERNELTREE are not a directory."
260 usage 1 "When building a snapshot, a tag name must be used."
263 [ "$TARGET" ] || usage 1 "A target must be specified with --target."
264 # TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
265 # [ -r "$TARGET_FILE" ] || \
266 # usage 1 "Target '$TARGET' was not found."
271 CANONICAL_TARGET="rhel5"
274 CANONICAL_TARGET="rhel-2.6"
277 CANONICAL_TARGET="sles-2.6"
280 CANONICAL_TARGET="sles10-2.6"
283 CANONICAL_TARGET="sles11"
286 CANONICAL_TARGET="hp-pnnl-2.4"
294 CANONICAL_TARGET="$TARGET"
298 local timestampnodig=$(echo $TIMESTAMP | sed -e s/[0-9]*//g)
299 [ "$timestampnodig" = "" ] || TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
300 local timestamplength="${#TIMESTAMP}"
301 if [ $timestamplength -eq 12 ]; then
302 TIMESTAMP="${TIMESTAMP}00"
303 elif [ $timestamplength -ne 14 ]; then
304 TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
307 RPMBUILD=$(which rpmbuild 2>/dev/null | head -1)
308 if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
309 RPMBUILD=$(which rpm 2>/dev/null | head -1)
310 if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
311 usage 1 "Could not find binary for making rpms (tried rpmbuild and rpm)."
315 if [ -n "$CCACHE" ]; then
316 which "$DISTCC" 2>/dev/null && export DISTCC RPM_BUILD_NCPUS
318 if which "$CCACHE" 2>/dev/null; then
319 local ccache=$(which "$CCACHE")
320 local bindir="$TOPDIR/bin"
322 [ -d $bindir ] || mkdir -p $bindir
323 if [ -d $bindir ]; then
324 rm ${bindir}/* > /dev/null 2>&1
325 ln -s "$ccache" ${bindir}/ccache
326 ln -s "$ccache" ${bindir}/cc
327 ln -s "$ccache" ${bindir}/$CC
328 export PATH=$bindir:$PATH
330 export CCACHE && export CC="ccache $CC"
331 # zero the cache so we can see how effective we are being with it
336 [ -z "$DISTRO" ] && DISTRO=$(autodetect_distro)
339 # autodetect used Distro
340 autodetect_distro() {
345 if [ -f /etc/SuSE-release ]; then
347 version=$(grep ^VERSION /etc/SuSE-release)
348 version=${version#*= }
349 elif [ -f /etc/redhat-release ]; then
350 name=$(head -1 /etc/redhat-release)
351 version=$(echo "$distroname" |
352 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ \.].*//')
354 if [ -z "$name" -o -z "$version" ]; then
355 fatal 1 "I don't know how to determine distro type/version.\n" \
356 "Either update autodetect_distro() or use the --distro argument"
359 echo ${name}${version}
366 echo $(echo "$*" | xargs -n 1 | sort -u)
373 local force="${3:-false}"
375 if $force || [ ! -r "$KERNELDIR/$srpm" ] ||
376 [ ! -s "$KERNELDIR/$srpm" ]; then
378 local location="http://downloads.lustre.org/public/kernels/$target/old"
379 echo "Downloading $location/$srpm..."
380 if ! wget -nv "$location/$srpm" -O "$KERNELDIR/$srpm" ||
381 [ ! -s "$KERNELDIR/$srpm" ]; then
382 rm -f $KERNELDIR/$srpm
383 fatal 1 "Could not download target $target's kernel SRPM" \
384 "$srpm from $location."
387 fatal 1 "$srpm not found in directory $KERNELDIR."
394 local force="${1:-false}"
396 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ] &&
397 ( $force || [ ! -r "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ||
398 [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ); then
400 local location="http://downloads.lustre.org/public/OFED/"
401 echo "Downloading $location/OFED-${OFED_VERSION}.tgz..."
402 if ! wget -nv "$location/OFED-${OFED_VERSION}.tgz" \
403 -O "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ||
404 [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ]; then
405 rm -f $KERNELTREE/OFED-${OFED_VERSION}.tgz
406 fatal 1 "Could not download OFED-${OFED_VERSION}.tgz" \
407 "from downloads.lustre.org."
410 fatal 1 "OFED-${OFED_VERSION}.tgz not found in kernel" \
411 "directory $KERNELTREE."
419 EXTRA_VERSION_save="$EXTRA_VERSION"
420 for patchesdir in "$EXTERNAL_PATCHES" \
421 "$TOPDIR/lustre/lustre/kernel_patches"; do
422 TARGET_FILE="$patchesdir/targets/$TARGET.target"
423 [ -r "$TARGET_FILE" ] && break
425 [ -r "$TARGET_FILE" ] || fatal 1 "Target $TARGET was not found."
427 echo "Loading target config file $TARGET.target..."
431 # doesn't make any sense to build OFED for xen domX's
436 # XXX - set_rpm_smp_type is an ugly undeterministic hack. it needs to
437 # go away and the target just specify the $RPMSMPTYPE
438 [ -z "$RPMSMPTYPE" ] && set_rpm_smp_type
440 # CC might have been overwriten in TARGET_FILE
441 if [[ $CC != ccache\ * ]] && which "$CCACHE" 2>/dev/null; then
442 export CCACHE && export CC="ccache $CC"
445 if [ ! "$KERNELTREE" = "" ] && [ -d "$KERNELTREE" ]; then
446 KERNELDIR="$KERNELTREE/${lnxmaj}"
447 [ -d "$KERNELDIR" ] || mkdir "$KERNELDIR"
450 # verify the series is available
451 if [ "$SERIES" ]; then
452 for series in $SERIES; do
453 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
454 [ -r "$patchesdir/series/$series" ] && continue 2
456 fatal 1 "Target $TARGET's series $SERIES could not be" \
457 "found.\nSearched:\n\t$EXTERNAL_PATCHES/series\n" \
458 "\t$TOPDIR/lustre/lustre/kernel_patches/series."
462 # set the location of the .config file
468 if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config ]; then
469 CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET$XENPOSTFIX-$TARGET_ARCH${RPMSMPTYPE:+-}${RPMSMPTYPE}.config"
472 local lnxrelnew=${lnxrel//-/_}
474 # remember the EXTRA_VERSION before we diddle it here
475 # XXX - we really should not diddle with any values read in from the
476 # target file. if we want to modify a value, we should create
478 PRISTINE_EXTRA_VERSION=$EXTRA_VERSION
480 if ! $PATCHLESS && [ ! -f "$CONFIG_FILE" ]; then
481 fatal 1 "Config file for target $TARGET missing from" \
482 "$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
485 if [ "$EXTRA_VERSION_save" ]; then
486 EXTRA_VERSION="$EXTRA_VERSION_save"
487 elif ! $RELEASE; then
488 # if there is no patch series, then this is not a lustre specific
489 # kernel. don't make it look like one
490 if [ -n "$SERIES" ]; then
491 #remove the @VERSION@ (lustre version)
492 # EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
493 # EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
494 ! ( $PATCHLESS ) && EXTRA_VERSION="${EXTRA_VERSION}.${TIMESTAMP}"
497 # EXTRA_VERSION=${EXTRA_VERSION//-/_}
499 ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $BIGSMP_ARCHS $PSERIES64_ARCHS $UP_ARCHS"
502 for arch in $(uniqify "$ALL_ARCHS"); do
503 if [ -z "$TARGET_ARCHS" ] ||
504 [[ \ $TARGET_ARCHS\ = *\ $arch\ * ]]; then
505 BUILD_ARCHS="$BUILD_ARCHS $arch"
508 [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
509 echo "Building for: $BUILD_ARCHS"
517 fatal 1 "tarflags(): File name argument missing."
529 fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
538 echo "Untarring ${file##*/}..."
539 tar $(tarflags "$file") "$file"
545 if ! untar "$KERNELTREE/OFED-${OFED_VERSION}.tgz"; then
548 [ -d OFED ] || ln -sf OFED-[0-9].[0-9]* OFED
554 if [ -z "$LUSTRE" ]; then
557 if [ -n "$USE_DATESTAMP" ]; then
558 DATESTAMP="-D '$DATE'"
561 local DIRNAME="lustre-$TAG-$TIMESTAMP"
563 cvs -d "$CVSROOT" -qz3 co $DATESTAMP -d "$DIRNAME" lustre || \
564 fatal 1 "There was an error checking out toplevel Lustre from CVS."
565 pushd "$DIRNAME" > /dev/null
566 ./lustrecvs "$TAG" || \
567 fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
568 echo "Creating lustre tarball..."
569 sh autogen.sh || fatal 1 "There was an error running autogen.sh."
570 ./configure --disable-{modules,utils,liblustre,tests,doc} || \
571 fatal 1 "There was an error running ./configure to create makefiles."
572 make dist || fatal 1 "There was an error running 'make dist'."
573 LUSTRE=$PWD/lustre-*.tar.gz
577 untar "$LUSTRE" || fatal 1 "Error unpacking Lustre tarball"
578 [ -d lustre ] || ln -sf lustre-[0-9].[0-9]* lustre
584 local do_patch=${1:-true}
586 FULL_PATCH="$PWD/lustre-kernel-${TARGET}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}.patch"
587 [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
588 $do_patch && 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
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" || {
601 fatal 1 "Error adding patch $patch to full patch."
604 patch -s -p1 < "$PATCH_FILE" || {
606 fatal 1 "Error applying patch $patch."
614 $do_patch && popd >/dev/null
615 echo "Full patch has been saved in ${FULL_PATCH##*/}."
623 pushd lustre >/dev/null
625 echo "Building Lustre RPMs for: $BUILD_ARCHS..."
627 for arch in $BUILD_ARCHS; do
628 targets="--target $arch $targets"
631 local confoptions="--with-linux=${LINUX}"
633 confoptions="--with-linux=${LINUX} --disable-server"
635 if [ ! "$LINUXOBJ" = "" ]; then
636 confoptions="$confoptions --with-linux-obj=${LINUXOBJ}"
639 ./configure $confoptions ${CONFIGURE_FLAGS}
640 if [ "$?" != "0" ]; then
641 local saved_config="../config.log.$(date +%s)"
642 cp config.log $saved_config
643 chmod a+r $saved_config
644 echo "Saved config.log is at $saved_config"
648 echo "config.log contents:"
656 # hack. Somebody move build/lustre.spec to lustre.spec for b1_6
658 [ -f lustre.spec ] && lustre_spec=lustre.spec
659 [ -f build/lustre.spec ] && lustre_spec=build/lustre.spec
661 [ -f "$lustre_spec" ] && sed \
662 -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
666 local rpmbuildopt='-bb'
669 echo NORPM mode. Only compiling.
672 # convert the $PATCHLESS boolean to an empty/no-empty boolean
673 # as silly as this seems, it makes the syntax of the rpmbuild command
674 # simpler and not need an eval to deal with the quotes in the quotes
675 local is_patchless=""
679 $RPMBUILD $targets $rpmbuildopt ../lustre.spec \
680 ${is_patchless:+--define "lustre_name lustre-client"} \
681 --define "_tmppath $TMPDIR" \
682 --define "_topdir $TOPDIR" || \
683 fatal 1 "Error building rpms for $BUILD_ARCHS."
686 ( $(skeep_ldiskfs_rpm $TAG) ) && return
688 pushd lustre/ldiskfs || return 255
690 if [ "$?" != "0" ]; then
694 cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
698 local ldiskfs_spec=lustre-ldiskfs.spec
699 [ -f "$ldiskfs_spec" ] && sed \
700 -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
702 > ../lustre-ldiskfs.spec
704 $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
705 --define "_tmppath /var/tmp" \
706 --define "_topdir $TOPDIR"
707 if [ "$?" != "0" ]; then
713 $RPMBUILD -bs ../lustre-ldiskfs.spec \
714 --define "_tmppath /var/tmp" \
715 --define "_topdir $TOPDIR"
716 if [ "$?" != "0" ]; then
727 [ "$STAGEDIR" ] || return 0
729 for arch in $BUILD_ARCHS; do
730 rpmdir="${STAGEDIR}/${CANONICAL_TARGET}-${arch}"
731 echo "${0##*/}: Copying RPMs into ${rpmdir}"
733 cp -v RPMS/${arch}/*.rpm "${rpmdir}"
734 if [ -d RPMS/noarch ]; then
735 cp -v RPMS/noarch/*.rpm "${rpmdir}"
739 cp -v "$LUSTRE" "$STAGEDIR"
743 #check if we need to build separate ldiskfs RPM
744 skeep_ldiskfs_rpm() {
749 if ! $LDISKFSRPM; then
751 elif $PATCHLESS; then
754 for skiptag in $SKIPLDISKFSRPM; do
755 [[ $tag == $skiptag ]] && skip=true && break
762 #generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
763 gen_lustre_version() {
765 LUSTRE_EXTRA_VERSION="${lnxmaj}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}${TARGET_DELIMITER}${RPMSMPTYPE}"
766 LUSTRE_EXTRA_VERSION=${LUSTRE_EXTRA_VERSION//-/_}
772 local infact_arch="${TARGET_ARCH}"
775 [ "$infact_arch" == "i586" ] && infact_arch="i686"
778 for smp_type in $SMP_ARCHS; do
779 [ $infact_arch == $smp_type ] && RPMSMPTYPE=smp && break
782 for smp_type in $BIGSMP_ARCHS; do
783 [ $infact_arch == $smp_type ] && RPMSMPTYPE=bigsmp && break
786 for smp_type in $DEFAULT_ARCHS; do
787 [ $infact_arch == $smp_type ] && RPMSMPTYPE=default && break
792 # This function takes a linux source pool and digs out the linux release
794 find_linux_release() {
797 local LINUXRELEASEHEADER=$SRCDIR/include/linux/version.h
798 if [ -s $SRCDIR/include/linux/utsrelease.h ]; then
799 LINUXRELEASEHEADER=$SRCDIR/include/linux/utsrelease.h
802 sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' $LINUXRELEASEHEADER
806 # XXX this needs to be re-written as a wrapper around find_rpm
807 # or just gotten rid of. :-)
810 local delimiter=${2:-"-"}
812 local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
813 [ -d $pathtorpms ] || return 255
815 local kernelbinaryrpm rpmfile
816 local wanted_kernel="${lnxmaj}${delimiter}${lnxrel}"
819 for arch in $TARGET_ARCHS_ALL; do
820 local found_rpm="" rpm
821 for rpm in ${pathtorpms}/${arch}/*.rpm; do
822 if rpm -q --provides -p "$rpm" | grep -q "kernel${prefix} = $wanted_kernel"; then
828 [ -f "$found_rpm" ] && break
836 # unpack kernel(/source/devel) RPM
838 # This function and it's setting of $LINUX and $LINUXOBJ is a total hack that
839 # needs to completely refactored. It completely ingores that $BUILD_ARCHS may
840 # contain a list of arches for which rpmbuild commands (including the one for
842 unpack_linux_devel_rpm() {
843 local kernelrpm="${1}"
844 # it's worth noting that neither sles10 nor rhel5 appear to use their
845 # extra_version delimiter for the dirname under /usr/src, so we could
846 # probably just get rid of this parameter
847 local delimiter=${2:-"-"}
849 [ -f "$kernelrpm" ] || return 255
850 [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
852 pushd $TOPDIR/reused || return 255
854 if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
858 # call a distro specific hook, if available
859 if type -p unpack_linux_devel_rpm-$DISTRO; then
860 unpack_linux_devel_rpm-$DISTRO "$kernelrpm"
865 find_linux_devel_paths $TOPDIR/reused
871 # XXX - this rhel/sles goop needs abstracting out into the
872 # lbuild-{rhel5,sles10} method files
873 find_linux_devel_paths() {
879 # RHEL-style and SLES-style rpms
880 # XXX - until bug 19336 cleans this up, we need to extricate the
881 # ${lnxmin}- from the $lnxrel
882 local paths="kernels/${lnxmaj}${lnxmin}${delimiter}${lnxrel}-${TARGET_ARCH} linux-${lnxmaj}${lnxmin}${delimiter}${lnxrel##${lnxmin#.}-}"
885 for path in $paths; do
888 if [ -d "$src/$path/" ]; then
889 LINUX="$(pwd)/$src/$path"
891 # SLES has a separate -obj tree
892 if [ -d "$src/${path}-obj" ]; then
893 local src="$src/${path}-obj"
894 local objects="$TARGET_ARCH/$RPMSMPTYPE"
896 # Novell, are you *TRYING* to make life hard for me?
897 if [ -d "$src/powerpc" ]; then
898 objects="powerpc/$TARGET_ARCH"
899 elif [ $TARGET_ARCH == 'i686' ]; then
900 objects="i386/$RPMSMPTYPE"
903 LINUXOBJ="$(pwd)/$src/$objects"
906 if [ -z "$LINUX" ]; then
909 # dig out the release version
910 LINUXRELEASE=$(find_linux_release ${LINUXOBJ:-$LINUX})
911 if [ -z "$LINUXRELEASE" ]; then
912 echo "Failed to find linux release in ${LINUXOBJ:-$LINUX}"
921 # build kernel-ib{,-devel}
922 # some I/B drivers are architecture dependent and kernel-ib's configure
923 # does not figure it out for us ~sigh~
924 local configure_options=""
925 case "$TARGET_ARCH" in
927 configure_options="--with-ipath_inf-mod"
930 configure_options="--with-ipath_inf-mod --with-ehca-mod"
934 # ofed 1.3 had a bug in the rpm spec
935 if [ "$OFED_VERSION" = "1.3" ]; then
938 $RPMBUILD --rebuild --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
939 --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
940 --define "KVERSION ${LINUXRELEASE}" \
941 --define "$K_SRC ${LINUXOBJ:-${LINUX}}" \
942 --define "LIB_MOD_DIR /lib/modules/${LINUXRELEASE}/updates" \
943 --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
945 if [ ${PIPESTATUS[0]} != 0 ]; then
946 fatal 1 "Error building kernel-ib"
963 location="$location"/"$signature"/"$module"
965 # the cleanup script removes any directory that doesn't have a
966 # .lastused, so let's try to prevent that as soon as we can
967 # this solution still slightly racy with the cleanup script
968 # but the race is a lot tighter now
969 touch -t 197001010000 "$location/.lastused"
970 ## use eval/echo here to make sure shell expansions are performed
971 #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
973 for article in $(eval echo $articles); do
974 if ! cp -a${linkflag} "$article" "$location"; then
975 error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
976 # rename the cache location so that it's not cached
977 # product, but is around for analysis
978 mv "$location"{,-bad-$(date +%s)} ||
979 error "failed to clean up a failed cache attempt" \
980 "in \"$location\" -- manual cleanup will be" \
986 # flag the cache as complete (i.e. in case lbuild was previously
987 # interrupted while caching)
988 touch "$location/.lastused"
997 local use_links="${3:-false}"
1000 if [ -n "$REUSEBUILD" ] && [ -d "$REUSEBUILD/$signature/$module" ]; then
1001 if [ ! -f "$REUSEBUILD/$signature/$module/.lastused" ]; then
1002 # the .lastused flag is populated at the end of the caching to
1003 # signal that the caching was completeld. if that flag is not
1004 # there, then the cache is invalid (and should be removed in fact)
1005 mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} ||
1006 fatal 1 "failed to clean up a bad cache in location" \
1007 "\"$REUSEBUILD/$signature/$module\" -- manual cleanup" \
1012 # so that we know how stale this entry is
1013 touch $REUSEBUILD/$signature/$module/.lastused
1016 if ls $REUSEBUILD/$signature/$module/* >/dev/null 2>&1; then
1017 cp -al $REUSEBUILD/$signature/$module/* $dest/
1020 # copying is pretty heavy
1021 # cp -a $REUSEBUILD/$signature/$module/* $dest/
1022 # do some creative symlinking instead
1024 for dir in BUILD SRPMS SPECS; do
1025 if ls $REUSEBUILD/$signature/$module/$dir/* >/dev/null 2>&1; then
1026 ln -s $REUSEBUILD/$signature/$module/$dir/* $dest/$dir
1029 # sources have to be copied by file because we need SOURCES to
1030 # be a dir we can write into
1031 # could overrun ls's arg list here
1032 #ls $REUSEBUILD/$signature/$module/SOURCES/* |
1033 find $REUSEBUILD/$signature/$module/SOURCES/ -type f |
1034 xargs ln -t $dest/SOURCES -s
1036 # same for RPMS/* dirs
1037 # could overrun ls's arg list here
1038 #ls $REUSEBUILD/$signature/$module/RPMS/$TARGET_ARCH/* |
1040 for dir in $REUSEBUILD/$signature/$module/RPMS/*; do
1041 mkdir -p $dest/RPMS/${dir##*/}
1043 xargs ln -t $dest/RPMS/${dir##*/} -s
1056 if [[ $arch = i[3456]86 ]]; then
1065 # in a given directory, find the first rpm matching given requirements
1069 local match_type="$2"
1072 pushd "$dir" > /dev/null || \
1073 fatal 1 "Unable to chdir to directory \"$dir\" in find_rpm()"
1076 for file in $(ls); do
1077 if [ ! -f "$file" ]; then
1080 case "$match_type" in
1082 # match is any valid ERE (i.e. given to egrep) match
1083 if rpm -q --provides -p "$file" | egrep -q "$match"; then
1091 fatal 1 "Unknown match type \"$match_type\" given to find_rpm()"
1100 build_kernel_with_srpm() {
1102 # need to generate the patch for this target
1103 do_patch_linux false >&2 # sets global $FULL_PATCH (yeah, yuck)
1105 # get an md5sum of the kernel patch + config for reuse check
1106 # XXX really, there needs to be a signature and a CONFIG_FILE per arch
1108 local REUSE_SIGNATURE=$({ echo $BUILD_GEN; cat $CONFIG_FILE $TARGET_FILE $FULL_PATCH; } | md5sum | cut -d" " -f1)
1110 # see if we can link to the reuse pool
1111 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1112 local CAN_LINK_FOR_REUSE=false
1113 touch $REUSEBUILD/$$
1114 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1115 CAN_LINK_FOR_REUSE=true
1119 # the extra version string to use for the kernel (which might be a reused
1121 local kernel_extra_version=""
1122 if $REUSERPM && reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1123 "$REUSE_SIGNATURE"; then
1124 # figure out the EXTRA_VERSION of the kernel we are re-using
1126 if ! KERNEL_RPM=$(find_rpm "$TOPDIR/RPMS/$TARGET_ARCH/" provides "^kernel ="); then
1127 fatal 1 "Failed to find a kernel RPM in $TOPDIR/RPMS/$TARGET_ARCH/"
1129 kernel_extra_version=$(rpm -q --queryformat "%{RELEASE}" -p $TOPDIR/RPMS/$TARGET_ARCH/$KERNEL_RPM)
1131 # nothing cached, build from scratch
1132 if [ ! -r "$KERNELDIR/$KERNEL_SRPM" ]; then
1133 download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&2
1136 rpm -ivh $KERNELDIR/$KERNEL_SRPM --define "_topdir $TOPDIR" >&2 || {
1137 # should we clean this up or leave it for analysis?
1139 fatal 1 "Error installing kernel SRPM."
1142 # put the Lustre kernel patch into the RPM build tree
1143 cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
1144 prepare_and_build_srpm >&2
1146 # store the resulting kernel RPM build tree for future use
1147 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1148 "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1149 "$CAN_LINK_FOR_REUSE"; then
1150 error "Failed to store kernel RPMS for reuse"
1154 kernel_extra_version=$EXTRA_VERSION
1157 # should now have the following RPMs
1158 # $TOPDIR/RPMS/$arch/kernel-lustre-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1159 # $TOPDIR/RPMS/$arch/kernel-lustre-devel-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1160 # $TOPDIR/RPMS/$arch/kernel-lustre-headers-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1161 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-common-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1162 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1164 echo $kernel_extra_version
1171 if ! $PATCHLESS; then
1172 local kernel_extra_version
1173 if ! kernel_extra_version=$(build_kernel_with_srpm); then
1174 fatal 1 "Failed to build the kernel from it's SRPM"
1177 for arch in $BUILD_ARCHS; do
1179 local kernel_devel_rpm
1180 if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/$arch/" provides "^$(devel_kernel_name true) ="); then
1181 fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/$arch/"
1184 # install the -devel RPM in preparation for the lustre build
1185 # note that the EXTRA_VERSION_DELIMITER is *NOT* used in the
1186 # version of the directory name under /usr/src
1187 if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
1188 "$TOPDIR/RPMS/$arch/$kernel_devel_rpm" "-"; then
1189 fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/$arch/$kernel_devel_rpm"
1193 # need to find and unpack the vendor's own kernel-devel for patchless
1196 if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE" ${EXTRA_VERSION_DELIMITER:-"-"}); then
1197 fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in ${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
1199 if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
1200 fatal 1 "Could not find the Linux tree in $kernelrpm"
1204 # before lustre, build kernel-ib
1205 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1206 # see if we can link to the reuse pool
1207 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1208 local CAN_LINK_FOR_REUSE=false
1209 touch $REUSEBUILD/$$
1210 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1211 CAN_LINK_FOR_REUSE=true
1215 local REUSE_SIGNATURE=$({ echo "$OFED_VERSION"; echo "$(find_linux_release ${LINUXOBJ:-$LINUX})"; cat "${LINUXOBJ:-${LINUX}}/include/linux/autoconf.h"; } | md5sum | cut -d" " -f1)
1216 if ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1217 "$REUSE_SIGNATURE"; then
1218 # stash away the existing built articles for a moment
1220 mv {BUILD,{S,}RPMS,S{OURCE,PEC}S} bak
1223 find . | cpio -pudlm ..
1227 create_rpmbuild_dirs
1230 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1231 "ofed" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1232 "$CAN_LINK_FOR_REUSE"; then
1233 error "Failed to store OFED RPMS for reuse"
1237 # put the stuff we stashed away back
1241 pushd "$TOPDIR" >/dev/null
1242 rm -rf kernel-ib-devel
1243 mkdir kernel-ib-devel
1245 # the actual ofed RPMs don't have the -rc$n or -$date string appened that
1246 # might be present on the file
1247 local ofed_version=$(echo $OFED_VERSION |
1248 sed -re 's/-(20[0-9]{6,6}-[0-9]{4,4}|rc[0-9]*)$//')
1249 local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version}-${LINUXRELEASE//-/_}.*.rpm)
1250 rpm2cpio -itv < $rpm | cpio -id
1251 CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
1256 if build_lustre; then
1257 # the build worked. resolve any symlinked files (i.e. from reuse)
1258 # in RPMS/$arch to real files so that that that huge mess of
1259 # complication knows as LTS can copy them yet somewhere else.
1260 # is it any wonder this whole process is so damn so? anyone ever
1261 # heard of hardlinks? it this cool new thing that allows you save
1262 # tons of time and space by creating... well you can go read about
1263 # them if you have not heard about them yet.
1264 # can i say how much the implemenation of all of this really impedes
1266 pushd RPMS/$TARGET_ARCH
1268 if [ -h $file ]; then
1280 create_rpmbuild_dirs() {
1282 if [ ! -d RPMS ]; then
1284 for arch in $BUILD_ARCHS; do
1288 [ -d BUILD ] || mkdir BUILD
1289 [ -d SOURCES ] || mkdir SOURCES
1290 [ -d SPECS ] || mkdir SPECS
1291 [ -d SRPMS ] || mkdir SRPMS
1313 [[ $list\ == *\ $item\ * ]]
1317 #########################################################################
1318 # Generate a backtrace through the call stack.
1322 #########################################################################
1326 local funcname="" sourcefile="" lineno="" n
1328 echo "Call stack: (most recent first)"
1329 for (( n = $strip ; n < ${#FUNCNAME[@]} ; ++n )) ; do
1330 funcname=${FUNCNAME[$n - 1]}
1331 sourcefile=$(basename ${BASH_SOURCE[$n]})
1332 lineno=${BASH_LINENO[$n - 1]}
1333 # Display function arguments
1334 if [[ ! -z "${BASH_ARGV[@]}" ]]; then
1335 local args newarg j p=0
1336 for (( j = ${BASH_ARGC[$n - 1]}; j > 0; j-- )); do
1337 newarg=${BASH_ARGV[$j + $p - 1]}
1338 args="${args:+${args} }'${newarg}'"
1340 let p+=${BASH_ARGC[$n - 1]}
1342 echo " ${funcname} ${args:+${args} }at ${sourcefile}:${lineno}"
1346 echo "BEGIN BACKTRACE"
1348 #echo ${BASH_LINENO[*]}
1349 #echo ${BASH_SOURCE[*]}
1350 #echo ${FUNCNAME[*]}
1351 local i=$((${#FUNCNAME[@]} - 1))
1352 while [ $i -ge 0 ]; do
1353 local SOURCELINE="${BASH_SOURCE[$i + 1]}:${BASH_LINENO[$i]}"
1354 # Can't figure out how to get function args from other frames...
1355 local FUNCTION="${FUNCNAME[$i]}()"
1356 echo "$SOURCELINE:$FUNCTION"
1360 echo "END BACKTRACE"
1366 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
1368 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 -- "$@")
1370 if [ $? != 0 ]; then
1374 eval set -- "$options"
1409 if ! KERNELTREE=$(canon_path "$2"); then
1410 fatal 1 "Could not determine the canonical location of $2"
1414 --linux | --with-linux)
1415 if ! LINUX=$(canon_path "$2"); then
1416 fatal 1 "Could not determine the canonical location of $2"
1429 if ! REUSEBUILD=$(canon_path "$2"); then
1430 fatal 1 "Could not determine the canonical location of $2"
1447 if ! KERNELRPMSBASE=$(canon_path "$2"); then
1448 fatal 1 "Could not determine the canonical location of $2"
1495 --disable-datestamp)
1506 CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
1510 usage 1 "Unrecognized option: $1"
1520 EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
1522 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1524 unpack_ofed || fatal 1 "Error unpacking OFED tarball"
1527 # make sure the RPM build environment is set up
1528 create_rpmbuild_dirs
1530 trap '[ -n "$CCACHE" ] && ccache -s' EXIT
1532 # if an unpacked kernel source tree was given on the command line
1533 # just build lustre with it (nothing distro kernel specific here)
1534 if [ -n "$LINUX" ]; then
1537 if [ -f "${0%/*}/lbuild-$DISTRO" ]; then
1538 seen_list=$(new_list)
1539 trap '(echo "Untrapped error"
1541 # have we seen this one
1542 echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
1544 if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
1545 echo "seen this one already"
1547 seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
1553 ) | tee >(mail -s "Untrapped error at ${BASH_SOURCE[0]##*/}:${BASH_LINENO[0]} on $HOSTNAME" brian@sun.com) >&2' ERR
1556 source ${0%/*}/lbuild-$DISTRO
1558 build_with_srpm || fatal 1 "Failed to build_with_srpm"
1560 source ${0%/*}/lbuild.old_school
1562 old_school_download_kernel
1566 patchless_build_sequence && build_success=true
1568 [ "$DISTRO" = "sles9" ] && build_sequence_rpm_reuse && build_success=true
1569 if ! $build_success; then
1570 build_sequence_reuse && build_success=true
1571 if ! $build_success; then
1572 build_sequence && build_success=true
1573 if $build_success; then
1574 store_for_reuse || echo "Cannot store for future reuse"
1579 ( $build_success ) || fatal 1 "Cannot build lustre"