diff mbox series

[RFC,2/3] bpf: set attached cgroup name in attach_name

Message ID 20220218095612.52082-3-laoar.shao@gmail.com (mailing list archive)
State RFC
Delegated to: BPF
Headers show
Series bpf: show attached name for progs without btf name | expand

Checks

Context Check Description
bpf/vmtest-bpf-PR fail PR summary
bpf/vmtest-bpf fail VM_Test
netdev/tree_selection success Guessing tree name failed - patch did not apply, async

Commit Message

Yafang Shao Feb. 18, 2022, 9:56 a.m. UTC
Set the cgroup path when a bpf prog is attached to a cgroup, and unset
it when the bpf prog is detached.

Below is the result after this change,
$ cat progs.debug
  id name             attached
   5 dump_bpf_map     bpf_iter_bpf_map
   7 dump_bpf_prog    bpf_iter_bpf_prog
  17 bpf_sockmap      cgroup:/
  19 bpf_redir_proxy

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/cgroup.c | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Alexei Starovoitov Feb. 19, 2022, 6:27 p.m. UTC | #1
On Fri, Feb 18, 2022 at 1:56 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> Set the cgroup path when a bpf prog is attached to a cgroup, and unset
> it when the bpf prog is detached.
>
> Below is the result after this change,
> $ cat progs.debug
>   id name             attached
>    5 dump_bpf_map     bpf_iter_bpf_map
>    7 dump_bpf_prog    bpf_iter_bpf_prog
>   17 bpf_sockmap      cgroup:/
>   19 bpf_redir_proxy
>
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---
>  kernel/bpf/cgroup.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> index 43eb3501721b..ebd87e54f2d0 100644
> --- a/kernel/bpf/cgroup.c
> +++ b/kernel/bpf/cgroup.c
> @@ -440,6 +440,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
>         struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
>         struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
>         enum cgroup_bpf_attach_type atype;
> +       char cgrp_path[64] = "cgroup:";
>         struct bpf_prog_list *pl;
>         struct list_head *progs;
>         int err;
> @@ -508,6 +509,11 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
>         else
>                 static_branch_inc(&cgroup_bpf_enabled_key[atype]);
>         bpf_cgroup_storages_link(new_storage, cgrp, type);
> +
> +       cgroup_name(cgrp, cgrp_path + strlen("cgroup:"), 64);
> +       cgrp_path[63] = '\0';
> +       prog->aux->attach_name = kstrdup(cgrp_path, GFP_KERNEL);
> +

This is pure debug code. We cannot have it in the kernel.
Not even under #ifdef.

Please do such debug code on a side as your own bpf program.
For example by kprobe-ing in this function and keeping the path
in a bpf map or send it to user space via ringbuf.
Or enable cgroup tracepoint and monitor cgroup_mkdir with full path.
Record it in user space or in bpf map, etc.

Also please read Documentation/bpf/bpf_devel_QA.rst
bpf patches should be based on bpf-next tree.
These patches are not.
Yafang Shao Feb. 20, 2022, 2:17 p.m. UTC | #2
On Sun, Feb 20, 2022 at 2:27 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Feb 18, 2022 at 1:56 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > Set the cgroup path when a bpf prog is attached to a cgroup, and unset
> > it when the bpf prog is detached.
> >
> > Below is the result after this change,
> > $ cat progs.debug
> >   id name             attached
> >    5 dump_bpf_map     bpf_iter_bpf_map
> >    7 dump_bpf_prog    bpf_iter_bpf_prog
> >   17 bpf_sockmap      cgroup:/
> >   19 bpf_redir_proxy
> >
> > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > ---
> >  kernel/bpf/cgroup.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> > index 43eb3501721b..ebd87e54f2d0 100644
> > --- a/kernel/bpf/cgroup.c
> > +++ b/kernel/bpf/cgroup.c
> > @@ -440,6 +440,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> >         struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> >         struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> >         enum cgroup_bpf_attach_type atype;
> > +       char cgrp_path[64] = "cgroup:";
> >         struct bpf_prog_list *pl;
> >         struct list_head *progs;
> >         int err;
> > @@ -508,6 +509,11 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> >         else
> >                 static_branch_inc(&cgroup_bpf_enabled_key[atype]);
> >         bpf_cgroup_storages_link(new_storage, cgrp, type);
> > +
> > +       cgroup_name(cgrp, cgrp_path + strlen("cgroup:"), 64);
> > +       cgrp_path[63] = '\0';
> > +       prog->aux->attach_name = kstrdup(cgrp_path, GFP_KERNEL);
> > +
>
> This is pure debug code. We cannot have it in the kernel.
> Not even under #ifdef.
>
> Please do such debug code on a side as your own bpf program.
> For example by kprobe-ing in this function and keeping the path
> in a bpf map or send it to user space via ringbuf.
> Or enable cgroup tracepoint and monitor cgroup_mkdir with full path.
> Record it in user space or in bpf map, etc.
>

