Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> writes: > On Sat, Mar 28, 2020 at 11:29 AM Toke Høiland-Jørgensen <toke@xxxxxxxxxx> wrote: >> >> For internal maps (most notably the maps backing global variables), libbpf >> uses an internal mmaped area to store the data after opening the object. >> This data is subsequently copied into the kernel map when the object is >> loaded. >> >> This adds a function to set a new value for that data, which can be used to >> before it is loaded into the kernel. This is especially relevant for RODATA >> maps, since those are frozen on load. >> >> Signed-off-by: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> >> --- >> v3: >> - Add a setter for the initial value instead of a getter for the pointer to it >> - Add selftest >> v2: >> - Add per-map getter for data area instead of a global rodata getter for bpf_obj >> >> tools/lib/bpf/libbpf.c | 11 +++++++++++ >> tools/lib/bpf/libbpf.h | 2 ++ >> tools/lib/bpf/libbpf.map | 1 + >> 3 files changed, 14 insertions(+) >> >> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c >> index 085e41f9b68e..f9953a8ffcfa 100644 >> --- a/tools/lib/bpf/libbpf.c >> +++ b/tools/lib/bpf/libbpf.c >> @@ -6756,6 +6756,17 @@ void *bpf_map__priv(const struct bpf_map *map) >> return map ? map->priv : ERR_PTR(-EINVAL); >> } >> >> +int bpf_map__set_initial_value(struct bpf_map *map, >> + void *data, size_t size) > > nit: const void * ACK. >> +{ >> + if (!map->mmaped || map->libbpf_type == LIBBPF_MAP_KCONFIG || >> + size != map->def.value_size) >> + return -EINVAL; >> + > > How about also checking that bpf_map wasn't yet created? Checking > map->fd >= 0 should be enough. Yup, makes sense. >> + memcpy(map->mmaped, data, size); >> + return 0; >> +} >> + >> bool bpf_map__is_offload_neutral(const struct bpf_map *map) >> { >> return map->def.type == BPF_MAP_TYPE_PERF_EVENT_ARRAY; >> diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h >> index d38d7a629417..ee30ed487221 100644 >> --- a/tools/lib/bpf/libbpf.h >> +++ b/tools/lib/bpf/libbpf.h >> @@ -407,6 +407,8 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); >> LIBBPF_API int bpf_map__set_priv(struct bpf_map *map, void *priv, >> bpf_map_clear_priv_t clear_priv); >> LIBBPF_API void *bpf_map__priv(const struct bpf_map *map); >> +LIBBPF_API int bpf_map__set_initial_value(struct bpf_map *map, >> + void *data, size_t size); >> LIBBPF_API int bpf_map__reuse_fd(struct bpf_map *map, int fd); >> LIBBPF_API int bpf_map__resize(struct bpf_map *map, __u32 max_entries); >> LIBBPF_API bool bpf_map__is_offload_neutral(const struct bpf_map *map); >> diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map >> index 5129283c0284..f46873b9fe5e 100644 >> --- a/tools/lib/bpf/libbpf.map >> +++ b/tools/lib/bpf/libbpf.map >> @@ -243,5 +243,6 @@ LIBBPF_0.0.8 { >> bpf_link__pin; >> bpf_link__pin_path; >> bpf_link__unpin; >> + bpf_map__set_initial_value; >> bpf_program__set_attach_target; >> } LIBBPF_0.0.7; >> -- >> 2.26.0 >>