|
@@ -1035,6 +1035,53 @@ static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+int bpf_map__reuse_fd(struct bpf_map *map, int fd)
|
|
|
+{
|
|
|
+ struct bpf_map_info info = {};
|
|
|
+ __u32 len = sizeof(info);
|
|
|
+ int new_fd, err;
|
|
|
+ char *new_name;
|
|
|
+
|
|
|
+ err = bpf_obj_get_info_by_fd(fd, &info, &len);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ new_name = strdup(info.name);
|
|
|
+ if (!new_name)
|
|
|
+ return -errno;
|
|
|
+
|
|
|
+ new_fd = open("/", O_RDONLY | O_CLOEXEC);
|
|
|
+ if (new_fd < 0)
|
|
|
+ goto err_free_new_name;
|
|
|
+
|
|
|
+ new_fd = dup3(fd, new_fd, O_CLOEXEC);
|
|
|
+ if (new_fd < 0)
|
|
|
+ goto err_close_new_fd;
|
|
|
+
|
|
|
+ err = zclose(map->fd);
|
|
|
+ if (err)
|
|
|
+ goto err_close_new_fd;
|
|
|
+ free(map->name);
|
|
|
+
|
|
|
+ map->fd = new_fd;
|
|
|
+ map->name = new_name;
|
|
|
+ map->def.type = info.type;
|
|
|
+ map->def.key_size = info.key_size;
|
|
|
+ map->def.value_size = info.value_size;
|
|
|
+ map->def.max_entries = info.max_entries;
|
|
|
+ map->def.map_flags = info.map_flags;
|
|
|
+ map->btf_key_type_id = info.btf_key_type_id;
|
|
|
+ map->btf_value_type_id = info.btf_value_type_id;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err_close_new_fd:
|
|
|
+ close(new_fd);
|
|
|
+err_free_new_name:
|
|
|
+ free(new_name);
|
|
|
+ return -errno;
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
bpf_object__create_maps(struct bpf_object *obj)
|
|
|
{
|
|
@@ -1047,6 +1094,12 @@ bpf_object__create_maps(struct bpf_object *obj)
|
|
|
struct bpf_map_def *def = &map->def;
|
|
|
int *pfd = &map->fd;
|
|
|
|
|
|
+ if (map->fd >= 0) {
|
|
|
+ pr_debug("skip map create (preset) %s: fd=%d\n",
|
|
|
+ map->name, map->fd);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
create_attr.name = map->name;
|
|
|
create_attr.map_ifindex = map->map_ifindex;
|
|
|
create_attr.map_type = def->type;
|