3 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
5 # this is an alternative FD for stdout, to be used especially when we are
6 # taking stdout from a function as it's return value. i.e. foo=$(bar)
7 # this is a workaround until a version of bash where we can put xtrace
13 if [[ $SHELLOPTS = *xtrace* ]]; then
18 # Assume that lbuild's support files can be found in the same
19 # canonicalized path as this very script.
20 LBUILD_SCRIPT=$(readlink -f ${0})
21 LBUILD_DIR=${LBUILD_DIR:-$(dirname ${LBUILD_SCRIPT})}
23 # include the exit_traps library
24 . ${LBUILD_DIR}/exit_traps.sh
25 . ${LBUILD_DIR}/funcs.sh
27 # our children should die when we do
28 push_exit_trap "kill -INT -$$ || true" kill_children
30 # increment this if you have made a change that should force a new kernel
40 # XXX - some recent hacking has pretty much neutered this option.
41 # search through this file for "-bb" and see how many places
42 # simply don't account for this option
47 TARGET_ARCH="$(uname -m)"
52 TMPDIR=${TMPDIR:-"/var/tmp"}
56 # this is the dir that should be used to store reuse products
58 # should cached products be used or force rebuilding?
60 # what does this do exactly? does it imply no kernel build?
64 SMPTYPES="smp bigsmp default ''"
66 PATCHLESS_SERVER=false
72 # default to not adding -lustre- into the kernel RPM package names
73 KERNEL_LUSTRE_NAMING=false
74 ENABLE_KERNEL_DEBUG=false
75 # default not use kabi check.
93 # not in the target file any more
96 # build the lustre-tests rpm?
105 # Readlink is not present on some older distributions: emulate it.
109 if [ -L "$path" ]; then
110 ll="$(LC_ALL=C ls -l "$path" 2> /dev/null)" &&
119 Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
121 --external-patches=EXTERNAL_PATCHES
122 Directory similar to lustre/lustre/kernel_patches/ that lbuild should
123 look for seres and config files in before looking in the lustre
126 --extraversion=EXTRAVERSION
127 Text to use for the rpm release and kernel extraversion.
129 --timestamp=TIMESTAMP
130 Date of building lustre in format YYYYMMDDhhmmss
133 Try to reuse old kernel builds from DIR
136 Path to distro kernel RPM collection
145 Build lustre client only
148 Build lustre server without patching the kernel
151 Which distro using. Autodetect by default
153 --kerneldir=KERNELDIR
154 Directory containing Linux source tarballs referenced by target
157 --kerneltree=KERNELTREE
158 Directory containing dirs with Linux source tarballs referenced by target
159 files. Dir names in format kernel version ('2.6.9', etc.)
161 --enable-kernel-debug
162 Build with kernel-<version>.config-debug instead
164 --linux=LINUX --with-linux=LINUX
165 Directory of Linux kernel sources. When this option is used, only
166 Lustre modules and userspace are built.
169 Path to an existing lustre source tarball to use.
172 Do not try to download a kernel from downloads.whamcloud.com
175 Do not build a .src.rpm, a full kernel patch, or a patched kernel
179 Type of OFED to build with lustre: inkernel, ofa, mlnx, ifs
180 ofa: OpenFabrics Alliance
182 ifs: Intel True Scale Fabric
185 Version of external OFED to build with lustre
188 Version of external Mellanox OFED to build with lustre
191 Tarball for either OFED. Tarball must follow below format
192 OFED-<ofed-version>.tgz regardless of vendors
193 It's likely that you need to reconstruct the directory name
194 It must be placed under KERNELTREE directory
197 Build with ldiskfs support. (Deprecated, always true)
200 Do not build lustre-iokit RPM. Now true by default
206 Specifies that the files generated do not include timestamps, and
207 that this is an official release.
210 Build Lustre without ZFS.
213 Build a .src.rpm, a full kernel patch, and a patched kernel tarball.
216 Directory used to stage packages for release. RPMs will be placed
217 more or less in DIR/<target>-<arch>, and the tarball will be
221 The name of the target to build. The available targets are listed
225 Builds a Xen domX kernel.
228 Sets a variable to a given value.
237 # canonicalize a relative path to a file
241 if [ ! -f "$PATH" ]; then
245 local FILE=${PATH##*/}
248 echo $(canon_path "$DIR")/$FILE
252 # canonicalize a relative path to a dir
256 if [ ! -d "$PATH" ]; then
260 pushd "$PATH" >/dev/null || return 1
270 if [ -z "$LUSTRE" -o ! -r "$LUSTRE" ]; then
271 usage 1 "Could not find Lustre source tarball '$LUSTRE'."
274 if $PATCHLESS && $PATCHLESS_SERVER; then
275 usage 1 "Can not use both --patchless and --patchless-server."
278 if [ -n "${OFED_SRC}" ]; then
279 if [ -z "${OFED_VERSION}" ]; then
280 usage 1 "Need to provide version for file ${OFED_SRC}."
282 if [ "${OFED_TYPE}" = "inkernel" ]; then
283 usage 1 "Need to provide ofed type for file ${OFED_SRC}."
286 if [ "${OFED_TYPE}" != "inkernel" -a -z "${OFED_VERSION}" ]; then
287 usage 1 "Need to provide version for $OFED_TYPE OFED"
290 if [ "${OFED_TYPE}" = "inkernel" -a -n "${OFED_VERSION}" ]; then
291 usage 1 "Can not specify version with inkernel OFED"
295 if [ -z "$DISTRO" ] ; then
296 DISTRO=$(autodetect_distro)
300 DISTROMAJ=${DISTRO%%.*}
302 [ -z "$TARGET" ] && TARGET=$(autodetect_target "$DISTRO")
304 if [ -z "$LINUX" ]; then
305 [ "$KERNELDIR" -o "$KERNELTREE" ] || \
306 usage 1 "A kernel directory must be specified with --kerneldir or --kerneltree."
308 [ -d "$KERNELDIR" -o -d "$KERNELTREE" ] || \
309 usage 1 "$KERNELDIR and $KERNELTREE are not a directory."
311 # TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
312 # [ -r "$TARGET_FILE" ] || \
313 # usage 1 "Target '$TARGET' was not found."
317 3.12-sles12 | 4.4-sles12)
318 CANONICAL_TARGET="sles12"
321 CANONICAL_TARGET="rhel9"
324 CANONICAL_TARGET="rhel8"
327 CANONICAL_TARGET="rhel7"
330 CANONICAL_TARGET="sles11"
333 CANONICAL_TARGET="oe2203"
337 echo "### GIT COMMIT BUILD-PARAMETERS CHECK: git log -1 ###"
339 echo "### GIT COMMIT BUILD-PARAMETERS CHECK: parsing ###"
340 local build_params="Build-Parameters:"
341 local build_distro=""
344 rhel*) build_distro=${DISTRO#rh} ;;
345 sles*) build_distro=${DISTRO/\./sp} ;;
346 *) build_distro=$DISTRO ;;
349 echo "### GIT COMMIT BUILD-PARAMETERS CHECK: environment ###"
350 echo "TARGET_ARCH='$TARGET_ARCH'"
351 echo "DISTRO='$DISTRO'"
352 echo "PATCHLESS='$PATCHLESS'"
353 echo "build_distro='$build_distro'"
355 echo "### GIT COMMIT BUILD-PARAMETERS CHECK: eval ###"
356 # Default should be to build everything, unless Build-Parameters are set,
357 # in which case only the specified builds will be done, all others skipped.
358 # Expect lines with one directive per line, possibly comma-separated:
359 # Build-Parameters: clientdistro=el8.7,el9.2 [clientarch=aarch64]
360 # Build-Parameters: serverdistro=el8.8 [serverarch=x86_64]
361 # Build-Parameters: ignore
362 # Having both clientdistro and serverdistro on the same line will not work.
365 while read build_parameters param1 param2 ignored_params; do
370 [[ "$param1" =~ "ignore" ]] && break # skip all builds, only for review
371 [[ "$param1" =~ "client" && "$PATCHLESS" == "false" ]] && continue
372 [[ "$param1" =~ "server" && "$PATCHLESS" == "true" ]] && continue
373 [[ "$param1" =~ "distro" ]] && distro="$param1" || distro="$param2"
374 [[ "$param1" =~ "arch" ]] && arch="$param1" || arch="$param2"
375 [[ -z "$arch" || "$arch" =~ "$TARGET_ARCH" ]] &&
376 [[ -z "$distro" || "$distro" =~ "$build_distro" ]] &&
378 done < <(git log -1 | grep -i "^ $build_params" || echo "")
381 local msg="SKIP: $build_distro:$TARGET_ARCH not found in $build_params"
382 # create some empty directories to keep createrepo in caller happy
384 echo "$msg" >> SRPMS/README
385 echo "$msg" >> README
389 echo "### GIT COMMIT BUILD-PARAMETERS CHECK: fini ###"
391 local timestampnodig=$(echo $TIMESTAMP | sed -e s/[0-9]*//g)
392 [ "$timestampnodig" = "" ] || TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
393 local timestamplength="${#TIMESTAMP}"
394 if [ $timestamplength -eq 12 ]; then
395 TIMESTAMP="${TIMESTAMP}00"
396 elif [ $timestamplength -ne 14 ]; then
397 TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M%S")
400 RPMBUILD=$(which rpmbuild 2>/dev/null | head -n 1)
401 RPMBUILD=${RPMBUILD:-$(which rpm 2>/dev/null | head -n 1)}
402 if [ -z "$RPMBUILD" ]; then
403 usage 1 "Could not find binary for making rpms (tried rpmbuild and rpm)."
406 local BINDIR="$TOPDIR/bin"
407 if [ -d $BINDIR ]; then
408 rm -rf $BINDIR >/dev/null 2>&1 || true
411 mkdir -p $BINDIR || fatal 1 "error trying to create $BINDIR"
412 export PATH=$BINDIR:$PATH
414 cat >${BINDIR}/rpmbuild <<EOF
417 ARGS="\${FIND_REQUIRES:+--define \"__find_requires \$FIND_REQUIRES\"}
418 \${FIND_KSYMS_REQUIRES:+--define \"__required_ksyms_requires \$FIND_KSYMS_REQUIRES\"}"
421 *\'* ) ARGS="\$ARGS \"\$arg\"" ;;
422 * ) ARGS="\$ARGS '\$arg'" ;;
426 eval $RPMBUILD \$ARGS
428 chmod 755 ${BINDIR}/rpmbuild
430 if [ -n "$CCACHE" ]; then
431 which "$DISTCC" &>/dev/null && export DISTCC RPM_BUILD_NCPUS
433 if which "$CCACHE" &>/dev/null; then
434 local ccache=$(which "$CCACHE" 2>/dev/null | head -n 1)
436 ln -s "$ccache" ${BINDIR}/ccache
437 ln -s "$ccache" ${BINDIR}/cc
438 ln -s "$ccache" ${BINDIR}/$CC
441 export CC="ccache $CC"
442 # zero the cache so we can see how effective we are being with it
446 # get some ccache stats when we are done
447 push_exit_trap '[ -n "$CCACHE" ] && ccache -s' "ccache_summary"
448 # should remove the ccache trap if lbuild is interrupted
449 trap 'echo "Received an INT TERM or HUP signal, terminating."; delete_exit_trap "ccache_summary"; exit 1' INT TERM HUP
456 # compare two versions $1 and $2. if $1 < $2, return 0 otherwise return 1.
458 [[ $1 == $2 ]] && return 1
460 # remove all minor sub version
461 local i val1=(${1//-*}) val2=(${2//-*})
463 # padding zero to val1 if it needs
464 for ((i=${#val1[@]}; i<${#val2[@]}; i++)); do
467 for ((i=0; i<${#val1[@]}; i++)); do
468 [[ -z ${val2[i]} ]] && return 1
470 if (( ${val1[i]} < ${val2[i]} )); then
472 elif (( ${val1[i]} > ${val2[i]} )); then
479 # Return a numeric version code based on a version string. The version
480 # code is useful for comparison two version strings to see which is newer.
482 # split arguments like "0.8.0" into "0", "8", "0"
483 eval set -- $(tr "[:punct:]" " " <<< $*)
484 echo -n "$((($1 << 16) | ($2 << 8) | $3))"
489 echo $(echo "$*" | xargs -n 1 | sort -u)
497 if [ -z "$target" ]; then
498 fatal 1 "fetch_url() called without a target to fetch to"
501 if [ -d $target ]; then
502 target+="/${url##*/}"
506 if which wget >/dev/null 2>&1; then
507 if ! wget -nv "$url" -O "$target"; then
510 elif which curl >/dev/null 2>&1; then
511 if ! curl -n -L -s -o "$target" "$url"; then
515 fatal 1 "Could not find either wget or curl to fetch URLs."
525 local force="${3:-false}"
527 [[ ! -s "$KERNELDIR/$srpm" ]] || return 0
529 # let the download_file handle the concurrency
532 # get the location from a distro specific method if it exists
533 if type -p kernel_srpm_location; then
534 location=$(kernel_srpm_location)
536 fatal 1 "Must specify location for download kernel SRPM."
538 echo "Downloading $location/$srpm..."
540 "$location/$srpm" "$KERNELDIR/$srpm" "$force" 2>&1 ||
541 [ ! -s "$KERNELDIR/$srpm" ]; then
542 rm -f $KERNELDIR/$srpm
543 fatal 1 "Could not download target $target's kernel \
544 SRPM $srpm from $location."
549 download_debuginfo_common() {
551 local force="${2:-false}"
553 [[ ! -s "$KERNELRPMSBASE/$lnxmaj/$DISTROMAJ/$TARGET_ARCH/$rpm" ]] ||
556 # let the download_file handle the concurrency
558 # get the location from a distro specific method if it exists
559 if type -p kernel_debuginfo_location; then
560 location=$(kernel_debuginfo_location)
562 echo "Downloading $location/$rpm"
564 "$location/$rpm" "$KERNELRPMSBASE/$lnxmaj/$DISTROMAJ/$TARGET_ARCH/$rpm" "$force" 2>&1 ||
565 [ ! -s "$KERNELRPMSBASE/$lnxmaj/$DISTROMAJ/$TARGET_ARCH/$rpm" ]; then
566 rm -f $KERNELRPMSBASE/$lnxmaj/$DISTROMAJ/$TARGET_ARCH/$rpm
567 fatal 1 "Could not download $rpm from $location."
577 local file=${from##*/}
583 local semaphore="$to-downloading"
586 if [ ! -f $semaphore ]; then
590 # make sure the download has not been aborted
591 local now=$(date +%s)
592 local file_mtime=$(stat -c %Y "$to")
593 local staleness=$((now - file_mtime))
594 # let's assume an active download will write at least once a minute
595 if [ $staleness -gt 60 ]; then
603 # if the semaphore file exists, the file is either still downloading
604 # or a download was aborted and we cannot trust the target file
605 if [ -f $semaphore ]; then
609 if ! is_downloading && [ -r "$to" ] && [ -s "$to" ]; then
616 if $force || ! is_downloaded; then
617 if is_downloading; then
618 echo "Somebody else is downloading $from..."
619 while is_downloading; do
620 echo "Waiting for $to to finish downloading"
623 if is_downloaded; then
626 echo "The download we were waiting for seems to have been aborted"
632 echo "Downloading $from..."
633 # flag others so they don't try to download also
634 push_exit_trap "rm -f $to $semaphore" "download"
636 if ! fetch_url "$from" "$to" || [ ! -s "$to" ]; then
637 # the trap will remove the files via the fatal below
638 fatal 1 "Could not download ${to##*/} from ${from%/*}/."
641 delete_exit_trap "download"
643 fatal 1 "${to##*/} not found in directory ${to%/*}."
653 local ofed_version="$2"
654 local force="${3:-false}"
655 local distro_name="${DISTRO}"
656 local arch="${TARGET_ARCH}"
660 #if a src tarball has been given in the command line, we use it
661 #The format of the tarball must be OFED-${OFED_VERSION}.tgz
662 [ -n "${OFED_SRC}" ] && return 0
666 location="https://www.openfabrics.org/downloads/OFED/ofed-${ofed_version}/"
668 if [[ $ofed_version = *-[rR][cC][0-9] ]]; then
669 ofed_version_loc=${ofed_version%%-[rR][cC][0-9]}
670 location="https://www.openfabrics.org/downloads/OFED/ofed-${ofed_version_loc}/"
673 if [[ $ofed_version = *-daily ]]; then
674 ofed_version=${ofed_version/-daily/}
675 location="https://www.openfabrics.org/downloads/OFED/ofed-${ofed_version}-daily/"
676 # find the filename for latest version
677 ofed_version=$(curl -1 -s "$location" | sed -nre "s/.*href=\"OFED-(${ofed_version//./\\.}-[0-9]{8}-[0-9]{4}).tgz.*$/\1/p" | tail -1)
678 if [ -z "$ofed_version" ]; then
679 fatal 1 "Could not determine the filename of the OFED snapshot from daily "
683 file="OFED-${ofed_version}.tgz"
684 download_file "$location/$file" "$KERNELTREE" "$force"
687 location="http://www.mellanox.com/downloads/ofed/MLNX_OFED-${ofed_version}"
688 # this is a work around for suse distro (sles11.3). what we need is
689 # sles11sp3. We really need to redesign how we use target and distro
690 [[ $distro_name =~ sles ]] && distro_name=${DISTRO/./sp}
691 if [[ $arch = "aarch64" ]] && [[ $DISTROMAJ < "rhel8" ]]; then
692 file="MLNX_OFED_LINUX-${ofed_version}-${distro_name}alternate-${arch}.tgz"
694 file="MLNX_OFED_LINUX-${ofed_version}-${distro_name}-${arch}.tgz"
696 download_file "$location/$file" "$KERNELTREE" "$force"
699 location="http://downloadmirror.intel.com/24625/eng/"
700 file="IntelIB-Basic.$(echo ${distro_name%%.*} | tr '[:lower:]' '[:upper:]')-${arch}.${ofed_version}.tgz"
701 download_file "$location/$file" "$KERNELTREE" "$force"
704 fatal 1 "Error: unknown OFED type: $ofed_type"
707 # version might change due to detect daily version
708 OFED_VERSION=${ofed_version}
714 EXTRA_VERSION_save="$EXTRA_VERSION"
715 for patchesdir in "$EXTERNAL_PATCHES" \
716 "$TOPDIR/lustre/lustre/kernel_patches"; do
717 TARGET_FILE="$patchesdir/targets/$TARGET.target"
718 [ -r "$TARGET_FILE" ] && break
720 [ -r "$TARGET_FILE" ] || fatal 1 "Target $TARGET was not found."
722 echo "Loading target config file $TARGET.target..."
724 # if the caller specified an OFED_VERSION it should override whatever
725 # the target file specifies
726 local env_OFED_VERSION="$OFED_VERSION"
731 # patched kernel build needs a series patches
732 if ! $PATCHLESS && ! $PATCHLESS_SERVER && [ ! "$SERIES" ]; then
733 fatal 1 "Distro $DISTRO doesn't support patched kernel server build!! Please use option --patchless-server"
736 if [ -n "$env_OFED_VERSION" ]; then
737 OFED_VERSION="$env_OFED_VERSION"
740 # doesn't make any sense to build OFED for xen domX's
745 # XXX - set_rpm_smp_type is an ugly undeterministic hack. it needs to
746 # go away and the target just specify the $RPMSMPTYPE
747 [ -z "$RPMSMPTYPE" ] && set_rpm_smp_type
749 # CC might have been overwritten in TARGET_FILE
750 if [[ $CC != ccache\ * ]] && which "$CCACHE" &>/dev/null; then
751 export CCACHE && export CC="ccache $CC"
754 if [ ! "$KERNELTREE" = "" ] && [ -d "$KERNELTREE" ]; then
755 KERNELDIR="$KERNELTREE/${lnxmaj}"
756 [ -d "$KERNELDIR" ] || mkdir "$KERNELDIR"
759 # verify the series is available
760 if [ "$SERIES" ]; then
761 for series in $SERIES; do
762 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
763 [ -r "$patchesdir/series/$series" ] && continue 2
765 fatal 1 "Target $TARGET's series $SERIES could not be found.\nSearched:\n\t$EXTERNAL_PATCHES/series\n\t$TOPDIR/lustre/lustre/kernel_patches/series."
769 # set the location of the .config file
775 if $ENABLE_KERNEL_DEBUG; then
776 if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config-debug ]; then
777 CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET$XENPOSTFIX-$TARGET_ARCH.config-debug"
780 if [ -f $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET-$TARGET_ARCH.config ]; then
781 CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/kernel-$lnxmaj-$TARGET$XENPOSTFIX-$TARGET_ARCH.config"
785 local lnxrelnew=${lnxrel//-/_}
787 # remember the EXTRA_VERSION before we diddle it here
788 # XXX - we really should not diddle with any values read in from the
789 # target file. if we want to modify a value, we should create
791 PRISTINE_EXTRA_VERSION=$EXTRA_VERSION
793 if ! $PATCHLESS && ! $PATCHLESS_SERVER && [ ! -f "$CONFIG_FILE" ]; then
794 fatal 1 "Config file for target $TARGET missing from $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
797 if [ "$EXTRA_VERSION_save" ]; then
798 EXTRA_VERSION="$EXTRA_VERSION_save"
799 elif ! $RELEASE; then
800 # if there is no patch series, then this is not a lustre specific
801 # kernel. don't make it look like one
802 if $PATCHLESS || [ -n "$SERIES" ]; then
803 EXTRA_VERSION=$(echo $EXTRA_VERSION | sed -e "s/\(.*_lustre\)\..*/\1/")
806 # EXTRA_VERSION=${EXTRA_VERSION//-/_}
812 echo -n '--wildcards '
815 fatal 1 "tarflags(): File name argument missing."
827 fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
836 local extractfile="$@"
838 echo "Untarring ${tarfile##*/}..."
839 tar $(tarflags "$tarfile") "$tarfile" $extractfile
845 local ofed_version="$2"
846 local distro_name="${DISTRO}"
847 local arch="${TARGET_ARCH}"
850 #if a src tarball has been given in the command line, we use it
851 #The format of the directory after untar MUST be in OFED-${version}
852 #even if it's from MLNX or IFS...or whatever
853 if [ -n "${OFED_SRC}" ]; then
854 if ! untar "$KERNELTREE/${OFED_SRC}"; then
857 [ -d OFED ] || ln -sf OFED-[0-9].[0-9]* OFED
862 file="OFED-${ofed_version}"
863 if ! untar "$KERNELTREE/${file}.tgz"; then
866 [ -d OFED ] || ln -sf OFED-[0-9].[0-9]* OFED
869 # this is a work around for suse distro (sles11.3). what we need is
870 # sles11sp3. We really need to redesign how we use target and distro
871 [[ $distro_name =~ sles ]] && distro_name=${DISTRO/./sp}
872 if [[ $arch = "aarch64" ]] && [[ $DISTROMAJ < "rhel8" ]]; then
873 file="MLNX_OFED_LINUX-${ofed_version}-${distro_name}alternate-${arch}"
875 file="MLNX_OFED_LINUX-${ofed_version}-${distro_name}-${arch}"
877 # it's not important what distro we get the tarball since we only
878 # interest in the src
879 if ! untar "$KERNELTREE/${file}.tgz"; then
882 # we need to untar again to get the src since it's being
883 # wrapped inside the tarball
884 # There are cases where the source version is different
886 # (ie. MLNX_OFED_LINUX-2.3-1.0.1 but MLNX_OFED_SRC-2.3-1.0.0)
887 local src=$(ls ${file}/src/MLNX_OFED_SRC-${ofed_version%.*}*.tgz)
888 if ! untar "$src"; then
891 [ -d OFED ] || ln -sf MLNX_OFED_SRC-[0-9]*.[0-9]* OFED
892 if compare_version $ofed_version 4.7 ||
893 compare_version 5.1 $ofed_version; then
894 [ -d OFED_RPMS ] || ln -sf ${file}/RPMS OFED_RPMS
896 [ -d OFED_RPMS ] || ln -sf ${file}/RPMS/MLNX_LIBS OFED_RPMS
900 file="IntelIB-Basic.$(echo ${distro_name%%.*} | tr '[:lower:]' '[:upper:]')-${arch}.${ofed_version}"
901 if ! untar "$KERNELTREE/${file}.tgz"; then
904 [ -d OFED ] || ln -sf $file/IntelIB-OFED.$(echo ${distro_name%%.*} | tr '[:lower:]' '[:upper:]')-${arch}.* OFED
905 ofed_version="$(cat OFED/Version)"
908 # version might change due to detect daily version
909 OFED_VERSION=${ofed_version}
914 untar "$LUSTRE" || fatal 1 "Error unpacking Lustre tarball"
915 [ -d lustre ] || ln -sf lustre-[0-9].[0-9]* lustre
921 local do_patch=${1:-true}
923 FULL_PATCH="$PWD/lustre-kernel-${TARGET}-${EXTRA_VERSION}.patch"
924 [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
925 $do_patch && pushd linux >/dev/null
926 for series in $SERIES; do
927 echo -n "Applying series $series:"
928 for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches"; do
929 [ -r "$patchesdir/series/$series" ] || continue
930 SERIES_FILE="$patchesdir/series/$series"
931 for patch in $(<"$SERIES_FILE"); do
933 PATCH_FILE="$patchesdir/patches/$patch"
934 [ -r "$PATCH_FILE" ] || \
935 fatal 1 "Patch $patch does not exist in Lustre tree."
936 cat "$PATCH_FILE" >> "$FULL_PATCH" || {
938 fatal 1 "Error adding patch $patch to full patch."
941 patch -s -p1 < "$PATCH_FILE" 2>&1 || {
943 fatal 1 "Error applying patch $patch."
951 $do_patch && popd >/dev/null
952 echo "Full patch has been saved in ${FULL_PATCH##*/}."
959 local configure_args=""
963 pushd lustre >/dev/null
965 if ! build_lustre_dkms; then
966 popd >/dev/null # pushd lustre
970 echo "Building Lustre RPMs for: $TARGET_ARCH"
972 # If server we now build the spl and zfs modules against the lustre kernel.
973 # These are required prior to the building of lustre server. Client does
974 # not require spl/zfs. Use !PATCHLESS to indicate server which follows the
975 # line above so is at least consistant.
976 if [ $PATCHLESS == false ] && [ "x$WITH_ZFS" == "x" ]; then
977 if ! build_spl_zfs; then
978 popd >/dev/null # pushd lustre
984 configure_args="$configure_args --disable-server"
987 # ditto for the lustre-tests boolean
988 if ! $LUSTRE_TESTS; then
989 configure_args="$configure_args --disable-tests"
993 configure_args="$configure_args --disable-iokit"
996 if ! $OSDZFSRPM; then
997 configure_args="$configure_args --without-zfs"
1000 if ! $OSDLDISKFSRPM; then
1001 configure_args="$configure_args --disable-ldiskfs"
1004 configure_args="$configure_args --with-linux=$linux"
1005 configure_args="$configure_args ${linuxobj:+--with-linux-obj=$linuxobj}"
1007 # allow environment setting to override ldiskfs series selection
1008 [ -n "$LDISKFS_SERIES" ] && export LDISKFS_SERIES
1010 ./configure $configure_args $CONFIGURE_FLAGS 2>&1 ||
1011 fatal 1 "Error in configure."
1013 if type -p apply_kmod_requires_conflicts; then
1014 apply_kmod_requires_conflicts
1018 fatal 1 "Error building rpms for $TARGET_ARCH."
1020 # move RPMs into place where they are expected to be
1021 mv -f *lustre*.${TARGET_ARCH}.rpm $TOPDIR/RPMS/${TARGET_ARCH}/
1022 mv -f lustre-*.src.rpm $TOPDIR/SRPMS/
1025 if type -p cleanup_rpmmacros; then
1032 build_lustre_dkms() {
1034 local ver=$(sed -n -e 's/^LUSTRE_VERSION = //p' LUSTRE-VERSION-FILE)
1036 echo "Building Lustre DKMS RPMs for: $TARGET_ARCH"
1037 ./configure --enable-dist || fatal 1 "Error in DKMS configure."
1040 build_args="--without servers"
1043 rpmbuild --define "_topdir $TOPDIR" $build_args -bs lustre-dkms.spec ||
1044 fatal 1 "Error building DKMS .src.rpm for $TARGET_ARCH."
1047 rpmbuild --define "_topdir $TOPDIR" $build_args \
1048 --rebuild $TOPDIR/SRPMS/lustre-client-dkms-$ver-*.src.rpm ||
1049 fatal 1 "Error building DKMS .rpm for $TARGET_ARCH."
1051 rpmbuild --define="_topdir $TOPDIR" --with servers \
1052 --with zfs --without ldiskfs -bs lustre-dkms.spec ||
1053 fatal 1 "Error creating DKMS (zfs) .srpm for $TARGET_ARCH."
1054 rpmbuild --define="_topdir $TOPDIR" --with servers \
1055 --without zfs --with ldiskfs -bs lustre-dkms.spec ||
1056 fatal 1 "Error creating DKMS (ldiskfs) .srpm for $TARGET_ARCH."
1057 rpmbuild --define="_topdir $TOPDIR" --with servers \
1058 --with zfs --with ldiskfs -bs lustre-dkms.spec ||
1059 fatal 1 "Error creating DKMS (all) .srpm for $TARGET_ARCH."
1061 rpmbuild --rebuild --define="_topdir $TOPDIR" --with servers \
1062 --with zfs --without ldiskfs $TOPDIR/SRPMS/lustre-zfs-dkms-$ver-*.src.rpm ||
1063 fatal 1 "Error building DKMS (zfs) .rpm for $TARGET_ARCH."
1064 rpmbuild --rebuild --define="_topdir $TOPDIR" --with servers \
1065 --without zfs --with ldiskfs $TOPDIR/SRPMS/lustre-ldiskfs-dkms-$ver-*.src.rpm ||
1066 fatal 1 "Error building DKMS (ldiskfs) .rpm for $TARGET_ARCH."
1067 rpmbuild --rebuild --define="_topdir $TOPDIR" --with servers \
1068 --with zfs --with ldiskfs $TOPDIR/SRPMS/lustre-all-dkms-$ver-*.src.rpm ||
1069 fatal 1 "Error building DKMS (all) .rpm for $TARGET_ARCH."
1078 # Fetch spl/zfs from the git repo and prepare for lustre build
1081 # SPLZFSGITREPO - URI of directory where spl.git and zfs.git are located
1082 # SPLZFSTAG - Tag to checkout of clone repositories
1083 # SPLZFSVER - Version to checkout of both (format zfs/spl-$SPLZFSVER)
1085 # return 0 if successful, else 255
1087 # make sure the RPM build environment is set up
1089 create_rpmbuild_dirs
1092 # The spl/zfs spec files expect RPM_BUILD_ROOT to point to the root of the
1093 # destination for the rpms
1094 export RPM_BUILD_ROOT=$TOPDIR
1095 SPLZFSVER=${SPLZFSVER:-2.1.15}
1096 SPLZFSTAG=${SPLZFSTAG:-}
1097 # "spl zfs" prior to 0.8.0
1098 # "zfs" for 0.8.0 and later
1099 (( $(version_code $SPLZFSVER) < $(version_code 0.8.0) )) &&
1100 SPLZFSPKGS="spl zfs" || SPLZFSPKGS="zfs"
1102 # The files expect a kver to be set to the kernel version .
1103 local kver=$(find_linux_release)
1105 # build and install the spl and zfs (and -devel) RPMs for lustre to use
1108 for pkg in $SPLZFSPKGS; do
1112 # need to fetch the repo in order to build it.
1113 # default to github but allow override
1114 git clone -n ${SPLZFSGITREPO:-"https://github.com/zfsonlinux"}/$pkg.git $pkg 2>&1
1116 pushd $pkg || return 255
1118 if [ -n "$SPLZFSTAG" ]; then
1123 git checkout -b lbuild $tag || fatal 1 "Failed to checkout \"$tag\" for $pkg.git"
1125 # This differentiates between older zfs versions
1126 if [ -f $pkg-modules.spec.in ]; then
1129 speclist="$pkg.spec $rpmpkg.spec"
1131 rpmpkg=kmod-$pkg-devel
1132 if [[ $DISTROMAJ > "rhel8" ]]; then
1137 speclist="$pkg.spec $pkg-kmod.spec $pkg-dkms.spec"
1140 bash autogen.sh || return 255
1142 if ! ./configure --with-linux=${LINUX} --with-linux-obj=${LINUXOBJ:-$LINUX} \
1143 ${spldir:+--with-spl="${spldir}"} 2>&1 ||
1144 ! make dist 2>&1; then
1150 ln -f $pkg/$pkg-*.tar.gz $TOPDIR/SOURCES ||
1151 error "failed to link $pkg/$pkg-*.tar.gz into $TOPDIR/SOURCES"
1152 if [ -f $pkg/scripts/kmodtool ]; then
1153 ln -f $pkg/scripts/kmodtool $TOPDIR/SOURCES/
1163 # set search dir for our own kmodtool to find correct
1165 export KERNELSOURCE=$(dirname ${LINUX})
1166 # Manually build rpms
1167 for spec in $speclist; do
1168 echo "Building RPMs from $pkg/$specdir/$spec"
1169 if ! rpmbuild $rpmb $pkg/$specdir/$spec \
1171 --define "_use_internal_dependency_generator 0" \
1172 --define "require_kdir ${LINUX}" \
1173 ${LINUXOBJ:+--define "require_kobj ${LINUXOBJ}"} \
1174 ${spldir:+--define "require_spldir ${spldir}"} \
1175 --define "kver $kver" \
1176 --define "kernels $kver" \
1177 --define "_tmppath /var/tmp" \
1178 --define "kernelbuildroot $TOPDIR/reused" \
1179 --define "_topdir $TOPDIR" 2>&1; then
1184 # We have built the rpms for the package. Now we need to extract the
1185 # contained files so we can build further things against them
1186 local rpms=$(ls -1 $TOPDIR/RPMS/*/$rpmpkg-*.rpm)
1188 # cpio only extract to pwd so we need to go there.
1191 for rpm in $rpms; do
1192 rpm2cpio $rpm | cpio -id
1195 if [ "$pkg" == "zfs" ]; then
1196 # We also need to extract both the zfs and zfs-devel rpms
1197 # the zfs rpm is needed because it has the actual libraries in
1198 # it and the zfs-devel rpm only has unversioned symlinks to the
1199 # libraries in the zfs rpm
1200 # this will all change one day when we have a libzfs rpm per
1201 # https://github.com/zfsonlinux/zfs/issues/2329
1202 # and it looks like it could be one day soon:
1203 # https://github.com/zfsonlinux/zfs/pull/2341
1204 local devel_rpms=$(ls -1 $TOPDIR/RPMS/*/{$pkg-devel,$pkg-$SPLZFSVER,lib*}-*.rpm)
1205 for rpm in $devel_rpms; do
1206 rpm2cpio $rpm | cpio -id
1208 CONFIGURE_FLAGS="--with-$pkg-devel=$TOPDIR ${CONFIGURE_FLAGS}"
1209 if [ -z "$spldir" ]; then
1210 # if spldir is empty, then we are only building ZFS and need to define SPL config flags
1211 CONFIGURE_FLAGS="--with-spl=$(ls -d $TOPDIR/usr/src/spl-*|tail -1) ${CONFIGURE_FLAGS}"
1212 CONFIGURE_FLAGS="--with-spl-obj=$(ls -d $TOPDIR/usr/src/$pkg-*/$kver*|tail -1) ${CONFIGURE_FLAGS}"
1214 elif [ "$pkg" == "spl" ]; then
1215 spldir="$(ls -d $TOPDIR/usr/src/spl-*|tail -1)"
1219 CONFIGURE_FLAGS="--with-$pkg=$(ls -d $TOPDIR/usr/src/$pkg-*|tail -1) ${CONFIGURE_FLAGS}"
1220 CONFIGURE_FLAGS="--with-$pkg-obj=$(ls -d $TOPDIR/usr/src/$pkg-*/$kver*|tail -1) ${CONFIGURE_FLAGS}"
1230 [ "$STAGEDIR" ] || return 0
1232 rpmdir="${STAGEDIR}/${CANONICAL_TARGET}-${TARGET_ARCH}"
1233 echo "${0##*/}: Copying RPMs into ${rpmdir}"
1234 mkdir -p "${rpmdir}"
1235 for rpm in $(ls RPMS/${TARGET_ARCH}/*.rpm RPMS/noarch/*.rpm); do
1236 cp -v $rpm "${rpmdir}"
1239 cp -v "$LUSTRE" "$STAGEDIR"
1243 set_rpm_smp_type() {
1245 local infact_arch="${TARGET_ARCH}"
1248 [ "$infact_arch" == "i586" ] && infact_arch="i686"
1251 for smp_type in $SMP_ARCHS; do
1252 [ $infact_arch == $smp_type ] && RPMSMPTYPE=smp && break
1255 for smp_type in $BIGSMP_ARCHS; do
1256 [ $infact_arch == $smp_type ] && RPMSMPTYPE=bigsmp && break
1259 for smp_type in $PPC64_ARCHS; do
1260 [ $infact_arch == $smp_type ] && RPMSMPTYPE=ppc64 && break
1263 for smp_type in $DEFAULT_ARCHS; do
1264 [ $infact_arch == $smp_type ] && RPMSMPTYPE=default && break
1269 # This function takes a linux include tree and digs out the linux release
1270 # from it. It is never called directly, only called from the distro
1271 # specific function find_linux_release() in lbuild-{rhel,sles}.
1272 _find_linux_release() {
1274 local LINUXRELEASEHEADER=""
1276 LINUXRELEASEHEADER=$SRC/include/linux/version.h
1277 if [ -s $SRC/include/generated/utsrelease.h ]; then
1278 LINUXRELEASEHEADER=$SRC/include/generated/utsrelease.h
1279 elif [ -s $SRC/include/linux/utsrelease.h ]; then
1280 LINUXRELEASEHEADER=$SRC/include/linux/utsrelease.h
1283 if [ ! -s $LINUXRELEASEHEADER ]; then
1284 fatal 1 "could not find UTS_RELEASE"
1287 sed -ne 's/#define UTS_RELEASE "\(.*\)"$/\1/p' $LINUXRELEASEHEADER
1290 # unpack kernel(/source/devel) RPM
1292 unpack_linux_devel_rpm() {
1293 local kernelrpm="${1}"
1295 [ -f "$kernelrpm" ] || return 255
1296 [ -d $TOPDIR/reused ] || mkdir $TOPDIR/reused || return 255
1298 pushd $TOPDIR/reused &>/dev/null || return 255
1300 if ! rpm2cpio < "$kernelrpm" | cpio -id > /dev/null 2>&1; then
1304 # call a distro specific hook, if available
1305 if type -p unpack_linux_devel_rpm-$DISTROMAJ; then
1306 if ! unpack_linux_devel_rpm-$DISTROMAJ "$kernelrpm"; then
1313 find_linux_devel_paths $TOPDIR/reused
1321 local kib_prefix="$2"
1323 local ofed_type="${4}"
1324 local ofed_version="${5}"
1326 # build kernel-ib{,-devel}/compat-rdma{,-devel}
1329 local OFED_CORE="--with-core-mod --with-ipoib-mod --with-user_mad-mod \
1330 --with-user_access-mod --with-addr_trans-mod --with-innova-flex "
1331 local OFED_HARDWARE="--with-mlx4-mod --with-mlx4_en-mod \
1332 --with-srp-mod --with-iser-mod --with-isert-mod --with-mlx5-mod \
1335 # some I/B drivers are architecture dependent and kernel-ib's configure
1336 # does not figure it out for us ~sigh~
1337 case "$TARGET_ARCH" in
1339 OFED_HARDWARE="$OFED_HARDWARE --with-ehca-mod"
1343 # assume we are just rebuilding the SRPM
1344 local BUILD_TYPE=${BUILD_TYPE:-"--rebuild"}
1345 local SOURCE="${TOPDIR}/OFED/SRPMS/${kib_prefix}-*.src.rpm"
1347 # but switch to building from the SPEC if we need to apply patches
1348 if ls ${TOPDIR}/lustre/contrib/patches/ofed/* >/dev/null; then
1350 rpm --define "_topdir ${TOPDIR}" -ivh $SOURCE
1351 SOURCE="${TOPDIR}/SPECS/${kib_prefix}.spec"
1352 local file ed_fragment1 ed_fragment2 n=1
1353 for file in $(ls ${TOPDIR}/lustre/contrib/patches/ofed/*.patch 2>/dev/null); do
1354 ed_fragment1="$ed_fragment1
1355 Patch$n: ${file%%*/}"
1356 ed_fragment2="$ed_fragment2
1358 cp $file ${TOPDIR}/SOURCES
1361 for file in $(ls ${TOPDIR}/lustre/contrib/patches/ofed/*.ed 2>/dev/null); do
1362 # Only apply the ed-scripts that should be used for the canonical target
1363 # ed-files in ${TOPDIR}/lustre/contrib/patches/ofed/ have to follow the naming
1365 # <two-digits>-<descriptive-name>:<canonical_target_1>: ...:<canonical_target_N>.ed
1366 # To apply the same change to multiple canonical target simply specify
1367 # a list of colon separated canoncial target names in the file name.
1368 echo "$file" | grep -q -e ":${CANONICAL_TARGET}:" \
1369 -e ":${CANONICAL_TARGET}.ed$"
1370 if [ $? -eq 0 ] ; then
1371 ed_fragment3="$ed_fragment3
1377 if [ $n -gt 1 ]; then
1391 local linuxrelease=$(find_linux_release)
1392 # a place to change/add any unique config
1394 ofa|ifs) local K_SRC_OBJ="K_SRC_OBJ"
1395 if ! $RPMBUILD $BUILD_TYPE --define 'build_kernel_ib 1' \
1396 --define 'build_kernel_ib_devel 1' \
1397 ${FIND_REQUIRES:+--define "__find_requires $FIND_REQUIRES"} \
1398 ${FIND_KSYMS_REQUIRES:+--define "__required_ksyms_requires $FIND_KSYMS_REQUIRES"} \
1399 --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
1400 --define "KVERSION ${linuxrelease}" \
1401 --define "$K_SRC ${linux}" \
1402 ${K_SRC_OBJ:+--define "$K_SRC_OBJ ${linux}"} \
1403 ${OFA_KERNEL_RELEASE:+--define "_release $OFA_KERNEL_RELEASE"} \
1404 --define "configure_options --without-quilt $OFED_CORE $OFED_HARDWARE $OFED_ISCSI" \
1405 ${SOURCE} 2>&1; then
1406 fatal 1 "Error building ${kib_rpm}"
1410 if ! $RPMBUILD $BUILD_TYPE \
1411 ${FIND_REQUIRES:+--define "__find_requires $FIND_REQUIRES"} \
1412 ${FIND_KSYMS_REQUIRES:+--define "__required_ksyms_requires $FIND_KSYMS_REQUIRES"} \
1413 ${MOFED_FLAVOR:+--define "flavors_to_build $MOFED_FLAVOR"} \
1414 --define "_topdir ${TOPDIR}" --target ${TARGET_ARCH} \
1415 --define "KVERSION ${linuxrelease}" \
1417 --define "$K_SRC ${linux}" \
1418 ${OFA_KERNEL_RELEASE:+--define "_release $OFA_KERNEL_RELEASE"} \
1419 ${SOURCE} 2>&1; then
1420 fatal 1 "Error building ${kib_rpm}"
1422 # now that we have the kernel rpms, we need to lib rpms too
1423 # we don't have to rebuild since MOFED include the binaries
1424 # Starting from MOFED 5.1, rdma-core is required for libib*
1425 if compare_version 5.1 $ofed_version; then
1426 cp -f OFED_RPMS/rdma-core-*.${TARGET_ARCH}.rpm \
1427 ${TOPDIR}/RPMS/${TARGET_ARCH} || \
1428 fatal 1 "Failed to copy MOFED rpms"
1430 cp -f OFED_RPMS/{libib*,librdmacm*,ibutils*,opensm-*,infiniband-diags*}.${TARGET_ARCH}.rpm \
1431 ${TOPDIR}/RPMS/${TARGET_ARCH} || \
1432 fatal 1 "Failed to copy MOFED rpms"
1442 local signature="$4"
1443 local use_links="$5"
1450 local unique_id=$(hostname -s)
1451 if [ -z "$unique_id" ]; then
1452 fatal 1 "Failed to determine hostname."
1455 local finallocation="$location"/"$signature"/"$module"
1456 location="$location"/"$signature-${unique_id}"/"$module"
1457 mkdir -p "$location"
1458 # the cleanup script removes any directory that doesn't have a
1459 # .lastused, so let's try to prevent that as soon as we can
1460 # this solution still slightly racy with the cleanup script
1461 # but the race is a lot tighter now
1462 touch -t 197001010000 "$location/.lastused"
1463 ## use eval/echo here to make sure shell expansions are performed
1464 #if ! cp -a${linkflag} $(eval echo $articles) "$location"; then
1466 for article in $(eval echo $articles); do
1467 if ! cp -a${linkflag} "$article" "$location"; then
1468 error "Failed to copy \"$article\" to \"$location\" in store_for_reuse()"
1469 # rename the cache location so that it's not cached
1470 # product, but is around for analysis
1471 mv "$location"{,-bad-$(date +%s)} ||
1472 error "failed to clean up a failed cache attempt" \
1473 "in \"$location\" -- manual cleanup will be" \
1479 # flag the cache as complete (i.e. in case lbuild was previously
1480 # interrupted while caching)
1481 touch "$location/.lastused"
1483 # put the temporary location into the final location
1485 mkdir -p "${finallocation%/*}"
1486 mv "$location" "$finallocation"
1487 rmdir "${location%/*}"
1495 local use_links="${3:-false}"
1496 local signature="$4"
1498 if [ -n "$REUSEBUILD" ] && [ -d "$REUSEBUILD/$signature/$module" ]; then
1499 if [ ! -f "$REUSEBUILD/$signature/$module/.lastused" ]; then
1500 # the .lastused flag is populated at the end of the caching to
1501 # signal that the caching was completed. if that flag is not
1502 # there, then the cache is invalid (and should be removed in fact)
1503 mv "$REUSEBUILD/$signature/$module"{,-bad-$(date +%s)} ||
1504 fatal 1 "failed to clean up a bad cache in location $REUSEBUILD/$signature/$module\" -- manual cleanup will be necessary"
1508 # so that we know how stale this entry is
1509 touch $REUSEBUILD/$signature/$module/.lastused
1512 if ls $REUSEBUILD/$signature/$module/* >/dev/null 2>&1; then
1513 cp -al $REUSEBUILD/$signature/$module/* $dest/
1516 # copying is pretty heavy
1517 # cp -a $REUSEBUILD/$signature/$module/* $dest/
1518 # do some creative symlinking instead
1520 for dir in BUILD SRPMS SPECS; do
1521 if ls $REUSEBUILD/$signature/$module/$dir/* >/dev/null 2>&1; then
1522 ln -s $REUSEBUILD/$signature/$module/$dir/* $dest/$dir
1525 # sources have to be copied by file because we need SOURCES to
1526 # be a dir we can write into
1527 # could overrun ls's arg list here
1528 #ls $REUSEBUILD/$signature/$module/SOURCES/* |
1529 find $REUSEBUILD/$signature/$module/SOURCES/ -type f |
1530 xargs ln -t $dest/SOURCES -s
1532 # same for RPMS/* dirs
1533 # could overrun ls's arg list here
1534 #ls $REUSEBUILD/$signature/$module/RPMS/$TARGET_ARCH/* |
1536 for dir in $REUSEBUILD/$signature/$module/RPMS/*; do
1537 mkdir -p $dest/RPMS/${dir##*/}
1539 xargs ln -t $dest/RPMS/${dir##*/} -s
1551 if [[ $arch = i[3456]86 ]]; then
1553 elif [[ $arch = aarch64 ]]; then
1561 build_kernel_with_srpm() {
1564 if [ -z "$outfd" ] || [ $outfd = 1 ]; then
1565 fatal 1 "You must supply a file descriptor to ${FUNCNAME[0]} and it cannot be 1"
1568 # need to generate the patch for this target
1569 do_patch_linux false >&${outfd} # sets global $FULL_PATCH (yeah, yuck)
1571 # get an md5sum of the kernel patch + config for reuse check
1574 local release_str="RELEASE=$RELEASE\n"
1577 if $USE_BUILD_CACHE && [ -n "$REUSEBUILD" ]; then
1578 local REUSE_SIGNATURE=$({ echo -en $release_str;
1581 cat "$TARGET_FILE" |
1582 sed -e '/_VERSION=/s/_[0-9]*_g.*$//g';
1584 cat "$LBUILD_DIR/lbuild";
1585 test -f lbuild-${DISTROMAJ%%[0-9]*} &&
1586 cat lbuild-${DISTROMAJ%%[0-9]*};
1587 cat "$LBUILD_DIR/lbuild-$DISTROMAJ"; } |
1588 md5sum | cut -d" " -f1)
1589 # see if we can link to the reuse pool
1590 # XXX - hrm. i'm not convinced this doesn't belong in the reuse
1592 local CAN_LINK_FOR_REUSE=false
1593 touch $REUSEBUILD/$$
1594 if cp -al $REUSEBUILD/$$ $TOPDIR/ 2>/dev/null; then
1595 CAN_LINK_FOR_REUSE=true
1600 # the extra version string to use for the kernel (which might be a reused
1602 local kernel_extra_version=""
1603 if ! $USE_BUILD_CACHE || ! reuse kernel "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1604 "$REUSE_SIGNATURE"; then
1605 # nothing cached, build from scratch
1606 echo "Downloading kernel SRPM" >&${outfd}
1607 download_srpm "$CANONICAL_TARGET" "$KERNEL_SRPM" >&${outfd}
1609 if ! rpm -ivh $KERNELDIR/$KERNEL_SRPM \
1610 --define "_topdir $TOPDIR" >&${outfd} 2>&1; then
1611 # should we clean this up or leave it for analysis?
1613 fatal 1 "Error installing kernel SRPM."
1616 # put the Lustre kernel patch into the RPM build tree
1617 cp $FULL_PATCH $TOPDIR/SOURCES/linux-${lnxmaj}-lustre.patch
1618 prepare_and_build_srpm >&${outfd} ||
1619 fatal 1 "failed to prepare_and_build_srpm"
1621 if [ -z "$REUSE_SIGNATURE" ]; then
1622 echo "No reuse signature was caculated so not storing the built kernel" >&${outfd}
1624 # store the resulting kernel RPM build tree for future use
1625 echo "Storing the built kernel for future reuse" >&${outfd}
1626 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,SRPMS,RPMS}" \
1627 "kernel" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1628 "$CAN_LINK_FOR_REUSE"; then
1629 error "Failed to store kernel RPMS for reuse"
1630 echo "unknown" >&${outfd}
1636 # figure out the EXTRA_VERSION of the kernel we built or are re-using
1638 if ! KERNEL_RPM=$(find_rpm "$TOPDIR/RPMS/$TARGET_ARCH/" provides "^kernel(-default)? ="); then
1639 fatal 1 "Failed to find a kernel RPM in $TOPDIR/RPMS/$TARGET_ARCH/"
1641 kernel_extra_version=$(rpm -q --queryformat "%{RELEASE}" -p $TOPDIR/RPMS/$TARGET_ARCH/$KERNEL_RPM)
1643 # should now have the following RPMs
1644 # $TOPDIR/RPMS/$arch/kernel-lustre-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1645 # $TOPDIR/RPMS/$arch/kernel-lustre-devel-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1646 # $TOPDIR/RPMS/$arch/kernel-lustre-headers-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1647 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-common-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1648 # $TOPDIR/RPMS/$arch/kernel-lustre-debuginfo-2.6.18-53.1.21.el5_lustre.1.6.5.1.$arch.rpm
1650 echo $kernel_extra_version
1658 # REUSEBUILD, USE_BUILD_CACHE
1663 local ofed_type="$2"
1664 local ofed_version="$3"
1671 if [ "$ofed_version" = "inkernel" ]; then
1672 # see if there is a distro specific override for this and use
1674 # XXX we need to better integrate a distro specific override with
1675 # the rest of this function so that all of the reuse cache
1676 # stuff is leveraged given that 80% of this function is reuse
1677 if type -p build_ofed-$DISTROMAJ; then
1679 ofed_location=$(build_ofed-$DISTROMAJ ${STDOUT})
1680 local rc=${PIPESTATUS[0]}
1681 CONFIGURE_FLAGS="--with-o2ib=${ofed_location} ${CONFIGURE_FLAGS}"
1688 mlnx) # no compat-rdma for mlnx as of 3.1
1689 kib_prefix="ofa_kernel"
1691 kib_rpm="${pre_prefix}${kib_prefix}"
1694 if compare_version $ofed_version 3.0; then
1695 kib_prefix="ofa_kernel"
1696 kib_rpm="${pre_prefix}${kib_prefix}"
1698 kib_prefix="compat-rdma"
1699 kib_rpm="compat-rdma"
1705 # build kernel-ib/compat-rdma
1706 if $USE_BUILD_CACHE && [ -n "$REUSEBUILD" ]; then
1707 local REUSE_SIGNATURE=$({ echo "$ofed_version";
1708 echo "$(find_linux_release;
1709 echo "$BUILD_GEN")";
1710 cat "${linux}/include/linux/autoconf.h";
1711 cat "$LBUILD_DIR/lbuild";
1712 test -f lbuild-${DISTROMAJ%%[0-9]*} &&
1713 cat lbuild-${DISTROMAJ%%[0-9]*};
1714 cat "$LBUILD_DIR/lbuild-$DISTROMAJ"; } |
1715 md5sum | cut -d" " -f1)
1716 # see if we can link to the reuse pool
1717 # XXX - hrm. i'm not convinced this doesn't belong in the reuse
1719 local CAN_LINK_FOR_REUSE=false
1720 touch $REUSEBUILD/$$
1721 if cp -al $REUSEBUILD/$$ $TOPDIR/; then
1722 CAN_LINK_FOR_REUSE=true
1727 if ! $USE_BUILD_CACHE || ! reuse ofed "$TOPDIR" "$CAN_LINK_FOR_REUSE" \
1728 "$REUSE_SIGNATURE"; then
1729 if [ -n "$REUSE_SIGNATURE" ]; then
1730 # stash away the existing built articles for a moment
1732 mv {BUILD,{S,}RPMS,S{OURCE,PEC}S} bak
1735 find . | cpio -pudlm ..
1739 create_rpmbuild_dirs
1742 build_kernel_ib "${linux}" "${pre_prefix}${kib_prefix}" "${kib_rpm}" \
1743 "${ofed_type}" "${ofed_version}"
1745 if [ -z "$REUSE_SIGNATURE" ]; then
1746 echo "No reuse signature was caculated so not storing the built ofed"
1748 # store the resulting RPM build tree for future use
1749 echo "Storing the built ofed for future reuse"
1750 if ! store_for_reuse "$TOPDIR/{SPECS,SOURCES,BUILD,SRPMS,RPMS}" \
1751 "ofed" "$REUSEBUILD" "$REUSE_SIGNATURE" \
1752 "$CAN_LINK_FOR_REUSE"; then
1753 error "Failed to store OFED RPMS for reuse"
1757 # put the stuff we stashed away back
1762 pushd "$TOPDIR" >/dev/null
1763 rm -rf ${kib_rpm}-devel
1764 mkdir ${kib_rpm}-devel
1768 mlnx) # Prior to MOFED 3.1, we had to use build_kernel_ib=1 to
1769 # build devel rpm. not so after 3.1
1770 if compare_version $ofed_version 3.0; then
1771 rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version%%-*}-*.rpm)
1773 rpm=$(ls $TOPDIR/RPMS/*/${kib_rpm}-devel-${ofed_version%%-*}-*.rpm)
1776 ofa) # Prior to OFA 3.18, we had to use build_kernel_ib=1 during configure,
1778 if compare_version $ofed_version 3.18; then
1779 rpm=$(ls $TOPDIR/RPMS/*/kernel-ib-devel-${ofed_version%%-*}-*.rpm)
1781 rpm=$(ls $TOPDIR/RPMS/*/${kib_rpm}-devel-${ofed_version%%-*}-*.rpm)
1784 ifs) # ifs doesn't follow any convention (if any)
1785 rpm=$(ls $TOPDIR/RPMS/*/${kib_rpm}-devel-*.rpm)
1788 if ! rpm2cpio < $rpm | cpio -id; then
1789 fatal 1 "could not unpack the $rpm."
1791 # find the path (this might not work for ofa and ifs)
1792 o2ib_location=$(find -H $(pwd)/usr/src/${kib_prefix} -type d -name ofed_scripts)
1793 CONFIGURE_FLAGS="--with-o2ib=$(dirname ${o2ib_location}) ${CONFIGURE_FLAGS}"
1799 local ofed_type="$1"
1800 local ofed_version="$2"
1803 if ! $PATCHLESS; then
1804 if $PATCHLESS_SERVER; then
1805 # need to find and unpack the vendor's own kernel-devel
1806 # for patchless server build
1807 if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE"); then
1808 fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in $KERNELRPMSBASE/$lnxmaj/$DISTROMAJ"
1810 if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
1811 fatal 1 "Could not find the Linux tree in $kernelrpm"
1813 # download and unpack kernel-debuginfo-common (only in EL)
1814 if [[ -n "$KERNEL_DEBUGINFO" ]]; then
1815 download_debuginfo_common "$KERNEL_DEBUGINFO"
1816 if ! lnxrel="$lnxrel" unpack_linux_devel_rpm \
1817 "$KERNELRPMSBASE/$lnxmaj/$DISTROMAJ/$TARGET_ARCH/$KERNEL_DEBUGINFO"; then
1818 fatal 1 "Could not find the Linux debuginfo common rpm in $KERNELRPMSBASE/$lnxmaj/$DISTROMAJ/$TARGET_ARCH/$KERNEL_DEBUGINFO"
1822 local kernel_extra_version
1823 if ! kernel_extra_version=$(build_kernel_with_srpm ${STDOUT}); then
1824 fatal 1 "Failed to build the kernel from it's SRPM"
1827 local kernel_devel_rpm
1828 if ! kernel_devel_rpm=$(find_rpm "$TOPDIR/RPMS/${TARGET_ARCH}/" provides "^$(devel_kernel_name $KERNEL_LUSTRE_NAMING) ="); then
1829 fatal 1 "Failed to find a kernel development RPM in $TOPDIR/RPMS/${TARGET_ARCH}/"
1832 # install the -devel RPM in preparation for modules builds
1833 if ! lnxrel="$kernel_extra_version" unpack_linux_devel_rpm \
1834 "$TOPDIR/RPMS/${TARGET_ARCH}/$kernel_devel_rpm"; then
1835 fatal 1 "Could not find the Linux tree in $TOPDIR/RPMS/${TARGET_ARCH}/$kernel_devel_rpm"
1839 # need to find and unpack the vendor's own kernel-devel for patchless
1841 if ! kernelrpm=$(find_linux_rpm "-$DEVEL_KERNEL_TYPE"); then
1842 fatal 1 "Could not find the kernel-$DEVEL_KERNEL_TYPE RPM in $KERNELRPMSBASE/$lnxmaj/$DISTROMAJ"
1844 if ! lnxrel="$lnxrel" unpack_linux_devel_rpm "$kernelrpm" "-"; then
1845 fatal 1 "Could not find the Linux tree in $kernelrpm"
1849 # ~sigh~ have to make copies of and modify some of the rpm
1850 # infrastructure files so that find-requires can find our unpacked
1851 # kernel-devel artifacts
1852 cp $RPM_HELPERS_DIR/{symset-table,find-requires{,.ksyms}} .
1853 export FIND_REQUIRES="$(pwd)/find-requires"
1854 export FIND_KSYMS_REQUIRES="$(pwd)/find-requires.ksyms"
1855 chmod 755 {symset-table,find-requires{,.ksyms}}
1857 tmp="${tmp//\//\\/}"
1858 sed -i "s/\/.*find-requires.ksyms/$tmp\/find-requires.ksyms/g" find-requires
1859 sed -i "s/\/usr\/src\/kernels/$tmp\/reused\/usr\/src\/kernels/" find-requires.ksyms
1860 sed -i "s/\/boot/$tmp\/reused\/boot/; s/\/usr\/src\/kernels/$tmp\/reused\/usr\/src\/kernels/" symset-table
1862 build_ofed "${LINUXOBJ:-$LINUX}" "$ofed_type" "$ofed_version" ||
1863 fatal 1 "error building OFED"
1866 if build_lustre "$LINUX" "$LINUXOBJ"; then
1867 # the build worked. resolve any symlinked files (i.e. from reuse)
1868 # in RPMS/$arch to real files so that that that huge mess of
1869 # complication known as LTS can copy them yet somewhere else.
1870 # is it any wonder this whole process is so damn so? anyone ever
1871 # heard of hardlinks? it's this cool new thing that allows you save
1872 # tons of time and space by creating... well you can go read about
1873 # them if you have not heard about them yet.
1874 # can i say how much the implemenation of all of this really impedes
1877 for dir in RPMS/*; do
1879 for file in $(ls); do
1880 if [ -h $file ]; then
1887 # also, for i?86, make sure all of the RPMs are in RPMS/$TARGET_ARCH
1888 # as that's where LTS expects to find them
1889 for dir in RPMS/*; do
1890 if [ $dir = RPMS/$TARGET_ARCH ]; then
1895 if [ -n "$files" ]; then
1896 cp -al $files ../$TARGET_ARCH
1906 create_rpmbuild_dirs() {
1908 [ -d RPMS ] || mkdir RPMS
1909 [ -d RPMS/${TARGET_ARCH} ] || mkdir RPMS/${TARGET_ARCH}
1910 [ -d RPMS/noarch ] || mkdir RPMS/noarch
1911 [ -d BUILD ] || mkdir BUILD
1912 [ -d SOURCES ] || mkdir SOURCES
1913 [ -d SPECS ] || mkdir SPECS
1914 [ -d SRPMS ] || mkdir SRPMS
1936 [[ $list\ == *\ $item\ * ]]
1940 #########################################################################
1941 # Generate a backtrace through the call stack.
1945 #########################################################################
1949 local funcname="" sourcefile="" lineno="" n
1951 echo "Call stack: (most recent first)"
1952 for (( n = $strip ; n < ${#FUNCNAME[@]} ; ++n )) ; do
1953 funcname=${FUNCNAME[$n - 1]}
1954 sourcefile=$(basename ${BASH_SOURCE[$n]})
1955 lineno=${BASH_LINENO[$n - 1]}
1959 # Display function arguments
1960 if [[ ! -z "${BASH_ARGV[@]}" ]]; then
1961 local args newarg j p=0
1962 for (( j = ${BASH_ARGC[$n - 1]}; j > 0; j-- )); do
1963 newarg=${BASH_ARGV[$j + $p - 1]}
1964 args="${args:+${args} }'${newarg}'"
1966 let p+=${BASH_ARGC[$n - 1]}
1968 echo " ${funcname} ${args:+${args} }at ${sourcefile}:${lineno}"
1972 echo "BEGIN BACKTRACE"
1974 #echo ${BASH_LINENO[*]}
1975 #echo ${BASH_SOURCE[*]}
1976 #echo ${FUNCNAME[*]}
1977 local i=$((${#FUNCNAME[@]} - 1))
1978 while [ $i -ge 0 ]; do
1979 local lineno=${BASH_LINENO[$i]}
1983 local SOURCELINE="${BASH_SOURCE[$i + 1]}:${lineno}"
1984 # Can't figure out how to get function args from other frames...
1985 local FUNCTION="${FUNCNAME[$i]}()"
1986 echo "$SOURCELINE:$FUNCTION"
1990 echo "END BACKTRACE"
1996 seen_list=$(new_list)
1998 echo "An unexpected error has occurred at ${BASH_SOURCE[0]##*/}:$((LINENO-1)).
1999 Unfortunately the above line number in the message may or may not be correct,
2000 but details have been send to the lbuild maintainer. Attempting to continue."; (echo "Untrapped error"
2002 # have we seen this one
2003 echo "checking seen list for ${BASH_SOURCE[0]}:${BASH_LINENO[0]}"
2005 if is_list_member "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"; then
2006 echo "seen this one already"
2008 seen_list=$(add_list "$seen_list" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}")
2011 ) ; set $xtrace' ERR
2014 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
2016 options=$(getopt -o D:h -l kerneltree:,distro:,kernelrpm:,reusebuild:,\
2017 patchless,patchless-server,enable-kernel-debug,ccache,norpm,external-patches:,timestamp:,\
2018 extraversion:,kerneldir:,linux:,lustre:,nodownload,nosrc,noiokit,ofed-type:,\
2019 ofed-version:,mlnx-version:,ofed-src:,publish,disable-zfs,release,set-value:,\
2020 src,stage:,target:,with-linux:,xen -- "$@")
2022 if [ $? != 0 ]; then
2026 eval set -- "$options"
2057 if ! KERNELTREE=$(canon_path "$2"); then
2058 fatal 1 "Could not determine the canonical location of $2"
2062 --linux | --with-linux)
2063 if ! LINUX=$(canon_path "$2"); then
2064 fatal 1 "Could not determine the canonical location of $2"
2073 if ! REUSEBUILD=$(canon_path "$2"); then
2074 fatal 1 "Could not determine the canonical location of $2"
2090 PATCHLESS_SERVER=true
2093 --enable-kernel-debug)
2094 ENABLE_KERNEL_DEBUG=true
2098 if ! KERNELRPMSBASE=$(canon_path "$2"); then
2099 fatal 1 "Could not determine the canonical location of $2"
2108 if ! LUSTRE=$(canon_filepath "$2"); then
2109 fatal 1 "Could not determine the canonical location of $2"
2166 # there are actually some lustre configure flags that we need to
2167 # handle ourselves (but we still give them to configure)
2168 if [[ \ $@\ == *\ --disable-tests\ * ]]; then
2175 usage 1 "Unrecognized option: $1"
2186 if [ -n "$OFED_TYPE" -a "$OFED_TYPE" != "inkernel" ]; then
2187 download_ofed "$OFED_TYPE" "$OFED_VERSION"
2188 unpack_ofed "$OFED_TYPE" "$OFED_VERSION" || fatal 1 "Error unpacking OFED tarball"
2191 # make sure the RPM build environment is set up
2192 create_rpmbuild_dirs
2194 # if an unpacked kernel source tree was given on the command line
2195 # just build lustre with it (nothing distro kernel specific here)
2196 if [ -n "$LINUX" ]; then
2197 find_linux_release() {
2198 _find_linux_release $LINUX
2200 build_ofed "${LINUXOBJ:-$LINUX}" "$OFED_TYPE" "$OFED_VERSION" ||
2201 fatal 1 "error building OFED"
2202 build_lustre "$LINUX" "$LINUXOBJ"
2204 if [ ! -f "${LBUILD_DIR}/lbuild-$DISTROMAJ" ]; then
2205 fatal 1 "${LBUILD_DIR}/lbuild-$DISTROMAJ not found"
2207 source ${LBUILD_DIR}/lbuild-$DISTROMAJ
2208 build_with_srpm "$OFED_TYPE" "$OFED_VERSION" || fatal 1 "Failed to build_with_srpm"