kmodloader.c 26 KB

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