aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2018-07-10 17:43:06 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-07-11 16:13:34 -0400
commit26736eb9a483715c2e971a8866f55fbb156903e2 (patch)
tree96dd4d1be8727b4b43c530bbf77f294bfd72fc1a
parent531b014e7a2fedaeff0b19b2934d830cd4b35dc0 (diff)
tools: libbpf: allow map reuse
More advanced applications may want to only replace programs without destroying associated maps. Allow libbpf users to achieve that. Instead of always creating all of the maps at load time, expose to users an API to reconstruct the map object from already existing map. The map parameters are read from the kernel and replace the parameters of the ELF map. libbpf does not restrict the map replacement, i.e. the reused map does not have to be compatible with the ELF map definition. We relay on the verifier for checking the compatibility between maps and programs. The ELF map definition is completely overwritten by the information read from the kernel, to make sure libbpf's view of map object corresponds to the actual map. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Acked-by: Andrey Ignatov <rdna@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--tools/lib/bpf/libbpf.c53
-rw-r--r--tools/lib/bpf/libbpf.h1
2 files changed, 54 insertions, 0 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index fd2c4433863d..955f8eafbf41 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1035,6 +1035,53 @@ static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
1035 return 0; 1035 return 0;
1036} 1036}
1037 1037
1038int bpf_map__reuse_fd(struct bpf_map *map, int fd)
1039{
1040 struct bpf_map_info info = {};
1041 __u32 len = sizeof(info);
1042 int new_fd, err;
1043 char *new_name;
1044
1045 err = bpf_obj_get_info_by_fd(fd, &info, &len);
1046 if (err)
1047 return err;
1048
1049 new_name = strdup(info.name);
1050 if (!new_name)
1051 return -errno;
1052
1053 new_fd = open("/", O_RDONLY | O_CLOEXEC);
1054 if (new_fd < 0)
1055 goto err_free_new_name;
1056
1057 new_fd = dup3(fd, new_fd, O_CLOEXEC);
1058 if (new_fd < 0)
1059 goto err_close_new_fd;
1060
1061 err = zclose(map->fd);
1062 if (err)
1063 goto err_close_new_fd;
1064 free(map->name);
1065
1066 map->fd = new_fd;
1067 map->name = new_name;
1068 map->def.type = info.type;
1069 map->def.key_size = info.key_size;
1070 map->def.value_size = info.value_size;
1071 map->def.max_entries = info.max_entries;
1072 map->def.map_flags = info.map_flags;
1073 map->btf_key_type_id = info.btf_key_type_id;
1074 map->btf_value_type_id = info.btf_value_type_id;
1075
1076 return 0;
1077
1078err_close_new_fd:
1079 close(new_fd);
1080err_free_new_name:
1081 free(new_name);
1082 return -errno;
1083}
1084
1038static int 1085static int
1039bpf_object__create_maps(struct bpf_object *obj) 1086bpf_object__create_maps(struct bpf_object *obj)
1040{ 1087{
@@ -1047,6 +1094,12 @@ bpf_object__create_maps(struct bpf_object *obj)
1047 struct bpf_map_def *def = &map->def; 1094 struct bpf_map_def *def = &map->def;
1048 int *pfd = &map->fd; 1095 int *pfd = &map->fd;
1049 1096
1097 if (map->fd >= 0) {
1098 pr_debug("skip map create (preset) %s: fd=%d\n",
1099 map->name, map->fd);
1100 continue;
1101 }
1102
1050 create_attr.name = map->name; 1103 create_attr.name = map->name;
1051 create_attr.map_ifindex = map->map_ifindex; 1104 create_attr.map_ifindex = map->map_ifindex;
1052 create_attr.map_type = def->type; 1105 create_attr.map_type = def->type;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index e911ad32d02e..1f8fc2060460 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -261,6 +261,7 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
261int bpf_map__set_priv(struct bpf_map *map, void *priv, 261int bpf_map__set_priv(struct bpf_map *map, void *priv,
262 bpf_map_clear_priv_t clear_priv); 262 bpf_map_clear_priv_t clear_priv);
263void *bpf_map__priv(struct bpf_map *map); 263void *bpf_map__priv(struct bpf_map *map);
264int bpf_map__reuse_fd(struct bpf_map *map, int fd);
264bool bpf_map__is_offload_neutral(struct bpf_map *map); 265bool bpf_map__is_offload_neutral(struct bpf_map *map);
265void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex); 266void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex);
266int bpf_map__pin(struct bpf_map *map, const char *path); 267int bpf_map__pin(struct bpf_map *map, const char *path);