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