From bc8083680c0e84cc980f90ce111c83324a8f645c Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Wed, 27 Sep 2023 01:12:16 +0900 Subject: [PATCH] lsfd: add BPF.NAME column MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit An example output: $ sudo ./lsfd -oCOMMAND,PID,ASSOC,TYPE,BPF.NAME,NAME -Q '(TYPE =~ "bpf-*")' -p 1 COMMAND PID ASSOC TYPE BPF.NAME NAME systemd 1 9 bpf_link anon_inode:bpf_link systemd 1 13 bpf-map cgroup_hash id=391 type=hash-of-maps name=cgroup_hash systemd 1 14 bpf-prog restrict_filesy id=8210 type=lsm name=restrict_filesy systemd 1 28 bpf-prog sd_devices id=8298 type=cgroup_device name=sd_devices systemd 1 29 bpf-prog sd_devices id=8299 type=cgroup_device name=sd_devices systemd 1 30 bpf-prog sd_devices id=8300 type=cgroup_device name=sd_devices ... Using memset was suggested by Thomas Weißschuh . Signed-off-by: Masatake YAMATO --- misc-utils/lsfd-unkn.c | 79 ++++++++++++++++++++++++++++++++++++++++++ misc-utils/lsfd.c | 3 ++ misc-utils/lsfd.h | 1 + 3 files changed, 83 insertions(+) diff --git a/misc-utils/lsfd-unkn.c b/misc-utils/lsfd-unkn.c index 4d68f40104..3b9902f58c 100644 --- a/misc-utils/lsfd-unkn.c +++ b/misc-utils/lsfd-unkn.c @@ -19,6 +19,9 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include +#include +#include #include #include @@ -27,6 +30,9 @@ #include "lsfd.h" +#define offsetofend(TYPE, MEMBER) \ + (offsetof(TYPE, MEMBER) + sizeof_member(TYPE, MEMBER)) + struct unkn { struct file file; const struct anon_ops *anon_ops; @@ -1021,6 +1027,7 @@ static const char *bpf_prog_type_table[] = { struct anon_bpf_prog_data { int type; int id; + char name[BPF_OBJ_NAME_LEN + 1]; }; static bool anon_bpf_prog_probe(const char *str) @@ -1059,6 +1066,9 @@ static bool anon_bpf_prog_fill_column(struct proc *proc __attribute__((__unused else xasprintf(str, "UNKNOWN(%d)", data->type); return true; + case COL_BPF_NAME: + *str = xstrdup(data->name); + return true; default: return false; } @@ -1076,6 +1086,9 @@ static char *anon_bpf_prog_get_name(struct unkn *unkn) else xasprintf(&str, "id=%d type=UNKNOWN(%d)", data->id, data->type); + if (*data->name) + xstrfappend(&str, " name=%s", data->name); + return str; } @@ -1085,6 +1098,7 @@ static void anon_bpf_prog_init(struct unkn *unkn) struct anon_bpf_prog_data *data = xmalloc(sizeof(*data)); data->type = -1; data->id = -1; + data->name[0] = '\0'; unkn->anon_data = data; } @@ -1094,6 +1108,33 @@ static void anon_bpf_prog_free(struct unkn *unkn) free(data); } +static void anon_bpf_prog_get_more_info(struct anon_bpf_prog_data *prog_data) +{ + union bpf_attr attr = { + .prog_id = (int32_t)prog_data->id, + .next_id = 0, + .open_flags = 0, + }; + struct bpf_prog_info info = { 0 }; + union bpf_attr info_attr = { + .info.info_len = sizeof(info), + .info.info = (uint64_t)(uintptr_t)&info, + }; + + int bpf_fd = syscall(SYS_bpf, BPF_PROG_GET_FD_BY_ID, &attr, sizeof(attr)); + if (bpf_fd < 0) + return; + + info_attr.info.bpf_fd = bpf_fd; + if (syscall(SYS_bpf, BPF_OBJ_GET_INFO_BY_FD, &info_attr, offsetofend(union bpf_attr, info)) == 0) { + memcpy(prog_data->name, + info.name, + BPF_OBJ_NAME_LEN); + prog_data->name[BPF_OBJ_NAME_LEN] = '\0'; + } + close (bpf_fd); +} + static int anon_bpf_prog_handle_fdinfo(struct unkn *unkn, const char *key, const char *value) { if (strcmp(key, "prog_id") == 0) { @@ -1102,6 +1143,7 @@ static int anon_bpf_prog_handle_fdinfo(struct unkn *unkn, const char *key, const if (rc < 0) return 0; /* ignore -- parse failed */ ((struct anon_bpf_prog_data *)unkn->anon_data)->id = (int)t; + anon_bpf_prog_get_more_info((struct anon_bpf_prog_data *)unkn->anon_data); return 1; } @@ -1169,6 +1211,7 @@ static const char *bpf_map_type_table[] = { struct anon_bpf_map_data { int type; int id; + char name[BPF_OBJ_NAME_LEN + 1]; }; static bool anon_bpf_map_probe(const char *str) @@ -1207,6 +1250,9 @@ static bool anon_bpf_map_fill_column(struct proc *proc __attribute__((__unused_ else xasprintf(str, "UNKNOWN(%d)", data->type); return true; + case COL_BPF_NAME: + *str = xstrdup(data->name); + return true; default: return false; } @@ -1223,6 +1269,10 @@ static char *anon_bpf_map_get_name(struct unkn *unkn) xasprintf(&str, "id=%d type=%s", data->id, t); else xasprintf(&str, "id=%d type=UNKNOWN(%d)", data->id, data->type); + + if (*data->name) + xstrfappend(&str, " name=%s", data->name); + return str; } @@ -1231,6 +1281,7 @@ static void anon_bpf_map_init(struct unkn *unkn) struct anon_bpf_map_data *data = xmalloc(sizeof(*data)); data->type = -1; data->id = -1; + data->name[0] = '\0'; unkn->anon_data = data; } @@ -1240,6 +1291,33 @@ static void anon_bpf_map_free(struct unkn *unkn) free(data); } +static void anon_bpf_map_get_more_info(struct anon_bpf_map_data *map_data) +{ + union bpf_attr attr = { + .map_id = (int32_t)map_data->id, + .next_id = 0, + .open_flags = 0, + }; + struct bpf_map_info info = { 0 }; + union bpf_attr info_attr = { + .info.info_len = sizeof(info), + .info.info = (uint64_t)(uintptr_t)&info, + }; + + int bpf_fd = syscall(SYS_bpf, BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr)); + if (bpf_fd < 0) + return; + + info_attr.info.bpf_fd = bpf_fd; + if (syscall(SYS_bpf, BPF_OBJ_GET_INFO_BY_FD, &info_attr, offsetofend(union bpf_attr, info)) == 0) { + memcpy(map_data->name, + info.name, + BPF_OBJ_NAME_LEN); + map_data->name[BPF_OBJ_NAME_LEN] = '\0'; + } + close (bpf_fd); +} + static int anon_bpf_map_handle_fdinfo(struct unkn *unkn, const char *key, const char *value) { if (strcmp(key, "map_id") == 0) { @@ -1248,6 +1326,7 @@ static int anon_bpf_map_handle_fdinfo(struct unkn *unkn, const char *key, const if (rc < 0) return 0; /* ignore -- parse failed */ ((struct anon_bpf_map_data *)unkn->anon_data)->id = (int)t; + anon_bpf_map_get_more_info((struct anon_bpf_map_data *)unkn->anon_data); return 1; } diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index d6bd6e971e..7d1d381fd8 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -137,6 +137,9 @@ static const struct colinfo infos[] = { [COL_BPF_MAP_TYPE_RAW]= { "BPF-MAP.TYPE.RAW", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("bpf map type (raw)") }, + [COL_BPF_NAME] = { "BPF.NAME", + 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("bpf object name") }, [COL_BPF_PROG_ID] = { "BPF-PROG.ID", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("bpf program id associated with the fd") }, diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index 8cddc59ef2..9cf87f8308 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -46,6 +46,7 @@ enum { COL_BPF_MAP_ID, COL_BPF_MAP_TYPE, COL_BPF_MAP_TYPE_RAW, + COL_BPF_NAME, COL_BPF_PROG_ID, COL_BPF_PROG_TYPE, COL_BPF_PROG_TYPE_RAW, -- 2.47.2