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 if (!n) { 340 ULOG_ERR("Failed to allocate memory for module\n"); 341 return -1; 342 } 343 344 n->usage = m.usage; 345 n->state = LOADED; 346 } 347 free(buf); 348 fclose(fp); 349 350 return 0; 351 } 352 353 static struct module* get_module_info(const char *module, const char *name) 354 { 355 int fd = open(module, O_RDONLY); 356 unsigned int offset, size; 357 char *map = MAP_FAILED, *strings, *dep = NULL; 358 const char **aliases = NULL; 359 const char **aliasesr; 360 int naliases = 0; 361 struct module *m = NULL; 362 struct stat s; 363 364 if (fd < 0) { 365 ULOG_ERR("failed to open %s\n", module); 366 goto out; 367 } 368 369 if (fstat(fd, &s) == -1) { 370 ULOG_ERR("failed to stat %s\n", module); 371 goto out; 372 } 373 374 map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 375 if (map == MAP_FAILED) { 376 ULOG_ERR("failed to mmap %s\n", module); 377 goto out; 378 } 379 380 if (elf_find_section(map, ".modinfo", &offset, &size)) { 381 ULOG_ERR("failed to load the .modinfo section from %s\n", module); 382 goto out; 383 } 384 385 strings = map + offset; 386 while (true) { 387 char *sep; 388 int len; 389 390 while (!strings[0]) 391 strings++; 392 if (strings >= map + offset + size) 393 break; 394 sep = strstr(strings, "="); 395 if (!sep) 396 break; 397 len = sep - strings; 398 sep++; 399 if (!strncmp(strings, "depends=", len + 1)) 400 dep = sep; 401 else if (!strncmp(strings, "alias=", len + 1)) { 402 aliasesr = realloc(aliases, sizeof(sep) * (naliases + 1)); 403 if (!aliasesr) { 404 ULOG_ERR("out of memory\n"); 405 goto out; 406 } 407 408 aliases = aliasesr; 409 aliases[naliases++] = sep; 410 } 411 strings = &sep[strlen(sep)]; 412 } 413 414 m = alloc_module(name, aliases, naliases, dep, s.st_size); 415 416 if (m) 417 m->state = SCANNED; 418 419 out: 420 if (map != MAP_FAILED) 421 munmap(map, s.st_size); 422 423 if (fd >= 0) 424 close(fd); 425 426 free(aliases); 427 428 return m; 429 } 430 431 static int scan_module_folder(const char *dir) 432 { 433 int gl_flags = GLOB_NOESCAPE | GLOB_MARK; 434 struct utsname ver; 435 char *path; 436 glob_t gl; 437 int j, rv = 0; 438 439 uname(&ver); 440 path = alloca(strlen(dir) + sizeof("*.ko") + 1); 441 sprintf(path, "%s*.ko", dir); 442 443 if (glob(path, gl_flags, NULL, &gl) < 0) 444 return -1; 445 446 for (j = 0; j < gl.gl_pathc; j++) { 447 char *name = get_module_name(gl.gl_pathv[j]); 448 struct module *m; 449 char *opts; 450 451 if (!name) 452 continue; 453 454 m = find_module(name); 455 if (m) 456 continue; 457 458 m = get_module_info(gl.gl_pathv[j], name); 459 if (!m) { 460 rv |= -1; 461 continue; 462 } 463 464 opts = kvlist_get(&options, name); 465 if (!opts) 466 continue; 467 468 if (*opts == '\x01') 469 m->state = BLACKLISTED; 470 else 471 m->opts = strdup(opts); 472 } 473 474 globfree(&gl); 475 476 return rv; 477 } 478 479 static int scan_module_folders(void) 480 { 481 int rv = 0; 482 char **p; 483 484 if (init_module_folders()) 485 return -1; 486 487 for (p = module_folders; *p; p++) 488 rv |= scan_module_folder(*p); 489 490 return rv; 491 } 492 493 static int print_modinfo(char *module) 494 { 495 int fd = open(module, O_RDONLY); 496 unsigned int offset, size; 497 struct stat s; 498 char *map = MAP_FAILED, *strings; 499 int rv = -1; 500 501 if (fd < 0) { 502 ULOG_ERR("failed to open %s\n", module); 503 goto out; 504 } 505 506 if (fstat(fd, &s) == -1) { 507 ULOG_ERR("failed to stat %s\n", module); 508 goto out; 509 } 510 511 map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 512 if (map == MAP_FAILED) { 513 ULOG_ERR("failed to mmap %s\n", module); 514 goto out; 515 } 516 517 if (elf_find_section(map, ".modinfo", &offset, &size)) { 518 ULOG_ERR("failed to load the .modinfo section from %s\n", module); 519 goto out; 520 } 521 522 strings = map + offset; 523 printf("module:\t\t%s\n", module); 524 while (true) { 525 char *dup = NULL; 526 char *sep; 527 528 while (!strings[0]) 529 strings++; 530 if (strings >= map + offset + size) 531 break; 532 sep = strstr(strings, "="); 533 if (!sep) 534 break; 535 dup = strndup(strings, sep - strings); 536 sep++; 537 if (strncmp(strings, "parm", 4)) { 538 if (strlen(dup) < 7) 539 printf("%s:\t\t%s\n", dup, sep); 540 else 541 printf("%s:\t%s\n", dup, sep); 542 } 543 strings = &sep[strlen(sep)]; 544 if (dup) 545 free(dup); 546 } 547 548 rv = 0; 549 550 out: 551 if (map != MAP_FAILED) 552 munmap(map, s.st_size); 553 554 if (fd >= 0) 555 close(fd); 556 557 return rv; 558 } 559 560 static int deps_available(struct module *m, int verbose) 561 { 562 char *dep; 563 int err = 0; 564 565 if (!m->depends || !strcmp(m->depends, "-") || !strcmp(m->depends, "")) 566 return 0; 567 568 dep = m->depends; 569 570 while (*dep) { 571 m = find_module(dep); 572 573 if (verbose && !m) 574 ULOG_ERR("missing dependency %s\n", dep); 575 if (verbose && m && (m->state != LOADED)) 576 ULOG_ERR("dependency not loaded %s\n", dep); 577 if (!m || (m->state != LOADED)) 578 err++; 579 dep += strlen(dep) + 1; 580 } 581 582 return err; 583 } 584 585 static int insert_module(char *path, const char *options) 586 { 587 void *data = 0; 588 struct stat s; 589 int fd, ret = -1; 590 591 if (!path) { 592 ULOG_ERR("Path not specified\n"); 593 return ret; 594 } 595 596 if (stat(path, &s)) { 597 ULOG_ERR("missing module %s\n", path); 598 return ret; 599 } 600 601 fd = open(path, O_RDONLY); 602 if (fd < 0) { 603 ULOG_ERR("cannot open %s\n", path); 604 return ret; 605 } 606 607 data = malloc(s.st_size); 608 if (!data) { 609 ULOG_ERR("out of memory\n"); 610 goto out; 611 } 612 613 if (read(fd, data, s.st_size) == s.st_size) { 614 ret = syscall(__NR_init_module, data, (unsigned long) s.st_size, options); 615 if (errno == EEXIST) 616 ret = 0; 617 } 618 else 619 ULOG_ERR("failed to read full module %s\n", path); 620 621 out: 622 close(fd); 623 free(data); 624 625 return ret; 626 } 627 628 static void load_moddeps(struct module *_m) 629 { 630 char *dep; 631 struct module *m; 632 633 if (!strcmp(_m->depends, "-") || !strcmp(_m->depends, "")) 634 return; 635 636 dep = _m->depends; 637 638 while (*dep) { 639 m = find_module(dep); 640 641 if (!m) 642 ULOG_ERR("failed to find dependency %s\n", dep); 643 if (m && (m->state != LOADED)) { 644 m->state = PROBE; 645 load_moddeps(m); 646 } 647 648 dep = dep + strlen(dep) + 1; 649 } 650 } 651 652 static int load_modprobe(bool allow_load_retry) 653 { 654 int loaded, skipped, failed; 655 struct module_node *mn; 656 struct module *m; 657 bool load_retry = false; 658 static bool first_iteration = true; 659 660 avl_for_each_element(&modules, mn, avl) { 661 if (mn->is_alias) 662 continue; 663 m = mn->m; 664 if (m->state == PROBE) 665 load_moddeps(m); 666 } 667 668 do { 669 loaded = 0; 670 skipped = 0; 671 failed = 0; 672 avl_for_each_element(&modules, mn, avl) { 673 if (mn->is_alias) 674 continue; 675 m = mn->m; 676 if ((m->state == PROBE) && (!deps_available(m, 0)) && (!m->error || load_retry)) { 677 if (!insert_module(get_module_path(m->name), (m->opts) ? (m->opts) : (""))) { 678 m->state = LOADED; 679 m->error = 0; 680 loaded++; 681 continue; 682 } 683 684 m->error = 1; 685 } 686 687 if (m->error) 688 failed++; 689 else if (m->state == PROBE) 690 skipped++; 691 } 692 693 if (allow_load_retry) { 694 /* if we can't load anything else let's try to load failed modules */ 695 load_retry = loaded ? (failed && !skipped) : (failed && !load_retry && !first_iteration); 696 } 697 698 first_iteration = false; 699 } while (loaded || load_retry); 700 701 return skipped + failed; 702 } 703 704 static int print_insmod_usage(void) 705 { 706 ULOG_INFO("Usage:\n\tinsmod filename [args]\n"); 707 708 return -1; 709 } 710 711 static int print_modprobe_usage(void) 712 { 713 ULOG_INFO( 714 "Usage:\n" 715 "\tmodprobe [-q] [-v] filename\n" 716 "\tmodprobe -a [-q] [-v] filename [filename...]\n" 717 ); 718 719 return -1; 720 } 721 722 static int print_usage(char *arg) 723 { 724 ULOG_INFO("Usage:\n\t%s module\n", arg); 725 726 return -1; 727 } 728 729 static int main_insmod(int argc, char **argv) 730 { 731 char *name, *cur, *options; 732 int i, ret, len; 733 734 if (argc < 2) 735 return print_insmod_usage(); 736 737 name = get_module_name(argv[1]); 738 if (!name) { 739 ULOG_ERR("cannot find module - %s\n", argv[1]); 740 return -1; 741 } 742 743 if (scan_loaded_modules()) 744 return -1; 745 746 if (find_module(name)) { 747 ULOG_ERR("module is already loaded - %s\n", name); 748 return -1; 749 750 } 751 752 free_modules(); 753 754 for (len = 0, i = 2; i < argc; i++) 755 len += strlen(argv[i]) + 1; 756 757 options = malloc(len); 758 if (!options) { 759 ULOG_ERR("out of memory\n"); 760 ret = -1; 761 goto err; 762 } 763 764 options[0] = 0; 765 cur = options; 766 for (i = 2; i < argc; i++) { 767 if (options[0]) { 768 *cur = ' '; 769 cur++; 770 } 771 cur += sprintf(cur, "%s", argv[i]); 772 } 773 774 if (init_module_folders()) { 775 fprintf(stderr, "Failed to find the folder holding the modules\n"); 776 ret = -1; 777 goto err; 778 } 779 780 if (get_module_path(argv[1])) { 781 name = argv[1]; 782 } else if (!get_module_path(name)) { 783 fprintf(stderr, "Failed to find %s. Maybe it is a built in module ?\n", name); 784 ret = -1; 785 goto err; 786 } 787 788 ret = insert_module(get_module_path(name), options); 789 if (ret) 790 ULOG_ERR("failed to insert %s\n", get_module_path(name)); 791 792 err: 793 free(options); 794 return ret; 795 } 796 797 static int main_rmmod(int argc, char **argv) 798 { 799 struct module *m; 800 char *name; 801 int ret; 802 803 if (argc != 2) 804 return print_usage("rmmod"); 805 806 if (scan_loaded_modules()) 807 return -1; 808 809 name = get_module_name(argv[1]); 810 m = find_module(name); 811 if (!m) { 812 ULOG_ERR("module is not loaded\n"); 813 return -1; 814 } 815 ret = syscall(__NR_delete_module, m->name, 0); 816 817 if (ret) 818 ULOG_ERR("unloading the module failed\n"); 819 820 free_modules(); 821 822 return ret; 823 } 824 825 static int main_lsmod(int argc, char **argv) 826 { 827 struct module_node *mn; 828 struct module *m; 829 char *dep; 830 831 if (scan_loaded_modules()) 832 return -1; 833 834 avl_for_each_element(&modules, mn, avl) { 835 if (mn->is_alias) 836 continue; 837 m = mn->m; 838 if (m->state == LOADED) { 839 printf("%-20s%8d%3d ", 840 m->name, m->size, m->usage); 841 if (m->depends && strcmp(m->depends, "-") && strcmp(m->depends, "")) { 842 dep = m->depends; 843 while (*dep) { 844 printf("%s", dep); 845 dep = dep + strlen(dep) + 1; 846 if (*dep) 847 printf(","); 848 } 849 } 850 printf("\n"); 851 } 852 } 853 854 free_modules(); 855 856 return 0; 857 } 858 859 static int main_modinfo(int argc, char **argv) 860 { 861 struct module *m; 862 char *name; 863 864 if (argc != 2) 865 return print_usage("modinfo"); 866 867 if (scan_module_folders()) 868 return -1; 869 870 name = get_module_name(argv[1]); 871 m = find_module(name); 872 if (!m) { 873 ULOG_ERR("cannot find module - %s\n", argv[1]); 874 return -1; 875 } 876 877 name = get_module_path(m->name); 878 if (!name) { 879 ULOG_ERR("cannot find path of module - %s\n", m->name); 880 return -1; 881 } 882 883 print_modinfo(name); 884 885 return 0; 886 } 887 888 static int main_modprobe(int argc, char **argv) 889 { 890 struct module_node *mn; 891 struct module *m; 892 int exit_code = 0; 893 int load_fail; 894 int log_level = LOG_WARNING; 895 int opt; 896 bool quiet = false; 897 bool use_all = false; 898 899 while ((opt = getopt(argc, argv, "aqv")) != -1 ) { 900 switch (opt) { 901 case 'a': 902 use_all = true; 903 break; 904 case 'q': /* shhhh! */ 905 quiet = true; 906 break; 907 case 'v': 908 log_level = LOG_DEBUG; 909 break; 910 default: /* '?' */ 911 return print_modprobe_usage(); 912 break; 913 } 914 } 915 916 if (optind >= argc) 917 return print_modprobe_usage(); /* expected module after options */ 918 919 /* after print_modprobe_usage() so it won't be filtered out */ 920 ulog_threshold(log_level); 921 922 if (scan_module_folders()) 923 return -1; 924 925 if (scan_loaded_modules()) 926 return -1; 927 928 do { 929 char *name; 930 931 name = get_module_name(argv[optind]); 932 m = find_module(name); 933 934 if (m && m->state == BLACKLISTED) { 935 if (!quiet) 936 ULOG_INFO("%s is blacklisted\n", name); 937 } else if (m && m->state == LOADED) { 938 if (!quiet) 939 ULOG_INFO("%s is already loaded\n", name); 940 } else if (!m) { 941 if (!quiet) 942 ULOG_ERR("failed to find a module named %s\n", name); 943 exit_code = -1; 944 } else { 945 m->state = PROBE; 946 } 947 948 optind++; 949 } while (use_all && optind < argc); 950 951 load_fail = load_modprobe(true); 952 if (load_fail) { 953 ULOG_ERR("%d module%s could not be probed\n", 954 load_fail, (load_fail == 1) ? ("") : ("s")); 955 956 avl_for_each_element(&modules, mn, avl) { 957 if (mn->is_alias) 958 continue; 959 m = mn->m; 960 if ((m->state == PROBE) || m->error) 961 ULOG_ERR("- %s\n", m->name); 962 } 963 964 exit_code = -1; 965 } 966 967 free_modules(); 968 969 return exit_code; 970 } 971 972 static int main_loader(int argc, char **argv) 973 { 974 int gl_flags = GLOB_NOESCAPE | GLOB_MARK; 975 char *dir = "/etc/modules.d/"; 976 struct module_node *mn; 977 struct module *m; 978 glob_t gl; 979 char *path; 980 int ret = 0, fail, j; 981 982 if (argc > 1) 983 dir = argv[1]; 984 985 path = malloc(strlen(dir) + 2); 986 if (!path) { 987 ULOG_ERR("out of memory\n"); 988 return -1; 989 } 990 991 strcpy(path, dir); 992 strcat(path, "*"); 993 994 if (scan_module_folders()) { 995 ret = -1; 996 goto free_path; 997 } 998 999 if (scan_loaded_modules()) { 1000 ret = -1; 1001 goto free_path; 1002 } 1003 1004 ULOG_INFO("loading kernel modules from %s\n", path); 1005 1006 if (glob(path, gl_flags, NULL, &gl) < 0) 1007 goto out; 1008 1009 for (j = 0; j < gl.gl_pathc; j++) { 1010 FILE *fp = fopen(gl.gl_pathv[j], "r"); 1011 size_t mod_len = 0; 1012 char *mod = NULL; 1013 1014 if (!fp) { 1015 ULOG_ERR("failed to open %s\n", gl.gl_pathv[j]); 1016 continue; 1017 } 1018 1019 while (getline(&mod, &mod_len, fp) > 0) { 1020 char *nl = strchr(mod, '\n'); 1021 struct module *m; 1022 char *opts; 1023 1024 if (nl) 1025 *nl = '\0'; 1026 1027 opts = strchr(mod, ' '); 1028 if (opts) 1029 *opts++ = '\0'; 1030 1031 m = find_module(get_module_name(mod)); 1032 if (!m || m->state == LOADED || m->state == BLACKLISTED) 1033 continue; 1034 1035 if (opts) { 1036 if (m->opts) { 1037 char *prev = m->opts; 1038 1039 fail = asprintf(&m->opts, "%s %s", prev, opts); 1040 free(prev); 1041 if (fail < 0) { 1042 ULOG_ERR("out of memory for opts %s\n", opts); 1043 free(mod); 1044 fclose(fp); 1045 ret = -1; 1046 goto out; 1047 } 1048 } else { 1049 m->opts = strdup(opts); 1050 } 1051 } 1052 m->state = PROBE; 1053 if (basename(gl.gl_pathv[j])[0] - '' <= 9) 1054 load_modprobe(false); 1055 1056 } 1057 free(mod); 1058 fclose(fp); 1059 } 1060 1061 fail = load_modprobe(true); 1062 1063 if (fail) { 1064 ULOG_ERR("%d module%s could not be probed\n", 1065 fail, (fail == 1) ? ("") : ("s")); 1066 1067 avl_for_each_element(&modules, mn, avl) { 1068 if (mn->is_alias) 1069 continue; 1070 m = mn->m; 1071 if ((m->state == PROBE) || (m->error)) 1072 ULOG_ERR("- %s - %d\n", m->name, deps_available(m, 1)); 1073 } 1074 } else { 1075 ULOG_INFO("done loading kernel modules from %s\n", path); 1076 } 1077 1078 out: 1079 globfree(&gl); 1080 free_path: 1081 free(path); 1082 1083 return ret; 1084 } 1085 1086 static inline char weight(char c) 1087 { 1088 return c == '_' ? '-' : c; 1089 } 1090 1091 static int avl_modcmp(const void *k1, const void *k2, void *ptr) 1092 { 1093 const char *s1 = k1; 1094 const char *s2 = k2; 1095 1096 while (*s1 && (weight(*s1) == weight(*s2))) 1097 { 1098 s1++; 1099 s2++; 1100 } 1101 1102 return (unsigned char)weight(*s1) - (unsigned char)weight(*s2); 1103 } 1104 1105 static void 1106 load_options(void) 1107 { 1108 static char buf[512]; 1109 char *s; 1110 FILE *f; 1111 1112 f = fopen("/etc/modules.conf", "r"); 1113 if (!f) 1114 return; 1115 1116 while ((s = fgets(buf, sizeof(buf), f)) != NULL) { 1117 char *c, *cmd, *mod; 1118 1119 while (isspace(*s)) 1120 s++; 1121 1122 c = strchr(s, '#'); 1123 if (c) 1124 *c = 0; 1125 1126 while (isspace(*s)) 1127 s++; 1128 1129 c = s + strlen(s); 1130 while (c > s && isspace(c[-1])) { 1131 c[-1] = 0; 1132 c--; 1133 } 1134 1135 cmd = strsep(&s, " \t"); 1136 if (!cmd || !*cmd) 1137 continue; 1138 1139 while (isspace(*s)) 1140 s++; 1141 1142 mod = strsep(&s, " \t"); 1143 if (!mod || !*mod) 1144 continue; 1145 1146 if (!strcmp(cmd, "blacklist")) { 1147 kvlist_set(&options, mod, "\x01"); 1148 continue; 1149 } 1150 1151 if (!strcmp(cmd, "options")) { 1152 char *prev = kvlist_get(&options, mod); 1153 char *val = NULL; 1154 1155 while (isspace(*s)) 1156 s++; 1157 1158 if (!*s) 1159 continue; 1160 1161 if (prev && prev[0] == '\x01') 1162 continue; 1163 1164 if (!prev) { 1165 kvlist_set(&options, mod, s); 1166 continue; 1167 } 1168 1169 if (asprintf(&val, "%s %s", prev, s) < 0) 1170 continue; 1171 1172 kvlist_set(&options, mod, val); 1173 free(val); 1174 continue; 1175 } 1176 } 1177 1178 fclose(f); 1179 } 1180 1181 int main(int argc, char **argv) 1182 { 1183 char *exec = basename(*argv); 1184 1185 avl_init(&modules, avl_modcmp, false, NULL); 1186 if (!strcmp(exec, "insmod")) 1187 return main_insmod(argc, argv); 1188 1189 if (!strcmp(exec, "rmmod")) 1190 return main_rmmod(argc, argv); 1191 1192 if (!strcmp(exec, "lsmod")) 1193 return main_lsmod(argc, argv); 1194 1195 if (!strcmp(exec, "modinfo")) 1196 return main_modinfo(argc, argv); 1197 1198 load_options(); 1199 1200 if (!strcmp(exec, "modprobe")) 1201 return main_modprobe(argc, argv); 1202 1203 ulog_open(ULOG_KMSG, LOG_USER, "kmodloader"); 1204 return main_loader(argc, argv); 1205 } 1206
This page was automatically generated by LXR 0.3.1. • OpenWrt