It is another possible solution to  hook the related kernel functions
or tracepoints, but it may be a little complicated to track all the
bpf attach types, for example we also want to track
BPF_PROG_TYPE_SK_MSG[1], BPF_PROG_TYPE_FLOW_DISSECTOR and etc.
While the attach_name provides us a generic way to get how the bpf
progs are attached, which can't be got by bpftool.
It is not for debug-only purpose, while it gives us a better way to
maintain all the bpf progs running on a single host.

> Also please read Documentation/bpf/bpf_devel_QA.rst
> bpf patches should be based on bpf-next tree.
> These patches are not.

My local bpf-next repo is a little old.
Next time I will pull the newest bpf-next code before sending bpf
patches. Thanks for the information.

[1]. https://patchwork.kernel.org/project/netdevbpf/patch/20220218095612.52082-4-laoar.shao@gmail.com/
Alexei Starovoitov Feb. 20, 2022, 8:59 p.m. UTC | #3
On Sun, Feb 20, 2022 at 6:17 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> On Sun, Feb 20, 2022 at 2:27 AM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Fri, Feb 18, 2022 at 1:56 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > >
> > > Set the cgroup path when a bpf prog is attached to a cgroup, and unset
> > > it when the bpf prog is detached.
> > >
> > > Below is the result after this change,
> > > $ cat progs.debug
> > >   id name             attached
> > >    5 dump_bpf_map     bpf_iter_bpf_map
> > >    7 dump_bpf_prog    bpf_iter_bpf_prog
> > >   17 bpf_sockmap      cgroup:/
> > >   19 bpf_redir_proxy
> > >
> > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > ---
> > >  kernel/bpf/cgroup.c | 8 ++++++++
> > >  1 file changed, 8 insertions(+)
> > >
> > > diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> > > index 43eb3501721b..ebd87e54f2d0 100644
> > > --- a/kernel/bpf/cgroup.c
> > > +++ b/kernel/bpf/cgroup.c
> > > @@ -440,6 +440,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > >         struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > >         struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > >         enum cgroup_bpf_attach_type atype;
> > > +       char cgrp_path[64] = "cgroup:";
> > >         struct bpf_prog_list *pl;
> > >         struct list_head *progs;
> > >         int err;
> > > @@ -508,6 +509,11 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > >         else
> > >                 static_branch_inc(&cgroup_bpf_enabled_key[atype]);
> > >         bpf_cgroup_storages_link(new_storage, cgrp, type);
> > > +
> > > +       cgroup_name(cgrp, cgrp_path + strlen("cgroup:"), 64);
> > > +       cgrp_path[63] = '\0';
> > > +       prog->aux->attach_name = kstrdup(cgrp_path, GFP_KERNEL);
> > > +
> >
> > This is pure debug code. We cannot have it in the kernel.
> > Not even under #ifdef.
> >
> > Please do such debug code on a side as your own bpf program.
> > For example by kprobe-ing in this function and keeping the path
> > in a bpf map or send it to user space via ringbuf.
> > Or enable cgroup tracepoint and monitor cgroup_mkdir with full path.
> > Record it in user space or in bpf map, etc.
> >
>
> It is another possible solution to  hook the related kernel functions
> or tracepoints, but it may be a little complicated to track all the
> bpf attach types, for example we also want to track
> BPF_PROG_TYPE_SK_MSG[1], BPF_PROG_TYPE_FLOW_DISSECTOR and etc.
> While the attach_name provides us a generic way to get how the bpf
> progs are attached, which can't be got by bpftool.

