tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects. For example: root@test# ./bpftool prog 3: tracepoint name tracepoint__irq tag f677a7dd722299a3 loaded_at Oct 26/11:39 uid 0 xlated 160B not jited memlock 4096B map_ids 4 pinned /sys/fs/bpf/softirq_prog 4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6 loaded_at Oct 26/11:39 uid 0 xlated 392B not jited memlock 4096B map_ids 4,6 root@test# ./bpftool --json --pretty prog [{ "id": 3, "type": "tracepoint", "name": "tracepoint__irq", "tag": "f677a7dd722299a3", "loaded_at": "Oct 26/11:39", "uid": 0, "bytes_xlated": 160, "jited": false, "bytes_memlock": 4096, "map_ids": [4 ], "pinned": ["/sys/fs/bpf/softirq_prog" ] },{ "id": 4, "type": "tracepoint", "name": "tracepoint__irq", "tag": "ea5dc530d00b92b6", "loaded_at": "Oct 26/11:39", "uid": 0, "bytes_xlated": 392, "jited": false, "bytes_memlock": 4096, "map_ids": [4,6 ], "pinned": [] } ] root@test# ./bpftool map 4: hash name start flags 0x0 key 4B value 16B max_entries 10240 memlock 1003520B pinned /sys/fs/bpf/softirq_map1 5: hash name iptr flags 0x0 key 4B value 8B max_entries 10240 memlock 921600B root@test# ./bpftool --json --pretty map [{ "id": 4, "type": "hash", "name": "start", "flags": 0, "bytes_key": 4, "bytes_value": 16, "max_entries": 10240, "bytes_memlock": 1003520, "pinned": ["/sys/fs/bpf/softirq_map1" ] },{ "id": 5, "type": "hash", "name": "iptr", "flags": 0, "bytes_key": 4, "bytes_value": 8, "max_entries": 10240, "bytes_memlock": 921600, "pinned": [] } ] Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
1852719658
Коммит
4990f1f461
|
@ -34,7 +34,9 @@
|
|||
/* Author: Jakub Kicinski <kubakici@wp.pl> */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fts.h>
|
||||
#include <libgen.h>
|
||||
#include <mntent.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -321,3 +323,83 @@ void print_hex_data_json(uint8_t *data, size_t len)
|
|||
jsonw_printf(json_wtr, "\"0x%02hhx\"", data[i]);
|
||||
jsonw_end_array(json_wtr);
|
||||
}
|
||||
|
||||
int build_pinned_obj_table(struct pinned_obj_table *tab,
|
||||
enum bpf_obj_type type)
|
||||
{
|
||||
struct bpf_prog_info pinned_info = {};
|
||||
struct pinned_obj *obj_node = NULL;
|
||||
__u32 len = sizeof(pinned_info);
|
||||
struct mntent *mntent = NULL;
|
||||
enum bpf_obj_type objtype;
|
||||
FILE *mntfile = NULL;
|
||||
FTSENT *ftse = NULL;
|
||||
FTS *fts = NULL;
|
||||
int fd, err;
|
||||
|
||||
mntfile = setmntent("/proc/mounts", "r");
|
||||
if (!mntfile)
|
||||
return -1;
|
||||
|
||||
while ((mntent = getmntent(mntfile))) {
|
||||
char *path[] = { mntent->mnt_dir, NULL };
|
||||
|
||||
if (strncmp(mntent->mnt_type, "bpf", 3) != 0)
|
||||
continue;
|
||||
|
||||
fts = fts_open(path, 0, NULL);
|
||||
if (!fts)
|
||||
continue;
|
||||
|
||||
while ((ftse = fts_read(fts))) {
|
||||
if (!(ftse->fts_info & FTS_F))
|
||||
continue;
|
||||
fd = open_obj_pinned(ftse->fts_path);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
objtype = get_fd_type(fd);
|
||||
if (objtype != type) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
memset(&pinned_info, 0, sizeof(pinned_info));
|
||||
err = bpf_obj_get_info_by_fd(fd, &pinned_info, &len);
|
||||
if (err) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
obj_node = malloc(sizeof(*obj_node));
|
||||
if (!obj_node) {
|
||||
close(fd);
|
||||
fts_close(fts);
|
||||
fclose(mntfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(obj_node, 0, sizeof(*obj_node));
|
||||
obj_node->id = pinned_info.id;
|
||||
obj_node->path = strdup(ftse->fts_path);
|
||||
hash_add(tab->table, &obj_node->hash, obj_node->id);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
fts_close(fts);
|
||||
}
|
||||
fclose(mntfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void delete_pinned_obj_table(struct pinned_obj_table *tab)
|
||||
{
|
||||
struct pinned_obj *obj;
|
||||
struct hlist_node *tmp;
|
||||
unsigned int bkt;
|
||||
|
||||
hash_for_each_safe(tab->table, bkt, tmp, obj, hash) {
|
||||
hash_del(&obj->hash);
|
||||
free(obj->path);
|
||||
free(obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ static int (*last_do_help)(int argc, char **argv);
|
|||
json_writer_t *json_wtr;
|
||||
bool pretty_output;
|
||||
bool json_output;
|
||||
struct pinned_obj_table prog_table;
|
||||
struct pinned_obj_table map_table;
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
|
@ -272,6 +274,9 @@ int main(int argc, char **argv)
|
|||
json_output = false;
|
||||
bin_name = argv[0];
|
||||
|
||||
hash_init(prog_table.table);
|
||||
hash_init(map_table.table);
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "Vhpj",
|
||||
options, NULL)) >= 0) {
|
||||
switch (opt) {
|
||||
|
@ -311,5 +316,8 @@ int main(int argc, char **argv)
|
|||
if (json_output)
|
||||
jsonw_destroy(&json_wtr);
|
||||
|
||||
delete_pinned_obj_table(&prog_table);
|
||||
delete_pinned_obj_table(&map_table);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <stdio.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/hashtable.h>
|
||||
|
||||
#include "json_writer.h"
|
||||
|
||||
|
@ -70,6 +71,8 @@ extern const char *bin_name;
|
|||
|
||||
extern json_writer_t *json_wtr;
|
||||
extern bool json_output;
|
||||
extern struct pinned_obj_table prog_table;
|
||||
extern struct pinned_obj_table map_table;
|
||||
|
||||
void p_err(const char *fmt, ...);
|
||||
void p_info(const char *fmt, ...);
|
||||
|
@ -78,6 +81,20 @@ bool is_prefix(const char *pfx, const char *str);
|
|||
void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep);
|
||||
void usage(void) __attribute__((noreturn));
|
||||
|
||||
struct pinned_obj_table {
|
||||
DECLARE_HASHTABLE(table, 16);
|
||||
};
|
||||
|
||||
struct pinned_obj {
|
||||
__u32 id;
|
||||
char *path;
|
||||
struct hlist_node hash;
|
||||
};
|
||||
|
||||
int build_pinned_obj_table(struct pinned_obj_table *table,
|
||||
enum bpf_obj_type type);
|
||||
void delete_pinned_obj_table(struct pinned_obj_table *tab);
|
||||
|
||||
struct cmd {
|
||||
const char *cmd;
|
||||
int (*func)(int argc, char **argv);
|
||||
|
|
|
@ -436,6 +436,18 @@ static int show_map_close_json(int fd, struct bpf_map_info *info)
|
|||
jsonw_int_field(json_wtr, "bytes_memlock", atoi(memlock));
|
||||
free(memlock);
|
||||
|
||||
if (!hash_empty(map_table.table)) {
|
||||
struct pinned_obj *obj;
|
||||
|
||||
jsonw_name(json_wtr, "pinned");
|
||||
jsonw_start_array(json_wtr);
|
||||
hash_for_each_possible(map_table.table, obj, hash, info->id) {
|
||||
if (obj->id == info->id)
|
||||
jsonw_string(json_wtr, obj->path);
|
||||
}
|
||||
jsonw_end_array(json_wtr);
|
||||
}
|
||||
|
||||
jsonw_end_object(json_wtr);
|
||||
|
||||
return 0;
|
||||
|
@ -466,7 +478,14 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info)
|
|||
free(memlock);
|
||||
|
||||
printf("\n");
|
||||
if (!hash_empty(map_table.table)) {
|
||||
struct pinned_obj *obj;
|
||||
|
||||
hash_for_each_possible(map_table.table, obj, hash, info->id) {
|
||||
if (obj->id == info->id)
|
||||
printf("\tpinned %s\n", obj->path);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -478,6 +497,8 @@ static int do_show(int argc, char **argv)
|
|||
int err;
|
||||
int fd;
|
||||
|
||||
build_pinned_obj_table(&map_table, BPF_OBJ_MAP);
|
||||
|
||||
if (argc == 2) {
|
||||
fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
|
||||
if (fd < 0)
|
||||
|
|
|
@ -272,6 +272,18 @@ static void print_prog_json(struct bpf_prog_info *info, int fd)
|
|||
if (info->nr_map_ids)
|
||||
show_prog_maps(fd, info->nr_map_ids);
|
||||
|
||||
if (!hash_empty(prog_table.table)) {
|
||||
struct pinned_obj *obj;
|
||||
|
||||
jsonw_name(json_wtr, "pinned");
|
||||
jsonw_start_array(json_wtr);
|
||||
hash_for_each_possible(prog_table.table, obj, hash, info->id) {
|
||||
if (obj->id == info->id)
|
||||
jsonw_string(json_wtr, obj->path);
|
||||
}
|
||||
jsonw_end_array(json_wtr);
|
||||
}
|
||||
|
||||
jsonw_end_object(json_wtr);
|
||||
}
|
||||
|
||||
|
@ -331,6 +343,16 @@ static void print_prog_plain(struct bpf_prog_info *info, int fd)
|
|||
if (info->nr_map_ids)
|
||||
show_prog_maps(fd, info->nr_map_ids);
|
||||
|
||||
if (!hash_empty(prog_table.table)) {
|
||||
struct pinned_obj *obj;
|
||||
|
||||
printf("\n");
|
||||
hash_for_each_possible(prog_table.table, obj, hash, info->id) {
|
||||
if (obj->id == info->id)
|
||||
printf("\tpinned %s\n", obj->path);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
@ -360,6 +382,8 @@ static int do_show(int argc, char **argv)
|
|||
int err;
|
||||
int fd;
|
||||
|
||||
build_pinned_obj_table(&prog_table, BPF_OBJ_PROG);
|
||||
|
||||
if (argc == 2) {
|
||||
fd = prog_parse_fd(&argc, &argv);
|
||||
if (fd < 0)
|
||||
|
|
Загрузка…
Ссылка в новой задаче