From: Masatake YAMATO Date: Tue, 11 Jul 2023 13:12:05 +0000 (+0900) Subject: lsfd: add BPF-MAP.TYPE, BPF-MAP.TYPE.RAW, and BPF-MAP.ID columns X-Git-Tag: v2.40-rc1~240 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ea9466d469f3573f840d5558129f063d3db80d2e;p=thirdparty%2Futil-linux.git lsfd: add BPF-MAP.TYPE, BPF-MAP.TYPE.RAW, and BPF-MAP.ID columns Based on these new columns, the NAME column for "bpf-map" is enhanced. An example output: # ./lsfd -p 1 -Q '(TYPE == "bpf-map")' | head COMMAND PID USER ASSOC XMODE TYPE SOURCE MNTID INODE NAME systemd 1 root 13 rw---- bpf-map anon_inodefs 15 106 id=305 type=hash-of-maps Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-unkn.c b/misc-utils/lsfd-unkn.c index 9cfd2bfa57..4d68f40104 100644 --- a/misc-utils/lsfd-unkn.c +++ b/misc-utils/lsfd-unkn.c @@ -1127,6 +1127,152 @@ static const struct anon_ops anon_bpf_prog_ops = { .handle_fdinfo = anon_bpf_prog_handle_fdinfo, }; +/* + * bpf-map + */ +static const char *bpf_map_type_table[] = { + [0] = "unspec", /* BPF_MAP_TYPE_UNSPEC */ + [1] = "hash", /* BPF_MAP_TYPE_HASH */ + [2] = "array", /* BPF_MAP_TYPE_ARRAY */ + [3] = "prog-array", /* BPF_MAP_TYPE_PROG_ARRAY */ + [4] = "perf-event-array", /* BPF_MAP_TYPE_PERF_EVENT_ARRAY */ + [5] = "percpu-hash", /* BPF_MAP_TYPE_PERCPU_HASH */ + [6] = "percpu-array", /* BPF_MAP_TYPE_PERCPU_ARRAY */ + [7] = "stack-trace", /* BPF_MAP_TYPE_STACK_TRACE */ + [8] = "cgroup-array", /* BPF_MAP_TYPE_CGROUP_ARRAY */ + [9] = "lru-hash", /* BPF_MAP_TYPE_LRU_HASH */ + [10] = "lru-percpu-hash", /* BPF_MAP_TYPE_LRU_PERCPU_HASH */ + [11] = "lpm-trie", /* BPF_MAP_TYPE_LPM_TRIE */ + [12] = "array-of-maps", /* BPF_MAP_TYPE_ARRAY_OF_MAPS */ + [13] = "hash-of-maps", /* BPF_MAP_TYPE_HASH_OF_MAPS */ + [14] = "devmap", /* BPF_MAP_TYPE_DEVMAP */ + [15] = "sockmap", /* BPF_MAP_TYPE_SOCKMAP */ + [16] = "cpumap", /* BPF_MAP_TYPE_CPUMAP */ + [17] = "xskmap", /* BPF_MAP_TYPE_XSKMAP */ + [18] = "sockhash", /* BPF_MAP_TYPE_SOCKHASH */ + [19] = "cgroup-storage", /* BPF_MAP_TYPE_CGROUP_STORAGE */ + [20] = "reuseport-sockarray", /* BPF_MAP_TYPE_REUSEPORT_SOCKARRAY */ + [21] = "percpu-cgroup-storage", /* BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE */ + [22] = "queue", /* BPF_MAP_TYPE_QUEUE */ + [23] = "stack", /* BPF_MAP_TYPE_STACK */ + [24] = "sk-storage", /* BPF_MAP_TYPE_SK_STORAGE */ + [25] = "devmap-hash", /* BPF_MAP_TYPE_DEVMAP_HASH */ + [26] = "struct-ops", /* BPF_MAP_TYPE_STRUCT_OPS */ + [27] = "ringbuf", /* BPF_MAP_TYPE_RINGBUF */ + [28] = "inode-storage", /* BPF_MAP_TYPE_INODE_STORAGE */ + [29] = "task-storage", /* BPF_MAP_TYPE_TASK_STORAGE */ + [30] = "bloom-filter", /* BPF_MAP_TYPE_BLOOM_FILTER */ + [31] = "user-ringbuf", /* BPF_MAP_TYPE_USER_RINGBUF */ + [32] = "cgrp-storage", /* BPF_MAP_TYPE_CGRP_STORAGE */ +}; + +struct anon_bpf_map_data { + int type; + int id; +}; + +static bool anon_bpf_map_probe(const char *str) +{ + return strncmp(str, "bpf-map", 8) == 0; +} + +static const char *anon_bpf_map_get_map_type_name(int type) +{ + if (0 <= type && type < (int)ARRAY_SIZE(bpf_map_type_table)) + return bpf_map_type_table[type]; + return NULL; +} + +static bool anon_bpf_map_fill_column(struct proc *proc __attribute__((__unused__)), + struct unkn *unkn, + struct libscols_line *ln __attribute__((__unused__)), + int column_id, + size_t column_index __attribute__((__unused__)), + char **str) +{ + struct anon_bpf_prog_data *data = (struct anon_bpf_prog_data *)unkn->anon_data; + const char *t; + + switch(column_id) { + case COL_BPF_MAP_ID: + xasprintf(str, "%d", data->id); + return true; + case COL_BPF_MAP_TYPE_RAW: + xasprintf(str, "%d", data->type); + return true; + case COL_BPF_MAP_TYPE: + t = anon_bpf_map_get_map_type_name(data->type); + if (t) + *str = xstrdup(t); + else + xasprintf(str, "UNKNOWN(%d)", data->type); + return true; + default: + return false; + } +} + +static char *anon_bpf_map_get_name(struct unkn *unkn) +{ + const char *t; + char *str = NULL; + struct anon_bpf_map_data *data = (struct anon_bpf_map_data *)unkn->anon_data; + + t = anon_bpf_map_get_map_type_name(data->type); + if (t) + xasprintf(&str, "id=%d type=%s", data->id, t); + else + xasprintf(&str, "id=%d type=UNKNOWN(%d)", data->id, data->type); + return str; +} + +static void anon_bpf_map_init(struct unkn *unkn) +{ + struct anon_bpf_map_data *data = xmalloc(sizeof(*data)); + data->type = -1; + data->id = -1; + unkn->anon_data = data; +} + +static void anon_bpf_map_free(struct unkn *unkn) +{ + struct anon_bpf_map_data *data = (struct anon_bpf_map_data *)unkn->anon_data; + free(data); +} + +static int anon_bpf_map_handle_fdinfo(struct unkn *unkn, const char *key, const char *value) +{ + if (strcmp(key, "map_id") == 0) { + int32_t t = -1; + int rc = ul_strtos32(value, &t, 10); + if (rc < 0) + return 0; /* ignore -- parse failed */ + ((struct anon_bpf_map_data *)unkn->anon_data)->id = (int)t; + return 1; + } + + if (strcmp(key, "map_type") == 0) { + int32_t t = -1; + int rc = ul_strtos32(value, &t, 10); + if (rc < 0) + return 0; /* ignore -- parse failed */ + ((struct anon_bpf_map_data *)unkn->anon_data)->type = (int)t; + return 1; + } + + return 0; +} + +static const struct anon_ops anon_bpf_map_ops = { + .class = "bpf-map", + .probe = anon_bpf_map_probe, + .get_name = anon_bpf_map_get_name, + .fill_column = anon_bpf_map_fill_column, + .init = anon_bpf_map_init, + .free = anon_bpf_map_free, + .handle_fdinfo = anon_bpf_map_handle_fdinfo, +}; + /* * generic (fallback implementation) */ @@ -1147,6 +1293,7 @@ static const struct anon_ops *anon_ops[] = { &anon_signalfd_ops, &anon_inotify_ops, &anon_bpf_prog_ops, + &anon_bpf_map_ops, }; static const struct anon_ops *anon_probe(const char *str) diff --git a/misc-utils/lsfd.1.adoc b/misc-utils/lsfd.1.adoc index d023801080..d3c993777b 100644 --- a/misc-utils/lsfd.1.adoc +++ b/misc-utils/lsfd.1.adoc @@ -132,6 +132,15 @@ Association between file and process. BLKDRV <``string``>:: Block device driver name resolved by `/proc/devices`. +BPF-MAP.ID <``number``>:: +Bpf map ID. + +BPF-MAP.TYPE <``string``>:: +Decoded name of bpf map type. + +BPF-MAP.TYPE.RAW <``number``>:: +Bpf map type (raw). + BPF-PROG.ID <``number``>:: Bpf program ID. @@ -250,6 +259,9 @@ Cooked version of KNAME. It is mostly same as KNAME. + Some files have special formats and information sources: + +bpf-map::: +id=_BPF-MAP.ID_ type=_BPF-MAP.TYPE_ ++ bpf-prog::: id=_BPF-PROG.ID_ type=_BPF-PROG.TYPE_ + diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index 0aaf18f12f..39b50d8f10 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -128,6 +128,15 @@ static const struct colinfo infos[] = { [COL_BLKDRV] = { "BLKDRV", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("block device driver name resolved by /proc/devices") }, + [COL_BPF_MAP_ID] = { "BPF-MAP.ID", + 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, + N_("bpf map id associated with the fd") }, + [COL_BPF_MAP_TYPE] = { "BPF-MAP.TYPE", + 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("bpf map type (decoded)") }, + [COL_BPF_MAP_TYPE_RAW]= { "BPF-MAP.TYPE.RAW", + 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, + N_("bpf map type (raw)") }, [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 a7396bddfd..7a5034e255 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -43,6 +43,9 @@ enum { COL_AINODECLASS, COL_ASSOC, COL_BLKDRV, + COL_BPF_MAP_ID, + COL_BPF_MAP_TYPE, + COL_BPF_MAP_TYPE_RAW, COL_BPF_PROG_ID, COL_BPF_PROG_TYPE, COL_BPF_PROG_TYPE_RAW,