Whamcloud - gitweb
LU-13485 build: Enable 2 stage configure tests 47/38347/4
authorShaun Tancheff <shaun.tancheff@hpe.com>
Sun, 10 May 2020 20:14:54 +0000 (15:14 -0500)
committerOleg Drokin <green@whamcloud.com>
Wed, 27 May 2020 05:05:07 +0000 (05:05 +0000)
This idea was implemented by OpenZFS a while ago. This
is heavily inspired by the OpenZFS work.

Here we enable splitting tests compile tests into two
distinct parts that share an internal unique name.

The source half can then be built in parallel and
the results can be determined based on the build
artifacts.

Tests which depend on order of execution and/or the
result of a previous test are not well suited for
being converted. However the majority of lustre
compile tests can be run in parallel.

Signed-off-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Change-Id: If01ccdfdf4810ecc2d616da3fa6b7ca786fe760f
Reviewed-on: https://review.whamcloud.com/38347
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Petros Koutoupis <petros.koutoupis@hpe.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
config/lustre-build-ldiskfs.m4
config/lustre-build-linux.m4
config/lustre-build.m4
libcfs/autoconf/lustre-libcfs.m4
lnet/autoconf/lustre-lnet.m4
lustre/autoconf/lustre-core.m4

index 88aaed7..6358dbf 100644 (file)
@@ -427,6 +427,10 @@ AC_MSG_RESULT([$enable_ldiskfs])
 AM_CONDITIONAL([LDISKFS_ENABLED], [test x$enable_ldiskfs = xyes])
 ]) # LB_CONFIG_LDISKFS
 
+
+AC_DEFUN([LB_EXT4_SRC_DIR_SRC], [])
+AC_DEFUN([LB_EXT4_SRC_DIR_RESULTS], [])
+
 #
 # LB_VALIDATE_EXT4_SRC_DIR
 #
index 53dc3a6..b8a5c2e 100644 (file)
@@ -638,3 +638,182 @@ AC_CACHE_CHECK([for $1], lb_header, [
 AS_VAR_IF([lb_header], [yes], [$2], [$3])[]dnl
 AS_VAR_POPDEF([lb_header])dnl
 ]) # LB_CHECK_LINUX_HEADER
