On 5/23/19 12:45 PM, Roman Gushchin wrote: > Add a kselftest to cover bpf auto-detachment functionality. > The test creates a cgroup, associates some resources with it, > attaches a couple of bpf programs and deletes the cgroup. > > Then it checks that bpf programs are going away in 5 seconds. > > Expected output: > $ ./test_cgroup_attach > #override:PASS > #multi:PASS > #autodetach:PASS > test_cgroup_attach:PASS > > On a kernel without auto-detaching: > $ ./test_cgroup_attach > #override:PASS > #multi:PASS > #autodetach:FAIL > test_cgroup_attach:FAIL > > Signed-off-by: Roman Gushchin <guro@xxxxxx> Looks good to me. It will be good if you can add test_cgroup_attach to .gitignore to avoid it shows up in `git status`. With that, Acked-by: Yonghong Song <yhs@xxxxxx> > --- > .../selftests/bpf/test_cgroup_attach.c | 98 ++++++++++++++++++- > 1 file changed, 97 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/bpf/test_cgroup_attach.c b/tools/testing/selftests/bpf/test_cgroup_attach.c > index 2d6d57f50e10..7671909ee1cb 100644 > --- a/tools/testing/selftests/bpf/test_cgroup_attach.c > +++ b/tools/testing/selftests/bpf/test_cgroup_attach.c > @@ -456,9 +456,105 @@ static int test_multiprog(void) > return rc; > } > > +static int test_autodetach(void) > +{ > + __u32 prog_cnt = 4, attach_flags; > + int allow_prog[2] = {0}; > + __u32 prog_ids[2] = {0}; > + int cg = 0, i, rc = -1; > + void *ptr = NULL; > + int attempts; > + > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { > + allow_prog[i] = prog_load_cnt(1, 1 << i); > + if (!allow_prog[i]) > + goto err; > + } > + > + if (setup_cgroup_environment()) > + goto err; > + > + /* create a cgroup, attach two programs and remember their ids */ > + cg = create_and_get_cgroup("/cg_autodetach"); > + if (cg < 0) > + goto err; > + > + if (join_cgroup("/cg_autodetach")) > + goto err; > + > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { > + if (bpf_prog_attach(allow_prog[i], cg, BPF_CGROUP_INET_EGRESS, > + BPF_F_ALLOW_MULTI)) { > + log_err("Attaching prog[%d] to cg:egress", i); > + goto err; > + } > + } > + > + /* make sure that programs are attached and run some traffic */ > + assert(bpf_prog_query(cg, BPF_CGROUP_INET_EGRESS, 0, &attach_flags, > + prog_ids, &prog_cnt) == 0); > + assert(system(PING_CMD) == 0); > + > + /* allocate some memory (4Mb) to pin the original cgroup */ > + ptr = malloc(4 * (1 << 20)); > + if (!ptr) > + goto err; > + > + /* close programs and cgroup fd */ > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { > + close(allow_prog[i]); > + allow_prog[i] = 0; > + } > + > + close(cg); > + cg = 0; > + > + /* leave the cgroup and remove it. don't detach programs */ > + cleanup_cgroup_environment(); > + > + /* wait for the asynchronous auto-detachment. > + * wait for no more than 5 sec and give up. > + */ > + for (i = 0; i < ARRAY_SIZE(prog_ids); i++) { > + for (attempts = 5; attempts >= 0; attempts--) { > + int fd = bpf_prog_get_fd_by_id(prog_ids[i]); > + > + if (fd < 0) > + break; > + > + /* don't leave the fd open */ > + close(fd); > + > + if (!attempts) > + goto err; > + > + sleep(1); > + } > + } > + > + rc = 0; > +err: > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) > + if (allow_prog[i] > 0) > + close(allow_prog[i]); > + if (cg) > + close(cg); > + free(ptr); > + cleanup_cgroup_environment(); > + if (!rc) > + printf("#autodetach:PASS\n"); > + else > + printf("#autodetach:FAIL\n"); > + return rc; > +} > + > int main(void) > { > - int (*tests[])(void) = {test_foo_bar, test_multiprog}; > + int (*tests[])(void) = { > + test_foo_bar, > + test_multiprog, > + test_autodetach, > + }; > int errors = 0; > int i; > >