[Toybox] [New Toy] - modprobe

ibid.ag at gmail.com ibid.ag at gmail.com
Wed Dec 18 07:57:54 PST 2013


On Tue, Dec 17, 2013 at 04:39:39PM +0530, Ashwini Sharma wrote:
> Hi List,
> 
> An implementation for modprobe is attached.
> go thru the same and let me know your inputs.
> 
> regards,
> Ashwini

It doesn't quite work.
Specifically, when I try loading by alias:
modprobe -v $ALIAS
I get the message:
"probing $ALIAS by realname"
Which indicates that no alias is matched; presumably this is because
get_mod always returns NULL in this case.

Using resolve_modalias, I can get the real module name and then load it
manually. The source for resolve_modalias is attached.

The only config files presemt are modules.alias, modules.dep, and
modules.symbols.

Thanks,
Isaac Dunham

> 
> /*
>  * Returns struct module_s from the data base if found, NULL otherwise.
>  * if ps - create module entry, add it to data base and return the same mod.
>  */
> static struct module_s *get_mod(char *mod, uint8_t ps)
> {
>   char name[MODNAME_LEN];
>   struct module_s *modentry;
>   struct arg_list *temp;
>   unsigned i, hash = 0;
> 
>   path2mod(mod, name);
>   for (i = 0; name[i]; i++) hash = ((hash*31) + hash) + name[i];
>   hash %= DBASE_SIZE;
>   for (temp = TT.dbase[hash]; temp; temp = temp->next) {
>     modentry = (struct module_s *) temp->arg;
>     if (!strcmp(modentry->name, name)) return modentry;
>   }
>   if (!ps) return NULL;

This line is the problem, but I'm not sure what's the right fix.

>   modentry = xzalloc(sizeof(*modentry));
>   modentry->name = xstrdup(name);
>   llist_add(&TT.dbase[hash], modentry);
>   return modentry;
> }
> 
<snip>
> /*
>  * Action to be taken on all config files in default directories
>  * checks for aliases, options, install, remove and blacklist
>  */
> static int config_action(struct dirtree *node)
> {
>   FILE *fc;
>   char *filename, *tokens[3], *line, *linecp;
>   struct module_s *modent;
>   int tcount = 0;
> 
>   if (!dirtree_notdotdot(node)) return 0;
>   if (S_ISDIR(node->st.st_mode)) return DIRTREE_RECURSE;
> 
>   if (!S_ISREG(node->st.st_mode)) return 0; // process only regular file
>   filename = dirtree_path(node, NULL);
>   if (!(fc = fopen(filename, "r"))) {
>     free(filename);
>     return 0;
>   }
>   for (line = linecp = NULL; read_line(fc, &line) > 0; 
>       free(line), free(linecp), line = linecp = NULL) {
>     char *tk = NULL;
> 
>     if (!strlen(line)) continue; 
>     linecp = xstrdup(line);
>     for (tk = strtok(linecp, "# \t"), tcount = 0; tk;
>         tk = strtok(NULL, "# \t"), tcount++) {
>       tokens[tcount] = tk;
>       if (tcount == 2) {
>         tokens[2] = line + strlen(tokens[0]) + strlen(tokens[1]) + 2;
>         break;
>       }
>     }
>     if (!tk) continue; 
>     // process the tokens[0] contains first word of config line.
>     if (!strcmp(tokens[0], "alias")) {
>       struct arg_list *temp;
>       char aliase[MODNAME_LEN], *realname;
> 
>       if (!tokens[2]) continue;
>       path2mod(tokens[1], aliase);
>       for (temp = TT.probes; temp; temp = temp->next) {
>         modent = (struct module_s *) temp->arg;
>         if (fnmatch(aliase, modent->name, 0)) continue;
>         realname = path2mod(tokens[2], NULL);
>         llist_add(&modent->rnames, realname);
>         if (modent->flags & MOD_NDDEPS) {
>           modent->flags &= ~MOD_NDDEPS;
>           TT.nudeps--;
>         }
>         modent = get_mod(realname, 1);
>         if (!(modent->flags & MOD_NDDEPS)) {
>           modent->flags |= MOD_NDDEPS;
>           TT.nudeps++;
>         }
>       }
>     } else if (!strcmp(tokens[0], "options")) {
>       if (!tokens[2]) continue;
>       modent = get_mod(tokens[1], 1);
>       modent->opts = add_opts(modent->opts, tokens[2]);
>     } else if (!strcmp(tokens[0], "include"))
>       dirtree_read(tokens[1], config_action);
>     else if (!strcmp(tokens[0], "blacklist"))
>       get_mod(tokens[1], 1)->flags |= MOD_BLACKLIST;
>     else if (!strcmp(tokens[0], "install")) continue;
>     else if (!strcmp(tokens[0], "remove")) continue;
>     else error_msg("Invalid option %s found in file %s", tokens[0], filename);
>   }
>   fclose(fc);
>   free(filename);
>   return 0;
> }
<snip>
> 
> void modprobe_main(void)
> {
>   struct utsname uts;
>   char **argv = toys.optargs, *procline = NULL;
>   FILE *fs;
>   struct module_s *module;
>   unsigned flags = toys.optflags;
> 
>   dbg = dummy;
>   if (flags & FLAG_v) dbg = xprintf;
> 
>   if ((toys.optc < 1) && (((flags & FLAG_r) && (flags & FLAG_l))
>         ||(!((flags & FLAG_r)||(flags & FLAG_l))))) {
> 	  toys.exithelp++;
> 	  error_exit(" Syntex Error.");
>   }
>   // 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) != 0)	perror_exit("rmmod");
>     return;
>   }
> 
>   // change directory to /lib/modules/<release>/ 
>   xchdir("/lib/modules");
>   uname(&uts);
>   xchdir(uts.release);
> 
>   // modules.dep processing for dependency check.
>   if (flags & FLAG_l) {
>     if (depmode_read_entry(toys.optargs[0])) error_exit("no module found.");
>     return;
>   }
>   // Read /proc/modules to get loadded modules.
>   fs = xfopen("/proc/modules", "r");
>   
>   while (read_line(fs, &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]);
>     TT.cmdopts = add_cmdopt(argv);
>   }
>   if (!TT.probes) {
>     fprintf(stderr, "All modules loaded successfully. \n");
>     return;
>   }
>   dirtree_read("/etc/modprobe.conf", config_action);
>   dirtree_read("/etc/modprobe.d", config_action);
>   if (TT.symreq) dirtree_read("modules.symbols", config_action);
>   if (TT.nudeps) dirtree_read("modules.alias", config_action);
>   find_dep();
>   while ((module = llist_popme(&TT.probes))) {
>     if (!module->rnames) {
>       dbg("probing by module name\n");
>       /* This is not an alias. Literal names are blacklisted
>        * only if '-b' is given.
>        */
>       if (!(flags & FLAG_b) || !(module->flags & MOD_BLACKLIST))
>         go_probe(module);
>       continue;
>     }
>     do { // Probe all real names for the alias.
>       char *real = llist_pop(&module->rnames);
>       struct module_s *m2 = get_mod(real, 0);

This is always NULL, as pointed out above.
>       
>       dbg("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))))
>         go_probe(m2);
>       free(real);
>     } while (module->rnames);
>   }
> }

-------------- next part --------------
A non-text attachment was scrubbed...
Name: resolve_modalias.c
Type: text/x-csrc
Size: 1927 bytes
Desc: not available
URL: <http://lists.landley.net/pipermail/toybox-landley.net/attachments/20131218/60c778fa/attachment-0002.c>


More information about the Toybox mailing list