[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20171108045549.5356-3-bhole_prashant_q7@lab.ntt.co.jp>
Date: Wed, 8 Nov 2017 13:55:48 +0900
From: Prashant Bhole <bhole_prashant_q7@....ntt.co.jp>
To: "David S . Miller" <davem@...emloft.net>
Cc: Prashant Bhole <bhole_prashant_q7@....ntt.co.jp>,
netdev@...r.kernel.org, Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Quentin Monnet <quentin.monnet@...ronome.com>,
Jakub Kicinski <jakub.kicinski@...ronome.com>
Subject: [PATCH net-next V4 2/3] tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@...t# ./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@...t# ./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@...t# ./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@...t# ./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@....ntt.co.jp>
---
v2:
- Dynamically identify bpf-fs moutpoint
- Close files descriptors before returning on error
- Fixed line break for proper output formatting
- Code style: wrapped lines > 80, used reverse christmastree style
v3:
- Handle multiple bpffs mountpoints
- Code style: fixed line break indentation
v4:
- Removed unnecessary hash empty check
- Code style changes
tools/bpf/bpftool/common.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++
tools/bpf/bpftool/main.c | 8 +++++
tools/bpf/bpftool/main.h | 17 ++++++++++
tools/bpf/bpftool/map.c | 21 ++++++++++++
tools/bpf/bpftool/prog.c | 24 ++++++++++++++
5 files changed, 152 insertions(+)
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index 4556947709ee..55e91fa9a43a 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -34,7 +34,9 @@
/* Author: Jakub Kicinski <kubakici@...pl> */
#include <errno.h>
+#include <fts.h>
#include <libgen.h>
+#include <mntent.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -290,3 +292,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 4b5685005cb0..726f6e27a706 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,11 +71,27 @@ 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;
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 250f80fd46aa..11375f669fc0 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -256,6 +256,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);
}
@@ -300,6 +312,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");
}
@@ -329,6 +351,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)
--
2.13.6
Powered by blists - more mailing lists