1 /* 2 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org> 3 * Copyright (C) 2013 John Crispin <blogic@openwrt.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License version 2.1 7 * as published by the Free Software Foundation 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 15 #define _GNU_SOURCE 16 #include <sys/syscall.h> 17 #include <sys/mman.h> 18 #include <sys/utsname.h> 19 20 #include <stdlib.h> 21 #include <unistd.h> 22 #include <sys/syscall.h> 23 #include <sys/types.h> 24 #include <values.h> 25 #include <errno.h> 26 #include <stdio.h> 27 #include <string.h> 28 #include <sys/stat.h> 29 #include <fcntl.h> 30 #include <libgen.h> 31 #include <glob.h> 32 #include <elf.h> 33 #include <ctype.h> 34 35 #include <libubox/avl.h> 36 #include <libubox/avl-cmp.h> 37 #include <libubox/utils.h> 38 #include <libubox/ulog.h> 39 #include <libubox/kvlist.h> 40 41 #define DEF_MOD_PATH "/modules/%s/" 42 /* duplicated from in-kernel include/linux/module.h */ 43 #define MODULE_NAME_LEN (64 - sizeof(unsigned long)) 44 45 enum { 46 SCANNED, 47 PROBE, 48 LOADED, 49 BLACKLISTED, 50 }; 51 52 struct module { 53 char *name; 54 char *depends; 55 char *opts; 56 57 int size; 58 int usage; 59 int state; 60 int error; 61 int refcnt; /* number of references from module_node.m */ 62 }; 63 64 struct module_node { 65 struct avl_node avl; 66 struct module *m; 67 bool is_alias; 68 }; 69 70 static struct avl_tree modules; 71 static KVLIST(options, kvlist_strlen); 72 73 static char **module_folders = NULL; 74 75 static void free_module(struct module *m); 76 77 static int init_module_folders(void) 78 { 79 int n = 0; 80 struct stat st; 81 struct utsname ver; 82 char *s, *e, *p, path[330], ldpath[256]; 83 84 e = ldpath; 85 s = getenv("LD_LIBRARY_PATH"); 86 87 if (s) 88 e += snprintf(ldpath, sizeof(ldpath), "%s:", s); 89 90 e += snprintf(e, sizeof(ldpath) - (e - ldpath), "/lib"); 91 92 uname(&ver); 93 94 for (s = p = ldpath; p <= e; p++) { 95 if (*p != ':' && *p != '\0') 96 continue; 97 98 *p = 0; 99 snprintf(path, sizeof(path), "%s" DEF_MOD_PATH, s, ver.release); 100 101 if (!stat(path, &st) && S_ISDIR(st.st_mode)) { 102 module_folders = realloc(module_folders, sizeof(p) * (n + 2)); 103 104 if (!module_folders) { 105 ULOG_ERR("out of memory\n"); 106 return -1; 107 } 108 109 module_folders[n++] = strdup(path); 110 } 111 112 s = p + 1; 113 } 114 115 if (!module_folders) { 116 ULOG_ERR("no module folders for kernel version %s found\n", ver.release); 117 return -1; 118 } 119 120 module_folders[n] = NULL; 121 return 0; 122 } 123 124 static struct module *find_module(const char *name) 125 { 126 struct module_node *mn; 127 mn = avl_find_element(&modules, name, mn, avl); 128 if (mn) 129 return mn->m; 130 else 131 return NULL; 132 } 133 134 static void free_modules(void) 135 { 136 struct module_node *mn, *tmp; 137 138 avl_remove_all_elements(&modules, mn, avl, tmp) { 139 struct module *m = mn->m; 140 141 m->refcnt -= 1; 142 if (m->refcnt == 0) 143 free_module(m); 144 free(mn); 145 } 146 } 147 148 static char* get_module_path(char *name) 149 { 150 char **p; 151 static char path[256]; 152 struct stat s; 153 154 if (!stat(name, &s) && S_ISREG(s.st_mode)) 155 return name; 156 157 for (p = module_folders; *p; p++) { 158 snprintf(path, sizeof(path), "%s%s.ko", *p, name); 159 if (!stat(path, &s) && S_ISREG(s.st_mode)) 160 return path; 161 } 162 163 return NULL; 164 } 165 166 static char* get_module_name(char *path) 167 { 168 static char name[MODULE_NAME_LEN]; 169 char *t; 170 171 strncpy(name, basename(path), sizeof(name) - 1); 172 173 t = strstr(name, ".ko"); 174 if (t) 175 *t = '\0'; 176 177 return name; 178 } 179 180 static int elf64_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size) 181 { 182 const char *secnames; 183 Elf64_Ehdr *e; 184 Elf64_Shdr *sh; 185 int i; 186 187 e = (Elf64_Ehdr *) map; 188 sh = (Elf64_Shdr *) (map + e->e_shoff); 189 190 secnames = map + sh[e->e_shstrndx].sh_offset; 191 for (i = 0; i < e->e_shnum; i++) { 192 if (!strcmp(section, secnames + sh[i].sh_name)) { 193 *size = sh[i].sh_size; 194 *offset = sh[i].sh_offset; 195 return 0; 196 } 197 } 198 199 return -1; 200 } 201 202 static int elf32_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size) 203 { 204 const char *secnames; 205 Elf32_Ehdr *e; 206 Elf32_Shdr *sh; 207 int i; 208 209 e = (Elf32_Ehdr *) map; 210 sh = (Elf32_Shdr *) (map + e->e_shoff); 211 212 secnames = map + sh[e->e_shstrndx].sh_offset; 213 for (i = 0; i < e->e_shnum; i++) { 214 if (!strcmp(section, secnames + sh[i].sh_name)) { 215 *size = sh[i].sh_size; 216 *offset = sh[i].sh_offset; 217 return 0; 218 } 219 } 220 221 return -1; 222 } 223 224 static int elf_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size) 225 { 226 int clazz = map[EI_CLASS]; 227 int endian = map[EI_DATA]; 228 229 #if __BYTE_ORDER == __LITTLE_ENDIAN 230 if (endian != ELFDATA2LSB) 231 #elif __BYTE_ORDER == __BIG_ENDIAN 232 if (endian != ELFDATA2MSB) 233 #else 234 #error "unsupported endian" 235 #endif 236 { 237 ULOG_ERR("invalid endianess: %d\n", endian); 238 return -1; 239 } 240 241 if (clazz == ELFCLASS32) 242 return elf32_find_section(map, section, offset, size); 243 else if (clazz == ELFCLASS64) 244 return elf64_find_section(map, section, offset, size); 245 246 ULOG_ERR("unknown elf format %d\n", clazz); 247 248 return -1; 249 } 250 251 static struct module_node * 252 alloc_module_node(const char *name, struct module *m, bool is_alias) 253 { 254 struct module_node *mn; 255 char *_name; 256 257 mn = calloc_a(sizeof(*mn), 258 &_name, strlen(name) + 1); 259 if (mn) { 260 mn->avl.key = strcpy(_name, name); 261 mn->m = m; 262 mn->is_alias = is_alias; 263 avl_insert(&modules, &mn->avl); 264 m->refcnt += 1; 265 } 266 return mn; 267 } 268 269 static struct module * 270 alloc_module(const char *name, const char * const *aliases, int naliases, const char *depends, int size) 271 { 272 struct module *m; 273 char *_name, *_dep; 274 int i; 275 276 m = calloc_a(sizeof(*m), 277 &_name, strlen(name) + 1, 278 &_dep, depends ? strlen(depends) + 2 : 0); 279 if (!m) 280 return NULL; 281 282 m->name = strcpy(_name, name); 283 m->opts = 0; 284 285 if (depends) { 286 m->depends = strcpy(_dep, depends); 287 while (*_dep) { 288 if (*_dep == ',') 289 *_dep = '\0'; 290 _dep++; 291 } 292 } 293 m->size = size; 294 295 m->refcnt = 0; 296 alloc_module_node(m->name, m, false); 297 for (i = 0; i < naliases; i++) 298 alloc_module_node(aliases[i], m, true); 299 300 return m; 301 } 302 303 static void free_module(struct module *m) 304 { 305 if (m->opts) 306 free(m->opts); 307 free(m); 308 } 309 310 static int scan_loaded_modules(void) 311 { 312 size_t buf_len = 0; 313 char *buf = NULL; 314 FILE *fp; 315 316 fp = fopen("/proc/modules", "r"); 317 if (!fp) { 318 ULOG_ERR("failed to open /proc/modules\n"); 319 return -1; 320 } 321 322 while (getline(&buf, &buf_len, fp) > 0) { 323 struct module m; 324 struct module *n; 325 326 m.name = strtok(buf, " "); 327 m.size = atoi(strtok(NULL, " ")); 328 m.usage = atoi(strtok(NULL, " ")); 329 m.depends = strtok(NULL, " "); 330 331 if (!m.name || !m.depends) 332 continue; 333 334 n = find_module(m.name); 335 if (!n) { 336 /* possibly a module outside /lib/modules/<ver>/ */ 337 n = alloc_module(m.name, NULL, 0, m.depends, m.size); 338 } 339 n->usage = m.usage; 340 n->state = LOADED; 341 } 342 free(buf); 343 fclose(fp); 344 345 return 0; 346 } 347 348 static struct module* get_module_info(const char *module, const char *name) 349 { 350 int fd = open(module, O_RDONLY); 351 unsigned int offset, size; 352 char *map = MAP_FAILED, *strings, *dep = NULL; 353 const char **aliases = NULL; 354 int naliases = 0; 355 struct module *m = NULL; 356 struct stat s; 357 358 if (fd < 0) { 359 ULOG_ERR("failed to open %s\n", module); 360 goto out; 361 } 362 363 if (fstat(fd, &s) == -1) { 364 ULOG_ERR("failed to stat %s\n", module); 365 goto out; 366 } 367 368 map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 369 if (map == MAP_FAILED) { 370 ULOG_ERR("failed to mmap %s\n", module); 371 goto out; 372 } 373 374 if (elf_find_section(map, ".modinfo", &offset, &size)) { 375 ULOG_ERR("failed to load the .modinfo section from %s\n", module); 376 goto out; 377 } 378 379 strings = map + offset; 380 while (true) { 381 char *sep; 382 int len; 383 384 while (!strings[0]) 385 strings++; 386 if (strings >= map + offset + size) 387 break; 388 sep = strstr(strings, "="); 389 if (!sep) 390 break; 391 len = sep - strings; 392 sep++; 393 if (!strncmp(strings, "depends=", len + 1)) 394 dep = sep; 395 else if (!strncmp(strings, "alias=", len + 1)) { 396 aliases = realloc(aliases, sizeof(sep) * (naliases + 1)); 397 if (!aliases) { 398 ULOG_ERR("out of memory\n"); 399 goto out; 400 } 401 402 aliases[naliases++] = sep; 403 } 404 strings = &sep[strlen(sep)]; 405 } 406 407 m = alloc_module(name, aliases, naliases, dep, s.st_size); 408 409 if (m) 410 m->state = SCANNED; 411 412 out: 413 if (map != MAP_FAILED) 414 munmap(map, s.st_size); 415 416 if (fd >= 0) 417 close(fd); 418 419 free(aliases); 420 421 return m; 422 } 423 424 static int scan_module_folder(const char *dir) 425 { 426 int gl_flags = GLOB_NOESCAPE | GLOB_MARK; 427 struct utsname ver; 428 char *path; 429 glob_t gl; 430 int j, rv = 0; 431 432 uname(&ver); 433 path = alloca(strlen(dir) + sizeof("*.ko") + 1); 434 sprintf(path, "%s*.ko", dir); 435 436 if (glob(path, gl_flags, NULL, &gl) < 0) 437 return -1; 438 439 for (j = 0; j < gl.gl_pathc; j++) { 440 char *name = get_module_name(gl.gl_pathv[j]); 441 struct module *m; 442 char *opts; 443 444 if (!name) 445 continue; 446 447 m = find_module(name); 448 if (m) 449 continue; 450 451 m = get_module_info(gl.gl_pathv[j], name); 452 if (!m) { 453 rv |= -1; 454 continue; 455 } 456 457 opts = kvlist_get(&options, name); 458 if (!opts) 459 continue; 460 461 if (*opts == '\x01') 462 m->state = BLACKLISTED; 463 else 464 m->opts = strdup(opts); 465 } 466 467 globfree(&gl); 468 469 return rv; 470 } 471 472 static int scan_module_folders(void) 473 { 474 int rv = 0; 475 char **p; 476 477 if (init_module_folders()) 478 return -1; 479 480 for (p = module_folders; *p; p++) 481 rv |= scan_module_folder(*p); 482 483 return rv; 484 } 485 486 static int print_modinfo(char *module) 487 { 488 int fd = open(module, O_RDONLY); 489 unsigned int offset, size; 490 struct stat s; 491 char *map = MAP_FAILED, *strings; 492 int rv = -1; 493 494 if (fd < 0) { 495 ULOG_ERR("failed to open %s\n", module); 496 goto out; 497 } 498 499 if (fstat(fd, &s) == -1) { 500 ULOG_ERR("failed to stat %s\n", module); 501 goto out; 502 } 503 504 map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 505 if (map == MAP_FAILED) { 506 ULOG_ERR("failed to mmap %s\n", module); 507 goto out; 508 } 509 510 if (elf_find_section(map, ".modinfo", &offset, &size)) { 511 ULOG_ERR("failed to load the .modinfo section from %s\n", module); 512 goto out; 513 } 514 515 strings = map + offset; 516 printf("module:\t\t%s\n", module); 517 while (true) { 518 char *dup = NULL; 519 char *sep; 520 521 while (!strings[0]) 522 strings++; 523 if (strings >= map + offset + size) 524 break; 525 sep = strstr(strings, "="); 526 if (!sep) 527 break; 528 dup = strndup(strings, sep - strings); 529 sep++; 530 if (strncmp(strings, "parm", 4)) { 531 if (strlen(dup) < 7) 532 printf("%s:\t\t%s\n", dup, sep); 533 else 534 printf("%s:\t%s\n", dup, sep); 535 } 536 strings = &sep[strlen(sep)]; 537 if (dup) 538 free(dup); 539 } 540 541 rv = 0; 542 543 out: 544 if (map != MAP_FAILED) 545 munmap(map, s.st_size); 546 547 if (fd >= 0) 548 close(fd); 549 550 return rv; 551 } 552 553 static int deps_available(struct module *m, int verbose) 554 { 555 char *dep; 556 int err = 0; 557 558 if (!m->depends || !strcmp(m->depends, "-") || !strcmp(m->depends, "")) 559 return 0; 560 561 dep = m->depends; 562 563 while (*dep) { 564 m = find_module(dep); 565 566 if (verbose && !m) 567 ULOG_ERR("missing dependency %s\n", dep); 568 if (verbose && m && (m->state != LOADED)) 569 ULOG_ERR("dependency not loaded %s\n", dep); 570 if (!m || (m->state != LOADED)) 571 err++; 572 dep += strlen(dep) + 1; 573 } 574 575 return err; 576 } 577 578 static int insert_module(char *path, const char *options) 579 { 580 void *data = 0; 581 struct stat s; 582 int fd, ret = -1; 583 584 if (stat(path, &s)) { 585 ULOG_ERR("missing module %s\n", path); 586 return ret; 587 } 588 589 fd = open(path, O_RDONLY); 590 if (fd < 0) { 591 ULOG_ERR("cannot open %s\n", path); 592 return ret; 593 } 594 595 data = malloc(s.st_size); 596 if (!data) { 597 ULOG_ERR("out of memory\n"); 598 goto out; 599 } 600 601 if (read(fd, data, s.st_size) == s.st_size) { 602 ret = syscall(__NR_init_module, data, (unsigned long) s.st_size, options); 603 if (errno == EEXIST) 604 ret = 0; 605 } 606 else 607 ULOG_ERR("failed to read full module %s\n", path); 608 609 out: 610 close(fd); 611 free(data); 612 613 return ret; 614 } 615 616 static void load_moddeps(struct module *_m) 617 { 618 char *dep; 619 struct module *m; 620 621 if (!strcmp(_m->depends, "-") || !strcmp(_m->depends, "")) 622 return; 623 624 dep = _m->depends; 625 626 while (*dep) { 627 m = find_module(dep); 628 629 if (!m) 630 ULOG_ERR("failed to find dependency %s\n", dep); 631 if (m && (m->state != LOADED)) { 632 m->state = PROBE; 633 load_moddeps(m); 634 } 635 636 dep = dep + strlen(dep) + 1; 637 } 638 } 639 640 static int load_modprobe(bool allow_load_retry) 641 { 642 int loaded, skipped, failed; 643 struct module_node *mn; 644 struct module *m; 645 bool load_retry = false; 646 static bool first_iteration = true; 647 648 avl_for_each_element(&modules, mn, avl) { 649 if (mn->is_alias) 650 continue; 651 m = mn->m; 652 if (m->state == PROBE) 653 load_moddeps(m); 654 } 655 656 do { 657 loaded = 0; 658 skipped = 0; 659 failed = 0; 660 avl_for_each_element(&modules, mn, avl) { 661 if (mn->is_alias) 662 continue; 663 m = mn->m; 664 if ((m->state == PROBE) && (!deps_available(m, 0)) && (!m->error || load_retry)) { 665 if (!insert_module(get_module_path(m->name), (m->opts) ? (m->opts) : (""))) { 666 m->state = LOADED; 667 m->error = 0; 668 loaded++; 669 continue; 670 } 671 672 m->error = 1; 673 } 674 675 if (m->error) 676 failed++; 677 else if (m->state == PROBE) 678 skipped++; 679 } 680 681 if (allow_load_retry) { 682 /* if we can't load anything else let's try to load failed modules */ 683 load_retry = loaded ? (failed && !skipped) : (failed && !load_retry && !first_iteration); 684 } 685 686 first_iteration = false; 687 } while (loaded || load_retry); 688 689 return skipped + failed; 690 } 691 692 static int print_insmod_usage(void) 693 { 694 ULOG_INFO("Usage:\n\tinsmod filename [args]\n"); 695 696 return -1; 697 } 698 699 static int print_modprobe_usage(void) 700 { 701 ULOG_INFO( 702 "Usage:\n" 703 "\tmodprobe [-q] [-v] filename\n" 704 "\tmodprobe -a [-q] [-v] filename [filename...]\n" 705 ); 706 707 return -1; 708 } 709 710 static int print_usage(char *arg) 711 { 712 ULOG_INFO("Usage:\n\t%s module\n", arg); 713 714 return -1; 715 } 716 717 static int main_insmod(int argc, char **argv) 718 { 719 char *name, *cur, *options; 720 int i, ret, len; 721 722 if (argc < 2) 723 return print_insmod_usage(); 724 725 name = get_module_name(argv[1]); 726 if (!name) { 727 ULOG_ERR("cannot find module - %s\n", argv[1]); 728 return -1; 729 } 730 731 if (scan_loaded_modules()) 732 return -1; 733 734 if (find_module(name)) { 735 ULOG_ERR("module is already loaded - %s\n", name); 736 return -1; 737 738 } 739 740 free_modules(); 741 742 for (len = 0, i = 2; i < argc; i++) 743 len += strlen(argv[i]) + 1; 744 745 options = malloc(len); 746 if (!options) { 747 ULOG_ERR("out of memory\n"); 748 ret = -1; 749 goto err; 750 } 751 752 options[0] = 0; 753 cur = options; 754 for (i = 2; i < argc; i++) { 755 if (options[0]) { 756 *cur = ' '; 757 cur++; 758 } 759 cur += sprintf(cur, "%s", argv[i]); 760 } 761 762 if (init_module_folders()) { 763 fprintf(stderr, "Failed to find the folder holding the modules\n"); 764 ret = -1; 765 goto err; 766 } 767 768 if (get_module_path(argv[1])) { 769 name = argv[1]; 770 } else if (!get_module_path(name)) { 771 fprintf(stderr, "Failed to find %s. Maybe it is a built in module ?\n", name); 772 ret = -1; 773 goto err; 774 } 775 776 ret = insert_module(get_module_path(name), options); 777 if (ret) 778 ULOG_ERR("failed to insert %s\n", get_module_path(name)); 779 780 err: 781 free(options); 782 return ret; 783 } 784 785 static int main_rmmod(int argc, char **argv) 786 { 787 struct module *m; 788 char *name; 789 int ret; 790 791 if (argc != 2) 792 return print_usage("rmmod"); 793 794 if (scan_loaded_modules()) 795 return -1; 796 797 name = get_module_name(argv[1]); 798 m = find_module(name); 799 if (!m) { 800 ULOG_ERR("module is not loaded\n"); 801 return -1; 802 } 803 ret = syscall(__NR_delete_module, m->name, 0); 804 805 if (ret) 806 ULOG_ERR("unloading the module failed\n"); 807 808 free_modules(); 809 810 return ret; 811 } 812 813 static int main_lsmod(int argc, char **argv) 814 { 815 struct module_node *mn; 816 struct module *m; 817 char *dep; 818 819 if (scan_loaded_modules()) 820 return -1; 821 822 avl_for_each_element(&modules, mn, avl) { 823 if (mn->is_alias) 824 continue; 825 m = mn->m; 826 if (m->state == LOADED) { 827 printf("%-20s%8d%3d ", 828 m->name, m->size, m->usage); 829 if (m->depends && strcmp(m->depends, "-") && strcmp(m->depends, "")) { 830 dep = m->depends; 831 while (*dep) { 832 printf("%s", dep); 833 dep = dep + strlen(dep) + 1; 834 if (*dep) 835 printf(","); 836 } 837 } 838 printf("\n"); 839 } 840 } 841 842 free_modules(); 843 844 return 0; 845 } 846 847 static int main_modinfo(int argc, char **argv) 848 { 849 struct module *m; 850 char *name; 851 852 if (argc != 2) 853 return print_usage("modinfo"); 854 855 if (scan_module_folders()) 856 return -1; 857 858 name = get_module_name(argv[1]); 859 m = find_module(name); 860 if (!m) { 861 ULOG_ERR("cannot find module - %s\n", argv[1]); 862 return -1; 863 } 864 865 name = get_module_path(m->name); 866 if (!name) { 867 ULOG_ERR("cannot find path of module - %s\n", m->name); 868 return -1; 869 } 870 871 print_modinfo(name); 872 873 return 0; 874 } 875 876 static int main_modprobe(int argc, char **argv) 877 { 878 struct module_node *mn; 879 struct module *m; 880 int exit_code = 0; 881 int load_fail; 882 int log_level = LOG_WARNING; 883 int opt; 884 bool quiet = false; 885 bool use_all = false; 886 887 while ((opt = getopt(argc, argv, "aqv")) != -1 ) { 888 switch (opt) { 889 case 'a': 890 use_all = true; 891 break; 892 case 'q': /* shhhh! */ 893 quiet = true; 894 break; 895 case 'v': 896 log_level = LOG_DEBUG; 897 break; 898 default: /* '?' */ 899 return print_modprobe_usage(); 900 break; 901 } 902 } 903 904 if (optind >= argc) 905 return print_modprobe_usage(); /* expected module after options */ 906 907 /* after print_modprobe_usage() so it won't be filtered out */ 908 ulog_threshold(log_level); 909 910 if (scan_module_folders()) 911 return -1; 912 913 if (scan_loaded_modules()) 914 return -1; 915 916 do { 917 char *name; 918 919 name = get_module_name(argv[optind]); 920 m = find_module(name); 921 922 if (m && m->state == BLACKLISTED) { 923 if (!quiet) 924 ULOG_INFO("%s is blacklisted\n", name); 925 } else if (m && m->state == LOADED) { 926 if (!quiet) 927 ULOG_INFO("%s is already loaded\n", name); 928 } else if (!m) { 929 if (!quiet) 930 ULOG_ERR("failed to find a module named %s\n", name); 931 exit_code = -1; 932 } else { 933 m->state = PROBE; 934 } 935 936 optind++; 937 } while (use_all && optind < argc); 938 939 load_fail = load_modprobe(true); 940 if (load_fail) { 941 ULOG_ERR("%d module%s could not be probed\n", 942 load_fail, (load_fail == 1) ? ("") : ("s")); 943 944 avl_for_each_element(&modules, mn, avl) { 945 if (mn->is_alias) 946 continue; 947 m = mn->m; 948 if ((m->state == PROBE) || m->error) 949 ULOG_ERR("- %s\n", m->name); 950 } 951 952 exit_code = -1; 953 } 954 955 free_modules(); 956 957 return exit_code; 958 } 959 960 static int main_loader(int argc, char **argv) 961 { 962 int gl_flags = GLOB_NOESCAPE | GLOB_MARK; 963 char *dir = "/etc/modules.d/"; 964 struct module_node *mn; 965 struct module *m; 966 glob_t gl; 967 char *path; 968 int fail, j; 969 970 if (argc > 1) 971 dir = argv[1]; 972 973 path = malloc(strlen(dir) + 2); 974 if (!path) { 975 ULOG_ERR("out of memory\n"); 976 return -1; 977 } 978 979 strcpy(path, dir); 980 strcat(path, "*"); 981 982 if (scan_module_folders()) { 983 free (path); 984 return -1; 985 } 986 987 if (scan_loaded_modules()) { 988 free (path); 989 return -1; 990 } 991 992 ULOG_INFO("loading kernel modules from %s\n", path); 993 994 if (glob(path, gl_flags, NULL, &gl) < 0) 995 goto out; 996 997 for (j = 0; j < gl.gl_pathc; j++) { 998 FILE *fp = fopen(gl.gl_pathv[j], "r"); 999 size_t mod_len = 0; 1000 char *mod = NULL; 1001 1002 if (!fp) { 1003 ULOG_ERR("failed to open %s\n", gl.gl_pathv[j]); 1004 continue; 1005 } 1006 1007 while (getline(&mod, &mod_len, fp) > 0) { 1008 char *nl = strchr(mod, '\n'); 1009 struct module *m; 1010 char *opts; 1011 1012 if (nl) 1013 *nl = '\0'; 1014 1015 opts = strchr(mod, ' '); 1016 if (opts) 1017 *opts++ = '\0'; 1018 1019 m = find_module(get_module_name(mod)); 1020 if (!m || m->state == LOADED || m->state == BLACKLISTED) 1021 continue; 1022 1023 if (opts) { 1024 if (m->opts) { 1025 char *prev = m->opts; 1026 1027 asprintf(&m->opts, "%s %s", prev, opts); 1028 free(prev); 1029 } else { 1030 m->opts = strdup(opts); 1031 } 1032 } 1033 m->state = PROBE; 1034 if (basename(gl.gl_pathv[j])[0] - '' <= 9) 1035 load_modprobe(false); 1036 1037 } 1038 free(mod); 1039 fclose(fp); 1040 } 1041 1042 fail = load_modprobe(true); 1043 1044 if (fail) { 1045 ULOG_ERR("%d module%s could not be probed\n", 1046 fail, (fail == 1) ? ("") : ("s")); 1047 1048 avl_for_each_element(&modules, mn, avl) { 1049 if (mn->is_alias) 1050 continue; 1051 m = mn->m; 1052 if ((m->state == PROBE) || (m->error)) 1053 ULOG_ERR("- %s - %d\n", m->name, deps_available(m, 1)); 1054 } 1055 } else { 1056 ULOG_INFO("done loading kernel modules from %s\n", path); 1057 } 1058 1059 out: 1060 globfree(&gl); 1061 free(path); 1062 1063 return 0; 1064 } 1065 1066 static inline char weight(char c) 1067 { 1068 return c == '_' ? '-' : c; 1069 } 1070 1071 static int avl_modcmp(const void *k1, const void *k2, void *ptr) 1072 { 1073 const char *s1 = k1; 1074 const char *s2 = k2; 1075 1076 while (*s1 && (weight(*s1) == weight(*s2))) 1077 { 1078 s1++; 1079 s2++; 1080 } 1081 1082 return (unsigned char)weight(*s1) - (unsigned char)weight(*s2); 1083 } 1084 1085 static void 1086 load_options(void) 1087 { 1088 static char buf[512]; 1089 char *s; 1090 FILE *f; 1091 1092 f = fopen("/etc/modules.conf", "r"); 1093 if (!f) 1094 return; 1095 1096 while ((s = fgets(buf, sizeof(buf), f)) != NULL) { 1097 char *c, *cmd, *mod; 1098 1099 while (isspace(*s)) 1100 s++; 1101 1102 c = strchr(s, '#'); 1103 if (c) 1104 *c = 0; 1105 1106 while (isspace(*s)) 1107 s++; 1108 1109 c = s + strlen(s); 1110 while (c > s && isspace(c[-1])) { 1111 c[-1] = 0; 1112 c--; 1113 } 1114 1115 cmd = strsep(&s, " \t"); 1116 if (!cmd || !*cmd) 1117 continue; 1118 1119 while (isspace(*s)) 1120 s++; 1121 1122 mod = strsep(&s, " \t"); 1123 if (!mod || !*mod) 1124 continue; 1125 1126 if (!strcmp(cmd, "blacklist")) { 1127 kvlist_set(&options, mod, "\x01"); 1128 continue; 1129 } 1130 1131 if (!strcmp(cmd, "options")) { 1132 char *prev = kvlist_get(&options, mod); 1133 char *val = NULL; 1134 1135 while (isspace(*s)) 1136 s++; 1137 1138 if (!*s) 1139 continue; 1140 1141 if (prev && prev[0] == '\x01') 1142 continue; 1143 1144 if (!prev) { 1145 kvlist_set(&options, mod, s); 1146 continue; 1147 } 1148 1149 if (asprintf(&val, "%s %s", prev, s) < 0) 1150 continue; 1151 1152 kvlist_set(&options, mod, val); 1153 free(val); 1154 continue; 1155 } 1156 } 1157 } 1158 1159 int main(int argc, char **argv) 1160 { 1161 char *exec = basename(*argv); 1162 1163 avl_init(&modules, avl_modcmp, false, NULL); 1164 if (!strcmp(exec, "insmod")) 1165 return main_insmod(argc, argv); 1166 1167 if (!strcmp(exec, "rmmod")) 1168 return main_rmmod(argc, argv); 1169 1170 if (!strcmp(exec, "lsmod")) 1171 return main_lsmod(argc, argv); 1172 1173 if (!strcmp(exec, "modinfo")) 1174 return main_modinfo(argc, argv); 1175 1176 load_options(); 1177 1178 if (!strcmp(exec, "modprobe")) 1179 return main_modprobe(argc, argv); 1180 1181 ulog_open(ULOG_KMSG, LOG_USER, "kmodloader"); 1182 return main_loader(argc, argv); 1183 } 1184
This page was automatically generated by LXR 0.3.1. • OpenWrt