bpftool can certainly print such details.
See how it's using task_file iterator.
It can be extended to look into cgroups and sockmap,
and for each program print "sockmap:%d", map->id if so desired.
Yafang Shao Feb. 21, 2022, 2:33 a.m. UTC | #4
On Mon, Feb 21, 2022 at 4:59 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Sun, Feb 20, 2022 at 6:17 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > On Sun, Feb 20, 2022 at 2:27 AM Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > >
> > > On Fri, Feb 18, 2022 at 1:56 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > >
> > > > Set the cgroup path when a bpf prog is attached to a cgroup, and unset
> > > > it when the bpf prog is detached.
> > > >
> > > > Below is the result after this change,
> > > > $ cat progs.debug
> > > >   id name             attached
> > > >    5 dump_bpf_map     bpf_iter_bpf_map
> > > >    7 dump_bpf_prog    bpf_iter_bpf_prog
> > > >   17 bpf_sockmap      cgroup:/
> > > >   19 bpf_redir_proxy
> > > >
> > > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > > ---
> > > >  kernel/bpf/cgroup.c | 8 ++++++++
> > > >  1 file changed, 8 insertions(+)
> > > >
> > > > diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> > > > index 43eb3501721b..ebd87e54f2d0 100644
> > > > --- a/kernel/bpf/cgroup.c
> > > > +++ b/kernel/bpf/cgroup.c
> > > > @@ -440,6 +440,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > > >         struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > > >         struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > > >         enum cgroup_bpf_attach_type atype;
> > > > +       char cgrp_path[64] = "cgroup:";
> > > >         struct bpf_prog_list *pl;
> > > >         struct list_head *progs;
> > > >         int err;
> > > > @@ -508,6 +509,11 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > > >         else
> > > >                 static_branch_inc(&cgroup_bpf_enabled_key[atype]);
> > > >         bpf_cgroup_storages_link(new_storage, cgrp, type);
> > > > +
> > > > +       cgroup_name(cgrp, cgrp_path + strlen("cgroup:"), 64);
> > > > +       cgrp_path[63] = '\0';
> > > > +       prog->aux->attach_name = kstrdup(cgrp_path, GFP_KERNEL);
> > > > +
> > >
> > > This is pure debug code. We cannot have it in the kernel.
> > > Not even under #ifdef.
> > >
> > > Please do such debug code on a side as your own bpf program.
> > > For example by kprobe-ing in this function and keeping the path
> > > in a bpf map or send it to user space via ringbuf.
> > > Or enable cgroup tracepoint and monitor cgroup_mkdir with full path.
> > > Record it in user space or in bpf map, etc.
> > >
> >
> > It is another possible solution to  hook the related kernel functions
> > or tracepoints, but it may be a little complicated to track all the
> > bpf attach types, for example we also want to track
> > BPF_PROG_TYPE_SK_MSG[1], BPF_PROG_TYPE_FLOW_DISSECTOR and etc.
> > While the attach_name provides us a generic way to get how the bpf
> > progs are attached, which can't be got by bpftool.
>
> bpftool can certainly print such details.
> See how it's using task_file iterator.
> It can be extended to look into cgroups and sockmap,
> and for each program print "sockmap:%d", map->id if so desired.

