diff --git a/ci/unit/required_packages.sh b/ci/unit/required_packages.sh index ff5e3f98d14..efbd48be545 100755 --- a/ci/unit/required_packages.sh +++ b/ci/unit/required_packages.sh @@ -16,6 +16,7 @@ pkgs="argobots \ fuse3-libs \ gotestsum \ hwloc-devel \ + libasan \ libipmctl-devel \ libisa-l-devel \ libfabric-devel \ diff --git a/site_scons/components/__init__.py b/site_scons/components/__init__.py index ed50b80461b..a83a040ddba 100644 --- a/site_scons/components/__init__.py +++ b/site_scons/components/__init__.py @@ -277,7 +277,15 @@ def define_components(reqs): abt_build = ['./configure', '--prefix=$ARGOBOTS_PREFIX', 'CC=gcc', - '--enable-stack-unwind'] + '--enable-stack-unwind=yes'] + try: + if reqs.get_env('SANITIZERS') != "": + # NOTE the address sanitizer library add some extra info on the stack and thus ULTs + # need a bigger stack + print("Increase argobots default stack size from 16384 to 32768") + abt_build += ['--enable-default-stacksize=32768'] + except KeyError: + pass if reqs.target_type == 'debug': abt_build.append('--enable-debug=most') diff --git a/site_scons/prereq_tools/base.py b/site_scons/prereq_tools/base.py index 0f47bd68a9a..50c6c874bbd 100644 --- a/site_scons/prereq_tools/base.py +++ b/site_scons/prereq_tools/base.py @@ -456,6 +456,7 @@ def __init__(self, env, opts): ['gcc', 'covc', 'clang', 'icc'], ignorecase=2)) opts.Add(EnumVariable('WARNING_LEVEL', "Set default warning level", 'error', ['warning', 'warn', 'error'], ignorecase=2)) + opts.Add(('SANITIZERS', 'Instrument C code with google sanitizers', None)) opts.Update(self.__env) diff --git a/site_scons/site_tools/compiler_setup.py b/site_scons/site_tools/compiler_setup.py index 9f25ccace71..155639d944e 100644 --- a/site_scons/site_tools/compiler_setup.py +++ b/site_scons/site_tools/compiler_setup.py @@ -2,6 +2,7 @@ from SCons.Script import Configure, Exit, GetOption +FRAME_SIZE_MAX = 4096 DESIRED_FLAGS = ['-fstack-usage', '-Wno-sign-compare', '-Wno-unused-parameter', @@ -13,7 +14,7 @@ '-Wno-unused-command-line-argument', '-Wmismatched-dealloc', '-Wfree-nonheap-object', - '-Wframe-larger-than=4096'] + f"-Wframe-larger-than={FRAME_SIZE_MAX}"] # Compiler flags to prevent optimizing out security checks DESIRED_FLAGS.extend(['-fno-strict-overflow', '-fno-delete-null-pointer-checks', '-fwrapv']) @@ -54,6 +55,25 @@ def _base_setup(env): env.AppendIfSupported(CCFLAGS=DESIRED_FLAGS) + if 'SANITIZERS' in env and env['SANITIZERS'] != "": + for flag in [f"-Wframe-larger-than={FRAME_SIZE_MAX}", '-fomit-frame-pointer']: + if flag in env["CCFLAGS"]: + env["CCFLAGS"].remove(flag) + cc_flags = [f"-Wframe-larger-than={max(8192, FRAME_SIZE_MAX)}", + '-fno-omit-frame-pointer', + '-fno-common'] + + asan_flags = [] + for sanitizer in env['SANITIZERS'].split(','): + asan_flags.append(f"-fsanitize={sanitizer}") + + env.AppendIfSupported(CCFLAGS=cc_flags + asan_flags) + + for flag in asan_flags: + if flag in env["CCFLAGS"]: + env.AppendUnique(LINKFLAGS=flag) + print(f"Enabling {flag.split('=')[1]} sanitizer for C code") + if '-Wmismatched-dealloc' in env['CCFLAGS']: env.AppendUnique(CPPDEFINES={'HAVE_DEALLOC': '1'}) @@ -183,10 +203,30 @@ def _set_fortify_level(env): Exit(1) +def _check_func(env, func_name): + """Check if a function is usable""" + denv = env.Clone() + # NOTE Remove sanitizers to not scramble the test output + if 'SANITIZERS' in denv and denv['SANITIZERS'] != "": + for sanitizer in denv['SANITIZERS'].split(','): + flag = f"-fsanitize={sanitizer}" + if flag not in denv["CCFLAGS"]: + continue + denv["CCFLAGS"].remove(flag) + denv["LINKFLAGS"].remove(flag) + + config = Configure(denv) + res = config.CheckFunc(func_name) + config.Finish() + + return res + + def generate(env): """Add daos specific method to environment""" env.AddMethod(_base_setup, 'compiler_setup') env.AddMethod(_append_if_supported, "AppendIfSupported") + env.AddMethod(_check_func, "CheckFunc") def exists(_env): diff --git a/src/SConscript b/src/SConscript index 2741e6c93e1..65992cf500d 100644 --- a/src/SConscript +++ b/src/SConscript @@ -76,12 +76,10 @@ def scons(): base_env_mpi.AppendUnique(CPPPATH=[Dir('include')]) if not env.GetOption('clean') and not env.GetOption('help'): - conf = env.Clone().Configure() # Detect if we have explicit_bzero - if not conf.CheckFunc('explicit_bzero'): + if not env.CheckFunc('explicit_bzero'): env.Append(CCFLAGS=['-DNEED_EXPLICIT_BZERO']) base_env.Append(CCFLAGS=['-DNEED_EXPLICIT_BZERO']) - conf.Finish() for header in HEADERS: env.Install(os.path.join('$PREFIX', 'include'), os.path.join('include', header)) diff --git a/src/client/dfs/SConscript b/src/client/dfs/SConscript index 5b98d6d7e8a..faa84a79fbe 100644 --- a/src/client/dfs/SConscript +++ b/src/client/dfs/SConscript @@ -18,7 +18,7 @@ def configure_lustre(denv): _print("No installed Lustre version detected") else: _print("Installed Lustre version detected") - if not conf.CheckFunc('llapi_unlink_foreign'): + if not denv.CheckFunc('llapi_unlink_foreign'): _print("Lustre version is not compatible") else: _print("Lustre version is compatible") diff --git a/src/control/SConscript b/src/control/SConscript index 06410fee53a..efb586cfccb 100644 --- a/src/control/SConscript +++ b/src/control/SConscript @@ -36,6 +36,8 @@ def get_build_flags(benv): """Return string of build flags""" if is_release_build(benv): return '-buildmode=pie' + if 'SANITIZERS' in benv and benv['SANITIZERS'] != "": + return '-asan' # enable race detector for non-release builds return '-race' diff --git a/utils/ansible/ftest/templates/daos-make.sh.j2 b/utils/ansible/ftest/templates/daos-make.sh.j2 index e1bde6a59b5..838d5c38062 100644 --- a/utils/ansible/ftest/templates/daos-make.sh.j2 +++ b/utils/ansible/ftest/templates/daos-make.sh.j2 @@ -115,7 +115,7 @@ function check_cmds function usage { cat <<- EOF - usage: daos-make.sh [OPTIONS] + usage: daos-make.sh [OPTIONS] [-- ARGS] Build and install DAOS for running avocado functional tests @@ -221,17 +221,20 @@ run $PIP_EXE install --upgrade pip run $PIP_EXE install -r "$DAOS_SOURCE_DIR/requirements.txt" SCONS_OPTS="--directory="$DAOS_SOURCE_DIR" --jobs=$JOBS_NB" +if "$FORCE_INSTALL" ; then + SCONS_OPTS+=" --config=force" +fi if "$DAOS_BUILD_DEPS" ; then info "Building DAOS dependencies from source tree $DAOS_SOURCE_DIR" - if ! run "$SCONS_EXE" BUILD_TYPE="$DAOS_BUILD_TYPE" PREFIX="$DAOS_INSTALL_DIR" $SCONS_OPTS --build-deps=only ; then + if ! run "$SCONS_EXE" BUILD_TYPE="$DAOS_BUILD_TYPE" PREFIX="$DAOS_INSTALL_DIR" "${args[@]}" $SCONS_OPTS --build-deps=only ; then fatal "DAOS dependencies could not be properly build" fi fi info "Building DAOS from source tree $DAOS_SOURCE_DIR" # NOTE Dependencies will not be build as 'no' is default value of the --build-deps option -if ! run env MPI_PKG=any "$SCONS_EXE" BUILD_TYPE="$DAOS_BUILD_TYPE" PREFIX="$DAOS_INSTALL_DIR" $SCONS_OPTS ; then +if ! run env MPI_PKG=any "$SCONS_EXE" BUILD_TYPE="$DAOS_BUILD_TYPE" PREFIX="$DAOS_INSTALL_DIR" "${args[@]}" $SCONS_OPTS ; then fatal "DAOS could not be properly build" fi @@ -275,10 +278,10 @@ run $CLUSH_EXE $CLUSH_OPTS -l root -w $CLIENTS_LIST chmod 755 /usr/bin/dfuse info "Updating dynamic linker configuration" {% if "daos_clients" in groups and groups["daos_clients"] | length > 0 %} run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST -w $CLIENTS_LIST rm -f /etc/ld.so.cache -run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST -w $CLIENTS_LIST ldconfig +run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST -w $CLIENTS_LIST ldconfig $DAOS_INSTALL_DIR/lib64 $DAOS_INSTALL_DIR/lib64/daos_srv {% else %} run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST rm -f /etc/ld.so.cache -run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST ldconfig +run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST ldconfig $DAOS_INSTALL_DIR/lib64 $DAOS_INSTALL_DIR/lib64/daos_srv {% endif %} if [[ ${MPICH_PATH:+x} ]] ; then @@ -627,8 +630,8 @@ fi info "Updating dynamic linker configuration" {% if "daos_clients" in groups and groups["daos_clients"] | length > 0 %} run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST -w $CLIENTS_LIST rm -f /etc/ld.so.cache -run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST -w $CLIENTS_LIST ldconfig +run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST -w $CLIENTS_LIST ldconfig $DAOS_INSTALL_DIR/lib64 $DAOS_INSTALL_DIR/lib64/daos_srv {% else %} run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST rm -f /etc/ld.so.cache -run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST ldconfig +run $CLUSH_EXE $CLUSH_OPTS -l root -w $SERVERS_LIST ldconfig $DAOS_INSTALL_DIR/lib64 $DAOS_INSTALL_DIR/lib64/daos_srv {% endif %} diff --git a/utils/ansible/ftest/vars/Rocky8.yml b/utils/ansible/ftest/vars/Rocky8.yml index bc4d5dccd57..e5c01deae85 100644 --- a/utils/ansible/ftest/vars/Rocky8.yml +++ b/utils/ansible/ftest/vars/Rocky8.yml @@ -11,6 +11,7 @@ daos_base_deps: - glibc - jq - lbzip2 + - libasan - numactl - numactl-libs - numatop @@ -33,6 +34,7 @@ daos_dev_deps: - gcc-c++ - gcc-gfortran - golang + - hdf5-devel - libaec-devel - libattr-devel - libcmocka-devel @@ -40,6 +42,7 @@ daos_dev_deps: - libyaml-devel - openssl-devel - pciutils-devel + - protobuf-c-devel - python3.11 - python3.11-devel - python3-clustershell diff --git a/utils/build.config b/utils/build.config index c38d49a267a..38025a2db9c 100644 --- a/utils/build.config +++ b/utils/build.config @@ -2,7 +2,7 @@ component=daos [commit_versions] -argobots=v1.1 +argobots=v1.2 fuse=fuse-3.16.2 pmdk=2.0.0 isal=v2.30.0 @@ -30,3 +30,4 @@ spdk=https://github.com/spdk/spdk/commit/b0aba3fcd5aceceea530a702922153bc7566497 ofi=https://github.com/ofiwg/libfabric/commit/d827c6484cc5bf67dfbe395890e258860c3f0979.diff fuse=https://github.com/libfuse/libfuse/commit/c9905341ea34ff9acbc11b3c53ba8bcea35eeed8.diff mercury=https://raw.githubusercontent.com/daos-stack/mercury/481297621bafbbcac4cc6f8feab3f1b6f8b14b59/na_ucx_keyres_epchk.patch +argobots=https://github.com/pmodels/argobots/pull/397/commits/411e5b344642ebc82190fd8b125db512e5b449d1.diff,https://github.com/pmodels/argobots/commit/bb0c908abfac4bfe37852eee621930634183c6aa.diff diff --git a/utils/rpms/daos.spec b/utils/rpms/daos.spec index f90e6d7010f..678c45d6055 100644 --- a/utils/rpms/daos.spec +++ b/utils/rpms/daos.spec @@ -15,7 +15,7 @@ Name: daos Version: 2.7.100 -Release: 5%{?relval}%{?dist} +Release: 7%{?relval}%{?dist} Summary: DAOS Storage Engine License: BSD-2-Clause-Patent @@ -41,7 +41,7 @@ BuildRequires: hwloc-devel BuildRequires: bullseye %endif %if (0%{?rhel} >= 8) -BuildRequires: argobots-devel >= 1.1 +BuildRequires: argobots-devel >= 1.2 BuildRequires: json-c-devel BuildRequires: boost-python3-devel %else @@ -121,6 +121,14 @@ BuildRequires: libuct-devel BuildRequires: ucx-devel %endif +# Needed for debugging tasks +%if (0%{?rhel} >= 8) +BuildRequires: libasan +%endif +%if (0%{?suse_version} > 0) +BuildRequires: libasan8 +%endif + Requires: openssl # This should only be temporary until we can get a stable upstream release # of mercury, at which time the autoprov shared library version should @@ -592,6 +600,10 @@ getent passwd daos_agent >/dev/null || useradd -s /sbin/nologin -r -g daos_agent # No files in a shim package %changelog +* Tue Sep 10 2024 Cedric Koch-Hofer 2.7.100-6 +- Update argobots to 1.2 +- Add support of the libasan + * Thu Aug 15 2024 Michael MacDonald 2.7.100-5 - Add libdaos_self_test.so to client RPM diff --git a/utils/scripts/install-el8.sh b/utils/scripts/install-el8.sh index 81a044bfddb..180455b996b 100755 --- a/utils/scripts/install-el8.sh +++ b/utils/scripts/install-el8.sh @@ -36,6 +36,7 @@ dnf --nodocs install \ java-1.8.0-openjdk \ json-c-devel \ libaio-devel \ + libasan \ libcmocka-devel \ libevent-devel \ libiscsi-devel \ diff --git a/utils/scripts/install-el9.sh b/utils/scripts/install-el9.sh index 9ddd8c257d6..ab73ee71a6e 100755 --- a/utils/scripts/install-el9.sh +++ b/utils/scripts/install-el9.sh @@ -35,6 +35,7 @@ dnf --nodocs install \ java-1.8.0-openjdk \ json-c-devel \ libaio-devel \ + libasan \ libcmocka-devel \ libevent-devel \ libipmctl-devel \ diff --git a/utils/scripts/install-leap15.sh b/utils/scripts/install-leap15.sh index fc9826ce508..deebe1e50e2 100755 --- a/utils/scripts/install-leap15.sh +++ b/utils/scripts/install-leap15.sh @@ -31,6 +31,7 @@ dnf --nodocs install \ hwloc-devel \ java-1_8_0-openjdk-devel \ libaio-devel \ + libasan8 \ libcmocka-devel \ libcapstone-devel \ libevent-devel \ diff --git a/utils/scripts/install-ubuntu.sh b/utils/scripts/install-ubuntu.sh index ec21c92f474..4f40eee161e 100755 --- a/utils/scripts/install-ubuntu.sh +++ b/utils/scripts/install-ubuntu.sh @@ -25,6 +25,7 @@ apt-get install \ golang-go \ kmod \ libaio-dev \ + libasan8 \ libboost-dev \ libcapstone-dev \ libcmocka-dev \ diff --git a/utils/sl/fake_scons/SCons/Script/__init__.py b/utils/sl/fake_scons/SCons/Script/__init__.py index f490ba78cbe..22a184be38d 100644 --- a/utils/sl/fake_scons/SCons/Script/__init__.py +++ b/utils/sl/fake_scons/SCons/Script/__init__.py @@ -1,5 +1,5 @@ """Fake scons environment shutting up pylint on SCons files""" -# Copyright 2016-2023 Intel Corporation +# Copyright 2016-2024 Intel Corporation # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -338,6 +338,10 @@ def require(self, env, *kw, headers_only=False): """Fake require""" return + def CheckFunc(self, *_args, **_kw): + """Fake CheckFunc""" + return True + class Variables(): """Fake variables"""