[LTP] [PATCH v2] lib: tst_kconfig: Add runtime checks for CONFIG_*_NS

Cyril Hrubis
2026-04-01T11:52:07Z

Previously LTP Kconfig parsing logic only checked if a feature was
enabled during kernel compilation (e.g., CONFIG_USER_NS=y). However,
some kernel features can be compiled in but disabled at runtime via
kernel command-line or sysctls. Tests relying only on Kconfig variables
may have failed when features were runtime disabled.

This patch introduces a runtime check mechanism for Kconfig variables.
When a CONFIG_* variable is parsed as 'y' or 'm' and when runtime check
has been associated with the variable we run the check and potentionaly
print a message and override the variable value.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
---
lib/newlib_tests/test_kconfig.c | 1 +
lib/tst_kconfig.c | 38 ++++++++++++++++++++++++++++++++-
lib/tst_kconfig_checks.h | 37 ++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+), 1 deletion(-)
create mode 100644 lib/tst_kconfig_checks.h

diff --git a/lib/newlib_tests/test_kconfig.c b/lib/newlib_tests/test_kconfig.c
index cea36b5ee..ed2c4610a 100644
--- a/lib/newlib_tests/test_kconfig.c
+++ b/lib/newlib_tests/test_kconfig.c
@@ -18,6 +18,7 @@ static const char *kconfigs[] = {
"CONFIG_MMU & CONFIG_EXT4_FS=m",
"CONFIG_EXT4_FS=m | CONFIG_MMU",
"CONFIG_DEFAULT_HOSTNAME=\"(none)\"",
+ "CONFIG_USER_NS",
NULL
};

diff --git a/lib/tst_kconfig.c b/lib/tst_kconfig.c
index adc56503e..52dd6d726 100644
--- a/lib/tst_kconfig.c
+++ b/lib/tst_kconfig.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2018 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) 2018-2026 Cyril Hrubis <chrubis@suse.cz>
*/

#include <stdlib.h>
@@ -16,6 +16,8 @@
#include "tst_bool_expr.h"
#include "tst_safe_stdio.h"

+#include "tst_kconfig_checks.h"
+
static int kconfig_skip_check(void)
{
char *skipped = getenv("KCONFIG_SKIP_CHECK");
@@ -110,6 +112,38 @@ static void close_kconfig(FILE *fp)
fclose(fp);
}

+static struct runtime_check {
+ const char *config;
+ bool (*runtime_check)(void);
+} runtime_checks[] = {
+ {"CONFIG_USER_NS", tst_user_ns_enabled},
+ {"CONFIG_NET_NS", tst_net_ns_enabled},
+ {"CONFIG_PID_NS", tst_pid_ns_enabled},
+ {"CONFIG_MNT_NS", tst_mnt_ns_enabled},
+ {"CONFIG_IPC_NS", tst_ipc_ns_enabled},
+ {}
+};
+
+static void runtime_check(struct tst_kconfig_var *var)
+{
+ size_t i;
+
+ for (i = 0; runtime_checks[i].config; i++) {
+ if (strcmp(runtime_checks[i].config, var->id))
+ continue;
+
+ tst_res(TDEBUG, "Running runtime check for '%s'", var->id);
+
+ if (!runtime_checks[i].runtime_check()) {
+ tst_res(TINFO,
+ "%s=%c present but disabled at runtime",
+ var->id, var->choice);
+ var->choice = 'n';
+ return;
+ }
+ }
+}
+
static inline int kconfig_parse_line(const char *line,
struct tst_kconfig_var *vars,
unsigned int vars_len)
@@ -183,9 +217,11 @@ out:
switch (val[0]) {
case 'y':
vars[i].choice = 'y';
+ runtime_check(&vars[i]);
return 1;
case 'm':
vars[i].choice = 'm';
+ runtime_check(&vars[i]);
return 1;
}
}
diff --git a/lib/tst_kconfig_checks.h b/lib/tst_kconfig_checks.h
new file mode 100644
index 000000000..94aad6411
--- /dev/null
+++ b/lib/tst_kconfig_checks.h
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+#ifndef TST_KCONFIG_CHECKS_H
+#define TST_KCONFIG_CHECKS_H
+
+#include <unistd.h>
+#include <stdbool.h>
+
+static inline bool tst_user_ns_enabled(void)
+{
+ return access("/proc/self/ns/user", F_OK) == 0;
+}
+
+static inline bool tst_net_ns_enabled(void)
+{
+ return access("/proc/self/ns/net", F_OK) == 0;
+}
+
+static inline bool tst_pid_ns_enabled(void)
+{
+ return access("/proc/self/ns/pid", F_OK) == 0;
+}
+
+static inline bool tst_mnt_ns_enabled(void)
+{
+ return access("/proc/self/ns/mnt", F_OK) == 0;
+}
+
+static inline bool tst_ipc_ns_enabled(void)
+{
+ return access("/proc/self/ns/ipc", F_OK) == 0;
+}
+
+#endif /* TST_KCONFIG_CHECKS_H */
--
2.52.0