Thanks for the explanation. I will analyze it.
Yafang Shao Feb. 21, 2022, 2:26 p.m. UTC | #5
On Mon, Feb 21, 2022 at 4:59 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Sun, Feb 20, 2022 at 6:17 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > On Sun, Feb 20, 2022 at 2:27 AM Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > >
> > > On Fri, Feb 18, 2022 at 1:56 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > >
> > > > Set the cgroup path when a bpf prog is attached to a cgroup, and unset
> > > > it when the bpf prog is detached.
> > > >
> > > > Below is the result after this change,
> > > > $ cat progs.debug
> > > >   id name             attached
> > > >    5 dump_bpf_map     bpf_iter_bpf_map
> > > >    7 dump_bpf_prog    bpf_iter_bpf_prog
> > > >   17 bpf_sockmap      cgroup:/
> > > >   19 bpf_redir_proxy
> > > >
> > > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > > ---
> > > >  kernel/bpf/cgroup.c | 8 ++++++++
> > > >  1 file changed, 8 insertions(+)
> > > >
> > > > diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> > > > index 43eb3501721b..ebd87e54f2d0 100644
> > > > --- a/kernel/bpf/cgroup.c
> > > > +++ b/kernel/bpf/cgroup.c
> > > > @@ -440,6 +440,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > > >         struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > > >         struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > > >         enum cgroup_bpf_attach_type atype;
> > > > +       char cgrp_path[64] = "cgroup:";
> > > >         struct bpf_prog_list *pl;
> > > >         struct list_head *progs;
> > > >         int err;
> > > > @@ -508,6 +509,11 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > > >         else
> > > >                 static_branch_inc(&cgroup_bpf_enabled_key[atype]);
> > > >         bpf_cgroup_storages_link(new_storage, cgrp, type);
> > > > +
> > > > +       cgroup_name(cgrp, cgrp_path + strlen("cgroup:"), 64);
> > > > +       cgrp_path[63] = '\0';
> > > > +       prog->aux->attach_name = kstrdup(cgrp_path, GFP_KERNEL);
> > > > +
> > >
> > > This is pure debug code. We cannot have it in the kernel.
> > > Not even under #ifdef.
> > >
> > > Please do such debug code on a side as your own bpf program.
> > > For example by kprobe-ing in this function and keeping the path
> > > in a bpf map or send it to user space via ringbuf.
> > > Or enable cgroup tracepoint and monitor cgroup_mkdir with full path.
> > > Record it in user space or in bpf map, etc.
> > >
> >
> > It is another possible solution to  hook the related kernel functions
> > or tracepoints, but it may be a little complicated to track all the
> > bpf attach types, for example we also want to track
> > BPF_PROG_TYPE_SK_MSG[1], BPF_PROG_TYPE_FLOW_DISSECTOR and etc.
> > While the attach_name provides us a generic way to get how the bpf
> > progs are attached, which can't be got by bpftool.
>
> bpftool can certainly print such details.
> See how it's using task_file iterator.
> It can be extended to look into cgroups and sockmap,
> and for each program print "sockmap:%d", map->id if so desired.

I have read through the task_file code, but I haven't found a direct
way to get the attached cgroups or maps of a specified prog.
It is easy to look into a cgroup or sockmap, but the key point here is
which is the proper cgroup or sockmap.
There are some possible ways to get the attached cgroup or sockmap.

- add new member into struct bpf_prog_aux
   For example,
    struct bpf_prog_aux{
        union {
            struct cgroup *attached_cgrp;
            struct bpf_map *attached_map;
        };
    };
    Then we can easily get the related map or cgroup by extending
task_file iterator.

- build a table for attached maps, cgroups and etc
   Like we did for pinned files.
   Then we can compare the prog with the members stored in this table
one by one, but that seems a little heavy.

There may be some other ways.
I'm not sure if I clearly understand what you mean.
Hopefully you could help clarify it.
Alexei Starovoitov Feb. 22, 2022, 4:30 a.m. UTC | #6
On Mon, Feb 21, 2022 at 6:26 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> On Mon, Feb 21, 2022 at 4:59 AM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Sun, Feb 20, 2022 at 6:17 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > >
> > > On Sun, Feb 20, 2022 at 2:27 AM Alexei Starovoitov
> > > <alexei.starovoitov@gmail.com> wrote:
> > > >
> > > > On Fri, Feb 18, 2022 at 1:56 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > > >
> > > > > Set the cgroup path when a bpf prog is attached to a cgroup, and unset
> > > > > it when the bpf prog is detached.
> > > > >
> > > > > Below is the result after this change,
> > > > > $ cat progs.debug
> > > > >   id name             attached
> > > > >    5 dump_bpf_map     bpf_iter_bpf_map
> > > > >    7 dump_bpf_prog    bpf_iter_bpf_prog
> > > > >   17 bpf_sockmap      cgroup:/
> > > > >   19 bpf_redir_proxy
> > > > >
> > > > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > > > ---
> > > > >  kernel/bpf/cgroup.c | 8 ++++++++
> > > > >  1 file changed, 8 insertions(+)
> > > > >
> > > > > diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> > > > > index 43eb3501721b..ebd87e54f2d0 100644
> > > > > --- a/kernel/bpf/cgroup.c
> > > > > +++ b/kernel/bpf/cgroup.c
> > > > > @@ -440,6 +440,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > > > >         struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > > > >         struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > > > >         enum cgroup_bpf_attach_type atype;
> > > > > +       char cgrp_path[64] = "cgroup:";
> > > > >         struct bpf_prog_list *pl;
> > > > >         struct list_head *progs;
> > > > >         int err;
> > > > > @@ -508,6 +509,11 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > > > >         else
> > > > >                 static_branch_inc(&cgroup_bpf_enabled_key[atype]);
> > > > >         bpf_cgroup_storages_link(new_storage, cgrp, type);
> > > > > +
> > > > > +       cgroup_name(cgrp, cgrp_path + strlen("cgroup:"), 64);
> > > > > +       cgrp_path[63] = '\0';
> > > > > +       prog->aux->attach_name = kstrdup(cgrp_path, GFP_KERNEL);
> > > > > +
> > > >
> > > > This is pure debug code. We cannot have it in the kernel.
> > > > Not even under #ifdef.
> > > >
> > > > Please do such debug code on a side as your own bpf program.
> > > > For example by kprobe-ing in this function and keeping the path
> > > > in a bpf map or send it to user space via ringbuf.
> > > > Or enable cgroup tracepoint and monitor cgroup_mkdir with full path.
> > > > Record it in user space or in bpf map, etc.
> > > >
> > >
> > > It is another possible solution to  hook the related kernel functions
> > > or tracepoints, but it may be a little complicated to track all the
> > > bpf attach types, for example we also want to track
> > > BPF_PROG_TYPE_SK_MSG[1], BPF_PROG_TYPE_FLOW_DISSECTOR and etc.
> > > While the attach_name provides us a generic way to get how the bpf
> > > progs are attached, which can't be got by bpftool.
> >
> > bpftool can certainly print such details.
> > See how it's using task_file iterator.
> > It can be extended to look into cgroups and sockmap,
> > and for each program print "sockmap:%d", map->id if so desired.
>
> I have read through the task_file code, but I haven't found a direct
> way to get the attached cgroups or maps of a specified prog.
> It is easy to look into a cgroup or sockmap, but the key point here is
> which is the proper cgroup or sockmap.
> There are some possible ways to get the attached cgroup or sockmap.
>
> - add new member into struct bpf_prog_aux

