comparison toys/pending/modprobe.c @ 1384:4a7438307429 draft

minor cleanup: move a global variable into GLOBALS(), inline strchr_null(), some whitespace and bracket cleanups.
author Rob Landley <rob@landley.net>
date Sun, 06 Jul 2014 23:21:13 -0500
parents b13728c24a58
children 00c20f410c46
comparison
equal deleted inserted replaced
1383:350655f8fe53 1384:4a7438307429
32 struct arg_list *probes; 32 struct arg_list *probes;
33 struct arg_list *dbase[256]; 33 struct arg_list *dbase[256];
34 char *cmdopts; 34 char *cmdopts;
35 int nudeps; 35 int nudeps;
36 uint8_t symreq; 36 uint8_t symreq;
37 void (*dbg)(char *format, ...);
37 ) 38 )
38 39
39 /* Note: if "#define DBASE_SIZE" modified, 40 /* Note: if "#define DBASE_SIZE" modified,
40 * Please update GLOBALS dbase[256] accordingly. 41 * Please update GLOBALS dbase[256] accordingly.
41 */ 42 */
46 #define MOD_ALOADED 0x0001 47 #define MOD_ALOADED 0x0001
47 #define MOD_BLACKLIST 0x0002 48 #define MOD_BLACKLIST 0x0002
48 #define MOD_FNDDEPMOD 0x0004 49 #define MOD_FNDDEPMOD 0x0004
49 #define MOD_NDDEPS 0x0008 50 #define MOD_NDDEPS 0x0008
50 51
51 static void (*dbg)(char *format, ...);
52 // dummy interface for debugging. 52 // dummy interface for debugging.
53 static void dummy(char *format, ...) 53 static void dummy(char *format, ...)
54 { 54 {
55 } 55 }
56 56
62 }; 62 };
63 63
64 // Converts path name FILE to module name. 64 // Converts path name FILE to module name.
65 static char *path2mod(char *file, char *mod) 65 static char *path2mod(char *file, char *mod)
66 { 66 {
67 int i; 67 int i;
68 char *from, *lslash; 68 char *from, *lslash;
69 69
70 if (!file) return NULL; 70 if (!file) return NULL;
71 if (!mod) mod = xmalloc(MODNAME_LEN); 71 if (!mod) mod = xmalloc(MODNAME_LEN);
72 72
73 lslash = strrchr(file, '/'); 73 lslash = strrchr(file, '/');
74 if (!lslash || (lslash == file && !lslash[1])) from = file; 74 if (!lslash || (lslash == file && !lslash[1])) from = file;
75 else from = lslash + 1; 75 else from = lslash + 1;
76 76
77 for (i = 0; i < (MODNAME_LEN-1) && from[i] && from[i] != '.'; i++) 77 for (i = 0; i < (MODNAME_LEN-1) && from[i] && from[i] != '.'; i++)
78 mod[i] = (from[i] == '-') ? '_' : from[i]; 78 mod[i] = (from[i] == '-') ? '_' : from[i];
79 mod[i] = '\0'; 79 mod[i] = '\0';
80 return mod; 80 return mod;
81 }
82
83 // locate character in string.
84 static char *strchr_nul(char *s, int c)
85 {
86 while(*s != '\0' && *s != c) s++;
87 return (char*)s;
88 } 81 }
89 82
90 // Add options in opts from toadd. 83 // Add options in opts from toadd.
91 static char *add_opts(char *opts, char *toadd) 84 static char *add_opts(char *opts, char *toadd)
92 { 85 {
301 294
302 tmp = strchr(name, '.'); 295 tmp = strchr(name, '.');
303 if (tmp) *tmp = '\0'; 296 if (tmp) *tmp = '\0';
304 if (!cmdname || !fnmatch(cmdname, name, 0)) { 297 if (!cmdname || !fnmatch(cmdname, name, 0)) {
305 if (tmp) *tmp = '.'; 298 if (tmp) *tmp = '.';
306 dbg("%s\n", line); 299 TT.dbg("%s\n", line);
307 ret = 0; 300 ret = 0;
308 } 301 }
309 } 302 }
310 free(line); 303 free(line);
311 } 304 }
349 } 342 }
350 343
351 // Remove a module from the Linux Kernel. if !modules does auto remove. 344 // Remove a module from the Linux Kernel. if !modules does auto remove.
352 static int rm_mod(char *modules, uint32_t flags) 345 static int rm_mod(char *modules, uint32_t flags)
353 { 346 {
354 errno = 0;
355 if (modules) { 347 if (modules) {
356 int len = strlen(modules); 348 int len = strlen(modules);
357 349
358 if (len > 3 && !strcmp(&modules[len-3], ".ko" )) modules[len-3] = 0; 350 if (len > 3 && !strcmp(modules+len-3, ".ko" )) modules[len-3] = 0;
359 } 351 }
360 if (!flags) flags = O_NONBLOCK|O_EXCL; 352
361 syscall(__NR_delete_module, modules, flags); 353 errno = 0;
354 syscall(__NR_delete_module, modules, flags ? flags : O_NONBLOCK|O_EXCL);
355
362 return errno; 356 return errno;
363 } 357 }
364 358
365 // Insert module same as insmod implementation. 359 // Insert module same as insmod implementation.
366 static int ins_mod(char *modules, char *flags) 360 static int ins_mod(char *modules, char *flags)
388 static void add_mod(char *name) 382 static void add_mod(char *name)
389 { 383 {
390 struct module_s *mod = get_mod(name, 1); 384 struct module_s *mod = get_mod(name, 1);
391 385
392 if (!(toys.optflags & (FLAG_r | FLAG_D)) && (mod->flags & MOD_ALOADED)) { 386 if (!(toys.optflags & (FLAG_r | FLAG_D)) && (mod->flags & MOD_ALOADED)) {
393 dbg("skipping %s, it is already loaded\n", name); 387 TT.dbg("skipping %s, it is already loaded\n", name);
394 return; 388 return;
395 } 389 }
396 dbg("queuing %s\n", name); 390 TT.dbg("queuing %s\n", name);
397 mod->cmdname = name; 391 mod->cmdname = name;
398 mod->flags |= MOD_NDDEPS; 392 mod->flags |= MOD_NDDEPS;
399 llist_add_tail(&TT.probes, mod); 393 llist_add_tail(&TT.probes, mod);
400 TT.nudeps++; 394 TT.nudeps++;
401 if (!strncmp(mod->name, "symbol:", 7)) TT.symreq = 1; 395 if (!strncmp(mod->name, "symbol:", 7)) TT.symreq = 1;
412 406
413 var = *argv; 407 var = *argv;
414 opt = xrealloc(opt, lopt + 2 + strlen(var) + 2); 408 opt = xrealloc(opt, lopt + 2 + strlen(var) + 2);
415 // check for key=val or key = val. 409 // check for key=val or key = val.
416 fmt = "%.*s%s "; 410 fmt = "%.*s%s ";
417 val = strchr_nul(var, '='); 411 for (val = var; *val && *val != '='; val++);
418 if (*val) { 412 if (*val && strchr(++val, ' ')) fmt = "%.*s\"%s\" ";
419 val++;
420 if (strchr(val, ' ')) fmt = "%.*s\"%s\" ";
421 }
422 lopt += sprintf(opt + lopt, fmt, (int) (val - var), var, val); 413 lopt += sprintf(opt + lopt, fmt, (int) (val - var), var, val);
423 } 414 }
424 return opt; 415 return opt;
425 } 416 }
426 417
432 if (!(m->flags & MOD_FNDDEPMOD)) { 423 if (!(m->flags & MOD_FNDDEPMOD)) {
433 if (!(toys.optflags & FLAG_s)) 424 if (!(toys.optflags & FLAG_s))
434 error_msg("module %s not found in modules.dep", m->name); 425 error_msg("module %s not found in modules.dep", m->name);
435 return -ENOENT; 426 return -ENOENT;
436 } 427 }
437 dbg("go_prob'ing %s\n", m->name); 428 TT.dbg("go_prob'ing %s\n", m->name);
438 if (!(toys.optflags & FLAG_r)) m->dep = llist_rev(m->dep); 429 if (!(toys.optflags & FLAG_r)) m->dep = llist_rev(m->dep);
439 430
440 while (m->dep) { 431 while (m->dep) {
441 struct module_s *m2; 432 struct module_s *m2;
442 char *fn, *options; 433 char *fn, *options;
461 m2->opts = NULL; 452 m2->opts = NULL;
462 if (m == m2) options = add_opts(options, TT.cmdopts); 453 if (m == m2) options = add_opts(options, TT.cmdopts);
463 454
464 // are we only checking dependencies ? 455 // are we only checking dependencies ?
465 if (toys.optflags & FLAG_D) { 456 if (toys.optflags & FLAG_D) {
466 dbg(options ? "insmod %s %s\n" : "insmod %s\n", fn, options); 457 TT.dbg(options ? "insmod %s %s\n" : "insmod %s\n", fn, options);
467 if (options) free(options); 458 if (options) free(options);
468 continue; 459 continue;
469 } 460 }
470 if (m2->flags & MOD_ALOADED) { 461 if (m2->flags & MOD_ALOADED) {
471 dbg("%s is already loaded, skipping\n", fn); 462 TT.dbg("%s is already loaded, skipping\n", fn);
472 if (options) free(options); 463 if (options) free(options);
473 continue; 464 continue;
474 } 465 }
475 // none of above is true insert the module. 466 // none of above is true insert the module.
476 rc = ins_mod(fn, options); 467 rc = ins_mod(fn, options);
477 dbg("loaded %s '%s', rc:%d\n", fn, options, rc); 468 TT.dbg("loaded %s '%s', rc:%d\n", fn, options, rc);
478 if (rc == EEXIST) rc = 0; 469 if (rc == EEXIST) rc = 0;
479 if (options) free(options); 470 if (options) free(options);
480 if (rc) { 471 if (rc) {
481 perror_msg("can't load module %s (%s)", m2->name, fn); 472 perror_msg("can't load module %s (%s)", m2->name, fn);
482 break; 473 break;
492 char **argv = toys.optargs, *procline = NULL; 483 char **argv = toys.optargs, *procline = NULL;
493 FILE *fs; 484 FILE *fs;
494 struct module_s *module; 485 struct module_s *module;
495 unsigned flags = toys.optflags; 486 unsigned flags = toys.optflags;
496 487
497 dbg = dummy; 488 TT.dbg = (flags & FLAG_v) ? xprintf : dummy;
498 if (flags & FLAG_v) dbg = xprintf;
499 489
500 if ((toys.optc < 1) && (((flags & FLAG_r) && (flags & FLAG_l)) 490 if ((toys.optc < 1) && (((flags & FLAG_r) && (flags & FLAG_l))
501 ||(!((flags & FLAG_r)||(flags & FLAG_l))))) { 491 ||(!((flags & FLAG_r)||(flags & FLAG_l)))))
492 {
502 toys.exithelp++; 493 toys.exithelp++;
503 error_exit("bad syntax"); 494 error_exit("bad syntax");
504 } 495 }
505 // Check for -r flag without arg if yes then do auto remove. 496 // Check for -r flag without arg if yes then do auto remove.
506 if ((flags & FLAG_r) && (!toys.optc)) { 497 if ((flags & FLAG_r) && !toys.optc) {
507 if (rm_mod(NULL, O_NONBLOCK | O_EXCL) != 0) perror_exit("rmmod"); 498 if (rm_mod(NULL, O_NONBLOCK | O_EXCL)) perror_exit("rmmod");
508 return; 499 return;
509 } 500 }
510 501
511 // change directory to /lib/modules/<release>/ 502 // change directory to /lib/modules/<release>/
512 xchdir("/lib/modules"); 503 xchdir("/lib/modules");
535 } else { 526 } else {
536 add_mod(argv[0]); 527 add_mod(argv[0]);
537 TT.cmdopts = add_cmdopt(argv); 528 TT.cmdopts = add_cmdopt(argv);
538 } 529 }
539 if (!TT.probes) { 530 if (!TT.probes) {
540 dbg("All modules loaded\n"); 531 TT.dbg("All modules loaded\n");
541 return; 532 return;
542 } 533 }
543 dirtree_read("/etc/modprobe.conf", config_action); 534 dirtree_read("/etc/modprobe.conf", config_action);
544 dirtree_read("/etc/modprobe.d", config_action); 535 dirtree_read("/etc/modprobe.d", config_action);
545 if (TT.symreq) dirtree_read("modules.symbols", config_action); 536 if (TT.symreq) dirtree_read("modules.symbols", config_action);
546 if (TT.nudeps) dirtree_read("modules.alias", config_action); 537 if (TT.nudeps) dirtree_read("modules.alias", config_action);
547 find_dep(); 538 find_dep();
548 while ((module = llist_popme(&TT.probes))) { 539 while ((module = llist_popme(&TT.probes))) {
549 if (!module->rnames) { 540 if (!module->rnames) {
550 dbg("probing by module name\n"); 541 TT.dbg("probing by module name\n");
551 /* This is not an alias. Literal names are blacklisted 542 /* This is not an alias. Literal names are blacklisted
552 * only if '-b' is given. 543 * only if '-b' is given.
553 */ 544 */
554 if (!(flags & FLAG_b) || !(module->flags & MOD_BLACKLIST)) 545 if (!(flags & FLAG_b) || !(module->flags & MOD_BLACKLIST))
555 go_probe(module); 546 go_probe(module);
557 } 548 }
558 do { // Probe all real names for the alias. 549 do { // Probe all real names for the alias.
559 char *real = ((struct arg_list*)llist_pop(&module->rnames))->arg; 550 char *real = ((struct arg_list*)llist_pop(&module->rnames))->arg;
560 struct module_s *m2 = get_mod(real, 0); 551 struct module_s *m2 = get_mod(real, 0);
561 552
562 dbg("probing alias %s by realname %s\n", module->name, real); 553 TT.dbg("probing alias %s by realname %s\n", module->name, real);
563 if (!m2) continue; 554 if (!m2) continue;
564 if (!(m2->flags & MOD_BLACKLIST) 555 if (!(m2->flags & MOD_BLACKLIST)
565 && (!(m2->flags & MOD_ALOADED) || (flags & (FLAG_r | FLAG_D)))) 556 && (!(m2->flags & MOD_ALOADED) || (flags & (FLAG_r | FLAG_D))))
566 go_probe(m2); 557 go_probe(m2);
567 free(real); 558 free(real);