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
764 #generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
765 gen_lustre_version() {
767 LUSTRE_EXTRA_VERSION="${lnxmaj}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}${TARGET_DELIMITER}${RPMSMPTYPE}"
768 LUSTRE_EXTRA_VERSION=${LUSTRE_EXTRA_VERSION//-/_}
774 local infact_arch="${TARGET_ARCH}"
777 [ "$infact_arch" == "i586" ] && infact_arch="i686"
780 for smp_type in $SMP_ARCHS; do
781 [ $infact_arch == $smp_type ] && RPMSMPTYPE=smp && break
784 for smp_type in $BIGSMP_ARCHS; do
785 [ $infact_arch == $smp_type ] && RPMSMPTYPE=bigsmp && break
788 for smp_type in $DEFAULT_ARCHS; do
789 [ $infact_arch == $smp_type ] && RPMSMPTYPE=default && break
794 # This function takes a linux source pool and digs out the linux release
796 find_linux_release() {
799 local LINUXRELEASEHEADER=$SRCDIR/include/linux/version.h
800 if [ -s $SRCDIR/include/linux/utsrelease.h ]; then
801 LINUXRELEASEHEADER=$SRCDIR/include/linux/utsrelease.h
804 sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' $LINUXRELEASEHEADER
808 # XXX this needs to be re-written as a wrapper around find_rpm
809 # or just gotten rid of. :-)
812 local delimiter=${2:-"-"}
814 local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
815 [ -d $pathtorpms ] || return 255
817 local kernelbinaryrpm rpmfile
818 local wanted_kernel="${lnxmaj}${delimiter}${lnxrel}"
821 for arch in $TARGET_ARCHS_ALL; do
822 local found_rpm="" rpm
823 for rpm in ${pathtorpms}/${arch}/*.rpm; do
824 if rpm -q --provides -p "$rpm" | grep -q "kernel${prefix} = $wanted_kernel"; then
830 [ -f "$found_rpm" ] && break
838 # unpack kernel(/source/devel) RPM
840 # This function and it's setting of $LINUX and $LINUXOBJ is a total hack that
841 # needs to completely refactored. It completely ingores that $BUILD_ARCHS may
842 # contain a list of arches for which rpmbuild commands (including the one for
844 unpack_linux_devel_rpm() {
845 local kernelrpm="${1}"
846 # it's worth noting that neither sles10 nor rhel5 appear to use their
847 # extra_version delimiter for the dirname under /usr/src, so we could
848 # probably just get rid of this parameter
849 local delimiter=${2:-"-"}
851 [ -f "$kernelrpm" ] || return 255
852 [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
854 pushd $TOPDIR/reused || return 255
856 if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
860 # call a distro specific hook, if available
861 if type -p unpack_linux_devel_rpm-$DISTRO; then
862 unpack_linux_devel_rpm-$DISTRO "$kernelrpm"
867 find_linux_devel_paths $TOPDIR/reused
873 # XXX - this rhel/sles goop needs abstracting out into the
874 # lbuild-{rhel5,sles10} method files
875 find_linux_devel_paths() {
881 # RHEL-style and SLES-style rpms
882 # XXX - until bug 19336 cleans this up, we need to extricate the
883 # ${lnxmin}- from the $lnxrel
884 local paths="kernels/${lnxmaj}${lnxmin}${delimiter}${lnxrel}-${TARGET_ARCH} linux-${lnxmaj}${lnxmin}${delimiter}${lnxrel##${lnxmin#.}-}"
887 for path in $paths; do
890 if [ -d "$src/$path/" ]; then
891 LINUX="$(pwd)/$src/$path"
893 # SLES has a separate -obj tree
894 if [ -d "$src/${path}-obj" ]; then
895 local src="$src/${path}-obj"
896 local objects="$TARGET_ARCH/$RPMSMPTYPE"
898 # Novell, are you *TRYING* to make life hard for me?
899 if [ -d "$src/powerpc" ]; then
900 objects="powerpc/$TARGET_ARCH"
901 elif [ $TARGET_ARCH == 'i686' ]; then
902 objects="i386/$RPMSMPTYPE"
905 LINUXOBJ="$(pwd)/$src/$objects"
908 if [ -z "$LINUX" ]; then
911 # dig out the release version
912 LINUXRELEASE=$(find_linux_release ${LINUXOBJ:-$LINUX})
913 if [ -z "$LINUXRELEASE" ]; then
914 echo "Failed to find linux release in ${LINUXOBJ:-$LINUX}"
923 # build kernel-ib{,-devel}
924 # some I/B drivers are architecture dependent and kernel-ib's configure
925 # does not figure it out for us ~sigh~
926 local configure_options=""
927 case "$TARGET_ARCH" in
929 configure_options="--with-ipath_inf-mod"
932 configure_options="--with-ipath_inf-mod --with-ehca-mod"
936 # ofed 1.3 had a bug in the rpm spec
937 if [ "$OFED_VERSION" = "1.3" ]; then
940 $RPMBUILD --rebuild --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
941 --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
942 --define "KVERSION ${LINUXRELEASE}" \
943 --define "$K_SRC ${LINUXOBJ:-${LINUX}}" \
944 --define "LIB_MOD_DIR /lib/modules/${LINUXRELEASE}/updates" \
945 --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
947 if [ ${PIPESTATUS[0]} != 0 ]; then
948 fatal 1 "Error building kernel-ib"
965 location="$location"/"$signature"/"$module"
967 # the cleanup script removes any directory that doesn't have a
968 # .lastused, so let's try to prevent that as soon as we can
969 # this solution still slightly racy with the cleanup script
970 # but the race is a lot tighter now
971 touch -t 197001010000 "$location/.lastused"
972 ## use eval/echo here to make sure shell expansions are performed
973 #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
975 for article in $(eval echo $articles); do
976 if ! cp -a${linkflag} "$article" "$location"; then
977 error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
978 # rename the cache location so that it's not cached
979 # product, but is around for analysis
980 mv "$location"{,-bad-$(date +%s)} ||
981 error "failed to clean up a failed cache attempt" \
982 "in \"$location\" -- manual cleanup will be" \
988 # flag the cache as complete (i.e. in case lbuild was previously
989 # interrupted while caching)
990 touch "$location/.lastused"
999 local use_links="${3:-false}"
1000 local signature="$4"
1002 if [ -n "$REUSEBUILD" ] && [ -d "$REUSEBUILD/$signature/$module" ]; then
1003 if [ ! -f "$REUSEBUILD/$signature/$module/.lastused" ]; then
1004 # the .lastused flag is populated at the end of the caching to
1005 # signal that the caching was completeld. if that flag is not
1006 # there, then the cache is invalid (and should be removed in fact)
1007 mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} ||
1008 fatal 1 "failed to clean up a bad cache in location" \
1009 "\"$REUSEBUILD/$signature/$module\" -- manual cleanup" \
1014 # so that we know how stale this entry is
1015 touch $REUSEBUILD/$signature/$module/.lastused
1018 if ls $REUSEBUILD/$signature/$module/* >/dev/null 2>&1; then
1019 cp -al $REUSEBUILD/$signature/$module/* $dest/
1022 # copying is pretty heavy
1023 # cp -a $REUSEBUILD/$signature/$module/* $dest/
1024 # do some creative symlinking instead
1026 for dir in BUILD SRPMS SPECS; do
1027 if ls $REUSEBUILD/$signature/$module/$dir/* >/dev/null 2>&1; then
1028 ln -s $REUSEBUILD/$signature/$module/$dir/* $dest/$dir
1031 # sources have to be copied by file because we need SOURCES to
1032 # be a dir we can write into
1033 # could overrun ls's arg list here
1034 #ls $REUSEBUILD/$signature/$module/SOURCES/* |
1035 find $REUSEBUILD/$signature/$module/SOURCES/ -type f |
1036 xargs ln -t $dest/SOURCES -s
1038 # same for RPMS/* dirs
1039 # could overrun ls's arg list here
1040 #ls $REUSEBUILD/$signature/$module/RPMS/$TARGET_ARCH/* |
1042 for dir in $REUSEBUILD/$signature/$module/RPMS/*; do
1043 mkdir -p $dest/RPMS/${dir##*/}
1045 xargs ln -t $dest/RPMS/${dir##*/} -s
1058 if [[ $arch = i[3456]86 ]]; then
1067 # in a given directory, find the first rpm matching given requirements
1071 local match_type="$2"
1074 pushd "$dir" > /dev/null || \
1075 fatal 1 "Unable to chdir to directory \"$dir\" in find_rpm()"
1078 for file in $(ls); do
1079 if [ ! -f "$file" ]; then
1082 case "$match_type" in
1084 # match is any valid ERE (i.e. given to egrep) match
1085 if rpm -q --provides -p "$file" | egrep -q "$match"; then
1093 fatal 1 "Unknown match type \"$match_type\" given to find_rpm()"
1102 build_kernel_with_srpm() {
1104 # need to generate the patch for this target
1105 do_patch_linux false >&2 # sets global $FULL_PATCH (yeah, yuck)
1107 # get an md5sum of the kernel patch + config for reuse check
1108 # XXX really, there needs to be a signature and a CONFIG_FILE per arch
1110 local REUSE_SIGNATURE=$({ echo $BUILD_GEN; cat $CONFIG_FILE $TARGET_FILE $FULL_PATCH; } | md5sum | cut -d" " -f1)
1112 # see if we can link to the reuse pool
1113 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1114 local CAN_LINK_FOR_REUSE=false
1115 touch $REUSEBUILD/$$
1116 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1117 CAN_LINK_FOR_REUSE=true
1121 # the extra version string to use for the kernel (which might be a reused
1123 local kernel_extra_version=""
1124 if $REUSERPM && reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1125 "$REUSE_SIGNATURE"; then
1126 # figure out the EXTRA_VERSION of the kernel we are re-using
1128 if ! KERNEL_RPM=$(find_rpm "$TOPDIR/RPMS/$TARGET_ARCH/" provides "^kernel ="); then
1129 fatal 1 "Failed to find a kernel RPM in $TOPDIR/RPMS/$TARGET_ARCH/"
1131 kernel_extra_version=$(rpm -q --queryformat "%{RELEASE}" -p $TOPDIR/RPMS/$TARGET_ARCH/$KERNEL_RPM)
1133 # nothing cached, build from scratch
1134 if [ ! -r "$KERNELDIR/$KERNEL_SRPM" ]; then
1135 download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&2
1138 rpm -ivh $KERNELDIR/$KERNEL_SRPM --define "_topdir $TOPDIR" >&2 || {
1139 # should we clean this up or leave it for analysis?
1141 fatal 1 "Error installing kernel SRPM."
1144 # put the Lustre kernel patch into the RPM build tree
1145 cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
1146 prepare_and_build_srpm >&2
1148 # store the resulting kernel RPM build tree for future use
1149 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1150 "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1151 "$CAN_LINK_FOR_REUSE"; then
1152 error "Failed to store kernel RPMS for reuse"
1156 kernel_extra_version=$EXTRA_VERSION
1159 # should now have the following RPMs
1160 # $TOPDIR/RPMS/$arch/kernel-lustre-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1161 # $TOPDIR/RPMS/$arch/kernel-lustre-devel-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1162 # $TOPDIR/RPMS/$arch/kernel-lustre-headers-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1163 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-common-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1164 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1166 echo $kernel_extra_version
1173 if ! $PATCHLESS; then
1174 local kernel_extra_version
1175 if ! kernel_extra_version=$(build_kernel_with_srpm); then
1176 fatal 1 "Failed to build the kernel from it's SRPM"
1179 for arch in $BUILD_ARCHS; do
1181 local kernel_devel_rpm
1182 if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/$arch/" provides "^$(devel_kernel_name $KERNEL_LUSTRE_NAMING) ="); then
1183 fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/$arch/"
1186 # install the -devel RPM in preparation for the lustre build
1187 # note that the EXTRA_VERSION_DELIMITER is *NOT* used in the
1188 # version of the directory name under /usr/src
1189 if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
1190 "$TOPDIR/RPMS/$arch/$kernel_devel_rpm" "-"; then
1191 fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/$arch/$kernel_devel_rpm"
1195 # need to find and unpack the vendor's own kernel-devel for patchless
1198 if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE" ${EXTRA_VERSION_DELIMITER:-"-"}); then
1199 fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in ${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
1201 if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
1202 fatal 1 "Could not find the Linux tree in $kernelrpm"
1206 # before lustre, build kernel-ib
1207 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1208 # see if we can link to the reuse pool
1209 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1210 local CAN_LINK_FOR_REUSE=false
1211 touch $REUSEBUILD/$$
1212 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1213 CAN_LINK_FOR_REUSE=true
1217 local REUSE_SIGNATURE=$({ echo "$OFED_VERSION"; echo "$(find_linux_release ${LINUXOBJ:-$LINUX})"; cat "${LINUXOBJ:-${LINUX}}/include/linux/autoconf.h"; } | md5sum | cut -d" " -f1)
1218 if ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1219 "$REUSE_SIGNATURE"; then
1220 # stash away the existing built articles for a moment
1222 mv {BUILD,{S,}RPMS,S{OURCE,PEC}S} bak
1225 find . | cpio -pudlm ..
1229 create_rpmbuild_dirs
1232 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1233 "ofed" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1234 "$CAN_LINK_FOR_REUSE"; then
1235 error "Failed to store OFED RPMS for reuse"
1239 # put the stuff we stashed away back
1243 pushd "$TOPDIR" >/dev/null
1244 rm -rf kernel-ib-devel
1245 mkdir kernel-ib-devel
1247 # the actual ofed RPMs don't have the -rc$n or -$date string appened that
1248 # might be present on the file
1249 local ofed_version=$(echo $OFED_VERSION |
1250 sed -re 's/-(20[0-9]{6,6}-[0-9]{4,4}|rc[0-9]*)$//')
1251 local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version}-${LINUXRELEASE//-/_}.*.rpm)
1252 rpm2cpio -itv < $rpm | cpio -id
1253 CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
1258 if build_lustre; then
1259 # the build worked. resolve any symlinked files (i.e. from reuse)
1260 # in RPMS/$arch to real files so that that that huge mess of
1261 # complication knows as LTS can copy them yet somewhere else.
1262 # is it any wonder this whole process is so damn so? anyone ever
1263 # heard of hardlinks? it this cool new thing that allows you save
1264 # tons of time and space by creating... well you can go read about
1265 # them if you have not heard about them yet.
1266 # can i say how much the implemenation of all of this really impedes
1268 pushd RPMS/$TARGET_ARCH
1270 if [ -h $file ]; then
1282 create_rpmbuild_dirs() {
1284 [ -d RPMS ] || mkdir RPMS
1285 for arch in $BUILD_ARCHS; do
1286 if [[ $arch = i?86 ]]; then
1287 # some stupidity in the sles11 kernel spec requires an RPMS/i386
1288 # even if the target arch is i686
1289 [ -d RPMS/i386 ] || mkdir RPMS/i386
1291 [ -d RPMS/$arch ] || mkdir RPMS/$arch
1293 [ -d BUILD ] || mkdir BUILD
1294 [ -d SOURCES ] || mkdir SOURCES
1295 [ -d SPECS ] || mkdir SPECS
1296 [ -d SRPMS ] || mkdir SRPMS
1318 [[ $list\ == *\ $item\ * ]]
1322 #########################################################################
1323 # Generate a backtrace through the call stack.
1327 #########################################################################
1331 local funcname="" sourcefile="" lineno="" n
1333 echo "Call stack: (most recent first)"
1334 for (( n = $strip ; n < ${#FUNCNAME[@]} ; ++n )) ; do
1335 funcname=${FUNCNAME[$n - 1]}
1336 sourcefile=$(basename ${BASH_SOURCE[$n]})
1337 lineno=${BASH_LINENO[$n - 1]}
1338 # Display function arguments
1339 if [[ ! -z "${BASH_ARGV[@]}" ]]; then
1340 local args newarg j p=0
1341 for (( j = ${BASH_ARGC[$n - 1]}; j > 0; j-- )); do
1342 newarg=${BASH_ARGV[$j + $p - 1]}
1343 args="${args:+${args} }'${newarg}'"
1345 let p+=${BASH_ARGC[$n - 1]}
1347 echo " ${funcname} ${args:+${args} }at ${sourcefile}:${lineno}"
1351 echo "BEGIN BACKTRACE"
1353 #echo ${BASH_LINENO[*]}
1354 #echo ${BASH_SOURCE[*]}
1355 #echo ${FUNCNAME[*]}
1356 local i=$((${#FUNCNAME[@]} - 1))
1357 while [ $i -ge 0 ]; do
1358 local SOURCELINE="${BASH_SOURCE[$i + 1]}:${BASH_LINENO[$i]}"
1359 # Can't figure out how to get function args from other frames...
1360 local FUNCTION="${FUNCNAME[$i]}()"
1361 echo "$SOURCELINE:$FUNCTION"
1365 echo "END BACKTRACE"
1371 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
1373 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 -- "$@")
1375 if [ $? != 0 ]; then
1379 eval set -- "$options"
1414 if ! KERNELTREE=$(canon_path "$2"); then
1415 fatal 1 "Could not determine the canonical location of $2"
1419 --linux | --with-linux)
1420 if ! LINUX=$(canon_path "$2"); then
1421 fatal 1 "Could not determine the canonical location of $2"
1434 if ! REUSEBUILD=$(canon_path "$2"); then
1435 fatal 1 "Could not determine the canonical location of $2"
1452 if ! KERNELRPMSBASE=$(canon_path "$2"); then
1453 fatal 1 "Could not determine the canonical location of $2"
1500 --disable-datestamp)
1511 CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
1515 usage 1 "Unrecognized option: $1"
1525 EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
1527 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1529 unpack_ofed || fatal 1 "Error unpacking OFED tarball"
1532 # make sure the RPM build environment is set up
1533 create_rpmbuild_dirs
1535 trap '[ -n "$CCACHE" ] && ccache -s' EXIT
1537 # if an unpacked kernel source tree was given on the command line
1538 # just build lustre with it (nothing distro kernel specific here)
1539 if [ -n "$LINUX" ]; then
1542 if [ -f "${0%/*}/lbuild-$DISTRO" ]; then
1543 seen_list=$(new_list)
1544 trap '(echo "Untrapped error"
1546 # have we seen this one
1547 echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
1549 if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
1550 echo "seen this one already"
1552 seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
1558 ) | tee >(mail -s "Untrapped error at ${BASH_SOURCE[0]##*/}:${BASH_LINENO[0]} on $HOSTNAME" brian@sun.com) >&2' ERR
1561 source ${0%/*}/lbuild-$DISTRO
1563 build_with_srpm || fatal 1 "Failed to build_with_srpm"
1565 source ${0%/*}/lbuild.old_school
1567 old_school_download_kernel
1571 patchless_build_sequence && build_success=true
1573 [ "$DISTRO" = "sles9" ] && build_sequence_rpm_reuse && build_success=true
1574 if ! $build_success; then
1575 build_sequence_reuse && build_success=true
1576 if ! $build_success; then
1577 build_sequence && build_success=true
1578 if $build_success; then
1579 store_for_reuse || echo "Cannot store for future reuse"
1584 ( $build_success ) || fatal 1 "Cannot build lustre"