Implement cgdetach command, which allows to detach the bpf program from a cgroup. It takes program id and attach type as arguments.
Example: $ ./bpftool cgdetach /sys/fs/cgroup/user.slice/ device 1 Signed-off-by: Roman Gushchin <g...@fb.com> Cc: Alexei Starovoitov <a...@kernel.org> Cc: Daniel Borkmann <dan...@iogearbox.net> Cc: Jakub Kicinski <jakub.kicin...@netronome.com> Cc: Martin KaFai Lau <ka...@fb.com> --- tools/bpf/bpftool/main.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index 8eb3b9bf5bb2..77fcc1a0bd5d 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -81,12 +81,13 @@ static int do_help(int argc, char **argv) "Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n" " %s batch file FILE\n" " %s cgattach FILE CGROUP TYPE\n" + " %s cgdetach CGROUP TYPE ID\n" " %s version\n" "\n" " OBJECT := { prog | map }\n" " " HELP_SPEC_OPTIONS "\n" "", - bin_name, bin_name, bin_name, bin_name); + bin_name, bin_name, bin_name, bin_name, bin_name); return 0; } @@ -166,6 +167,7 @@ void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep) static int do_batch(int argc, char **argv); static int do_cgattach(int argc, char **argv); +static int do_cgdetach(int argc, char **argv); static const struct cmd cmds[] = { { "help", do_help }, @@ -173,6 +175,7 @@ static const struct cmd cmds[] = { { "prog", do_prog }, { "map", do_map }, { "cgattach", do_cgattach }, + { "cgdetach", do_cgdetach }, { "version", do_version }, { 0 } }; @@ -338,6 +341,51 @@ static int do_cgattach(int argc, char **argv) return 0; } +static int do_cgdetach(int argc, char **argv) +{ + int prog_fd, cgroup_fd; + enum bpf_attach_type attach_type; + + if (argc < 3) { + p_err("too few parameters for cgdetach\n"); + return -1; + } else if (argc > 3) { + p_err("too many parameters for cgdetach\n"); + return -1; + } + + cgroup_fd = open(argv[0], O_RDONLY); + if (cgroup_fd < 0) { + p_err("can't open cgroup %s\n", argv[1]); + return -1; + } + + attach_type = parse_attach_type(argv[1]); + if (attach_type == __MAX_BPF_ATTACH_TYPE) { + close(cgroup_fd); + p_err("Invalid attach type"); + return -1; + } + + prog_fd = bpf_prog_get_fd_by_id(atoi(argv[2])); + if (prog_fd < 0) { + p_err("invalid program id\n"); + return -1; + } + + if (bpf_prog_detach2(prog_fd, cgroup_fd, attach_type)) { + close(prog_fd); + close(cgroup_fd); + p_err("Failed to attach program"); + return -1; + } + + close(prog_fd); + close(cgroup_fd); + + return 0; +} + int main(int argc, char **argv) { static const struct option options[] = { -- 2.14.3