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="oel5"
291 CANONICAL_TARGET="hp-pnnl-2.4"
299 CANONICAL_TARGET="$TARGET"
303 local timestampnodig=$(echo $TIMESTAMP | sed -e s/[0-9]*//g)
304 [ "$timestampnodig" = "" ] || TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
305 local timestamplength="${#TIMESTAMP}"
306 if [ $timestamplength -eq 12 ]; then
307 TIMESTAMP="${TIMESTAMP}00"
308 elif [ $timestamplength -ne 14 ]; then
309 TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
312 RPMBUILD=$(which rpmbuild 2>/dev/null | head -1)
313 if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
314 RPMBUILD=$(which rpm 2>/dev/null | head -1)
315 if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
316 usage 1 "Could not find binary for making rpms (tried rpmbuild and rpm)."
320 if [ -n "$CCACHE" ]; then
321 which "$DISTCC" 2>/dev/null && export DISTCC RPM_BUILD_NCPUS
323 if which "$CCACHE" 2>/dev/null; then
324 local ccache=$(which "$CCACHE")
325 local bindir="$TOPDIR/bin"
327 [ -d $bindir ] || mkdir -p $bindir
328 if [ -d $bindir ]; then
329 rm ${bindir}/* > /dev/null 2>&1
330 ln -s "$ccache" ${bindir}/ccache
331 ln -s "$ccache" ${bindir}/cc
332 ln -s "$ccache" ${bindir}/$CC
333 export PATH=$bindir:$PATH
335 export CCACHE && export CC="ccache $CC"
336 # zero the cache so we can see how effective we are being with it
341 [ -z "$DISTRO" ] && DISTRO=$(autodetect_distro)
344 # autodetect used Distro
345 autodetect_distro() {
350 if [ -f /etc/SuSE-release ]; then
352 version=$(grep ^VERSION /etc/SuSE-release)
353 version=${version#*= }
354 elif [ -f /etc/redhat-release ]; then
355 name=$(head -1 /etc/redhat-release)
356 version=$(echo "$distroname" |
357 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ \.].*//')
359 if [ -z "$name" -o -z "$version" ]; then
360 fatal 1 "I don't know how to determine distro type/version.\n" \
361 "Either update autodetect_distro() or use the --distro argument"
364 echo ${name}${version}
371 echo $(echo "$*" | xargs -n 1 | sort -u)
378 local force="${3:-false}"
380 if $force || [ ! -r "$KERNELDIR/$srpm" ] ||
381 [ ! -s "$KERNELDIR/$srpm" ]; then
383 local location="http://downloads.lustre.org/public/kernels/$target/old"
384 echo "Downloading $location/$srpm..."
385 if ! wget -nv "$location/$srpm" -O "$KERNELDIR/$srpm" ||
386 [ ! -s "$KERNELDIR/$srpm" ]; then
387 rm -f $KERNELDIR/$srpm
388 fatal 1 "Could not download target $target's kernel SRPM" \
389 "$srpm from $location."
392 fatal 1 "$srpm not found in directory $KERNELDIR."
399 local force="${1:-false}"
401 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ] &&
402 ( $force || [ ! -r "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ||
403 [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ); then
405 local location="http://downloads.lustre.org/public/OFED/"
406 echo "Downloading $location/OFED-${OFED_VERSION}.tgz..."
407 if ! wget -nv "$location/OFED-${OFED_VERSION}.tgz" \
408 -O "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ||
409 [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ]; then
410 rm -f $KERNELTREE/OFED-${OFED_VERSION}.tgz
411 fatal 1 "Could not download OFED-${OFED_VERSION}.tgz" \
412 "from downloads.lustre.org."
415 fatal 1 "OFED-${OFED_VERSION}.tgz not found in kernel" \
416 "directory $KERNELTREE."
424 EXTRA_VERSION_save="$EXTRA_VERSION"
425 for patchesdir in "$EXTERNAL_PATCHES" \
426 "$TOPDIR/lustre/lustre/kernel_patches"; do
427 TARGET_FILE="$patchesdir/targets/$TARGET.target"
428 [ -r "$TARGET_FILE" ] && break
430 [ -r "$TARGET_FILE" ] || fatal 1 "Target $TARGET was not found."
432 echo "Loading target config file $TARGET.target..."
436 # doesn't make any sense to build OFED for xen domX's
441 # XXX - set_rpm_smp_type is an ugly undeterministic hack. it needs to
442 # go away and the target just specify the $RPMSMPTYPE
443 [ -z "$RPMSMPTYPE" ] && set_rpm_smp_type
445 # CC might have been overwriten in TARGET_FILE
446 if [[ $CC != ccache\ * ]] && which "$CCACHE" 2>/dev/null; then
447 export CCACHE && export CC="ccache $CC"
450 if [ ! "$KERNELTREE" = "" ] && [ -d "$KERNELTREE" ]; then
451 KERNELDIR="$KERNELTREE/${lnxmaj}"
452 [ -d "$KERNELDIR" ] || mkdir "$KERNELDIR"
455 # verify the series is available
456 if [ "$SERIES" ]; then
457 for series in $SERIES; do
458 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
459 [ -r "$patchesdir/series/$series" ] && continue 2
461 fatal 1 "Target $TARGET's series $SERIES could not be" \
462 "found.\nSearched:\n\t$EXTERNAL_PATCHES/series\n" \
463 "\t$TOPDIR/lustre/lustre/kernel_patches/series."
467 # set the location of the .config file
473 if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config ]; then
474 CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET$XENPOSTFIX-$TARGET_ARCH${RPMSMPTYPE:+-}${RPMSMPTYPE}.config"
477 local lnxrelnew=${lnxrel//-/_}
479 # remember the EXTRA_VERSION before we diddle it here
480 # XXX - we really should not diddle with any values read in from the
481 # target file. if we want to modify a value, we should create
483 PRISTINE_EXTRA_VERSION=$EXTRA_VERSION
485 if ! $PATCHLESS && [ ! -f "$CONFIG_FILE" ]; then
486 fatal 1 "Config file for target $TARGET missing from" \
487 "$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
490 if [ "$EXTRA_VERSION_save" ]; then
491 EXTRA_VERSION="$EXTRA_VERSION_save"
492 elif ! $RELEASE; then
493 # if there is no patch series, then this is not a lustre specific
494 # kernel. don't make it look like one
495 if [ -n "$SERIES" ]; then
496 #remove the @VERSION@ (lustre version)
497 # EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
498 # EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
499 ! ( $PATCHLESS ) && EXTRA_VERSION="${EXTRA_VERSION}.${TIMESTAMP}"
502 # EXTRA_VERSION=${EXTRA_VERSION//-/_}
504 ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $BIGSMP_ARCHS $PSERIES64_ARCHS $UP_ARCHS"
507 for arch in $(uniqify "$ALL_ARCHS"); do
508 if [ -z "$TARGET_ARCHS" ] ||
509 [[ \ $TARGET_ARCHS\ = *\ $arch\ * ]]; then
510 BUILD_ARCHS="$BUILD_ARCHS $arch"
513 [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
514 echo "Building for: $BUILD_ARCHS"
522 fatal 1 "tarflags(): File name argument missing."
534 fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
543 echo "Untarring ${file##*/}..."
544 tar $(tarflags "$file") "$file"
550 if ! untar "$KERNELTREE/OFED-${OFED_VERSION}.tgz"; then
553 [ -d OFED ] || ln -sf OFED-[0-9].[0-9]* OFED
559 if [ -z "$LUSTRE" ]; then
562 if [ -n "$USE_DATESTAMP" ]; then
563 DATESTAMP="-D '$DATE'"
566 local DIRNAME="lustre-$TAG-$TIMESTAMP"
568 cvs -d "$CVSROOT" -qz3 co $DATESTAMP -d "$DIRNAME" lustre || \
569 fatal 1 "There was an error checking out toplevel Lustre from CVS."
570 pushd "$DIRNAME" > /dev/null
571 ./lustrecvs "$TAG" || \
572 fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
573 echo "Creating lustre tarball..."
574 sh autogen.sh || fatal 1 "There was an error running autogen.sh."
575 ./configure --disable-{modules,utils,liblustre,tests,doc} || \
576 fatal 1 "There was an error running ./configure to create makefiles."
577 make dist || fatal 1 "There was an error running 'make dist'."
578 LUSTRE=$PWD/lustre-*.tar.gz
582 untar "$LUSTRE" || fatal 1 "Error unpacking Lustre tarball"
583 [ -d lustre ] || ln -sf lustre-[0-9].[0-9]* lustre
589 local do_patch=${1:-true}
591 FULL_PATCH="$PWD/lustre-kernel-${TARGET}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}.patch"
592 [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
593 $do_patch && pushd linux >/dev/null
594 for series in $SERIES; do
595 echo -n "Applying series $series:"
596 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
597 [ -r "$patchesdir/series/$series" ] || continue
598 SERIES_FILE="$patchesdir/series/$series"
599 for patch in $(<"$SERIES_FILE"); do
601 PATCH_FILE="$patchesdir/patches/$patch"
602 [ -r "$PATCH_FILE" ] || \
603 fatal 1 "Patch $patch does not exist in Lustre tree."
604 cat "$PATCH_FILE" >> "$FULL_PATCH" || {
606 fatal 1 "Error adding patch $patch to full patch."
609 patch -s -p1 < "$PATCH_FILE" || {
611 fatal 1 "Error applying patch $patch."
619 $do_patch && popd >/dev/null
620 echo "Full patch has been saved in ${FULL_PATCH##*/}."
628 pushd lustre >/dev/null
630 echo "Building Lustre RPMs for: $BUILD_ARCHS..."
632 for arch in $BUILD_ARCHS; do
633 targets="--target $arch $targets"
636 local confoptions="--with-linux=${LINUX}"
638 confoptions="--with-linux=${LINUX} --disable-server"
640 if [ ! "$LINUXOBJ" = "" ]; then
641 confoptions="$confoptions --with-linux-obj=${LINUXOBJ}"
644 ./configure $confoptions ${CONFIGURE_FLAGS}
645 if [ "$?" != "0" ]; then
646 local saved_config="../config.log.$(date +%s)"
647 cp config.log $saved_config
648 chmod a+r $saved_config
649 echo "Saved config.log is at $saved_config"
653 echo "config.log contents:"
661 # hack. Somebody move build/lustre.spec to lustre.spec for b1_6
663 [ -f lustre.spec ] && lustre_spec=lustre.spec
664 [ -f build/lustre.spec ] && lustre_spec=build/lustre.spec
666 [ -f "$lustre_spec" ] && sed \
667 -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
671 local rpmbuildopt='-bb'
674 echo NORPM mode. Only compiling.
677 # convert the $PATCHLESS boolean to an empty/no-empty boolean
678 # as silly as this seems, it makes the syntax of the rpmbuild command
679 # simpler and not need an eval to deal with the quotes in the quotes
680 local is_patchless=""
684 $RPMBUILD $targets $rpmbuildopt ../lustre.spec \
685 ${is_patchless:+--define "lustre_name lustre-client"} \
686 --define "_tmppath $TMPDIR" \
687 --define "_topdir $TOPDIR" || \
688 fatal 1 "Error building rpms for $BUILD_ARCHS."
691 ( $(skeep_ldiskfs_rpm $TAG) ) && return
693 pushd lustre/ldiskfs || return 255
695 if [ "$?" != "0" ]; then
699 cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
703 local ldiskfs_spec=lustre-ldiskfs.spec
704 [ -f "$ldiskfs_spec" ] && sed \
705 -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
707 > ../lustre-ldiskfs.spec
709 $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
710 --define "_tmppath /var/tmp" \
711 --define "_topdir $TOPDIR"
712 if [ "$?" != "0" ]; then
718 $RPMBUILD -bs ../lustre-ldiskfs.spec \
719 --define "_tmppath /var/tmp" \
720 --define "_topdir $TOPDIR"
721 if [ "$?" != "0" ]; then
732 [ "$STAGEDIR" ] || return 0
734 for arch in $BUILD_ARCHS; do
735 rpmdir="${STAGEDIR}/${CANONICAL_TARGET}-${arch}"
736 echo "${0##*/}: Copying RPMs into ${rpmdir}"
738 cp -v RPMS/${arch}/*.rpm "${rpmdir}"
739 if [ -d RPMS/noarch ]; then
740 cp -v RPMS/noarch/*.rpm "${rpmdir}"
744 cp -v "$LUSTRE" "$STAGEDIR"
748 #check if we need to build separate ldiskfs RPM
749 skeep_ldiskfs_rpm() {
754 if ! $LDISKFSRPM; then
756 elif $PATCHLESS; then
759 for skiptag in $SKIPLDISKFSRPM; do
760 [[ $tag == $skiptag ]] && skip=true && break
764 pushd $TOPDIR/BUILD/lustre-[1-9]* >/dev/null
765 grep -q '^SERVER_TRUE[ \t]=[ \t]#$' autoMakefile && skip=true
772 #generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
773 gen_lustre_version() {
775 LUSTRE_EXTRA_VERSION="${lnxmaj}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}${TARGET_DELIMITER}${RPMSMPTYPE}"
776 LUSTRE_EXTRA_VERSION=${LUSTRE_EXTRA_VERSION//-/_}
782 local infact_arch="${TARGET_ARCH}"
785 [ "$infact_arch" == "i586" ] && infact_arch="i686"
788 for smp_type in $SMP_ARCHS; do
789 [ $infact_arch == $smp_type ] && RPMSMPTYPE=smp && break
792 for smp_type in $BIGSMP_ARCHS; do
793 [ $infact_arch == $smp_type ] && RPMSMPTYPE=bigsmp && break
796 for smp_type in $DEFAULT_ARCHS; do
797 [ $infact_arch == $smp_type ] && RPMSMPTYPE=default && break
802 # This function takes a linux source pool and digs out the linux release
804 find_linux_release() {
807 local LINUXRELEASEHEADER=$SRCDIR/include/linux/version.h
808 if [ -s $SRCDIR/include/linux/utsrelease.h ]; then
809 LINUXRELEASEHEADER=$SRCDIR/include/linux/utsrelease.h
812 sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' $LINUXRELEASEHEADER
816 # XXX this needs to be re-written as a wrapper around find_rpm
817 # or just gotten rid of. :-)
820 local delimiter=${2:-"-"}
822 local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
823 [ -d $pathtorpms ] || return 255
825 local kernelbinaryrpm rpmfile
826 local wanted_kernel="${lnxmaj}${delimiter}${lnxrel}"
829 for arch in $TARGET_ARCHS_ALL; do
830 local found_rpm="" rpm
831 for rpm in ${pathtorpms}/${arch}/*.rpm; do
832 if rpm -q --provides -p "$rpm" | grep -q "kernel${prefix} = $wanted_kernel"; then
838 [ -f "$found_rpm" ] && break
846 # unpack kernel(/source/devel) RPM
848 # This function and it's setting of $LINUX and $LINUXOBJ is a total hack that
849 # needs to completely refactored. It completely ingores that $BUILD_ARCHS may
850 # contain a list of arches for which rpmbuild commands (including the one for
852 unpack_linux_devel_rpm() {
853 local kernelrpm="${1}"
854 # it's worth noting that neither sles10 nor rhel5 appear to use their
855 # extra_version delimiter for the dirname under /usr/src, so we could
856 # probably just get rid of this parameter
857 local delimiter=${2:-"-"}
859 [ -f "$kernelrpm" ] || return 255
860 [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
862 pushd $TOPDIR/reused || return 255
864 if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
868 # call a distro specific hook, if available
869 if type -p unpack_linux_devel_rpm-$DISTRO; then
870 unpack_linux_devel_rpm-$DISTRO "$kernelrpm"
875 find_linux_devel_paths $TOPDIR/reused
881 # XXX - this rhel/sles goop needs abstracting out into the
882 # lbuild-{rhel5,sles10} method files
883 find_linux_devel_paths() {
889 # RHEL-style and SLES-style rpms
890 # XXX - until bug 19336 cleans this up, we need to extricate the
891 # ${lnxmin}- from the $lnxrel
892 local paths="kernels/${lnxmaj}${lnxmin}${delimiter}${lnxrel}-${TARGET_ARCH} linux-${lnxmaj}${lnxmin}${delimiter}${lnxrel##${lnxmin#.}-}"
895 for path in $paths; do
898 if [ -d "$src/$path/" ]; then
899 LINUX="$(pwd)/$src/$path"
901 # SLES has a separate -obj tree
902 if [ -d "$src/${path}-obj" ]; then
903 local src="$src/${path}-obj"
904 local objects="$TARGET_ARCH/$RPMSMPTYPE"
906 # Novell, are you *TRYING* to make life hard for me?
907 if [ -d "$src/powerpc" ]; then
908 objects="powerpc/$TARGET_ARCH"
909 elif [ $TARGET_ARCH == 'i686' ]; then
910 objects="i386/$RPMSMPTYPE"
913 LINUXOBJ="$(pwd)/$src/$objects"
916 if [ -z "$LINUX" ]; then
919 # dig out the release version
920 LINUXRELEASE=$(find_linux_release ${LINUXOBJ:-$LINUX})
921 if [ -z "$LINUXRELEASE" ]; then
922 echo "Failed to find linux release in ${LINUXOBJ:-$LINUX}"
931 # build kernel-ib{,-devel}
932 # some I/B drivers are architecture dependent and kernel-ib's configure
933 # does not figure it out for us ~sigh~
934 local configure_options=""
935 case "$TARGET_ARCH" in
937 configure_options="--with-ipath_inf-mod"
940 configure_options="--with-ipath_inf-mod --with-ehca-mod"
944 # ofed 1.3 had a bug in the rpm spec
945 if [ "$OFED_VERSION" = "1.3" ]; then
948 $RPMBUILD --rebuild --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
949 --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
950 --define "KVERSION ${LINUXRELEASE}" \
951 --define "$K_SRC ${LINUXOBJ:-${LINUX}}" \
952 --define "LIB_MOD_DIR /lib/modules/${LINUXRELEASE}/updates" \
953 --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
955 if [ ${PIPESTATUS[0]} != 0 ]; then
956 fatal 1 "Error building kernel-ib"
973 location="$location"/"$signature"/"$module"
975 # the cleanup script removes any directory that doesn't have a
976 # .lastused, so let's try to prevent that as soon as we can
977 # this solution still slightly racy with the cleanup script
978 # but the race is a lot tighter now
979 touch -t 197001010000 "$location/.lastused"
980 ## use eval/echo here to make sure shell expansions are performed
981 #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
983 for article in $(eval echo $articles); do
984 if ! cp -a${linkflag} "$article" "$location"; then
985 error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
986 # rename the cache location so that it's not cached
987 # product, but is around for analysis
988 mv "$location"{,-bad-$(date +%s)} ||
989 error "failed to clean up a failed cache attempt" \
990 "in \"$location\" -- manual cleanup will be" \
996 # flag the cache as complete (i.e. in case lbuild was previously
997 # interrupted while caching)
998 touch "$location/.lastused"
1007 local use_links="${3:-false}"
1008 local signature="$4"
1010 if [ -n "$REUSEBUILD" ] && [ -d "$REUSEBUILD/$signature/$module" ]; then
1011 if [ ! -f "$REUSEBUILD/$signature/$module/.lastused" ]; then
1012 # the .lastused flag is populated at the end of the caching to
1013 # signal that the caching was completeld. if that flag is not
1014 # there, then the cache is invalid (and should be removed in fact)
1015 mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} ||
1016 fatal 1 "failed to clean up a bad cache in location" \
1017 "\"$REUSEBUILD/$signature/$module\" -- manual cleanup" \
1022 # so that we know how stale this entry is
1023 touch $REUSEBUILD/$signature/$module/.lastused
1026 if ls $REUSEBUILD/$signature/$module/* >/dev/null 2>&1; then
1027 cp -al $REUSEBUILD/$signature/$module/* $dest/
1030 # copying is pretty heavy
1031 # cp -a $REUSEBUILD/$signature/$module/* $dest/
1032 # do some creative symlinking instead
1034 for dir in BUILD SRPMS SPECS; do
1035 if ls $REUSEBUILD/$signature/$module/$dir/* >/dev/null 2>&1; then
1036 ln -s $REUSEBUILD/$signature/$module/$dir/* $dest/$dir
1039 # sources have to be copied by file because we need SOURCES to
1040 # be a dir we can write into
1041 # could overrun ls's arg list here
1042 #ls $REUSEBUILD/$signature/$module/SOURCES/* |
1043 find $REUSEBUILD/$signature/$module/SOURCES/ -type f |
1044 xargs ln -t $dest/SOURCES -s
1046 # same for RPMS/* dirs
1047 # could overrun ls's arg list here
1048 #ls $REUSEBUILD/$signature/$module/RPMS/$TARGET_ARCH/* |
1050 for dir in $REUSEBUILD/$signature/$module/RPMS/*; do
1051 mkdir -p $dest/RPMS/${dir##*/}
1053 xargs ln -t $dest/RPMS/${dir##*/} -s
1066 if [[ $arch = i[3456]86 ]]; then
1075 # in a given directory, find the first rpm matching given requirements
1079 local match_type="$2"
1082 pushd "$dir" > /dev/null || \
1083 fatal 1 "Unable to chdir to directory \"$dir\" in find_rpm()"
1086 for file in $(ls *.rpm); do
1087 if [ ! -f "$file" ]; then
1090 case "$match_type" in
1092 # match is any valid ERE (i.e. given to egrep) match
1093 if rpm -q --provides -p "$file" | egrep -q "$match"; then
1101 fatal 1 "Unknown match type \"$match_type\" given to find_rpm()"
1110 build_kernel_with_srpm() {
1112 # need to generate the patch for this target
1113 do_patch_linux false >&2 # sets global $FULL_PATCH (yeah, yuck)
1115 # get an md5sum of the kernel patch + config for reuse check
1116 # XXX really, there needs to be a signature and a CONFIG_FILE per arch
1120 local release_str="RELEASE=$RELEASE\n"
1122 local REUSE_SIGNATURE=$({ echo -en $release_str; echo $BUILD_GEN; cat $CONFIG_FILE $TARGET_FILE $FULL_PATCH; } | md5sum | cut -d" " -f1)
1124 # see if we can link to the reuse pool
1125 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1126 local CAN_LINK_FOR_REUSE=false
1127 touch $REUSEBUILD/$$
1128 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1129 CAN_LINK_FOR_REUSE=true
1133 # the extra version string to use for the kernel (which might be a reused
1135 local kernel_extra_version=""
1136 if $REUSERPM && ! reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1137 "$REUSE_SIGNATURE"; then
1138 # nothing cached, build from scratch
1139 if [ ! -r "$KERNELDIR/$KERNEL_SRPM" ]; then
1140 download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&2
1143 if ! rpm -ivh $KERNELDIR/$KERNEL_SRPM \
1144 --define "_topdir $TOPDIR" >&2; then
1145 # should we clean this up or leave it for analysis?
1147 fatal 1 "Error installing kernel SRPM."
1150 # put the Lustre kernel patch into the RPM build tree
1151 cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
1152 prepare_and_build_srpm >&2
1154 # store the resulting kernel RPM build tree for future use
1155 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1156 "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1157 "$CAN_LINK_FOR_REUSE"; then
1158 error "Failed to store kernel RPMS for reuse"
1164 # figure out the EXTRA_VERSION of the kernel we built or are re-using
1166 if ! KERNEL_RPM=$(find_rpm "$TOPDIR/RPMS/$TARGET_ARCH/" provides "^kernel ="); then
1167 fatal 1 "Failed to find a kernel RPM in $TOPDIR/RPMS/$TARGET_ARCH/"
1169 kernel_extra_version=$(rpm -q --queryformat "%{RELEASE}" -p $TOPDIR/RPMS/$TARGET_ARCH/$KERNEL_RPM)
1171 # should now have the following RPMs
1172 # $TOPDIR/RPMS/$arch/kernel-lustre-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1173 # $TOPDIR/RPMS/$arch/kernel-lustre-devel-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1174 # $TOPDIR/RPMS/$arch/kernel-lustre-headers-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1175 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-common-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1176 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1178 echo $kernel_extra_version
1185 if ! $PATCHLESS; then
1186 local kernel_extra_version
1187 if ! kernel_extra_version=$(build_kernel_with_srpm); then
1188 fatal 1 "Failed to build the kernel from it's SRPM"
1191 for arch in $BUILD_ARCHS; do
1193 local kernel_devel_rpm
1194 if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/$arch/" provides "^$(devel_kernel_name $KERNEL_LUSTRE_NAMING) ="); then
1195 fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/$arch/"
1198 # install the -devel RPM in preparation for the lustre build
1199 # note that the EXTRA_VERSION_DELIMITER is *NOT* used in the
1200 # version of the directory name under /usr/src
1201 if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
1202 "$TOPDIR/RPMS/$arch/$kernel_devel_rpm" "-"; then
1203 fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/$arch/$kernel_devel_rpm"
1207 # need to find and unpack the vendor's own kernel-devel for patchless
1210 if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE" ${EXTRA_VERSION_DELIMITER:-"-"}); then
1211 fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in ${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
1213 if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
1214 fatal 1 "Could not find the Linux tree in $kernelrpm"
1218 # before lustre, build kernel-ib
1219 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1220 # see if we can link to the reuse pool
1221 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1222 local CAN_LINK_FOR_REUSE=false
1223 touch $REUSEBUILD/$$
1224 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1225 CAN_LINK_FOR_REUSE=true
1229 local REUSE_SIGNATURE=$({ echo "$OFED_VERSION"; echo "$(find_linux_release ${LINUXOBJ:-$LINUX})"; cat "${LINUXOBJ:-${LINUX}}/include/linux/autoconf.h"; } | md5sum | cut -d" " -f1)
1230 if ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1231 "$REUSE_SIGNATURE"; then
1232 # stash away the existing built articles for a moment
1234 mv {BUILD,{S,}RPMS,S{OURCE,PEC}S} bak
1237 find . | cpio -pudlm ..
1241 create_rpmbuild_dirs
1244 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1245 "ofed" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1246 "$CAN_LINK_FOR_REUSE"; then
1247 error "Failed to store OFED RPMS for reuse"
1251 # put the stuff we stashed away back
1255 pushd "$TOPDIR" >/dev/null
1256 rm -rf kernel-ib-devel
1257 mkdir kernel-ib-devel
1259 # the actual ofed RPMs don't have the -rc$n or -$date string appened that
1260 # might be present on the file
1261 local ofed_version=$(echo $OFED_VERSION |
1262 sed -re 's/-(20[0-9]{6,6}-[0-9]{4,4}|rc[0-9]*)$//')
1263 local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version}-${LINUXRELEASE//-/_}.*.rpm)
1264 rpm2cpio -itv < $rpm | cpio -id
1265 CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
1270 if build_lustre; then
1271 # the build worked. resolve any symlinked files (i.e. from reuse)
1272 # in RPMS/$arch to real files so that that that huge mess of
1273 # complication knows as LTS can copy them yet somewhere else.
1274 # is it any wonder this whole process is so damn so? anyone ever
1275 # heard of hardlinks? it this cool new thing that allows you save
1276 # tons of time and space by creating... well you can go read about
1277 # them if you have not heard about them yet.
1278 # can i say how much the implemenation of all of this really impedes
1280 pushd RPMS/$TARGET_ARCH
1282 if [ -h $file ]; then
1294 create_rpmbuild_dirs() {
1296 [ -d RPMS ] || mkdir RPMS
1297 for arch in $BUILD_ARCHS; do
1298 if [[ $arch = i?86 ]]; then
1299 # some stupidity in the sles11 kernel spec requires an RPMS/i386
1300 # even if the target arch is i686
1301 [ -d RPMS/i386 ] || mkdir RPMS/i386
1303 [ -d RPMS/$arch ] || mkdir RPMS/$arch
1305 [ -d BUILD ] || mkdir BUILD
1306 [ -d SOURCES ] || mkdir SOURCES
1307 [ -d SPECS ] || mkdir SPECS
1308 [ -d SRPMS ] || mkdir SRPMS
1330 [[ $list\ == *\ $item\ * ]]
1334 #########################################################################
1335 # Generate a backtrace through the call stack.
1339 #########################################################################
1343 local funcname="" sourcefile="" lineno="" n
1345 echo "Call stack: (most recent first)"
1346 for (( n = $strip ; n < ${#FUNCNAME[@]} ; ++n )) ; do
1347 funcname=${FUNCNAME[$n - 1]}
1348 sourcefile=$(basename ${BASH_SOURCE[$n]})
1349 lineno=${BASH_LINENO[$n - 1]}
1350 # Display function arguments
1351 if [[ ! -z "${BASH_ARGV[@]}" ]]; then
1352 local args newarg j p=0
1353 for (( j = ${BASH_ARGC[$n - 1]}; j > 0; j-- )); do
1354 newarg=${BASH_ARGV[$j + $p - 1]}
1355 args="${args:+${args} }'${newarg}'"
1357 let p+=${BASH_ARGC[$n - 1]}
1359 echo " ${funcname} ${args:+${args} }at ${sourcefile}:${lineno}"
1363 echo "BEGIN BACKTRACE"
1365 #echo ${BASH_LINENO[*]}
1366 #echo ${BASH_SOURCE[*]}
1367 #echo ${FUNCNAME[*]}
1368 local i=$((${#FUNCNAME[@]} - 1))
1369 while [ $i -ge 0 ]; do
1370 local SOURCELINE="${BASH_SOURCE[$i + 1]}:${BASH_LINENO[$i]}"
1371 # Can't figure out how to get function args from other frames...
1372 local FUNCTION="${FUNCNAME[$i]}()"
1373 echo "$SOURCELINE:$FUNCTION"
1377 echo "END BACKTRACE"
1383 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
1385 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 -- "$@")
1387 if [ $? != 0 ]; then
1391 eval set -- "$options"
1426 if ! KERNELTREE=$(canon_path "$2"); then
1427 fatal 1 "Could not determine the canonical location of $2"
1431 --linux | --with-linux)
1432 if ! LINUX=$(canon_path "$2"); then
1433 fatal 1 "Could not determine the canonical location of $2"
1446 if ! REUSEBUILD=$(canon_path "$2"); then
1447 fatal 1 "Could not determine the canonical location of $2"
1464 if ! KERNELRPMSBASE=$(canon_path "$2"); then
1465 fatal 1 "Could not determine the canonical location of $2"
1512 --disable-datestamp)
1523 CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
1527 usage 1 "Unrecognized option: $1"
1537 EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
1539 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1541 unpack_ofed || fatal 1 "Error unpacking OFED tarball"
1544 # make sure the RPM build environment is set up
1545 create_rpmbuild_dirs
1547 trap '[ -n "$CCACHE" ] && ccache -s' EXIT
1549 # if an unpacked kernel source tree was given on the command line
1550 # just build lustre with it (nothing distro kernel specific here)
1551 if [ -n "$LINUX" ]; then
1554 if [ -f "${0%/*}/lbuild-$DISTRO" ]; then
1555 seen_list=$(new_list)
1556 trap '(echo "Untrapped error"
1558 # have we seen this one
1559 echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
1561 if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
1562 echo "seen this one already"
1564 seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
1570 ) | tee >(mail -s "Untrapped error at ${BASH_SOURCE[0]##*/}:${BASH_LINENO[0]} on $HOSTNAME" brian@sun.com) >&2' ERR
1573 source ${0%/*}/lbuild-$DISTRO
1575 build_with_srpm || fatal 1 "Failed to build_with_srpm"
1577 source ${0%/*}/lbuild.old_school
1579 old_school_download_kernel
1583 patchless_build_sequence && build_success=true
1585 [ "$DISTRO" = "sles9" ] && build_sequence_rpm_reuse && build_success=true
1586 if ! $build_success; then
1587 build_sequence_reuse && build_success=true
1588 if ! $build_success; then
1589 build_sequence && build_success=true
1590 if $build_success; then
1591 store_for_reuse || echo "Cannot store for future reuse"
1596 ( $build_success ) || fatal 1 "Cannot build lustre"