No. Please stop proposing kernel changes for your debug needs.

>    For example,
>     struct bpf_prog_aux{
>         union {
>             struct cgroup *attached_cgrp;
>             struct bpf_map *attached_map;
>         };
>     };
>     Then we can easily get the related map or cgroup by extending
> task_file iterator.
>
> - build a table for attached maps, cgroups and etc
>    Like we did for pinned files.
>    Then we can compare the prog with the members stored in this table
> one by one, but that seems a little heavy.
>
> There may be some other ways.

- iterate bpf maps
- find sockmap
- do equivalent of sock_map_progs(), but open coded inside bpf prog
- read progs, print them.
Yafang Shao Feb. 22, 2022, 8:34 a.m. UTC | #7
On Tue, Feb 22, 2022 at 12:30 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Mon, Feb 21, 2022 at 6:26 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > On Mon, Feb 21, 2022 at 4:59 AM Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > >
> > > On Sun, Feb 20, 2022 at 6:17 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > >
> > > > On Sun, Feb 20, 2022 at 2:27 AM Alexei Starovoitov
> > > > <alexei.starovoitov@gmail.com> wrote:
> > > > >
> > > > > On Fri, Feb 18, 2022 at 1:56 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > > > >
> > > > > > Set the cgroup path when a bpf prog is attached to a cgroup, and unset
> > > > > > it when the bpf prog is detached.
> > > > > >
> > > > > > Below is the result after this change,
> > > > > > $ cat progs.debug
> > > > > >   id name             attached
> > > > > >    5 dump_bpf_map     bpf_iter_bpf_map
> > > > > >    7 dump_bpf_prog    bpf_iter_bpf_prog
> > > > > >   17 bpf_sockmap      cgroup:/
> > > > > >   19 bpf_redir_proxy
> > > > > >
> > > > > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > > > > ---
> > > > > >  kernel/bpf/cgroup.c | 8 ++++++++
> > > > > >  1 file changed, 8 insertions(+)
> > > > > >
> > > > > > diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
> > > > > > index 43eb3501721b..ebd87e54f2d0 100644
> > > > > > --- a/kernel/bpf/cgroup.c
> > > > > > +++ b/kernel/bpf/cgroup.c
> > > > > > @@ -440,6 +440,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > > > > >         struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > > > > >         struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
> > > > > >         enum cgroup_bpf_attach_type atype;
> > > > > > +       char cgrp_path[64] = "cgroup:";
> > > > > >         struct bpf_prog_list *pl;
> > > > > >         struct list_head *progs;
> > > > > >         int err;
> > > > > > @@ -508,6 +509,11 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
> > > > > >         else
> > > > > >                 static_branch_inc(&cgroup_bpf_enabled_key[atype]);
> > > > > >         bpf_cgroup_storages_link(new_storage, cgrp, type);
> > > > > > +
> > > > > > +       cgroup_name(cgrp, cgrp_path + strlen("cgroup:"), 64);
> > > > > > +       cgrp_path[63] = '\0';
> > > > > > +       prog->aux->attach_name = kstrdup(cgrp_path, GFP_KERNEL);
> > > > > > +
> > > > >
> > > > > This is pure debug code. We cannot have it in the kernel.
> > > > > Not even under #ifdef.
> > > > >
> > > > > Please do such debug code on a side as your own bpf program.
> > > > > For example by kprobe-ing in this function and keeping the path
> > > > > in a bpf map or send it to user space via ringbuf.
> > > > > Or enable cgroup tracepoint and monitor cgroup_mkdir with full path.
> > > > > Record it in user space or in bpf map, etc.
> > > > >
> > > >
> > > > It is another possible solution to  hook the related kernel functions
> > > > or tracepoints, but it may be a little complicated to track all the
> > > > bpf attach types, for example we also want to track
> > > > BPF_PROG_TYPE_SK_MSG[1], BPF_PROG_TYPE_FLOW_DISSECTOR and etc.
> > > > While the attach_name provides us a generic way to get how the bpf
> > > > progs are attached, which can't be got by bpftool.
> > >
> > > bpftool can certainly print such details.
> > > See how it's using task_file iterator.
> > > It can be extended to look into cgroups and sockmap,
> > > and for each program print "sockmap:%d", map->id if so desired.
> >
> > I have read through the task_file code, but I haven't found a direct
> > way to get the attached cgroups or maps of a specified prog.
> > It is easy to look into a cgroup or sockmap, but the key point here is
> > which is the proper cgroup or sockmap.
> > There are some possible ways to get the attached cgroup or sockmap.
> >
> > - add new member into struct bpf_prog_aux
>
> No. Please stop proposing kernel changes for your debug needs.
>
> >    For example,
> >     struct bpf_prog_aux{
> >         union {
> >             struct cgroup *attached_cgrp;
> >             struct bpf_map *attached_map;
> >         };
> >     };
> >     Then we can easily get the related map or cgroup by extending
> > task_file iterator.
> >
> > - build a table for attached maps, cgroups and etc
> >    Like we did for pinned files.
> >    Then we can compare the prog with the members stored in this table
> > one by one, but that seems a little heavy.
> >
> > There may be some other ways.
>
> - iterate bpf maps
> - find sockmap
> - do equivalent of sock_map_progs(), but open coded inside bpf prog
> - read progs, print them.

