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 * > +{ > + 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. > + 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 >