System crashes and other failures can occur if an environment attempts
to run the unit tests with the "production" / in-tree versions of the
nfit and libnvdimm modules. Ensure that all required test modules are
supplied by out-of-tree versions.

Granted that this detection mechanism will not differentiate the proper
tools/testing/nvdimm/ out-of-tree modules with something like a "driver
update" version of the modules, but it should catch the common case of a
platform being misconfigured for unit-test execution.

Reported-by: Dave Jiang <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
 test/Makefile.am |   25 ++++++++++--------
 test/core.c      |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 11 deletions(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 592308ee5f07..524fafa4a28a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -40,30 +40,33 @@ LIBNDCTL_LIB =\
        ../ndctl/lib/libndctl.la \
        ../daxctl/lib/libdaxctl.la
 
-libndctl_SOURCES = libndctl.c core.c
+testcore =\
+       core.c \
+       ../util/log.c \
+       ../util/sysfs.c
+
+libndctl_SOURCES = libndctl.c $(testcore)
 libndctl_LDADD = $(LIBNDCTL_LIB) $(UUID_LIBS) $(KMOD_LIBS)
 
 dsm_fail_SOURCES =\
        dsm-fail.c \
-       core.c \
-       ../util/log.c \
-       ../util/sysfs.c
+       $(testcore)
 
 dsm_fail_LDADD = $(LIBNDCTL_LIB) $(KMOD_LIBS)
 
-blk_ns_SOURCES = blk_namespaces.c core.c
+blk_ns_SOURCES = blk_namespaces.c $(testcore)
 blk_ns_LDADD = $(LIBNDCTL_LIB) $(KMOD_LIBS)
 
-pmem_ns_SOURCES = pmem_namespaces.c core.c
+pmem_ns_SOURCES = pmem_namespaces.c $(testcore)
 pmem_ns_LDADD = $(LIBNDCTL_LIB) $(KMOD_LIBS)
 
-dpa_alloc_SOURCES = dpa-alloc.c core.c
+dpa_alloc_SOURCES = dpa-alloc.c $(testcore)
 dpa_alloc_LDADD = $(LIBNDCTL_LIB) $(UUID_LIBS) $(KMOD_LIBS)
 
-parent_uuid_SOURCES = parent-uuid.c core.c
+parent_uuid_SOURCES = parent-uuid.c $(testcore)
 parent_uuid_LDADD = $(LIBNDCTL_LIB) $(UUID_LIBS) $(KMOD_LIBS)
 
-dax_dev_SOURCES = dax-dev.c core.c
+dax_dev_SOURCES = dax-dev.c $(testcore)
 dax_dev_LDADD = $(LIBNDCTL_LIB) $(KMOD_LIBS)
 
 dax_pmd_SOURCES = dax-pmd.c
@@ -73,7 +76,7 @@ device_dax_SOURCES = \
                device-dax.c \
                dax-dev.c \
                dax-pmd.c \
-               core.c \
+               $(testcore) \
                ../ndctl/builtin-xaction-namespace.c \
                ../util/json.c
 device_dax_LDADD = \
@@ -84,7 +87,7 @@ device_dax_LDADD = \
 
 multi_pmem_SOURCES = \
                multi-pmem.c \
-               core.c \
+               $(testcore) \
                ../ndctl/builtin-xaction-namespace.c \
                ../util/json.c
 multi_pmem_LDADD = \
diff --git a/test/core.c b/test/core.c
index 3119fd826a94..d1c38902feb4 100644
--- a/test/core.c
+++ b/test/core.c
@@ -6,6 +6,10 @@
 #include <stdio.h>
 #include <test.h>
 
+#include <util/log.h>
+#include <util/sysfs.h>
+#include <ccan/array_size/array_size.h>
+
 #define KVER_STRLEN 20
 
 struct ndctl_test {
@@ -103,12 +107,84 @@ int nfit_test_init(struct kmod_ctx **ctx, struct 
kmod_module **mod,
                int log_level)
 {
        int rc;
+       unsigned int i;
+       struct log_ctx log_ctx;
+       const char *list[] = {
+               "nfit",
+               "dax",
+               "dax_pmem",
+               "libnvdimm",
+               "nd_blk",
+               "nd_btt",
+               "nd_e820",
+               "nd_pmem",
+       };
+
+       log_init(&log_ctx, "test/init", "NDCTL_TEST");
+       log_ctx.log_priority = log_level;
 
        *ctx = kmod_new(NULL, NULL);
        if (!*ctx)
                return -ENXIO;
        kmod_set_log_priority(*ctx, log_level);
 
+       /*
+        * Check that all nfit, libnvdimm, and device-dax modules are
+        * the mocked versions. If they are loaded, check that they have
+        * the "out-of-tree" kernel taint, otherwise check that they
+        * come from the "/lib/modules/<KVER>/extra" directory.
+        */
+       for (i = 0; i < ARRAY_SIZE(list); i++) {
+               char attr[SYSFS_ATTR_SIZE];
+               const char *name = list[i];
+               const char *path;
+               char buf[100];
+               int state;
+
+               rc = kmod_module_new_from_name(*ctx, name, mod);
+               if (rc) {
+                       log_err(&log_ctx, "%s.ko: missing\n", name);
+                       break;
+               }
+
+               path = kmod_module_get_path(*mod);
+               if (!path) {
+                       log_err(&log_ctx, "%s.ko: failed to get path\n", name);
+                       break;
+               }
+
+               if (!strstr(path, "/extra/")) {
+                       log_err(&log_ctx, "%s.ko: appears to be production 
version: %s\n",
+                                       name, path);
+                       break;
+               }
+
+               state = kmod_module_get_initstate(*mod);
+               if (state == KMOD_MODULE_LIVE) {
+                       sprintf(buf, "/sys/module/%s/taint", name);
+                       rc = __sysfs_read_attr(&log_ctx, buf, attr);
+                       if (rc < 0) {
+                               log_err(&log_ctx, "%s.ko: failed to read %s\n",
+                                               name, buf);
+                               break;
+                       }
+
+                       if (strcmp(attr, "O") != 0) {
+                               log_err(&log_ctx, "%s.ko: expected taint: O 
got: %s\n",
+                                               name, attr);
+                               break;
+                       }
+               } else if (state == KMOD_MODULE_BUILTIN) {
+                       log_err(&log_ctx, "%s: must be built as a module\n", 
name);
+                       break;
+               }
+       }
+
+       if (i < ARRAY_SIZE(list)) {
+               kmod_unref(*ctx);
+               return -ENXIO;
+       }
+
        rc = kmod_module_new_from_name(*ctx, "nfit_test", mod);
        if (rc < 0) {
                kmod_unref(*ctx);

_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to