diff options
author | Lennart Poettering <lennart@poettering.net> | 2019-01-24 10:19:33 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-01-24 23:50:26 +0100 |
commit | 3dffcfc78bc31cb70a1cb0b350ec95332ff0f2fe (patch) | |
tree | a53d27916d4c3decd60970b31c3bda8b693a8457 | |
parent | Merge pull request #11536 from yuwata/fix-11529 (diff) | |
download | systemd-3dffcfc78bc31cb70a1cb0b350ec95332ff0f2fe.tar.xz systemd-3dffcfc78bc31cb70a1cb0b350ec95332ff0f2fe.zip |
test-bpf: check if we can mlock() before trying bpf
-rw-r--r-- | src/test/test-bpf.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/test/test-bpf.c b/src/test/test-bpf.c index 7341f7f1ea..cd8d68f215 100644 --- a/src/test/test-bpf.c +++ b/src/test/test-bpf.c @@ -2,6 +2,7 @@ #include <linux/libbpf.h> #include <string.h> +#include <sys/mman.h> #include <unistd.h> #include "bpf-firewall.h" @@ -14,6 +15,30 @@ #include "tests.h" #include "unit.h" +/* We use the same limit here that PID 1 bumps RLIMIT_MEMLOCK to if it can */ +#define CAN_MEMLOCK_SIZE (64U*1024U*1024U) + +static bool can_memlock(void) { + void *p; + bool b; + + /* Let's see if we can mlock() a larger blob of memory. BPF programs are charged against + * RLIMIT_MEMLOCK, hence let's first make sure we can lock memory at all, and skip the test if we + * cannot. Why not check RLIMIT_MEMLOCK explicitly? Because in container environments the + * RLIMIT_MEMLOCK value we see might not match the RLIMIT_MEMLOCK value actually in effect. */ + + p = mmap(NULL, CAN_MEMLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0); + if (p == MAP_FAILED) + return false; + + b = mlock(p, CAN_MEMLOCK_SIZE) >= 0; + if (b) + assert_se(munlock(p, CAN_MEMLOCK_SIZE) >= 0); + + assert_se(munmap(p, CAN_MEMLOCK_SIZE) >= 0); + return b; +} + int main(int argc, char *argv[]) { struct bpf_insn exit_insn[] = { BPF_MOV64_IMM(BPF_REG_0, 1), @@ -26,6 +51,7 @@ int main(int argc, char *argv[]) { _cleanup_(manager_freep) Manager *m = NULL; Unit *u; char log_buf[65535]; + struct rlimit rl; int r; test_setup_logging(LOG_DEBUG); @@ -33,6 +59,13 @@ int main(int argc, char *argv[]) { if (is_run_on_travis_ci()) return log_tests_skipped("test-bpf fails on Travis CI: https://github.com/systemd/systemd/issues/9666"); + assert_se(getrlimit(RLIMIT_MEMLOCK, &rl) >= 0); + rl.rlim_cur = rl.rlim_max = MAX3(rl.rlim_cur, rl.rlim_max, CAN_MEMLOCK_SIZE); + (void) setrlimit(RLIMIT_MEMLOCK, &rl); + + if (!can_memlock()) + return log_tests_skipped("Can't use mlock(), skipping."); + r = enter_cgroup_subroot(); if (r == -ENOMEDIUM) return log_tests_skipped("cgroupfs not available"); |