From: Tony Ambardar Date: Fri, 1 Dec 2023 09:40:17 +0000 (-0800) Subject: kmodloader: support loadable module parameters in modinfo X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=8c95fc7039cb7db79f0f484cf5a29648e3118057;p=project%2Fubox.git 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 --- 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: