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 local location="http://downloads.lustre.org/public/OFED/"
404 if [[ $OFED_VERSION = daily-* ]]; then
405 OFED_VERSION=${OFED_VERSION/daily-/}
406 Mmv=${OFED_VERSION%%-*}
407 daily=${OFED_VERSION##$Mmv-}
408 location="http://www.openfabrics.org/downloads/OFED/ofed-${Mmv}-daily/"
409 # find the filename for the version for the date specified
410 OFED_VERSION=$(curl -s "$location" | sed -nre "/${daily}-/s/.*href=\"OFED-([0-9]+\.[0-9]+-${daily}-[0-9]{4,4}).tgz.*$/\1/p")
411 if [ -z "$OFED_VERSION" ]; then
412 fatal 1 "Could not determine the filename of the OFED snapshot for ${daily}"
416 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ] &&
417 ( $force || [ ! -r "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ||
418 [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ] ); then
420 echo "Downloading $location/OFED-${OFED_VERSION}.tgz..."
421 if ! wget -nv "$location/OFED-${OFED_VERSION}.tgz" \
422 -O "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ||
423 [ ! -s "$KERNELTREE/OFED-${OFED_VERSION}.tgz" ]; then
424 rm -f $KERNELTREE/OFED-${OFED_VERSION}.tgz
425 fatal 1 "Could not download OFED-${OFED_VERSION}.tgz" \
426 "from downloads.lustre.org."
429 fatal 1 "OFED-${OFED_VERSION}.tgz not found in kernel" \
430 "directory $KERNELTREE."
438 EXTRA_VERSION_save="$EXTRA_VERSION"
439 for patchesdir in "$EXTERNAL_PATCHES" \
440 "$TOPDIR/lustre/lustre/kernel_patches"; do
441 TARGET_FILE="$patchesdir/targets/$TARGET.target"
442 [ -r "$TARGET_FILE" ] && break
444 [ -r "$TARGET_FILE" ] || fatal 1 "Target $TARGET was not found."
446 echo "Loading target config file $TARGET.target..."
448 # if the caller specified an OFED_VERSION it should override whatever
449 # the target file specifies
450 local env_OFED_VERSION="$OFED_VERSION"
454 if [ -n "$env_OFED_VERSION" ]; then
455 OFED_VERSION="$env_OFED_VERSION"
458 # doesn't make any sense to build OFED for xen domX's
463 # XXX - set_rpm_smp_type is an ugly undeterministic hack. it needs to
464 # go away and the target just specify the $RPMSMPTYPE
465 [ -z "$RPMSMPTYPE" ] && set_rpm_smp_type
467 # CC might have been overwriten in TARGET_FILE
468 if [[ $CC != ccache\ * ]] && which "$CCACHE" 2>/dev/null; then
469 export CCACHE && export CC="ccache $CC"
472 if [ ! "$KERNELTREE" = "" ] && [ -d "$KERNELTREE" ]; then
473 KERNELDIR="$KERNELTREE/${lnxmaj}"
474 [ -d "$KERNELDIR" ] || mkdir "$KERNELDIR"
477 # verify the series is available
478 if [ "$SERIES" ]; then
479 for series in $SERIES; do
480 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
481 [ -r "$patchesdir/series/$series" ] && continue 2
483 fatal 1 "Target $TARGET's series $SERIES could not be" \
484 "found.\nSearched:\n\t$EXTERNAL_PATCHES/series\n" \
485 "\t$TOPDIR/lustre/lustre/kernel_patches/series."
489 # set the location of the .config file
495 if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config ]; then
496 CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET$XENPOSTFIX-$TARGET_ARCH${RPMSMPTYPE:+-}${RPMSMPTYPE}.config"
499 local lnxrelnew=${lnxrel//-/_}
501 # remember the EXTRA_VERSION before we diddle it here
502 # XXX - we really should not diddle with any values read in from the
503 # target file. if we want to modify a value, we should create
505 PRISTINE_EXTRA_VERSION=$EXTRA_VERSION
507 if ! $PATCHLESS && [ ! -f "$CONFIG_FILE" ]; then
508 fatal 1 "Config file for target $TARGET missing from" \
509 "$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
512 if [ "$EXTRA_VERSION_save" ]; then
513 EXTRA_VERSION="$EXTRA_VERSION_save"
514 elif ! $RELEASE; then
515 # if there is no patch series, then this is not a lustre specific
516 # kernel. don't make it look like one
517 if [ -n "$SERIES" ]; then
518 #remove the @VERSION@ (lustre version)
519 # EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
520 # EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
521 ! ( $PATCHLESS ) && EXTRA_VERSION="${EXTRA_VERSION}.${TIMESTAMP}"
524 # EXTRA_VERSION=${EXTRA_VERSION//-/_}
526 ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $BIGSMP_ARCHS $PSERIES64_ARCHS $UP_ARCHS"
529 for arch in $(uniqify "$ALL_ARCHS"); do
530 if [ -z "$TARGET_ARCHS" ] ||
531 [[ \ $TARGET_ARCHS\ = *\ $arch\ * ]]; then
532 BUILD_ARCHS="$BUILD_ARCHS $arch"
535 [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
536 echo "Building for: $BUILD_ARCHS"
544 fatal 1 "tarflags(): File name argument missing."
556 fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
565 echo "Untarring ${file##*/}..."
566 tar $(tarflags "$file") "$file"
572 if ! untar "$KERNELTREE/OFED-${OFED_VERSION}.tgz"; then
575 [ -d OFED ] || ln -sf OFED-[0-9].[0-9]* OFED
581 if [ -z "$LUSTRE" ]; then
584 if [ -n "$USE_DATESTAMP" ]; then
585 DATESTAMP="-D '$DATE'"
588 local DIRNAME="lustre-$TAG-$TIMESTAMP"
590 cvs -d "$CVSROOT" -qz3 co $DATESTAMP -d "$DIRNAME" lustre || \
591 fatal 1 "There was an error checking out toplevel Lustre from CVS."
592 pushd "$DIRNAME" > /dev/null
593 ./lustrecvs "$TAG" || \
594 fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
595 echo "Creating lustre tarball..."
596 sh autogen.sh || fatal 1 "There was an error running autogen.sh."
597 ./configure --disable-{modules,utils,liblustre,tests,doc} || \
598 fatal 1 "There was an error running ./configure to create makefiles."
599 make dist || fatal 1 "There was an error running 'make dist'."
600 LUSTRE=$PWD/lustre-*.tar.gz
604 untar "$LUSTRE" || fatal 1 "Error unpacking Lustre tarball"
605 [ -d lustre ] || ln -sf lustre-[0-9].[0-9]* lustre
611 local do_patch=${1:-true}
613 FULL_PATCH="$PWD/lustre-kernel-${TARGET}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}.patch"
614 [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
615 $do_patch && pushd linux >/dev/null
616 for series in $SERIES; do
617 echo -n "Applying series $series:"
618 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
619 [ -r "$patchesdir/series/$series" ] || continue
620 SERIES_FILE="$patchesdir/series/$series"
621 for patch in $(<"$SERIES_FILE"); do
623 PATCH_FILE="$patchesdir/patches/$patch"
624 [ -r "$PATCH_FILE" ] || \
625 fatal 1 "Patch $patch does not exist in Lustre tree."
626 cat "$PATCH_FILE" >> "$FULL_PATCH" || {
628 fatal 1 "Error adding patch $patch to full patch."
631 patch -s -p1 < "$PATCH_FILE" || {
633 fatal 1 "Error applying patch $patch."
641 $do_patch && popd >/dev/null
642 echo "Full patch has been saved in ${FULL_PATCH##*/}."
650 pushd lustre >/dev/null
652 echo "Building Lustre RPMs for: $BUILD_ARCHS..."
654 for arch in $BUILD_ARCHS; do
655 targets="--target $arch $targets"
658 local confoptions="--with-linux=${LINUX}"
660 confoptions="--with-linux=${LINUX} --disable-server"
662 if [ ! "$LINUXOBJ" = "" ]; then
663 confoptions="$confoptions --with-linux-obj=${LINUXOBJ}"
666 ./configure $confoptions ${CONFIGURE_FLAGS}
667 if [ "$?" != "0" ]; then
668 local saved_config="../config.log.$(date +%s)"
669 cp config.log $saved_config
670 chmod a+r $saved_config
671 echo "Saved config.log is at $saved_config"
675 echo "config.log contents:"
683 # hack. Somebody move build/lustre.spec to lustre.spec for b1_6
685 [ -f lustre.spec ] && lustre_spec=lustre.spec
686 [ -f build/lustre.spec ] && lustre_spec=build/lustre.spec
688 [ -f "$lustre_spec" ] && sed \
689 -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
693 local rpmbuildopt='-bb'
696 echo NORPM mode. Only compiling.
699 # convert the $PATCHLESS boolean to an empty/no-empty boolean
700 # as silly as this seems, it makes the syntax of the rpmbuild command
701 # simpler and not need an eval to deal with the quotes in the quotes
702 local is_patchless=""
706 $RPMBUILD $targets $rpmbuildopt ../lustre.spec \
707 ${is_patchless:+--define "lustre_name lustre-client"} \
708 --define "_tmppath $TMPDIR" \
709 --define "_topdir $TOPDIR" || \
710 fatal 1 "Error building rpms for $BUILD_ARCHS."
713 ( $(skeep_ldiskfs_rpm $TAG) ) && return
715 pushd lustre/ldiskfs || return 255
717 if [ "$?" != "0" ]; then
721 cp lustre-ldiskfs*.tar.gz $TOPDIR/SOURCES
725 local ldiskfs_spec=lustre-ldiskfs.spec
726 [ -f "$ldiskfs_spec" ] && sed \
727 -e "s^Release: .*$^Release: $LUSTRE_EXTRA_VERSION^" \
729 > ../lustre-ldiskfs.spec
731 $RPMBUILD $targets $rpmbuildopt ../lustre-ldiskfs.spec \
732 --define "_tmppath /var/tmp" \
733 --define "_topdir $TOPDIR"
734 if [ "$?" != "0" ]; then
740 $RPMBUILD -bs ../lustre-ldiskfs.spec \
741 --define "_tmppath /var/tmp" \
742 --define "_topdir $TOPDIR"
743 if [ "$?" != "0" ]; then
754 [ "$STAGEDIR" ] || return 0
756 for arch in $BUILD_ARCHS; do
757 rpmdir="${STAGEDIR}/${CANONICAL_TARGET}-${arch}"
758 echo "${0##*/}: Copying RPMs into ${rpmdir}"
760 cp -v RPMS/${arch}/*.rpm "${rpmdir}"
761 if [ -d RPMS/noarch ]; then
762 cp -v RPMS/noarch/*.rpm "${rpmdir}"
766 cp -v "$LUSTRE" "$STAGEDIR"
770 #check if we need to build separate ldiskfs RPM
771 skeep_ldiskfs_rpm() {
776 if ! $LDISKFSRPM; then
778 elif $PATCHLESS; then
781 for skiptag in $SKIPLDISKFSRPM; do
782 [[ $tag == $skiptag ]] && skip=true && break
786 pushd $TOPDIR/BUILD/lustre-[1-9]* >/dev/null
787 grep -q '^SERVER_TRUE[ \t]=[ \t]#$' autoMakefile && skip=true
794 #generate LUSTRE_EXTRA_VERSION from EXTRA_VERSION
795 gen_lustre_version() {
797 LUSTRE_EXTRA_VERSION="${lnxmaj}${EXTRA_VERSION_DELIMITER}${EXTRA_VERSION}${TARGET_DELIMITER}${RPMSMPTYPE}"
798 LUSTRE_EXTRA_VERSION=${LUSTRE_EXTRA_VERSION//-/_}
804 local infact_arch="${TARGET_ARCH}"
807 [ "$infact_arch" == "i586" ] && infact_arch="i686"
810 for smp_type in $SMP_ARCHS; do
811 [ $infact_arch == $smp_type ] && RPMSMPTYPE=smp && break
814 for smp_type in $BIGSMP_ARCHS; do
815 [ $infact_arch == $smp_type ] && RPMSMPTYPE=bigsmp && break
818 for smp_type in $DEFAULT_ARCHS; do
819 [ $infact_arch == $smp_type ] && RPMSMPTYPE=default && break
824 # This function takes a linux source pool and digs out the linux release
826 find_linux_release() {
829 local LINUXRELEASEHEADER=$SRCDIR/include/linux/version.h
830 if [ -s $SRCDIR/include/linux/utsrelease.h ]; then
831 LINUXRELEASEHEADER=$SRCDIR/include/linux/utsrelease.h
834 sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' $LINUXRELEASEHEADER
838 # XXX this needs to be re-written as a wrapper around find_rpm
839 # or just gotten rid of. :-)
842 local delimiter=${2:-"-"}
844 local pathtorpms="${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
845 [ -d $pathtorpms ] || return 255
847 local kernelbinaryrpm rpmfile
848 local wanted_kernel="${lnxmaj}${delimiter}${lnxrel}"
851 for arch in $TARGET_ARCHS_ALL; do
852 local found_rpm="" rpm
853 for rpm in ${pathtorpms}/${arch}/*.rpm; do
854 if rpm -q --provides -p "$rpm" | grep -q "kernel${prefix} = $wanted_kernel"; then
860 [ -f "$found_rpm" ] && break
868 # unpack kernel(/source/devel) RPM
870 # This function and it's setting of $LINUX and $LINUXOBJ is a total hack that
871 # needs to completely refactored. It completely ingores that $BUILD_ARCHS may
872 # contain a list of arches for which rpmbuild commands (including the one for
874 unpack_linux_devel_rpm() {
875 local kernelrpm="${1}"
876 # it's worth noting that neither sles10 nor rhel5 appear to use their
877 # extra_version delimiter for the dirname under /usr/src, so we could
878 # probably just get rid of this parameter
879 local delimiter=${2:-"-"}
881 [ -f "$kernelrpm" ] || return 255
882 [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
884 pushd $TOPDIR/reused || return 255
886 if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
890 # call a distro specific hook, if available
891 if type -p unpack_linux_devel_rpm-$DISTRO; then
892 unpack_linux_devel_rpm-$DISTRO "$kernelrpm"
897 find_linux_devel_paths $TOPDIR/reused
903 # XXX - this rhel/sles goop needs abstracting out into the
904 # lbuild-{rhel5,sles10} method files
905 find_linux_devel_paths() {
911 # RHEL-style and SLES-style rpms
912 # XXX - until bug 19336 cleans this up, we need to extricate the
913 # ${lnxmin}- from the $lnxrel
914 local paths="kernels/${lnxmaj}${lnxmin}${delimiter}${lnxrel}-${TARGET_ARCH} linux-${lnxmaj}${lnxmin}${delimiter}${lnxrel##${lnxmin#.}-}"
917 for path in $paths; do
920 if [ -d "$src/$path/" ]; then
921 LINUX="$(pwd)/$src/$path"
923 # SLES has a separate -obj tree
924 if [ -d "$src/${path}-obj" ]; then
925 local src="$src/${path}-obj"
926 local objects="$TARGET_ARCH/$RPMSMPTYPE"
928 # Novell, are you *TRYING* to make life hard for me?
929 if [ -d "$src/powerpc" ]; then
930 objects="powerpc/$TARGET_ARCH"
931 elif [ $TARGET_ARCH == 'i686' ]; then
932 objects="i386/$RPMSMPTYPE"
935 LINUXOBJ="$(pwd)/$src/$objects"
938 if [ -z "$LINUX" ]; then
941 # dig out the release version
942 LINUXRELEASE=$(find_linux_release ${LINUXOBJ:-$LINUX})
943 if [ -z "$LINUXRELEASE" ]; then
944 echo "Failed to find linux release in ${LINUXOBJ:-$LINUX}"
955 # build kernel-ib{,-devel}
957 # ofed 1.3 had a bug in the rpm spec
958 if [ "$OFED_VERSION" = "1.3" ]; then
962 local OFED_CORE="--with-core-mod --with-ipoib-mod --with-sdp-mod --with-user_mad-mod --with-user_access-mod --with-addr_trans-mod --with-rds-mod --with-qlgc_vnic-mod --with-madeye-mod"
963 local OFED_HARDWARE="--with-mthca-mod --with-mlx4-mod --with-mlx4_en-mod --with-cxgb3-mod --with-nes-mod"
964 # some I/B drivers are architecture dependent and kernel-ib's configure
965 # does not figure it out for us ~sigh~
966 case "$TARGET_ARCH" in
968 OFED_HARDWARE="$OFED_HARDWARE --with-ehca-mod"
971 # we're no longer shipping the OFED iSCSI
972 #OFED_ISCSI="--with-srp-mod --with-srp-target-mod"
973 ## ISER module has no backport support as of OFED 1.5 (i.e. only builds on
975 #if [[ $OFED_VERSION = 1.[0-4]* ]]; then
976 # OFED_ISCSI="$OFED_ISCSI --with-iser-mod"
979 local linuxrelease=$(find_linux_release "$linux")
980 $RPMBUILD --rebuild --define 'build_kernel_ib 1' --define 'build_kernel_ib_devel 1' \
981 --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
982 --define "KVERSION ${linuxrelease}" \
983 --define "$K_SRC ${linux}" \
984 --define "LIB_MOD_DIR /lib/modules/${linuxrelease}/updates" \
985 ${OFA_KERNEL_RELEASE:+--define "_release $OFA_KERNEL_RELEASE"} \
986 --define "configure_options --without-quilt $OFED_CORE $OFED_HARDWARE $OFED_ISCSI" \
987 ${TOPDIR}/OFED/SRPMS/ofa_kernel-*.src.rpm
989 if [ ${PIPESTATUS[0]} != 0 ]; then
990 fatal 1 "Error building kernel-ib"
1000 local use_links="$5"
1007 location="$location"/"$signature"/"$module"
1008 mkdir -p "$location"
1009 # the cleanup script removes any directory that doesn't have a
1010 # .lastused, so let's try to prevent that as soon as we can
1011 # this solution still slightly racy with the cleanup script
1012 # but the race is a lot tighter now
1013 touch -t 197001010000 "$location/.lastused"
1014 ## use eval/echo here to make sure shell expansions are performed
1015 #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
1017 for article in $(eval echo $articles); do
1018 if ! cp -a${linkflag} "$article" "$location"; then
1019 error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
1020 # rename the cache location so that it's not cached
1021 # product, but is around for analysis
1022 mv "$location"{,-bad-$(date +%s)} ||
1023 error "failed to clean up a failed cache attempt" \
1024 "in \"$location\" -- manual cleanup will be" \
1030 # flag the cache as complete (i.e. in case lbuild was previously
1031 # interrupted while caching)
1032 touch "$location/.lastused"
1041 local use_links="${3:-false}"
1042 local signature="$4"
1044 if [ -n "$REUSEBUILD" ] && [ -d "$REUSEBUILD/$signature/$module" ]; then
1045 if [ ! -f "$REUSEBUILD/$signature/$module/.lastused" ]; then
1046 # the .lastused flag is populated at the end of the caching to
1047 # signal that the caching was completeld. if that flag is not
1048 # there, then the cache is invalid (and should be removed in fact)
1049 mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} ||
1050 fatal 1 "failed to clean up a bad cache in location" \
1051 "\"$REUSEBUILD/$signature/$module\" -- manual cleanup" \
1056 # so that we know how stale this entry is
1057 touch $REUSEBUILD/$signature/$module/.lastused
1060 if ls $REUSEBUILD/$signature/$module/* >/dev/null 2>&1; then
1061 cp -al $REUSEBUILD/$signature/$module/* $dest/
1064 # copying is pretty heavy
1065 # cp -a $REUSEBUILD/$signature/$module/* $dest/
1066 # do some creative symlinking instead
1068 for dir in BUILD SRPMS SPECS; do
1069 if ls $REUSEBUILD/$signature/$module/$dir/* >/dev/null 2>&1; then
1070 ln -s $REUSEBUILD/$signature/$module/$dir/* $dest/$dir
1073 # sources have to be copied by file because we need SOURCES to
1074 # be a dir we can write into
1075 # could overrun ls's arg list here
1076 #ls $REUSEBUILD/$signature/$module/SOURCES/* |
1077 find $REUSEBUILD/$signature/$module/SOURCES/ -type f |
1078 xargs ln -t $dest/SOURCES -s
1080 # same for RPMS/* dirs
1081 # could overrun ls's arg list here
1082 #ls $REUSEBUILD/$signature/$module/RPMS/$TARGET_ARCH/* |
1084 for dir in $REUSEBUILD/$signature/$module/RPMS/*; do
1085 mkdir -p $dest/RPMS/${dir##*/}
1087 xargs ln -t $dest/RPMS/${dir##*/} -s
1100 if [[ $arch = i[3456]86 ]]; then
1109 # in a given directory, find the first rpm matching given requirements
1113 local match_type="$2"
1116 pushd "$dir" > /dev/null || \
1117 fatal 1 "Unable to chdir to directory \"$dir\" in find_rpm()"
1120 for file in $(ls *.rpm); do
1121 if [ ! -f "$file" ]; then
1124 case "$match_type" in
1126 # match is any valid ERE (i.e. given to egrep) match
1127 if rpm -q --provides -p "$file" | egrep -q "$match"; then
1135 fatal 1 "Unknown match type \"$match_type\" given to find_rpm()"
1144 build_kernel_with_srpm() {
1146 # need to generate the patch for this target
1147 do_patch_linux false >&2 # sets global $FULL_PATCH (yeah, yuck)
1149 # get an md5sum of the kernel patch + config for reuse check
1150 # XXX really, there needs to be a signature and a CONFIG_FILE per arch
1154 local release_str="RELEASE=$RELEASE\n"
1156 local REUSE_SIGNATURE=$({ echo -en $release_str; echo $BUILD_GEN; cat $CONFIG_FILE $TARGET_FILE $FULL_PATCH; } | md5sum | cut -d" " -f1)
1158 # see if we can link to the reuse pool
1159 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1160 local CAN_LINK_FOR_REUSE=false
1161 touch $REUSEBUILD/$$
1162 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1163 CAN_LINK_FOR_REUSE=true
1167 # the extra version string to use for the kernel (which might be a reused
1169 local kernel_extra_version=""
1170 if $REUSERPM && ! reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1171 "$REUSE_SIGNATURE"; then
1172 # nothing cached, build from scratch
1173 if [ ! -r "$KERNELDIR/$KERNEL_SRPM" ]; then
1174 download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&2
1177 if ! rpm -ivh $KERNELDIR/$KERNEL_SRPM \
1178 --define "_topdir $TOPDIR" >&2; then
1179 # should we clean this up or leave it for analysis?
1181 fatal 1 "Error installing kernel SRPM."
1184 # put the Lustre kernel patch into the RPM build tree
1185 cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
1186 prepare_and_build_srpm >&2
1188 # store the resulting kernel RPM build tree for future use
1189 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1190 "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1191 "$CAN_LINK_FOR_REUSE"; then
1192 error "Failed to store kernel RPMS for reuse"
1198 # figure out the EXTRA_VERSION of the kernel we built or are re-using
1200 if ! KERNEL_RPM=$(find_rpm "$TOPDIR/RPMS/$TARGET_ARCH/" provides "^kernel ="); then
1201 fatal 1 "Failed to find a kernel RPM in $TOPDIR/RPMS/$TARGET_ARCH/"
1203 kernel_extra_version=$(rpm -q --queryformat "%{RELEASE}" -p $TOPDIR/RPMS/$TARGET_ARCH/$KERNEL_RPM)
1205 # should now have the following RPMs
1206 # $TOPDIR/RPMS/$arch/kernel-lustre-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1207 # $TOPDIR/RPMS/$arch/kernel-lustre-devel-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1208 # $TOPDIR/RPMS/$arch/kernel-lustre-headers-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1209 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-common-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1210 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1212 echo $kernel_extra_version
1219 if ! $PATCHLESS; then
1220 local kernel_extra_version
1221 if ! kernel_extra_version=$(build_kernel_with_srpm); then
1222 fatal 1 "Failed to build the kernel from it's SRPM"
1225 for arch in $BUILD_ARCHS; do
1227 local kernel_devel_rpm
1228 if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/$arch/" provides "^$(devel_kernel_name $KERNEL_LUSTRE_NAMING) ="); then
1229 fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/$arch/"
1232 # install the -devel RPM in preparation for the lustre build
1233 # note that the EXTRA_VERSION_DELIMITER is *NOT* used in the
1234 # version of the directory name under /usr/src
1235 if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
1236 "$TOPDIR/RPMS/$arch/$kernel_devel_rpm" "-"; then
1237 fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/$arch/$kernel_devel_rpm"
1241 # need to find and unpack the vendor's own kernel-devel for patchless
1244 if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE" ${EXTRA_VERSION_DELIMITER:-"-"}); then
1245 fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in ${KERNELRPMSBASE}/${lnxmaj}/${DISTRO}"
1247 if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
1248 fatal 1 "Could not find the Linux tree in $kernelrpm"
1252 # before lustre, build kernel-ib
1253 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1254 # see if we can link to the reuse pool
1255 # XXX - hrm. i'm not convinced this doesn't belong in the reuse "library"
1256 local CAN_LINK_FOR_REUSE=false
1257 touch $REUSEBUILD/$$
1258 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1259 CAN_LINK_FOR_REUSE=true
1263 local REUSE_SIGNATURE=$({ echo "$OFED_VERSION"; echo "$(find_linux_release ${LINUXOBJ:-$LINUX})"; cat "${LINUXOBJ:-${LINUX}}/include/linux/autoconf.h"; } | md5sum | cut -d" " -f1)
1264 if ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1265 "$REUSE_SIGNATURE"; then
1266 # stash away the existing built articles for a moment
1268 mv {BUILD,{S,}RPMS,S{OURCE,PEC}S} bak
1271 find . | cpio -pudlm ..
1275 create_rpmbuild_dirs
1277 build_kernel_ib "${LINUXOBJ:-${LINUX}}"
1278 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1279 "ofed" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1280 "$CAN_LINK_FOR_REUSE"; then
1281 error "Failed to store OFED RPMS for reuse"
1285 # put the stuff we stashed away back
1289 pushd "$TOPDIR" >/dev/null
1290 rm -rf kernel-ib-devel
1291 mkdir kernel-ib-devel
1293 # the actual ofed RPMs don't have the -rc$n or -$date string appened that
1294 # might be present on the file
1295 local ofed_version=$(echo $OFED_VERSION |
1296 sed -re 's/-(20[0-9]{6,6}-[0-9]{4,4}|rc[0-9]*)$//')
1297 local rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version}-${LINUXRELEASE//-/_}.*.rpm)
1298 rpm2cpio -itv < $rpm | cpio -id
1299 CONFIGURE_FLAGS="--with-o2ib=$(pwd)/usr/src/ofa_kernel ${CONFIGURE_FLAGS}"
1304 if build_lustre; then
1305 # the build worked. resolve any symlinked files (i.e. from reuse)
1306 # in RPMS/$arch to real files so that that that huge mess of
1307 # complication knows as LTS can copy them yet somewhere else.
1308 # is it any wonder this whole process is so damn so? anyone ever
1309 # heard of hardlinks? it this cool new thing that allows you save
1310 # tons of time and space by creating... well you can go read about
1311 # them if you have not heard about them yet.
1312 # can i say how much the implemenation of all of this really impedes
1314 pushd RPMS/$TARGET_ARCH
1316 if [ -h $file ]; then
1328 create_rpmbuild_dirs() {
1330 [ -d RPMS ] || mkdir RPMS
1331 for arch in $BUILD_ARCHS; do
1332 if [[ $arch = i?86 ]]; then
1333 # some stupidity in the sles11 kernel spec requires an RPMS/i386
1334 # even if the target arch is i686
1335 [ -d RPMS/i386 ] || mkdir RPMS/i386
1337 [ -d RPMS/$arch ] || mkdir RPMS/$arch
1339 [ -d BUILD ] || mkdir BUILD
1340 [ -d SOURCES ] || mkdir SOURCES
1341 [ -d SPECS ] || mkdir SPECS
1342 [ -d SRPMS ] || mkdir SRPMS
1364 [[ $list\ == *\ $item\ * ]]
1368 #########################################################################
1369 # Generate a backtrace through the call stack.
1373 #########################################################################
1377 local funcname="" sourcefile="" lineno="" n
1379 echo "Call stack: (most recent first)"
1380 for (( n = $strip ; n < ${#FUNCNAME[@]} ; ++n )) ; do
1381 funcname=${FUNCNAME[$n - 1]}
1382 sourcefile=$(basename ${BASH_SOURCE[$n]})
1383 lineno=${BASH_LINENO[$n - 1]}
1384 # Display function arguments
1385 if [[ ! -z "${BASH_ARGV[@]}" ]]; then
1386 local args newarg j p=0
1387 for (( j = ${BASH_ARGC[$n - 1]}; j > 0; j-- )); do
1388 newarg=${BASH_ARGV[$j + $p - 1]}
1389 args="${args:+${args} }'${newarg}'"
1391 let p+=${BASH_ARGC[$n - 1]}
1393 echo " ${funcname} ${args:+${args} }at ${sourcefile}:${lineno}"
1397 echo "BEGIN BACKTRACE"
1399 #echo ${BASH_LINENO[*]}
1400 #echo ${BASH_SOURCE[*]}
1401 #echo ${FUNCNAME[*]}
1402 local i=$((${#FUNCNAME[@]} - 1))
1403 while [ $i -ge 0 ]; do
1404 local SOURCELINE="${BASH_SOURCE[$i + 1]}:${BASH_LINENO[$i]}"
1405 # Can't figure out how to get function args from other frames...
1406 local FUNCTION="${FUNCNAME[$i]}()"
1407 echo "$SOURCELINE:$FUNCTION"
1411 echo "END BACKTRACE"
1417 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
1419 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,ofed-version:,publish,release,src,stage:,tag:,target:,target-archs:,with-linux:,xen -- "$@")
1421 if [ $? != 0 ]; then
1425 eval set -- "$options"
1460 if ! KERNELTREE=$(canon_path "$2"); then
1461 fatal 1 "Could not determine the canonical location of $2"
1465 --linux | --with-linux)
1466 if ! LINUX=$(canon_path "$2"); then
1467 fatal 1 "Could not determine the canonical location of $2"
1480 if ! REUSEBUILD=$(canon_path "$2"); then
1481 fatal 1 "Could not determine the canonical location of $2"
1498 if ! KERNELRPMSBASE=$(canon_path "$2"); then
1499 fatal 1 "Could not determine the canonical location of $2"
1550 --disable-datestamp)
1561 CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-liblustre --enable-liblustre-tests"
1565 usage 1 "Unrecognized option: $1"
1575 EXTRA_VERSION_DELIMITER=${EXTRA_VERSION_DELIMITER:-"-"}
1577 if [ -n "$OFED_VERSION" -a "$OFED_VERSION" != "inkernel" ]; then
1579 unpack_ofed || fatal 1 "Error unpacking OFED tarball"
1582 # make sure the RPM build environment is set up
1583 create_rpmbuild_dirs
1585 trap '[ -n "$CCACHE" ] && ccache -s' EXIT
1587 # if an unpacked kernel source tree was given on the command line
1588 # just build lustre with it (nothing distro kernel specific here)
1589 if [ -n "$LINUX" ]; then
1592 if [ -f "${0%/*}/lbuild-$DISTRO" ]; then
1593 seen_list=$(new_list)
1594 trap '(echo "Untrapped error"
1596 # have we seen this one
1597 echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
1599 if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
1600 echo "seen this one already"
1602 seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
1608 ) | tee >(mail -s "Untrapped error at ${BASH_SOURCE[0]##*/}:${BASH_LINENO[0]} on $HOSTNAME" brian@sun.com) >&2' ERR
1611 source ${0%/*}/lbuild-$DISTRO
1613 build_with_srpm || fatal 1 "Failed to build_with_srpm"
1615 source ${0%/*}/lbuild.old_school
1617 old_school_download_kernel
1621 patchless_build_sequence && build_success=true
1623 [ "$DISTRO" = "sles9" ] && build_sequence_rpm_reuse && build_success=true
1624 if ! $build_success; then
1625 build_sequence_reuse && build_success=true
1626 if ! $build_success; then
1627 build_sequence && build_success=true
1628 if $build_success; then
1629 store_for_reuse || echo "Cannot store for future reuse"
1634 ( $build_success ) || fatal 1 "Cannot build lustre"