On Fri, Mar 27, 2020 at 5:58 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 getter for the pointer to that internal data store. This can be > used to modify the data before it is loaded into the kernel, which is > especially relevant for RODATA, which is frozen on load. This same pointer > is already exposed to the auto-generated skeletons, so access to it is > already API; this just adds a way to get at it without pulling in the full > skeleton infrastructure. > > Signed-off-by: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> > --- > v2: > - Add per-map getter for data area instead of a global rodata getter for bpf_obj > > tools/lib/bpf/libbpf.c | 9 +++++++++ > tools/lib/bpf/libbpf.h | 1 + > tools/lib/bpf/libbpf.map | 1 + > 3 files changed, 11 insertions(+) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index 085e41f9b68e..a0055f8908fd 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -6756,6 +6756,15 @@ void *bpf_map__priv(const struct bpf_map *map) > return map ? map->priv : ERR_PTR(-EINVAL); > } > > +void *bpf_map__data_area(const struct bpf_map *map, size_t *size) I'm not entirely thrilled about "data_area" name. This is entirely for providing initial value for maps, so maybe something like bpf_map__init_value() or something along those lines? Actually, how about a different API altogether: bpf_map__set_init_value(struct bpf_map *map, void *data, size_t size)? Application will have to prepare data of correct size, which will be copied to libbpf's internal storage. It also doesn't expose any of internal pointer. I don't think extra memcopy is a big deal here. Thoughts? > +{ > + if (map->mmaped && map->libbpf_type != LIBBPF_MAP_KCONFIG) { > + *size = map->def.value_size; > + return map->mmaped; > + } > + return NULL; > +} > + > 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..baef0d2f3205 100644 > --- a/tools/lib/bpf/libbpf.h > +++ b/tools/lib/bpf/libbpf.h > @@ -407,6 +407,7 @@ 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 void *bpf_map__data_area(const struct bpf_map *map, 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..258528045a85 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__data_area; > bpf_program__set_attach_target; > } LIBBPF_0.0.7; > -- > 2.26.0 >