diff options
Diffstat (limited to 'config')
140 files changed, 13609 insertions, 0 deletions
diff --git a/config/.gitignore b/config/.gitignore new file mode 100644 index 000000000000..cd811a0a956a --- /dev/null +++ b/config/.gitignore @@ -0,0 +1,9 @@ +/compile +/config.guess +/config.sub +/depcomp +/install-sh +/ltmain.sh +/missing +/libtool.m4 +/lt*.m4 diff --git a/config/Rules.am b/config/Rules.am new file mode 100644 index 000000000000..b02511a05298 --- /dev/null +++ b/config/Rules.am @@ -0,0 +1,62 @@ +# +# Default build rules for all user space components, every Makefile.am +# should include these rules and override or extend them as needed. +# + +DEFAULT_INCLUDES = \ + -include $(top_builddir)/zfs_config.h \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/module/icp/include \ + -I$(top_srcdir)/lib/libspl/include + +if BUILD_LINUX +DEFAULT_INCLUDES += \ + -I$(top_srcdir)/lib/libspl/include/os/linux +endif + +if BUILD_FREEBSD +DEFAULT_INCLUDES += \ + -I$(top_srcdir)/lib/libspl/include/os/freebsd +endif + +AM_LIBTOOLFLAGS = --silent + +AM_CFLAGS = -std=gnu99 -Wall -Wstrict-prototypes -Wmissing-prototypes +AM_CFLAGS += -fno-strict-aliasing +AM_CFLAGS += $(NO_OMIT_FRAME_POINTER) +AM_CFLAGS += $(DEBUG_CFLAGS) +AM_CFLAGS += $(ASAN_CFLAGS) +AM_CFLAGS += $(CODE_COVERAGE_CFLAGS) $(NO_FORMAT_ZERO_LENGTH) +if BUILD_FREEBSD +AM_CFLAGS += -fPIC -Werror -Wno-unknown-pragmas -Wno-enum-conversion +AM_CFLAGS += -include $(top_srcdir)/include/os/freebsd/spl/sys/ccompile.h +AM_CFLAGS += -I/usr/include -I/usr/local/include +endif + +AM_CPPFLAGS = -D_GNU_SOURCE +AM_CPPFLAGS += -D_REENTRANT +AM_CPPFLAGS += -D_FILE_OFFSET_BITS=64 +AM_CPPFLAGS += -D_LARGEFILE64_SOURCE +AM_CPPFLAGS += -DHAVE_LARGE_STACKS=1 +AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\" +AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\" +AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\" +AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\" +AM_CPPFLAGS += $(DEBUG_CPPFLAGS) +AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS) +if BUILD_LINUX +AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-linux-user\" +endif +if BUILD_FREEBSD +AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-freebsd-user\" +endif + +AM_LDFLAGS = $(DEBUG_LDFLAGS) +AM_LDFLAGS += $(ASAN_LDFLAGS) + +if BUILD_FREEBSD +AM_LDFLAGS += -fstack-protector-strong -shared +AM_LDFLAGS += -Wl,-x -Wl,--fatal-warnings -Wl,--warn-shared-textrel +AM_LDFLAGS += -lm +endif diff --git a/config/Substfiles.am b/config/Substfiles.am new file mode 100644 index 000000000000..63697bfa2b6a --- /dev/null +++ b/config/Substfiles.am @@ -0,0 +1,34 @@ +subst_sed_cmd = \ + -e 's|@bindir[@]|$(bindir)|g' \ + -e 's|@sbindir[@]|$(sbindir)|g' \ + -e 's|@datadir[@]|$(datadir)|g' \ + -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ + -e 's|@runstatedir[@]|$(runstatedir)|g' \ + -e 's|@initconfdir[@]|$(initconfdir)|g' \ + -e 's|@initdir[@]|$(initdir)|g' \ + -e 's|@mounthelperdir[@]|$(mounthelperdir)|g' \ + -e 's|@systemdgeneratordir[@]|$(systemdgeneratordir)|g' \ + -e 's|@systemdunitdir[@]|$(systemdunitdir)|g' \ + -e 's|@udevdir[@]|$(udevdir)|g' \ + -e 's|@udevruledir[@]|$(udevruledir)|g' \ + -e 's|@zfsexecdir[@]|$(zfsexecdir)|g' \ + -e 's|@PYTHON[@]|$(PYTHON)|g' \ + -e 's|@PYTHON_SHEBANG[@]|$(PYTHON_SHEBANG)|g' \ + -e 's|@DEFAULT_INIT_NFS_SERVER[@]|$(DEFAULT_INIT_NFS_SERVER)|g' \ + -e 's|@DEFAULT_INIT_SHELL[@]|$(DEFAULT_INIT_SHELL)|g' + +SUBSTFILES = +CLEANFILES = $(SUBSTFILES) +EXTRA_DIST = $(SUBSTFILES:=.in) + +$(SUBSTFILES):%:%.in Makefile + $(AM_V_GEN)set -e; \ + $(MKDIR_P) $$(dirname $@); \ + $(RM) $@~; \ + $(SED) $(subst_sed_cmd) $< >$@~; \ + if grep -E '@[a-zA-Z0-9_]+@' $@~ >&2; then \ + echo "Undefined substitution" >&2; \ + exit 1; \ + else test $$? -eq 1; fi; \ + test -x $< && chmod +x $@~; \ + mv -f $@~ $@ diff --git a/config/always-arch.m4 b/config/always-arch.m4 new file mode 100644 index 000000000000..25e8c963a4b4 --- /dev/null +++ b/config/always-arch.m4 @@ -0,0 +1,41 @@ +dnl # +dnl # Set the target cpu architecture. This allows the +dnl # following syntax to be used in a Makefile.am. +dnl # +dnl # ifeq ($(TARGET_CPU),x86_64) +dnl # ... +dnl # endif +dnl # +dnl # if TARGET_CPU_POWERPC +dnl # ... +dnl # else +dnl # ... +dnl # endif +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_ARCH], [ + case $target_cpu in + i?86) + TARGET_CPU=i386 + ;; + amd64|x86_64) + TARGET_CPU=x86_64 + ;; + powerpc*) + TARGET_CPU=powerpc + ;; + aarch64*) + TARGET_CPU=aarch64 + ;; + sparc64) + TARGET_CPU=sparc64 + ;; + esac + + AC_SUBST(TARGET_CPU) + + AM_CONDITIONAL([TARGET_CPU_I386], test $TARGET_CPU = i386) + AM_CONDITIONAL([TARGET_CPU_X86_64], test $TARGET_CPU = x86_64) + AM_CONDITIONAL([TARGET_CPU_POWERPC], test $TARGET_CPU = powerpc) + AM_CONDITIONAL([TARGET_CPU_AARCH64], test $TARGET_CPU = aarch64) + AM_CONDITIONAL([TARGET_CPU_SPARC64], test $TARGET_CPU = sparc64) +]) diff --git a/config/always-compiler-options.m4 b/config/always-compiler-options.m4 new file mode 100644 index 000000000000..a84123317989 --- /dev/null +++ b/config/always-compiler-options.m4 @@ -0,0 +1,204 @@ +dnl # +dnl # Enabled -fsanitize=address if supported by gcc. +dnl # +dnl # LDFLAGS needs -fsanitize=address at all times so libraries compiled with +dnl # it will be linked successfully. CFLAGS will vary by binary being built. +dnl # +dnl # The ASAN_OPTIONS environment variable can be used to further control +dnl # the behavior of binaries and libraries build with -fsanitize=address. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_ASAN], [ + AC_MSG_CHECKING([whether to build with -fsanitize=address support]) + AC_ARG_ENABLE([asan], + [AS_HELP_STRING([--enable-asan], + [Enable -fsanitize=address support @<:@default=no@:>@])], + [], + [enable_asan=no]) + + AM_CONDITIONAL([ASAN_ENABLED], [test x$enable_asan = xyes]) + AC_SUBST([ASAN_ENABLED], [$enable_asan]) + AC_MSG_RESULT($enable_asan) + + AS_IF([ test "$enable_asan" = "yes" ], [ + AC_MSG_CHECKING([whether $CC supports -fsanitize=address]) + saved_cflags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -fsanitize=address" + AC_LINK_IFELSE([ + AC_LANG_SOURCE([[ int main() { return 0; } ]]) + ], [ + ASAN_CFLAGS="-fsanitize=address" + ASAN_LDFLAGS="-fsanitize=address" + ASAN_ZFS="_with_asan" + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_ERROR([$CC does not support -fsanitize=address]) + ]) + CFLAGS="$saved_cflags" + ], [ + ASAN_CFLAGS="" + ASAN_LDFLAGS="" + ASAN_ZFS="_without_asan" + ]) + + AC_SUBST([ASAN_CFLAGS]) + AC_SUBST([ASAN_LDFLAGS]) + AC_SUBST([ASAN_ZFS]) +]) + +dnl # +dnl # Check if gcc supports -Wframe-larger-than=<size> option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN], [ + AC_MSG_CHECKING([whether $CC supports -Wframe-larger-than=<size>]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wframe-larger-than=4096" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + FRAME_LARGER_THAN="-Wframe-larger-than=4096" + AC_MSG_RESULT([yes]) + ], [ + FRAME_LARGER_THAN="" + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([FRAME_LARGER_THAN]) +]) + +dnl # +dnl # Check if gcc supports -Wno-format-truncation option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION], [ + AC_MSG_CHECKING([whether $CC supports -Wno-format-truncation]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wno-format-truncation" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + NO_FORMAT_TRUNCATION=-Wno-format-truncation + AC_MSG_RESULT([yes]) + ], [ + NO_FORMAT_TRUNCATION= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([NO_FORMAT_TRUNCATION]) +]) + +dnl # +dnl # Check if gcc supports -Wno-format-truncation option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH], [ + AC_MSG_CHECKING([whether $CC supports -Wno-format-zero-length]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wno-format-zero-length" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + NO_FORMAT_ZERO_LENGTH=-Wno-format-zero-length + AC_MSG_RESULT([yes]) + ], [ + NO_FORMAT_ZERO_LENGTH= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([NO_FORMAT_ZERO_LENGTH]) +]) + + +dnl # +dnl # Check if gcc supports -Wno-bool-compare option. +dnl # +dnl # We actually invoke gcc with the -Wbool-compare option +dnl # and infer the 'no-' version does or doesn't exist based upon +dnl # the results. This is required because when checking any of +dnl # no- prefixed options gcc always returns success. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE], [ + AC_MSG_CHECKING([whether $CC supports -Wno-bool-compare]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wbool-compare" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + NO_BOOL_COMPARE=-Wno-bool-compare + AC_MSG_RESULT([yes]) + ], [ + NO_BOOL_COMPARE= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([NO_BOOL_COMPARE]) +]) + +dnl # +dnl # Check if gcc supports -Wno-unused-but-set-variable option. +dnl # +dnl # We actually invoke gcc with the -Wunused-but-set-variable option +dnl # and infer the 'no-' version does or doesn't exist based upon +dnl # the results. This is required because when checking any of +dnl # no- prefixed options gcc always returns success. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_UNUSED_BUT_SET_VARIABLE], [ + AC_MSG_CHECKING([whether $CC supports -Wno-unused-but-set-variable]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wunused-but-set-variable" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable + AC_MSG_RESULT([yes]) + ], [ + NO_UNUSED_BUT_SET_VARIABLE= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([NO_UNUSED_BUT_SET_VARIABLE]) +]) + +dnl # +dnl # Check if gcc supports -fno-omit-frame-pointer option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_OMIT_FRAME_POINTER], [ + AC_MSG_CHECKING([whether $CC supports -fno-omit-frame-pointer]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -fno-omit-frame-pointer" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + NO_OMIT_FRAME_POINTER=-fno-omit-frame-pointer + AC_MSG_RESULT([yes]) + ], [ + NO_OMIT_FRAME_POINTER= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([NO_OMIT_FRAME_POINTER]) +]) + +dnl # +dnl # Check if cc supports -fno-ipa-sra option. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_NO_IPA_SRA], [ + AC_MSG_CHECKING([whether $CC supports -fno-ipa-sra]) + + saved_flags="$CFLAGS" + CFLAGS="$CFLAGS -Werror -fno-ipa-sra" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [ + NO_IPA_SRA=-fno-ipa-sra + AC_MSG_RESULT([yes]) + ], [ + NO_IPA_SRA= + AC_MSG_RESULT([no]) + ]) + + CFLAGS="$saved_flags" + AC_SUBST([NO_IPA_SRA]) +]) diff --git a/config/always-python.m4 b/config/always-python.m4 new file mode 100644 index 000000000000..c01e631a8f4f --- /dev/null +++ b/config/always-python.m4 @@ -0,0 +1,70 @@ +dnl # +dnl # The majority of the python scripts are written to be compatible +dnl # with Python 2.6 and Python 3.4. Therefore, they may be installed +dnl # and used with either interpreter. This option is intended to +dnl # to provide a method to specify the default system version, and +dnl # set the PYTHON environment variable accordingly. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYTHON], [ + AC_ARG_WITH([python], + AC_HELP_STRING([--with-python[=VERSION]], + [default system python version @<:@default=check@:>@]), + [with_python=$withval], + [with_python=check]) + + AS_CASE([$with_python], + [check], [AC_CHECK_PROGS([PYTHON], [python3 python2], [:])], + [2*], [PYTHON="python${with_python}"], + [*python2*], [PYTHON="${with_python}"], + [3*], [PYTHON="python${with_python}"], + [*python3*], [PYTHON="${with_python}"], + [no], [PYTHON=":"], + [AC_MSG_ERROR([Unknown --with-python value '$with_python'])] + ) + + dnl # + dnl # Minimum supported Python versions for utilities: + dnl # Python 2.6 or Python 3.4 + dnl # + AM_PATH_PYTHON([], [], [:]) + AS_IF([test -z "$PYTHON_VERSION"], [ + PYTHON_VERSION=$(basename $PYTHON | tr -cd 0-9.) + ]) + PYTHON_MINOR=${PYTHON_VERSION#*\.} + + AS_CASE([$PYTHON_VERSION], + [2.*], [ + AS_IF([test $PYTHON_MINOR -lt 6], + [AC_MSG_ERROR("Python >= 2.6 is required")]) + ], + [3.*], [ + AS_IF([test $PYTHON_MINOR -lt 4], + [AC_MSG_ERROR("Python >= 3.4 is required")]) + ], + [:|2|3], [], + [PYTHON_VERSION=3] + ) + + AM_CONDITIONAL([USING_PYTHON], [test "$PYTHON" != :]) + AM_CONDITIONAL([USING_PYTHON_2], [test "x${PYTHON_VERSION%%\.*}" = x2]) + AM_CONDITIONAL([USING_PYTHON_3], [test "x${PYTHON_VERSION%%\.*}" = x3]) + + AM_COND_IF([USING_PYTHON_2], + [AC_SUBST([PYTHON_SHEBANG], [python2])], + [AC_SUBST([PYTHON_SHEBANG], [python3])]) + + dnl # + dnl # Request that packages be built for a specific Python version. + dnl # + AS_IF([test "x$with_python" != xcheck], [ + PYTHON_PKG_VERSION=$(echo $PYTHON_VERSION | tr -d .) + DEFINE_PYTHON_PKG_VERSION='--define "__use_python_pkg_version '${PYTHON_PKG_VERSION}'"' + DEFINE_PYTHON_VERSION='--define "__use_python '${PYTHON}'"' + ], [ + DEFINE_PYTHON_VERSION='' + DEFINE_PYTHON_PKG_VERSION='' + ]) + + AC_SUBST(DEFINE_PYTHON_VERSION) + AC_SUBST(DEFINE_PYTHON_PKG_VERSION) +]) diff --git a/config/always-pyzfs.m4 b/config/always-pyzfs.m4 new file mode 100644 index 000000000000..f620a8f9a18b --- /dev/null +++ b/config/always-pyzfs.m4 @@ -0,0 +1,105 @@ +dnl # +dnl # ZFS_AC_PYTHON_MODULE(module_name, [action-if-true], [action-if-false]) +dnl # +dnl # Checks for Python module. Freely inspired by AX_PYTHON_MODULE +dnl # https://www.gnu.org/software/autoconf-archive/ax_python_module.html +dnl # Required by ZFS_AC_CONFIG_ALWAYS_PYZFS. +dnl # +AC_DEFUN([ZFS_AC_PYTHON_MODULE], [ + PYTHON_NAME=$(basename $PYTHON) + AC_MSG_CHECKING([for $PYTHON_NAME module: $1]) + AS_IF([$PYTHON -c "import $1" 2>/dev/null], [ + AC_MSG_RESULT(yes) + m4_ifvaln([$2], [$2]) + ], [ + AC_MSG_RESULT(no) + m4_ifvaln([$3], [$3]) + ]) +]) + +dnl # +dnl # Determines if pyzfs can be built, requires Python 2.7 or later. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_PYZFS], [ + AC_ARG_ENABLE([pyzfs], + AC_HELP_STRING([--enable-pyzfs], + [install libzfs_core python bindings @<:@default=check@:>@]), + [enable_pyzfs=$enableval], + [enable_pyzfs=check]) + + dnl # + dnl # Packages for pyzfs specifically enabled/disabled. + dnl # + AS_IF([test "x$enable_pyzfs" != xcheck], [ + AS_IF([test "x$enable_pyzfs" = xyes], [ + DEFINE_PYZFS='--with pyzfs' + ], [ + DEFINE_PYZFS='--without pyzfs' + ]) + ], [ + AS_IF([test "$PYTHON" != :], [ + DEFINE_PYZFS='' + ], [ + enable_pyzfs=no + DEFINE_PYZFS='--without pyzfs' + ]) + ]) + AC_SUBST(DEFINE_PYZFS) + + dnl # + dnl # Require python-devel libraries + dnl # + AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [ + AS_CASE([$PYTHON_VERSION], + [3.*], [PYTHON_REQUIRED_VERSION=">= '3.4.0'"], + [2.*], [PYTHON_REQUIRED_VERSION=">= '2.7.0'"], + [AC_MSG_ERROR("Python $PYTHON_VERSION unknown")] + ) + + AX_PYTHON_DEVEL([$PYTHON_REQUIRED_VERSION], [ + AS_IF([test "x$enable_pyzfs" = xyes], [ + AC_MSG_ERROR("Python $PYTHON_REQUIRED_VERSION development library is not installed") + ], [test "x$enable_pyzfs" != xno], [ + enable_pyzfs=no + ]) + ]) + ]) + + dnl # + dnl # Python "setuptools" module is required to build and install pyzfs + dnl # + AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [ + ZFS_AC_PYTHON_MODULE([setuptools], [], [ + AS_IF([test "x$enable_pyzfs" = xyes], [ + AC_MSG_ERROR("Python $PYTHON_VERSION setuptools is not installed") + ], [test "x$enable_pyzfs" != xno], [ + enable_pyzfs=no + ]) + ]) + ]) + + dnl # + dnl # Python "cffi" module is required to run pyzfs + dnl # + AS_IF([test "x$enable_pyzfs" = xcheck -o "x$enable_pyzfs" = xyes], [ + ZFS_AC_PYTHON_MODULE([cffi], [], [ + AS_IF([test "x$enable_pyzfs" = xyes], [ + AC_MSG_ERROR("Python $PYTHON_VERSION cffi is not installed") + ], [test "x$enable_pyzfs" != xno], [ + enable_pyzfs=no + ]) + ]) + ]) + + dnl # + dnl # Set enable_pyzfs to 'yes' if every check passed + dnl # + AS_IF([test "x$enable_pyzfs" = xcheck], [enable_pyzfs=yes]) + + AM_CONDITIONAL([PYZFS_ENABLED], [test "x$enable_pyzfs" = xyes]) + AC_SUBST([PYZFS_ENABLED], [$enable_pyzfs]) + AC_SUBST(pythonsitedir, [$PYTHON_SITE_PKG]) + + AC_MSG_CHECKING([whether to enable pyzfs: ]) + AC_MSG_RESULT($enable_pyzfs) +]) diff --git a/config/always-sed.m4 b/config/always-sed.m4 new file mode 100644 index 000000000000..19633e118aed --- /dev/null +++ b/config/always-sed.m4 @@ -0,0 +1,16 @@ +dnl # +dnl # Set the flags used for sed in-place edits. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_SED], [ + AC_REQUIRE([AC_PROG_SED])dnl + AC_CACHE_CHECK([for sed --in-place], [ac_cv_inplace], [ + tmpfile=$(mktemp conftest.XXX) + echo foo >$tmpfile + AS_IF([$SED --in-place 's#foo#bar#' $tmpfile 2>/dev/null], + [ac_cv_inplace="--in-place"], + [$SED -i '' 's#foo#bar#' $tmpfile 2>/dev/null], + [ac_cv_inplace="-i ''"], + [AC_MSG_ERROR([$SED does not support in-place])]) + ]) + AC_SUBST([ac_inplace], [$ac_cv_inplace]) +]) diff --git a/config/always-system.m4 b/config/always-system.m4 new file mode 100644 index 000000000000..3225a52af8ae --- /dev/null +++ b/config/always-system.m4 @@ -0,0 +1,26 @@ +dnl # +dnl # Set the target system +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_SYSTEM], [ + AC_MSG_CHECKING([for system type ($host_os)]) + case $host_os in + *linux*) + AC_DEFINE([SYSTEM_LINUX], [1], + [True if ZFS is to be compiled for a Linux system]) + ac_system="Linux" + ;; + *freebsd*) + AC_DEFINE([SYSTEM_FREEBSD], [1], + [True if ZFS is to be compiled for a FreeBSD system]) + ac_system="FreeBSD" + ;; + *) + ac_system="unknown" + ;; + esac + AC_MSG_RESULT([$ac_system]) + AC_SUBST([ac_system]) + + AM_CONDITIONAL([BUILD_LINUX], [test "x$ac_system" = "xLinux"]) + AM_CONDITIONAL([BUILD_FREEBSD], [test "x$ac_system" = "xFreeBSD"]) +]) diff --git a/config/ax_code_coverage.m4 b/config/ax_code_coverage.m4 new file mode 100644 index 000000000000..3e3c666f3c54 --- /dev/null +++ b/config/ax_code_coverage.m4 @@ -0,0 +1,268 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CODE_COVERAGE() +# +# DESCRIPTION +# +# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, +# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included +# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every +# build target (program or library) which should be built with code +# coverage support. Also defines CODE_COVERAGE_RULES which should be +# substituted in your Makefile; and $enable_code_coverage which can be +# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined +# and substituted, and corresponds to the value of the +# --enable-code-coverage option, which defaults to being disabled. +# +# Test also for gcov program and create GCOV variable that could be +# substituted. +# +# Note that all optimization flags in CFLAGS must be disabled when code +# coverage is enabled. +# +# Usage example: +# +# configure.ac: +# +# AX_CODE_COVERAGE +# +# Makefile.am: +# +# @CODE_COVERAGE_RULES@ +# my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ... +# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... +# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... +# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... +# +# This results in a "check-code-coverage" rule being added to any +# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module +# has been configured with --enable-code-coverage). Running `make +# check-code-coverage` in that directory will run the module's test suite +# (`make check`) and build a code coverage report detailing the code which +# was touched, then print the URI for the report. +# +# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined +# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of +# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is +# deprecated. They have the same value. +# +# This code was derived from Makefile.decl in GLib, originally licensed +# under LGPLv2.1+. +# +# LICENSE +# +# Copyright (c) 2012, 2016 Philip Withnall +# Copyright (c) 2012 Xan Lopez +# Copyright (c) 2012 Christian Persch +# Copyright (c) 2012 Paolo Borelli +# Copyright (c) 2012 Dan Winship +# Copyright (c) 2015 Bastien ROUCARIES +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or (at +# your option) any later version. +# +# This library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +#serial 25 + +AC_DEFUN([AX_CODE_COVERAGE],[ + dnl Check for --enable-code-coverage + AC_REQUIRE([AC_PROG_SED]) + + # allow to override gcov location + AC_ARG_WITH([gcov], + [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], + [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], + [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) + + AC_MSG_CHECKING([whether to build with code coverage support]) + AC_ARG_ENABLE([code-coverage], + AS_HELP_STRING([--enable-code-coverage], + [Whether to enable code coverage support]),, + enable_code_coverage=no) + + AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) + AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) + AC_MSG_RESULT($enable_code_coverage) + + AS_IF([ test "$enable_code_coverage" = "yes" ], [ + # check for gcov + AC_CHECK_TOOL([GCOV], + [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], + [:]) + AS_IF([test "X$GCOV" = "X:"], + [AC_MSG_ERROR([gcov is needed to do coverage])]) + AC_SUBST([GCOV]) + + dnl Check if gcc is being used + AS_IF([ test "$GCC" = "no" ], [ + AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) + ]) + + AC_CHECK_PROG([LCOV], [lcov], [lcov]) + AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) + + AS_IF([ test -z "$LCOV" ], [ + AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed]) + ]) + + AS_IF([ test -z "$GENHTML" ], [ + AC_MSG_ERROR([Could not find genhtml from the lcov package]) + ]) + + dnl Build the code coverage flags + dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility + CODE_COVERAGE_CPPFLAGS="" + CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_LIBS="-lgcov" + CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" + + AC_SUBST([CODE_COVERAGE_CPPFLAGS]) + AC_SUBST([CODE_COVERAGE_CFLAGS]) + AC_SUBST([CODE_COVERAGE_CXXFLAGS]) + AC_SUBST([CODE_COVERAGE_LIBS]) + AC_SUBST([CODE_COVERAGE_LDFLAGS]) + + [CODE_COVERAGE_RULES_CHECK=' + -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check + $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +'] + [CODE_COVERAGE_RULES_CAPTURE=' + $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) + $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) + -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp + $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) + @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" +'] + [CODE_COVERAGE_RULES_CLEAN=' +clean: code-coverage-clean +distclean: code-coverage-clean +code-coverage-clean: + -$(LCOV) --directory $(top_builddir) -z + -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) + -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete +'] + ], [ + [CODE_COVERAGE_RULES_CHECK=' + @echo "Need to reconfigure with --enable-code-coverage" +'] + CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" + CODE_COVERAGE_RULES_CLEAN='' + ]) + +[CODE_COVERAGE_RULES=' +# Code coverage +# +# Optional: +# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. +# Multiple directories may be specified, separated by whitespace. +# (Default: $(top_builddir)) +# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated +# by lcov for code coverage. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) +# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage +# reports to be created. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) +# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, +# set to 0 to disable it and leave empty to stay with the default. +# (Default: empty) +# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov +# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov +# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov +# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the +# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov +# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering +# lcov instance. (Default: empty) +# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov +# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the +# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml +# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) +# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore +# +# The generated report will be titled using the $(PACKAGE_NAME) and +# $(PACKAGE_VERSION). In order to add the current git hash to the title, +# use the git-version-gen script, available online. + +# Optional variables +CODE_COVERAGE_DIRECTORY ?= $(top_builddir) +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage +CODE_COVERAGE_BRANCH_COVERAGE ?= +CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" +CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= +CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ +$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) + +# Add any folders you want to ignore here +# Ignore tmp and tests themselves +CODE_COVERAGE_IGNORE_PATTERN ?= "/tmp/*" "*/tests/*" +CODE_COVERAGE_IGNORE_PATTERN += "*/module/zstd/lib/*" + +GITIGNOREFILES ?= +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) + +code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) +code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ + $(CODE_COVERAGE_OUTPUT_FILE); +code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) +code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ + $(CODE_COVERAGE_IGNORE_PATTERN); +code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) +code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); +code_coverage_quiet = $(code_coverage_quiet_$(V)) +code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +code_coverage_quiet_0 = --quiet + +# sanitizes the test-name: replaces with underscores: dashes and dots +code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) + +# Use recursive makes in order to ignore errors during check +check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' + +# Capture code coverage data +code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' + +# Hook rule executed before code-coverage-capture, overridable by the user +code-coverage-capture-hook: + +'"$CODE_COVERAGE_RULES_CLEAN"' + +A''M_DISTCHECK_CONFIGURE_FLAGS ?= +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage + +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean +'] + + AC_SUBST([CODE_COVERAGE_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) +]) diff --git a/config/ax_python_devel.m4 b/config/ax_python_devel.m4 new file mode 100644 index 000000000000..c51b45b7d54d --- /dev/null +++ b/config/ax_python_devel.m4 @@ -0,0 +1,345 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_python_devel.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PYTHON_DEVEL([version], [action-if-not-found]) +# +# DESCRIPTION +# +# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it +# in your configure.ac. +# +# Note: this is a slightly modified version of the original AX_PYTHON_DEVEL +# macro which accepts an additional [action-if-not-found] argument. This +# allow to detect if Python development is available without aborting the +# configure phase with an hard error in case it is not. +# +# This macro checks for Python and tries to get the include path to +# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output +# variables. It also exports $(PYTHON_EXTRA_LIBS) and +# $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code. +# +# You can search for some particular version of Python by passing a +# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please +# note that you *have* to pass also an operator along with the version to +# match, and pay special attention to the single quotes surrounding the +# version number. Don't use "PYTHON_VERSION" for this: that environment +# variable is declared as precious and thus reserved for the end-user. +# +# This macro should work for all versions of Python >= 2.1.0. As an end +# user, you can disable the check for the python version by setting the +# PYTHON_NOVERSIONCHECK environment variable to something else than the +# empty string. +# +# If you need to use this macro for an older Python version, please +# contact the authors. We're always open for feedback. +# +# LICENSE +# +# Copyright (c) 2009 Sebastian Huber <sebastian-huber@web.de> +# Copyright (c) 2009 Alan W. Irwin +# Copyright (c) 2009 Rafael Laboissiere <rafael@laboissiere.net> +# Copyright (c) 2009 Andrew Collier +# Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org> +# Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org> +# Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu> +# Copyright (c) 2018 loli10K <ezomori.nozomu@gmail.com> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 21 + +AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL]) +AC_DEFUN([AX_PYTHON_DEVEL],[ + # + # Allow the use of a (user set) custom python version + # + AC_ARG_VAR([PYTHON_VERSION],[The installed Python + version to use, for example '2.3'. This string + will be appended to the Python interpreter + canonical name.]) + + AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) + if test -z "$PYTHON"; then + m4_ifvaln([$2],[$2],[ + AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path]) + PYTHON_VERSION="" + ]) + fi + + # + # Check for a version of Python >= 2.1.0 + # + AC_MSG_CHECKING([for a version of Python >= '2.1.0']) + ac_supports_python_ver=`$PYTHON -c "import sys; \ + ver = sys.version.split ()[[0]]; \ + print (ver >= '2.1.0')"` + if test "$ac_supports_python_ver" != "True"; then + if test -z "$PYTHON_NOVERSIONCHECK"; then + AC_MSG_RESULT([no]) + m4_ifvaln([$2],[$2],[ + AC_MSG_FAILURE([ +This version of the AC@&t@_PYTHON_DEVEL macro +doesn't work properly with versions of Python before +2.1.0. You may need to re-run configure, setting the +variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG, +PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. +Moreover, to disable this check, set PYTHON_NOVERSIONCHECK +to something else than an empty string. +]) + ]) + else + AC_MSG_RESULT([skip at user request]) + fi + else + AC_MSG_RESULT([yes]) + fi + + # + # if the macro parameter ``version'' is set, honour it + # + if test -n "$1"; then + AC_MSG_CHECKING([for a version of Python $1]) + ac_supports_python_ver=`$PYTHON -c "import sys; \ + ver = sys.version.split ()[[0]]; \ + print (ver $1)"` + if test "$ac_supports_python_ver" = "True"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + m4_ifvaln([$2],[$2],[ + AC_MSG_ERROR([this package requires Python $1. +If you have it installed, but it isn't the default Python +interpreter in your system path, please pass the PYTHON_VERSION +variable to configure. See ``configure --help'' for reference. +]) + PYTHON_VERSION="" + ]) + fi + fi + + # + # Check if you have distutils, else fail + # + AC_MSG_CHECKING([for the distutils Python package]) + ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` + if test $? -eq 0; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + m4_ifvaln([$2],[$2],[ + AC_MSG_ERROR([cannot import Python module "distutils". +Please check your Python installation. The error was: +$ac_distutils_result]) + PYTHON_VERSION="" + ]) + fi + + # + # Check for Python include path + # + AC_MSG_CHECKING([for Python include path]) + if test -z "$PYTHON_CPPFLAGS"; then + python_path=`$PYTHON -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_python_inc ());"` + plat_python_path=`$PYTHON -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_python_inc (plat_specific=1));"` + if test -n "${python_path}"; then + if test "${plat_python_path}" != "${python_path}"; then + python_path="-I$python_path -I$plat_python_path" + else + python_path="-I$python_path" + fi + fi + PYTHON_CPPFLAGS=$python_path + fi + AC_MSG_RESULT([$PYTHON_CPPFLAGS]) + AC_SUBST([PYTHON_CPPFLAGS]) + + # + # Check for Python library path + # + AC_MSG_CHECKING([for Python library path]) + if test -z "$PYTHON_LIBS"; then + # (makes two attempts to ensure we've got a version number + # from the interpreter) + ac_python_version=`cat<<EOD | $PYTHON - + +# join all versioning strings, on some systems +# major/minor numbers could be in different list elements +from distutils.sysconfig import * +e = get_config_var('VERSION') +if e is not None: + print(e) +EOD` + + if test -z "$ac_python_version"; then + if test -n "$PYTHON_VERSION"; then + ac_python_version=$PYTHON_VERSION + else + ac_python_version=`$PYTHON -c "import sys; \ + print (sys.version[[:3]])"` + fi + fi + + # Make the versioning information available to the compiler + AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"], + [If available, contains the Python version number currently in use.]) + + # First, the library directory: + ac_python_libdir=`cat<<EOD | $PYTHON - + +# There should be only one +import distutils.sysconfig +e = distutils.sysconfig.get_config_var('LIBDIR') +if e is not None: + print (e) +EOD` + + # Now, for the library: + ac_python_library=`cat<<EOD | $PYTHON - + +import distutils.sysconfig +c = distutils.sysconfig.get_config_vars() +if 'LDVERSION' in c: + print ('python'+c[['LDVERSION']]) +else: + print ('python'+c[['VERSION']]) +EOD` + + # This small piece shamelessly adapted from PostgreSQL python macro; + # credits goes to momjian, I think. I'd like to put the right name + # in the credits, if someone can point me in the right direction... ? + # + if test -n "$ac_python_libdir" -a -n "$ac_python_library" + then + # use the official shared library + ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"` + PYTHON_LIBS="-L$ac_python_libdir -l$ac_python_library" + else + # old way: use libpython from python_configdir + ac_python_libdir=`$PYTHON -c \ + "from distutils.sysconfig import get_python_lib as f; \ + import os; \ + print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"` + PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version" + fi + + if test -z "PYTHON_LIBS"; then + m4_ifvaln([$2],[$2],[ + AC_MSG_ERROR([ + Cannot determine location of your Python DSO. Please check it was installed with + dynamic libraries enabled, or try setting PYTHON_LIBS by hand. + ]) + ]) + fi + fi + AC_MSG_RESULT([$PYTHON_LIBS]) + AC_SUBST([PYTHON_LIBS]) + + # + # Check for site packages + # + AC_MSG_CHECKING([for Python site-packages path]) + if test -z "$PYTHON_SITE_PKG"; then + PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_python_lib(0,0));"` + fi + AC_MSG_RESULT([$PYTHON_SITE_PKG]) + AC_SUBST([PYTHON_SITE_PKG]) + + # + # libraries which must be linked in when embedding + # + AC_MSG_CHECKING(python extra libraries) + if test -z "$PYTHON_EXTRA_LIBS"; then + PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print (conf('LIBS') + ' ' + conf('SYSLIBS'))"` + fi + AC_MSG_RESULT([$PYTHON_EXTRA_LIBS]) + AC_SUBST(PYTHON_EXTRA_LIBS) + + # + # linking flags needed when embedding + # + AC_MSG_CHECKING(python extra linking flags) + if test -z "$PYTHON_EXTRA_LDFLAGS"; then + PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print (conf('LINKFORSHARED'))"` + fi + AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS]) + AC_SUBST(PYTHON_EXTRA_LDFLAGS) + + # + # final check to see if everything compiles alright + # + AC_MSG_CHECKING([consistency of all components of python development environment]) + # save current global flags + ac_save_LIBS="$LIBS" + ac_save_LDFLAGS="$LDFLAGS" + ac_save_CPPFLAGS="$CPPFLAGS" + LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS" + LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS" + CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS" + AC_LANG_PUSH([C]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[#include <Python.h>]], + [[Py_Initialize();]]) + ],[pythonexists=yes],[pythonexists=no]) + AC_LANG_POP([C]) + # turn back to default flags + CPPFLAGS="$ac_save_CPPFLAGS" + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + + AC_MSG_RESULT([$pythonexists]) + + if test ! "x$pythonexists" = "xyes"; then + m4_ifvaln([$2],[$2],[ + AC_MSG_FAILURE([ + Could not link test program to Python. Maybe the main Python library has been + installed in some non-standard library path. If so, pass it to configure, + via the LIBS environment variable. + Example: ./configure LIBS="-L/usr/non-standard-path/python/lib" + ============================================================================ + ERROR! + You probably have to install the development version of the Python package + for your distribution. The exact name of this package varies among them. + ============================================================================ + ]) + PYTHON_VERSION="" + ]) + fi + + # + # all done! + # +]) diff --git a/config/ax_restore_flags.m4 b/config/ax_restore_flags.m4 new file mode 100644 index 000000000000..cf03cae79015 --- /dev/null +++ b/config/ax_restore_flags.m4 @@ -0,0 +1,31 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_restore_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_RESTORE_FLAGS() +# +# DESCRIPTION +# +# Restore common compilation flags from temporary variables +# +# LICENSE +# +# Copyright (c) 2009 Filippo Giunchedi <filippo@esaurito.net> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AC_DEFUN([AX_RESTORE_FLAGS], [ + CPPFLAGS="${CPPFLAGS_save}" + CFLAGS="${CFLAGS_save}" + CXXFLAGS="${CXXFLAGS_save}" + OBJCFLAGS="${OBJCFLAGS_save}" + LDFLAGS="${LDFLAGS_save}" + LIBS="${LIBS_save}" +]) diff --git a/config/ax_save_flags.m4 b/config/ax_save_flags.m4 new file mode 100644 index 000000000000..d2a054223b91 --- /dev/null +++ b/config/ax_save_flags.m4 @@ -0,0 +1,31 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_save_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_SAVE_FLAGS() +# +# DESCRIPTION +# +# Save common compilation flags into temporary variables +# +# LICENSE +# +# Copyright (c) 2009 Filippo Giunchedi <filippo@esaurito.net> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AC_DEFUN([AX_SAVE_FLAGS], [ + CPPFLAGS_save="${CPPFLAGS}" + CFLAGS_save="${CFLAGS}" + CXXFLAGS_save="${CXXFLAGS}" + OBJCFLAGS_save="${OBJCFLAGS}" + LDFLAGS_save="${LDFLAGS}" + LIBS_save="${LIBS}" +]) diff --git a/config/config.awk b/config/config.awk new file mode 100644 index 000000000000..cc4b7cc265cd --- /dev/null +++ b/config/config.awk @@ -0,0 +1,15 @@ +# Remove default preprocessor define's from config.h +# PACKAGE +# PACKAGE_BUGREPORT +# PACKAGE_NAME +# PACKAGE_STRING +# PACKAGE_TARNAME +# PACKAGE_VERSION +# STDC_HEADERS +# VERSION + +BEGIN { RS = "" ; FS = "\n" } \ + !/.#define PACKAGE./ && \ + !/.#define VERSION./ && \ + !/.#define STDC_HEADERS./ \ + { print $0"\n" } diff --git a/config/config.rpath b/config/config.rpath new file mode 100755 index 000000000000..be202c1a9e79 --- /dev/null +++ b/config/config.rpath @@ -0,0 +1,684 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2019 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + nagfor*) + wl='-Wl,-Wl,,' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + xl* | bgxl* | bgf* | mpixl*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + wl= + ;; + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + newsos6) + ;; + *nto* | *qnx*) + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + wl='-Qoption ld ' + ;; + *) + wl='-Wl,' + ;; + esac + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + haiku*) + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + : + else + ld_shlibs=no + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd2.[01]*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + *nto* | *qnx*) + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + case "$host_cpu" in + powerpc*) + library_names_spec='$libname$shrext' ;; + m68k) + library_names_spec='$libname.a' ;; + esac + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd[23].*) + library_names_spec='$libname$shrext$versuffix' + ;; + freebsd* | dragonfly*) + library_names_spec='$libname$shrext' + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + haiku*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + *nto* | *qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + tpf*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF + +# How to pass a linker flag through the compiler. +wl="$escaped_wl" + +# Static library suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally "so"). +shlibext="$shlibext" + +# Format of library name prefix. +libname_spec="$escaped_libname_spec" + +# Library names that the linker finds when passed -lNAME. +library_names_spec="$escaped_library_names_spec" + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="$hardcode_libdir_separator" + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct="$hardcode_direct" + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L="$hardcode_minus_L" + +EOF diff --git a/config/deb.am b/config/deb.am new file mode 100644 index 000000000000..88679545a594 --- /dev/null +++ b/config/deb.am @@ -0,0 +1,74 @@ +PHONY += deb-kmod deb-dkms deb-utils deb deb-local + +deb-local: + @(if test "${HAVE_DPKGBUILD}" = "no"; then \ + echo -e "\n" \ + "*** Required util ${DPKGBUILD} missing. Please install the\n" \ + "*** package for your distribution which provides ${DPKGBUILD},\n" \ + "*** re-run configure, and try again.\n"; \ + exit 1; \ + fi; \ + if test "${HAVE_ALIEN}" = "no"; then \ + echo -e "\n" \ + "*** Required util ${ALIEN} missing. Please install the\n" \ + "*** package for your distribution which provides ${ALIEN},\n" \ + "*** re-run configure, and try again.\n"; \ + exit 1; \ + fi) + +deb-kmod: deb-local rpm-kmod + name=${PACKAGE}; \ + version=${VERSION}-${RELEASE}; \ + arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \ + debarch=`$(DPKG) --print-architecture`; \ + pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \ + fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1 || exit 1; \ + $(RM) $$pkg1 + + +deb-dkms: deb-local rpm-dkms + name=${PACKAGE}; \ + version=${VERSION}-${RELEASE}; \ + arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \ + debarch=`$(DPKG) --print-architecture`; \ + pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \ + fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1 || exit 1; \ + $(RM) $$pkg1 + +deb-utils: deb-local rpm-utils + name=${PACKAGE}; \ + version=${VERSION}-${RELEASE}; \ + arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \ + debarch=`$(DPKG) --print-architecture`; \ + pkg1=$${name}-$${version}.$${arch}.rpm; \ + pkg2=libnvpair1-$${version}.$${arch}.rpm; \ + pkg3=libuutil1-$${version}.$${arch}.rpm; \ + pkg4=libzfs2-$${version}.$${arch}.rpm; \ + pkg5=libzpool2-$${version}.$${arch}.rpm; \ + pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \ + pkg7=$${name}-test-$${version}.$${arch}.rpm; \ + pkg8=$${name}-dracut-$${version}.noarch.rpm; \ + pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \ + pkg10=`ls python*-pyzfs-$${version}* | tail -1`; \ +## Arguments need to be passed to dh_shlibdeps. Alien provides no mechanism +## to do this, so we install a shim onto the path which calls the real +## dh_shlibdeps with the required arguments. + path_prepend=`mktemp -d /tmp/intercept.XXX`; \ + echo "#$(SHELL)" > $${path_prepend}/dh_shlibdeps; \ + echo "`which dh_shlibdeps` -- \ + -xlibuutil1linux -xlibnvpair1linux -xlibzfs2linux -xlibzpool2linux" \ + >> $${path_prepend}/dh_shlibdeps; \ +## These -x arguments are passed to dpkg-shlibdeps, which exclude the +## Debianized packages from the auto-generated dependencies of the new debs, +## which should NOT be mixed with the alien-generated debs created here + chmod +x $${path_prepend}/dh_shlibdeps; \ + env PATH=$${path_prepend}:$${PATH} \ + fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \ + $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \ + $$pkg8 $$pkg9 $$pkg10 || exit 1; \ + $(RM) $${path_prepend}/dh_shlibdeps; \ + rmdir $${path_prepend}; \ + $(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \ + $$pkg8 $$pkg9 $$pkg10; + +deb: deb-kmod deb-dkms deb-utils diff --git a/config/find_system_library.m4 b/config/find_system_library.m4 new file mode 100644 index 000000000000..9a95d6a15033 --- /dev/null +++ b/config/find_system_library.m4 @@ -0,0 +1,93 @@ +# find_system_lib.m4 - Macros to search for a system library. -*- Autoconf -*- + +dnl requires pkg.m4 from pkg-config +dnl requires ax_save_flags.m4 from autoconf-archive +dnl requires ax_restore_flags.m4 from autoconf-archive + +dnl ZFS_AC_FIND_SYSTEM_LIBRARY(VARIABLE-PREFIX, MODULE, HEADER, HEADER-PREFIXES, LIBRARY, FUNCTIONS, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) + +AC_DEFUN([ZFS_AC_FIND_SYSTEM_LIBRARY], [ + AC_REQUIRE([PKG_PROG_PKG_CONFIG]) + + _header_found= + _library_found= + + AS_IF([test -n "$2"], [PKG_CHECK_MODULES([$1], [$2], [ + _header_found=1 + _library_found=1 + ], [:])]) + + # set _header_found/_library_found if the user passed in CFLAGS/LIBS + AS_IF([test "x$[$1][_CFLAGS]" != x], [_header_found=1]) + AS_IF([test "x$[$1][_LIBS]" != x], [_library_found=1]) + + AX_SAVE_FLAGS + + orig_CFLAGS="$CFLAGS" + + for _prefixdir in /usr /usr/local + do + AS_VAR_PUSHDEF([header_cache], [ac_cv_header_$3]) + AS_IF([test "x$_prefixdir" != "x/usr"], [ + [$1][_CFLAGS]="-I$lt_sysroot$_prefixdir/include" + AS_IF([test "x$_library_found" = x], [ + [$1][_LIBS]="-L$lt_sysroot$_prefixdir/lib" + ]) + ]) + CFLAGS="$orig_CFLAGS $[$1][_CFLAGS]" + AS_UNSET([header_cache]) + AC_CHECK_HEADER([$3], [ + _header_found=1 + break + ], [AS_IF([test "x$_header_found" = "x1"], [ + # if pkg-config or the user set CFLAGS, fail if the header is unusable + AC_MSG_FAILURE([header [$3] for library [$5] is not usable]) + ])], [AC_INCLUDES_DEFAULT]) + # search for header under HEADER-PREFIXES + m4_foreach_w([prefix], [$4], [ + [$1][_CFLAGS]=["-I$lt_sysroot$_prefixdir/include/]prefix["] + CFLAGS="$orig_CFLAGS $[$1][_CFLAGS]" + AS_UNSET([header_cache]) + AC_CHECK_HEADER([$3], [ + _header_found=1 + break + ], [], [AC_INCLUDES_DEFAULT]) + ]) + AS_VAR_POPDEF([header_cache]) + done + + AS_IF([test "x$_header_found" = "x1"], [ + AS_IF([test "x$_library_found" = x], [ + [$1][_LIBS]="$[$1]_LIBS -l[$5]" + ]) + LDFLAGS="$LDFLAGS $[$1][_LIBS]" + + _libcheck=1 + m4_ifval([$6], + [m4_foreach_w([func], [$6], [AC_CHECK_LIB([$5], func, [:], [_libcheck=])])], + [AC_CHECK_LIB([$5], [main], [:], [_libcheck=])]) + + AS_IF([test "x$_libcheck" = "x1"], [_library_found=1], + [test "x$_library_found" = "x1"], [ + # if pkg-config or the user set LIBS, fail if the library is unusable + AC_MSG_FAILURE([library [$5] is not usable]) + ]) + ], [test "x$_library_found" = "x1"], [ + # if the user set LIBS, fail if we didn't find the header + AC_MSG_FAILURE([cannot find header [$3] for library [$5]]) + ]) + + AX_RESTORE_FLAGS + + AS_IF([test "x$_header_found" = "x1" && test "x$_library_found" = "x1"], [ + AC_SUBST([$1]_CFLAGS) + AC_SUBST([$1]_LIBS) + AC_DEFINE([HAVE_][$1], [1], [Define if you have [$5]]) + $7 + ],[dnl ELSE + AC_SUBST([$1]_CFLAGS, []) + AC_SUBST([$1]_LIBS, []) + AC_MSG_WARN([cannot find [$5] via pkg-config or in the standard locations]) + $8 + ]) +]) diff --git a/config/gettext.m4 b/config/gettext.m4 new file mode 100644 index 000000000000..e7832418ea16 --- /dev/null +++ b/config/gettext.m4 @@ -0,0 +1,386 @@ +# gettext.m4 serial 70 (gettext-0.20) +dnl Copyright (C) 1995-2014, 2016, 2018 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2006, 2008-2010. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL must be one of 'external', 'use-libtool'. +dnl INTLSYMBOL should be 'external' for packages other than GNU gettext, and +dnl 'use-libtool' for the packages 'gettext-runtime' and 'gettext-tools'. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value '$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])]) + ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old], + [errprint([ERROR: Use of AM_GNU_GETTEXT without [external] argument is no longer supported. +])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define([gt_included_intl], + ifelse([$1], [external], [no], [yes])) + gt_NEEDS_INIT + AM_GNU_GETTEXT_NEED([$2]) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is not documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation. + gt_INTL_MACOSX + + dnl Set USE_NLS. + AC_REQUIRE([AM_NLS]) + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl Add a version number to the cache macros. + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH([included-gettext], + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext]) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [eval "$gt_func_gnugettext_libc=yes"], + [eval "$gt_func_gnugettext_libc=no"])]) + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + [$gt_func_gnugettext_libintl], + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [eval "$gt_func_gnugettext_libintl=yes"], + [eval "$gt_func_gnugettext_libintl=no"]) + dnl Now see whether libintl exists and depends on libiconv. + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + ]])], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LIBICONV $LIBTHREAD" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.la $LTLIBICONV $LTLIBTHREAD" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + CATOBJEXT= + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Some extra flags are needed during linking. + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE([ENABLE_NLS], [1], + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + AC_MSG_CHECKING([whether to use NLS]) + AC_MSG_RESULT([$USE_NLS]) + if test "$USE_NLS" = "yes"; then + AC_MSG_CHECKING([where the gettext function comes from]) + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + AC_MSG_RESULT([$gt_source]) + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE([HAVE_GETTEXT], [1], + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE([HAVE_DCGETTEXT], [1], + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl In GNU gettext we have to set BUILD_INCLUDED_LIBINTL to 'yes' + dnl because some of the testsuite requires it. + BUILD_INCLUDED_LIBINTL=yes + + dnl Make all variables we use known to autoconf. + AC_SUBST([BUILD_INCLUDED_LIBINTL]) + AC_SUBST([USE_INCLUDED_LIBINTL]) + AC_SUBST([CATOBJEXT]) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST([INTLLIBS]) + + dnl Make all documented variables known to autoconf. + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + AC_SUBST([POSUB]) +]) + + +dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. +m4_define([gt_NEEDS_INIT], +[ + m4_divert_text([DEFAULTS], [gt_needs=]) + m4_define([gt_NEEDS_INIT], []) +]) + + +dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) +AC_DEFUN([AM_GNU_GETTEXT_NEED], +[ + m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) + + +dnl Usage: AM_GNU_GETTEXT_REQUIRE_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_REQUIRE_VERSION], []) diff --git a/config/host-cpu-c-abi.m4 b/config/host-cpu-c-abi.m4 new file mode 100644 index 000000000000..4407296d0849 --- /dev/null +++ b/config/host-cpu-c-abi.m4 @@ -0,0 +1,644 @@ +# host-cpu-c-abi.m4 serial 11 +dnl Copyright (C) 2002-2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible and Sam Steingold. + +dnl Sets the HOST_CPU variable to the canonical name of the CPU. +dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its +dnl C language ABI (application binary interface). +dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in +dnl config.h. +dnl +dnl This canonical name can be used to select a particular assembly language +dnl source file that will interoperate with C code on the given host. +dnl +dnl For example: +dnl * 'i386' and 'sparc' are different canonical names, because code for i386 +dnl will not run on SPARC CPUs and vice versa. They have different +dnl instruction sets. +dnl * 'sparc' and 'sparc64' are different canonical names, because code for +dnl 'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code +dnl contains 32-bit instructions, whereas 'sparc64' code contains 64-bit +dnl instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit +dnl mode, but not both. +dnl * 'mips' and 'mipsn32' are different canonical names, because they use +dnl different argument passing and return conventions for C functions, and +dnl although the instruction set of 'mips' is a large subset of the +dnl instruction set of 'mipsn32'. +dnl * 'mipsn32' and 'mips64' are different canonical names, because they use +dnl different sizes for the C types like 'int' and 'void *', and although +dnl the instruction sets of 'mipsn32' and 'mips64' are the same. +dnl * The same canonical name is used for different endiannesses. You can +dnl determine the endianness through preprocessor symbols: +dnl - 'arm': test __ARMEL__. +dnl - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL. +dnl - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN. +dnl * The same name 'i386' is used for CPUs of type i386, i486, i586 +dnl (Pentium), AMD K7, Pentium II, Pentium IV, etc., because +dnl - Instructions that do not exist on all of these CPUs (cmpxchg, +dnl MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your +dnl assembly language source files use such instructions, you will +dnl need to make the distinction. +dnl - Speed of execution of the common instruction set is reasonable across +dnl the entire family of CPUs. If you have assembly language source files +dnl that are optimized for particular CPU types (like GNU gmp has), you +dnl will need to make the distinction. +dnl See <https://en.wikipedia.org/wiki/X86_instruction_listings>. +AC_DEFUN([gl_HOST_CPU_C_ABI], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_C_ASM]) + AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi], + [case "$host_cpu" in + +changequote(,)dnl + i[4567]86 ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=i386 + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=x86_64-x32], + [gl_cv_host_cpu_c_abi=x86_64])], + [gl_cv_host_cpu_c_abi=i386]) + ;; + +changequote(,)dnl + alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=alpha + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __aarch64__ + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=arm64-ilp32], + [gl_cv_host_cpu_c_abi=arm64])], + [# Don't distinguish little-endian and big-endian arm, since they + # don't require different machine code for simple operations and + # since the user can distinguish them through the preprocessor + # defines __ARMEL__ vs. __ARMEB__. + # But distinguish arm which passes floating-point arguments and + # return values in integer registers (r0, r1, ...) - this is + # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which + # passes them in float registers (s0, s1, ...) and double registers + # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer + # sets the preprocessor defines __ARM_PCS (for the first case) and + # __ARM_PCS_VFP (for the second case), but older GCC does not. + echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c + # Look for a reference to the register d0 in the .s file. + AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1 + if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then + gl_cv_host_cpu_c_abi=armhf + else + gl_cv_host_cpu_c_abi=arm + fi + rm -f conftest* + ]) + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __LP64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=hppa64], + [gl_cv_host_cpu_c_abi=hppa]) + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=ia64-ilp32], + [gl_cv_host_cpu_c_abi=ia64]) + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mips64], + [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32. + # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (_MIPS_SIM == _ABIN32) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mipsn32], + [gl_cv_host_cpu_c_abi=mips])]) + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + ]])], + [# On powerpc64, there are two ABIs on Linux: The AIX compatible + # one and the ELFv2 one. The latter defines _CALL_ELF=2. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _CALL_ELF && _CALL_ELF == 2 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=powerpc64-elfv2], + [gl_cv_host_cpu_c_abi=powerpc64]) + ], + [gl_cv_host_cpu_c_abi=powerpc]) + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi=powerpc + ;; + + riscv32 | riscv64 ) + # There are 2 architectures (with variants): rv32* and rv64*. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if __riscv_xlen == 64 + int ok; + #else + error fail + #endif + ]])], + [cpu=riscv64], + [cpu=riscv32]) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [main_abi=lp64], + [main_abi=ilp32]) + # Float ABIs: + # __riscv_float_abi_double: + # 'float' and 'double' are passed in floating-point registers. + # __riscv_float_abi_single: + # 'float' are passed in floating-point registers. + # __riscv_float_abi_soft: + # No values are passed in floating-point registers. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_double + int ok; + #else + error fail + #endif + ]])], + [float_abi=d], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_single + int ok; + #else + error fail + #endif + ]])], + [float_abi=f], + [float_abi='']) + ]) + gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}" + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=s390x], + [gl_cv_host_cpu_c_abi=s390]) + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=sparc64], + [gl_cv_host_cpu_c_abi=sparc]) + ;; + + *) + gl_cv_host_cpu_c_abi="$host_cpu" + ;; + esac + ]) + + dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same. + HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'` + HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi" + AC_SUBST([HOST_CPU]) + AC_SUBST([HOST_CPU_C_ABI]) + + # This was + # AC_DEFINE_UNQUOTED([__${HOST_CPU}__]) + # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__]) + # earlier, but KAI C++ 3.2d doesn't like this. + sed -e 's/-/_/g' >> confdefs.h <<EOF +#ifndef __${HOST_CPU}__ +#define __${HOST_CPU}__ 1 +#endif +#ifndef __${HOST_CPU_C_ABI}__ +#define __${HOST_CPU_C_ABI}__ 1 +#endif +EOF + AH_TOP([/* CPU and C ABI indicator */ +#ifndef __i386__ +#undef __i386__ +#endif +#ifndef __x86_64_x32__ +#undef __x86_64_x32__ +#endif +#ifndef __x86_64__ +#undef __x86_64__ +#endif +#ifndef __alpha__ +#undef __alpha__ +#endif +#ifndef __arm__ +#undef __arm__ +#endif +#ifndef __armhf__ +#undef __armhf__ +#endif +#ifndef __arm64_ilp32__ +#undef __arm64_ilp32__ +#endif +#ifndef __arm64__ +#undef __arm64__ +#endif +#ifndef __hppa__ +#undef __hppa__ +#endif +#ifndef __hppa64__ +#undef __hppa64__ +#endif +#ifndef __ia64_ilp32__ +#undef __ia64_ilp32__ +#endif +#ifndef __ia64__ +#undef __ia64__ +#endif +#ifndef __m68k__ +#undef __m68k__ +#endif +#ifndef __mips__ +#undef __mips__ +#endif +#ifndef __mipsn32__ +#undef __mipsn32__ +#endif +#ifndef __mips64__ +#undef __mips64__ +#endif +#ifndef __powerpc__ +#undef __powerpc__ +#endif +#ifndef __powerpc64__ +#undef __powerpc64__ +#endif +#ifndef __powerpc64_elfv2__ +#undef __powerpc64_elfv2__ +#endif +#ifndef __riscv32__ +#undef __riscv32__ +#endif +#ifndef __riscv64__ +#undef __riscv64__ +#endif +#ifndef __riscv32_ilp32__ +#undef __riscv32_ilp32__ +#endif +#ifndef __riscv32_ilp32f__ +#undef __riscv32_ilp32f__ +#endif +#ifndef __riscv32_ilp32d__ +#undef __riscv32_ilp32d__ +#endif +#ifndef __riscv64_ilp32__ +#undef __riscv64_ilp32__ +#endif +#ifndef __riscv64_ilp32f__ +#undef __riscv64_ilp32f__ +#endif +#ifndef __riscv64_ilp32d__ +#undef __riscv64_ilp32d__ +#endif +#ifndef __riscv64_lp64__ +#undef __riscv64_lp64__ +#endif +#ifndef __riscv64_lp64f__ +#undef __riscv64_lp64f__ +#endif +#ifndef __riscv64_lp64d__ +#undef __riscv64_lp64d__ +#endif +#ifndef __s390__ +#undef __s390__ +#endif +#ifndef __s390x__ +#undef __s390x__ +#endif +#ifndef __sh__ +#undef __sh__ +#endif +#ifndef __sparc__ +#undef __sparc__ +#endif +#ifndef __sparc64__ +#undef __sparc64__ +#endif +]) + +]) + + +dnl Sets the HOST_CPU_C_ABI_32BIT variable to 'yes' if the C language ABI +dnl (application binary interface) is a 32-bit one, or to 'no' otherwise. +dnl This is a simplified variant of gl_HOST_CPU_C_ABI. +AC_DEFUN([gl_HOST_CPU_C_ABI_32BIT], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([32-bit host C ABI], [gl_cv_host_cpu_c_abi_32bit], + [if test -n "$gl_cv_host_cpu_c_abi"; then + case "$gl_cv_host_cpu_c_abi" in + i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc) + gl_cv_host_cpu_c_abi_32bit=yes ;; + *) + gl_cv_host_cpu_c_abi_32bit=no ;; + esac + else + case "$host_cpu" in + +changequote(,)dnl + i[4567]86 ) +changequote([,])dnl + gl_cv_host_cpu_c_abi_32bit=yes + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) \ + && !(defined __ILP32__ || defined _ILP32) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=no], + [gl_cv_host_cpu_c_abi_32bit=yes]) + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __aarch64__ && !(defined __ILP32__ || defined _ILP32) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=no], + [gl_cv_host_cpu_c_abi_32bit=yes]) + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __LP64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=no], + [gl_cv_host_cpu_c_abi_32bit=yes]) + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=yes], + [gl_cv_host_cpu_c_abi_32bit=no]) + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=no], + [gl_cv_host_cpu_c_abi_32bit=yes]) + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=no], + [gl_cv_host_cpu_c_abi_32bit=yes]) + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi_32bit=yes + ;; + + riscv32 | riscv64 ) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=no], + [gl_cv_host_cpu_c_abi_32bit=yes]) + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=no], + [gl_cv_host_cpu_c_abi_32bit=yes]) + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi_32bit=no], + [gl_cv_host_cpu_c_abi_32bit=yes]) + ;; + + *) + gl_cv_host_cpu_c_abi_32bit=no + ;; + esac + fi + ]) + + HOST_CPU_C_ABI_32BIT="$gl_cv_host_cpu_c_abi_32bit" +]) diff --git a/config/iconv.m4 b/config/iconv.m4 new file mode 100644 index 000000000000..99b339a9f89e --- /dev/null +++ b/config/iconv.m4 @@ -0,0 +1,287 @@ +# iconv.m4 serial 21 +dnl Copyright (C) 2000-2002, 2007-2014, 2016-2019 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl so that if libiconv is installed, it will be used (unless disabled + dnl via --without-libiconv-prefix). The first AC_LINK_IFELSE will + dnl then fail, the second AC_LINK_IFELSE will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <stdlib.h> +#include <iconv.h> + ]], + [[iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);]])], + [am_cv_func_iconv=yes]) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <stdlib.h> +#include <iconv.h> + ]], + [[iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);]])], + [am_cv_lib_iconv=yes] + [am_cv_func_iconv=yes]) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ + dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, + dnl Solaris 10. + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <iconv.h> +#include <string.h> + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + ]], + [[int result = 0; + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 1; + iconv_close (cd_utf8_to_88591); + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\263"; + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 2; + iconv_close (cd_ascii_to_88591); + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + ICONV_CONST char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + result |= 4; + iconv_close (cd_88591_to_utf8); + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + result |= 8; + iconv_close (cd_88591_to_utf8); + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + { + /* Try standardized names. */ + iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP"); + /* Try IRIX, OSF/1 names. */ + iconv_t cd2 = iconv_open ("UTF-8", "eucJP"); + /* Try AIX names. */ + iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP"); + /* Try HP-UX names. */ + iconv_t cd4 = iconv_open ("utf8", "eucJP"); + if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) + && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) + result |= 16; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd3 != (iconv_t)(-1)) + iconv_close (cd3); + if (cd4 != (iconv_t)(-1)) + iconv_close (cd4); + } + return result; +]])], + [am_cv_func_iconv_works=yes], , + [case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac]) + test "$am_cv_func_iconv_works" = no || break + done + LIBS="$am_save_LIBS" + ]) + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + AC_DEFINE([HAVE_ICONV], [1], + [Define if you have the iconv() function and it works.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) +]) + +dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to +dnl avoid warnings like +dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". +dnl This is tricky because of the way 'aclocal' is implemented: +dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. +dnl Otherwise aclocal's initial scan pass would miss the macro definition. +dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. +dnl Otherwise aclocal would emit many "Use of uninitialized value $1" +dnl warnings. +m4_define([gl_iconv_AC_DEFUN], + m4_version_prereq([2.64], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [m4_ifdef([gl_00GNULIB], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [[AC_DEFUN( + [$1], [$2])]])])) +gl_iconv_AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL([am_cv_proto_iconv], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <stdlib.h> +#include <iconv.h> +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif + ]], + [[]])], + [am_cv_proto_iconv_arg1=""], + [am_cv_proto_iconv_arg1="const"]) + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$am_cv_proto_iconv]) + else + dnl When compiling GNU libiconv on a system that does not have iconv yet, + dnl pick the POSIX compliant declaration without 'const'. + am_cv_proto_iconv_arg1="" + fi + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) + dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>. + m4_ifdef([gl_ICONV_H_DEFAULTS], + [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) + if test -n "$am_cv_proto_iconv_arg1"; then + ICONV_CONST="const" + fi + ]) +]) diff --git a/config/intlmacosx.m4 b/config/intlmacosx.m4 new file mode 100644 index 000000000000..30e6f50e0ac6 --- /dev/null +++ b/config/intlmacosx.m4 @@ -0,0 +1,72 @@ +# intlmacosx.m4 serial 6 (gettext-0.20) +dnl Copyright (C) 2004-2014, 2016, 2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Checks for special options needed on Mac OS X. +dnl Defines INTL_MACOSX_LIBS. +AC_DEFUN([gt_INTL_MACOSX], +[ + dnl Check for API introduced in Mac OS X 10.4. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + [gt_cv_func_CFPreferencesCopyAppValue], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include <CoreFoundation/CFPreferences.h>]], + [[CFPreferencesCopyAppValue(NULL, NULL)]])], + [gt_cv_func_CFPreferencesCopyAppValue=yes], + [gt_cv_func_CFPreferencesCopyAppValue=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], + [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi + dnl Check for API introduced in Mac OS X 10.5. + AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include <CoreFoundation/CFLocale.h>]], + [[CFLocaleCopyCurrent();]])], + [gt_cv_func_CFLocaleCopyCurrent=yes], + [gt_cv_func_CFLocaleCopyCurrent=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], + [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) + fi + AC_CACHE_CHECK([for CFLocaleCopyPreferredLanguages], [gt_cv_func_CFLocaleCopyPreferredLanguages], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include <CoreFoundation/CFLocale.h>]], + [[CFLocaleCopyPreferredLanguages();]])], + [gt_cv_func_CFLocaleCopyPreferredLanguages=yes], + [gt_cv_func_CFLocaleCopyPreferredLanguages=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYPREFERREDLANGUAGES], [1], + [Define to 1 if you have the Mac OS X function CFLocaleCopyPreferredLanguages in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes \ + || test $gt_cv_func_CFLocaleCopyCurrent = yes \ + || test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + AC_SUBST([INTL_MACOSX_LIBS]) +]) diff --git a/config/kernel-access-ok-type.m4 b/config/kernel-access-ok-type.m4 new file mode 100644 index 000000000000..dc9433458703 --- /dev/null +++ b/config/kernel-access-ok-type.m4 @@ -0,0 +1,27 @@ +dnl # +dnl # Linux 5.0: access_ok() drops 'type' parameter: +dnl # +dnl # - access_ok(type, addr, size) +dnl # + access_ok(addr, size) +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE], [ + ZFS_LINUX_TEST_SRC([access_ok_type], [ + #include <linux/uaccess.h> + ],[ + const void __user __attribute__((unused)) *addr = + (void *) 0xdeadbeef; + unsigned long __attribute__((unused)) size = 1; + int error __attribute__((unused)) = access_ok(0, addr, size); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_ACCESS_OK_TYPE], [ + AC_MSG_CHECKING([whether access_ok() has 'type' parameter]) + ZFS_LINUX_TEST_RESULT([access_ok_type], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_ACCESS_OK_TYPE, 1, + [kernel has access_ok with 'type' parameter]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-acl.m4 b/config/kernel-acl.m4 new file mode 100644 index 000000000000..0f1c24656730 --- /dev/null +++ b/config/kernel-acl.m4 @@ -0,0 +1,289 @@ +dnl # +dnl # Check if posix_acl_release can be used from a ZFS_META_LICENSED +dnl # module. The is_owner_or_cap macro was replaced by +dnl # inode_owner_or_capable +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_RELEASE], [ + ZFS_LINUX_TEST_SRC([posix_acl_release], [ + #include <linux/cred.h> + #include <linux/fs.h> + #include <linux/posix_acl.h> + ], [ + struct posix_acl *tmp = posix_acl_alloc(1, 0); + posix_acl_release(tmp); + ], [], [$ZFS_META_LICENSE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [ + AC_MSG_CHECKING([whether posix_acl_release() is available]) + ZFS_LINUX_TEST_RESULT([posix_acl_release], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_POSIX_ACL_RELEASE, 1, + [posix_acl_release() is available]) + + AC_MSG_CHECKING([whether posix_acl_release() is GPL-only]) + ZFS_LINUX_TEST_RESULT([posix_acl_release_license], [ + AC_MSG_RESULT(no) + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_POSIX_ACL_RELEASE_GPL_ONLY, 1, + [posix_acl_release() is GPL-only]) + ]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 3.14 API change, +dnl # set_cached_acl() and forget_cached_acl() changed from inline to +dnl # EXPORT_SYMBOL. In the former case, they may not be usable because of +dnl # posix_acl_release. In the latter case, we can always use them. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_CACHED_ACL_USABLE], [ + ZFS_LINUX_TEST_SRC([set_cached_acl], [ + #include <linux/cred.h> + #include <linux/fs.h> + #include <linux/posix_acl.h> + ], [ + struct inode *ip = NULL; + struct posix_acl *acl = posix_acl_alloc(1, 0); + set_cached_acl(ip, ACL_TYPE_ACCESS, acl); + forget_cached_acl(ip, ACL_TYPE_ACCESS); + ], [], [$ZFS_META_LICENSE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE], [ + AC_MSG_CHECKING([whether set_cached_acl() is usable]) + ZFS_LINUX_TEST_RESULT([set_cached_acl_license], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SET_CACHED_ACL_USABLE, 1, + [set_cached_acl() is usable]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 3.1 API change, +dnl # posix_acl_chmod() was added as the preferred interface. +dnl # +dnl # 3.14 API change, +dnl # posix_acl_chmod() was changed to __posix_acl_chmod() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_CHMOD], [ + ZFS_LINUX_TEST_SRC([posix_acl_chmod], [ + #include <linux/fs.h> + #include <linux/posix_acl.h> + ],[ + posix_acl_chmod(NULL, 0, 0) + ]) + + ZFS_LINUX_TEST_SRC([__posix_acl_chmod], [ + #include <linux/fs.h> + #include <linux/posix_acl.h> + ],[ + __posix_acl_chmod(NULL, 0, 0) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [ + AC_MSG_CHECKING([whether __posix_acl_chmod exists]) + ZFS_LINUX_TEST_RESULT([__posix_acl_chmod], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE___POSIX_ACL_CHMOD, 1, + [__posix_acl_chmod() exists]) + ],[ + AC_MSG_RESULT(no) + + AC_MSG_CHECKING([whether posix_acl_chmod exists]) + ZFS_LINUX_TEST_RESULT([posix_acl_chmod], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_POSIX_ACL_CHMOD, 1, + [posix_acl_chmod() exists]) + ],[ + ZFS_LINUX_TEST_ERROR([posix_acl_chmod()]) + ]) + ]) +]) + +dnl # +dnl # 3.1 API change, +dnl # posix_acl_equiv_mode now wants an umode_t instead of a mode_t +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [ + ZFS_LINUX_TEST_SRC([posix_acl_equiv_mode], [ + #include <linux/fs.h> + #include <linux/posix_acl.h> + ],[ + umode_t tmp; + posix_acl_equiv_mode(NULL, &tmp); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [ + AC_MSG_CHECKING([whether posix_acl_equiv_mode() wants umode_t]) + ZFS_LINUX_TEST_RESULT([posix_acl_equiv_mode], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([posix_acl_equiv_mode()]) + ]) +]) + +dnl # +dnl # 4.8 API change, +dnl # The function posix_acl_valid now must be passed a namespace. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS], [ + ZFS_LINUX_TEST_SRC([posix_acl_valid_with_ns], [ + #include <linux/fs.h> + #include <linux/posix_acl.h> + ],[ + struct user_namespace *user_ns = NULL; + const struct posix_acl *acl = NULL; + int error; + + error = posix_acl_valid(user_ns, acl); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [ + AC_MSG_CHECKING([whether posix_acl_valid() wants user namespace]) + ZFS_LINUX_TEST_RESULT([posix_acl_valid_with_ns], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_POSIX_ACL_VALID_WITH_NS, 1, + [posix_acl_valid() wants user namespace]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 3.1 API change, +dnl # Check if inode_operations contains the function get_acl +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [ + ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [ + #include <linux/fs.h> + + struct posix_acl *get_acl_fn(struct inode *inode, int type) + { return NULL; } + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .get_acl = get_acl_fn, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [ + AC_MSG_CHECKING([whether iops->get_acl() exists]) + ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([iops->get_acl()]) + ]) +]) + +dnl # +dnl # 3.14 API change, +dnl # Check if inode_operations contains the function set_acl +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [ + ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [ + #include <linux/fs.h> + + int set_acl_fn(struct inode *inode, struct posix_acl *acl, + int type) { return 0; } + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .set_acl = set_acl_fn, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [ + AC_MSG_CHECKING([whether iops->set_acl() exists]) + ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.7 API change, +dnl # The kernel get_acl will now check cache before calling i_op->get_acl and +dnl # do set_cached_acl after that, so i_op->get_acl don't need to do that +dnl # anymore. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE], [ + ZFS_LINUX_TEST_SRC([get_acl_handle_cache], [ + #include <linux/fs.h> + ],[ + void *sentinel __attribute__ ((unused)) = + uncached_acl_sentinel(NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE], [ + AC_MSG_CHECKING([whether uncached_acl_sentinel() exists]) + ZFS_LINUX_TEST_RESULT([get_acl_handle_cache], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KERNEL_GET_ACL_HANDLE_CACHE, 1, + [uncached_acl_sentinel() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.16 kernel: check if struct posix_acl acl.a_refcount is a refcount_t. +dnl # It's an atomic_t on older kernels. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT], [ + ZFS_LINUX_TEST_SRC([acl_refcount], [ + #include <linux/backing-dev.h> + #include <linux/refcount.h> + #include <linux/posix_acl.h> + ],[ + struct posix_acl acl; + refcount_t *r __attribute__ ((unused)) = &acl.a_refcount; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_ACL_HAS_REFCOUNT], [ + AC_MSG_CHECKING([whether posix_acl has refcount_t]) + ZFS_LINUX_TEST_RESULT([acl_refcount], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_ACL_REFCOUNT, 1, [posix_acl has refcount_t]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL], [ + ZFS_AC_KERNEL_SRC_POSIX_ACL_RELEASE + ZFS_AC_KERNEL_SRC_SET_CACHED_ACL_USABLE + ZFS_AC_KERNEL_SRC_POSIX_ACL_CHMOD + ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T + ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS + ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL + ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL + ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE + ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT +]) + +AC_DEFUN([ZFS_AC_KERNEL_ACL], [ + ZFS_AC_KERNEL_POSIX_ACL_RELEASE + ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE + ZFS_AC_KERNEL_POSIX_ACL_CHMOD + ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T + ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS + ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL + ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL + ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE + ZFS_AC_KERNEL_ACL_HAS_REFCOUNT +]) diff --git a/config/kernel-aio-fsync.m4 b/config/kernel-aio-fsync.m4 new file mode 100644 index 000000000000..b4dbf29ba781 --- /dev/null +++ b/config/kernel-aio-fsync.m4 @@ -0,0 +1,23 @@ +dnl # +dnl # Linux 4.9-rc5+ ABI, removal of the .aio_fsync field +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_AIO_FSYNC], [ + ZFS_LINUX_TEST_SRC([aio_fsync], [ + #include <linux/fs.h> + + static const struct file_operations + fops __attribute__ ((unused)) = { + .aio_fsync = NULL, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [ + AC_MSG_CHECKING([whether fops->aio_fsync() exists]) + ZFS_LINUX_TEST_RESULT([aio_fsync], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_FILE_AIO_FSYNC, 1, [fops->aio_fsync() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-automount.m4 b/config/kernel-automount.m4 new file mode 100644 index 000000000000..f7bb63c68154 --- /dev/null +++ b/config/kernel-automount.m4 @@ -0,0 +1,25 @@ +dnl # +dnl # 2.6.37 API change +dnl # The dops->d_automount() dentry operation was added as a clean +dnl # solution to handling automounts. Prior to this cifs/nfs clients +dnl # which required automount support would abuse the follow_link() +dnl # operation on directories for this purpose. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [ + ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [ + #include <linux/dcache.h> + struct vfsmount *d_automount(struct path *p) { return NULL; } + struct dentry_operations dops __attribute__ ((unused)) = { + .d_automount = d_automount, + }; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [ + AC_MSG_CHECKING([whether dops->d_automount() exists]) + ZFS_LINUX_TEST_RESULT([dentry_operations_d_automount], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([dops->d_automount()]) + ]) +]) diff --git a/config/kernel-bdi.m4 b/config/kernel-bdi.m4 new file mode 100644 index 000000000000..9351df71b4b8 --- /dev/null +++ b/config/kernel-bdi.m4 @@ -0,0 +1,79 @@ +dnl # +dnl # Check available BDI interfaces. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BDI], [ + ZFS_LINUX_TEST_SRC([super_setup_bdi_name], [ + #include <linux/fs.h> + struct super_block sb; + ], [ + char *name = "bdi"; + atomic_long_t zfs_bdi_seq; + int error __attribute__((unused)) = + super_setup_bdi_name(&sb, "%.28s-%ld", name, + atomic_long_inc_return(&zfs_bdi_seq)); + ]) + + ZFS_LINUX_TEST_SRC([bdi_setup_and_register], [ + #include <linux/backing-dev.h> + struct backing_dev_info bdi; + ], [ + char *name = "bdi"; + int error __attribute__((unused)) = + bdi_setup_and_register(&bdi, name); + ]) + + ZFS_LINUX_TEST_SRC([bdi_setup_and_register_3args], [ + #include <linux/backing-dev.h> + struct backing_dev_info bdi; + ], [ + char *name = "bdi"; + unsigned int cap = BDI_CAP_MAP_COPY; + int error __attribute__((unused)) = + bdi_setup_and_register(&bdi, name, cap); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BDI], [ + dnl # + dnl # 4.12, super_setup_bdi_name() introduced. + dnl # + AC_MSG_CHECKING([whether super_setup_bdi_name() exists]) + ZFS_LINUX_TEST_RESULT_SYMBOL([super_setup_bdi_name], + [super_setup_bdi_name], [fs/super.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SUPER_SETUP_BDI_NAME, 1, + [super_setup_bdi_name() exits]) + ], [ + AC_MSG_RESULT(no) + + dnl # + dnl # 4.0 - 4.11, bdi_setup_and_register() takes 2 arguments. + dnl # + AC_MSG_CHECKING( + [whether bdi_setup_and_register() wants 2 args]) + ZFS_LINUX_TEST_RESULT_SYMBOL([bdi_setup_and_register], + [bdi_setup_and_register], [mm/backing-dev.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_2ARGS_BDI_SETUP_AND_REGISTER, 1, + [bdi_setup_and_register() wants 2 args]) + ], [ + AC_MSG_RESULT(no) + + dnl # + dnl # 2.6.34 - 3.19, bdi_setup_and_register() + dnl # takes 3 arguments. + dnl # + AC_MSG_CHECKING( + [whether bdi_setup_and_register() wants 3 args]) + ZFS_LINUX_TEST_RESULT_SYMBOL( + [bdi_setup_and_register_3args], + [bdi_setup_and_register], [mm/backing-dev.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_3ARGS_BDI_SETUP_AND_REGISTER, 1, + [bdi_setup_and_register() wants 3 args]) + ], [ + ZFS_LINUX_TEST_ERROR([bdi_setup]) + ]) + ]) + ]) +]) diff --git a/config/kernel-bio.m4 b/config/kernel-bio.m4 new file mode 100644 index 000000000000..afa1f1cabeb0 --- /dev/null +++ b/config/kernel-bio.m4 @@ -0,0 +1,403 @@ +dnl # +dnl # 2.6.36 API change, +dnl # REQ_FAILFAST_{DEV|TRANSPORT|DRIVER} +dnl # REQ_DISCARD +dnl # REQ_FLUSH +dnl # +dnl # 4.8 - 4.9 API, +dnl # REQ_FLUSH was renamed to REQ_PREFLUSH +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_REQ], [ + ZFS_LINUX_TEST_SRC([req_failfast_mask], [ + #include <linux/bio.h> + ],[ + int flags __attribute__ ((unused)); + flags = REQ_FAILFAST_MASK; + ]) + + ZFS_LINUX_TEST_SRC([req_discard], [ + #include <linux/bio.h> + ],[ + int flags __attribute__ ((unused)); + flags = REQ_DISCARD; + ]) + + ZFS_LINUX_TEST_SRC([req_flush], [ + #include <linux/bio.h> + ],[ + int flags __attribute__ ((unused)); + flags = REQ_FLUSH; + ]) + + ZFS_LINUX_TEST_SRC([req_preflush], [ + #include <linux/bio.h> + ],[ + int flags __attribute__ ((unused)); + flags = REQ_PREFLUSH; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_REQ_FAILFAST_MASK], [ + AC_MSG_CHECKING([whether REQ_FAILFAST_MASK is defined]) + ZFS_LINUX_TEST_RESULT([req_failfast_mask], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([REQ_FAILFAST_MASK]) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_REQ_DISCARD], [ + AC_MSG_CHECKING([whether REQ_DISCARD is defined]) + ZFS_LINUX_TEST_RESULT([req_discard], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_REQ_DISCARD, 1, [REQ_DISCARD is defined]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_REQ_FLUSH], [ + AC_MSG_CHECKING([whether REQ_FLUSH is defined]) + ZFS_LINUX_TEST_RESULT([req_flush], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_REQ_FLUSH, 1, [REQ_FLUSH is defined]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_REQ_PREFLUSH], [ + AC_MSG_CHECKING([whether REQ_PREFLUSH is defined]) + ZFS_LINUX_TEST_RESULT([req_preflush], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_REQ_PREFLUSH, 1, [REQ_PREFLUSH is defined]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # Linux 4.8 API, +dnl # +dnl # The bio_op() helper was introduced as a replacement for explicitly +dnl # checking the bio->bi_rw flags. The following checks are used to +dnl # detect if a specific operation is supported. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_OPS], [ + ZFS_LINUX_TEST_SRC([req_op_discard], [ + #include <linux/blk_types.h> + ],[ + int op __attribute__ ((unused)) = REQ_OP_DISCARD; + ]) + + ZFS_LINUX_TEST_SRC([req_op_secure_erase], [ + #include <linux/blk_types.h> + ],[ + int op __attribute__ ((unused)) = REQ_OP_SECURE_ERASE; + ]) + + ZFS_LINUX_TEST_SRC([req_op_flush], [ + #include <linux/blk_types.h> + ],[ + int op __attribute__ ((unused)) = REQ_OP_FLUSH; + ]) + + ZFS_LINUX_TEST_SRC([bio_bi_opf], [ + #include <linux/bio.h> + ],[ + struct bio bio __attribute__ ((unused)); + bio.bi_opf = 0; + ]) + + ZFS_LINUX_TEST_SRC([bio_set_op_attrs], [ + #include <linux/bio.h> + ],[ + struct bio *bio __attribute__ ((unused)) = NULL; + bio_set_op_attrs(bio, 0, 0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_REQ_OP_DISCARD], [ + AC_MSG_CHECKING([whether REQ_OP_DISCARD is defined]) + ZFS_LINUX_TEST_RESULT([req_op_discard], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_REQ_OP_DISCARD, 1, [REQ_OP_DISCARD is defined]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_REQ_OP_SECURE_ERASE], [ + AC_MSG_CHECKING([whether REQ_OP_SECURE_ERASE is defined]) + ZFS_LINUX_TEST_RESULT([req_op_secure_erase], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_REQ_OP_SECURE_ERASE, 1, + [REQ_OP_SECURE_ERASE is defined]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_REQ_OP_FLUSH], [ + AC_MSG_CHECKING([whether REQ_OP_FLUSH is defined]) + ZFS_LINUX_TEST_RESULT([req_op_flush], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_REQ_OP_FLUSH, 1, [REQ_OP_FLUSH is defined]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_OPF], [ + AC_MSG_CHECKING([whether bio->bi_opf is defined]) + ZFS_LINUX_TEST_RESULT([bio_bi_opf], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BIO_BI_OPF, 1, [bio->bi_opf is defined]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_OP_ATTRS], [ + AC_MSG_CHECKING([whether bio_set_op_attrs is available]) + ZFS_LINUX_TEST_RESULT([bio_set_op_attrs], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BIO_SET_OP_ATTRS, 1, + [bio_set_op_attrs is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # Linux 4.14 API, +dnl # +dnl # The bio_set_dev() helper macro was introduced as part of the transition +dnl # to have struct gendisk in struct bio. +dnl # +dnl # Linux 5.0 API, +dnl # +dnl # The bio_set_dev() helper macro was updated to internally depend on +dnl # bio_associate_blkg() symbol which is exported GPL-only. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SET_DEV], [ + ZFS_LINUX_TEST_SRC([bio_set_dev], [ + #include <linux/bio.h> + #include <linux/fs.h> + ],[ + struct block_device *bdev = NULL; + struct bio *bio = NULL; + bio_set_dev(bio, bdev); + ], [], [$ZFS_META_LICENSE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_SET_DEV], [ + AC_MSG_CHECKING([whether bio_set_dev() is available]) + ZFS_LINUX_TEST_RESULT([bio_set_dev], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BIO_SET_DEV, 1, [bio_set_dev() is available]) + + AC_MSG_CHECKING([whether bio_set_dev() is GPL-only]) + ZFS_LINUX_TEST_RESULT([bio_set_dev_license], [ + AC_MSG_RESULT(no) + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BIO_SET_DEV_GPL_ONLY, 1, + [bio_set_dev() GPL-only]) + ]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.3 API change +dnl # Error argument dropped from bio_endio in favor of newly introduced +dnl # bio->bi_error. This also replaces bio->bi_flags value BIO_UPTODATE. +dnl # Introduced by torvalds/linux@4246a0b63bd8f56a1469b12eafeb875b1041a451 +dnl # ("block: add a bi_error field to struct bio"). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS], [ + ZFS_LINUX_TEST_SRC([bio_end_io_t_args], [ + #include <linux/bio.h> + void wanted_end_io(struct bio *bio) { return; } + bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io; + ], []) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [ + AC_MSG_CHECKING([whether bio_end_io_t wants 1 arg]) + ZFS_LINUX_TEST_RESULT([bio_end_io_t_args], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_1ARG_BIO_END_IO_T, 1, + [bio_end_io_t wants 1 arg]) + ], [ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.13 API change +dnl # The bio->bi_error field was replaced with bio->bi_status which is an +dnl # enum which describes all possible error types. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_BI_STATUS], [ + ZFS_LINUX_TEST_SRC([bio_bi_status], [ + #include <linux/bio.h> + ], [ + struct bio bio __attribute__ ((unused)); + blk_status_t status __attribute__ ((unused)) = BLK_STS_OK; + bio.bi_status = status; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_STATUS], [ + AC_MSG_CHECKING([whether bio->bi_status exists]) + ZFS_LINUX_TEST_RESULT([bio_bi_status], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BIO_BI_STATUS, 1, [bio->bi_status exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 3.14 API change, +dnl # Immutable biovecs. A number of fields of struct bio are moved to +dnl # struct bvec_iter. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER], [ + ZFS_LINUX_TEST_SRC([bio_bvec_iter], [ + #include <linux/bio.h> + ],[ + struct bio bio; + bio.bi_iter.bi_sector = 0; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_BVEC_ITER], [ + AC_MSG_CHECKING([whether bio has bi_iter]) + ZFS_LINUX_TEST_RESULT([bio_bvec_iter], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BIO_BVEC_ITER, 1, [bio has bi_iter]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.8 API change +dnl # The rw argument has been removed from submit_bio/submit_bio_wait. +dnl # Callers are now expected to set bio->bi_rw instead of passing it in. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO], [ + ZFS_LINUX_TEST_SRC([submit_bio], [ + #include <linux/bio.h> + ],[ + blk_qc_t blk_qc; + struct bio *bio = NULL; + blk_qc = submit_bio(bio); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_SUBMIT_BIO], [ + AC_MSG_CHECKING([whether submit_bio() wants 1 arg]) + ZFS_LINUX_TEST_RESULT([submit_bio], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_1ARG_SUBMIT_BIO, 1, [submit_bio() wants 1 arg]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.34 API change +dnl # current->bio_list +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST], [ + ZFS_LINUX_TEST_SRC([current_bio_list], [ + #include <linux/sched.h> + ], [ + current->bio_list = (struct bio_list *) NULL; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST], [ + AC_MSG_CHECKING([whether current->bio_list exists]) + ZFS_LINUX_TEST_RESULT([current_bio_list], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([bio_list]) + ]) +]) + +dnl # +dnl # Linux 5.5 API, +dnl # +dnl # The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by +dnl # blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched(). +dnl # As a side effect the function was converted to GPL-only. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKG_TRYGET], [ + ZFS_LINUX_TEST_SRC([blkg_tryget], [ + #include <linux/blk-cgroup.h> + #include <linux/bio.h> + #include <linux/fs.h> + ],[ + struct blkcg_gq blkg __attribute__ ((unused)); + bool rc __attribute__ ((unused)); + rc = blkg_tryget(&blkg); + ], [], [$ZFS_META_LICENSE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKG_TRYGET], [ + AC_MSG_CHECKING([whether blkg_tryget() is available]) + ZFS_LINUX_TEST_RESULT([blkg_tryget], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLKG_TRYGET, 1, [blkg_tryget() is available]) + + AC_MSG_CHECKING([whether blkg_tryget() is GPL-only]) + ZFS_LINUX_TEST_RESULT([blkg_tryget_license], [ + AC_MSG_RESULT(no) + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLKG_TRYGET_GPL_ONLY, 1, + [blkg_tryget() GPL-only]) + ]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [ + ZFS_AC_KERNEL_SRC_REQ + ZFS_AC_KERNEL_SRC_BIO_OPS + ZFS_AC_KERNEL_SRC_BIO_SET_DEV + ZFS_AC_KERNEL_SRC_BIO_END_IO_T_ARGS + ZFS_AC_KERNEL_SRC_BIO_BI_STATUS + ZFS_AC_KERNEL_SRC_BIO_BVEC_ITER + ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO + ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST + ZFS_AC_KERNEL_SRC_BLKG_TRYGET +]) + +AC_DEFUN([ZFS_AC_KERNEL_BIO], [ + ZFS_AC_KERNEL_BIO_REQ_FAILFAST_MASK + ZFS_AC_KERNEL_BIO_REQ_DISCARD + ZFS_AC_KERNEL_BIO_REQ_FLUSH + ZFS_AC_KERNEL_BIO_REQ_PREFLUSH + + ZFS_AC_KERNEL_BIO_REQ_OP_DISCARD + ZFS_AC_KERNEL_BIO_REQ_OP_SECURE_ERASE + ZFS_AC_KERNEL_BIO_REQ_OP_FLUSH + ZFS_AC_KERNEL_BIO_BI_OPF + ZFS_AC_KERNEL_BIO_SET_OP_ATTRS + + ZFS_AC_KERNEL_BIO_SET_DEV + ZFS_AC_KERNEL_BIO_END_IO_T_ARGS + ZFS_AC_KERNEL_BIO_BI_STATUS + ZFS_AC_KERNEL_BIO_BVEC_ITER + ZFS_AC_KERNEL_BIO_SUBMIT_BIO + ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST + ZFS_AC_KERNEL_BLKG_TRYGET +]) diff --git a/config/kernel-blk-queue.m4 b/config/kernel-blk-queue.m4 new file mode 100644 index 000000000000..382ebefd34a3 --- /dev/null +++ b/config/kernel-blk-queue.m4 @@ -0,0 +1,302 @@ +dnl # +dnl # 2.6.39 API change, +dnl # blk_start_plug() and blk_finish_plug() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG], [ + ZFS_LINUX_TEST_SRC([blk_plug], [ + #include <linux/blkdev.h> + ],[ + struct blk_plug plug __attribute__ ((unused)); + + blk_start_plug(&plug); + blk_finish_plug(&plug); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_PLUG], [ + AC_MSG_CHECKING([whether struct blk_plug is available]) + ZFS_LINUX_TEST_RESULT([blk_plug], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([blk_plug]) + ]) +]) + +dnl # +dnl # 2.6.32 - 4.11, statically allocated bdi in request_queue +dnl # 4.12 - x.y, dynamically allocated bdi in request_queue +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI], [ + ZFS_LINUX_TEST_SRC([blk_queue_bdi], [ + #include <linux/blkdev.h> + ],[ + struct request_queue q; + struct backing_dev_info bdi; + q.backing_dev_info = &bdi; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_BDI], [ + AC_MSG_CHECKING([whether blk_queue bdi is dynamic]) + ZFS_LINUX_TEST_RESULT([blk_queue_bdi], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_BDI_DYNAMIC, 1, + [blk queue backing_dev_info is dynamic]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.32 - 4.x API, +dnl # blk_queue_discard() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD], [ + ZFS_LINUX_TEST_SRC([blk_queue_discard], [ + #include <linux/blkdev.h> + ],[ + struct request_queue *q __attribute__ ((unused)) = NULL; + int value __attribute__ ((unused)); + value = blk_queue_discard(q); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_DISCARD], [ + AC_MSG_CHECKING([whether blk_queue_discard() is available]) + ZFS_LINUX_TEST_RESULT([blk_queue_discard], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([blk_queue_discard]) + ]) +]) + +dnl # +dnl # 4.8 - 4.x API, +dnl # blk_queue_secure_erase() +dnl # +dnl # 2.6.36 - 4.7 API, +dnl # blk_queue_secdiscard() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE], [ + ZFS_LINUX_TEST_SRC([blk_queue_secure_erase], [ + #include <linux/blkdev.h> + ],[ + struct request_queue *q __attribute__ ((unused)) = NULL; + int value __attribute__ ((unused)); + value = blk_queue_secure_erase(q); + ]) + + ZFS_LINUX_TEST_SRC([blk_queue_secdiscard], [ + #include <linux/blkdev.h> + ],[ + struct request_queue *q __attribute__ ((unused)) = NULL; + int value __attribute__ ((unused)); + value = blk_queue_secdiscard(q); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE], [ + AC_MSG_CHECKING([whether blk_queue_secure_erase() is available]) + ZFS_LINUX_TEST_RESULT([blk_queue_secure_erase], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_SECURE_ERASE, 1, + [blk_queue_secure_erase() is available]) + ],[ + AC_MSG_RESULT(no) + + AC_MSG_CHECKING([whether blk_queue_secdiscard() is available]) + ZFS_LINUX_TEST_RESULT([blk_queue_secdiscard], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_SECDISCARD, 1, + [blk_queue_secdiscard() is available]) + ],[ + ZFS_LINUX_TEST_ERROR([blk_queue_secure_erase]) + ]) + ]) +]) + +dnl # +dnl # 4.16 API change, +dnl # Introduction of blk_queue_flag_set and blk_queue_flag_clear +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET], [ + ZFS_LINUX_TEST_SRC([blk_queue_flag_set], [ + #include <linux/kernel.h> + #include <linux/blkdev.h> + ],[ + struct request_queue *q = NULL; + blk_queue_flag_set(0, q); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET], [ + AC_MSG_CHECKING([whether blk_queue_flag_set() exists]) + ZFS_LINUX_TEST_RESULT([blk_queue_flag_set], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_FLAG_SET, 1, + [blk_queue_flag_set() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_CLEAR], [ + ZFS_LINUX_TEST_SRC([blk_queue_flag_clear], [ + #include <linux/kernel.h> + #include <linux/blkdev.h> + ],[ + struct request_queue *q = NULL; + blk_queue_flag_clear(0, q); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR], [ + AC_MSG_CHECKING([whether blk_queue_flag_clear() exists]) + ZFS_LINUX_TEST_RESULT([blk_queue_flag_clear], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_FLAG_CLEAR, 1, + [blk_queue_flag_clear() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.36 API change, +dnl # Added blk_queue_flush() interface, while the previous interface +dnl # was available to all the new one is GPL-only. Thus in addition to +dnl # detecting if this function is available we determine if it is +dnl # GPL-only. If the GPL-only interface is there we implement our own +dnl # compatibility function, otherwise we use the function. The hope +dnl # is that long term this function will be opened up. +dnl # +dnl # 4.7 API change, +dnl # Replace blk_queue_flush with blk_queue_write_cache +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLUSH], [ + ZFS_LINUX_TEST_SRC([blk_queue_flush], [ + #include <linux/blkdev.h> + ], [ + struct request_queue *q = NULL; + (void) blk_queue_flush(q, REQ_FLUSH); + ], [$NO_UNUSED_BUT_SET_VARIABLE], [$ZFS_META_LICENSE]) + + ZFS_LINUX_TEST_SRC([blk_queue_write_cache], [ + #include <linux/kernel.h> + #include <linux/blkdev.h> + ], [ + struct request_queue *q = NULL; + blk_queue_write_cache(q, true, true); + ], [$NO_UNUSED_BUT_SET_VARIABLE], [$ZFS_META_LICENSE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [ + AC_MSG_CHECKING([whether blk_queue_flush() is available]) + ZFS_LINUX_TEST_RESULT([blk_queue_flush], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1, + [blk_queue_flush() is available]) + + AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only]) + ZFS_LINUX_TEST_RESULT([blk_queue_flush_license], [ + AC_MSG_RESULT(no) + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1, + [blk_queue_flush() is GPL-only]) + ]) + ],[ + AC_MSG_RESULT(no) + ]) + + dnl # + dnl # 4.7 API change + dnl # Replace blk_queue_flush with blk_queue_write_cache + dnl # + AC_MSG_CHECKING([whether blk_queue_write_cache() exists]) + ZFS_LINUX_TEST_RESULT([blk_queue_write_cache], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE, 1, + [blk_queue_write_cache() exists]) + + AC_MSG_CHECKING([whether blk_queue_write_cache() is GPL-only]) + ZFS_LINUX_TEST_RESULT([blk_queue_write_cache_license], [ + AC_MSG_RESULT(no) + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY, 1, + [blk_queue_write_cache() is GPL-only]) + ]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.34 API change +dnl # blk_queue_max_hw_sectors() replaces blk_queue_max_sectors(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_HW_SECTORS], [ + ZFS_LINUX_TEST_SRC([blk_queue_max_hw_sectors], [ + #include <linux/blkdev.h> + ], [ + struct request_queue *q = NULL; + (void) blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS); + ], [$NO_UNUSED_BUT_SET_VARIABLE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS], [ + AC_MSG_CHECKING([whether blk_queue_max_hw_sectors() is available]) + ZFS_LINUX_TEST_RESULT([blk_queue_max_hw_sectors], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([blk_queue_max_hw_sectors]) + ]) +]) + +dnl # +dnl # 2.6.34 API change +dnl # blk_queue_max_segments() consolidates blk_queue_max_hw_segments() +dnl # and blk_queue_max_phys_segments(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_SEGMENTS], [ + ZFS_LINUX_TEST_SRC([blk_queue_max_segments], [ + #include <linux/blkdev.h> + ], [ + struct request_queue *q = NULL; + (void) blk_queue_max_segments(q, BLK_MAX_SEGMENTS); + ], [$NO_UNUSED_BUT_SET_VARIABLE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS], [ + AC_MSG_CHECKING([whether blk_queue_max_segments() is available]) + ZFS_LINUX_TEST_RESULT([blk_queue_max_segments], [ + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([blk_queue_max_segments]) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLK_QUEUE], [ + ZFS_AC_KERNEL_SRC_BLK_QUEUE_PLUG + ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI + ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD + ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE + ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_SET + ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLAG_CLEAR + ZFS_AC_KERNEL_SRC_BLK_QUEUE_FLUSH + ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_HW_SECTORS + ZFS_AC_KERNEL_SRC_BLK_QUEUE_MAX_SEGMENTS +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE], [ + ZFS_AC_KERNEL_BLK_QUEUE_PLUG + ZFS_AC_KERNEL_BLK_QUEUE_BDI + ZFS_AC_KERNEL_BLK_QUEUE_DISCARD + ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE + ZFS_AC_KERNEL_BLK_QUEUE_FLAG_SET + ZFS_AC_KERNEL_BLK_QUEUE_FLAG_CLEAR + ZFS_AC_KERNEL_BLK_QUEUE_FLUSH + ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS + ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS +]) diff --git a/config/kernel-blkdev.m4 b/config/kernel-blkdev.m4 new file mode 100644 index 000000000000..2644555f5524 --- /dev/null +++ b/config/kernel-blkdev.m4 @@ -0,0 +1,212 @@ +dnl # +dnl # 2.6.38 API change, +dnl # Added blkdev_get_by_path() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [ + ZFS_LINUX_TEST_SRC([blkdev_get_by_path], [ + #include <linux/fs.h> + #include <linux/blkdev.h> + ], [ + struct block_device *bdev __attribute__ ((unused)) = NULL; + const char *path = "path"; + fmode_t mode = 0; + void *holder = NULL; + + bdev = blkdev_get_by_path(path, mode, holder); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [ + AC_MSG_CHECKING([whether blkdev_get_by_path() exists]) + ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [ + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()]) + ]) +]) + +dnl # +dnl # 2.6.38 API change, +dnl # Added blkdev_put() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT], [ + ZFS_LINUX_TEST_SRC([blkdev_put], [ + #include <linux/fs.h> + #include <linux/blkdev.h> + ], [ + struct block_device *bdev = NULL; + fmode_t mode = 0; + + blkdev_put(bdev, mode); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [ + AC_MSG_CHECKING([whether blkdev_put() exists]) + ZFS_LINUX_TEST_RESULT([blkdev_put], [ + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([blkdev_put()]) + ]) +]) + +dnl # +dnl # 4.1 API, exported blkdev_reread_part() symbol, back ported to the +dnl # 3.10.0 CentOS 7.x enterprise kernels. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART], [ + ZFS_LINUX_TEST_SRC([blkdev_reread_part], [ + #include <linux/fs.h> + #include <linux/blkdev.h> + ], [ + struct block_device *bdev = NULL; + int error; + + error = blkdev_reread_part(bdev); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_REREAD_PART], [ + AC_MSG_CHECKING([whether blkdev_reread_part() exists]) + ZFS_LINUX_TEST_RESULT([blkdev_reread_part], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLKDEV_REREAD_PART, 1, + [blkdev_reread_part() exists]) + ], [ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.22 API change +dnl # Single argument invalidate_bdev() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV], [ + ZFS_LINUX_TEST_SRC([invalidate_bdev], [ + #include <linux/buffer_head.h> + #include <linux/blkdev.h> + ],[ + struct block_device *bdev = NULL; + invalidate_bdev(bdev); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_INVALIDATE_BDEV], [ + AC_MSG_CHECKING([whether invalidate_bdev() exists]) + ZFS_LINUX_TEST_RESULT([invalidate_bdev], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([invalidate_bdev()]) + ]) +]) + +dnl # +dnl # 2.6.27, lookup_bdev() was exported. +dnl # 4.4.0-6.21 - lookup_bdev() takes 2 arguments. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV], [ + ZFS_LINUX_TEST_SRC([lookup_bdev_1arg], [ + #include <linux/fs.h> + #include <linux/blkdev.h> + ], [ + lookup_bdev(NULL); + ]) + + ZFS_LINUX_TEST_SRC([lookup_bdev_2args], [ + #include <linux/fs.h> + ], [ + lookup_bdev(NULL, FMODE_READ); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_LOOKUP_BDEV], [ + AC_MSG_CHECKING([whether lookup_bdev() wants 1 arg]) + ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_1arg], + [lookup_bdev], [fs/block_dev.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_1ARG_LOOKUP_BDEV, 1, + [lookup_bdev() wants 1 arg]) + ], [ + AC_MSG_RESULT(no) + + AC_MSG_CHECKING([whether lookup_bdev() wants 2 args]) + ZFS_LINUX_TEST_RESULT_SYMBOL([lookup_bdev_2args], + [lookup_bdev], [fs/block_dev.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_2ARGS_LOOKUP_BDEV, 1, + [lookup_bdev() wants 2 args]) + ], [ + ZFS_LINUX_TEST_ERROR([lookup_bdev()]) + ]) + ]) +]) + +dnl # +dnl # 2.6.30 API change +dnl # +dnl # The bdev_physical_block_size() interface was added to provide a way +dnl # to determine the smallest write which can be performed without a +dnl # read-modify-write operation. +dnl # +dnl # Unfortunately, this interface isn't entirely reliable because +dnl # drives are sometimes known to misreport this value. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_PHYSICAL_BLOCK_SIZE], [ + ZFS_LINUX_TEST_SRC([bdev_physical_block_size], [ + #include <linux/blkdev.h> + ],[ + struct block_device *bdev __attribute__ ((unused)) = NULL; + bdev_physical_block_size(bdev); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_PHYSICAL_BLOCK_SIZE], [ + AC_MSG_CHECKING([whether bdev_physical_block_size() is available]) + ZFS_LINUX_TEST_RESULT([bdev_physical_block_size], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([bdev_physical_block_size()]) + ]) +]) + +dnl # +dnl # 2.6.30 API change +dnl # Added bdev_logical_block_size(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_LOGICAL_BLOCK_SIZE], [ + ZFS_LINUX_TEST_SRC([bdev_logical_block_size], [ + #include <linux/blkdev.h> + ],[ + struct block_device *bdev __attribute__ ((unused)) = NULL; + bdev_logical_block_size(bdev); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_LOGICAL_BLOCK_SIZE], [ + AC_MSG_CHECKING([whether bdev_logical_block_size() is available]) + ZFS_LINUX_TEST_RESULT([bdev_logical_block_size], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([bdev_logical_block_size()]) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ + ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH + ZFS_AC_KERNEL_SRC_BLKDEV_PUT + ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART + ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV + ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV + ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_LOGICAL_BLOCK_SIZE + ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_PHYSICAL_BLOCK_SIZE +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ + ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH + ZFS_AC_KERNEL_BLKDEV_PUT + ZFS_AC_KERNEL_BLKDEV_REREAD_PART + ZFS_AC_KERNEL_BLKDEV_INVALIDATE_BDEV + ZFS_AC_KERNEL_BLKDEV_LOOKUP_BDEV + ZFS_AC_KERNEL_BLKDEV_BDEV_LOGICAL_BLOCK_SIZE + ZFS_AC_KERNEL_BLKDEV_BDEV_PHYSICAL_BLOCK_SIZE +]) diff --git a/config/kernel-block-device-operations.m4 b/config/kernel-block-device-operations.m4 new file mode 100644 index 000000000000..8e64ecca909b --- /dev/null +++ b/config/kernel-block-device-operations.m4 @@ -0,0 +1,63 @@ +dnl # +dnl # 2.6.38 API change +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [ + ZFS_LINUX_TEST_SRC([block_device_operations_check_events], [ + #include <linux/blkdev.h> + + unsigned int blk_check_events(struct gendisk *disk, + unsigned int clearing) { return (0); } + + static const struct block_device_operations + bops __attribute__ ((unused)) = { + .check_events = blk_check_events, + }; + ], [], [$NO_UNUSED_BUT_SET_VARIABLE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [ + AC_MSG_CHECKING([whether bops->check_events() exists]) + ZFS_LINUX_TEST_RESULT([block_device_operations_check_events], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([bops->check_events()]) + ]) +]) + +dnl # +dnl # 3.10.x API change +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ + ZFS_LINUX_TEST_SRC([block_device_operations_release_void], [ + #include <linux/blkdev.h> + + void blk_release(struct gendisk *g, fmode_t mode) { return; } + + static const struct block_device_operations + bops __attribute__ ((unused)) = { + .open = NULL, + .release = blk_release, + .ioctl = NULL, + .compat_ioctl = NULL, + }; + ], [], [$NO_UNUSED_BUT_SET_VARIABLE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ + AC_MSG_CHECKING([whether bops->release() is void]) + ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([bops->release()]) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [ + ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS + ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS], [ + ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS + ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID +]) diff --git a/config/kernel-clear-inode.m4 b/config/kernel-clear-inode.m4 new file mode 100644 index 000000000000..3f454d7ec0d3 --- /dev/null +++ b/config/kernel-clear-inode.m4 @@ -0,0 +1,39 @@ +dnl # +dnl # 3.5.0 API change +dnl # torvalds/linux@dbd5768f87ff6fb0a4fe09c4d7b6c4a24de99430 and +dnl # torvalds/linux@7994e6f7254354e03028a11f98a27bd67dace9f1 reworked +dnl # where inode_sync_wait() is called. +dnl # +dnl # Prior to these changes it would occur in end_writeback() but due +dnl # to various issues (described in the above commits) it has been +dnl # moved to evict(). This changes the ordering is which sync occurs +dnl # but otherwise doesn't impact the zpl implementation. +dnl # +dnl # The major impact here is the renaming of end_writeback() to +dnl # clear_inode(). However, care must be taken when detecting this +dnl # API change because as recently as 2.6.35 there was a clear_inode() +dnl # function. However, it was made obsolete by the evict_inode() API +dnl # change at the same time. +dnl # +dnl # Therefore, to ensure we have the correct API we only allow the +dnl # clear_inode() compatibility code to be defined iff the evict_inode() +dnl # functionality is also detected. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CLEAR_INODE], [ + ZFS_LINUX_TEST_SRC([clear_inode], [ + #include <linux/fs.h> + ], [ + clear_inode(NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CLEAR_INODE], [ + AC_MSG_CHECKING([whether clear_inode() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([clear_inode], + [clear_inode], [fs/inode.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_CLEAR_INODE, 1, [clear_inode() is available]) + ], [ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-commit-metadata.m4 b/config/kernel-commit-metadata.m4 new file mode 100644 index 000000000000..7df9b980290e --- /dev/null +++ b/config/kernel-commit-metadata.m4 @@ -0,0 +1,24 @@ +dnl # +dnl # 2.6.33 API change +dnl # Added eops->commit_metadata() callback to allow the underlying +dnl # filesystem to determine the most efficient way to commit the inode. +dnl # Prior to this the nfs server would issue an explicit fsync(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_COMMIT_METADATA], [ + ZFS_LINUX_TEST_SRC([export_operations_commit_metadata], [ + #include <linux/exportfs.h> + int commit_metadata(struct inode *inode) { return 0; } + static struct export_operations eops __attribute__ ((unused))={ + .commit_metadata = commit_metadata, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_COMMIT_METADATA], [ + AC_MSG_CHECKING([whether eops->commit_metadata() exists]) + ZFS_LINUX_TEST_RESULT([export_operations_commit_metadata], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([eops->commit_metadata()]) + ]) +]) diff --git a/config/kernel-config-defined.m4 b/config/kernel-config-defined.m4 new file mode 100644 index 000000000000..0ee4231cc2db --- /dev/null +++ b/config/kernel-config-defined.m4 @@ -0,0 +1,183 @@ +dnl # +dnl # Certain kernel build options are not supported. These must be +dnl # detected at configure time and cause a build failure. Otherwise +dnl # modules may be successfully built that behave incorrectly. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEFINED], [ + AS_IF([test "x$cross_compiling" != xyes], [ + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([ + #include "$LINUX/include/linux/license.h" + ], [ + return !license_is_gpl_compatible( + "$ZFS_META_LICENSE"); + ]) + ], [ + AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1], + [Define to 1 if GPL-only symbols can be used]) + ], [ + ]) + ]) + + ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE + ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC + ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS + ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_INFLATE + ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE + + AC_MSG_CHECKING([for kernel config option compatibility]) + ZFS_LINUX_TEST_COMPILE_ALL([config]) + AC_MSG_RESULT([done]) + + ZFS_AC_KERNEL_CONFIG_THREAD_SIZE + ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC + ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS + ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE + ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE +]) + +dnl # +dnl # Check configured THREAD_SIZE +dnl # +dnl # The stack size will vary by architecture, but as of Linux 3.15 on x86_64 +dnl # the default thread stack size was increased to 16K from 8K. Therefore, +dnl # on newer kernels and some architectures stack usage optimizations can be +dnl # conditionally applied to improve performance without negatively impacting +dnl # stability. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_THREAD_SIZE], [ + ZFS_LINUX_TEST_SRC([config_thread_size], [ + #include <linux/module.h> + ],[ + #if (THREAD_SIZE < 16384) + #error "THREAD_SIZE is less than 16K" + #endif + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [ + AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks]) + ZFS_LINUX_TEST_RESULT([config_thread_size], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks]) + ],[ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # Check CONFIG_DEBUG_LOCK_ALLOC +dnl # +dnl # This is typically only set for debug kernels because it comes with +dnl # a performance penalty. However, when it is set it maps the non-GPL +dnl # symbol mutex_lock() to the GPL-only mutex_lock_nested() symbol. +dnl # This will cause a failure at link time which we'd rather know about +dnl # at compile time. +dnl # +dnl # Since we plan to pursue making mutex_lock_nested() a non-GPL symbol +dnl # with the upstream community we add a check to detect this case. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_DEBUG_LOCK_ALLOC], [ + ZFS_LINUX_TEST_SRC([config_debug_lock_alloc], [ + #include <linux/mutex.h> + ],[ + struct mutex lock; + + mutex_init(&lock); + mutex_lock(&lock); + mutex_unlock(&lock); + ], [], [$ZFS_META_LICENSE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC], [ + AC_MSG_CHECKING([whether mutex_lock() is GPL-only]) + ZFS_LINUX_TEST_RESULT([config_debug_lock_alloc], [ + AC_MSG_RESULT(no) + ],[ + AC_MSG_RESULT(yes) + AC_MSG_ERROR([ + *** Kernel built with CONFIG_DEBUG_LOCK_ALLOC which is incompatible + *** with the CDDL license and will prevent the module linking stage + *** from succeeding. You must rebuild your kernel without this + *** option enabled.]) + ]) +]) + +dnl # +dnl # Check CONFIG_TRIM_UNUSED_KSYMS +dnl # +dnl # Verify the kernel has CONFIG_TRIM_UNUSED_KSYMS disabled. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS], [ + ZFS_LINUX_TEST_SRC([config_trim_unusued_ksyms], [ + #if defined(CONFIG_TRIM_UNUSED_KSYMS) + #error CONFIG_TRIM_UNUSED_KSYMS not defined + #endif + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS], [ + AC_MSG_CHECKING([whether CONFIG_TRIM_UNUSED_KSYM is disabled]) + ZFS_LINUX_TEST_RESULT([config_trim_unusued_ksyms], [ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AS_IF([test "x$enable_linux_builtin" != xyes], [ + AC_MSG_ERROR([ + *** This kernel has unused symbols trimming enabled, please disable. + *** Rebuild the kernel with CONFIG_TRIM_UNUSED_KSYMS=n set.]) + ]) + ]) +]) + +dnl # +dnl # Check CONFIG_ZLIB_INFLATE +dnl # +dnl # Verify the kernel has CONFIG_ZLIB_INFLATE support enabled. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_INFLATE], [ + ZFS_LINUX_TEST_SRC([config_zlib_inflate], [ + #if !defined(CONFIG_ZLIB_INFLATE) && \ + !defined(CONFIG_ZLIB_INFLATE_MODULE) + #error CONFIG_ZLIB_INFLATE not defined + #endif + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE], [ + AC_MSG_CHECKING([whether CONFIG_ZLIB_INFLATE is defined]) + ZFS_LINUX_TEST_RESULT([config_zlib_inflate], [ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_ERROR([ + *** This kernel does not include the required zlib inflate support. + *** Rebuild the kernel with CONFIG_ZLIB_INFLATE=y|m set.]) + ]) +]) + +dnl # +dnl # Check CONFIG_ZLIB_DEFLATE +dnl # +dnl # Verify the kernel has CONFIG_ZLIB_DEFLATE support enabled. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE], [ + ZFS_LINUX_TEST_SRC([config_zlib_deflate], [ + #if !defined(CONFIG_ZLIB_DEFLATE) && \ + !defined(CONFIG_ZLIB_DEFLATE_MODULE) + #error CONFIG_ZLIB_DEFLATE not defined + #endif + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE], [ + AC_MSG_CHECKING([whether CONFIG_ZLIB_DEFLATE is defined]) + ZFS_LINUX_TEST_RESULT([config_zlib_deflate], [ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_ERROR([ + *** This kernel does not include the required zlib deflate support. + *** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set.]) + ]) +]) diff --git a/config/kernel-current-time.m4 b/config/kernel-current-time.m4 new file mode 100644 index 000000000000..3ceb5f63efa9 --- /dev/null +++ b/config/kernel-current-time.m4 @@ -0,0 +1,23 @@ +dnl # +dnl # 4.9, current_time() added +dnl # 4.18, return type changed from timespec to timespec64 +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_TIME], [ + ZFS_LINUX_TEST_SRC([current_time], [ + #include <linux/fs.h> + ], [ + struct inode ip __attribute__ ((unused)); + ip.i_atime = current_time(&ip); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CURRENT_TIME], [ + AC_MSG_CHECKING([whether current_time() exists]) + ZFS_LINUX_TEST_RESULT_SYMBOL([current_time], + [current_time], [fs/inode.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_CURRENT_TIME, 1, [current_time() exists]) + ], [ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-declare-event-class.m4 b/config/kernel-declare-event-class.m4 new file mode 100644 index 000000000000..6c78ee858d7d --- /dev/null +++ b/config/kernel-declare-event-class.m4 @@ -0,0 +1,55 @@ +dnl # +dnl # Ensure the DECLARE_EVENT_CLASS macro is available to non-GPL modules. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_DECLARE_EVENT_CLASS], [ + AC_MSG_CHECKING([whether DECLARE_EVENT_CLASS() is available]) + ZFS_LINUX_TRY_COMPILE_HEADER([ + #include <linux/module.h> + MODULE_LICENSE("$ZFS_META_LICENSE"); + + #define CREATE_TRACE_POINTS + #include "conftest.h" + ],[ + trace_zfs_autoconf_event_one(1UL); + trace_zfs_autoconf_event_two(2UL); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DECLARE_EVENT_CLASS, 1, + [DECLARE_EVENT_CLASS() is available]) + ],[ + AC_MSG_RESULT(no) + ],[ + #if !defined(_CONFTEST_H) || defined(TRACE_HEADER_MULTI_READ) + #define _CONFTEST_H + + #undef TRACE_SYSTEM + #define TRACE_SYSTEM zfs + #include <linux/tracepoint.h> + + DECLARE_EVENT_CLASS(zfs_autoconf_event_class, + TP_PROTO(unsigned long i), + TP_ARGS(i), + TP_STRUCT__entry( + __field(unsigned long, i) + ), + TP_fast_assign( + __entry->i = i; + ), + TP_printk("i = %lu", __entry->i) + ); + + #define DEFINE_AUTOCONF_EVENT(name) \ + DEFINE_EVENT(zfs_autoconf_event_class, name, \ + TP_PROTO(unsigned long i), \ + TP_ARGS(i)) + DEFINE_AUTOCONF_EVENT(zfs_autoconf_event_one); + DEFINE_AUTOCONF_EVENT(zfs_autoconf_event_two); + + #endif /* _CONFTEST_H */ + + #undef TRACE_INCLUDE_PATH + #define TRACE_INCLUDE_PATH . + #define TRACE_INCLUDE_FILE conftest + #include <trace/define_trace.h> + ]) +]) diff --git a/config/kernel-dentry-operations.m4 b/config/kernel-dentry-operations.m4 new file mode 100644 index 000000000000..dd470d7607b4 --- /dev/null +++ b/config/kernel-dentry-operations.m4 @@ -0,0 +1,190 @@ +dnl # +dnl # 3.4.0 API change +dnl # Added d_make_root() to replace previous d_alloc_root() function. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_D_MAKE_ROOT], [ + ZFS_LINUX_TEST_SRC([d_make_root], [ + #include <linux/dcache.h> + ], [ + d_make_root(NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_D_MAKE_ROOT], [ + AC_MSG_CHECKING([whether d_make_root() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([d_make_root], + [d_make_root], [fs/dcache.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_D_MAKE_ROOT, 1, [d_make_root() is available]) + ], [ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.28 API change +dnl # Added d_obtain_alias() helper function. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS], [ + ZFS_LINUX_TEST_SRC([d_obtain_alias], [ + #include <linux/dcache.h> + ], [ + d_obtain_alias(NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_D_OBTAIN_ALIAS], [ + AC_MSG_CHECKING([whether d_obtain_alias() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([d_obtain_alias], + [d_obtain_alias], [fs/dcache.c], [ + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([d_obtain_alias()]) + ]) +]) + +dnl # +dnl # 2.6.12 API change +dnl # d_prune_aliases() helper function available. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_D_PRUNE_ALIASES], [ + ZFS_LINUX_TEST_SRC([d_prune_aliases], [ + #include <linux/dcache.h> + ], [ + struct inode *ip = NULL; + d_prune_aliases(ip); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_D_PRUNE_ALIASES], [ + AC_MSG_CHECKING([whether d_prune_aliases() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([d_prune_aliases], + [d_prune_aliases], [fs/dcache.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_D_PRUNE_ALIASES, 1, + [d_prune_aliases() is available]) + ], [ + ZFS_LINUX_TEST_ERROR([d_prune_aliases()]) + ]) +]) + +dnl # +dnl # 2.6.38 API change +dnl # Added d_set_d_op() helper function. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_D_SET_D_OP], [ + ZFS_LINUX_TEST_SRC([d_set_d_op], [ + #include <linux/dcache.h> + ], [ + d_set_d_op(NULL, NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP], [ + AC_MSG_CHECKING([whether d_set_d_op() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([d_set_d_op], + [d_set_d_op], [fs/dcache.c], [ + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([d_set_d_op]) + ]) +]) + +dnl # +dnl # 3.6 API change +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_D_REVALIDATE_NAMEIDATA], [ + ZFS_LINUX_TEST_SRC([dentry_operations_revalidate], [ + #include <linux/dcache.h> + #include <linux/sched.h> + + int revalidate (struct dentry *dentry, + struct nameidata *nidata) { return 0; } + + static const struct dentry_operations + dops __attribute__ ((unused)) = { + .d_revalidate = revalidate, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA], [ + AC_MSG_CHECKING([whether dops->d_revalidate() takes struct nameidata]) + ZFS_LINUX_TEST_RESULT([dentry_operations_revalidate], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_D_REVALIDATE_NAMEIDATA, 1, + [dops->d_revalidate() operation takes nameidata]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.30 API change +dnl # The 'struct dentry_operations' was constified in the dentry structure. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CONST_DENTRY_OPERATIONS], [ + ZFS_LINUX_TEST_SRC([dentry_operations_const], [ + #include <linux/dcache.h> + + const struct dentry_operations test_d_op = { + .d_revalidate = NULL, + }; + ],[ + struct dentry d __attribute__ ((unused)); + d.d_op = &test_d_op; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS], [ + AC_MSG_CHECKING([whether dentry uses const struct dentry_operations]) + ZFS_LINUX_TEST_RESULT([dentry_operations_const], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_CONST_DENTRY_OPERATIONS, 1, + [dentry uses const struct dentry_operations]) + ],[ + ZFS_LINUX_TEST_ERROR([const dentry_operations]) + ]) +]) + +dnl # +dnl # 2.6.38 API change +dnl # Added sb->s_d_op default dentry_operations member +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_S_D_OP], [ + ZFS_LINUX_TEST_SRC([super_block_s_d_op], [ + #include <linux/fs.h> + ],[ + struct super_block sb __attribute__ ((unused)); + sb.s_d_op = NULL; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_S_D_OP], [ + AC_MSG_CHECKING([whether super_block has s_d_op]) + ZFS_LINUX_TEST_RESULT([super_block_s_d_op], [ + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([super_block s_d_op]) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY], [ + ZFS_AC_KERNEL_SRC_D_MAKE_ROOT + ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS + ZFS_AC_KERNEL_SRC_D_PRUNE_ALIASES + ZFS_AC_KERNEL_SRC_D_SET_D_OP + ZFS_AC_KERNEL_SRC_D_REVALIDATE_NAMEIDATA + ZFS_AC_KERNEL_SRC_CONST_DENTRY_OPERATIONS + ZFS_AC_KERNEL_SRC_S_D_OP +]) + +AC_DEFUN([ZFS_AC_KERNEL_DENTRY], [ + ZFS_AC_KERNEL_D_MAKE_ROOT + ZFS_AC_KERNEL_D_OBTAIN_ALIAS + ZFS_AC_KERNEL_D_PRUNE_ALIASES + ZFS_AC_KERNEL_D_SET_D_OP + ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA + ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS + ZFS_AC_KERNEL_S_D_OP +]) diff --git a/config/kernel-dirty-inode.m4 b/config/kernel-dirty-inode.m4 new file mode 100644 index 000000000000..dc7667fa4881 --- /dev/null +++ b/config/kernel-dirty-inode.m4 @@ -0,0 +1,29 @@ +dnl # +dnl # 3.0 API change +dnl # The sops->dirty_inode() callbacks were updated to take a flags +dnl # argument. This allows the greater control over whether the +dnl # filesystem needs to push out a transaction or not. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_DIRTY_INODE], [ + ZFS_LINUX_TEST_SRC([dirty_inode_with_flags], [ + #include <linux/fs.h> + + void dirty_inode(struct inode *a, int b) { return; } + + static const struct super_operations + sops __attribute__ ((unused)) = { + .dirty_inode = dirty_inode, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_DIRTY_INODE], [ + AC_MSG_CHECKING([whether sops->dirty_inode() wants flags]) + ZFS_LINUX_TEST_RESULT([dirty_inode_with_flags], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_DIRTY_INODE_WITH_FLAGS, 1, + [sops->dirty_inode() wants flags]) + ],[ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/config/kernel-discard-granularity.m4 b/config/kernel-discard-granularity.m4 new file mode 100644 index 000000000000..61326e67732b --- /dev/null +++ b/config/kernel-discard-granularity.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 2.6.33 API change +dnl # Discard granularity and alignment restrictions may now be set. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_DISCARD_GRANULARITY], [ + ZFS_LINUX_TEST_SRC([discard_granularity], [ + #include <linux/blkdev.h> + ],[ + struct queue_limits ql __attribute__ ((unused)); + ql.discard_granularity = 0; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_DISCARD_GRANULARITY], [ + AC_MSG_CHECKING([whether ql->discard_granularity is available]) + ZFS_LINUX_TEST_RESULT([discard_granularity], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([ql->discard_granularity]) + ]) +]) diff --git a/config/kernel-encode-fh-inode.m4 b/config/kernel-encode-fh-inode.m4 new file mode 100644 index 000000000000..9d4ba5f0f61f --- /dev/null +++ b/config/kernel-encode-fh-inode.m4 @@ -0,0 +1,27 @@ +dnl # +dnl # 3.5.0 API change +dnl # torvalds/linux@b0b0382bb4904965a9e9fca77ad87514dfda0d1c changed the +dnl # ->encode_fh() callback to pass the child inode and its parents inode +dnl # rather than a dentry and a boolean saying whether we want the parent. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE], [ + ZFS_LINUX_TEST_SRC([export_operations_encode_fh], [ + #include <linux/exportfs.h> + int encode_fh(struct inode *inode, __u32 *fh, int *max_len, + struct inode *parent) { return 0; } + static struct export_operations eops __attribute__ ((unused))={ + .encode_fh = encode_fh, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE], [ + AC_MSG_CHECKING([whether eops->encode_fh() wants inode]) + ZFS_LINUX_TEST_RESULT([export_operations_encode_fh], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_ENCODE_FH_WITH_INODE, 1, + [eops->encode_fh() wants child and parent inodes]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-evict-inode.m4 b/config/kernel-evict-inode.m4 new file mode 100644 index 000000000000..66f10492de54 --- /dev/null +++ b/config/kernel-evict-inode.m4 @@ -0,0 +1,24 @@ +dnl # +dnl # 2.6.36 API change +dnl # The sops->delete_inode() and sops->clear_inode() callbacks have +dnl # replaced by a single sops->evict_inode() callback. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_EVICT_INODE], [ + ZFS_LINUX_TEST_SRC([evict_inode], [ + #include <linux/fs.h> + void evict_inode (struct inode * t) { return; } + static struct super_operations sops __attribute__ ((unused)) = { + .evict_inode = evict_inode, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_EVICT_INODE], [ + AC_MSG_CHECKING([whether sops->evict_inode() exists]) + ZFS_LINUX_TEST_RESULT([evict_inode], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_EVICT_INODE, 1, [sops->evict_inode() exists]) + ],[ + ZFS_LINUX_TEST_ERROR([evict_inode]) + ]) +]) diff --git a/config/kernel-fallocate.m4 b/config/kernel-fallocate.m4 new file mode 100644 index 000000000000..7a8550f7e760 --- /dev/null +++ b/config/kernel-fallocate.m4 @@ -0,0 +1,27 @@ +dnl # +dnl # Linux 2.6.38 - 3.x API +dnl # The fallocate callback was moved from the inode_operations +dnl # structure to the file_operations structure. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_FALLOCATE], [ + ZFS_LINUX_TEST_SRC([file_fallocate], [ + #include <linux/fs.h> + + long test_fallocate(struct file *file, int mode, + loff_t offset, loff_t len) { return 0; } + + static const struct file_operations + fops __attribute__ ((unused)) = { + .fallocate = test_fallocate, + }; + ], []) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FALLOCATE], [ + AC_MSG_CHECKING([whether fops->fallocate() exists]) + ZFS_LINUX_TEST_RESULT([file_fallocate], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([file_fallocate]) + ]) +]) diff --git a/config/kernel-file-dentry.m4 b/config/kernel-file-dentry.m4 new file mode 100644 index 000000000000..9cb5869c3821 --- /dev/null +++ b/config/kernel-file-dentry.m4 @@ -0,0 +1,24 @@ +dnl # +dnl # 4.1 API change +dnl # struct access file->f_path.dentry was replaced by accessor function +dnl # since fix torvalds/linux@4bacc9c9234c ("overlayfs: Make f_path always +dnl # point to the overlay and f_inode to the underlay"). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_FILE_DENTRY], [ + ZFS_LINUX_TEST_SRC([file_dentry], [ + #include <linux/fs.h> + ],[ + struct file *f = NULL; + file_dentry(f); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FILE_DENTRY], [ + AC_MSG_CHECKING([whether file_dentry() is available]) + ZFS_LINUX_TEST_RESULT([file_dentry], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_FILE_DENTRY, 1, [file_dentry() is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-file-inode.m4 b/config/kernel-file-inode.m4 new file mode 100644 index 000000000000..00a3621657ad --- /dev/null +++ b/config/kernel-file-inode.m4 @@ -0,0 +1,23 @@ +dnl # +dnl # 3.19 API change +dnl # struct access f->f_dentry->d_inode was replaced by accessor function +dnl # file_inode(f) +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_FILE_INODE], [ + ZFS_LINUX_TEST_SRC([file_inode], [ + #include <linux/fs.h> + ],[ + struct file *f = NULL; + file_inode(f); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FILE_INODE], [ + AC_MSG_CHECKING([whether file_inode() is available]) + ZFS_LINUX_TEST_RESULT([file_inode], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_FILE_INODE, 1, [file_inode() is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-fmode-t.m4 b/config/kernel-fmode-t.m4 new file mode 100644 index 000000000000..5f111e21b443 --- /dev/null +++ b/config/kernel-fmode-t.m4 @@ -0,0 +1,20 @@ +dnl # +dnl # 2.6.28 API change, +dnl # check if fmode_t typedef is defined +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_FMODE_T], [ + ZFS_LINUX_TEST_SRC([type_fmode_t], [ + #include <linux/types.h> + ],[ + fmode_t *ptr __attribute__ ((unused)); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FMODE_T], [ + AC_MSG_CHECKING([whether kernel defines fmode_t]) + ZFS_LINUX_TEST_RESULT([type_fmode_t], [ + AC_MSG_RESULT([yes]) + ],[ + ZFS_LINUX_TEST_ERROR([type_fmode_t]) + ]) +]) diff --git a/config/kernel-follow-down-one.m4 b/config/kernel-follow-down-one.m4 new file mode 100644 index 000000000000..38c460d3506e --- /dev/null +++ b/config/kernel-follow-down-one.m4 @@ -0,0 +1,22 @@ +dnl # +dnl # 2.6.38 API change +dnl # follow_down() renamed follow_down_one(). The original follow_down() +dnl # symbol still exists but will traverse down all the layers. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE], [ + ZFS_LINUX_TEST_SRC([follow_down_one], [ + #include <linux/namei.h> + ],[ + struct path *p = NULL; + follow_down_one(p); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_DOWN_ONE], [ + AC_MSG_CHECKING([whether follow_down_one() is available]) + ZFS_LINUX_TEST_RESULT([follow_down_one], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([follow_down_one()]) + ]) +]) diff --git a/config/kernel-fpu.m4 b/config/kernel-fpu.m4 new file mode 100644 index 000000000000..3c7933413d18 --- /dev/null +++ b/config/kernel-fpu.m4 @@ -0,0 +1,131 @@ +dnl # +dnl # Handle differences in kernel FPU code. +dnl # +dnl # Kernel +dnl # 5.0: Wrappers have been introduced to save/restore the FPU state. +dnl # This change was made to the 4.19.38 and 4.14.120 LTS kernels. +dnl # HAVE_KERNEL_FPU_INTERNAL +dnl # +dnl # 4.2: Use __kernel_fpu_{begin,end}() +dnl # HAVE_UNDERSCORE_KERNEL_FPU & KERNEL_EXPORTS_X86_FPU +dnl # +dnl # Pre-4.2: Use kernel_fpu_{begin,end}() +dnl # HAVE_KERNEL_FPU & KERNEL_EXPORTS_X86_FPU +dnl # +dnl # N.B. The header check is performed before all other checks since it +dnl # depends on HAVE_KERNEL_FPU_API_HEADER being set in confdefs.h. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_FPU_HEADER], [ + AC_MSG_CHECKING([whether fpu headers are available]) + ZFS_LINUX_TRY_COMPILE([ + #include <linux/module.h> + #include <asm/fpu/api.h> + ],[ + ],[ + AC_DEFINE(HAVE_KERNEL_FPU_API_HEADER, 1, + [kernel has asm/fpu/api.h]) + AC_MSG_RESULT(asm/fpu/api.h) + ],[ + AC_MSG_RESULT(i387.h & xcr.h) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_FPU], [ + ZFS_LINUX_TEST_SRC([kernel_fpu], [ + #include <linux/types.h> + #ifdef HAVE_KERNEL_FPU_API_HEADER + #include <asm/fpu/api.h> + #else + #include <asm/i387.h> + #include <asm/xcr.h> + #endif + ], [ + kernel_fpu_begin(); + kernel_fpu_end(); + ], [], [$ZFS_META_LICENSE]) + + ZFS_LINUX_TEST_SRC([__kernel_fpu], [ + #include <linux/types.h> + #ifdef HAVE_KERNEL_FPU_API_HEADER + #include <asm/fpu/api.h> + #else + #include <asm/i387.h> + #include <asm/xcr.h> + #endif + ], [ + __kernel_fpu_begin(); + __kernel_fpu_end(); + ], [], [$ZFS_META_LICENSE]) + + ZFS_LINUX_TEST_SRC([fpu_internal], [ + #if defined(__x86_64) || defined(__x86_64__) || \ + defined(__i386) || defined(__i386__) + #if !defined(__x86) + #define __x86 + #endif + #endif + + #if !defined(__x86) + #error Unsupported architecture + #endif + + #include <linux/types.h> + #ifdef HAVE_KERNEL_FPU_API_HEADER + #include <asm/fpu/api.h> + #include <asm/fpu/internal.h> + #else + #include <asm/i387.h> + #include <asm/xcr.h> + #endif + + #if !defined(XSTATE_XSAVE) + #error XSTATE_XSAVE not defined + #endif + + #if !defined(XSTATE_XRESTORE) + #error XSTATE_XRESTORE not defined + #endif + ],[ + struct fpu *fpu = ¤t->thread.fpu; + union fpregs_state *st = &fpu->state; + struct fregs_state *fr __attribute__ ((unused)) = &st->fsave; + struct fxregs_state *fxr __attribute__ ((unused)) = &st->fxsave; + struct xregs_state *xr __attribute__ ((unused)) = &st->xsave; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FPU], [ + dnl # + dnl # Legacy kernel + dnl # + AC_MSG_CHECKING([whether kernel fpu is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([kernel_fpu_license], + [kernel_fpu_begin], [arch/x86/kernel/fpu/core.c], [ + AC_MSG_RESULT(kernel_fpu_*) + AC_DEFINE(HAVE_KERNEL_FPU, 1, + [kernel has kernel_fpu_* functions]) + AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1, + [kernel exports FPU functions]) + ],[ + dnl # + dnl # Linux 4.2 kernel + dnl # + ZFS_LINUX_TEST_RESULT_SYMBOL([__kernel_fpu_license], + [__kernel_fpu_begin], + [arch/x86/kernel/fpu/core.c arch/x86/kernel/i387.c], [ + AC_MSG_RESULT(__kernel_fpu_*) + AC_DEFINE(HAVE_UNDERSCORE_KERNEL_FPU, 1, + [kernel has __kernel_fpu_* functions]) + AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1, + [kernel exports FPU functions]) + ],[ + ZFS_LINUX_TEST_RESULT([fpu_internal], [ + AC_MSG_RESULT(internal) + AC_DEFINE(HAVE_KERNEL_FPU_INTERNAL, 1, + [kernel fpu internal]) + ],[ + AC_MSG_RESULT(unavailable) + ]) + ]) + ]) +]) diff --git a/config/kernel-fst-mount.m4 b/config/kernel-fst-mount.m4 new file mode 100644 index 000000000000..576f5f0129c5 --- /dev/null +++ b/config/kernel-fst-mount.m4 @@ -0,0 +1,30 @@ +dnl # +dnl # 2.6.38 API change +dnl # The .get_sb callback has been replaced by a .mount callback +dnl # in the file_system_type structure. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_FST_MOUNT], [ + ZFS_LINUX_TEST_SRC([file_system_type_mount], [ + #include <linux/fs.h> + + static struct dentry * + mount(struct file_system_type *fs_type, int flags, + const char *osname, void *data) { + struct dentry *d = NULL; + return (d); + } + + static struct file_system_type fst __attribute__ ((unused)) = { + .mount = mount, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FST_MOUNT], [ + AC_MSG_CHECKING([whether fst->mount() exists]) + ZFS_LINUX_TEST_RESULT([file_system_type_mount], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([fst->mount()]) + ]) +]) diff --git a/config/kernel-fsync.m4 b/config/kernel-fsync.m4 new file mode 100644 index 000000000000..d198191d3ab9 --- /dev/null +++ b/config/kernel-fsync.m4 @@ -0,0 +1,53 @@ +dnl # +dnl # Check file_operations->fsync interface. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_FSYNC], [ + ZFS_LINUX_TEST_SRC([fsync_without_dentry], [ + #include <linux/fs.h> + + int test_fsync(struct file *f, int x) { return 0; } + + static const struct file_operations + fops __attribute__ ((unused)) = { + .fsync = test_fsync, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([fsync_range], [ + #include <linux/fs.h> + + int test_fsync(struct file *f, loff_t a, loff_t b, int c) + { return 0; } + + static const struct file_operations + fops __attribute__ ((unused)) = { + .fsync = test_fsync, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FSYNC], [ + dnl # + dnl # Linux 2.6.35 - Linux 3.0 API + dnl # + AC_MSG_CHECKING([whether fops->fsync() wants no dentry]) + ZFS_LINUX_TEST_RESULT([fsync_without_dentry], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_FSYNC_WITHOUT_DENTRY, 1, + [fops->fsync() without dentry]) + ],[ + AC_MSG_RESULT([no]) + + dnl # + dnl # Linux 3.1 - 3.x API + dnl # + AC_MSG_CHECKING([whether fops->fsync() wants range]) + ZFS_LINUX_TEST_RESULT([fsync_range], [ + AC_MSG_RESULT([range]) + AC_DEFINE(HAVE_FSYNC_RANGE, 1, + [fops->fsync() with range]) + ],[ + ZFS_LINUX_TEST_ERROR([fops->fsync]) + ]) + ]) +]) diff --git a/config/kernel-generic_io_acct.m4 b/config/kernel-generic_io_acct.m4 new file mode 100644 index 000000000000..423b3e5a3521 --- /dev/null +++ b/config/kernel-generic_io_acct.m4 @@ -0,0 +1,64 @@ +dnl # +dnl # Check for generic io accounting interface. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [ + ZFS_LINUX_TEST_SRC([generic_acct_3args], [ + #include <linux/bio.h> + + void (*generic_start_io_acct_f)(int, unsigned long, + struct hd_struct *) = &generic_start_io_acct; + void (*generic_end_io_acct_f)(int, struct hd_struct *, + unsigned long) = &generic_end_io_acct; + ], [ + generic_start_io_acct(0, 0, NULL); + generic_end_io_acct(0, NULL, 0); + ]) + + ZFS_LINUX_TEST_SRC([generic_acct_4args], [ + #include <linux/bio.h> + + void (*generic_start_io_acct_f)(struct request_queue *, int, + unsigned long, struct hd_struct *) = &generic_start_io_acct; + void (*generic_end_io_acct_f)(struct request_queue *, int, + struct hd_struct *, unsigned long) = &generic_end_io_acct; + ], [ + generic_start_io_acct(NULL, 0, 0, NULL); + generic_end_io_acct(NULL, 0, NULL, 0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [ + dnl # + dnl # 3.19 API addition + dnl # + dnl # torvalds/linux@394ffa50 allows us to increment iostat + dnl # counters without generic_make_request(). + dnl # + AC_MSG_CHECKING([whether generic IO accounting wants 3 args]) + ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args], + [generic_start_io_acct], [block/bio.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1, + [generic_start_io_acct()/generic_end_io_acct() available]) + ], [ + AC_MSG_RESULT(no) + + dnl # + dnl # Linux 4.14 API, + dnl # + dnl # generic_start_io_acct/generic_end_io_acct now require + dnl # request_queue to be provided. No functional changes, + dnl # but preparation for inflight accounting. + dnl # + AC_MSG_CHECKING([whether generic IO accounting wants 4 args]) + ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args], + [generic_start_io_acct], [block/bio.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1, + [generic_start_io_acct()/generic_end_io_acct() ] + [4 arg available]) + ], [ + AC_MSG_RESULT(no) + ]) + ]) +]) diff --git a/config/kernel-generic_readlink.m4 b/config/kernel-generic_readlink.m4 new file mode 100644 index 000000000000..a7a33b408abd --- /dev/null +++ b/config/kernel-generic_readlink.m4 @@ -0,0 +1,25 @@ +dnl # +dnl # 4.10 API +dnl # +dnl # NULL inode_operations.readlink implies generic_readlink(), which +dnl # has been made static. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_READLINK_GLOBAL], [ + ZFS_LINUX_TEST_SRC([generic_readlink_global], [ + #include <linux/fs.h> + ],[ + int i __attribute__ ((unused)); + i = generic_readlink(NULL, NULL, 0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL], [ + AC_MSG_CHECKING([whether generic_readlink is global]) + ZFS_LINUX_TEST_RESULT([generic_readlink_global], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_GENERIC_READLINK, 1, + [generic_readlink is global]) + ],[ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/config/kernel-get-disk-and-module.m4 b/config/kernel-get-disk-and-module.m4 new file mode 100644 index 000000000000..51cf7743cf0b --- /dev/null +++ b/config/kernel-get-disk-and-module.m4 @@ -0,0 +1,24 @@ +dnl # +dnl # 4.16 API change +dnl # Verify if get_disk_and_module() symbol is available. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_DISK_AND_MODULE], [ + ZFS_LINUX_TEST_SRC([get_disk_and_module], [ + #include <linux/genhd.h> + ], [ + struct gendisk *disk = NULL; + (void) get_disk_and_module(disk); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_AND_MODULE], [ + AC_MSG_CHECKING([whether get_disk_and_module() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([get_disk_and_module], + [get_disk_and_module], [block/genhd.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GET_DISK_AND_MODULE, + 1, [get_disk_and_module() is available]) + ], [ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-get-disk-ro.m4 b/config/kernel-get-disk-ro.m4 new file mode 100644 index 000000000000..8a379c7669fa --- /dev/null +++ b/config/kernel-get-disk-ro.m4 @@ -0,0 +1,20 @@ +dnl # +dnl # 2.6.x API change +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_DISK_RO], [ + ZFS_LINUX_TEST_SRC([get_disk_ro], [ + #include <linux/blkdev.h> + ],[ + struct gendisk *disk = NULL; + (void) get_disk_ro(disk); + ], [$NO_UNUSED_BUT_SET_VARIABLE]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GET_DISK_RO], [ + AC_MSG_CHECKING([whether get_disk_ro() is available]) + ZFS_LINUX_TEST_RESULT([get_disk_ro], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([get_disk_ro()]) + ]) +]) diff --git a/config/kernel-get-link.m4 b/config/kernel-get-link.m4 new file mode 100644 index 000000000000..e4f478e37c18 --- /dev/null +++ b/config/kernel-get-link.m4 @@ -0,0 +1,104 @@ +dnl # +dnl # Supported get_link() interfaces checked newest to oldest. +dnl # Note this interface used to be named follow_link. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GET_LINK], [ + ZFS_LINUX_TEST_SRC([inode_operations_get_link], [ + #include <linux/fs.h> + const char *get_link(struct dentry *de, struct inode *ip, + struct delayed_call *done) { return "symlink"; } + static struct inode_operations + iops __attribute__ ((unused)) = { + .get_link = get_link, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([inode_operations_get_link_cookie], [ + #include <linux/fs.h> + const char *get_link(struct dentry *de, struct + inode *ip, void **cookie) { return "symlink"; } + static struct inode_operations + iops __attribute__ ((unused)) = { + .get_link = get_link, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([inode_operations_follow_link], [ + #include <linux/fs.h> + const char *follow_link(struct dentry *de, + void **cookie) { return "symlink"; } + static struct inode_operations + iops __attribute__ ((unused)) = { + .follow_link = follow_link, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([inode_operations_follow_link_nameidata], [ + #include <linux/fs.h> + void *follow_link(struct dentry *de, struct + nameidata *nd) { return (void *)NULL; } + static struct inode_operations + iops __attribute__ ((unused)) = { + .follow_link = follow_link, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [ + dnl # + dnl # 4.5 API change + dnl # The get_link interface has added a delayed done call and + dnl # used it to retire the put_link() interface. + dnl # + AC_MSG_CHECKING([whether iops->get_link() passes delayed]) + ZFS_LINUX_TEST_RESULT([inode_operations_get_link], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GET_LINK_DELAYED, 1, [iops->get_link() delayed]) + ],[ + AC_MSG_RESULT(no) + + dnl # + dnl # 4.5 API change + dnl # The follow_link() interface has been replaced by + dnl # get_link() which behaves the same as before except: + dnl # - An inode is passed as a separate argument + dnl # - When called in RCU mode a NULL dentry is passed. + dnl # + AC_MSG_CHECKING([whether iops->get_link() passes cookie]) + ZFS_LINUX_TEST_RESULT([inode_operations_get_link_cookie], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GET_LINK_COOKIE, 1, + [iops->get_link() cookie]) + ],[ + AC_MSG_RESULT(no) + + dnl # + dnl # 4.2 API change + dnl # This kernel retired the nameidata structure. + dnl # + AC_MSG_CHECKING( + [whether iops->follow_link() passes cookie]) + ZFS_LINUX_TEST_RESULT([inode_operations_follow_link], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_FOLLOW_LINK_COOKIE, 1, + [iops->follow_link() cookie]) + ],[ + AC_MSG_RESULT(no) + + dnl # + dnl # 2.6.32 API + dnl # + AC_MSG_CHECKING( + [whether iops->follow_link() passes nameidata]) + ZFS_LINUX_TEST_RESULT( + [inode_operations_follow_link_nameidata],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1, + [iops->follow_link() nameidata]) + ],[ + ZFS_LINUX_TEST_ERROR([get_link]) + ]) + ]) + ]) + ]) +]) diff --git a/config/kernel-global_page_state.m4 b/config/kernel-global_page_state.m4 new file mode 100644 index 000000000000..75043f40beca --- /dev/null +++ b/config/kernel-global_page_state.m4 @@ -0,0 +1,137 @@ +dnl # +dnl # 4.8 API change +dnl # +dnl # 75ef71840539 mm, vmstat: add infrastructure for per-node vmstats +dnl # 599d0c954f91 mm, vmscan: move LRU lists to node +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_NODE_PAGE_STATE], [ + ZFS_LINUX_TEST_SRC([global_node_page_state], [ + #include <linux/mm.h> + #include <linux/vmstat.h> + ],[ + (void) global_node_page_state(0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE], [ + AC_MSG_CHECKING([whether global_node_page_state() exists]) + ZFS_LINUX_TEST_RESULT([global_node_page_state], [ + AC_MSG_RESULT(yes) + AC_DEFINE(ZFS_GLOBAL_NODE_PAGE_STATE, 1, + [global_node_page_state() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.14 API change +dnl # +dnl # c41f012ade0b mm: rename global_page_state to global_zone_page_state +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_ZONE_PAGE_STATE], [ + ZFS_LINUX_TEST_SRC([global_zone_page_state], [ + #include <linux/mm.h> + #include <linux/vmstat.h> + ],[ + (void) global_zone_page_state(0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE], [ + AC_MSG_CHECKING([whether global_zone_page_state() exists]) + ZFS_LINUX_TEST_RESULT([global_zone_page_state], [ + AC_MSG_RESULT(yes) + AC_DEFINE(ZFS_GLOBAL_ZONE_PAGE_STATE, 1, + [global_zone_page_state() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # Create a define and autoconf variable for an enum member +dnl # +AC_DEFUN([ZFS_AC_KERNEL_ENUM_MEMBER], [ + AC_MSG_CHECKING([whether enum $2 contains $1]) + AS_IF([AC_TRY_COMMAND( + "${srcdir}/scripts/enum-extract.pl" "$2" "$3" | egrep -qx $1)],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(m4_join([_], [ZFS_ENUM], m4_toupper($2), $1), 1, + [enum $2 contains $1]) + m4_join([_], [ZFS_ENUM], m4_toupper($2), $1)=1 + ],[ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # Sanity check helpers +dnl # +AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR],[ + AC_MSG_RESULT(no) + AC_MSG_RESULT([$1 in either node_stat_item or zone_stat_item: $2]) + ZFS_LINUX_TEST_ERROR([global page state]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK], [ + enum_check_a="m4_join([_], [$ZFS_ENUM_NODE_STAT_ITEM], $1)" + enum_check_b="m4_join([_], [$ZFS_ENUM_ZONE_STAT_ITEM], $1)" + AS_IF([test -n "$enum_check_a" -a -n "$enum_check_b"],[ + ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR([$1], [DUPLICATE]) + ]) + AS_IF([test -z "$enum_check_a" -a -z "$enum_check_b"],[ + ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_ERROR([$1], [NOT FOUND]) + ]) +]) + +dnl # +dnl # Ensure the config tests are finding one and only one of each enum. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [ + AC_MSG_CHECKING([whether global_page_state enums are sane]) + + ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_FILE_PAGES]) + ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_ANON]) + ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_FILE]) + AS_IF([test -z "$ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE_B"],[ + ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_SLAB_RECLAIMABLE]) + ]) + + AC_MSG_RESULT(yes) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_GLOBAL_PAGE_STATE], [ + ZFS_AC_KERNEL_SRC_GLOBAL_NODE_PAGE_STATE + ZFS_AC_KERNEL_SRC_GLOBAL_ZONE_PAGE_STATE +]) + +dnl # +dnl # enum members in which we're interested +dnl # +AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE], [ + ZFS_AC_KERNEL_GLOBAL_NODE_PAGE_STATE + ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE + + ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES], + [node_stat_item], [$LINUX/include/linux/mmzone.h]) + ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON], + [node_stat_item], [$LINUX/include/linux/mmzone.h]) + ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE], + [node_stat_item], [$LINUX/include/linux/mmzone.h]) + ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE], + [node_stat_item], [$LINUX/include/linux/mmzone.h]) + ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE_B], + [node_stat_item], [$LINUX/include/linux/mmzone.h]) + + ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES], + [zone_stat_item], [$LINUX/include/linux/mmzone.h]) + ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_ANON], + [zone_stat_item], [$LINUX/include/linux/mmzone.h]) + ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE], + [zone_stat_item], [$LINUX/include/linux/mmzone.h]) + ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE], + [zone_stat_item], [$LINUX/include/linux/mmzone.h]) + + ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY +]) diff --git a/config/kernel-group-info.m4 b/config/kernel-group-info.m4 new file mode 100644 index 000000000000..0fee1d36d50d --- /dev/null +++ b/config/kernel-group-info.m4 @@ -0,0 +1,22 @@ +dnl # +dnl # 4.9 API change +dnl # group_info changed from 2d array via >blocks to 1d array via ->gid +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GROUP_INFO_GID], [ + ZFS_LINUX_TEST_SRC([group_info_gid], [ + #include <linux/cred.h> + ],[ + struct group_info *gi = groups_alloc(1); + gi->gid[0] = KGIDT_INIT(0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GROUP_INFO_GID], [ + AC_MSG_CHECKING([whether group_info->gid exists]) + ZFS_LINUX_TEST_RESULT([group_info_gid], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GROUP_INFO_GID, 1, [group_info->gid exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-in-compat-syscall.m4 b/config/kernel-in-compat-syscall.m4 new file mode 100644 index 000000000000..baaac8c4fda2 --- /dev/null +++ b/config/kernel-in-compat-syscall.m4 @@ -0,0 +1,24 @@ +dnl # +dnl # 4.5 API change +dnl # Added in_compat_syscall() which can be overridden on a per- +dnl # architecture basis. Prior to this is_compat_task() was the +dnl # provided interface. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL], [ + ZFS_LINUX_TEST_SRC([in_compat_syscall], [ + #include <linux/compat.h> + ],[ + in_compat_syscall(); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_IN_COMPAT_SYSCALL], [ + AC_MSG_CHECKING([whether in_compat_syscall() is available]) + ZFS_LINUX_TEST_RESULT([in_compat_syscall], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_IN_COMPAT_SYSCALL, 1, + [in_compat_syscall() is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-inode-create.m4 b/config/kernel-inode-create.m4 new file mode 100644 index 000000000000..9f28bcbd4f7f --- /dev/null +++ b/config/kernel-inode-create.m4 @@ -0,0 +1,26 @@ +dnl # +dnl # 3.6 API change +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [ + ZFS_LINUX_TEST_SRC([create_flags], [ + #include <linux/fs.h> + #include <linux/sched.h> + + int inode_create(struct inode *inode ,struct dentry *dentry, + umode_t umode, bool flag) { return 0; } + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .create = inode_create, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CREATE_FLAGS], [ + AC_MSG_CHECKING([whether iops->create() passes flags]) + ZFS_LINUX_TEST_RESULT([create_flags], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([iops->create()]) + ]) +]) diff --git a/config/kernel-inode-getattr.m4 b/config/kernel-inode-getattr.m4 new file mode 100644 index 000000000000..48391d66f8bd --- /dev/null +++ b/config/kernel-inode-getattr.m4 @@ -0,0 +1,53 @@ +dnl # +dnl # Linux 4.11 API +dnl # See torvalds/linux@a528d35 +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [ + ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [ + #include <linux/fs.h> + + int test_getattr( + const struct path *p, struct kstat *k, + u32 request_mask, unsigned int query_flags) + { return 0; } + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .getattr = test_getattr, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([inode_operations_getattr_vfsmount], [ + #include <linux/fs.h> + + int test_getattr( + struct vfsmount *mnt, struct dentry *d, + struct kstat *k) + { return 0; } + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .getattr = test_getattr, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [ + AC_MSG_CHECKING([whether iops->getattr() takes a path]) + ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1, + [iops->getattr() takes a path]) + ],[ + AC_MSG_RESULT(no) + + AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount]) + ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1, + [iops->getattr() takes a vfsmount]) + ],[ + AC_MSG_RESULT(no) + ]) + ]) +]) diff --git a/config/kernel-inode-lock.m4 b/config/kernel-inode-lock.m4 new file mode 100644 index 000000000000..5eb04af78771 --- /dev/null +++ b/config/kernel-inode-lock.m4 @@ -0,0 +1,24 @@ +dnl # +dnl # 4.7 API change +dnl # i_mutex is changed to i_rwsem. Instead of directly using +dnl # i_mutex/i_rwsem, we should use inode_lock() and inode_lock_shared() +dnl # We test inode_lock_shared because inode_lock is introduced earlier. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_LOCK], [ + ZFS_LINUX_TEST_SRC([inode_lock], [ + #include <linux/fs.h> + ],[ + struct inode *inode = NULL; + inode_lock_shared(inode); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INODE_LOCK], [ + AC_MSG_CHECKING([whether inode_lock_shared() exists]) + ZFS_LINUX_TEST_RESULT([inode_lock], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_INODE_LOCK_SHARED, 1, [yes]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-inode-lookup.m4 b/config/kernel-inode-lookup.m4 new file mode 100644 index 000000000000..1a56e69b04aa --- /dev/null +++ b/config/kernel-inode-lookup.m4 @@ -0,0 +1,26 @@ +dnl # +dnl # 3.6 API change +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS], [ + ZFS_LINUX_TEST_SRC([lookup_flags], [ + #include <linux/fs.h> + #include <linux/sched.h> + + struct dentry *inode_lookup(struct inode *inode, + struct dentry *dentry, unsigned int flags) { return NULL; } + + static const struct inode_operations iops + __attribute__ ((unused)) = { + .lookup = inode_lookup, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_FLAGS], [ + AC_MSG_CHECKING([whether iops->lookup() passes flags]) + ZFS_LINUX_TEST_RESULT([lookup_flags], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([iops->lookup()]) + ]) +]) diff --git a/config/kernel-inode-set-flags.m4 b/config/kernel-inode-set-flags.m4 new file mode 100644 index 000000000000..133f666a9517 --- /dev/null +++ b/config/kernel-inode-set-flags.m4 @@ -0,0 +1,22 @@ +dnl # +dnl # 3.15 API change +dnl # inode_set_flags introduced to set i_flags +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SET_FLAGS], [ + ZFS_LINUX_TEST_SRC([inode_set_flags], [ + #include <linux/fs.h> + ],[ + struct inode inode; + inode_set_flags(&inode, S_IMMUTABLE, S_IMMUTABLE); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_FLAGS], [ + AC_MSG_CHECKING([whether inode_set_flags() exists]) + ZFS_LINUX_TEST_RESULT([inode_set_flags], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_INODE_SET_FLAGS, 1, [inode_set_flags() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-inode-set-iversion.m4 b/config/kernel-inode-set-iversion.m4 new file mode 100644 index 000000000000..dd415de324a7 --- /dev/null +++ b/config/kernel-inode-set-iversion.m4 @@ -0,0 +1,23 @@ +dnl # +dnl # 4.16 API change +dnl # inode_set_iversion introduced to set i_version +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SET_IVERSION], [ + ZFS_LINUX_TEST_SRC([inode_set_iversion], [ + #include <linux/iversion.h> + ],[ + struct inode inode; + inode_set_iversion(&inode, 1); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INODE_SET_IVERSION], [ + AC_MSG_CHECKING([whether inode_set_iversion() exists]) + ZFS_LINUX_TEST_RESULT([inode_set_iversion], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_INODE_SET_IVERSION, 1, + [inode_set_iversion() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-inode-times.m4 b/config/kernel-inode-times.m4 new file mode 100644 index 000000000000..9c016c790081 --- /dev/null +++ b/config/kernel-inode-times.m4 @@ -0,0 +1,50 @@ +AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [ + + dnl # + dnl # 5.6 API change + dnl # timespec64_trunc() replaced by timestamp_truncate() interface. + dnl # + ZFS_LINUX_TEST_SRC([timestamp_truncate], [ + #include <linux/fs.h> + ],[ + struct timespec64 ts; + struct inode ip; + + memset(&ts, 0, sizeof(ts)); + ts = timestamp_truncate(ts, &ip); + ]) + + dnl # + dnl # 4.18 API change + dnl # i_atime, i_mtime, and i_ctime changed from timespec to timespec64. + dnl # + ZFS_LINUX_TEST_SRC([inode_times], [ + #include <linux/fs.h> + ],[ + struct inode ip; + struct timespec ts; + + memset(&ip, 0, sizeof(ip)); + ts = ip.i_mtime; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [ + AC_MSG_CHECKING([whether timestamp_truncate() exists]) + ZFS_LINUX_TEST_RESULT([timestamp_truncate], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_INODE_TIMESTAMP_TRUNCATE, 1, + [timestamp_truncate() exists]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([whether inode->i_*time's are timespec64]) + ZFS_LINUX_TEST_RESULT([inode_times], [ + AC_MSG_RESULT(no) + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1, + [inode->i_*time's are timespec64]) + ]) +]) diff --git a/config/kernel-insert-inode-locked.m4 b/config/kernel-insert-inode-locked.m4 new file mode 100644 index 000000000000..348aff9a5770 --- /dev/null +++ b/config/kernel-insert-inode-locked.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 2.6.28 API change +dnl # Added insert_inode_locked() helper function. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED], [ + ZFS_LINUX_TEST_SRC([insert_inode_locked], [ + #include <linux/fs.h> + ], [ + insert_inode_locked(NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INSERT_INODE_LOCKED], [ + AC_MSG_CHECKING([whether insert_inode_locked() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([insert_inode_locked], + [insert_inode_locked], [fs/inode.c], [ + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([insert_inode_locked()]) + ]) +]) diff --git a/config/kernel-is_owner_or_cap.m4 b/config/kernel-is_owner_or_cap.m4 new file mode 100644 index 000000000000..3df6163da270 --- /dev/null +++ b/config/kernel-is_owner_or_cap.m4 @@ -0,0 +1,23 @@ +dnl # +dnl # 2.6.39 API change, +dnl # The is_owner_or_cap() macro was renamed to inode_owner_or_capable(), +dnl # This is used for permission checks in the xattr and file attribute call +dnl # paths. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [ + ZFS_LINUX_TEST_SRC([inode_owner_or_capable], [ + #include <linux/fs.h> + ],[ + struct inode *ip = NULL; + (void) inode_owner_or_capable(ip); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [ + AC_MSG_CHECKING([whether inode_owner_or_capable() exists]) + ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([capability]) + ]) +]) diff --git a/config/kernel-kmap-atomic-args.m4 b/config/kernel-kmap-atomic-args.m4 new file mode 100644 index 000000000000..1172505afc68 --- /dev/null +++ b/config/kernel-kmap-atomic-args.m4 @@ -0,0 +1,22 @@ +dnl # +dnl # 2.6.37 API change +dnl # kmap_atomic changed from assigning hard-coded named slot to using +dnl # push/pop based dynamical allocation. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS], [ + ZFS_LINUX_TEST_SRC([kmap_atomic], [ + #include <linux/pagemap.h> + ],[ + struct page page; + kmap_atomic(&page); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS], [ + AC_MSG_CHECKING([whether kmap_atomic wants 1 args]) + ZFS_LINUX_TEST_RESULT([kmap_atomic], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([kmap_atomic()]) + ]) +]) diff --git a/config/kernel-kmem-cache.m4 b/config/kernel-kmem-cache.m4 new file mode 100644 index 000000000000..0e9fe9eb2a90 --- /dev/null +++ b/config/kernel-kmem-cache.m4 @@ -0,0 +1,41 @@ +dnl # +dnl # grsecurity API change, +dnl # kmem_cache_create() with SLAB_USERCOPY flag replaced by +dnl # kmem_cache_create_usercopy(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KMEM_CACHE_CREATE_USERCOPY], [ + ZFS_LINUX_TEST_SRC([kmem_cache_create_usercopy], [ + #include <linux/slab.h> + static void ctor(void *foo) { /* fake ctor */ } + ],[ + struct kmem_cache *skc_linux_cache; + const char *name = "test"; + size_t size = 4096; + size_t align = 8; + unsigned long flags = 0; + size_t useroffset = 0; + size_t usersize = size - useroffset; + + skc_linux_cache = kmem_cache_create_usercopy( + name, size, align, flags, useroffset, usersize, ctor); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY], [ + AC_MSG_CHECKING([whether kmem_cache_create_usercopy() exists]) + ZFS_LINUX_TEST_RESULT([kmem_cache_create_usercopy], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KMEM_CACHE_CREATE_USERCOPY, 1, + [kmem_cache_create_usercopy() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_KMEM_CACHE], [ + ZFS_AC_KERNEL_SRC_KMEM_CACHE_CREATE_USERCOPY +]) + +AC_DEFUN([ZFS_AC_KERNEL_KMEM_CACHE], [ + ZFS_AC_KERNEL_KMEM_CACHE_CREATE_USERCOPY +]) diff --git a/config/kernel-kmem.m4 b/config/kernel-kmem.m4 new file mode 100644 index 000000000000..43f9e72f88d8 --- /dev/null +++ b/config/kernel-kmem.m4 @@ -0,0 +1,108 @@ +dnl # +dnl # Enabled by default it provides a minimal level of memory tracking. +dnl # A total count of bytes allocated is kept for each alloc and free. +dnl # Then at module unload time a report to the console will be printed +dnl # if memory was leaked. +dnl # +AC_DEFUN([SPL_AC_DEBUG_KMEM], [ + AC_ARG_ENABLE([debug-kmem], + [AS_HELP_STRING([--enable-debug-kmem], + [Enable basic kmem accounting @<:@default=no@:>@])], + [], + [enable_debug_kmem=no]) + + AS_IF([test "x$enable_debug_kmem" = xyes], + [ + KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM" + DEBUG_KMEM="_with_debug_kmem" + AC_DEFINE([DEBUG_KMEM], [1], + [Define to 1 to enable basic kmem accounting]) + ], [ + DEBUG_KMEM="_without_debug_kmem" + ]) + + AC_SUBST(DEBUG_KMEM) + AC_MSG_CHECKING([whether basic kmem accounting is enabled]) + AC_MSG_RESULT([$enable_debug_kmem]) +]) + +dnl # +dnl # Disabled by default it provides detailed memory tracking. This +dnl # feature also requires --enable-debug-kmem to be set. When enabled +dnl # not only will total bytes be tracked but also the location of every +dnl # alloc and free. When the SPL module is unloaded a list of all leaked +dnl # addresses and where they were allocated will be dumped to the console. +dnl # Enabling this feature has a significant impact on performance but it +dnl # makes finding memory leaks pretty straight forward. +dnl # +AC_DEFUN([SPL_AC_DEBUG_KMEM_TRACKING], [ + AC_ARG_ENABLE([debug-kmem-tracking], + [AS_HELP_STRING([--enable-debug-kmem-tracking], + [Enable detailed kmem tracking @<:@default=no@:>@])], + [], + [enable_debug_kmem_tracking=no]) + + AS_IF([test "x$enable_debug_kmem_tracking" = xyes], + [ + KERNELCPPFLAGS="${KERNELCPPFLAGS} -DDEBUG_KMEM_TRACKING" + DEBUG_KMEM_TRACKING="_with_debug_kmem_tracking" + AC_DEFINE([DEBUG_KMEM_TRACKING], [1], + [Define to 1 to enable detailed kmem tracking]) + ], [ + DEBUG_KMEM_TRACKING="_without_debug_kmem_tracking" + ]) + + AC_SUBST(DEBUG_KMEM_TRACKING) + AC_MSG_CHECKING([whether detailed kmem tracking is enabled]) + AC_MSG_RESULT([$enable_debug_kmem_tracking]) +]) + +dnl # +dnl # 4.12 API, +dnl # Added kvmalloc allocation strategy +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KVMALLOC], [ + ZFS_LINUX_TEST_SRC([kvmalloc], [ + #include <linux/mm.h> + ],[ + void *p __attribute__ ((unused)); + + p = kvmalloc(0, GFP_KERNEL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KVMALLOC], [ + AC_MSG_CHECKING([whether kvmalloc(ptr, flags) is available]) + ZFS_LINUX_TEST_RESULT([kvmalloc], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KVMALLOC, 1, [kvmalloc exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 5.8 API, +dnl # __vmalloc PAGE_KERNEL removal +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VMALLOC_PAGE_KERNEL], [ + ZFS_LINUX_TEST_SRC([__vmalloc], [ + #include <linux/mm.h> + #include <linux/vmalloc.h> + ],[ + void *p __attribute__ ((unused)); + + p = __vmalloc(0, GFP_KERNEL, PAGE_KERNEL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VMALLOC_PAGE_KERNEL], [ + AC_MSG_CHECKING([whether __vmalloc(ptr, flags, pageflags) is available]) + ZFS_LINUX_TEST_RESULT([__vmalloc], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_VMALLOC_PAGE_KERNEL, 1, [__vmalloc page flags exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) +-
\ No newline at end of file diff --git a/config/kernel-kstrtoul.m4 b/config/kernel-kstrtoul.m4 new file mode 100644 index 000000000000..8e4b542978a9 --- /dev/null +++ b/config/kernel-kstrtoul.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 2.6.39 API change +dnl # Added kstrtoul() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KSTRTOUL], [ + ZFS_LINUX_TEST_SRC([kstrtoul], [ + #include <linux/kernel.h> + ],[ + int ret __attribute__ ((unused)) = kstrtoul(NULL, 10, NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KSTRTOUL], [ + AC_MSG_CHECKING([whether kstrtoul() exists]) + ZFS_LINUX_TEST_RESULT([kstrtoul], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KSTRTOUL, 1, [kstrtoul() exists]) + ],[ + ZFS_LINUX_TEST_ERROR([kstrtoul()]) + ]) +]) diff --git a/config/kernel-ktime.m4 b/config/kernel-ktime.m4 new file mode 100644 index 000000000000..64c3b5f90328 --- /dev/null +++ b/config/kernel-ktime.m4 @@ -0,0 +1,55 @@ +dnl # +dnl # 4.18: ktime_get_coarse_real_ts64() replaces current_kernel_time64(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64], [ + ZFS_LINUX_TEST_SRC([ktime_get_coarse_real_ts64], [ + #include <linux/mm.h> + ], [ + struct timespec64 ts; + ktime_get_coarse_real_ts64(&ts); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64], [ + AC_MSG_CHECKING([whether ktime_get_coarse_real_ts64() exists]) + ZFS_LINUX_TEST_RESULT([ktime_get_coarse_real_ts64], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KTIME_GET_COARSE_REAL_TS64, 1, + [ktime_get_coarse_real_ts64() exists]) + ], [ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.18: ktime_get_raw_ts64() replaces getrawmonotonic64(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME_GET_RAW_TS64], [ + ZFS_LINUX_TEST_SRC([ktime_get_raw_ts64], [ + #include <linux/mm.h> + ], [ + struct timespec64 ts; + ktime_get_raw_ts64(&ts); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_RAW_TS64], [ + AC_MSG_CHECKING([whether ktime_get_raw_ts64() exists]) + ZFS_LINUX_TEST_RESULT([ktime_get_raw_ts64], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KTIME_GET_RAW_TS64, 1, + [ktime_get_raw_ts64() exists]) + ], [ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME], [ + ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64 + ZFS_AC_KERNEL_SRC_KTIME_GET_RAW_TS64 +]) + +AC_DEFUN([ZFS_AC_KERNEL_KTIME], [ + ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64 + ZFS_AC_KERNEL_KTIME_GET_RAW_TS64 +]) diff --git a/config/kernel-kuid-helpers.m4 b/config/kernel-kuid-helpers.m4 new file mode 100644 index 000000000000..38a439fa6ea9 --- /dev/null +++ b/config/kernel-kuid-helpers.m4 @@ -0,0 +1,24 @@ +dnl # +dnl # 3.5 API change, +dnl # Since usernamespaces were introduced in kernel version 3.5, it +dnl # became necessary to go through one more level of indirection +dnl # when dealing with uid/gid - namely the kuid type. +dnl # +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KUID_HELPERS], [ + ZFS_LINUX_TEST_SRC([i_uid_read], [ + #include <linux/fs.h> + ],[ + struct inode *ip = NULL; + (void) i_uid_read(ip); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KUID_HELPERS], [ + AC_MSG_CHECKING([whether i_(uid|gid)_(read|write) exist]) + ZFS_LINUX_TEST_RESULT([i_uid_read], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([i_uid_read]) + ]) +]) diff --git a/config/kernel-kuidgid.m4 b/config/kernel-kuidgid.m4 new file mode 100644 index 000000000000..b7e441408cb9 --- /dev/null +++ b/config/kernel-kuidgid.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 3.8 API change, +dnl # User namespaces, use kuid_t in place of uid_t where available. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KUIDGID_T], [ + ZFS_LINUX_TEST_SRC([kuidgid_t], [ + #include <linux/uidgid.h> + ], [ + kuid_t userid __attribute__ ((unused)) = KUIDT_INIT(0); + kgid_t groupid __attribute__ ((unused)) = KGIDT_INIT(0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KUIDGID_T], [ + AC_MSG_CHECKING([whether kuid_t/kgid_t is available]) + ZFS_LINUX_TEST_RESULT([kuidgid_t], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([kuid_t/kgid_t]) + ]) +]) diff --git a/config/kernel-lseek-execute.m4 b/config/kernel-lseek-execute.m4 new file mode 100644 index 000000000000..652f611f8da4 --- /dev/null +++ b/config/kernel-lseek-execute.m4 @@ -0,0 +1,27 @@ +dnl # +dnl # 3.11 API change +dnl # lseek_execute helper exported +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_LSEEK_EXECUTE], [ + ZFS_LINUX_TEST_SRC([lseek_execute], [ + #include <linux/fs.h> + ], [ + struct file *fp __attribute__ ((unused)) = NULL; + struct inode *ip __attribute__ ((unused)) = NULL; + loff_t offset __attribute__ ((unused)) = 0; + loff_t maxsize __attribute__ ((unused)) = 0; + + lseek_execute(fp, ip, offset, maxsize); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_LSEEK_EXECUTE], [ + AC_MSG_CHECKING([whether lseek_execute() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([lseek_execute], + [lseek_exclusive], [fs/read_write.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LSEEK_EXECUTE, 1, [lseek_execute() is available]) + ], [ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-make-request-fn.m4 b/config/kernel-make-request-fn.m4 new file mode 100644 index 000000000000..1576fece1368 --- /dev/null +++ b/config/kernel-make-request-fn.m4 @@ -0,0 +1,101 @@ +dnl # +dnl # Check for make_request_fn interface. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN], [ + ZFS_LINUX_TEST_SRC([make_request_fn_void], [ + #include <linux/blkdev.h> + void make_request(struct request_queue *q, + struct bio *bio) { return; } + ],[ + blk_queue_make_request(NULL, &make_request); + ]) + + ZFS_LINUX_TEST_SRC([make_request_fn_blk_qc_t], [ + #include <linux/blkdev.h> + blk_qc_t make_request(struct request_queue *q, + struct bio *bio) { return (BLK_QC_T_NONE); } + ],[ + blk_queue_make_request(NULL, &make_request); + ]) + + ZFS_LINUX_TEST_SRC([blk_alloc_queue_request_fn], [ + #include <linux/blkdev.h> + blk_qc_t make_request(struct request_queue *q, + struct bio *bio) { return (BLK_QC_T_NONE); } + ],[ + struct request_queue *q __attribute__ ((unused)); + q = blk_alloc_queue(make_request, NUMA_NO_NODE); + ]) + + ZFS_LINUX_TEST_SRC([block_device_operations_submit_bio], [ + #include <linux/blkdev.h> + ],[ + struct block_device_operations o; + o.submit_bio = NULL; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [ + dnl # Checked as part of the blk_alloc_queue_request_fn test + dnl # + dnl # Linux 5.9 API Change + dnl # make_request_fn was moved into block_device_operations->submit_bio + dnl # + AC_MSG_CHECKING([whether submit_bio is member of struct block_device_operations]) + ZFS_LINUX_TEST_RESULT([block_device_operations_submit_bio], [ + AC_MSG_RESULT(yes) + + AC_DEFINE(HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS, 1, + [submit_bio is member of struct block_device_operations]) + ],[ + dnl # Checked as part of the blk_alloc_queue_request_fn test + dnl # + dnl # Linux 5.7 API Change + dnl # blk_alloc_queue() expects request function. + dnl # + AC_MSG_CHECKING([whether blk_alloc_queue() expects request function]) + ZFS_LINUX_TEST_RESULT([blk_alloc_queue_request_fn], [ + AC_MSG_CHECKING([whether make_request_fn() returns blk_qc_t]) + AC_MSG_RESULT(yes) + + AC_DEFINE(HAVE_BLK_ALLOC_QUEUE_REQUEST_FN, 1, + [blk_alloc_queue() expects request function]) + AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t, + [make_request_fn() return type]) + AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1, + [Noting that make_request_fn() returns blk_qc_t]) + ],[ + dnl # + dnl # Linux 3.2 API Change + dnl # make_request_fn returns void. + dnl # + AC_MSG_CHECKING([whether make_request_fn() returns void]) + ZFS_LINUX_TEST_RESULT([make_request_fn_void], [ + AC_MSG_RESULT(yes) + AC_DEFINE(MAKE_REQUEST_FN_RET, void, + [make_request_fn() return type]) + AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_VOID, 1, + [Noting that make_request_fn() returns void]) + ],[ + AC_MSG_RESULT(no) + + dnl # + dnl # Linux 4.4 API Change + dnl # make_request_fn returns blk_qc_t. + dnl # + AC_MSG_CHECKING( + [whether make_request_fn() returns blk_qc_t]) + ZFS_LINUX_TEST_RESULT([make_request_fn_blk_qc_t], [ + AC_MSG_RESULT(yes) + AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t, + [make_request_fn() return type]) + AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1, + [Noting that make_request_fn() ] + [returns blk_qc_t]) + ],[ + ZFS_LINUX_TEST_ERROR([make_request_fn]) + ]) + ]) + ]) + ]) +]) diff --git a/config/kernel-misc-minor.m4 b/config/kernel-misc-minor.m4 new file mode 100644 index 000000000000..20fe2cd2f3cd --- /dev/null +++ b/config/kernel-misc-minor.m4 @@ -0,0 +1,26 @@ +dnl # +dnl # Determine an available miscellaneous minor number which can be used +dnl # for the /dev/zfs device. This is needed because kernel module +dnl # auto-loading depends on registering a reserved non-conflicting minor +dnl # number. Start with a large known available unreserved minor and work +dnl # our way down to lower value if a collision is detected. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_MISC_MINOR], [ + AC_MSG_CHECKING([whether /dev/zfs minor is available]) + + for i in $(seq 249 -1 200); do + if ! grep -q "^#define\s\+.*_MINOR\s\+.*$i" \ + ${LINUX}/include/linux/miscdevice.h; then + ZFS_DEVICE_MINOR="$i" + AC_MSG_RESULT($ZFS_DEVICE_MINOR) + AC_DEFINE_UNQUOTED([ZFS_DEVICE_MINOR], + [$ZFS_DEVICE_MINOR], [/dev/zfs minor]) + break + fi + done + + AS_IF([ test -z "$ZFS_DEVICE_MINOR"], [ + AC_MSG_ERROR([ + *** No available misc minor numbers available for use.]) + ]) +]) diff --git a/config/kernel-mkdir-umode-t.m4 b/config/kernel-mkdir-umode-t.m4 new file mode 100644 index 000000000000..19599670df3b --- /dev/null +++ b/config/kernel-mkdir-umode-t.m4 @@ -0,0 +1,32 @@ +dnl # +dnl # 3.3 API change +dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a +dnl # umode_t type rather than an int. The expectation is that any backport +dnl # would also change all three prototypes. However, if it turns out that +dnl # some distribution doesn't backport the whole thing this could be +dnl # broken apart into three separate checks. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T], [ + ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [ + #include <linux/fs.h> + + int mkdir(struct inode *inode, struct dentry *dentry, + umode_t umode) { return 0; } + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .mkdir = mkdir, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [ + AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t]) + ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MKDIR_UMODE_T, 1, + [iops->create()/mkdir()/mknod() take umode_t]) + ],[ + ZFS_LINUX_TEST_ERROR([mkdir()]) + ]) +]) diff --git a/config/kernel-mod-param.m4 b/config/kernel-mod-param.m4 new file mode 100644 index 000000000000..e00f19d61e7d --- /dev/null +++ b/config/kernel-mod-param.m4 @@ -0,0 +1,33 @@ +dnl # +dnl # Grsecurity kernel API change +dnl # constified parameters of module_param_call() methods +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST], [ + ZFS_LINUX_TEST_SRC([module_param_call], [ + #include <linux/module.h> + #include <linux/moduleparam.h> + + int param_get(char *b, const struct kernel_param *kp) + { + return (0); + } + + int param_set(const char *b, const struct kernel_param *kp) + { + return (0); + } + + module_param_call(p, param_set, param_get, NULL, 0644); + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [ + AC_MSG_CHECKING([whether module_param_call() is hardened]) + ZFS_LINUX_TEST_RESULT([module_param_call], [ + AC_MSG_RESULT(yes) + AC_DEFINE(MODULE_PARAM_CALL_CONST, 1, + [hardened module_param_call]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-objtool.m4 b/config/kernel-objtool.m4 new file mode 100644 index 000000000000..bf60e7869213 --- /dev/null +++ b/config/kernel-objtool.m4 @@ -0,0 +1,45 @@ +dnl # +dnl # Check for objtool support. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_OBJTOOL], [ + + dnl # 4.6 API for compile-time stack validation + ZFS_LINUX_TEST_SRC([objtool], [ + #undef __ASSEMBLY__ + #include <asm/frame.h> + ],[ + #if !defined(FRAME_BEGIN) + CTASSERT(1); + #endif + ]) + + dnl # 4.6 API added STACK_FRAME_NON_STANDARD macro + ZFS_LINUX_TEST_SRC([stack_frame_non_standard], [ + #include <linux/frame.h> + ],[ + #if !defined(STACK_FRAME_NON_STANDARD) + CTASSERT(1); + #endif + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_OBJTOOL], [ + AC_MSG_CHECKING( + [whether compile-time stack validation (objtool) is available]) + ZFS_LINUX_TEST_RESULT([objtool], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KERNEL_OBJTOOL, 1, + [kernel does stack verification]) + + AC_MSG_CHECKING([whether STACK_FRAME_NON_STANDARD is defined]) + ZFS_LINUX_TEST_RESULT([stack_frame_non_standard], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STACK_FRAME_NON_STANDARD, 1, + [STACK_FRAME_NON_STANDARD is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-pde-data.m4 b/config/kernel-pde-data.m4 new file mode 100644 index 000000000000..f866d77a11df --- /dev/null +++ b/config/kernel-pde-data.m4 @@ -0,0 +1,20 @@ +dnl # +dnl # 3.10 API change, +dnl # PDE is replaced by PDE_DATA +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_PDE_DATA], [ + ZFS_LINUX_TEST_SRC([pde_data], [ + #include <linux/proc_fs.h> + ], [ + PDE_DATA(NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_PDE_DATA], [ + AC_MSG_CHECKING([whether PDE_DATA() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([pde_data], [PDE_DATA], [], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([PDE_DATA]) + ]) +]) diff --git a/config/kernel-percpu.m4 b/config/kernel-percpu.m4 new file mode 100644 index 000000000000..e9654a69ee0a --- /dev/null +++ b/config/kernel-percpu.m4 @@ -0,0 +1,34 @@ +dnl # +dnl # 3.18 API change, +dnl # The function percpu_counter_init now must be passed a GFP mask. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_PERCPU_COUNTER_INIT], [ + ZFS_LINUX_TEST_SRC([percpu_counter_init_with_gfp], [ + #include <linux/gfp.h> + #include <linux/percpu_counter.h> + ],[ + struct percpu_counter counter; + int error; + + error = percpu_counter_init(&counter, 0, GFP_KERNEL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_PERCPU_COUNTER_INIT], [ + AC_MSG_CHECKING([whether percpu_counter_init() wants gfp_t]) + ZFS_LINUX_TEST_RESULT([percpu_counter_init_with_gfp], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PERCPU_COUNTER_INIT_WITH_GFP, 1, + [percpu_counter_init() wants gfp_t]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_PERCPU], [ + ZFS_AC_KERNEL_SRC_PERCPU_COUNTER_INIT +]) + +AC_DEFUN([ZFS_AC_KERNEL_PERCPU], [ + ZFS_AC_KERNEL_PERCPU_COUNTER_INIT +]) diff --git a/config/kernel-proc-operations.m4 b/config/kernel-proc-operations.m4 new file mode 100644 index 000000000000..df216222ecc2 --- /dev/null +++ b/config/kernel-proc-operations.m4 @@ -0,0 +1,41 @@ +dnl # +dnl # 5.6 API Change +dnl # The proc_ops structure was introduced to replace the use of +dnl # of the file_operations structure when registering proc handlers. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_PROC_OPERATIONS], [ + ZFS_LINUX_TEST_SRC([proc_ops_struct], [ + #include <linux/proc_fs.h> + + int test_open(struct inode *ip, struct file *fp) { return 0; } + ssize_t test_read(struct file *fp, char __user *ptr, + size_t size, loff_t *offp) { return 0; } + ssize_t test_write(struct file *fp, const char __user *ptr, + size_t size, loff_t *offp) { return 0; } + loff_t test_lseek(struct file *fp, loff_t off, int flag) + { return 0; } + int test_release(struct inode *ip, struct file *fp) + { return 0; } + + const struct proc_ops test_ops __attribute__ ((unused)) = { + .proc_open = test_open, + .proc_read = test_read, + .proc_write = test_write, + .proc_lseek = test_lseek, + .proc_release = test_release, + }; + ], [ + struct proc_dir_entry *entry __attribute__ ((unused)) = + proc_create_data("test", 0444, NULL, &test_ops, NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_PROC_OPERATIONS], [ + AC_MSG_CHECKING([whether proc_ops structure exists]) + ZFS_LINUX_TEST_RESULT([proc_ops_struct], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PROC_OPS_STRUCT, 1, [proc_ops structure exists]) + ], [ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-put-link.m4 b/config/kernel-put-link.m4 new file mode 100644 index 000000000000..4234861f3347 --- /dev/null +++ b/config/kernel-put-link.m4 @@ -0,0 +1,61 @@ +dnl # +dnl # Supported symlink APIs +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_PUT_LINK], [ + ZFS_LINUX_TEST_SRC([put_link_cookie], [ + #include <linux/fs.h> + void put_link(struct inode *ip, void *cookie) + { return; } + static struct inode_operations + iops __attribute__ ((unused)) = { + .put_link = put_link, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([put_link_nameidata], [ + #include <linux/fs.h> + void put_link(struct dentry *de, struct + nameidata *nd, void *ptr) { return; } + static struct inode_operations + iops __attribute__ ((unused)) = { + .put_link = put_link, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_PUT_LINK], [ + dnl # + dnl # 4.5 API change + dnl # get_link() uses delayed done, there is no put_link() interface. + dnl # This check initially uses the inode_operations_get_link result + dnl # + ZFS_LINUX_TEST_RESULT([inode_operations_get_link], [ + AC_DEFINE(HAVE_PUT_LINK_DELAYED, 1, [iops->put_link() delayed]) + ],[ + dnl # + dnl # 4.2 API change + dnl # This kernel retired the nameidata structure. + dnl # + AC_MSG_CHECKING([whether iops->put_link() passes cookie]) + ZFS_LINUX_TEST_RESULT([put_link_cookie], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PUT_LINK_COOKIE, 1, + [iops->put_link() cookie]) + ],[ + AC_MSG_RESULT(no) + + dnl # + dnl # 2.6.32 API + dnl # + AC_MSG_CHECKING( + [whether iops->put_link() passes nameidata]) + ZFS_LINUX_TEST_RESULT([put_link_nameidata], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PUT_LINK_NAMEIDATA, 1, + [iops->put_link() nameidata]) + ],[ + ZFS_LINUX_TEST_ERROR([put_link]) + ]) + ]) + ]) +]) diff --git a/config/kernel-rename.m4 b/config/kernel-rename.m4 new file mode 100644 index 000000000000..f707391539d8 --- /dev/null +++ b/config/kernel-rename.m4 @@ -0,0 +1,29 @@ +dnl # +dnl # 4.9 API change, +dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants +dnl # flags. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [ + ZFS_LINUX_TEST_SRC([inode_operations_rename], [ + #include <linux/fs.h> + int rename_fn(struct inode *sip, struct dentry *sdp, + struct inode *tip, struct dentry *tdp, + unsigned int flags) { return 0; } + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .rename = rename_fn, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [ + AC_MSG_CHECKING([whether iops->rename() wants flags]) + ZFS_LINUX_TEST_RESULT([inode_operations_rename], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1, + [iops->rename() wants flags]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-rw.m4 b/config/kernel-rw.m4 new file mode 100644 index 000000000000..85b47d5c6fc2 --- /dev/null +++ b/config/kernel-rw.m4 @@ -0,0 +1,69 @@ +dnl # +dnl # 4.14 API change +dnl # kernel_write() which was introduced in 3.9 was updated to take +dnl # the offset as a pointer which is needed by vn_rdwr(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_WRITE], [ + ZFS_LINUX_TEST_SRC([kernel_write], [ + #include <linux/fs.h> + ],[ + struct file *file = NULL; + const void *buf = NULL; + size_t count = 0; + loff_t *pos = NULL; + ssize_t ret; + + ret = kernel_write(file, buf, count, pos); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_WRITE], [ + AC_MSG_CHECKING([whether kernel_write() takes loff_t pointer]) + ZFS_LINUX_TEST_RESULT([kernel_write], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KERNEL_WRITE_PPOS, 1, + [kernel_write() take loff_t pointer]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.14 API change +dnl # kernel_read() which has existed for forever was updated to take +dnl # the offset as a pointer which is needed by vn_rdwr(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_READ], [ + ZFS_LINUX_TEST_SRC([kernel_read], [ + #include <linux/fs.h> + ],[ + struct file *file = NULL; + void *buf = NULL; + size_t count = 0; + loff_t *pos = NULL; + ssize_t ret; + + ret = kernel_read(file, buf, count, pos); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_READ], [ + AC_MSG_CHECKING([whether kernel_read() takes loff_t pointer]) + ZFS_LINUX_TEST_RESULT([kernel_read], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KERNEL_READ_PPOS, 1, + [kernel_read() take loff_t pointer]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_RW], [ + ZFS_AC_KERNEL_SRC_WRITE + ZFS_AC_KERNEL_SRC_READ +]) + +AC_DEFUN([ZFS_AC_KERNEL_RW], [ + ZFS_AC_KERNEL_WRITE + ZFS_AC_KERNEL_READ +]) diff --git a/config/kernel-rwsem.m4 b/config/kernel-rwsem.m4 new file mode 100644 index 000000000000..824f4a3ffd41 --- /dev/null +++ b/config/kernel-rwsem.m4 @@ -0,0 +1,88 @@ +dnl # +dnl # 3.1 API Change +dnl # +dnl # The rw_semaphore.wait_lock member was changed from spinlock_t to +dnl # raw_spinlock_t at commit ddb6c9b58a19edcfac93ac670b066c836ff729f1. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_SPINLOCK_IS_RAW], [ + ZFS_LINUX_TEST_SRC([rwsem_spinlock_is_raw], [ + #include <linux/rwsem.h> + ],[ + struct rw_semaphore dummy_semaphore __attribute__ ((unused)); + raw_spinlock_t dummy_lock __attribute__ ((unused)) = + __RAW_SPIN_LOCK_INITIALIZER(dummy_lock); + dummy_semaphore.wait_lock = dummy_lock; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW], [ + AC_MSG_CHECKING([whether struct rw_semaphore member wait_lock is raw]) + ZFS_LINUX_TEST_RESULT([rwsem_spinlock_is_raw], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([rwsem_spinlock_is_raw]) + ]) +]) + +dnl # +dnl # 3.16 API Change +dnl # +dnl # rwsem-spinlock "->activity" changed to "->count" +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_ACTIVITY], [ + ZFS_LINUX_TEST_SRC([rwsem_activity], [ + #include <linux/rwsem.h> + ],[ + struct rw_semaphore dummy_semaphore __attribute__ ((unused)); + dummy_semaphore.activity = 0; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ACTIVITY], [ + AC_MSG_CHECKING([whether struct rw_semaphore has member activity]) + ZFS_LINUX_TEST_RESULT([rwsem_activity], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_RWSEM_ACTIVITY, 1, + [struct rw_semaphore has member activity]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.8 API Change +dnl # +dnl # rwsem "->count" changed to atomic_long_t type +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM_ATOMIC_LONG_COUNT], [ + ZFS_LINUX_TEST_SRC([rwsem_atomic_long_count], [ + #include <linux/rwsem.h> + ],[ + DECLARE_RWSEM(dummy_semaphore); + (void) atomic_long_read(&dummy_semaphore.count); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT], [ + AC_MSG_CHECKING( + [whether struct rw_semaphore has atomic_long_t member count]) + ZFS_LINUX_TEST_RESULT([rwsem_atomic_long_count], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_RWSEM_ATOMIC_LONG_COUNT, 1, + [struct rw_semaphore has atomic_long_t member count]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_RWSEM], [ + ZFS_AC_KERNEL_SRC_RWSEM_SPINLOCK_IS_RAW + ZFS_AC_KERNEL_SRC_RWSEM_ACTIVITY + ZFS_AC_KERNEL_SRC_RWSEM_ATOMIC_LONG_COUNT +]) + +AC_DEFUN([ZFS_AC_KERNEL_RWSEM], [ + ZFS_AC_KERNEL_RWSEM_SPINLOCK_IS_RAW + ZFS_AC_KERNEL_RWSEM_ACTIVITY + ZFS_AC_KERNEL_RWSEM_ATOMIC_LONG_COUNT +]) diff --git a/config/kernel-sched.m4 b/config/kernel-sched.m4 new file mode 100644 index 000000000000..17e49fbdf472 --- /dev/null +++ b/config/kernel-sched.m4 @@ -0,0 +1,82 @@ +dnl # +dnl # 3.9 API change, +dnl # Moved things from linux/sched.h to linux/sched/rt.h +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED_RT_HEADER], [ + ZFS_LINUX_TEST_SRC([sched_rt_header], [ + #include <linux/sched.h> + #include <linux/sched/rt.h> + ],[ + return 0; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SCHED_RT_HEADER], [ + AC_MSG_CHECKING([whether header linux/sched/rt.h exists]) + ZFS_LINUX_TEST_RESULT([sched_rt_header], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([sched_rt_header]) + ]) +]) + +dnl # +dnl # 4.11 API change, +dnl # Moved things from linux/sched.h to linux/sched/signal.h +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED_SIGNAL_HEADER], [ + ZFS_LINUX_TEST_SRC([sched_signal_header], [ + #include <linux/sched.h> + #include <linux/sched/signal.h> + ],[ + return 0; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER], [ + AC_MSG_CHECKING([whether header linux/sched/signal.h exists]) + ZFS_LINUX_TEST_RESULT([sched_signal_header], [ + AC_DEFINE(HAVE_SCHED_SIGNAL_HEADER, 1, + [linux/sched/signal.h exists]) + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 3.19 API change +dnl # The io_schedule_timeout() function is present in all 2.6.32 kernels +dnl # but it was not exported until Linux 3.19. The RHEL 7.x kernels which +dnl # are based on a 3.10 kernel do export this symbol. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_IO_SCHEDULE_TIMEOUT], [ + ZFS_LINUX_TEST_SRC([io_schedule_timeout], [ + #include <linux/sched.h> + ], [ + (void) io_schedule_timeout(1); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT], [ + AC_MSG_CHECKING([whether io_schedule_timeout() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([io_schedule_timeout], + [io_schedule_timeout], [], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_IO_SCHEDULE_TIMEOUT, 1, [yes]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_SCHED], [ + ZFS_AC_KERNEL_SRC_SCHED_RT_HEADER + ZFS_AC_KERNEL_SRC_SCHED_SIGNAL_HEADER + ZFS_AC_KERNEL_SRC_IO_SCHEDULE_TIMEOUT +]) + +AC_DEFUN([ZFS_AC_KERNEL_SCHED], [ + ZFS_AC_KERNEL_SCHED_RT_HEADER + ZFS_AC_KERNEL_SCHED_SIGNAL_HEADER + ZFS_AC_KERNEL_IO_SCHEDULE_TIMEOUT +]) diff --git a/config/kernel-security-inode-init.m4 b/config/kernel-security-inode-init.m4 new file mode 100644 index 000000000000..4e4bfd29b2ff --- /dev/null +++ b/config/kernel-security-inode-init.m4 @@ -0,0 +1,36 @@ +dnl # +dnl # 3.2 API change +dnl # The security_inode_init_security() API has been changed to include +dnl # a filesystem specific callback to write security extended attributes. +dnl # This was done to support the initialization of multiple LSM xattrs +dnl # and the EVM xattr. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_CALLBACK], [ + ZFS_LINUX_TEST_SRC([security_inode_init_security], [ + #include <linux/security.h> + ],[ + struct inode *ip __attribute__ ((unused)) = NULL; + struct inode *dip __attribute__ ((unused)) = NULL; + const struct qstr *str __attribute__ ((unused)) = NULL; + initxattrs func __attribute__ ((unused)) = NULL; + + security_inode_init_security(ip, dip, str, func, NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_CALLBACK], [ + AC_MSG_CHECKING([whether security_inode_init_security wants callback]) + ZFS_LINUX_TEST_RESULT([security_inode_init_security], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([security_inode_init_security callback]) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_SECURITY_INODE], [ + ZFS_AC_KERNEL_SRC_SECURITY_INODE_INIT_SECURITY_CALLBACK +]) + +AC_DEFUN([ZFS_AC_KERNEL_SECURITY_INODE], [ + ZFS_AC_KERNEL_SECURITY_INODE_INIT_SECURITY_CALLBACK +]) diff --git a/config/kernel-set-nlink.m4 b/config/kernel-set-nlink.m4 new file mode 100644 index 000000000000..fa4f928b27d5 --- /dev/null +++ b/config/kernel-set-nlink.m4 @@ -0,0 +1,22 @@ +dnl # +dnl # Linux 3.2 API change +dnl # set_nlink() +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SET_NLINK], [ + ZFS_LINUX_TEST_SRC([set_nlink], [ + #include <linux/fs.h> + ],[ + struct inode node; + unsigned int link = 0; + (void) set_nlink(&node, link); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SET_NLINK], [ + AC_MSG_CHECKING([whether set_nlink() is available]) + ZFS_LINUX_TEST_RESULT([set_nlink], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([set_nlink()]) + ]) +]) diff --git a/config/kernel-setattr-prepare.m4 b/config/kernel-setattr-prepare.m4 new file mode 100644 index 000000000000..45408c45c69b --- /dev/null +++ b/config/kernel-setattr-prepare.m4 @@ -0,0 +1,27 @@ +dnl # +dnl # 4.9 API change +dnl # The inode_change_ok() function has been renamed setattr_prepare() +dnl # and updated to take a dentry rather than an inode. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [ + ZFS_LINUX_TEST_SRC([setattr_prepare], [ + #include <linux/fs.h> + ], [ + struct dentry *dentry = NULL; + struct iattr *attr = NULL; + int error __attribute__ ((unused)) = + setattr_prepare(dentry, attr); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [ + AC_MSG_CHECKING([whether setattr_prepare() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare], + [setattr_prepare], [fs/attr.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SETATTR_PREPARE, 1, + [setattr_prepare() is available]) + ], [ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-sget-args.m4 b/config/kernel-sget-args.m4 new file mode 100644 index 000000000000..afa62c797d75 --- /dev/null +++ b/config/kernel-sget-args.m4 @@ -0,0 +1,25 @@ +dnl # +dnl # 3.6 API change, +dnl # 'sget' now takes the mount flags as an argument. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SGET], [ + ZFS_LINUX_TEST_SRC([sget_5args], [ + #include <linux/fs.h> + ],[ + struct file_system_type *type = NULL; + int (*test)(struct super_block *,void *) = NULL; + int (*set)(struct super_block *,void *) = NULL; + int flags = 0; + void *data = NULL; + (void) sget(type, test, set, flags, data); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SGET], [ + AC_MSG_CHECKING([whether sget() wants 5 args]) + ZFS_LINUX_TEST_RESULT([sget_5args], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([sget()]) + ]) +]) diff --git a/config/kernel-show-options.m4 b/config/kernel-show-options.m4 new file mode 100644 index 000000000000..93bd5fbfbb24 --- /dev/null +++ b/config/kernel-show-options.m4 @@ -0,0 +1,25 @@ +dnl # +dnl # Linux 3.3 API +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SHOW_OPTIONS], [ + ZFS_LINUX_TEST_SRC([super_operations_show_options], [ + #include <linux/fs.h> + + int show_options(struct seq_file * x, struct dentry * y) { + return 0; + }; + + static struct super_operations sops __attribute__ ((unused)) = { + .show_options = show_options, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SHOW_OPTIONS], [ + AC_MSG_CHECKING([whether sops->show_options() wants dentry]) + ZFS_LINUX_TEST_RESULT([super_operations_show_options], [ + AC_MSG_RESULT([yes]) + ],[ + ZFS_LINUX_TEST_ERROR([sops->show_options()]) + ]) +]) diff --git a/config/kernel-shrink.m4 b/config/kernel-shrink.m4 new file mode 100644 index 000000000000..a40c86d5c57f --- /dev/null +++ b/config/kernel-shrink.m4 @@ -0,0 +1,151 @@ +dnl # +dnl # 3.1 API change +dnl # The super_block structure now stores a per-filesystem shrinker. +dnl # This interface is preferable because it can be used to specifically +dnl # target only the zfs filesystem for pruning. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK], [ + ZFS_LINUX_TEST_SRC([super_block_s_shrink], [ + #include <linux/fs.h> + + int shrink(struct shrinker *s, struct shrink_control *sc) + { return 0; } + + static const struct super_block + sb __attribute__ ((unused)) = { + .s_shrink.seeks = DEFAULT_SEEKS, + .s_shrink.batch = 0, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK], [ + AC_MSG_CHECKING([whether super_block has s_shrink]) + ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([sb->s_shrink()]) + ]) +]) + +dnl # +dnl # 3.12 API change +dnl # The nid member was added to struct shrink_control to support +dnl # NUMA-aware shrinkers. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID], [ + ZFS_LINUX_TEST_SRC([shrink_control_nid], [ + #include <linux/fs.h> + ],[ + struct shrink_control sc __attribute__ ((unused)); + unsigned long scnidsize __attribute__ ((unused)) = + sizeof(sc.nid); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID], [ + AC_MSG_CHECKING([whether shrink_control has nid]) + ZFS_LINUX_TEST_RESULT([shrink_control_nid], [ + AC_MSG_RESULT(yes) + AC_DEFINE(SHRINK_CONTROL_HAS_NID, 1, + [struct shrink_control has nid]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [ + ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control], [ + #include <linux/mm.h> + int shrinker_cb(struct shrinker *shrink, + struct shrink_control *sc) { return 0; } + ],[ + struct shrinker cache_shrinker = { + .shrink = shrinker_cb, + .seeks = DEFAULT_SEEKS, + }; + register_shrinker(&cache_shrinker); + ]) + + ZFS_LINUX_TEST_SRC([shrinker_cb_shrink_control_split], [ + #include <linux/mm.h> + unsigned long shrinker_cb(struct shrinker *shrink, + struct shrink_control *sc) { return 0; } + ],[ + struct shrinker cache_shrinker = { + .count_objects = shrinker_cb, + .scan_objects = shrinker_cb, + .seeks = DEFAULT_SEEKS, + }; + register_shrinker(&cache_shrinker); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[ + dnl # + dnl # 3.0 - 3.11 API change + dnl # ->shrink(struct shrinker *, struct shrink_control *sc) + dnl # + AC_MSG_CHECKING([whether new 2-argument shrinker exists]) + ZFS_LINUX_TEST_RESULT([shrinker_cb_shrink_control], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SINGLE_SHRINKER_CALLBACK, 1, + [new shrinker callback wants 2 args]) + ],[ + AC_MSG_RESULT(no) + + dnl # + dnl # 3.12 API change, + dnl # ->shrink() is logically split in to + dnl # ->count_objects() and ->scan_objects() + dnl # + AC_MSG_CHECKING([whether ->count_objects callback exists]) + ZFS_LINUX_TEST_RESULT([shrinker_cb_shrink_control_split], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, 1, + [->count_objects exists]) + ],[ + ZFS_LINUX_TEST_ERROR([shrinker]) + ]) + ]) +]) + +dnl # +dnl # 2.6.39 API change, +dnl # Shrinker adjust to use common shrink_control structure. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT], [ + ZFS_LINUX_TEST_SRC([shrink_control_struct], [ + #include <linux/mm.h> + ],[ + struct shrink_control sc __attribute__ ((unused)); + + sc.nr_to_scan = 0; + sc.gfp_mask = GFP_KERNEL; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [ + AC_MSG_CHECKING([whether struct shrink_control exists]) + ZFS_LINUX_TEST_RESULT([shrink_control_struct], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SHRINK_CONTROL_STRUCT, 1, + [struct shrink_control exists]) + ],[ + ZFS_LINUX_TEST_ERROR([shrink_control]) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [ + ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK + ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID + ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK + ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT +]) + +AC_DEFUN([ZFS_AC_KERNEL_SHRINKER], [ + ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK + ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID + ZFS_AC_KERNEL_SHRINKER_CALLBACK + ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT +]) diff --git a/config/kernel-super-userns.m4 b/config/kernel-super-userns.m4 new file mode 100644 index 000000000000..1ad35f2d19ba --- /dev/null +++ b/config/kernel-super-userns.m4 @@ -0,0 +1,25 @@ +dnl # +dnl # 4.8 API change +dnl # struct user_namespace was added to struct super_block as +dnl # super->s_user_ns member +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_USER_NS], [ + ZFS_LINUX_TEST_SRC([super_user_ns], [ + #include <linux/fs.h> + #include <linux/user_namespace.h> + ], [ + struct super_block super; + super.s_user_ns = (struct user_namespace *)NULL; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SUPER_USER_NS], [ + AC_MSG_CHECKING([whether super_block->s_user_ns exists]) + ZFS_LINUX_TEST_RESULT([super_user_ns], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SUPER_USER_NS, 1, + [super_block->s_user_ns exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-timer.m4 b/config/kernel-timer.m4 new file mode 100644 index 000000000000..403cff3f4189 --- /dev/null +++ b/config/kernel-timer.m4 @@ -0,0 +1,75 @@ +dnl # 4.14-rc3 API change +dnl # https://lwn.net/Articles/735887/ +dnl # +dnl # Check if timer_list.func get passed a timer_list or an unsigned long +dnl # (older kernels). Also sanity check the from_timer() and timer_setup() +dnl # macros are available as well, since they will be used in the same newer +dnl # kernels that support the new timer_list.func signature. +dnl # +dnl # Also check for the existence of flags in struct timer_list, they were +dnl # added in 4.1-rc8 via 0eeda71bc30d. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_TIMER_SETUP], [ + ZFS_LINUX_TEST_SRC([timer_setup], [ + #include <linux/timer.h> + + struct my_task_timer { + struct timer_list timer; + int data; + }; + + void task_expire(struct timer_list *tl) + { + struct my_task_timer *task_timer = + from_timer(task_timer, tl, timer); + task_timer->data = 42; + } + ],[ + struct my_task_timer task_timer; + timer_setup(&task_timer.timer, task_expire, 0); + ]) + + ZFS_LINUX_TEST_SRC([timer_list_function], [ + #include <linux/timer.h> + void task_expire(struct timer_list *tl) {} + ],[ + struct timer_list tl; + tl.function = task_expire; + ]) + + ZFS_LINUX_TEST_SRC([timer_list_flags], [ + #include <linux/timer.h> + ],[ + struct timer_list tl; + tl.flags = 2; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_TIMER_SETUP], [ + AC_MSG_CHECKING([whether timer_setup() is available]) + ZFS_LINUX_TEST_RESULT([timer_setup], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KERNEL_TIMER_SETUP, 1, + [timer_setup() is available]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([whether timer function expects timer_list]) + ZFS_LINUX_TEST_RESULT([timer_list_function], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST, 1, + [timer_list.function gets a timer_list]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([whether struct timer_list has flags]) + ZFS_LINUX_TEST_RESULT([timer_list_flags], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KERNEL_TIMER_LIST_FLAGS, 1, + [struct timer_list has a flags member]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-tmpfile.m4 b/config/kernel-tmpfile.m4 new file mode 100644 index 000000000000..f510bfe6ba03 --- /dev/null +++ b/config/kernel-tmpfile.m4 @@ -0,0 +1,25 @@ +dnl # +dnl # 3.11 API change +dnl # Add support for i_op->tmpfile +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [ + ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [ + #include <linux/fs.h> + int tmpfile(struct inode *inode, struct dentry *dentry, + umode_t mode) { return 0; } + static struct inode_operations + iops __attribute__ ((unused)) = { + .tmpfile = tmpfile, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [ + AC_MSG_CHECKING([whether i_op->tmpfile() exists]) + ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-totalhigh_pages.m4 b/config/kernel-totalhigh_pages.m4 new file mode 100644 index 000000000000..4ecb03a50a51 --- /dev/null +++ b/config/kernel-totalhigh_pages.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 5.0 API change +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES], [ + ZFS_LINUX_TEST_SRC([totalhigh_pages], [ + #include <linux/highmem.h> + ],[ + unsigned long pages __attribute__ ((unused)); + pages = totalhigh_pages(); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_TOTALHIGH_PAGES], [ + AC_MSG_CHECKING([whether totalhigh_pages() exists]) + ZFS_LINUX_TEST_RESULT([totalhigh_pages], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_TOTALHIGH_PAGES, 1, [totalhigh_pages() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-totalram-pages-func.m4 b/config/kernel-totalram-pages-func.m4 new file mode 100644 index 000000000000..d0e812a8d2d2 --- /dev/null +++ b/config/kernel-totalram-pages-func.m4 @@ -0,0 +1,23 @@ +dnl # +dnl # Linux 5.0: totalram_pages is no longer a global variable, and must be +dnl # read via the totalram_pages() helper function. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC], [ + ZFS_LINUX_TEST_SRC([totalram_pages], [ + #include <linux/mm.h> + ],[ + unsigned long pages __attribute__ ((unused)); + pages = totalram_pages(); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC], [ + AC_MSG_CHECKING([whether totalram_pages() exists]) + ZFS_LINUX_TEST_RESULT([totalram_pages], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_TOTALRAM_PAGES_FUNC, 1, + [kernel has totalram_pages()]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-truncate-setsize.m4 b/config/kernel-truncate-setsize.m4 new file mode 100644 index 000000000000..76c82ef3021b --- /dev/null +++ b/config/kernel-truncate-setsize.m4 @@ -0,0 +1,21 @@ +dnl # +dnl # 2.6.35 API change +dnl # Added truncate_setsize() helper function. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE], [ + ZFS_LINUX_TEST_SRC([truncate_setsize], [ + #include <linux/mm.h> + ], [ + truncate_setsize(NULL, 0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_TRUNCATE_SETSIZE], [ + AC_MSG_CHECKING([whether truncate_setsize() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([truncate_setsize], + [truncate_setsize], [mm/truncate.c], [ + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([truncate_setsize]) + ]) +]) diff --git a/config/kernel-userns-capabilities.m4 b/config/kernel-userns-capabilities.m4 new file mode 100644 index 000000000000..026503623a2b --- /dev/null +++ b/config/kernel-userns-capabilities.m4 @@ -0,0 +1,106 @@ +dnl # +dnl # 2.6.38 API change +dnl # ns_capable() was introduced +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_NS_CAPABLE], [ + ZFS_LINUX_TEST_SRC([ns_capable], [ + #include <linux/capability.h> + ],[ + ns_capable((struct user_namespace *)NULL, CAP_SYS_ADMIN); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_NS_CAPABLE], [ + AC_MSG_CHECKING([whether ns_capable exists]) + ZFS_LINUX_TEST_RESULT([ns_capable], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([ns_capable()]) + ]) +]) + +dnl # +dnl # 4.10 API change +dnl # has_capability() was exported. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_HAS_CAPABILITY], [ + ZFS_LINUX_TEST_SRC([has_capability], [ + #include <linux/capability.h> + ],[ + struct task_struct *task = NULL; + int cap = 0; + bool result __attribute__ ((unused)); + + result = has_capability(task, cap); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_HAS_CAPABILITY], [ + AC_MSG_CHECKING([whether has_capability() is available]) + ZFS_LINUX_TEST_RESULT_SYMBOL([has_capability], + [has_capability], [kernel/capability.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_HAS_CAPABILITY, 1, [has_capability() is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.39 API change +dnl # struct user_namespace was added to struct cred_t as cred->user_ns member +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CRED_USER_NS], [ + ZFS_LINUX_TEST_SRC([cred_user_ns], [ + #include <linux/cred.h> + ],[ + struct cred cr; + cr.user_ns = (struct user_namespace *)NULL; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CRED_USER_NS], [ + AC_MSG_CHECKING([whether cred_t->user_ns exists]) + ZFS_LINUX_TEST_RESULT([cred_user_ns], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([cred_t->user_ns()]) + ]) +]) + +dnl # +dnl # 3.4 API change +dnl # kuid_has_mapping() and kgid_has_mapping() were added to distinguish +dnl # between internal kernel uids/gids and user namespace uids/gids. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING], [ + ZFS_LINUX_TEST_SRC([kuid_has_mapping], [ + #include <linux/uidgid.h> + ],[ + kuid_has_mapping((struct user_namespace *)NULL, KUIDT_INIT(0)); + kgid_has_mapping((struct user_namespace *)NULL, KGIDT_INIT(0)); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [ + AC_MSG_CHECKING([whether kuid_has_mapping/kgid_has_mapping exist]) + ZFS_LINUX_TEST_RESULT([kuid_has_mapping], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([kuid_has_mapping()]) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES], [ + ZFS_AC_KERNEL_SRC_NS_CAPABLE + ZFS_AC_KERNEL_SRC_HAS_CAPABILITY + ZFS_AC_KERNEL_SRC_CRED_USER_NS + ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING +]) + +AC_DEFUN([ZFS_AC_KERNEL_USERNS_CAPABILITIES], [ + ZFS_AC_KERNEL_NS_CAPABLE + ZFS_AC_KERNEL_HAS_CAPABILITY + ZFS_AC_KERNEL_CRED_USER_NS + ZFS_AC_KERNEL_KUID_HAS_MAPPING +]) diff --git a/config/kernel-usleep_range.m4 b/config/kernel-usleep_range.m4 new file mode 100644 index 000000000000..06eb381a3c38 --- /dev/null +++ b/config/kernel-usleep_range.m4 @@ -0,0 +1,23 @@ +dnl # +dnl # 2.6.36 API compatibility- Added usleep_range timer. +dnl # +dnl # usleep_range is a finer precision implementation of msleep +dnl # designed to be a drop-in replacement for udelay where a precise +dnl # sleep / busy-wait is unnecessary. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_USLEEP_RANGE], [ + ZFS_LINUX_TEST_SRC([usleep_range], [ + #include <linux/delay.h> + ],[ + usleep_range(0, 0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_USLEEP_RANGE], [ + AC_MSG_CHECKING([whether usleep_range() is available]) + ZFS_LINUX_TEST_RESULT([usleep_range], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([usleep_range()]) + ]) +]) diff --git a/config/kernel-vfs-direct_IO.m4 b/config/kernel-vfs-direct_IO.m4 new file mode 100644 index 000000000000..82583d52fcbc --- /dev/null +++ b/config/kernel-vfs-direct_IO.m4 @@ -0,0 +1,109 @@ +dnl # +dnl # Check for direct IO interfaces. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO], [ + ZFS_LINUX_TEST_SRC([direct_io_iter], [ + #include <linux/fs.h> + + ssize_t test_direct_IO(struct kiocb *kiocb, + struct iov_iter *iter) { return 0; } + + static const struct address_space_operations + aops __attribute__ ((unused)) = { + .direct_IO = test_direct_IO, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([direct_io_iter_offset], [ + #include <linux/fs.h> + + ssize_t test_direct_IO(struct kiocb *kiocb, + struct iov_iter *iter, loff_t offset) { return 0; } + + static const struct address_space_operations + aops __attribute__ ((unused)) = { + .direct_IO = test_direct_IO, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([direct_io_iter_rw_offset], [ + #include <linux/fs.h> + + ssize_t test_direct_IO(int rw, struct kiocb *kiocb, + struct iov_iter *iter, loff_t offset) { return 0; } + + static const struct address_space_operations + aops __attribute__ ((unused)) = { + .direct_IO = test_direct_IO, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([direct_io_iovec], [ + #include <linux/fs.h> + + ssize_t test_direct_IO(int rw, struct kiocb *kiocb, + const struct iovec *iov, loff_t offset, + unsigned long nr_segs) { return 0; } + + static const struct address_space_operations + aops __attribute__ ((unused)) = { + .direct_IO = test_direct_IO, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO], [ + dnl # + dnl # Linux 4.6.x API change + dnl # + AC_MSG_CHECKING([whether aops->direct_IO() uses iov_iter]) + ZFS_LINUX_TEST_RESULT([direct_io_iter], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER, 1, + [aops->direct_IO() uses iov_iter without rw]) + ],[ + AC_MSG_RESULT([no]) + + dnl # + dnl # Linux 4.1.x API change + dnl # + AC_MSG_CHECKING( + [whether aops->direct_IO() uses offset]) + ZFS_LINUX_TEST_RESULT([direct_io_iter_offset], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_OFFSET, 1, + [aops->direct_IO() uses iov_iter with offset]) + + ],[ + AC_MSG_RESULT([no]) + + dnl # + dnl # Linux 3.16.x API change + dnl # + AC_MSG_CHECKING( + [whether aops->direct_IO() uses rw and offset]) + ZFS_LINUX_TEST_RESULT([direct_io_iter_rw_offset], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_RW_OFFSET, 1, + [aops->direct_IO() uses iov_iter with ] + [rw and offset]) + ],[ + AC_MSG_RESULT([no]) + + dnl # + dnl # Ancient Linux API (predates git) + dnl # + AC_MSG_CHECKING( + [whether aops->direct_IO() uses iovec]) + ZFS_LINUX_TEST_RESULT([direct_io_iovec], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_VFS_DIRECT_IO_IOVEC, 1, + [aops->direct_IO() uses iovec]) + ],[ + ZFS_LINUX_TEST_ERROR([direct IO]) + AC_MSG_RESULT([no]) + ]) + ]) + ]) + ]) +]) diff --git a/config/kernel-vfs-fsync.m4 b/config/kernel-vfs-fsync.m4 new file mode 100644 index 000000000000..159efca4532f --- /dev/null +++ b/config/kernel-vfs-fsync.m4 @@ -0,0 +1,20 @@ +dnl # +dnl # 2.6.35 API change, +dnl # Unused 'struct dentry *' removed from vfs_fsync() prototype. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS], [ + ZFS_LINUX_TEST_SRC([vfs_fsync_2args], [ + #include <linux/fs.h> + ],[ + vfs_fsync(NULL, 0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_FSYNC_2ARGS], [ + AC_MSG_CHECKING([whether vfs_fsync() wants 2 args]) + ZFS_LINUX_TEST_RESULT([vfs_fsync_2args], [ + AC_MSG_RESULT(yes) + ],[ + ZFS_LINUX_TEST_ERROR([vfs_fsync()]) + ]) +]) diff --git a/config/kernel-vfs-getattr.m4 b/config/kernel-vfs-getattr.m4 new file mode 100644 index 000000000000..eb07853cc4b9 --- /dev/null +++ b/config/kernel-vfs-getattr.m4 @@ -0,0 +1,86 @@ +dnl # +dnl # 4.11 API, a528d35e@torvalds/linux +dnl # vfs_getattr(const struct path *p, struct kstat *s, u32 m, unsigned int f) +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_4ARGS], [ + ZFS_LINUX_TEST_SRC([vfs_getattr_4args], [ + #include <linux/fs.h> + ],[ + vfs_getattr((const struct path *)NULL, + (struct kstat *)NULL, + (u32)0, + (unsigned int)0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_4ARGS], [ + AC_MSG_CHECKING([whether vfs_getattr() wants 4 args]) + ZFS_LINUX_TEST_RESULT([vfs_getattr_4args], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_4ARGS_VFS_GETATTR, 1, + [vfs_getattr wants 4 args]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 3.9 API +dnl # vfs_getattr(struct path *p, struct kstat *s) +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_2ARGS], [ + ZFS_LINUX_TEST_SRC([vfs_getattr_2args], [ + #include <linux/fs.h> + ],[ + vfs_getattr((struct path *) NULL, + (struct kstat *)NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_2ARGS], [ + AC_MSG_CHECKING([whether vfs_getattr() wants 2 args]) + ZFS_LINUX_TEST_RESULT([vfs_getattr_2args], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_2ARGS_VFS_GETATTR, 1, + [vfs_getattr wants 2 args]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # <3.9 API +dnl # vfs_getattr(struct vfsmount *v, struct dentry *d, struct kstat *k) +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR_3ARGS], [ + ZFS_LINUX_TEST_SRC([vfs_getattr_3args], [ + #include <linux/fs.h> + ],[ + vfs_getattr((struct vfsmount *)NULL, + (struct dentry *)NULL, + (struct kstat *)NULL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR_3ARGS], [ + AC_MSG_CHECKING([whether vfs_getattr() wants 3 args]) + ZFS_LINUX_TEST_RESULT([vfs_getattr_3args], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_3ARGS_VFS_GETATTR, 1, + [vfs_getattr wants 3 args]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GETATTR], [ + ZFS_AC_KERNEL_SRC_VFS_GETATTR_4ARGS + ZFS_AC_KERNEL_SRC_VFS_GETATTR_2ARGS + ZFS_AC_KERNEL_SRC_VFS_GETATTR_3ARGS +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_GETATTR], [ + ZFS_AC_KERNEL_VFS_GETATTR_4ARGS + ZFS_AC_KERNEL_VFS_GETATTR_2ARGS + ZFS_AC_KERNEL_VFS_GETATTR_3ARGS +]) diff --git a/config/kernel-vfs-iterate.m4 b/config/kernel-vfs-iterate.m4 new file mode 100644 index 000000000000..172118eac87b --- /dev/null +++ b/config/kernel-vfs-iterate.m4 @@ -0,0 +1,83 @@ +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_ITERATE], [ + ZFS_LINUX_TEST_SRC([file_operations_iterate_shared], [ + #include <linux/fs.h> + int iterate(struct file *filp, struct dir_context * context) + { return 0; } + + static const struct file_operations fops + __attribute__ ((unused)) = { + .iterate_shared = iterate, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([file_operations_iterate], [ + #include <linux/fs.h> + int iterate(struct file *filp, + struct dir_context *context) { return 0; } + + static const struct file_operations fops + __attribute__ ((unused)) = { + .iterate = iterate, + }; + + #if defined(FMODE_KABI_ITERATE) + #error "RHEL 7.5, FMODE_KABI_ITERATE interface" + #endif + ],[]) + + ZFS_LINUX_TEST_SRC([file_operations_readdir], [ + #include <linux/fs.h> + int readdir(struct file *filp, void *entry, + filldir_t func) { return 0; } + + static const struct file_operations fops + __attribute__ ((unused)) = { + .readdir = readdir, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [ + dnl # + dnl # 4.7 API change + dnl # + AC_MSG_CHECKING([whether fops->iterate_shared() is available]) + ZFS_LINUX_TEST_RESULT([file_operations_iterate_shared], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_VFS_ITERATE_SHARED, 1, + [fops->iterate_shared() is available]) + ],[ + AC_MSG_RESULT(no) + + dnl # + dnl # 3.11 API change + dnl # + dnl # RHEL 7.5 compatibility; the fops.iterate() method was + dnl # added to the file_operations structure but in order to + dnl # maintain KABI compatibility all callers must set + dnl # FMODE_KABI_ITERATE which is checked in iterate_dir(). + dnl # When detected ignore this interface and fallback to + dnl # to using fops.readdir() to retain KABI compatibility. + dnl # + AC_MSG_CHECKING([whether fops->iterate() is available]) + ZFS_LINUX_TEST_RESULT([file_operations_iterate], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_VFS_ITERATE, 1, + [fops->iterate() is available]) + ],[ + AC_MSG_RESULT(no) + + dnl # + dnl # readdir interface introduced + dnl # + AC_MSG_CHECKING([whether fops->readdir() is available]) + ZFS_LINUX_TEST_RESULT([file_operations_readdir], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_VFS_READDIR, 1, + [fops->readdir() is available]) + ],[ + ZFS_LINUX_TEST_ERROR([vfs_iterate]) + ]) + ]) + ]) +]) diff --git a/config/kernel-vfs-rw-iterate.m4 b/config/kernel-vfs-rw-iterate.m4 new file mode 100644 index 000000000000..000353ec15b0 --- /dev/null +++ b/config/kernel-vfs-rw-iterate.m4 @@ -0,0 +1,80 @@ +dnl # +dnl # Linux 3.16 API +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE], [ + ZFS_LINUX_TEST_SRC([file_operations_rw], [ + #include <linux/fs.h> + + ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to) + { return 0; } + ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from) + { return 0; } + + static const struct file_operations + fops __attribute__ ((unused)) = { + .read_iter = test_read, + .write_iter = test_write, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([new_sync_rw], [ + #include <linux/fs.h> + ],[ + ssize_t ret __attribute__ ((unused)); + struct file *filp = NULL; + char __user *rbuf = NULL; + const char __user *wbuf = NULL; + size_t len = 0; + loff_t ppos; + + ret = new_sync_read(filp, rbuf, len, &ppos); + ret = new_sync_write(filp, wbuf, len, &ppos); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE], [ + AC_MSG_CHECKING([whether fops->read/write_iter() are available]) + ZFS_LINUX_TEST_RESULT([file_operations_rw], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_VFS_RW_ITERATE, 1, + [fops->read/write_iter() are available]) + + dnl # + dnl # Linux 4.1 API + dnl # + AC_MSG_CHECKING([whether new_sync_read/write() are available]) + ZFS_LINUX_TEST_RESULT([new_sync_rw], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NEW_SYNC_READ, 1, + [new_sync_read()/new_sync_write() are available]) + ],[ + AC_MSG_RESULT(no) + ]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # Linux 4.1.x API +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_GENERIC_WRITE_CHECKS], [ + ZFS_LINUX_TEST_SRC([generic_write_checks], [ + #include <linux/fs.h> + ],[ + struct kiocb *iocb = NULL; + struct iov_iter *iov = NULL; + generic_write_checks(iocb, iov); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_GENERIC_WRITE_CHECKS], [ + AC_MSG_CHECKING([whether generic_write_checks() takes kiocb]) + ZFS_LINUX_TEST_RESULT([generic_write_checks], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GENERIC_WRITE_CHECKS_KIOCB, 1, + [generic_write_checks() takes kiocb]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-wait.m4 b/config/kernel-wait.m4 new file mode 100644 index 000000000000..0414242bf6d4 --- /dev/null +++ b/config/kernel-wait.m4 @@ -0,0 +1,99 @@ +dnl # +dnl # 4.13 API change +dnl # Renamed struct wait_queue -> struct wait_queue_entry. +dnl # +dnl # N.B. The type check is performed before all other checks +dnl # since ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY depends on +dnl # HAVE_WAIT_QUEUE_ENTRY_T being set in confdefs.h. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T], [ + AC_MSG_CHECKING([whether wait_queue_entry_t exists]) + ZFS_LINUX_TRY_COMPILE([ + #include <linux/wait.h> + ],[ + wait_queue_entry_t *entry __attribute__ ((unused)); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WAIT_QUEUE_ENTRY_T, 1, + [wait_queue_entry_t exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 3.17 API change, +dnl # wait_on_bit() no longer requires an action argument. The former +dnl # "wait_on_bit" interface required an 'action' function to be provided +dnl # which does the actual waiting. There were over 20 such functions in the +dnl # kernel, many of them identical, though most cases can be satisfied by one +dnl # of just two functions: one which uses io_schedule() and one which just +dnl # uses schedule(). This API change was made to consolidate all of those +dnl # redundant wait functions. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT_ON_BIT], [ + ZFS_LINUX_TEST_SRC([wait_on_bit], [ + #include <linux/wait.h> + ],[ + int (*action)(void *) = NULL; + wait_on_bit(NULL, 0, action, 0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_WAIT_ON_BIT], [ + AC_MSG_CHECKING([whether wait_on_bit() takes an action]) + ZFS_LINUX_TEST_RESULT([wait_on_bit], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WAIT_ON_BIT_ACTION, 1, [yes]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 4.13 API change +dnl # Renamed wait_queue_head::task_list -> wait_queue_head::head +dnl # Renamed wait_queue_entry::task_list -> wait_queue_entry::entry +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY], [ + ZFS_LINUX_TEST_SRC([wait_queue_head_entry], [ + #include <linux/wait.h> + + #ifdef HAVE_WAIT_QUEUE_ENTRY_T + typedef wait_queue_head_t spl_wait_queue_head_t; + typedef wait_queue_entry_t spl_wait_queue_entry_t; + #else + typedef wait_queue_head_t spl_wait_queue_head_t; + typedef wait_queue_t spl_wait_queue_entry_t; + #endif + ],[ + spl_wait_queue_head_t wq_head; + spl_wait_queue_entry_t wq_entry; + struct list_head *head __attribute__ ((unused)); + struct list_head *entry __attribute__ ((unused)); + + head = &wq_head.head; + entry = &wq_entry.entry; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY], [ + AC_MSG_CHECKING([whether wq_head->head and wq_entry->entry exist]) + ZFS_LINUX_TEST_RESULT([wait_queue_head_entry], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WAIT_QUEUE_HEAD_ENTRY, 1, + [wq_head->head and wq_entry->entry exist]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_WAIT], [ + ZFS_AC_KERNEL_SRC_WAIT_ON_BIT + ZFS_AC_KERNEL_SRC_WAIT_QUEUE_HEAD_ENTRY +]) + +AC_DEFUN([ZFS_AC_KERNEL_WAIT], [ + ZFS_AC_KERNEL_WAIT_ON_BIT + ZFS_AC_KERNEL_WAIT_QUEUE_HEAD_ENTRY +]) diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4 new file mode 100644 index 000000000000..137bf4a8aff0 --- /dev/null +++ b/config/kernel-xattr-handler.m4 @@ -0,0 +1,397 @@ +dnl # +dnl # 2.6.35 API change, +dnl # The 'struct xattr_handler' was constified in the generic +dnl # super_block structure. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_CONST_XATTR_HANDLER], [ + ZFS_LINUX_TEST_SRC([const_xattr_handler], [ + #include <linux/fs.h> + #include <linux/xattr.h> + + const struct xattr_handler xattr_test_handler = { + .prefix = "test", + .get = NULL, + .set = NULL, + }; + + const struct xattr_handler *xattr_handlers[] = { + &xattr_test_handler, + }; + + const struct super_block sb __attribute__ ((unused)) = { + .s_xattr = xattr_handlers, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [ + AC_MSG_CHECKING([whether super_block uses const struct xattr_handler]) + ZFS_LINUX_TEST_RESULT([const_xattr_handler], [ + AC_MSG_RESULT([yes]) + ],[ + ZFS_LINUX_TEST_ERROR([const xattr_handler]) + ]) +]) + +dnl # +dnl # 4.5 API change, +dnl # struct xattr_handler added new member "name". +dnl # xattr_handler which matches to whole name rather than prefix should use +dnl # "name" instead of "prefix", e.g. "system.posix_acl_access" +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_NAME], [ + ZFS_LINUX_TEST_SRC([xattr_handler_name], [ + #include <linux/xattr.h> + + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .name = XATTR_NAME_POSIX_ACL_ACCESS, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [ + AC_MSG_CHECKING([whether xattr_handler has name]) + ZFS_LINUX_TEST_RESULT([xattr_handler_name], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_HANDLER_NAME, 1, + [xattr_handler has name]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # Supported xattr handler get() interfaces checked newest to oldest. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET], [ + ZFS_LINUX_TEST_SRC([xattr_handler_get_dentry_inode], [ + #include <linux/xattr.h> + + int get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, size_t size) { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .get = get, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([xattr_handler_get_xattr_handler], [ + #include <linux/xattr.h> + + int get(const struct xattr_handler *handler, + struct dentry *dentry, const char *name, + void *buffer, size_t size) { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .get = get, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([xattr_handler_get_dentry], [ + #include <linux/xattr.h> + + int get(struct dentry *dentry, const char *name, + void *buffer, size_t size, int handler_flags) + { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .get = get, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [ + dnl # + dnl # 4.7 API change, + dnl # The xattr_handler->get() callback was changed to take both + dnl # dentry and inode. + dnl # + AC_MSG_CHECKING([whether xattr_handler->get() wants dentry and inode]) + ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry_inode], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1, + [xattr_handler->get() wants both dentry and inode]) + ],[ + dnl # + dnl # 4.4 API change, + dnl # The xattr_handler->get() callback was changed to take a + dnl # attr_handler, and handler_flags argument was removed and + dnl # should be accessed by handler->flags. + dnl # + AC_MSG_RESULT(no) + AC_MSG_CHECKING( + [whether xattr_handler->get() wants xattr_handler]) + ZFS_LINUX_TEST_RESULT([xattr_handler_get_xattr_handler], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1, + [xattr_handler->get() wants xattr_handler]) + ],[ + dnl # + dnl # 2.6.33 API change, + dnl # The xattr_handler->get() callback was changed + dnl # to take a dentry instead of an inode, and a + dnl # handler_flags argument was added. + dnl # + AC_MSG_RESULT(no) + AC_MSG_CHECKING( + [whether xattr_handler->get() wants dentry]) + ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1, + [xattr_handler->get() wants dentry]) + ],[ + ZFS_LINUX_TEST_ERROR([xattr get()]) + ]) + ]) + ]) +]) + +dnl # +dnl # Supported xattr handler set() interfaces checked newest to oldest. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [ + ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [ + #include <linux/xattr.h> + + int set(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, const void *buffer, + size_t size, int flags) + { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .set = set, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([xattr_handler_set_xattr_handler], [ + #include <linux/xattr.h> + + int set(const struct xattr_handler *handler, + struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags) + { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .set = set, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry], [ + #include <linux/xattr.h> + + int set(struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags, + int handler_flags) { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .set = set, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [ + dnl # + dnl # 4.7 API change, + dnl # The xattr_handler->set() callback was changed to take both + dnl # dentry and inode. + dnl # + AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode]) + ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1, + [xattr_handler->set() wants both dentry and inode]) + ],[ + dnl # + dnl # 4.4 API change, + dnl # The xattr_handler->set() callback was changed to take a + dnl # xattr_handler, and handler_flags argument was removed and + dnl # should be accessed by handler->flags. + dnl # + AC_MSG_RESULT(no) + AC_MSG_CHECKING( + [whether xattr_handler->set() wants xattr_handler]) + ZFS_LINUX_TEST_RESULT([xattr_handler_set_xattr_handler], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1, + [xattr_handler->set() wants xattr_handler]) + ],[ + dnl # + dnl # 2.6.33 API change, + dnl # The xattr_handler->set() callback was changed + dnl # to take a dentry instead of an inode, and a + dnl # handler_flags argument was added. + dnl # + AC_MSG_RESULT(no) + AC_MSG_CHECKING( + [whether xattr_handler->set() wants dentry]) + ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1, + [xattr_handler->set() wants dentry]) + ],[ + ZFS_LINUX_TEST_ERROR([xattr set()]) + ]) + ]) + ]) +]) + +dnl # +dnl # Supported xattr handler list() interfaces checked newest to oldest. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_LIST], [ + ZFS_LINUX_TEST_SRC([xattr_handler_list_simple], [ + #include <linux/xattr.h> + + bool list(struct dentry *dentry) { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .list = list, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([xattr_handler_list_xattr_handler], [ + #include <linux/xattr.h> + + size_t list(const struct xattr_handler *handler, + struct dentry *dentry, char *list, size_t list_size, + const char *name, size_t name_len) { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .list = list, + }; + ],[]) + + ZFS_LINUX_TEST_SRC([xattr_handler_list_dentry], [ + #include <linux/xattr.h> + + size_t list(struct dentry *dentry, + char *list, size_t list_size, + const char *name, size_t name_len, + int handler_flags) { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .list = list, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [ + dnl # 4.5 API change, + dnl # The xattr_handler->list() callback was changed to take only a + dnl # dentry and it only needs to return if it's accessible. + AC_MSG_CHECKING([whether xattr_handler->list() wants simple]) + ZFS_LINUX_TEST_RESULT([xattr_handler_list_simple], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_LIST_SIMPLE, 1, + [xattr_handler->list() wants simple]) + ],[ + dnl # + dnl # 4.4 API change, + dnl # The xattr_handler->list() callback was changed to take a + dnl # xattr_handler, and handler_flags argument was removed + dnl # and should be accessed by handler->flags. + dnl # + AC_MSG_RESULT(no) + AC_MSG_CHECKING( + [whether xattr_handler->list() wants xattr_handler]) + ZFS_LINUX_TEST_RESULT([xattr_handler_list_xattr_handler], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_LIST_HANDLER, 1, + [xattr_handler->list() wants xattr_handler]) + ],[ + dnl # + dnl # 2.6.33 API change, + dnl # The xattr_handler->list() callback was changed + dnl # to take a dentry instead of an inode, and a + dnl # handler_flags argument was added. + dnl # + AC_MSG_RESULT(no) + AC_MSG_CHECKING( + [whether xattr_handler->list() wants dentry]) + ZFS_LINUX_TEST_RESULT([xattr_handler_list_dentry], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_LIST_DENTRY, 1, + [xattr_handler->list() wants dentry]) + ],[ + ZFS_LINUX_TEST_ERROR([xattr list()]) + ]) + ]) + ]) +]) + +dnl # +dnl # 3.7 API change, +dnl # The posix_acl_{from,to}_xattr functions gained a new +dnl # parameter: user_ns +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_FROM_XATTR_USERNS], [ + ZFS_LINUX_TEST_SRC([posix_acl_from_xattr_userns], [ + #include <linux/cred.h> + #include <linux/fs.h> + #include <linux/posix_acl_xattr.h> + ],[ + posix_acl_from_xattr(&init_user_ns, NULL, 0); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS], [ + AC_MSG_CHECKING([whether posix_acl_from_xattr() needs user_ns]) + ZFS_LINUX_TEST_RESULT([posix_acl_from_xattr_userns], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_POSIX_ACL_FROM_XATTR_USERNS, 1, + [posix_acl_from_xattr() needs user_ns]) + ],[ + ZFS_LINUX_TEST_ERROR([posix_acl_from_xattr()]) + ]) +]) + +dnl # +dnl # 4.9 API change, +dnl # iops->{set,get,remove}xattr and generic_{set,get,remove}xattr are +dnl # removed. xattr operations will directly go through sb->s_xattr. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_SETXATTR], [ + ZFS_LINUX_TEST_SRC([have_generic_setxattr], [ + #include <linux/fs.h> + #include <linux/xattr.h> + + static const struct inode_operations + iops __attribute__ ((unused)) = { + .setxattr = generic_setxattr + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_GENERIC_SETXATTR], [ + AC_MSG_CHECKING([whether generic_setxattr() exists]) + ZFS_LINUX_TEST_RESULT([have_generic_setxattr], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GENERIC_SETXATTR, 1, + [generic_setxattr() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR], [ + ZFS_AC_KERNEL_SRC_CONST_XATTR_HANDLER + ZFS_AC_KERNEL_SRC_XATTR_HANDLER_NAME + ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET + ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET + ZFS_AC_KERNEL_SRC_XATTR_HANDLER_LIST + ZFS_AC_KERNEL_SRC_POSIX_ACL_FROM_XATTR_USERNS + ZFS_AC_KERNEL_SRC_GENERIC_SETXATTR +]) + +AC_DEFUN([ZFS_AC_KERNEL_XATTR], [ + ZFS_AC_KERNEL_CONST_XATTR_HANDLER + ZFS_AC_KERNEL_XATTR_HANDLER_NAME + ZFS_AC_KERNEL_XATTR_HANDLER_GET + ZFS_AC_KERNEL_XATTR_HANDLER_SET + ZFS_AC_KERNEL_XATTR_HANDLER_LIST + ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS + ZFS_AC_KERNEL_GENERIC_SETXATTR +]) diff --git a/config/kernel-zlib.m4 b/config/kernel-zlib.m4 new file mode 100644 index 000000000000..752d388389cb --- /dev/null +++ b/config/kernel-zlib.m4 @@ -0,0 +1,26 @@ +dnl # +dnl # 2.6.39 API compat, +dnl +dnl # The function zlib_deflate_workspacesize() now take 2 arguments. +dnl # This was done to avoid always having to allocate the maximum size +dnl # workspace (268K). The caller can now specific the windowBits and +dnl # memLevel compression parameters to get a smaller workspace. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE], [ + ZFS_LINUX_TEST_SRC([2args_zlib_deflate_workspacesize], [ + #include <linux/zlib.h> + ],[ + return zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE], [ + AC_MSG_CHECKING([whether zlib_deflate_workspacesize() wants 2 args]) + ZFS_LINUX_TEST_RESULT([2args_zlib_deflate_workspacesize], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE, 1, + [zlib_deflate_workspacesize() wants 2 args]) + ],[ + ZFS_LINUX_TEST_ERROR([zlib_deflate_workspacesize()]) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 new file mode 100644 index 000000000000..ec52f014a7a3 --- /dev/null +++ b/config/kernel.m4 @@ -0,0 +1,861 @@ +dnl # +dnl # Default ZFS kernel configuration +dnl # +AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ + AM_COND_IF([BUILD_LINUX], [ + dnl # Setup the kernel build environment. + ZFS_AC_KERNEL + ZFS_AC_QAT + + dnl # Sanity checks for module building and CONFIG_* defines + ZFS_AC_KERNEL_TEST_MODULE + ZFS_AC_KERNEL_CONFIG_DEFINED + + dnl # Sequential ZFS_LINUX_TRY_COMPILE tests + ZFS_AC_KERNEL_FPU_HEADER + ZFS_AC_KERNEL_WAIT_QUEUE_ENTRY_T + ZFS_AC_KERNEL_MISC_MINOR + ZFS_AC_KERNEL_DECLARE_EVENT_CLASS + + dnl # Parallel ZFS_LINUX_TEST_SRC / ZFS_LINUX_TEST_RESULT tests + ZFS_AC_KERNEL_TEST_SRC + ZFS_AC_KERNEL_TEST_RESULT + + AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ + KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ" + ]) + + AC_SUBST(KERNEL_MAKE) + ]) +]) + +dnl # +dnl # Generate and compile all of the kernel API test cases to determine +dnl # which interfaces are available. By invoking the kernel build system +dnl # only once the compilation can be done in parallel significantly +dnl # speeding up the process. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ + ZFS_AC_KERNEL_SRC_OBJTOOL + ZFS_AC_KERNEL_SRC_GLOBAL_PAGE_STATE + ZFS_AC_KERNEL_SRC_ACCESS_OK_TYPE + ZFS_AC_KERNEL_SRC_PDE_DATA + ZFS_AC_KERNEL_SRC_FALLOCATE + ZFS_AC_KERNEL_SRC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE + ZFS_AC_KERNEL_SRC_RWSEM + ZFS_AC_KERNEL_SRC_SCHED + ZFS_AC_KERNEL_SRC_USLEEP_RANGE + ZFS_AC_KERNEL_SRC_KMEM_CACHE + ZFS_AC_KERNEL_SRC_KVMALLOC + ZFS_AC_KERNEL_SRC_VMALLOC_PAGE_KERNEL + ZFS_AC_KERNEL_SRC_WAIT + ZFS_AC_KERNEL_SRC_INODE_TIMES + ZFS_AC_KERNEL_SRC_INODE_LOCK + ZFS_AC_KERNEL_SRC_GROUP_INFO_GID + ZFS_AC_KERNEL_SRC_RW + ZFS_AC_KERNEL_SRC_TIMER_SETUP + ZFS_AC_KERNEL_SRC_SUPER_USER_NS + ZFS_AC_KERNEL_SRC_PROC_OPERATIONS + ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS + ZFS_AC_KERNEL_SRC_BIO + ZFS_AC_KERNEL_SRC_BLKDEV + ZFS_AC_KERNEL_SRC_BLK_QUEUE + ZFS_AC_KERNEL_SRC_GET_DISK_AND_MODULE + ZFS_AC_KERNEL_SRC_GET_DISK_RO + ZFS_AC_KERNEL_SRC_GENERIC_READLINK_GLOBAL + ZFS_AC_KERNEL_SRC_DISCARD_GRANULARITY + ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE + ZFS_AC_KERNEL_SRC_XATTR + ZFS_AC_KERNEL_SRC_ACL + ZFS_AC_KERNEL_SRC_INODE_GETATTR + ZFS_AC_KERNEL_SRC_INODE_SET_FLAGS + ZFS_AC_KERNEL_SRC_INODE_SET_IVERSION + ZFS_AC_KERNEL_SRC_SHOW_OPTIONS + ZFS_AC_KERNEL_SRC_FILE_INODE + ZFS_AC_KERNEL_SRC_FILE_DENTRY + ZFS_AC_KERNEL_SRC_FSYNC + ZFS_AC_KERNEL_SRC_AIO_FSYNC + ZFS_AC_KERNEL_SRC_EVICT_INODE + ZFS_AC_KERNEL_SRC_DIRTY_INODE + ZFS_AC_KERNEL_SRC_SHRINKER + ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T + ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS + ZFS_AC_KERNEL_SRC_CREATE_FLAGS + ZFS_AC_KERNEL_SRC_GET_LINK + ZFS_AC_KERNEL_SRC_PUT_LINK + ZFS_AC_KERNEL_SRC_TMPFILE + ZFS_AC_KERNEL_SRC_AUTOMOUNT + ZFS_AC_KERNEL_SRC_ENCODE_FH_WITH_INODE + ZFS_AC_KERNEL_SRC_COMMIT_METADATA + ZFS_AC_KERNEL_SRC_CLEAR_INODE + ZFS_AC_KERNEL_SRC_SETATTR_PREPARE + ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED + ZFS_AC_KERNEL_SRC_DENTRY + ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE + ZFS_AC_KERNEL_SRC_SECURITY_INODE + ZFS_AC_KERNEL_SRC_FST_MOUNT + ZFS_AC_KERNEL_SRC_BDI + ZFS_AC_KERNEL_SRC_SET_NLINK + ZFS_AC_KERNEL_SRC_SGET + ZFS_AC_KERNEL_SRC_LSEEK_EXECUTE + ZFS_AC_KERNEL_SRC_VFS_GETATTR + ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS + ZFS_AC_KERNEL_SRC_VFS_ITERATE + ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO + ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE + ZFS_AC_KERNEL_SRC_VFS_GENERIC_WRITE_CHECKS + ZFS_AC_KERNEL_SRC_KMAP_ATOMIC_ARGS + ZFS_AC_KERNEL_SRC_FOLLOW_DOWN_ONE + ZFS_AC_KERNEL_SRC_MAKE_REQUEST_FN + ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT + ZFS_AC_KERNEL_SRC_FPU + ZFS_AC_KERNEL_SRC_FMODE_T + ZFS_AC_KERNEL_SRC_KUIDGID_T + ZFS_AC_KERNEL_SRC_KUID_HELPERS + ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST + ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS + ZFS_AC_KERNEL_SRC_CURRENT_TIME + ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES + ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL + ZFS_AC_KERNEL_SRC_KTIME + ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC + ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES + ZFS_AC_KERNEL_SRC_KSTRTOUL + ZFS_AC_KERNEL_SRC_PERCPU + + AC_MSG_CHECKING([for available kernel interfaces]) + ZFS_LINUX_TEST_COMPILE_ALL([kabi]) + AC_MSG_RESULT([done]) +]) + +dnl # +dnl # Check results of kernel interface tests. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ + ZFS_AC_KERNEL_ACCESS_OK_TYPE + ZFS_AC_KERNEL_GLOBAL_PAGE_STATE + ZFS_AC_KERNEL_OBJTOOL + ZFS_AC_KERNEL_PDE_DATA + ZFS_AC_KERNEL_FALLOCATE + ZFS_AC_KERNEL_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE + ZFS_AC_KERNEL_RWSEM + ZFS_AC_KERNEL_SCHED + ZFS_AC_KERNEL_USLEEP_RANGE + ZFS_AC_KERNEL_KMEM_CACHE + ZFS_AC_KERNEL_KVMALLOC + ZFS_AC_KERNEL_VMALLOC_PAGE_KERNEL + ZFS_AC_KERNEL_WAIT + ZFS_AC_KERNEL_INODE_TIMES + ZFS_AC_KERNEL_INODE_LOCK + ZFS_AC_KERNEL_GROUP_INFO_GID + ZFS_AC_KERNEL_RW + ZFS_AC_KERNEL_TIMER_SETUP + ZFS_AC_KERNEL_SUPER_USER_NS + ZFS_AC_KERNEL_PROC_OPERATIONS + ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS + ZFS_AC_KERNEL_BIO + ZFS_AC_KERNEL_BLKDEV + ZFS_AC_KERNEL_BLK_QUEUE + ZFS_AC_KERNEL_GET_DISK_AND_MODULE + ZFS_AC_KERNEL_GET_DISK_RO + ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL + ZFS_AC_KERNEL_DISCARD_GRANULARITY + ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE + ZFS_AC_KERNEL_XATTR + ZFS_AC_KERNEL_ACL + ZFS_AC_KERNEL_INODE_GETATTR + ZFS_AC_KERNEL_INODE_SET_FLAGS + ZFS_AC_KERNEL_INODE_SET_IVERSION + ZFS_AC_KERNEL_SHOW_OPTIONS + ZFS_AC_KERNEL_FILE_INODE + ZFS_AC_KERNEL_FILE_DENTRY + ZFS_AC_KERNEL_FSYNC + ZFS_AC_KERNEL_AIO_FSYNC + ZFS_AC_KERNEL_EVICT_INODE + ZFS_AC_KERNEL_DIRTY_INODE + ZFS_AC_KERNEL_SHRINKER + ZFS_AC_KERNEL_MKDIR_UMODE_T + ZFS_AC_KERNEL_LOOKUP_FLAGS + ZFS_AC_KERNEL_CREATE_FLAGS + ZFS_AC_KERNEL_GET_LINK + ZFS_AC_KERNEL_PUT_LINK + ZFS_AC_KERNEL_TMPFILE + ZFS_AC_KERNEL_AUTOMOUNT + ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE + ZFS_AC_KERNEL_COMMIT_METADATA + ZFS_AC_KERNEL_CLEAR_INODE + ZFS_AC_KERNEL_SETATTR_PREPARE + ZFS_AC_KERNEL_INSERT_INODE_LOCKED + ZFS_AC_KERNEL_DENTRY + ZFS_AC_KERNEL_TRUNCATE_SETSIZE + ZFS_AC_KERNEL_SECURITY_INODE + ZFS_AC_KERNEL_FST_MOUNT + ZFS_AC_KERNEL_BDI + ZFS_AC_KERNEL_SET_NLINK + ZFS_AC_KERNEL_SGET + ZFS_AC_KERNEL_LSEEK_EXECUTE + ZFS_AC_KERNEL_VFS_GETATTR + ZFS_AC_KERNEL_VFS_FSYNC_2ARGS + ZFS_AC_KERNEL_VFS_ITERATE + ZFS_AC_KERNEL_VFS_DIRECT_IO + ZFS_AC_KERNEL_VFS_RW_ITERATE + ZFS_AC_KERNEL_VFS_GENERIC_WRITE_CHECKS + ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS + ZFS_AC_KERNEL_FOLLOW_DOWN_ONE + ZFS_AC_KERNEL_MAKE_REQUEST_FN + ZFS_AC_KERNEL_GENERIC_IO_ACCT + ZFS_AC_KERNEL_FPU + ZFS_AC_KERNEL_FMODE_T + ZFS_AC_KERNEL_KUIDGID_T + ZFS_AC_KERNEL_KUID_HELPERS + ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST + ZFS_AC_KERNEL_RENAME_WANTS_FLAGS + ZFS_AC_KERNEL_CURRENT_TIME + ZFS_AC_KERNEL_USERNS_CAPABILITIES + ZFS_AC_KERNEL_IN_COMPAT_SYSCALL + ZFS_AC_KERNEL_KTIME + ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC + ZFS_AC_KERNEL_TOTALHIGH_PAGES + ZFS_AC_KERNEL_KSTRTOUL + ZFS_AC_KERNEL_PERCPU +]) + +dnl # +dnl # Detect name used for Module.symvers file in kernel +dnl # +AC_DEFUN([ZFS_AC_MODULE_SYMVERS], [ + modpost=$LINUX/scripts/Makefile.modpost + AC_MSG_CHECKING([kernel file name for module symbols]) + AS_IF([test "x$enable_linux_builtin" != xyes -a -f "$modpost"], [ + AS_IF([grep -q Modules.symvers $modpost], [ + LINUX_SYMBOLS=Modules.symvers + ], [ + LINUX_SYMBOLS=Module.symvers + ]) + + AS_IF([test ! -f "$LINUX_OBJ/$LINUX_SYMBOLS"], [ + AC_MSG_ERROR([ + *** Please make sure the kernel devel package for your distribution + *** is installed. If you are building with a custom kernel, make sure + *** the kernel is configured, built, and the '--with-linux=PATH' + *** configure option refers to the location of the kernel source. + ]) + ]) + ], [ + LINUX_SYMBOLS=NONE + ]) + AC_MSG_RESULT($LINUX_SYMBOLS) + AC_SUBST(LINUX_SYMBOLS) +]) + +dnl # +dnl # Detect the kernel to be built against +dnl # +AC_DEFUN([ZFS_AC_KERNEL], [ + AC_ARG_WITH([linux], + AS_HELP_STRING([--with-linux=PATH], + [Path to kernel source]), + [kernelsrc="$withval"]) + + AC_ARG_WITH(linux-obj, + AS_HELP_STRING([--with-linux-obj=PATH], + [Path to kernel build objects]), + [kernelbuild="$withval"]) + + AC_MSG_CHECKING([kernel source directory]) + AS_IF([test -z "$kernelsrc"], [ + AS_IF([test -e "/lib/modules/$(uname -r)/source"], [ + headersdir="/lib/modules/$(uname -r)/source" + sourcelink=$(readlink -f "$headersdir") + ], [test -e "/lib/modules/$(uname -r)/build"], [ + headersdir="/lib/modules/$(uname -r)/build" + sourcelink=$(readlink -f "$headersdir") + ], [ + sourcelink=$(ls -1d /usr/src/kernels/* \ + /usr/src/linux-* \ + 2>/dev/null | grep -v obj | tail -1) + ]) + + AS_IF([test -n "$sourcelink" && test -e ${sourcelink}], [ + kernelsrc=`readlink -f ${sourcelink}` + ], [ + kernelsrc="[Not found]" + ]) + ], [ + AS_IF([test "$kernelsrc" = "NONE"], [ + kernsrcver=NONE + ]) + withlinux=yes + ]) + + AC_MSG_RESULT([$kernelsrc]) + AS_IF([test ! -d "$kernelsrc"], [ + AC_MSG_ERROR([ + *** Please make sure the kernel devel package for your distribution + *** is installed and then try again. If that fails, you can specify the + *** location of the kernel source with the '--with-linux=PATH' option.]) + ]) + + AC_MSG_CHECKING([kernel build directory]) + AS_IF([test -z "$kernelbuild"], [ + AS_IF([test x$withlinux != xyes -a -e "/lib/modules/$(uname -r)/build"], [ + kernelbuild=`readlink -f /lib/modules/$(uname -r)/build` + ], [test -d ${kernelsrc}-obj/${target_cpu}/${target_cpu}], [ + kernelbuild=${kernelsrc}-obj/${target_cpu}/${target_cpu} + ], [test -d ${kernelsrc}-obj/${target_cpu}/default], [ + kernelbuild=${kernelsrc}-obj/${target_cpu}/default + ], [test -d `dirname ${kernelsrc}`/build-${target_cpu}], [ + kernelbuild=`dirname ${kernelsrc}`/build-${target_cpu} + ], [ + kernelbuild=${kernelsrc} + ]) + ]) + AC_MSG_RESULT([$kernelbuild]) + + AC_MSG_CHECKING([kernel source version]) + utsrelease1=$kernelbuild/include/linux/version.h + utsrelease2=$kernelbuild/include/linux/utsrelease.h + utsrelease3=$kernelbuild/include/generated/utsrelease.h + AS_IF([test -r $utsrelease1 && fgrep -q UTS_RELEASE $utsrelease1], [ + utsrelease=linux/version.h + ], [test -r $utsrelease2 && fgrep -q UTS_RELEASE $utsrelease2], [ + utsrelease=linux/utsrelease.h + ], [test -r $utsrelease3 && fgrep -q UTS_RELEASE $utsrelease3], [ + utsrelease=generated/utsrelease.h + ]) + + AS_IF([test "$utsrelease"], [ + kernsrcver=`(echo "#include <$utsrelease>"; + echo "kernsrcver=UTS_RELEASE") | + ${CPP} -I $kernelbuild/include - | + grep "^kernsrcver=" | cut -d \" -f 2` + + AS_IF([test -z "$kernsrcver"], [ + AC_MSG_RESULT([Not found]) + AC_MSG_ERROR([ + *** Cannot determine kernel version. + ]) + ]) + ], [ + AC_MSG_RESULT([Not found]) + if test "x$enable_linux_builtin" != xyes; then + AC_MSG_ERROR([ + *** Cannot find UTS_RELEASE definition. + ]) + else + AC_MSG_ERROR([ + *** Cannot find UTS_RELEASE definition. + *** Please run 'make prepare' inside the kernel source tree.]) + fi + ]) + + AC_MSG_RESULT([$kernsrcver]) + + AS_VERSION_COMPARE([$kernsrcver], [$ZFS_META_KVER_MIN], [ + AC_MSG_ERROR([ + *** Cannot build against kernel version $kernsrcver. + *** The minimum supported kernel version is $ZFS_META_KVER_MIN. + ]) + ]) + + LINUX=${kernelsrc} + LINUX_OBJ=${kernelbuild} + LINUX_VERSION=${kernsrcver} + + AC_SUBST(LINUX) + AC_SUBST(LINUX_OBJ) + AC_SUBST(LINUX_VERSION) + + ZFS_AC_MODULE_SYMVERS +]) + +dnl # +dnl # Detect the QAT module to be built against, QAT provides hardware +dnl # acceleration for data compression: +dnl # +dnl # https://01.org/intel-quickassist-technology +dnl # +dnl # 1) Download and install QAT driver from the above link +dnl # 2) Start QAT driver in your system: +dnl # service qat_service start +dnl # 3) Enable QAT in ZFS, e.g.: +dnl # ./configure --with-qat=<qat-driver-path>/QAT1.6 +dnl # make +dnl # 4) Set GZIP compression in ZFS dataset: +dnl # zfs set compression = gzip <dataset> +dnl # +dnl # Then the data written to this ZFS pool is compressed by QAT accelerator +dnl # automatically, and de-compressed by QAT when read from the pool. +dnl # +dnl # 1) Get QAT hardware statistics with: +dnl # cat /proc/icp_dh895xcc_dev/qat +dnl # 2) To disable QAT: +dnl # insmod zfs.ko zfs_qat_disable=1 +dnl # +AC_DEFUN([ZFS_AC_QAT], [ + AC_ARG_WITH([qat], + AS_HELP_STRING([--with-qat=PATH], + [Path to qat source]), + AS_IF([test "$withval" = "yes"], + AC_MSG_ERROR([--with-qat=PATH requires a PATH]), + [qatsrc="$withval"])) + + AC_ARG_WITH([qat-obj], + AS_HELP_STRING([--with-qat-obj=PATH], + [Path to qat build objects]), + [qatbuild="$withval"]) + + AS_IF([test ! -z "${qatsrc}"], [ + AC_MSG_CHECKING([qat source directory]) + AC_MSG_RESULT([$qatsrc]) + QAT_SRC="${qatsrc}/quickassist" + AS_IF([ test ! -e "$QAT_SRC/include/cpa.h"], [ + AC_MSG_ERROR([ + *** Please make sure the qat driver package is installed + *** and specify the location of the qat source with the + *** '--with-qat=PATH' option then try again. Failed to + *** find cpa.h in: + ${QAT_SRC}/include]) + ]) + ]) + + AS_IF([test ! -z "${qatsrc}"], [ + AC_MSG_CHECKING([qat build directory]) + AS_IF([test -z "$qatbuild"], [ + qatbuild="${qatsrc}/build" + ]) + + AC_MSG_RESULT([$qatbuild]) + QAT_OBJ=${qatbuild} + AS_IF([ ! test -e "$QAT_OBJ/icp_qa_al.ko" && ! test -e "$QAT_OBJ/qat_api.ko"], [ + AC_MSG_ERROR([ + *** Please make sure the qat driver is installed then try again. + *** Failed to find icp_qa_al.ko or qat_api.ko in: + $QAT_OBJ]) + ]) + + AC_SUBST(QAT_SRC) + AC_SUBST(QAT_OBJ) + + AC_DEFINE(HAVE_QAT, 1, + [qat is enabled and existed]) + ]) + + dnl # + dnl # Detect the name used for the QAT Module.symvers file. + dnl # + AS_IF([test ! -z "${qatsrc}"], [ + AC_MSG_CHECKING([qat file for module symbols]) + QAT_SYMBOLS=$QAT_SRC/lookaside/access_layer/src/Module.symvers + + AS_IF([test -r $QAT_SYMBOLS], [ + AC_MSG_RESULT([$QAT_SYMBOLS]) + AC_SUBST(QAT_SYMBOLS) + ],[ + AC_MSG_ERROR([ + *** Please make sure the qat driver is installed then try again. + *** Failed to find Module.symvers in: + $QAT_SYMBOLS + ]) + ]) + ]) +]) + +dnl # +dnl # Basic toolchain sanity check. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_TEST_MODULE], [ + AC_MSG_CHECKING([whether modules can be built]) + ZFS_LINUX_TRY_COMPILE([], [], [ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + if test "x$enable_linux_builtin" != xyes; then + AC_MSG_ERROR([ + *** Unable to build an empty module. + ]) + else + AC_MSG_ERROR([ + *** Unable to build an empty module. + *** Please run 'make scripts' inside the kernel source tree.]) + fi + ]) +]) + +dnl # +dnl # ZFS_LINUX_CONFTEST_H +dnl # +AC_DEFUN([ZFS_LINUX_CONFTEST_H], [ +test -d build/$2 || mkdir -p build/$2 +cat - <<_ACEOF >build/$2/$2.h +$1 +_ACEOF +]) + +dnl # +dnl # ZFS_LINUX_CONFTEST_C +dnl # +AC_DEFUN([ZFS_LINUX_CONFTEST_C], [ +test -d build/$2 || mkdir -p build/$2 +cat confdefs.h - <<_ACEOF >build/$2/$2.c +$1 +_ACEOF +]) + +dnl # +dnl # ZFS_LINUX_CONFTEST_MAKEFILE +dnl # +dnl # $1 - test case name +dnl # $2 - add to top-level Makefile +dnl # $3 - additional build flags +dnl # +AC_DEFUN([ZFS_LINUX_CONFTEST_MAKEFILE], [ + test -d build || mkdir -p build + test -d build/$1 || mkdir -p build/$1 + + file=build/$1/Makefile + + dnl # Example command line to manually build source. + cat - <<_ACEOF >$file +# Example command line to manually build source +# make modules -C $LINUX_OBJ $ARCH_UM M=$PWD/build/$1 + +ccflags-y := -Werror $FRAME_LARGER_THAN +_ACEOF + + dnl # Additional custom CFLAGS as requested. + m4_ifval($3, [echo "ccflags-y += $3" >>$file], []) + + dnl # Test case source + echo "obj-m := $1.o" >>$file + + AS_IF([test "x$2" = "xyes"], [echo "obj-m += $1/" >>build/Makefile], []) +]) + +dnl # +dnl # ZFS_LINUX_TEST_PROGRAM(C)([PROLOGUE], [BODY]) +dnl # +m4_define([ZFS_LINUX_TEST_PROGRAM], [ +$1 +int +main (void) +{ +$2 + ; + return 0; +} +]) + +dnl # +dnl # ZFS_LINUX_TEST_REMOVE +dnl # +dnl # Removes the specified test source and results. +dnl # +AC_DEFUN([ZFS_LINUX_TEST_REMOVE], [ + test -d build/$1 && rm -Rf build/$1 + test -f build/Makefile && sed '/$1/d' build/Makefile +]) + +dnl # +dnl # ZFS_LINUX_COMPILE +dnl # +dnl # $1 - build dir +dnl # $2 - test command +dnl # $3 - pass command +dnl # $4 - fail command +dnl # $5 - set KBUILD_MODPOST_NOFINAL='yes' +dnl # $6 - set KBUILD_MODPOST_WARN='yes' +dnl # +dnl # Used internally by ZFS_LINUX_TEST_{COMPILE,MODPOST} +dnl # +AC_DEFUN([ZFS_LINUX_COMPILE], [ + AC_TRY_COMMAND([ + KBUILD_MODPOST_NOFINAL="$5" KBUILD_MODPOST_WARN="$6" + make modules -k -j$TEST_JOBS -C $LINUX_OBJ $ARCH_UM + M=$PWD/$1 >$1/build.log 2>&1]) + AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4]) +]) + +dnl # +dnl # ZFS_LINUX_TEST_COMPILE +dnl # +dnl # Perform a full compile excluding the final modpost phase. +dnl # +AC_DEFUN([ZFS_LINUX_TEST_COMPILE], [ + ZFS_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.]) + ], [yes], []) +]) + +dnl # +dnl # ZFS_LINUX_TEST_MODPOST +dnl # +dnl # Perform a full compile including the modpost phase. This may +dnl # be an incremental build if the objects have already been built. +dnl # +AC_DEFUN([ZFS_LINUX_TEST_MODPOST], [ + ZFS_LINUX_COMPILE([$2], [test -f $2/build.log], [ + mv $2/Makefile $2/Makefile.modpost.$1 + cat $2/build.log >>build/build.log.$1 + ],[ + AC_MSG_ERROR([ + *** Unable to modpost test source to determine kernel interfaces.]) + ], [], [yes]) +]) + +dnl # +dnl # Perform the compilation of the test cases in two phases. +dnl # +dnl # Phase 1) attempt to build the object files for all of the tests +dnl # defined by the ZFS_LINUX_TEST_SRC macro. But do not +dnl # perform the final modpost stage. +dnl # +dnl # Phase 2) disable all tests which failed the initial compilation, +dnl # then invoke the final modpost step for the remaining tests. +dnl # +dnl # This allows us efficiently build the test cases in parallel while +dnl # remaining resilient to build failures which are expected when +dnl # detecting the available kernel interfaces. +dnl # +dnl # The maximum allowed parallelism can be controlled by setting the +dnl # TEST_JOBS environment variable. Otherwise, it default to $(nproc). +dnl # +AC_DEFUN([ZFS_LINUX_TEST_COMPILE_ALL], [ + dnl # Phase 1 - Compilation only, final linking is skipped. + ZFS_LINUX_TEST_COMPILE([$1], [build]) + + dnl # + dnl # Phase 2 - When building external modules disable test cases + dnl # which failed to compile and invoke modpost to verify the + dnl # final linking. + dnl # + dnl # Test names suffixed with '_license' call modpost independently + dnl # to ensure that a single incompatibility does not result in the + dnl # modpost phase exiting early. This check is not performed on + dnl # every symbol since the majority are compatible and doing so + dnl # would significantly slow down this phase. + dnl # + dnl # When configuring for builtin (--enable-linux-builtin) + dnl # fake the linking step artificially create the expected .ko + dnl # files for tests which did compile. This is required for + dnl # kernels which do not have loadable module support or have + dnl # not yet been built. + dnl # + AS_IF([test "x$enable_linux_builtin" = "xno"], [ + for dir in $(awk '/^obj-m/ { print [$]3 }' \ + build/Makefile.compile.$1); do + name=${dir%/} + AS_IF([test -f build/$name/$name.o], [ + AS_IF([test "${name##*_}" = "license"], [ + ZFS_LINUX_TEST_MODPOST([$1], + [build/$name]) + echo "obj-n += $dir" >>build/Makefile + ], [ + echo "obj-m += $dir" >>build/Makefile + ]) + ], [ + echo "obj-n += $dir" >>build/Makefile + ]) + done + + ZFS_LINUX_TEST_MODPOST([$1], [build]) + ], [ + for dir in $(awk '/^obj-m/ { print [$]3 }' \ + build/Makefile.compile.$1); do + name=${dir%/} + AS_IF([test -f build/$name/$name.o], [ + touch build/$name/$name.ko + ]) + done + ]) +]) + +dnl # +dnl # ZFS_LINUX_TEST_SRC +dnl # +dnl # $1 - name +dnl # $2 - global +dnl # $3 - source +dnl # $4 - extra cflags +dnl # $5 - check license-compatibility +dnl # +dnl # N.B because all of the test cases are compiled in parallel they +dnl # must never depend on the results of previous tests. Each test +dnl # needs to be entirely independent. +dnl # +AC_DEFUN([ZFS_LINUX_TEST_SRC], [ + ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM([[$2]], [[$3]])], [$1]) + ZFS_LINUX_CONFTEST_MAKEFILE([$1], [yes], [$4]) + + AS_IF([ test -n "$5" ], [ + ZFS_LINUX_CONFTEST_C([ZFS_LINUX_TEST_PROGRAM([[ + #include <linux/module.h> + MODULE_LICENSE("$5"); + $2]], [[$3]])], [$1_license]) + ZFS_LINUX_CONFTEST_MAKEFILE([$1_license], [yes], [$4]) + ]) +]) + +dnl # +dnl # ZFS_LINUX_TEST_RESULT +dnl # +dnl # $1 - name of a test source (ZFS_LINUX_TEST_SRC) +dnl # $2 - run on success (valid .ko generated) +dnl # $3 - run on failure (unable to compile) +dnl # +AC_DEFUN([ZFS_LINUX_TEST_RESULT], [ + AS_IF([test -d build/$1], [ + AS_IF([test -f build/$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. + ]) + ]) +]) + +dnl # +dnl # ZFS_LINUX_TEST_ERROR +dnl # +dnl # Generic error message which can be used when none of the expected +dnl # kernel interfaces were detected. +dnl # +AC_DEFUN([ZFS_LINUX_TEST_ERROR], [ + AC_MSG_ERROR([ + *** None of the expected "$1" interfaces were detected. + *** This may be because your kernel version is newer than what is + *** supported, or you are using a patched custom kernel with + *** incompatible modifications. + *** + *** ZFS Version: $ZFS_META_ALIAS + *** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX + ]) +]) + +dnl # +dnl # ZFS_LINUX_TEST_RESULT_SYMBOL +dnl # +dnl # Like ZFS_LINUX_TEST_RESULT except ZFS_CHECK_SYMBOL_EXPORT is called to +dnl # verify symbol exports, unless --enable-linux-builtin was provided to +dnl # configure. +dnl # +AC_DEFUN([ZFS_LINUX_TEST_RESULT_SYMBOL], [ + AS_IF([ ! test -f build/$1/$1.ko], [ + $5 + ], [ + AS_IF([test "x$enable_linux_builtin" != "xyes"], [ + ZFS_CHECK_SYMBOL_EXPORT([$2], [$3], [$4], [$5]) + ], [ + $4 + ]) + ]) +]) + +dnl # +dnl # ZFS_LINUX_COMPILE_IFELSE +dnl # +AC_DEFUN([ZFS_LINUX_COMPILE_IFELSE], [ + ZFS_LINUX_TEST_REMOVE([conftest]) + + m4_ifvaln([$1], [ZFS_LINUX_CONFTEST_C([$1], [conftest])]) + m4_ifvaln([$5], [ZFS_LINUX_CONFTEST_H([$5], [conftest])], + [ZFS_LINUX_CONFTEST_H([], [conftest])]) + + ZFS_LINUX_CONFTEST_MAKEFILE([conftest], [no], + [m4_ifvaln([$5], [-I$PWD/build/conftest], [])]) + ZFS_LINUX_COMPILE([build/conftest], [$2], [$3], [$4], [], []) +]) + +dnl # +dnl # ZFS_LINUX_TRY_COMPILE +dnl # +dnl # $1 - global +dnl # $2 - source +dnl # $3 - run on success (valid .ko generated) +dnl # $4 - run on failure (unable to compile) +dnl # +dnl # When configuring as builtin (--enable-linux-builtin) for kernels +dnl # without loadable module support (CONFIG_MODULES=n) only the object +dnl # file is created. See ZFS_LINUX_TEST_COMPILE_ALL for details. +dnl # +AC_DEFUN([ZFS_LINUX_TRY_COMPILE], [ + AS_IF([test "x$enable_linux_builtin" = "xyes"], [ + ZFS_LINUX_COMPILE_IFELSE( + [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]])], + [test -f build/conftest/conftest.o], [$3], [$4]) + ], [ + ZFS_LINUX_COMPILE_IFELSE( + [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]])], + [test -f build/conftest/conftest.ko], [$3], [$4]) + ]) +]) + +dnl # +dnl # ZFS_CHECK_SYMBOL_EXPORT +dnl # +dnl # Check if a symbol is exported on not by consulting the symbols +dnl # file, or optionally the source code. +dnl # +AC_DEFUN([ZFS_CHECK_SYMBOL_EXPORT], [ + grep -q -E '[[[:space:]]]$1[[[:space:]]]' \ + $LINUX_OBJ/$LINUX_SYMBOLS 2>/dev/null + rc=$? + if test $rc -ne 0; then + export=0 + for file in $2; do + grep -q -E "EXPORT_SYMBOL.*($1)" \ + "$LINUX/$file" 2>/dev/null + rc=$? + if test $rc -eq 0; then + export=1 + break; + fi + done + if test $export -eq 0; then : + $4 + else : + $3 + fi + else : + $3 + fi +]) + +dnl # +dnl # ZFS_LINUX_TRY_COMPILE_SYMBOL +dnl # +dnl # Like ZFS_LINUX_TRY_COMPILER except ZFS_CHECK_SYMBOL_EXPORT is called +dnl # to verify symbol exports, unless --enable-linux-builtin was provided +dnl # to configure. +dnl # +AC_DEFUN([ZFS_LINUX_TRY_COMPILE_SYMBOL], [ + ZFS_LINUX_TRY_COMPILE([$1], [$2], [rc=0], [rc=1]) + if test $rc -ne 0; then : + $6 + else + if test "x$enable_linux_builtin" != xyes; then + ZFS_CHECK_SYMBOL_EXPORT([$3], [$4], [rc=0], [rc=1]) + fi + if test $rc -ne 0; then : + $6 + else : + $5 + fi + fi +]) + +dnl # +dnl # ZFS_LINUX_TRY_COMPILE_HEADER +dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are +dnl # provided via the fifth parameter +dnl # +AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [ + ZFS_LINUX_COMPILE_IFELSE( + [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]])], + [test -f build/conftest/conftest.ko], + [$3], [$4], [$5]) +]) diff --git a/config/lib-ld.m4 b/config/lib-ld.m4 new file mode 100644 index 000000000000..a18719630d59 --- /dev/null +++ b/config/lib-ld.m4 @@ -0,0 +1,168 @@ +# lib-ld.m4 serial 9 +dnl Copyright (C) 1996-2003, 2009-2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid +dnl collision with libtool.m4. + +dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + acl_cv_prog_gnu_ld=yes + ;; +*) + acl_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-2.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld [default=no]])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +if test -n "$LD"; then + AC_MSG_CHECKING([for ld]) +elif test "$GCC" = yes; then + AC_MSG_CHECKING([for ld used by $CC]) +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + AC_CACHE_VAL([acl_cv_path_LD], + [ + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$acl_save_ifs" + fi + case $host in + *-*-aix*) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + ]])], + [# The compiler produces 64-bit code. Add option '-b64' so that the + # linker groks 64-bit object files. + case "$acl_cv_path_LD " in + *" -b64 "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;; + esac + ], []) + ;; + sparc64-*-netbsd*) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [], + [# The compiler produces 32-bit code. Add option '-m elf32_sparc' + # so that the linker groks 32-bit object files. + case "$acl_cv_path_LD " in + *" -m elf32_sparc "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;; + esac + ]) + ;; + esac + ]) + LD="$acl_cv_path_LD" +fi +if test -n "$LD"; then + AC_MSG_RESULT([$LD]) +else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([no acceptable ld found in \$PATH]) +fi +AC_LIB_PROG_LD_GNU +]) diff --git a/config/lib-link.m4 b/config/lib-link.m4 new file mode 100644 index 000000000000..041f976d79a1 --- /dev/null +++ b/config/lib-link.m4 @@ -0,0 +1,774 @@ +# lib-link.m4 serial 28 +dnl Copyright (C) 2001-2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ([2.61]) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[m4_translit([$1],[./+-], [____])]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + popdef([NAME]) + popdef([Name]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message]) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. The missing-message +dnl defaults to 'no' and may contain additional hints for the user. +dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} +dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[m4_translit([$1],[./+-], [____])]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl so that if lib[]Name is installed, it will be used (unless + dnl disabled via --without-lib[]Name-prefix). + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS, + dnl because these -l options might require -L options that are present in + dnl LIBS. -l options benefit only from the -L options listed before it. + dnl Otherwise, add it to the front of LIBS, because it may be a static + dnl library that depends on another static library that is present in LIBS. + dnl Static libraries benefit only from the static libraries listed after + dnl it. + case " $LIB[]NAME" in + *" -l"*) LIBS="$LIBS $LIB[]NAME" ;; + *) LIBS="$LIB[]NAME $LIBS" ;; + esac + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[$3]], [[$4]])], + [ac_cv_lib[]Name=yes], + [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])']) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + LIB[]NAME[]_PREFIX= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + popdef([NAME]) + popdef([Name]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl acl_libext, +dnl acl_shlibext, +dnl acl_libname_spec, +dnl acl_library_names_spec, +dnl acl_hardcode_libdir_flag_spec, +dnl acl_hardcode_libdir_separator, +dnl acl_hardcode_direct, +dnl acl_hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Complain if config.rpath is missing. + AC_REQUIRE_AUX_FILE([config.rpath]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH(PACK[-prefix], +[[ --with-]]PACK[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]PACK[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && test ! -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-search. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been + dnl computed. So it has to be reset here. + HAVE_LIB[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/config/lib-prefix.m4 b/config/lib-prefix.m4 new file mode 100644 index 000000000000..f7db2371db45 --- /dev/null +++ b/config/lib-prefix.m4 @@ -0,0 +1,248 @@ +# lib-prefix.m4 serial 14 +dnl Copyright (C) 2001-2005, 2008-2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl packages should use other packages that are installed with the same +dnl --prefix option. This macro is not needed if only AC_LIB_LINKFLAGS is +dnl used to locate libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH([lib-prefix], +[[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a variable acl_libdirstem, containing the basename of the libdir, either +dnl "lib" or "lib64" or "lib/64", +dnl - a variable acl_libdirstem2, as a secondary possible value for +dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or +dnl "lib/amd64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. + dnl On glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine + dnl the compiler's default mode by looking at the compiler's library search + dnl path. If at least one of its elements ends in /lib64 or points to a + dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. + dnl Otherwise we use the default, namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_HOST_CPU_C_ABI_32BIT]) + + case "$host_os" in + solaris*) + AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _LP64 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_solaris_64bit=yes], + [gl_cv_solaris_64bit=no]) + ]);; + esac + + dnl Allow the user to override the result by setting acl_cv_libdirstems. + AC_CACHE_CHECK([for the common suffixes of directories in the library search path], + [acl_cv_libdirstems], + [acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl <https://docs.oracle.com/cd/E19253-01/816-5138/dev-env/index.html>. + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + dnl If $CC generates code for a 32-bit ABI, the libraries are + dnl surely under $prefix/lib, not $prefix/lib64. + if test "$HOST_CPU_C_ABI_32BIT" != yes; then + dnl The result is a property of the system. However, non-system + dnl compilers sometimes have odd library search paths. Therefore + dnl prefer asking /usr/bin/gcc, if available, rather than $CC. + searchpath=`(if test -f /usr/bin/gcc \ + && LC_ALL=C /usr/bin/gcc -print-search-dirs >/dev/null 2>/dev/null; then \ + LC_ALL=C /usr/bin/gcc -print-search-dirs; \ + else \ + LC_ALL=C $CC -print-search-dirs; \ + fi) 2>/dev/null \ + | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2" + ]) + # Decompose acl_cv_libdirstems into acl_libdirstem and acl_libdirstem2. + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e '/,/s/.*,//'` +]) diff --git a/config/mount-helper.m4 b/config/mount-helper.m4 new file mode 100644 index 000000000000..0a6c7670840b --- /dev/null +++ b/config/mount-helper.m4 @@ -0,0 +1,8 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_MOUNT_HELPER], [ + AC_ARG_WITH(mounthelperdir, + AC_HELP_STRING([--with-mounthelperdir=DIR], + [install mount.zfs in dir [[/sbin]]]), + mounthelperdir=$withval,mounthelperdir=/sbin) + + AC_SUBST(mounthelperdir) +]) diff --git a/config/nls.m4 b/config/nls.m4 new file mode 100644 index 000000000000..b62f61485700 --- /dev/null +++ b/config/nls.m4 @@ -0,0 +1,32 @@ +# nls.m4 serial 5 (gettext-0.18) +dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016, 2019 Free Software +dnl Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. + +AC_PREREQ([2.50]) + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE([nls], + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT([$USE_NLS]) + AC_SUBST([USE_NLS]) +]) diff --git a/config/pkg.m4 b/config/pkg.m4 new file mode 100644 index 000000000000..f9075e56c87a --- /dev/null +++ b/config/pkg.m4 @@ -0,0 +1,275 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + +dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.2]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurrence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR diff --git a/config/po.m4 b/config/po.m4 new file mode 100644 index 000000000000..143792dba560 --- /dev/null +++ b/config/po.m4 @@ -0,0 +1,450 @@ +# po.m4 serial 30 (gettext-0.20) +dnl Copyright (C) 1995-2014, 2016, 2018-2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. + +AC_PREREQ([2.60]) + +dnl Checks for all prerequisites of the po subdirectory. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AC_PROG_MKDIR_P])dnl + AC_REQUIRE([AC_PROG_SED])dnl + AC_REQUIRE([AM_NLS])dnl + + dnl Release version of the gettext macros. This is used to ensure that + dnl the gettext macros and po/Makefile.in.in are in sync. + AC_SUBST([GETTEXT_MACRO_VERSION], [0.20]) + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) + + dnl Test whether it is GNU msgfmt >= 0.15. +changequote(,)dnl + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([GMSGFMT_015]) + + dnl Search for GNU xgettext 0.12 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Test whether it is GNU xgettext >= 0.15. +changequote(,)dnl + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac +changequote([,])dnl + AC_SUBST([XGETTEXT_015]) + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) + + dnl Test whether it is GNU msgmerge >= 0.20. + if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt' + else + dnl Test whether it is GNU msgmerge >= 0.12. + if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet' + else + dnl With these old versions, $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) is + dnl slow. But this is not a big problem, as such old gettext versions are + dnl hardly in use any more. + MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet' + fi + fi + AC_SUBST([MSGMERGE_FOR_MSGFMT_OPTION]) + + dnl Support for AM_XGETTEXT_OPTION. + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) + + AC_CONFIG_COMMANDS([po-directories], [[ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + gt_tab=`printf '\t'` + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done]], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. + OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS" + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + +dnl Postprocesses a Makefile in a directory containing PO files. +AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], +[ + # When this code is run, in config.status, two variables have already been + # set: + # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, + # - LINGUAS is the value of the environment variable LINGUAS at configure + # time. + +changequote(,)dnl + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + # Find a way to echo strings without interpreting backslash. + if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='echo' + else + if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='printf %s\n' + else + echo_func () { + cat <<EOT +$* +EOT + } + gt_echo='echo_func' + fi + fi + + # A sed script that extracts the value of VARIABLE from a Makefile. + tab=`printf '\t'` + sed_x_variable=' +# Test if the hold space is empty. +x +s/P/P/ +x +ta +# Yes it was empty. Look if we have the expected variable definition. +/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=/{ + # Seen the first line of the variable definition. + s/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=// + ba +} +bd +:a +# Here we are processing a line from the variable definition. +# Remove comment, more precisely replace it with a space. +s/#.*$/ / +# See if the line ends in a backslash. +tb +:b +s/\\$// +# Print the line, without the trailing backslash. +p +tc +# There was no trailing backslash. The end of the variable definition is +# reached. Clear the hold space. +s/^.*$// +x +bd +:c +# A trailing backslash means that the variable definition continues in the +# next line. Put a nonempty string into the hold space to indicate this. +s/^.*$/P/ +x +:d +' +changequote([,])dnl + + # Set POTFILES to the value of the Makefile variable POTFILES. + sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'` + POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"` + # Compute POTFILES_DEPS as + # $(foreach file, $(POTFILES), $(top_srcdir)/$(file)) + POTFILES_DEPS= + for file in $POTFILES; do + POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file" + done + POMAKEFILEDEPS="" + + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS. + sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'` + ALL_LINGUAS=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"` + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + # Compute PROPERTIESFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(DOMAIN)_$(lang).properties) + # Compute CLASSFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(DOMAIN)_$(lang).class) + # Compute QMFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm) + # Compute MSGFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg) + # Compute RESOURCESDLLFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + PROPERTIESFILES= + CLASSFILES= + QMFILES= + MSGFILES= + RESOURCESDLLFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + PROPERTIESFILES="$PROPERTIESFILES \$(srcdir)/\$(DOMAIN)_$lang.properties" + CLASSFILES="$CLASSFILES \$(srcdir)/\$(DOMAIN)_$lang.class" + QMFILES="$QMFILES $srcdirpre$lang.qm" + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg" + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + JAVACATALOGS= + QTCATALOGS= + TCLCATALOGS= + CSHARPCATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties" + QTCATALOGS="$QTCATALOGS $lang.qm" + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg" + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll" + done + fi + + sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp" + tab=`printf '\t'` + if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + cat >> "$ac_file.tmp" <<EOF +$frobbedlang.msg: $lang.po +${tab}@echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \ +${tab}\$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; } +EOF + done + fi + if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + cat >> "$ac_file.tmp" <<EOF +$frobbedlang/\$(DOMAIN).resources.dll: $lang.po +${tab}@echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \ +${tab}\$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; } +EOF + done + fi + if test -n "$POMAKEFILEDEPS"; then + cat >> "$ac_file.tmp" <<EOF +Makefile: $POMAKEFILEDEPS +EOF + fi + mv "$ac_file.tmp" "$ac_file" +]) + +dnl Initializes the accumulator used by AM_XGETTEXT_OPTION. +AC_DEFUN([AM_XGETTEXT_OPTION_INIT], +[ + XGETTEXT_EXTRA_OPTIONS= +]) + +dnl Registers an option to be passed to xgettext in the po subdirectory. +AC_DEFUN([AM_XGETTEXT_OPTION], +[ + AC_REQUIRE([AM_XGETTEXT_OPTION_INIT]) + XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1" +]) diff --git a/config/progtest.m4 b/config/progtest.m4 new file mode 100644 index 000000000000..5f186b14909c --- /dev/null +++ b/config/progtest.m4 @@ -0,0 +1,91 @@ +# progtest.m4 serial 7 (gettext-0.18.2) +dnl Copyright (C) 1996-2003, 2005, 2008-2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1996. + +AC_PREREQ([2.50]) + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[ +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL([ac_cv_path_$1], +[case "[$]$1" in + [[\\/]]* | ?:[[\\/]]*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in ifelse([$5], , $PATH, [$5]); do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$][$1]) +else + AC_MSG_RESULT([no]) +fi +AC_SUBST([$1])dnl +]) diff --git a/config/rpm.am b/config/rpm.am new file mode 100644 index 000000000000..9dd69ade333e --- /dev/null +++ b/config/rpm.am @@ -0,0 +1,93 @@ +############################################################################### +# Copyright (C) 2007-2013 Lawrence Livermore National Security, LLC. +# Copyright (C) 2007 The Regents of the University of California. +# Written by Brian Behlendorf <behlendorf1@llnl.gov>. +############################################################################### +# Build targets for RPM packages. +############################################################################### + +PHONY += srpm srpms srpm-kmod srpm-dkms srpm-utils +PHONY += rpm rpms rpm-kmod rpm-dkms rpm-utils +PHONY += srpm-common rpm-common rpm-local + +srpm-kmod srpm-dkms srpm-utils: dist + +srpm-kmod: + $(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \ + def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_KMOD}' srpm-common + +srpm-dkms: + $(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \ + def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_DKMS}' srpm-common + +srpm-utils: + $(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \ + def='${SRPM_DEFINE_COMMON} ${SRPM_DEFINE_UTIL}' srpm-common + +srpm: srpm-kmod srpm-dkms srpm-utils +srpms: srpm-kmod srpm-dkms srpm-utils + +rpm-kmod: srpm-kmod + $(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-kmod" \ + def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_KMOD}' rpm-common + +rpm-dkms: srpm-dkms + $(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}-dkms" \ + def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_DKMS}' rpm-common + +rpm-utils: srpm-utils + $(MAKE) $(AM_MAKEFLAGS) pkg="${PACKAGE}" \ + def='${RPM_DEFINE_COMMON} ${RPM_DEFINE_UTIL}' rpm-common + +rpm: rpm-kmod rpm-dkms rpm-utils +rpms: rpm-kmod rpm-dkms rpm-utils + +rpm-local: + @(if test "${HAVE_RPMBUILD}" = "no"; then \ + echo -e "\n" \ + "*** Required util ${RPMBUILD} missing. Please install the\n" \ + "*** package for your distribution which provides ${RPMBUILD},\n" \ + "*** re-run configure, and try again.\n"; \ + exit 1; \ + fi; \ + mkdir -p $(rpmbuild)/TMP && \ + mkdir -p $(rpmbuild)/BUILD && \ + mkdir -p $(rpmbuild)/RPMS && \ + mkdir -p $(rpmbuild)/SRPMS && \ + mkdir -p $(rpmbuild)/SPECS && \ + cp ${RPM_SPEC_DIR}/$(rpmspec) $(rpmbuild)/SPECS && \ + mkdir -p $(rpmbuild)/SOURCES && \ + cp $(top_srcdir)/scripts/kmodtool $(rpmbuild)/SOURCES && \ + cp $(distdir).tar.gz $(rpmbuild)/SOURCES) + +srpm-common: + @(dist=`$(RPM) --eval %{?dist}`; \ + rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \ + rpmspec=$(pkg).spec; \ + rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \ + $(MAKE) $(AM_MAKEFLAGS) \ + rpmbuild="$$rpmbuild" \ + rpmspec="$$rpmspec" \ + rpm-local || exit 1; \ + LANG=C $(RPMBUILD) \ + --define "_tmppath $$rpmbuild/TMP" \ + --define "_topdir $$rpmbuild" \ + $(def) -bs $$rpmbuild/SPECS/$$rpmspec || exit 1; \ + cp $$rpmbuild/SRPMS/$$rpmpkg . || exit 1; \ + rm -R $$rpmbuild) + +rpm-common: + @(dist=`$(RPM) --eval %{?dist}`; \ + rpmpkg=$(pkg)-$(VERSION)-$(RELEASE)$$dist*src.rpm; \ + rpmspec=$(pkg).spec; \ + rpmbuild=`mktemp -t -d $(PACKAGE)-build-$$USER-XXXXXXXX`; \ + $(MAKE) $(AM_MAKEFLAGS) \ + rpmbuild="$$rpmbuild" \ + rpmspec="$$rpmspec" \ + rpm-local || exit 1; \ + LANG=C ${RPMBUILD} \ + --define "_tmppath $$rpmbuild/TMP" \ + --define "_topdir $$rpmbuild" \ + $(def) --rebuild $$rpmpkg || exit 1; \ + cp $$rpmbuild/RPMS/*/* . || exit 1; \ + rm -R $$rpmbuild) diff --git a/config/tgz.am b/config/tgz.am new file mode 100644 index 000000000000..2499ba42305b --- /dev/null +++ b/config/tgz.am @@ -0,0 +1,30 @@ +PHONY += tgz tgz-kmod tgz-utils tgz-local + +tgz-local: + @(if test "${HAVE_ALIEN}" = "no"; then \ + echo -e "\n" \ + "*** Required util ${ALIEN} missing. Please install the\n" \ + "*** package for your distribution which provides ${ALIEN},\n" \ + "*** re-run configure, and try again.\n"; \ + exit 1; \ + fi) + +tgz-kmod: tgz-local rpm-kmod + name=${PACKAGE}; \ + version=${VERSION}-${RELEASE}; \ + arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \ + pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \ + fakeroot $(ALIEN) --scripts --to-tgz $$pkg1; \ + $(RM) $$pkg1 + +tgz-utils: tgz-local rpm-utils + name=${PACKAGE}; \ + version=${VERSION}-${RELEASE}; \ + arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \ + pkg1=$${name}-$${version}.$${arch}.rpm; \ + pkg2=$${name}-devel-$${version}.$${arch}.rpm; \ + pkg3=$${name}-test-$${version}.$${arch}.rpm; \ + fakeroot $(ALIEN) --scripts --to-tgz $$pkg1 $$pkg2 $$pkg3; \ + $(RM) $$pkg1 $$pkg2 $$pkg3 + +tgz: tgz-kmod tgz-utils diff --git a/config/toolchain-simd.m4 b/config/toolchain-simd.m4 new file mode 100644 index 000000000000..1153cd6941a8 --- /dev/null +++ b/config/toolchain-simd.m4 @@ -0,0 +1,424 @@ +dnl # +dnl # Checks if host toolchain supports SIMD instructions +dnl # +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_SIMD], [ + case "$host_cpu" in + amd64 | x86_64 | x86 | i686) + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE2 + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE3 + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSSE3 + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_1 + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_2 + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX2 + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512F + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512CD + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512DQ + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512BW + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512IFMA + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VBMI + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512PF + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512ER + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VL + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AES + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_PCLMULQDQ + ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_MOVBE + ;; + esac +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE], [ + AC_MSG_CHECKING([whether host toolchain supports SSE]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + void main() + { + __asm__ __volatile__("xorps %xmm0, %xmm1"); + } + ]])], [ + AC_DEFINE([HAVE_SSE], 1, [Define if host toolchain supports SSE]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE2 +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE2], [ + AC_MSG_CHECKING([whether host toolchain supports SSE2]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + void main() + { + __asm__ __volatile__("pxor %xmm0, %xmm1"); + } + ]])], [ + AC_DEFINE([HAVE_SSE2], 1, [Define if host toolchain supports SSE2]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE3 +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE3], [ + AC_MSG_CHECKING([whether host toolchain supports SSE3]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + void main() + { + char v[16]; + __asm__ __volatile__("lddqu %0,%%xmm0" :: "m"(v[0])); + } + ]])], [ + AC_DEFINE([HAVE_SSE3], 1, [Define if host toolchain supports SSE3]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSSE3 +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSSE3], [ + AC_MSG_CHECKING([whether host toolchain supports SSSE3]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + void main() + { + __asm__ __volatile__("pshufb %xmm0,%xmm1"); + } + ]])], [ + AC_DEFINE([HAVE_SSSE3], 1, [Define if host toolchain supports SSSE3]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_1 +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_1], [ + AC_MSG_CHECKING([whether host toolchain supports SSE4.1]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + void main() + { + __asm__ __volatile__("pmaxsb %xmm0,%xmm1"); + } + ]])], [ + AC_DEFINE([HAVE_SSE4_1], 1, [Define if host toolchain supports SSE4.1]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_2 +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_SSE4_2], [ + AC_MSG_CHECKING([whether host toolchain supports SSE4.2]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + void main() + { + __asm__ __volatile__("pcmpgtq %xmm0, %xmm1"); + } + ]])], [ + AC_DEFINE([HAVE_SSE4_2], 1, [Define if host toolchain supports SSE4.2]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX], [ + AC_MSG_CHECKING([whether host toolchain supports AVX]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([[ + void main() + { + char v[32]; + __asm__ __volatile__("vmovdqa %0,%%ymm0" :: "m"(v[0])); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX], 1, [Define if host toolchain supports AVX]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX2 +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX2], [ + AC_MSG_CHECKING([whether host toolchain supports AVX2]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vpshufb %ymm0,%ymm1,%ymm2"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX2], 1, [Define if host toolchain supports AVX2]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512F +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512F], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512F]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vpandd %zmm0,%zmm1,%zmm2"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512F], 1, [Define if host toolchain supports AVX512F]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512CD +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512CD], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512CD]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vplzcntd %zmm0,%zmm1"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512CD], 1, [Define if host toolchain supports AVX512CD]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512DQ +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512DQ], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512DQ]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vandpd %zmm0,%zmm1,%zmm2"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512DQ], 1, [Define if host toolchain supports AVX512DQ]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512BW +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512BW], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512BW]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vpshufb %zmm0,%zmm1,%zmm2"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512BW], 1, [Define if host toolchain supports AVX512BW]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512IFMA +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512IFMA], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512IFMA]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vpmadd52luq %zmm0,%zmm1,%zmm2"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512IFMA], 1, [Define if host toolchain supports AVX512IFMA]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VBMI +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VBMI], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512VBMI]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vpermb %zmm0,%zmm1,%zmm2"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512VBMI], 1, [Define if host toolchain supports AVX512VBMI]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512PF +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512PF], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512PF]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vgatherpf0dps (%rsi,%zmm0,4){%k1}"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512PF], 1, [Define if host toolchain supports AVX512PF]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512ER +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512ER], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512ER]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vexp2pd %zmm0,%zmm1"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512ER], 1, [Define if host toolchain supports AVX512ER]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VL +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AVX512VL], [ + AC_MSG_CHECKING([whether host toolchain supports AVX512VL]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("vpabsq %zmm0,%zmm1"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AVX512VL], 1, [Define if host toolchain supports AVX512VL]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AES +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_AES], [ + AC_MSG_CHECKING([whether host toolchain supports AES]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("aesenc %xmm0, %xmm1"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_AES], 1, [Define if host toolchain supports AES]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_PCLMULQDQ +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_PCLMULQDQ], [ + AC_MSG_CHECKING([whether host toolchain supports PCLMULQDQ]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("pclmulqdq %0, %%xmm0, %%xmm1" :: "i"(0)); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_PCLMULQDQ], 1, [Define if host toolchain supports PCLMULQDQ]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +dnl # +dnl # ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_MOVBE +dnl # +AC_DEFUN([ZFS_AC_CONFIG_TOOLCHAIN_CAN_BUILD_MOVBE], [ + AC_MSG_CHECKING([whether host toolchain supports MOVBE]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([ + [ + void main() + { + __asm__ __volatile__("movbe 0(%eax), %eax"); + } + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_MOVBE], 1, [Define if host toolchain supports MOVBE]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/config/user-clock_gettime.m4 b/config/user-clock_gettime.m4 new file mode 100644 index 000000000000..c96024da797b --- /dev/null +++ b/config/user-clock_gettime.m4 @@ -0,0 +1,12 @@ +dnl # +dnl # Check if librt is required for clock_gettime. +dnl # clock_gettime is generally available in libc on modern systems. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_CLOCK_GETTIME], [ + AC_CHECK_FUNC([clock_gettime], [], [ + AC_CHECK_LIB([rt], [clock_gettime], [ + AC_SUBST([LIBCLOCK_GETTIME], [-lrt])], [ + AC_MSG_FAILURE([*** clock_gettime is missing in libc and librt]) + ]) + ]) +]) diff --git a/config/user-dracut.m4 b/config/user-dracut.m4 new file mode 100644 index 000000000000..95f800bda47a --- /dev/null +++ b/config/user-dracut.m4 @@ -0,0 +1,22 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_DRACUT], [ + AC_MSG_CHECKING(for dracut directory) + AC_ARG_WITH([dracutdir], + AC_HELP_STRING([--with-dracutdir=DIR], + [install dracut helpers @<:@default=check@:>@]), + [dracutdir=$withval], + [dracutdir=check]) + + AS_IF([test "x$dracutdir" = xcheck], [ + path1=/usr/share/dracut + path2=/usr/lib/dracut + default=$path2 + + AS_IF([test -d "$path1"], [dracutdir="$path1"], [ + AS_IF([test -d "$path2"], [dracutdir="$path2"], + [dracutdir="$default"]) + ]) + ]) + + AC_SUBST(dracutdir) + AC_MSG_RESULT([$dracutdir]) +]) diff --git a/config/user-gettext.m4 b/config/user-gettext.m4 new file mode 100644 index 000000000000..824318eab960 --- /dev/null +++ b/config/user-gettext.m4 @@ -0,0 +1,6 @@ +dnl # +dnl # Check if libintl and possibly libiconv are needed for gettext() functionality +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_GETTEXT], [ + AM_GNU_GETTEXT([external]) +]) diff --git a/config/user-libaio.m4 b/config/user-libaio.m4 new file mode 100644 index 000000000000..95c144d76b4f --- /dev/null +++ b/config/user-libaio.m4 @@ -0,0 +1,6 @@ +dnl # +dnl # Check for libaio - only used for libaiot test cases. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBAIO], [ + ZFS_AC_FIND_SYSTEM_LIBRARY(LIBAIO, [], [libaio.h], [], [aio], [], [user_libaio=yes], [user_libaio=no]) +]) diff --git a/config/user-libblkid.m4 b/config/user-libblkid.m4 new file mode 100644 index 000000000000..f2016dcb15cd --- /dev/null +++ b/config/user-libblkid.m4 @@ -0,0 +1,9 @@ +dnl # +dnl # Check for libblkid. Basic support for detecting ZFS pools +dnl # has existing in blkid since 2008. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBBLKID], [ + ZFS_AC_FIND_SYSTEM_LIBRARY(LIBBLKID, [blkid], [blkid/blkid.h], [], [blkid], [], [], [ + AC_MSG_FAILURE([ + *** blkid.h missing, libblkid-devel package required])]) +]) diff --git a/config/user-libcrypto.m4 b/config/user-libcrypto.m4 new file mode 100644 index 000000000000..7293e1b0b42c --- /dev/null +++ b/config/user-libcrypto.m4 @@ -0,0 +1,8 @@ +dnl # +dnl # Check for libcrypto. Used for userspace password derivation via PBKDF2. +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBCRYPTO], [ + ZFS_AC_FIND_SYSTEM_LIBRARY(LIBCRYPTO, [libcrypto], [openssl/evp.h], [], [crypto], [PKCS5_PBKDF2_HMAC_SHA1], [], [ + AC_MSG_FAILURE([ + *** evp.h missing, libssl-devel package required])]) +]) diff --git a/config/user-libexec.m4 b/config/user-libexec.m4 new file mode 100644 index 000000000000..31bcea3fcfd3 --- /dev/null +++ b/config/user-libexec.m4 @@ -0,0 +1,9 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_ZFSEXEC], [ + AC_ARG_WITH(zfsexecdir, + AC_HELP_STRING([--with-zfsexecdir=DIR], + [install scripts [[@<:@libexecdir@:>@/zfs]]]), + [zfsexecdir=$withval], + [zfsexecdir="${libexecdir}/zfs"]) + + AC_SUBST([zfsexecdir]) +]) diff --git a/config/user-libtirpc.m4 b/config/user-libtirpc.m4 new file mode 100644 index 000000000000..aa7ab4a1fd32 --- /dev/null +++ b/config/user-libtirpc.m4 @@ -0,0 +1,30 @@ +dnl # +dnl # Check for libtirpc - may be needed for xdr functionality +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBTIRPC], [ + AC_ARG_WITH([tirpc], + [AS_HELP_STRING([--with-tirpc], + [use tirpc for xdr encoding @<:@default=check@:>@])], + [], + [with_tirpc=check]) + + have_xdr= + + AS_IF([test "x$with_tirpc" != "xyes"], [ + AC_SEARCH_LIBS([xdrmem_create], [], [have_xdr=1], [ + AS_IF([test "x$with_tirpc" = "xno"], [ + AC_MSG_FAILURE([xdrmem_create() requires sunrpc support in libc if not using libtirpc]) + ]) + ]) + ]) + + AS_IF([test "x$have_xdr" = "x"], [ + ZFS_AC_FIND_SYSTEM_LIBRARY(LIBTIRPC, [libtirpc], [rpc/xdr.h], [tirpc], [tirpc], [xdrmem_create], [], [ + AS_IF([test "x$with_tirpc" = "xyes"], [ + AC_MSG_FAILURE([--with-tirpc was given, but libtirpc is not available, try installing libtirpc-devel]) + ],[dnl ELSE + AC_MSG_FAILURE([neither libc sunrpc support nor libtirpc is available, try installing libtirpc-devel]) + ]) + ]) + ]) +]) diff --git a/config/user-libudev.m4 b/config/user-libudev.m4 new file mode 100644 index 000000000000..8c3c1d7e0087 --- /dev/null +++ b/config/user-libudev.m4 @@ -0,0 +1,17 @@ +dnl # +dnl # Check for libudev - needed for vdev auto-online and auto-replace +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBUDEV], [ + ZFS_AC_FIND_SYSTEM_LIBRARY(LIBUDEV, [libudev], [libudev.h], [], [udev], [], [user_libudev=yes], [user_libudev=no]) + + AS_IF([test "x$user_libudev" = xyes], [ + AX_SAVE_FLAGS + + CFLAGS="$CFLAGS $LIBUDEV_CFLAGS" + LIBS="$LIBUDEV_LIBS $LIBS" + + AC_CHECK_FUNCS([udev_device_get_is_initialized]) + + AX_RESTORE_FLAGS + ]) +]) diff --git a/config/user-libuuid.m4 b/config/user-libuuid.m4 new file mode 100644 index 000000000000..0cfa83c9926a --- /dev/null +++ b/config/user-libuuid.m4 @@ -0,0 +1,8 @@ +dnl # +dnl # Check for libuuid +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_LIBUUID], [ + ZFS_AC_FIND_SYSTEM_LIBRARY(LIBUUID, [uuid], [uuid/uuid.h], [], [uuid], [uuid_generate uuid_is_null], [], [ + AC_MSG_FAILURE([*** libuuid-devel package required]) + ]) +]) diff --git a/config/user-makedev.m4 b/config/user-makedev.m4 new file mode 100644 index 000000000000..4383681a8f4c --- /dev/null +++ b/config/user-makedev.m4 @@ -0,0 +1,39 @@ +dnl # +dnl # glibc 2.25 +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_MAKEDEV_IN_SYSMACROS], [ + AC_MSG_CHECKING([makedev() is declared in sys/sysmacros.h]) + AC_TRY_COMPILE( + [ + #include <sys/sysmacros.h> + ],[ + int k; + k = makedev(0,0); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MAKEDEV_IN_SYSMACROS, 1, + [makedev() is declared in sys/sysmacros.h]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # glibc X < Y < 2.25 +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_MAKEDEV_IN_MKDEV], [ + AC_MSG_CHECKING([makedev() is declared in sys/mkdev.h]) + AC_TRY_COMPILE( + [ + #include <sys/mkdev.h> + ],[ + int k; + k = makedev(0,0); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MAKEDEV_IN_MKDEV, 1, + [makedev() is declared in sys/mkdev.h]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/user-pam.m4 b/config/user-pam.m4 new file mode 100644 index 000000000000..9db35808c340 --- /dev/null +++ b/config/user-pam.m4 @@ -0,0 +1,38 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_PAM], [ + AC_ARG_ENABLE([pam], + AS_HELP_STRING([--enable-pam], + [install pam_zfs_key module [[default: check]]]), + [enable_pam=$enableval], + [enable_pam=check]) + + AC_ARG_WITH(pammoduledir, + AS_HELP_STRING([--with-pammoduledir=DIR], + [install pam module in dir [[$libdir/security]]]), + [pammoduledir="$withval"],[pammoduledir=$libdir/security]) + + AC_ARG_WITH(pamconfigsdir, + AS_HELP_STRING([--with-pamconfigsdir=DIR], + [install pam-config files in dir [DATADIR/pam-configs]]), + [pamconfigsdir="$withval"], + [pamconfigsdir='${datadir}/pam-configs']) + + AS_IF([test "x$enable_pam" != "xno"], [ + AC_CHECK_HEADERS([security/pam_modules.h], [ + enable_pam=yes + ], [ + AS_IF([test "x$enable_pam" = "xyes"], [ + AC_MSG_FAILURE([ + *** security/pam_modules.h missing, libpam0g-dev package required + ]) + ],[ + enable_pam=no + ]) + ]) + ]) + AS_IF([test "x$enable_pam" = "xyes"], [ + DEFINE_PAM='--with pam' + ]) + AC_SUBST(DEFINE_PAM) + AC_SUBST(pammoduledir) + AC_SUBST(pamconfigsdir) +]) diff --git a/config/user-runstatedir.m4 b/config/user-runstatedir.m4 new file mode 100644 index 000000000000..ded1362c7b22 --- /dev/null +++ b/config/user-runstatedir.m4 @@ -0,0 +1,6 @@ +dnl For backwards compatibility; runstatedir added in autoconf 2.70. +AC_DEFUN([ZFS_AC_CONFIG_USER_RUNSTATEDIR], [ + if test "x$runstatedir" = x; then + AC_SUBST([runstatedir], ['${localstatedir}/run']) + fi +]) diff --git a/config/user-systemd.m4 b/config/user-systemd.m4 new file mode 100644 index 000000000000..3e6a4a281f3c --- /dev/null +++ b/config/user-systemd.m4 @@ -0,0 +1,53 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_SYSTEMD], [ + AC_ARG_ENABLE(systemd, + AC_HELP_STRING([--enable-systemd], + [install systemd unit/preset files [[default: yes]]]), + [enable_systemd=$enableval], + [enable_systemd=check]) + + AC_ARG_WITH(systemdunitdir, + AC_HELP_STRING([--with-systemdunitdir=DIR], + [install systemd unit files in dir [[/usr/lib/systemd/system]]]), + systemdunitdir=$withval,systemdunitdir=/usr/lib/systemd/system) + + AC_ARG_WITH(systemdpresetdir, + AC_HELP_STRING([--with-systemdpresetdir=DIR], + [install systemd preset files in dir [[/usr/lib/systemd/system-preset]]]), + systemdpresetdir=$withval,systemdpresetdir=/usr/lib/systemd/system-preset) + + AC_ARG_WITH(systemdmodulesloaddir, + AC_HELP_STRING([--with-systemdmodulesloaddir=DIR], + [install systemd module load files into dir [[/usr/lib/modules-load.d]]]), + systemdmodulesloaddir=$withval,systemdmodulesloaddir=/usr/lib/modules-load.d) + + AC_ARG_WITH(systemdgeneratordir, + AC_HELP_STRING([--with-systemdgeneratordir=DIR], + [install systemd generators in dir [[/usr/lib/systemd/system-generators]]]), + systemdgeneratordir=$withval,systemdgeneratordir=/usr/lib/systemd/system-generators) + + AS_IF([test "x$enable_systemd" = xcheck], [ + AS_IF([systemctl --version >/dev/null 2>&1], + [enable_systemd=yes], + [enable_systemd=no]) + ]) + + AC_MSG_CHECKING(for systemd support) + AC_MSG_RESULT([$enable_systemd]) + + AS_IF([test "x$enable_systemd" = xyes], [ + ZFS_INIT_SYSTEMD=systemd + ZFS_MODULE_LOAD=modules-load.d + DEFINE_SYSTEMD='--with systemd --define "_unitdir $(systemdunitdir)" --define "_presetdir $(systemdpresetdir)" --define "_generatordir $(systemdgeneratordir)"' + modulesloaddir=$systemdmodulesloaddir + ],[ + DEFINE_SYSTEMD='--without systemd' + ]) + + AC_SUBST(ZFS_INIT_SYSTEMD) + AC_SUBST(ZFS_MODULE_LOAD) + AC_SUBST(DEFINE_SYSTEMD) + AC_SUBST(systemdunitdir) + AC_SUBST(systemdpresetdir) + AC_SUBST(systemdgeneratordir) + AC_SUBST(modulesloaddir) +]) diff --git a/config/user-sysvinit.m4 b/config/user-sysvinit.m4 new file mode 100644 index 000000000000..65dcc3819231 --- /dev/null +++ b/config/user-sysvinit.m4 @@ -0,0 +1,11 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_SYSVINIT], [ + AC_ARG_ENABLE(sysvinit, + AC_HELP_STRING([--enable-sysvinit], + [install SysV init scripts [default: yes]]), + [],enable_sysvinit=yes) + + AS_IF([test "x$enable_sysvinit" = xyes], + [ZFS_INIT_SYSV=init.d]) + + AC_SUBST(ZFS_INIT_SYSV) +]) diff --git a/config/user-udev.m4 b/config/user-udev.m4 new file mode 100644 index 000000000000..65dc79fb4847 --- /dev/null +++ b/config/user-udev.m4 @@ -0,0 +1,29 @@ +AC_DEFUN([ZFS_AC_CONFIG_USER_UDEV], [ + AC_MSG_CHECKING(for udev directories) + AC_ARG_WITH(udevdir, + AC_HELP_STRING([--with-udevdir=DIR], + [install udev helpers @<:@default=check@:>@]), + [udevdir=$withval], + [udevdir=check]) + + AS_IF([test "x$udevdir" = xcheck], [ + path1=/lib/udev + path2=/usr/lib/udev + default=$path2 + + AS_IF([test -d "$path1"], [udevdir="$path1"], [ + AS_IF([test -d "$path2"], [udevdir="$path2"], + [udevdir="$default"]) + ]) + ]) + + AC_ARG_WITH(udevruledir, + AC_HELP_STRING([--with-udevruledir=DIR], + [install udev rules [[UDEVDIR/rules.d]]]), + [udevruledir=$withval], + [udevruledir="${udevdir}/rules.d"]) + + AC_SUBST(udevdir) + AC_SUBST(udevruledir) + AC_MSG_RESULT([$udevdir;$udevruledir]) +]) diff --git a/config/user-zlib.m4 b/config/user-zlib.m4 new file mode 100644 index 000000000000..1f3792829bb6 --- /dev/null +++ b/config/user-zlib.m4 @@ -0,0 +1,8 @@ +dnl # +dnl # Check for zlib +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER_ZLIB], [ + ZFS_AC_FIND_SYSTEM_LIBRARY(ZLIB, [zlib], [zlib.h], [], [z], [compress2 uncompress crc32], [], [ + AC_MSG_FAILURE([*** zlib-devel package required]) + ]) +]) diff --git a/config/user.m4 b/config/user.m4 new file mode 100644 index 000000000000..c220675514e6 --- /dev/null +++ b/config/user.m4 @@ -0,0 +1,45 @@ +dnl # +dnl # Default ZFS user configuration +dnl # +AC_DEFUN([ZFS_AC_CONFIG_USER], [ + ZFS_AC_CONFIG_USER_GETTEXT + ZFS_AC_CONFIG_USER_MOUNT_HELPER + ZFS_AC_CONFIG_USER_SYSVINIT + ZFS_AC_CONFIG_USER_DRACUT + AM_COND_IF([BUILD_FREEBSD], [ + PKG_INSTALLDIR(['${prefix}/libdata/pkgconfig'])], [ + PKG_INSTALLDIR + ]) + ZFS_AC_CONFIG_USER_ZLIB + AM_COND_IF([BUILD_LINUX], [ + ZFS_AC_CONFIG_USER_UDEV + ZFS_AC_CONFIG_USER_SYSTEMD + ZFS_AC_CONFIG_USER_LIBUUID + ZFS_AC_CONFIG_USER_LIBBLKID + ]) + ZFS_AC_CONFIG_USER_LIBTIRPC + ZFS_AC_CONFIG_USER_LIBUDEV + ZFS_AC_CONFIG_USER_LIBCRYPTO + ZFS_AC_CONFIG_USER_LIBAIO + ZFS_AC_CONFIG_USER_CLOCK_GETTIME + ZFS_AC_CONFIG_USER_PAM + ZFS_AC_CONFIG_USER_RUNSTATEDIR + ZFS_AC_CONFIG_USER_MAKEDEV_IN_SYSMACROS + ZFS_AC_CONFIG_USER_MAKEDEV_IN_MKDEV + ZFS_AC_CONFIG_USER_ZFSEXEC + ZFS_AC_TEST_FRAMEWORK + + AC_CHECK_FUNCS([issetugid mlockall strlcat strlcpy]) +]) + +dnl # +dnl # Setup the environment for the ZFS Test Suite. Currently only +dnl # Linux style systems are supported but this infrastructure can +dnl # be extended to support other platforms if needed. +dnl # +AC_DEFUN([ZFS_AC_TEST_FRAMEWORK], [ + ZONENAME="echo global" + AC_SUBST(ZONENAME) + + AC_SUBST(RM) +]) diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 new file mode 100644 index 000000000000..54b61de090e7 --- /dev/null +++ b/config/zfs-build.m4 @@ -0,0 +1,554 @@ +AC_DEFUN([ZFS_AC_LICENSE], [ + AC_MSG_CHECKING([zfs author]) + AC_MSG_RESULT([$ZFS_META_AUTHOR]) + + AC_MSG_CHECKING([zfs license]) + AC_MSG_RESULT([$ZFS_META_LICENSE]) +]) + +AC_DEFUN([ZFS_AC_DEBUG_ENABLE], [ + DEBUG_CFLAGS="-Werror" + DEBUG_CPPFLAGS="-DDEBUG -UNDEBUG" + DEBUG_LDFLAGS="" + DEBUG_ZFS="_with_debug" + AC_DEFINE(ZFS_DEBUG, 1, [zfs debugging enabled]) + + KERNEL_DEBUG_CFLAGS="-Werror" + KERNEL_DEBUG_CPPFLAGS="-DDEBUG -UNDEBUG" +]) + +AC_DEFUN([ZFS_AC_DEBUG_DISABLE], [ + DEBUG_CFLAGS="" + DEBUG_CPPFLAGS="-UDEBUG -DNDEBUG" + DEBUG_LDFLAGS="" + DEBUG_ZFS="_without_debug" + + KERNEL_DEBUG_CFLAGS="" + KERNEL_DEBUG_CPPFLAGS="-UDEBUG -DNDEBUG" +]) + +dnl # +dnl # When debugging is enabled: +dnl # - Enable all ASSERTs (-DDEBUG) +dnl # - Promote all compiler warnings to errors (-Werror) +dnl # +AC_DEFUN([ZFS_AC_DEBUG], [ + AC_MSG_CHECKING([whether assertion support will be enabled]) + AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [Enable compiler and code assertions @<:@default=no@:>@])], + [], + [enable_debug=no]) + + AS_CASE(["x$enable_debug"], + ["xyes"], + [ZFS_AC_DEBUG_ENABLE], + ["xno"], + [ZFS_AC_DEBUG_DISABLE], + [AC_MSG_ERROR([Unknown option $enable_debug])]) + + AC_SUBST(DEBUG_CFLAGS) + AC_SUBST(DEBUG_CPPFLAGS) + AC_SUBST(DEBUG_LDFLAGS) + AC_SUBST(DEBUG_ZFS) + + AC_SUBST(KERNEL_DEBUG_CFLAGS) + AC_SUBST(KERNEL_DEBUG_CPPFLAGS) + + AC_MSG_RESULT([$enable_debug]) +]) + +AC_DEFUN([ZFS_AC_DEBUGINFO_ENABLE], [ + DEBUG_CFLAGS="$DEBUG_CFLAGS -g -fno-inline $NO_IPA_SRA" + + KERNEL_DEBUG_CFLAGS="$KERNEL_DEBUG_CFLAGS -fno-inline $NO_IPA_SRA" + KERNEL_MAKE="$KERNEL_MAKE CONFIG_DEBUG_INFO=y" + + DEBUGINFO_ZFS="_with_debuginfo" +]) + +AC_DEFUN([ZFS_AC_DEBUGINFO_DISABLE], [ + DEBUGINFO_ZFS="_without_debuginfo" +]) + +AC_DEFUN([ZFS_AC_DEBUGINFO], [ + AC_MSG_CHECKING([whether debuginfo support will be forced]) + AC_ARG_ENABLE([debuginfo], + [AS_HELP_STRING([--enable-debuginfo], + [Force generation of debuginfo @<:@default=no@:>@])], + [], + [enable_debuginfo=no]) + + AS_CASE(["x$enable_debuginfo"], + ["xyes"], + [ZFS_AC_DEBUGINFO_ENABLE], + ["xno"], + [ZFS_AC_DEBUGINFO_DISABLE], + [AC_MSG_ERROR([Unknown option $enable_debuginfo])]) + + AC_SUBST(DEBUG_CFLAGS) + AC_SUBST(DEBUGINFO_ZFS) + + AC_SUBST(KERNEL_DEBUG_CFLAGS) + AC_SUBST(KERNEL_MAKE) + + AC_MSG_RESULT([$enable_debuginfo]) +]) + +dnl # +dnl # Disabled by default, provides basic memory tracking. Track the total +dnl # number of bytes allocated with kmem_alloc() and freed with kmem_free(). +dnl # Then at module unload time if any bytes were leaked it will be reported +dnl # on the console. +dnl # +AC_DEFUN([ZFS_AC_DEBUG_KMEM], [ + AC_MSG_CHECKING([whether basic kmem accounting is enabled]) + AC_ARG_ENABLE([debug-kmem], + [AS_HELP_STRING([--enable-debug-kmem], + [Enable basic kmem accounting @<:@default=no@:>@])], + [], + [enable_debug_kmem=no]) + + AS_IF([test "x$enable_debug_kmem" = xyes], [ + KERNEL_DEBUG_CPPFLAGS="${KERNEL_DEBUG_CPPFLAGS} -DDEBUG_KMEM" + DEBUG_KMEM_ZFS="_with_debug_kmem" + ], [ + DEBUG_KMEM_ZFS="_without_debug_kmem" + ]) + + AC_SUBST(KERNEL_DEBUG_CPPFLAGS) + AC_SUBST(DEBUG_KMEM_ZFS) + + AC_MSG_RESULT([$enable_debug_kmem]) +]) + +dnl # +dnl # Disabled by default, provides detailed memory tracking. This feature +dnl # also requires --enable-debug-kmem to be set. When enabled not only will +dnl # total bytes be tracked but also the location of every kmem_alloc() and +dnl # kmem_free(). When the module is unloaded a list of all leaked addresses +dnl # and where they were allocated will be dumped to the console. Enabling +dnl # this feature has a significant impact on performance but it makes finding +dnl # memory leaks straight forward. +dnl # +AC_DEFUN([ZFS_AC_DEBUG_KMEM_TRACKING], [ + AC_MSG_CHECKING([whether detailed kmem tracking is enabled]) + AC_ARG_ENABLE([debug-kmem-tracking], + [AS_HELP_STRING([--enable-debug-kmem-tracking], + [Enable detailed kmem tracking @<:@default=no@:>@])], + [], + [enable_debug_kmem_tracking=no]) + + AS_IF([test "x$enable_debug_kmem_tracking" = xyes], [ + KERNEL_DEBUG_CPPFLAGS="${KERNEL_DEBUG_CPPFLAGS} -DDEBUG_KMEM_TRACKING" + DEBUG_KMEM_TRACKING_ZFS="_with_debug_kmem_tracking" + ], [ + DEBUG_KMEM_TRACKING_ZFS="_without_debug_kmem_tracking" + ]) + + AC_SUBST(KERNEL_DEBUG_CPPFLAGS) + AC_SUBST(DEBUG_KMEM_TRACKING_ZFS) + + AC_MSG_RESULT([$enable_debug_kmem_tracking]) +]) + +AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [ + ZFS_AC_CONFIG_ALWAYS_CC_NO_UNUSED_BUT_SET_VARIABLE + ZFS_AC_CONFIG_ALWAYS_CC_NO_BOOL_COMPARE + ZFS_AC_CONFIG_ALWAYS_CC_FRAME_LARGER_THAN + ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_TRUNCATION + ZFS_AC_CONFIG_ALWAYS_CC_NO_FORMAT_ZERO_LENGTH + ZFS_AC_CONFIG_ALWAYS_CC_NO_OMIT_FRAME_POINTER + ZFS_AC_CONFIG_ALWAYS_CC_NO_IPA_SRA + ZFS_AC_CONFIG_ALWAYS_CC_ASAN + ZFS_AC_CONFIG_ALWAYS_TOOLCHAIN_SIMD + ZFS_AC_CONFIG_ALWAYS_SYSTEM + ZFS_AC_CONFIG_ALWAYS_ARCH + ZFS_AC_CONFIG_ALWAYS_PYTHON + ZFS_AC_CONFIG_ALWAYS_PYZFS + ZFS_AC_CONFIG_ALWAYS_SED +]) + +AC_DEFUN([ZFS_AC_CONFIG], [ + + dnl # Remove the previous build test directory. + rm -Rf build + + ZFS_CONFIG=all + AC_ARG_WITH([config], + AS_HELP_STRING([--with-config=CONFIG], + [Config file 'kernel|user|all|srpm']), + [ZFS_CONFIG="$withval"]) + AC_ARG_ENABLE([linux-builtin], + [AC_HELP_STRING([--enable-linux-builtin], + [Configure for builtin in-tree kernel modules @<:@default=no@:>@])], + [], + [enable_linux_builtin=no]) + + AC_MSG_CHECKING([zfs config]) + AC_MSG_RESULT([$ZFS_CONFIG]); + AC_SUBST(ZFS_CONFIG) + + ZFS_AC_CONFIG_ALWAYS + + + AM_COND_IF([BUILD_LINUX], [ + 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=$(nproc) + fi + AC_SUBST(TEST_JOBS) + ]) + + case "$ZFS_CONFIG" in + kernel) ZFS_AC_CONFIG_KERNEL ;; + user) ZFS_AC_CONFIG_USER ;; + all) ZFS_AC_CONFIG_USER + ZFS_AC_CONFIG_KERNEL ;; + srpm) ;; + *) + AC_MSG_RESULT([Error!]) + AC_MSG_ERROR([Bad value "$ZFS_CONFIG" for --with-config, + user kernel|user|all|srpm]) ;; + esac + + AM_CONDITIONAL([CONFIG_USER], + [test "$ZFS_CONFIG" = user -o "$ZFS_CONFIG" = all]) + AM_CONDITIONAL([CONFIG_KERNEL], + [test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all] && + [test "x$enable_linux_builtin" != xyes ]) + AM_CONDITIONAL([CONFIG_QAT], + [test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all] && + [test "x$qatsrc" != x ]) + AM_CONDITIONAL([WANT_DEVNAME2DEVID], [test "x$user_libudev" = xyes ]) + AM_CONDITIONAL([WANT_MMAP_LIBAIO], [test "x$user_libaio" = xyes ]) + AM_CONDITIONAL([PAM_ZFS_ENABLED], [test "x$enable_pam" = xyes]) +]) + +dnl # +dnl # Check for rpm+rpmbuild to build RPM packages. If these tools +dnl # are missing it is non-fatal but you will not be able to build +dnl # RPM packages and will be warned if you try too. +dnl # +dnl # By default the generic spec file will be used because it requires +dnl # minimal dependencies. Distribution specific spec files can be +dnl # placed under the 'rpm/<distribution>' directory and enabled using +dnl # the --with-spec=<distribution> configure option. +dnl # +AC_DEFUN([ZFS_AC_RPM], [ + RPM=rpm + RPMBUILD=rpmbuild + + AC_MSG_CHECKING([whether $RPM is available]) + AS_IF([tmp=$($RPM --version 2>/dev/null)], [ + RPM_VERSION=$(echo $tmp | $AWK '/RPM/ { print $[3] }') + HAVE_RPM=yes + AC_MSG_RESULT([$HAVE_RPM ($RPM_VERSION)]) + ],[ + HAVE_RPM=no + AC_MSG_RESULT([$HAVE_RPM]) + ]) + + AC_MSG_CHECKING([whether $RPMBUILD is available]) + AS_IF([tmp=$($RPMBUILD --version 2>/dev/null)], [ + RPMBUILD_VERSION=$(echo $tmp | $AWK '/RPM/ { print $[3] }') + HAVE_RPMBUILD=yes + AC_MSG_RESULT([$HAVE_RPMBUILD ($RPMBUILD_VERSION)]) + ],[ + HAVE_RPMBUILD=no + AC_MSG_RESULT([$HAVE_RPMBUILD]) + ]) + + RPM_DEFINE_COMMON='--define "$(DEBUG_ZFS) 1"' + RPM_DEFINE_COMMON=${RPM_DEFINE_COMMON}' --define "$(DEBUGINFO_ZFS) 1"' + RPM_DEFINE_COMMON=${RPM_DEFINE_COMMON}' --define "$(DEBUG_KMEM_ZFS) 1"' + RPM_DEFINE_COMMON=${RPM_DEFINE_COMMON}' --define "$(DEBUG_KMEM_TRACKING_ZFS) 1"' + RPM_DEFINE_COMMON=${RPM_DEFINE_COMMON}' --define "$(ASAN_ZFS) 1"' + + RPM_DEFINE_UTIL=' --define "_initconfdir $(initconfdir)"' + + dnl # Make the next three RPM_DEFINE_UTIL additions conditional, since + dnl # their values may not be set when running: + dnl # + dnl # ./configure --with-config=srpm + dnl # + AS_IF([test -n "$dracutdir" ], [ + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' --define "_dracutdir $(dracutdir)"' + ]) + AS_IF([test -n "$udevdir" ], [ + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' --define "_udevdir $(udevdir)"' + ]) + AS_IF([test -n "$udevruledir" ], [ + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' --define "_udevruledir $(udevruledir)"' + ]) + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_INITRAMFS)' + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_SYSTEMD)' + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_PYZFS)' + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_PAM)' + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_PYTHON_VERSION)' + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' $(DEFINE_PYTHON_PKG_VERSION)' + + dnl # Override default lib directory on Debian/Ubuntu systems. The + dnl # provided /usr/lib/rpm/platform/<arch>/macros files do not + dnl # specify the correct path for multiarch systems as described + dnl # by the packaging guidelines. + dnl # + dnl # https://wiki.ubuntu.com/MultiarchSpec + dnl # https://wiki.debian.org/Multiarch/Implementation + dnl # + AS_IF([test "$DEFAULT_PACKAGE" = "deb"], [ + MULTIARCH_LIBDIR="lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)" + RPM_DEFINE_UTIL=${RPM_DEFINE_UTIL}' --define "_lib $(MULTIARCH_LIBDIR)"' + AC_SUBST(MULTIARCH_LIBDIR) + ]) + + dnl # Make RPM_DEFINE_KMOD additions conditional on CONFIG_KERNEL, + dnl # since the values will not be set otherwise. The spec files + dnl # provide defaults for them. + dnl # + RPM_DEFINE_KMOD='--define "_wrong_version_format_terminate_build 0"' + AM_COND_IF([CONFIG_KERNEL], [ + RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernels $(LINUX_VERSION)"' + RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "ksrc $(LINUX)"' + RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kobj $(LINUX_OBJ)"' + ]) + + RPM_DEFINE_DKMS='' + + SRPM_DEFINE_COMMON='--define "build_src_rpm 1"' + SRPM_DEFINE_UTIL= + SRPM_DEFINE_KMOD= + SRPM_DEFINE_DKMS= + + RPM_SPEC_DIR="rpm/generic" + AC_ARG_WITH([spec], + AS_HELP_STRING([--with-spec=SPEC], + [Spec files 'generic|redhat']), + [RPM_SPEC_DIR="rpm/$withval"]) + + AC_MSG_CHECKING([whether spec files are available]) + AC_MSG_RESULT([yes ($RPM_SPEC_DIR/*.spec.in)]) + + AC_SUBST(HAVE_RPM) + AC_SUBST(RPM) + AC_SUBST(RPM_VERSION) + + AC_SUBST(HAVE_RPMBUILD) + AC_SUBST(RPMBUILD) + AC_SUBST(RPMBUILD_VERSION) + + AC_SUBST(RPM_SPEC_DIR) + AC_SUBST(RPM_DEFINE_UTIL) + AC_SUBST(RPM_DEFINE_KMOD) + AC_SUBST(RPM_DEFINE_DKMS) + AC_SUBST(RPM_DEFINE_COMMON) + AC_SUBST(SRPM_DEFINE_UTIL) + AC_SUBST(SRPM_DEFINE_KMOD) + AC_SUBST(SRPM_DEFINE_DKMS) + AC_SUBST(SRPM_DEFINE_COMMON) +]) + +dnl # +dnl # Check for dpkg+dpkg-buildpackage to build DEB packages. If these +dnl # tools are missing it is non-fatal but you will not be able to build +dnl # DEB packages and will be warned if you try too. +dnl # +AC_DEFUN([ZFS_AC_DPKG], [ + DPKG=dpkg + DPKGBUILD=dpkg-buildpackage + + AC_MSG_CHECKING([whether $DPKG is available]) + AS_IF([tmp=$($DPKG --version 2>/dev/null)], [ + DPKG_VERSION=$(echo $tmp | $AWK '/Debian/ { print $[7] }') + HAVE_DPKG=yes + AC_MSG_RESULT([$HAVE_DPKG ($DPKG_VERSION)]) + ],[ + HAVE_DPKG=no + AC_MSG_RESULT([$HAVE_DPKG]) + ]) + + AC_MSG_CHECKING([whether $DPKGBUILD is available]) + AS_IF([tmp=$($DPKGBUILD --version 2>/dev/null)], [ + DPKGBUILD_VERSION=$(echo $tmp | \ + $AWK '/Debian/ { print $[4] }' | cut -f-4 -d'.') + HAVE_DPKGBUILD=yes + AC_MSG_RESULT([$HAVE_DPKGBUILD ($DPKGBUILD_VERSION)]) + ],[ + HAVE_DPKGBUILD=no + AC_MSG_RESULT([$HAVE_DPKGBUILD]) + ]) + + AC_SUBST(HAVE_DPKG) + AC_SUBST(DPKG) + AC_SUBST(DPKG_VERSION) + + AC_SUBST(HAVE_DPKGBUILD) + AC_SUBST(DPKGBUILD) + AC_SUBST(DPKGBUILD_VERSION) +]) + +dnl # +dnl # Until native packaging for various different packing systems +dnl # can be added the least we can do is attempt to use alien to +dnl # convert the RPM packages to the needed package type. This is +dnl # a hack but so far it has worked reasonable well. +dnl # +AC_DEFUN([ZFS_AC_ALIEN], [ + ALIEN=alien + + AC_MSG_CHECKING([whether $ALIEN is available]) + AS_IF([tmp=$($ALIEN --version 2>/dev/null)], [ + ALIEN_VERSION=$(echo $tmp | $AWK '{ print $[3] }') + HAVE_ALIEN=yes + AC_MSG_RESULT([$HAVE_ALIEN ($ALIEN_VERSION)]) + ],[ + HAVE_ALIEN=no + AC_MSG_RESULT([$HAVE_ALIEN]) + ]) + + AC_SUBST(HAVE_ALIEN) + AC_SUBST(ALIEN) + AC_SUBST(ALIEN_VERSION) +]) + +dnl # +dnl # Using the VENDOR tag from config.guess set the default +dnl # package type for 'make pkg': (rpm | deb | tgz) +dnl # +AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ + AC_MSG_CHECKING([os distribution]) + if test -f /etc/toss-release ; then + VENDOR=toss ; + elif test -f /etc/fedora-release ; then + VENDOR=fedora ; + elif test -f /etc/redhat-release ; then + VENDOR=redhat ; + elif test -f /etc/gentoo-release ; then + VENDOR=gentoo ; + elif test -f /etc/arch-release ; then + VENDOR=arch ; + elif test -f /etc/SuSE-release ; then + VENDOR=sles ; + elif test -f /etc/slackware-version ; then + VENDOR=slackware ; + elif test -f /etc/lunar.release ; then + VENDOR=lunar ; + elif test -f /etc/lsb-release ; then + VENDOR=ubuntu ; + elif test -f /etc/debian_version ; then + VENDOR=debian ; + elif test -f /etc/alpine-release ; then + VENDOR=alpine ; + elif test -f /bin/freebsd-version ; then + VENDOR=freebsd ; + else + VENDOR= ; + fi + AC_MSG_RESULT([$VENDOR]) + AC_SUBST(VENDOR) + + AC_MSG_CHECKING([default package type]) + case "$VENDOR" in + toss) DEFAULT_PACKAGE=rpm ;; + redhat) DEFAULT_PACKAGE=rpm ;; + fedora) DEFAULT_PACKAGE=rpm ;; + gentoo) DEFAULT_PACKAGE=tgz ;; + alpine) DEFAULT_PACKAGE=tgz ;; + arch) DEFAULT_PACKAGE=tgz ;; + sles) DEFAULT_PACKAGE=rpm ;; + slackware) DEFAULT_PACKAGE=tgz ;; + lunar) DEFAULT_PACKAGE=tgz ;; + ubuntu) DEFAULT_PACKAGE=deb ;; + debian) DEFAULT_PACKAGE=deb ;; + freebsd) DEFAULT_PACKAGE=pkg ;; + *) DEFAULT_PACKAGE=rpm ;; + esac + AC_MSG_RESULT([$DEFAULT_PACKAGE]) + AC_SUBST(DEFAULT_PACKAGE) + + AC_MSG_CHECKING([default init directory]) + case "$VENDOR" in + freebsd) initdir=$sysconfdir/rc.d ;; + *) initdir=$sysconfdir/init.d;; + esac + AC_MSG_RESULT([$initdir]) + AC_SUBST(initdir) + + AC_MSG_CHECKING([default init script type and shell]) + case "$VENDOR" in + toss) DEFAULT_INIT_SCRIPT=redhat ;; + redhat) DEFAULT_INIT_SCRIPT=redhat ;; + fedora) DEFAULT_INIT_SCRIPT=fedora ;; + gentoo) DEFAULT_INIT_SCRIPT=openrc ;; + alpine) DEFAULT_INIT_SCRIPT=openrc ;; + arch) DEFAULT_INIT_SCRIPT=lsb ;; + sles) DEFAULT_INIT_SCRIPT=lsb ;; + slackware) DEFAULT_INIT_SCRIPT=lsb ;; + lunar) DEFAULT_INIT_SCRIPT=lunar ;; + ubuntu) DEFAULT_INIT_SCRIPT=lsb ;; + debian) DEFAULT_INIT_SCRIPT=lsb ;; + freebsd) DEFAULT_INIT_SCRIPT=freebsd;; + *) DEFAULT_INIT_SCRIPT=lsb ;; + esac + + # On gentoo, it's possible that OpenRC isn't installed. Check if + # /sbin/openrc-run exists, and if not, fall back to generic defaults. + + DEFAULT_INIT_SHELL="/bin/sh" + AS_IF([test "$DEFAULT_INIT_SCRIPT" = "openrc"], [ + AS_IF([test -x "/sbin/openrc-run"], + [DEFAULT_INIT_SHELL="/sbin/openrc-run"], + [DEFAULT_INIT_SCRIPT=lsb]) + ]) + + AC_MSG_RESULT([$DEFAULT_INIT_SCRIPT:$DEFAULT_INIT_SHELL]) + AC_SUBST(DEFAULT_INIT_SCRIPT) + AC_SUBST(DEFAULT_INIT_SHELL) + + AC_MSG_CHECKING([default nfs server init script]) + AS_IF([test "$VENDOR" = "debian"], + [DEFAULT_INIT_NFS_SERVER="nfs-kernel-server"], + [DEFAULT_INIT_NFS_SERVER="nfs"] + ) + AC_MSG_RESULT([$DEFAULT_INIT_NFS_SERVER]) + AC_SUBST(DEFAULT_INIT_NFS_SERVER) + + AC_MSG_CHECKING([default init config directory]) + case "$VENDOR" in + alpine) initconfdir=/etc/conf.d ;; + gentoo) initconfdir=/etc/conf.d ;; + toss) initconfdir=/etc/sysconfig ;; + redhat) initconfdir=/etc/sysconfig ;; + fedora) initconfdir=/etc/sysconfig ;; + sles) initconfdir=/etc/sysconfig ;; + ubuntu) initconfdir=/etc/default ;; + debian) initconfdir=/etc/default ;; + freebsd) initconfdir=$sysconfdir/rc.conf.d;; + *) initconfdir=/etc/default ;; + esac + AC_MSG_RESULT([$initconfdir]) + AC_SUBST(initconfdir) + + AC_MSG_CHECKING([whether initramfs-tools is available]) + if test -d /usr/share/initramfs-tools ; then + DEFINE_INITRAMFS='--define "_initramfs 1"' + AC_MSG_RESULT([yes]) + else + DEFINE_INITRAMFS='' + AC_MSG_RESULT([no]) + fi + AC_SUBST(DEFINE_INITRAMFS) +]) + +dnl # +dnl # Default ZFS package configuration +dnl # +AC_DEFUN([ZFS_AC_PACKAGE], [ + ZFS_AC_DEFAULT_PACKAGE + AS_IF([test x$VENDOR != xfreebsd], [ + ZFS_AC_RPM + ZFS_AC_DPKG + ZFS_AC_ALIEN + ]) +]) diff --git a/config/zfs-meta.m4 b/config/zfs-meta.m4 new file mode 100644 index 000000000000..b3c1befaac5d --- /dev/null +++ b/config/zfs-meta.m4 @@ -0,0 +1,207 @@ +dnl # +dnl # DESCRIPTION: +dnl # Read meta data from the META file. When building from a git repository +dnl # the ZFS_META_RELEASE field will be overwritten if there is an annotated +dnl # tag matching the form ZFS_META_NAME-ZFS_META_VERSION-*. This allows +dnl # for working builds to be uniquely identified using the git commit hash. +dnl # +dnl # The META file format is as follows: +dnl # ^[ ]*KEY:[ \t]+VALUE$ +dnl # +dnl # In other words: +dnl # - KEY is separated from VALUE by a colon and one or more spaces/tabs. +dnl # - KEY and VALUE are case sensitive. +dnl # - Leading spaces are ignored. +dnl # - First match wins for duplicate keys. +dnl # +dnl # A line can be commented out by preceding it with a '#' (or technically +dnl # any non-space character since that will prevent the regex from +dnl # matching). +dnl # +dnl # WARNING: +dnl # Placing a colon followed by a space or tab (ie, ":[ \t]+") within the +dnl # VALUE will prematurely terminate the string since that sequence is +dnl # used as the awk field separator. +dnl # +dnl # KEYS: +dnl # The following META keys are recognized: +dnl # Name, Version, Release, Date, Author, LT_Current, LT_Revision, LT_Age +dnl # +dnl # Written by Chris Dunlap <cdunlap@llnl.gov>. +dnl # Modified by Brian Behlendorf <behlendorf1@llnl.gov>. +dnl # +AC_DEFUN([ZFS_AC_META], [ + + AH_BOTTOM([ +#undef PACKAGE +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef STDC_HEADERS +#undef VERSION]) + + AC_PROG_AWK + AC_MSG_CHECKING([metadata]) + + META="$srcdir/META" + _zfs_ac_meta_type="none" + if test -f "$META"; then + _zfs_ac_meta_type="META file" + + ZFS_META_NAME=_ZFS_AC_META_GETVAL([(Name|Project|Package)]); + if test -n "$ZFS_META_NAME"; then + AC_DEFINE_UNQUOTED([ZFS_META_NAME], ["$ZFS_META_NAME"], + [Define the project name.] + ) + AC_SUBST([ZFS_META_NAME]) + fi + + ZFS_META_VERSION=_ZFS_AC_META_GETVAL([Version]); + if test -n "$ZFS_META_VERSION"; then + AC_DEFINE_UNQUOTED([ZFS_META_VERSION], + ["$ZFS_META_VERSION"], + [Define the project version.]) + AC_DEFINE_UNQUOTED([SPL_META_VERSION], + [ZFS_META_VERSION], + [Defined for legacy compatibility.]) + AC_SUBST([ZFS_META_VERSION]) + fi + + ZFS_META_RELEASE=_ZFS_AC_META_GETVAL([Release]); + if test ! -f ".nogitrelease" && git rev-parse --git-dir > /dev/null 2>&1; then + _match="${ZFS_META_NAME}-${ZFS_META_VERSION}" + _alias=$(git describe --match=${_match} 2>/dev/null) + _release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g') + if test -n "${_release}"; then + ZFS_META_RELEASE=${_release} + _zfs_ac_meta_type="git describe" + else + _match="${ZFS_META_NAME}-${ZFS_META_VERSION}-${ZFS_META_RELEASE}" + _alias=$(git describe --match=${_match} 2>/dev/null) + _release=$(echo ${_alias}|cut -f3- -d'-'|sed 's/-/_/g') + if test -n "${_release}"; then + ZFS_META_RELEASE=${_release} + _zfs_ac_meta_type="git describe" + fi + fi + fi + + if test -n "$ZFS_META_RELEASE"; then + AC_DEFINE_UNQUOTED([ZFS_META_RELEASE], + ["$ZFS_META_RELEASE"], + [Define the project release.]) + AC_DEFINE_UNQUOTED([SPL_META_RELEASE], + [ZFS_META_RELEASE], + [Defined for legacy compatibility.]) + AC_SUBST([ZFS_META_RELEASE]) + + RELEASE="$ZFS_META_RELEASE" + AC_SUBST([RELEASE]) + fi + + ZFS_META_LICENSE=_ZFS_AC_META_GETVAL([License]); + if test -n "$ZFS_META_LICENSE"; then + AC_DEFINE_UNQUOTED([ZFS_META_LICENSE], ["$ZFS_META_LICENSE"], + [Define the project license.] + ) + AC_SUBST([ZFS_META_LICENSE]) + fi + + if test -n "$ZFS_META_NAME" -a -n "$ZFS_META_VERSION"; then + ZFS_META_ALIAS="$ZFS_META_NAME-$ZFS_META_VERSION" + test -n "$ZFS_META_RELEASE" && + ZFS_META_ALIAS="$ZFS_META_ALIAS-$ZFS_META_RELEASE" + AC_DEFINE_UNQUOTED([ZFS_META_ALIAS], + ["$ZFS_META_ALIAS"], + [Define the project alias string.]) + AC_DEFINE_UNQUOTED([SPL_META_ALIAS], + [ZFS_META_ALIAS], + [Defined for legacy compatibility.]) + AC_SUBST([ZFS_META_ALIAS]) + fi + + ZFS_META_DATA=_ZFS_AC_META_GETVAL([Date]); + if test -n "$ZFS_META_DATA"; then + AC_DEFINE_UNQUOTED([ZFS_META_DATA], ["$ZFS_META_DATA"], + [Define the project release date.] + ) + AC_SUBST([ZFS_META_DATA]) + fi + + ZFS_META_AUTHOR=_ZFS_AC_META_GETVAL([Author]); + if test -n "$ZFS_META_AUTHOR"; then + AC_DEFINE_UNQUOTED([ZFS_META_AUTHOR], ["$ZFS_META_AUTHOR"], + [Define the project author.] + ) + AC_SUBST([ZFS_META_AUTHOR]) + fi + + ZFS_META_KVER_MIN=_ZFS_AC_META_GETVAL([Linux-Minimum]); + if test -n "$ZFS_META_KVER_MIN"; then + AC_DEFINE_UNQUOTED([ZFS_META_KVER_MIN], + ["$ZFS_META_KVER_MIN"], + [Define the minimum compatible kernel version.] + ) + AC_SUBST([ZFS_META_KVER_MIN]) + fi + + ZFS_META_KVER_MAX=_ZFS_AC_META_GETVAL([Linux-Maximum]); + if test -n "$ZFS_META_KVER_MAX"; then + AC_DEFINE_UNQUOTED([ZFS_META_KVER_MAX], + ["$ZFS_META_KVER_MAX"], + [Define the maximum compatible kernel version.] + ) + AC_SUBST([ZFS_META_KVER_MAX]) + fi + + m4_pattern_allow([^LT_(CURRENT|REVISION|AGE)$]) + ZFS_META_LT_CURRENT=_ZFS_AC_META_GETVAL([LT_Current]); + ZFS_META_LT_REVISION=_ZFS_AC_META_GETVAL([LT_Revision]); + ZFS_META_LT_AGE=_ZFS_AC_META_GETVAL([LT_Age]); + if test -n "$ZFS_META_LT_CURRENT" \ + -o -n "$ZFS_META_LT_REVISION" \ + -o -n "$ZFS_META_LT_AGE"; then + test -n "$ZFS_META_LT_CURRENT" || ZFS_META_LT_CURRENT="0" + test -n "$ZFS_META_LT_REVISION" || ZFS_META_LT_REVISION="0" + test -n "$ZFS_META_LT_AGE" || ZFS_META_LT_AGE="0" + AC_DEFINE_UNQUOTED([ZFS_META_LT_CURRENT], + ["$ZFS_META_LT_CURRENT"], + [Define the libtool library 'current' + version information.] + ) + AC_DEFINE_UNQUOTED([ZFS_META_LT_REVISION], + ["$ZFS_META_LT_REVISION"], + [Define the libtool library 'revision' + version information.] + ) + AC_DEFINE_UNQUOTED([ZFS_META_LT_AGE], ["$ZFS_META_LT_AGE"], + [Define the libtool library 'age' + version information.] + ) + AC_SUBST([ZFS_META_LT_CURRENT]) + AC_SUBST([ZFS_META_LT_REVISION]) + AC_SUBST([ZFS_META_LT_AGE]) + fi + fi + + AC_MSG_RESULT([$_zfs_ac_meta_type]) + ] +) + +dnl # _ZFS_AC_META_GETVAL (KEY_NAME_OR_REGEX) +dnl # +dnl # Returns the META VALUE associated with the given KEY_NAME_OR_REGEX expr. +dnl # +dnl # Despite their resemblance to line noise, +dnl # the "@<:@" and "@:>@" constructs are quadrigraphs for "[" and "]". +dnl # <www.gnu.org/software/autoconf/manual/autoconf.html#Quadrigraphs> +dnl # +dnl # The "$[]1" and "$[]2" constructs prevent M4 parameter expansion +dnl # so a literal $1 and $2 will be passed to the resulting awk script, +dnl # whereas the "$1" will undergo M4 parameter expansion for the META key. +dnl # +AC_DEFUN([_ZFS_AC_META_GETVAL], + [`$AWK -F ':@<:@ \t@:>@+' '$[]1 ~ /^ *$1$/ { print $[]2; exit }' $META`]dnl +) |