That's similar to the second  way I proposed above.
The trouble is it may be too heavy to iterate the target objects, for
example, there may be thousands of cgroups on a single host, and if we
want to know which cgroup is attached by a bpf prog we have to iterate
all the cgroups until find it.
But it seems there is no better choice.
Anyway thanks for the advice.
diff mbox series

Patch

diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 43eb3501721b..ebd87e54f2d0 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -440,6 +440,7 @@  static int __cgroup_bpf_attach(struct cgroup *cgrp,
 	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
 	struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
 	enum cgroup_bpf_attach_type atype;
+	char cgrp_path[64] = "cgroup:";
 	struct bpf_prog_list *pl;
 	struct list_head *progs;
 	int err;
@@ -508,6 +509,11 @@  static int __cgroup_bpf_attach(struct cgroup *cgrp,
 	else
 		static_branch_inc(&cgroup_bpf_enabled_key[atype]);
 	bpf_cgroup_storages_link(new_storage, cgrp, type);
+
+	cgroup_name(cgrp, cgrp_path + strlen("cgroup:"), 64);
+	cgrp_path[63] = '\0';
+	prog->aux->attach_name = kstrdup(cgrp_path, GFP_KERNEL);
+
 	return 0;
 
 cleanup:
@@ -735,6 +741,8 @@  static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
 	if (old_prog)
 		bpf_prog_put(old_prog);
 	static_branch_dec(&cgroup_bpf_enabled_key[atype]);
+	kfree(prog->aux->attach_name);
+
 	return 0;
 
 cleanup: