Sharing a list of names across API and CLI
Robin Jarry
rjarry at redhat.com
Sat Aug 22 11:40:57 CEST 2026
Hi Morten,
Morten Brørup, Aug 21, 2026 at 19:22:
> Seeking guidance...
>
> I'm working on a Grout "dump" API+CLI to call the various _dump() functions in DPDK.
>
> My modules/infra/api/dump.c has the table below.
>
> I want the type names in the table to be shared with modules/infra/cli/dump.c, so I can avoid copy-paste, and only have one place to add new entries.
>
> I suppose this can be done using a macro with two variants; one variant for use in the cli file, and another variant for use in the api file.
>
> E.g.
> #if API
> #define GR_DUMP_MACRO(name, description, dump_list_fn, dump_fn, lookup_fn) \
> {name, dump_list_fn, dump_fn, lookup_fn}
> #elif CLI
> #define GR_DUMP_MACRO(name,description,dump_list_fn,dump_fn,lookup_fn) \
> with_help(description, ec_node_str(EC_NO_ID, name))
> #endif
What would the API messages look like?
> And then the shared table using these macros:
> [...]
> GR_DUMP_MACRO("graph", "DPDK graph.", rte_graph_list_dump, (dump_fn_t)graph_dump, (lookup_fn_t)rte_graph_lookup),
> GR_DUMP_MACRO("memzone", "DPDK memzone.", rte_memzone_dump, NULL, NULL),
> [...]
>
> Now, my question is:
> In which directory should I put the file with the shared table?
The issue is that grcli concerns have nothing to do with the API socket
itself. It may not be possible to avoid duplication.
> Or should I use a completely different design pattern?
I must ask: is this intended for debugging/development or do you expect
to use this in production? What do you want to do with these dumps?
Does this need to go through the API socket and grcli? I am wondering if
such dumps would fit better in the openmetrics endpoints. E.g.:
https://github.com/DPDK/grout/blob/v0.17.1/modules/infra/api/iface.c#L218-L239
https://github.com/DPDK/grout/blob/v0.17.1/modules/infra/api/stats.c#L263-L306
These endpoints are self describing, no need to duplicate anything and
eventually, this data could be scraped by prometheus and stored in
a time series db for later analysis.
However, that means you need to expose "structured" information (i.e.
key=value pairs) which may not fit with the "dump" functions from DPDK
that seem to only expose text blobs.
If you are concerned with exposing too much information, they could be
hidden by default and only exposed when a certain variable is set (e.g.
GROUT_METRICS_DEBUG=1)
What do you think?
> modules/infra/api/dump.c:
>
> typedef void (*dump_list_fn_t)(FILE *f);
> typedef void (*dump_fn_t)(FILE *f, void *obj);
> typedef void *(*lookup_fn_t)(const char *name);
>
> struct dump_obj_helper {
> char *type;
> dump_list_fn_t dump_list_fn;
> dump_fn_t dump_fn;
> lookup_fn_t lookup_fn;
> } dump_obj_helpers[] =
> {
> // DPDK libs first, in alphabetical order.
> {"bus", rte_bus_dump, NULL, (lookup_fn_t)rte_bus_find_by_name},
> {"graph", rte_graph_list_dump, (dump_fn_t)graph_dump, (lookup_fn_t)rte_graph_lookup},
> {"lcore", rte_lcore_dump, NULL, NULL},
> {"log", rte_log_dump, NULL, NULL},
> {"malloc_heaps", rte_malloc_dump_heaps, NULL, NULL},
> {"malloc_stats", malloc_dump_stats, NULL, NULL},
> {"mbuf_dyn", rte_mbuf_dyn_dump, NULL, NULL},
> {"mempool", rte_mempool_list_dump, (dump_fn_t)rte_mempool_dump, (lookup_fn_t)rte_mempool_lookup},
> {"memzone", rte_memzone_dump, NULL, NULL},
> {"node", rte_node_list_dump, (dump_fn_t)node_dump, (lookup_fn_t)rte_node_from_name},
> {"pci", rte_pci_dump, NULL, NULL},
> {"physmem_layout", rte_dump_physmem_layout, NULL, NULL},
> {"ring", rte_ring_list_dump, (dump_fn_t)rte_ring_dump, (lookup_fn_t)rte_ring_lookup},
> {"tailq", rte_dump_tailq, NULL, NULL},
> {"trace", rte_trace_dump, NULL, NULL},
> {NULL, NULL, NULL, NULL}
> };
--
Robin
# Disposable, use only once.
More information about the grout
mailing list