diff options
| author | Sargun Dhillon <sargun@sargun.me> | 2016-12-02 05:42:18 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-12-03 16:07:11 -0500 |
| commit | 1a922fee66c8a691bfec738b6a5694b2dbb2177d (patch) | |
| tree | a2196acc64ef60499075d0711c4a0eecb0abef09 /samples/bpf/test_current_task_under_cgroup_user.c | |
| parent | 69a9d09b2251aeb968e76f39f2b89774312daa3d (diff) | |
samples, bpf: Refactor test_current_task_under_cgroup - separate out helpers
This patch modifies test_current_task_under_cgroup_user. The test has
several helpers around creating a temporary environment for cgroup
testing, and moving the current task around cgroups. This set of
helpers can then be used in other tests.
Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples/bpf/test_current_task_under_cgroup_user.c')
| -rw-r--r-- | samples/bpf/test_current_task_under_cgroup_user.c | 108 |
1 files changed, 24 insertions, 84 deletions
diff --git a/samples/bpf/test_current_task_under_cgroup_user.c b/samples/bpf/test_current_task_under_cgroup_user.c index 30b0bce884f9..95aaaa846130 100644 --- a/samples/bpf/test_current_task_under_cgroup_user.c +++ b/samples/bpf/test_current_task_under_cgroup_user.c | |||
| @@ -11,50 +11,16 @@ | |||
| 11 | #include <unistd.h> | 11 | #include <unistd.h> |
| 12 | #include "libbpf.h" | 12 | #include "libbpf.h" |
| 13 | #include "bpf_load.h" | 13 | #include "bpf_load.h" |
| 14 | #include <string.h> | ||
| 15 | #include <fcntl.h> | ||
| 16 | #include <errno.h> | ||
| 17 | #include <linux/bpf.h> | 14 | #include <linux/bpf.h> |
| 18 | #include <sched.h> | 15 | #include "cgroup_helpers.h" |
| 19 | #include <sys/mount.h> | ||
| 20 | #include <sys/stat.h> | ||
| 21 | #include <sys/types.h> | ||
| 22 | #include <linux/limits.h> | ||
| 23 | 16 | ||
| 24 | #define CGROUP_MOUNT_PATH "/mnt" | 17 | #define CGROUP_PATH "/my-cgroup" |
| 25 | #define CGROUP_PATH "/mnt/my-cgroup" | ||
| 26 | |||
| 27 | #define clean_errno() (errno == 0 ? "None" : strerror(errno)) | ||
| 28 | #define log_err(MSG, ...) fprintf(stderr, "(%s:%d: errno: %s) " MSG "\n", \ | ||
| 29 | __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) | ||
| 30 | |||
| 31 | static int join_cgroup(char *path) | ||
| 32 | { | ||
| 33 | int fd, rc = 0; | ||
| 34 | pid_t pid = getpid(); | ||
| 35 | char cgroup_path[PATH_MAX + 1]; | ||
| 36 | |||
| 37 | snprintf(cgroup_path, sizeof(cgroup_path), "%s/cgroup.procs", path); | ||
| 38 | |||
| 39 | fd = open(cgroup_path, O_WRONLY); | ||
| 40 | if (fd < 0) { | ||
| 41 | log_err("Opening Cgroup"); | ||
| 42 | return 1; | ||
| 43 | } | ||
| 44 | |||
| 45 | if (dprintf(fd, "%d\n", pid) < 0) { | ||
| 46 | log_err("Joining Cgroup"); | ||
| 47 | rc = 1; | ||
| 48 | } | ||
| 49 | close(fd); | ||
| 50 | return rc; | ||
| 51 | } | ||
| 52 | 18 | ||
| 53 | int main(int argc, char **argv) | 19 | int main(int argc, char **argv) |
| 54 | { | 20 | { |
| 55 | char filename[256]; | ||
| 56 | int cg2, idx = 0; | ||
| 57 | pid_t remote_pid, local_pid = getpid(); | 21 | pid_t remote_pid, local_pid = getpid(); |
| 22 | int cg2, idx = 0, rc = 0; | ||
| 23 | char filename[256]; | ||
| 58 | 24 | ||
| 59 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); | 25 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); |
| 60 | if (load_bpf_file(filename)) { | 26 | if (load_bpf_file(filename)) { |
| @@ -62,47 +28,22 @@ int main(int argc, char **argv) | |||
| 62 | return 1; | 28 | return 1; |
| 63 | } | 29 | } |
| 64 | 30 | ||
| 65 | /* | 31 | if (setup_cgroup_environment()) |
| 66 | * This is to avoid interfering with existing cgroups. Unfortunately, | 32 | goto err; |
| 67 | * most people don't have cgroupv2 enabled at this point in time. | ||
| 68 | * It's easier to create our own mount namespace and manage it | ||
| 69 | * ourselves. | ||
| 70 | */ | ||
| 71 | if (unshare(CLONE_NEWNS)) { | ||
| 72 | log_err("unshare"); | ||
| 73 | return 1; | ||
| 74 | } | ||
| 75 | |||
| 76 | if (mount("none", "/", NULL, MS_REC | MS_PRIVATE, NULL)) { | ||
| 77 | log_err("mount fakeroot"); | ||
| 78 | return 1; | ||
| 79 | } | ||
| 80 | |||
| 81 | if (mount("none", CGROUP_MOUNT_PATH, "cgroup2", 0, NULL)) { | ||
| 82 | log_err("mount cgroup2"); | ||
| 83 | return 1; | ||
| 84 | } | ||
| 85 | 33 | ||
| 86 | if (mkdir(CGROUP_PATH, 0777) && errno != EEXIST) { | 34 | cg2 = create_and_get_cgroup(CGROUP_PATH); |
| 87 | log_err("mkdir cgroup"); | ||
| 88 | return 1; | ||
| 89 | } | ||
| 90 | 35 | ||
| 91 | cg2 = open(CGROUP_PATH, O_RDONLY); | 36 | if (!cg2) |
| 92 | if (cg2 < 0) { | 37 | goto err; |
| 93 | log_err("opening target cgroup"); | ||
| 94 | goto cleanup_cgroup_err; | ||
| 95 | } | ||
| 96 | 38 | ||
| 97 | if (bpf_update_elem(map_fd[0], &idx, &cg2, BPF_ANY)) { | 39 | if (bpf_update_elem(map_fd[0], &idx, &cg2, BPF_ANY)) { |
| 98 | log_err("Adding target cgroup to map"); | 40 | log_err("Adding target cgroup to map"); |
| 99 | goto cleanup_cgroup_err; | 41 | goto err; |
| 100 | } | ||
| 101 | if (join_cgroup("/mnt/my-cgroup")) { | ||
| 102 | log_err("Leaving target cgroup"); | ||
| 103 | goto cleanup_cgroup_err; | ||
| 104 | } | 42 | } |
| 105 | 43 | ||
| 44 | if (join_cgroup(CGROUP_PATH)) | ||
| 45 | goto err; | ||
| 46 | |||
| 106 | /* | 47 | /* |
| 107 | * The installed helper program catched the sync call, and should | 48 | * The installed helper program catched the sync call, and should |
| 108 | * write it to the map. | 49 | * write it to the map. |
| @@ -115,12 +56,12 @@ int main(int argc, char **argv) | |||
| 115 | fprintf(stderr, | 56 | fprintf(stderr, |
| 116 | "BPF Helper didn't write correct PID to map, but: %d\n", | 57 | "BPF Helper didn't write correct PID to map, but: %d\n", |
| 117 | remote_pid); | 58 | remote_pid); |
| 118 | goto leave_cgroup_err; | 59 | goto err; |
| 119 | } | 60 | } |
| 120 | 61 | ||
| 121 | /* Verify the negative scenario; leave the cgroup */ | 62 | /* Verify the negative scenario; leave the cgroup */ |
| 122 | if (join_cgroup(CGROUP_MOUNT_PATH)) | 63 | if (join_cgroup("/")) |
| 123 | goto leave_cgroup_err; | 64 | goto err; |
| 124 | 65 | ||
| 125 | remote_pid = 0; | 66 | remote_pid = 0; |
| 126 | bpf_update_elem(map_fd[1], &idx, &remote_pid, BPF_ANY); | 67 | bpf_update_elem(map_fd[1], &idx, &remote_pid, BPF_ANY); |
| @@ -130,16 +71,15 @@ int main(int argc, char **argv) | |||
| 130 | 71 | ||
| 131 | if (local_pid == remote_pid) { | 72 | if (local_pid == remote_pid) { |
| 132 | fprintf(stderr, "BPF cgroup negative test did not work\n"); | 73 | fprintf(stderr, "BPF cgroup negative test did not work\n"); |
| 133 | goto cleanup_cgroup_err; | 74 | goto err; |
| 134 | } | 75 | } |
| 135 | 76 | ||
| 136 | rmdir(CGROUP_PATH); | 77 | goto out; |
| 137 | return 0; | 78 | err: |
| 79 | rc = 1; | ||
| 138 | 80 | ||
| 139 | /* Error condition, cleanup */ | 81 | out: |
| 140 | leave_cgroup_err: | 82 | close(cg2); |
| 141 | join_cgroup(CGROUP_MOUNT_PATH); | 83 | cleanup_cgroup_environment(); |
| 142 | cleanup_cgroup_err: | 84 | return rc; |
| 143 | rmdir(CGROUP_PATH); | ||
| 144 | return 1; | ||
| 145 | } | 85 | } |
