diff options
| author | Tony Ambardar | 2023-12-01 09:40:17 +0000 |
|---|---|---|
| committer | Tony Ambardar | 2024-01-16 01:54:35 +0000 |
| commit | 8c95fc7039cb7db79f0f484cf5a29648e3118057 (patch) | |
| tree | 8ef13bd2a3948d7ac4bda0d120bd98d5425570a6 | |
| parent | 811ca6c2234a3d13efef55947a9cff8bef56ceb7 (diff) | |
| download | ubox-8c95fc7039cb7db79f0f484cf5a29648e3118057.tar.gz | |
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 <itugrok@yahoo.com>
| -rw-r--r-- | kmodloader.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/kmodloader.c b/kmodloader.c index 0afc795..8d06ff1 100644 --- a/kmodloader.c +++ b/kmodloader.c @@ -37,11 +37,19 @@ #include <libubox/utils.h> #include <libubox/ulog.h> #include <libubox/kvlist.h> +#include <libubox/list.h> #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: |