summaryrefslogtreecommitdiff
path: root/src/shared/tests.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-10-24 17:07:04 +0200
committerLennart Poettering <lennart@poettering.net>2018-10-24 19:40:24 +0200
commita4bc3c1d250a7a751baacbc5a61975aa1dd6d3d5 (patch)
treecc969122abe741890c7d4050fe963b0203acf501 /src/shared/tests.c
parent795919efdfab290ab341d8ffe6e82f6c85cb6198 (diff)
downloadsystemd-a4bc3c1d250a7a751baacbc5a61975aa1dd6d3d5.tar.gz
tests: add helper call have_namespaces() to test whether Linux namespaces are available
A slighly sloppy test call for conditionalizing several tests.
Diffstat (limited to 'src/shared/tests.c')
-rw-r--r--src/shared/tests.c37
1 files changed, 37 insertions, 0 deletions
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 <sched.h>
+#include <signal.h>
#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
#include <util.h>
/* 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");
+}