On Wed, May 22, 2019 at 03:24:38PM -0700, Stanislav Fomichev wrote:
> On 05/22, 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 <g...@fb.com>
> > ---
> >  .../selftests/bpf/test_cgroup_attach.c        | 108 +++++++++++++++++-
> >  1 file changed, 107 insertions(+), 1 deletion(-)
> > 
> > diff --git a/tools/testing/selftests/bpf/test_cgroup_attach.c 
> > b/tools/testing/selftests/bpf/test_cgroup_attach.c
> > index 93d4fe295e7d..36441fd0f392 100644
> > --- a/tools/testing/selftests/bpf/test_cgroup_attach.c
> > +++ b/tools/testing/selftests/bpf/test_cgroup_attach.c
> > @@ -456,9 +456,115 @@ 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();
> > +
> 
> [..]
> > +   /* programs must stay pinned by the allocated memory */
> > +   for (i = 0; i < ARRAY_SIZE(prog_ids); i++) {
> > +           int fd = bpf_prog_get_fd_by_id(prog_ids[i]);
> > +
> > +           if (fd < 0)
> > +                   goto err;
> > +           close(fd);
> > +   }
> This looks a bit flaky. It's essentially the same check you later
> do in a for loop. I guess there is a chance that async auto-detach
> might happen right after cleanup_cgroup_environment and before this for loop?

Ah, this section remained from an earlier version which had another step.
I'll remove it completely, it's totally useless now.

Thanks!

Reply via email to