logd: add udebug support
[project/ubox.git] / kmodloader.c
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] - '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 }