+
+# ------------------------------------------------------------------------------
+# Support 2 stage: parallel compile then checked test results
+# Heavily inspired by OpenZFS
+
+AC_DEFUN([LB2_LINUX_CONFTEST_C], [
+test -d ${TEST_DIR}/$2 || mkdir -p ${TEST_DIR}/$2
+cat confdefs.h - <<_EOF >${TEST_DIR}/$2/$2.c
+$1
+_EOF
+])
+
+#
+# LB2_LINUX_CONFTEST_MAKEFILE
+#
+# $1 - *unique* test case name
+# $2 - additional build flags (ccflags)
+# $3 - external kernel includes for lnet o2ib|gni
+#
+AC_DEFUN([LB2_LINUX_CONFTEST_MAKEFILE], [
+       test -d ${TEST_DIR} || mkdir -p ${TEST_DIR}
+       test -d ${TEST_DIR}/$1 || mkdir -p ${TEST_DIR}/$1
+
+       file=${TEST_DIR}/$1/Makefile
+       EXT_INCLUDE="$3"
+
+       cat - <<_EOF >$file
+# Example command line to manually build source
+# make modules -C $LINUX_OBJ $ARCH_UM M=${TEST_DIR}/$1
+
+${LD:+LD="$LD"}
+CC=$CC
+ZINC=${ZFS}
+SINC=${SPL}
+ZOBJ=${ZFS_OBJ}
+SOBJ=${SPL_OBJ}
+
+LINUXINCLUDE  = $EXT_INCLUDE
+LINUXINCLUDE += -I$LINUX/arch/$SUBARCH/include
+LINUXINCLUDE += -Iinclude -Iarch/$SUBARCH/include/generated
+LINUXINCLUDE += -I$LINUX/include
+LINUXINCLUDE += -Iinclude2
+LINUXINCLUDE += -I$LINUX/include/uapi
+LINUXINCLUDE += -Iinclude/generated
+LINUXINCLUDE += -I$LINUX/arch/$SUBARCH/include/uapi
+LINUXINCLUDE += -Iarch/$SUBARCH/include/generated/uapi
+LINUXINCLUDE += -I$LINUX/include/uapi -Iinclude/generated/uapi
+ifneq (\$(SOBJ),)
+LINUXINCLUDE += -include \$(SOBJ)/spl_config.h
+endif
+ifneq (\$(ZOBJ),)
+LINUXINCLUDE += -include \$(ZOBJ)/zfs_config.h
+endif
+ifneq (\$(SINC),)
+LINUXINCLUDE += -I\$(SINC)/include
+endif
+ifneq (\$(ZINC),)
+LINUXINCLUDE += -I\$(ZINC) -I\$(ZINC)/include
+ifneq (\$(SINC),)
+LINUXINCLUDE += -I\$(SINC)
+else
+LINUXINCLUDE += -I\$(ZINC)/include/spl
+endif
+endif
+LINUXINCLUDE += -include $CONFIG_INCLUDE
+KBUILD_EXTRA_SYMBOLS=${ZFS_OBJ:+$ZFS_OBJ/Module.symvers}
+
+ccflags-y := -Werror-implicit-function-declaration
+_EOF
+
+       # Additional custom CFLAGS as requested.
+       m4_ifval($2, [echo "ccflags-y += $2" >>$file], [])
+
+       # Test case source
+       echo "obj-m := $1.o" >>$file
+       echo "obj-m += $1/" >>${TEST_DIR}/Makefile
+])
+
+
+#
+# LB2_LINUX_COMPILE
+#
+# $1 - build dir
+# $2 - test command
+# $3 - pass command
+# $4 - fail command
+#
+# Used internally by LB2_LINUX_TEST_COMPILE
+#
+AC_DEFUN([LB2_LINUX_COMPILE], [
+       AC_TRY_COMMAND([
+           KBUILD_MODPOST_NOFINAL="yes"
+           make modules -k -j$TEST_JOBS -C $LINUX_OBJ $ARCH_UM
+           M=$1 >$1/build.log 2>&1])
+       AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4])
+])
+
+#
+# LB2_LINUX_TEST_COMPILE
+#
+# Perform a full compile excluding the final modpost phase.
+# $1 - flavor
+# $2 - dirname
+#
+AC_DEFUN([LB2_LINUX_TEST_COMPILE], [
+       LB2_LINUX_COMPILE([$2], [test -f $2/build.log], [
+               mv $2/Makefile $2/Makefile.compile.$1
+               mv $2/build.log $2/build.log.$1
+       ],[
+               AC_MSG_ERROR([
+        *** Unable to compile test source to determine kernel interfaces.])
+       ])
+])
+
+#
+# Perform the compilation of the test cases in two phases.
+#
+# Phase 1) attempt to build the object files for all of the tests
+#          defined by the LB2_LINUX_TEST_SRC macro.
+#
+# Phase 2) disable all tests which failed the initial compilation.
+#
+# This allows us efficiently build the test cases in parallel while
+# remaining resilient to build failures which are expected when
+# detecting the available kernel interfaces.
+#
+# The maximum allowed parallelism can be controlled by setting the
+# TEST_JOBS environment variable which defaults to $(nproc).
+#
+AC_DEFUN([LB2_LINUX_TEST_COMPILE_ALL], [
+       # Phase 1 - Compilation only, final linking is skipped.
+       LB2_LINUX_TEST_COMPILE([$1], [${TEST_DIR}])
+
+       for dir in $(awk '/^obj-m/ { print [$]3 }' \
+           ${TEST_DIR}/Makefile.compile.$1); do
+               name=${dir%/}
+               AS_IF([test -f ${TEST_DIR}/$name/$name.o], [
+                       touch ${TEST_DIR}/$name/$name.ko
+               ])
+       done
+])
+
+#
+# LB2_LINUX_TEST_SRC
+#
+# $1 - *unique* name
+# $2 - global
+# $3 - source
+# $4 - extra cflags
+# $5 - external include paths
+#
+# NOTICE as all of the test cases are compiled in parallel tests may not
+# depend on the results other tests.
+# Each test needs resolve any external dependencies at the time the program
+# source is generated.
+#
+AC_DEFUN([LB2_LINUX_TEST_SRC], [
+       LB2_LINUX_CONFTEST_C([LB_LANG_PROGRAM([[$2]], [[$3]])], [$1])
+       LB2_LINUX_CONFTEST_MAKEFILE([$1], [$4], [$5])
+])
+
+#
+# LB2_LINUX_TEST_RESULT
+#
+# $1 - *unique* name matching the LB2_LINUX_TEST_SRC macro
+# $2 - run on success (valid .ko generated)
+# $3 - run on failure (unable to compile)
+#
+AC_DEFUN([LB2_LINUX_TEST_RESULT], [
+       AS_IF([test -d ${TEST_DIR}/$1], [
+               AS_IF([test -f ${TEST_DIR}/$1/$1.ko], [$2], [$3])
+       ], [
+               AC_MSG_ERROR([
+       *** No matching source for the "$1" test, check that
+       *** both the test source and result macros refer to the same name.
+               ])
+       ])
+])
+
index 4b9f9d1..2f6a98c 100644 (file)
@@ -157,11 +157,25 @@ AC_MSG_RESULT([$enable_modules ($target_os)])
 AS_IF([test "x$enable_modules" = xyes], [
        AS_CASE([$target_os],
                [linux*], [
+                       # Run serial tests
                        LB_PROG_LINUX
                        LIBCFS_PROG_LINUX
                        LN_PROG_LINUX
                        AS_IF([test "x$enable_server" != xno], [LB_EXT4_SRC_DIR])
                        LC_PROG_LINUX
+
+                       # Run any parallel compile tests
+                       LIBCFS_PROG_LINUX_SRC
+                       LN_PROG_LINUX_SRC
+                       AS_IF([test "x$enable_server" != xno], [LB_EXT4_SRC_DIR_SRC])
+                       LC_PROG_LINUX_SRC
+
+                       # Collect parallel compile tests results
+                       LIBCFS_PROG_LINUX_RESULTS
+                       LN_PROG_LINUX_RESULTS
+                       AS_IF([test "x$enable_server" != xno], [LB_EXT4_SRC_DIR_RESULTS])
+                       LC_PROG_LINUX_RESULTS
+
                ], [*], [
                        # This is strange - Lustre supports a target we don't
                        AC_MSG_ERROR([Modules are not supported on $target_os])
index e933bc6..c3efe06 100644 (file)
@@ -1259,6 +1259,8 @@ Lustre requires that CONFIG_CRYPTO_CRC32 is enabled in your kernel.
 ])])
 ]) # LIBCFS_CONFIG_CRYPTO_CRC32
 
