From 8c95fc7039cb7db79f0f484cf5a29648e3118057 Mon Sep 17 00:00:00 2001 From: Tony Ambardar Date: Fri, 1 Dec 2023 01:40:17 -0800 Subject: [PATCH] kmodloader: support loadable module parameters in modinfo Current OpenWrt loadable modules embed details of parameters accepted on loading, but these aren't shown to users. Enable modinfo to print this information like most other distros. For example: root@OpenWrt:/# modinfo mac80211 filename: /lib/modules/6.1.65/mac80211.ko license: GPL depends: cfg80211,compat name: mac80211 vermagic: 6.1.65 SMP mod_unload MIPS32_R2 32BIT parm: minstrel_vht_only (bool) parm: max_nullfunc_tries (int) parm: max_probe_tries (int) parm: beacon_loss_count (int) parm: probe_wait_ms (int) parm: ieee80211_default_rc_algo (charp) Signed-off-by: Tony Ambardar --- kmodloader.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/kmodloader.c b/kmodloader.c index 0afc795..8d06ff1 100644 --- a/kmodloader.c +++ b/kmodloader.c @@ -37,11 +37,19 @@ #include #include #include +#include #define DEF_MOD_PATH "/modules/%s/" /* duplicated from in-kernel include/linux/module.h */ #define MODULE_NAME_LEN (64 - sizeof(unsigned long)) +struct param { + char *name; + char *desc; + char *type; + struct list_head list; +}; + enum { SCANNED, PROBE, @@ -495,10 +503,13 @@ static int print_modinfo(char *module) { int fd = open(module, O_RDONLY); unsigned int offset, size; + struct param *p; struct stat s; char *map = MAP_FAILED, *strings; int rv = -1; + LIST_HEAD(params); + if (fd < 0) { ULOG_ERR("failed to open %s\n", module); goto out; @@ -523,8 +534,9 @@ static int print_modinfo(char *module) strings = map + offset; printf("module:\t\t%s\n", module); while (true) { + char *pname, *pdata; char *dup = NULL; - char *sep; + char *sep, *sep2; while (!strings[0]) strings++; @@ -540,12 +552,49 @@ static int print_modinfo(char *module) printf("%s:\t\t%s\n", dup, sep); else printf("%s:\t%s\n", dup, sep); + } else { + sep2 = strstr(sep, ":"); + if (!sep2) + break; + pname = strndup(sep, sep2 - sep); + sep2++; + pdata = strdup(sep2); + + list_for_each_entry(p, ¶ms, list) + if (!strcmp(pname, p->name)) + break; + + if (list_entry_is_h(p, ¶ms, list)) { + p = alloca(sizeof(*p)); + p->name = pname; + p->desc = p->type = NULL; + list_add(&p->list, ¶ms); + } else { + free(pname); + } + + if (!strcmp(dup, "parmtype")) + p->type = pdata; + else + p->desc = pdata; } strings = &sep[strlen(sep)]; if (dup) free(dup); } + list_for_each_entry(p, ¶ms, list) { + printf("parm:\t\t%s", p->name); + if (p->desc) + printf(":%s", p->desc); + if (p->type) + printf(" (%s)", p->type); + printf("\n"); + free(p->name); + free(p->desc); + free(p->type); + } + rv = 0; out: -- 2.30.2