diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-10-24 17:07:04 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-10-24 19:40:24 +0200 |
commit | a4bc3c1d250a7a751baacbc5a61975aa1dd6d3d5 (patch) | |
tree | cc969122abe741890c7d4050fe963b0203acf501 /src/shared/tests.c | |
parent | 795919efdfab290ab341d8ffe6e82f6c85cb6198 (diff) | |
download | systemd-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.c | 37 |
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"); +} |