+AC_DEFUN([LIBCFS_PROG_LINUX_SRC], [] )
+AC_DEFUN([LIBCFS_PROG_LINUX_RESULTS], [])
 
 #
 # LIBCFS_PROG_LINUX
index 961808b..139ce1c 100644 (file)
@@ -102,6 +102,8 @@ esac
 
 AS_IF([test $ENABLEO2IB = "no"], [
        AC_MSG_RESULT([no])
+       AC_DEFUN([LN_CONFIG_O2IB_SRC], [])
+       AC_DEFUN([LN_CONFIG_O2IB_RESULTS], [])
 ], [
        o2ib_found=false
        for O2IBPATH in $O2IBPATHS; do
@@ -521,6 +523,8 @@ AS_IF([test $ENABLEO2IB != "no"], [
        LN_IB_SG_DMA_ADDRESS_EXISTS
 
        EXTRA_CHECK_INCLUDE=""
+       AC_DEFUN([LN_CONFIG_O2IB_SRC], [])
+       AC_DEFUN([LN_CONFIG_O2IB_RESULTS], [])
 ]) # ENABLEO2IB != "no"
 ]) # LN_CONFIG_O2IB
 
@@ -767,6 +771,10 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
 ])
 ]) # LN_USR_RDMA
 
+
+AC_DEFUN([LN_PROG_LINUX_SRC], [])
+AC_DEFUN([LN_PROG_LINUX_RESULTS], [])
+
 #
 # LN_PROG_LINUX
 #
index b3242f7..4eec916 100644 (file)
@@ -285,6 +285,18 @@ AC_ARG_ENABLE([gss],
        [], [enable_gss="auto"])
 AC_MSG_RESULT([$enable_gss])
 
+AC_ARG_VAR([TEST_JOBS],
+    [simultaneous jobs during configure (defaults to $(nproc))])
+if test "x$ac_cv_env_TEST_JOBS_set" != "xset"; then
+       TEST_JOBS=${TEST_JOBS:-$(nproc)}
+fi
+AC_SUBST(TEST_JOBS)
+
+AC_ARG_VAR([TEST_DIR],
+    [location of temporary parallel configure tests (defaults to $PWD/lb2)])
+       TEST_DIR=${TEST_DIR:-$PWD/_lpb}
+AC_SUBST(TEST_DIR)
+
 AS_IF([test "x$enable_gss" != xno], [
        LC_CONFIG_GSS_KEYRING
        LC_KEY_TYPE_INSTANTIATE_2ARGS
@@ -2189,6 +2201,9 @@ lock_manager_ops_lm_compare_owner, [
 EXTRA_KCFLAGS="$tmp_flags"
 ]) # LC_LM_COMPARE_OWNER_EXISTS
 
+AC_DEFUN([LC_PROG_LINUX_SRC], [])
+AC_DEFUN([LC_PROG_LINUX_RESULTS], [])
+
 #
 # LC_FSCRYPT_SUPPORT
 #