From 6e3f2fdb2bf11e2f49130436fa8ca7d3ad9c52ee Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 3 Feb 2021 04:35:39 -0600 Subject: Cleanup pass on modprobe. I need to set up a test environment for this... --- toys/pending/modprobe.c | 94 +++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 54 deletions(-) (limited to 'toys/pending') diff --git a/toys/pending/modprobe.c b/toys/pending/modprobe.c index 1d5479fd..7424e7c0 100644 --- a/toys/pending/modprobe.c +++ b/toys/pending/modprobe.c @@ -32,11 +32,9 @@ config MODPROBE GLOBALS( struct arg_list *dirs; - struct arg_list *probes; - struct arg_list *dbase[256]; + struct arg_list *probes, *dbase[256]; char *cmdopts; - int nudeps; - uint8_t symreq; + int nudeps, symreq; ) /* Note: if "#define DBASE_SIZE" modified, @@ -170,7 +168,7 @@ static int read_line(FILE *fl, char **li) ssize_t len, nxtlen; size_t linelen, nxtlinelen; - while (1) { + for (;;) { line = NULL; linelen = nxtlinelen = 0; len = getline(&line, &linelen, fl); @@ -273,7 +271,7 @@ static int config_action(struct dirtree *node) get_mod(tokens[1], 1)->flags |= MOD_BLACKLIST; else if (!strcmp(tokens[0], "install")) continue; else if (!strcmp(tokens[0], "remove")) continue; - else if (toys.optflags & FLAG_q) + else if (!FLAG(q)) error_msg("Invalid option %s found in file %s", tokens[0], filename); } fclose(fc); @@ -299,7 +297,7 @@ static int depmode_read_entry(char *cmdname) if (tmp) *tmp = '\0'; if (!cmdname || !fnmatch(cmdname, name, 0)) { if (tmp) *tmp = '.'; - if (toys.optflags&FLAG_v) puts(line); + if (FLAG(v)) puts(line); ret = 0; } } @@ -323,11 +321,10 @@ static void find_dep(void) *tmp = '\0'; mod = get_mod(line, 0); if (!mod) continue; - if ((mod->flags & MOD_ALOADED) && - !(toys.optflags & (FLAG_r | FLAG_D))) continue; + if ((mod->flags & MOD_ALOADED) && !(FLAG(r)|FLAG(D))) continue; mod->flags |= MOD_FNDDEPMOD; - if ((mod->flags & MOD_NDDEPS) && (!mod->dep)) { + if ((mod->flags & MOD_NDDEPS) && !mod->dep) { TT.nudeps--; llist_add(&mod->dep, xstrdup(line)); tmp++; @@ -346,16 +343,13 @@ static void find_dep(void) } // Remove a module from the Linux Kernel. if !modules does auto remove. -static int rm_mod(char *modules, uint32_t flags) +static int rm_mod(char *modules, unsigned flags) { - if (modules) { - int len = strlen(modules); - - if (len > 3 && !strcmp(modules+len-3, ".ko" )) modules[len-3] = 0; - } + char *s; + if (modules && (s = strend(modules, ".ko"))) *s = 0; errno = 0; - syscall(__NR_delete_module, modules, flags ? flags : O_NONBLOCK|O_EXCL); + syscall(__NR_delete_module, modules, flags ? : O_NONBLOCK|O_EXCL); return errno; } @@ -397,11 +391,11 @@ static void add_mod(char *name) { struct module_s *mod = get_mod(name, 1); - if (!(toys.optflags & (FLAG_r | FLAG_D)) && (mod->flags & MOD_ALOADED)) { - if (toys.optflags&FLAG_v) printf("skipping %s, already loaded\n", name); + if (!(FLAG(r)|FLAG(D)) && (mod->flags & MOD_ALOADED)) { + if (FLAG(v)) printf("%s already loaded\n", name); return; } - if (toys.optflags&FLAG_v) printf("queuing %s\n", name); + if (FLAG(v)) printf("queuing %s\n", name); mod->cmdname = name; mod->flags |= MOD_NDDEPS; llist_add_tail(&TT.probes, mod); @@ -435,12 +429,11 @@ static int go_probe(struct module_s *m) int rc = 0, first = 1; if (!(m->flags & MOD_FNDDEPMOD)) { - if (!(toys.optflags & FLAG_q)) - error_msg("module %s not found in modules.dep", m->name); + if (!FLAG(q)) error_msg("module %s not found in modules.dep", m->name); return -ENOENT; } - if (toys.optflags & FLAG_v) printf("go_prob'ing %s\n", m->name); - if (!(toys.optflags & FLAG_r)) m->dep = llist_rev(m->dep); + if (FLAG(v)) printf("go_prob'ing %s\n", m->name); + if (!FLAG(r)) m->dep = llist_rev(m->dep); while (m->dep) { struct module_s *m2; @@ -450,7 +443,7 @@ static int go_probe(struct module_s *m) fn = llist_popme(&m->dep); m2 = get_mod(fn, 1); // are we removing ? - if (toys.optflags & FLAG_r) { + if (FLAG(r)) { if (m2->flags & MOD_ALOADED) { if ((rc = rm_mod(m2->name, O_EXCL))) { if (first) { @@ -462,27 +455,27 @@ static int go_probe(struct module_s *m) first = 0; continue; } +// TODO how does free work here without leaking? options = m2->opts; m2->opts = NULL; if (m == m2) options = add_opts(options, TT.cmdopts); // are we only checking dependencies ? - if (toys.optflags & FLAG_D) { - if (toys.optflags & FLAG_v) + if (FLAG(D)) { + if (FLAG(v)) printf(options ? "insmod %s %s\n" : "insmod %s\n", fn, options); if (options) free(options); continue; } if (m2->flags & MOD_ALOADED) { - if (toys.optflags&FLAG_v) - printf("%s is already loaded, skipping\n", fn); + if (FLAG(v)) printf("%s already loaded\n", fn); if (options) free(options); continue; } // none of above is true insert the module. errno = 0; rc = ins_mod(fn, options); - if (toys.optflags&FLAG_v) + if (FLAG(v)) printf("loaded %s '%s': %s\n", fn, options, strerror(errno)); if (errno == EEXIST) rc = 0; free(options); @@ -497,35 +490,31 @@ static int go_probe(struct module_s *m) void modprobe_main(void) { - struct utsname uts; char **argv = toys.optargs, *procline = NULL; FILE *fs; struct module_s *module; - unsigned flags = toys.optflags; struct arg_list *dirs; - if ((toys.optc < 1) && (((flags & FLAG_r) && (flags & FLAG_l)) - ||(!((flags & FLAG_r)||(flags & FLAG_l))))) - { - help_exit("bad syntax"); - } + if (toys.optc<1 && !FLAG(r) == !FLAG(l)) help_exit("bad syntax"); // Check for -r flag without arg if yes then do auto remove. - if ((flags & FLAG_r) && !toys.optc) { - if (rm_mod(NULL, O_NONBLOCK | O_EXCL)) perror_exit("rmmod"); + if (FLAG(r) && !toys.optc) { + if (rm_mod(0, O_NONBLOCK|O_EXCL)) perror_exit("rmmod"); return; } if (!TT.dirs) { + struct utsname uts; + uname(&uts); TT.dirs = xzalloc(sizeof(struct arg_list)); TT.dirs->arg = xmprintf("/lib/modules/%s", uts.release); } // modules.dep processing for dependency check. - if (flags & FLAG_l) { + if (FLAG(l)) { for (dirs = TT.dirs; dirs; dirs = dirs->next) { xchdir(dirs->arg); - if (!depmode_read_entry(toys.optargs[0])) return; + if (!depmode_read_entry(*toys.optargs)) return; } error_exit("no module found."); } @@ -534,22 +523,19 @@ void modprobe_main(void) fs = xfopen("/proc/modules", "r"); while (read_line(fs, &procline) > 0) { - *(strchr(procline, ' ')) = '\0'; + *strchr(procline, ' ') = 0; get_mod(procline, 1)->flags = MOD_ALOADED; free(procline); procline = NULL; } fclose(fs); - if ((flags & FLAG_a) || (flags & FLAG_r)) { - do { - add_mod(*argv++); - } while (*argv); - } else { - add_mod(argv[0]); + if (FLAG(a) || FLAG(r)) while (argv) add_mod(*argv++); + else { + add_mod(*argv); TT.cmdopts = add_cmdopt(argv); } if (!TT.probes) { - if (toys.optflags&FLAG_v) puts("All modules loaded"); + if (FLAG(v)) puts("All modules loaded"); return; } dirtree_flagread("/etc/modprobe.conf", DIRTREE_SHUTUP, config_action); @@ -568,23 +554,23 @@ void modprobe_main(void) while ((module = llist_popme(&TT.probes))) { if (!module->rnames) { - if (toys.optflags&FLAG_v) puts("probing by module name"); + if (FLAG(v)) puts("probing by module name"); /* This is not an alias. Literal names are blacklisted * only if '-b' is given. */ - if (!(flags & FLAG_b) || !(module->flags & MOD_BLACKLIST)) + if (!FLAG(b) || !(module->flags & MOD_BLACKLIST)) go_probe(module); continue; } do { // Probe all real names for the alias. - char *real = ((struct arg_list*)llist_pop(&module->rnames))->arg; + char *real = ((struct arg_list *)llist_pop(&module->rnames))->arg; struct module_s *m2 = get_mod(real, 0); - if (toys.optflags&FLAG_v) + if (FLAG(v)) printf("probing alias %s by realname %s\n", module->name, real); if (!m2) continue; if (!(m2->flags & MOD_BLACKLIST) - && (!(m2->flags & MOD_ALOADED) || (flags & (FLAG_r | FLAG_D)))) + && (!(m2->flags & MOD_ALOADED) || FLAG(r) || FLAG(D))) go_probe(m2); free(real); } while (module->rnames); -- cgit v1.2.3