From a4bc3c1d250a7a751baacbc5a61975aa1dd6d3d5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Oct 2018 17:07:04 +0200 Subject: [PATCH] tests: add helper call have_namespaces() to test whether Linux namespaces are available A slighly sloppy test call for conditionalizing several tests. --- src/shared/tests.c | 37 +++++++++++++++++++++++++++++++++++++ src/shared/tests.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/src/shared/tests.c b/src/shared/tests.c index ec8039575e..d21bd22b40 100644 --- a/src/shared/tests.c +++ b/src/shared/tests.c @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +#include +#include #include +#include +#include #include /* When we include libgen.h because we need dirname() we immediately @@ -112,3 +116,36 @@ int log_tests_skipped_errno(int r, const char *message) { program_invocation_short_name, message); return EXIT_TEST_SKIP; } + +bool have_namespaces(void) { + siginfo_t si = {}; + pid_t pid; + + /* Checks whether namespaces are available. In some cases they aren't. We do this by calling unshare(), and we + * do so in a child process in order not to affect our own process. */ + + pid = fork(); + assert_se(pid >= 0); + + if (pid == 0) { + /* child */ + if (unshare(CLONE_NEWNS) < 0) + _exit(EXIT_FAILURE); + + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + assert_se(waitid(P_PID, pid, &si, WEXITED) >= 0); + assert_se(si.si_code == CLD_EXITED); + + if (si.si_status == EXIT_SUCCESS) + return true; + + if (si.si_status == EXIT_FAILURE) + return false; + + assert_not_reached("unexpected exit code"); +} diff --git a/src/shared/tests.h b/src/shared/tests.h index 58a3e1c32d..718196f134 100644 --- a/src/shared/tests.h +++ b/src/shared/tests.h @@ -10,3 +10,5 @@ bool slow_tests_enabled(void); void test_setup_logging(int level); int log_tests_skipped(const char *message); int log_tests_skipped_errno(int r, const char *message); + +bool have_namespaces(void);