diff options
author | Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp> | 2017-11-08 13:55:48 +0900 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-11-11 12:35:41 +0900 |
commit | 4990f1f4610b483a60397ed2768d268df228a551 (patch) | |
tree | 7a720763c6ec3710eeeb333c4d502f25139f7576 /tools/bpf | |
parent | 1852719658c0f853b5481c9eaed862f1a9355edc (diff) | |
download | linux-4990f1f4610b483a60397ed2768d268df228a551.tar.bz2 |
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>
Diffstat (limited to 'tools/bpf')
-rw-r--r-- | tools/bpf/bpftool/common.c | 82 | ||||
-rw-r--r-- | tools/bpf/bpftool/main.c | 8 | ||||
-rw-r--r-- | tools/bpf/bpftool/main.h | 17 | ||||
-rw-r--r-- | tools/bpf/bpftool/map.c | 21 | ||||
-rw-r--r-- | tools/bpf/bpftool/prog.c | 24 |
5 files changed, 152 insertions, 0 deletions
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 6b3d25d6a782..2bd3b280e6dd 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -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); + } +} diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index 78d9afb74ef4..6ad53f1797fa 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -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; } diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index 2ff2a361af0d..13453de2e570 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h @@ -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); diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index e978ab23a77f..de0980657cef 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -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) diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index d3ab808dc882..8f94b8ac2e63 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -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) |