• source navigation  • diff markup  • identifier search  • freetext search  • 

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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt