modprobe-small.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * simplified modprobe
  4. *
  5. * Copyright (c) 2008 Vladimir Dronnikov
  6. * Copyright (c) 2008 Bernhard Reutner-Fischer (initial depmod code)
  7. *
  8. * Licensed under GPLv2, see file LICENSE in this source tree.
  9. */
  10. /* modprobe-small configs are defined in Config.src to ensure better
  11. * "make config" order */
  12. //applet:IF_LSMOD( IF_MODPROBE_SMALL(APPLET(lsmod, BB_DIR_SBIN, BB_SUID_DROP)))
  13. //applet:IF_MODPROBE(IF_MODPROBE_SMALL(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP)))
  14. // APPLET_ODDNAME:name main location suid_type help
  15. //applet:IF_DEPMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(depmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, depmod)))
  16. //applet:IF_INSMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, insmod)))
  17. //applet:IF_RMMOD( IF_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, rmmod)))
  18. //kbuild:lib-$(CONFIG_MODPROBE_SMALL) += modprobe-small.o
  19. #include "libbb.h"
  20. /* After libbb.h, since it needs sys/types.h on some systems */
  21. #include <sys/utsname.h> /* uname() */
  22. #include <fnmatch.h>
  23. #include <sys/syscall.h>
  24. #define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
  25. #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
  26. #ifdef __NR_finit_module
  27. # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags)
  28. #endif
  29. /* linux/include/linux/module.h has limit of 64 chars on module names */
  30. #undef MODULE_NAME_LEN
  31. #define MODULE_NAME_LEN 64
  32. #if 1
  33. # define dbg1_error_msg(...) ((void)0)
  34. # define dbg2_error_msg(...) ((void)0)
  35. #else
  36. # define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__)
  37. # define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__)
  38. #endif
  39. #define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb"
  40. //usage:#if ENABLE_MODPROBE_SMALL
  41. //usage:#define lsmod_trivial_usage
  42. //usage: ""
  43. //usage:#define lsmod_full_usage "\n\n"
  44. //usage: "List loaded kernel modules"
  45. //usage:#endif
  46. #if ENABLE_LSMOD
  47. int lsmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  48. int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
  49. {
  50. xprint_and_close_file(xfopen_for_read("/proc/modules"));
  51. return EXIT_SUCCESS;
  52. }
  53. #endif
  54. /* Num of applets that use modprobe_main() entry point. */
  55. /* lsmod is not here. */
  56. #define MOD_APPLET_CNT (ENABLE_MODPROBE + ENABLE_DEPMOD + ENABLE_INSMOD + ENABLE_RMMOD)
  57. /* Do not bother if MODPROBE_SMALL=y but no applets selected. */
  58. /* The rest of the file is in this if block. */
  59. #if MOD_APPLET_CNT > 0
  60. #define ONLY_APPLET (MOD_APPLET_CNT == 1)
  61. #define is_modprobe (ENABLE_MODPROBE && (ONLY_APPLET || applet_name[0] == 'm'))
  62. #define is_depmod (ENABLE_DEPMOD && (ONLY_APPLET || applet_name[0] == 'd'))
  63. #define is_insmod (ENABLE_INSMOD && (ONLY_APPLET || applet_name[0] == 'i'))
  64. #define is_rmmod (ENABLE_RMMOD && (ONLY_APPLET || applet_name[0] == 'r'))
  65. enum {
  66. DEPMOD_OPT_n = (1 << 0), /* dry-run, print to stdout */
  67. OPT_q = (1 << 0), /* be quiet */
  68. OPT_r = (1 << 1), /* module removal instead of loading */
  69. };
  70. typedef struct module_info {
  71. char *pathname;
  72. char *aliases;
  73. char *deps;
  74. smallint open_read_failed;
  75. } module_info;
  76. /*
  77. * GLOBALS
  78. */
  79. struct globals {
  80. module_info *modinfo;
  81. char *module_load_options;
  82. smallint dep_bb_seen;
  83. smallint wrote_dep_bb_ok;
  84. unsigned module_count;
  85. int module_found_idx;
  86. unsigned stringbuf_idx;
  87. unsigned stringbuf_size;
  88. char *stringbuf; /* some modules have lots of stuff */
  89. /* for example, drivers/media/video/saa7134/saa7134.ko */
  90. /* therefore having a fixed biggish buffer is not wise */
  91. };
  92. #define G (*ptr_to_globals)
  93. #define modinfo (G.modinfo )
  94. #define dep_bb_seen (G.dep_bb_seen )
  95. #define wrote_dep_bb_ok (G.wrote_dep_bb_ok )
  96. #define module_count (G.module_count )
  97. #define module_found_idx (G.module_found_idx )
  98. #define module_load_options (G.module_load_options)
  99. #define stringbuf_idx (G.stringbuf_idx )
  100. #define stringbuf_size (G.stringbuf_size )
  101. #define stringbuf (G.stringbuf )
  102. #define INIT_G() do { \
  103. SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
  104. } while (0)
  105. static void append(const char *s)
  106. {
  107. unsigned len = strlen(s);
  108. if (stringbuf_idx + len + 15 > stringbuf_size) {
  109. stringbuf_size = stringbuf_idx + len + 127;
  110. dbg2_error_msg("grow stringbuf to %u", stringbuf_size);
  111. stringbuf = xrealloc(stringbuf, stringbuf_size);
  112. }
  113. memcpy(stringbuf + stringbuf_idx, s, len);
  114. stringbuf_idx += len;
  115. }
  116. static void appendc(char c)
  117. {
  118. /* We appendc() only after append(), + 15 trick in append()
  119. * makes it unnecessary to check for overflow here */
  120. stringbuf[stringbuf_idx++] = c;
  121. }
  122. static void bksp(void)
  123. {
  124. if (stringbuf_idx)
  125. stringbuf_idx--;
  126. }
  127. static void reset_stringbuf(void)
  128. {
  129. stringbuf_idx = 0;
  130. }
  131. static char* copy_stringbuf(void)
  132. {
  133. char *copy = xzalloc(stringbuf_idx + 1); /* terminating NUL */
  134. return memcpy(copy, stringbuf, stringbuf_idx);
  135. }
  136. static char* find_keyword(char *ptr, size_t len, const char *word)
  137. {
  138. if (!ptr) /* happens if xmalloc_open_zipped_read_close cannot read it */
  139. return NULL;
  140. len -= strlen(word) - 1;
  141. while ((ssize_t)len > 0) {
  142. char *old = ptr;
  143. char *after_word;
  144. /* search for the first char in word */
  145. ptr = memchr(ptr, word[0], len);
  146. if (ptr == NULL) /* no occurrence left, done */
  147. break;
  148. after_word = is_prefixed_with(ptr, word);
  149. if (after_word)
  150. return after_word; /* found, return ptr past it */
  151. ++ptr;
  152. len -= (ptr - old);
  153. }
  154. return NULL;
  155. }
  156. static void replace(char *s, char what, char with)
  157. {
  158. while (*s) {
  159. if (what == *s)
  160. *s = with;
  161. ++s;
  162. }
  163. }
  164. static char *filename2modname(const char *filename, char *modname)
  165. {
  166. int i;
  167. const char *from;
  168. // Disabled since otherwise "modprobe dir/name" would work
  169. // as if it is "modprobe name". It is unclear why
  170. // 'basenamization' was here in the first place.
  171. //from = bb_get_last_path_component_nostrip(filename);
  172. from = filename;
  173. for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '\0' && from[i] != '.'; i++)
  174. modname[i] = (from[i] == '-') ? '_' : from[i];
  175. modname[i] = '\0';
  176. return modname;
  177. }
  178. static int pathname_matches_modname(const char *pathname, const char *modname)
  179. {
  180. int r;
  181. char name[MODULE_NAME_LEN];
  182. filename2modname(bb_get_last_path_component_nostrip(pathname), name);
  183. r = (strcmp(name, modname) == 0);
  184. return r;
  185. }
  186. /* Take "word word", return malloced "word",NUL,"word",NUL,NUL */
  187. static char* str_2_list(const char *str)
  188. {
  189. int len = strlen(str) + 1;
  190. char *dst = xmalloc(len + 1);
  191. dst[len] = '\0';
  192. memcpy(dst, str, len);
  193. //TODO: protect against 2+ spaces: "word word"
  194. replace(dst, ' ', '\0');
  195. return dst;
  196. }
  197. /* We use error numbers in a loose translation... */
  198. static const char *moderror(int err)
  199. {
  200. switch (err) {
  201. case ENOEXEC:
  202. return "invalid module format";
  203. case ENOENT:
  204. return "unknown symbol in module or invalid parameter";
  205. case ESRCH:
  206. return "module has wrong symbol version";
  207. case EINVAL: /* "invalid parameter" */
  208. return "unknown symbol in module or invalid parameter"
  209. + sizeof("unknown symbol in module or");
  210. default:
  211. return strerror(err);
  212. }
  213. }
  214. static int load_module(const char *fname, const char *options)
  215. {
  216. #if 1
  217. int r;
  218. size_t len = MAXINT(ssize_t);
  219. char *module_image;
  220. if (!options)
  221. options = "";
  222. dbg1_error_msg("load_module('%s','%s')", fname, options);
  223. /*
  224. * First we try finit_module if available. Some kernels are configured
  225. * to only allow loading of modules off of secure storage (like a read-
  226. * only rootfs) which needs the finit_module call. If it fails, we fall
  227. * back to normal module loading to support compressed modules.
  228. */
  229. r = 1;
  230. # ifdef __NR_finit_module
  231. {
  232. int fd = open(fname, O_RDONLY | O_CLOEXEC);
  233. if (fd >= 0) {
  234. r = finit_module(fd, options, 0) != 0;
  235. close(fd);
  236. }
  237. }
  238. # endif
  239. if (r != 0) {
  240. module_image = xmalloc_open_zipped_read_close(fname, &len);
  241. r = (!module_image || init_module(module_image, len, options) != 0);
  242. free(module_image);
  243. }
  244. dbg1_error_msg("load_module:%d", r);
  245. return r; /* 0 = success */
  246. #else
  247. /* For testing */
  248. dbg1_error_msg("load_module('%s','%s')", fname, options);
  249. return 1;
  250. #endif
  251. }
  252. /* Returns !0 if open/read was unsuccessful */
  253. static int parse_module(module_info *info, const char *pathname)
  254. {
  255. char *module_image;
  256. char *ptr;
  257. size_t len;
  258. size_t pos;
  259. dbg1_error_msg("parse_module('%s')", pathname);
  260. /* Read (possibly compressed) module */
  261. errno = 0;
  262. len = 64 * 1024 * 1024; /* 64 Mb at most */
  263. module_image = xmalloc_open_zipped_read_close(pathname, &len);
  264. /* module_image == NULL is ok here, find_keyword handles it */
  265. //TODO: optimize redundant module body reads
  266. /* "alias1 symbol:sym1 alias2 symbol:sym2" */
  267. reset_stringbuf();
  268. pos = 0;
  269. while (1) {
  270. unsigned start = stringbuf_idx;
  271. ptr = find_keyword(module_image + pos, len - pos, "alias=");
  272. if (!ptr) {
  273. ptr = find_keyword(module_image + pos, len - pos, "__ksymtab_");
  274. if (!ptr)
  275. break;
  276. /* DOCME: __ksymtab_gpl and __ksymtab_strings occur
  277. * in many modules. What do they mean? */
  278. if (strcmp(ptr, "gpl") == 0 || strcmp(ptr, "strings") == 0)
  279. goto skip;
  280. dbg2_error_msg("alias:'symbol:%s'", ptr);
  281. append("symbol:");
  282. } else {
  283. dbg2_error_msg("alias:'%s'", ptr);
  284. }
  285. append(ptr);
  286. appendc(' ');
  287. /*
  288. * Don't add redundant aliases, such as:
  289. * libcrc32c.ko symbol:crc32c symbol:crc32c
  290. */
  291. if (start) { /* "if we aren't the first alias" */
  292. char *found, *last;
  293. stringbuf[stringbuf_idx] = '\0';
  294. last = stringbuf + start;
  295. /*
  296. * String at last-1 is " symbol:crc32c "
  297. * (with both leading and trailing spaces).
  298. */
  299. if (strncmp(stringbuf, last, stringbuf_idx - start) == 0)
  300. /* First alias matches us */
  301. found = stringbuf;
  302. else
  303. /* Does any other alias match? */
  304. found = strstr(stringbuf, last-1);
  305. if (found < last-1) {
  306. /* There is absolutely the same string before us */
  307. dbg2_error_msg("redundant:'%s'", last);
  308. stringbuf_idx = start;
  309. goto skip;
  310. }
  311. }
  312. skip:
  313. pos = (ptr - module_image);
  314. }
  315. bksp(); /* remove last ' ' */
  316. info->aliases = copy_stringbuf();
  317. replace(info->aliases, '-', '_');
  318. /* "dependency1 depandency2" */
  319. reset_stringbuf();
  320. ptr = find_keyword(module_image, len, "depends=");
  321. if (ptr && *ptr) {
  322. replace(ptr, ',', ' ');
  323. replace(ptr, '-', '_');
  324. dbg2_error_msg("dep:'%s'", ptr);
  325. append(ptr);
  326. }
  327. free(module_image);
  328. info->deps = copy_stringbuf();
  329. info->open_read_failed = (module_image == NULL);
  330. return info->open_read_failed;
  331. }
  332. static FAST_FUNC int fileAction(const char *pathname,
  333. struct stat *sb UNUSED_PARAM,
  334. void *modname_to_match,
  335. int depth UNUSED_PARAM)
  336. {
  337. int cur;
  338. const char *fname;
  339. bool is_remove = (ENABLE_RMMOD && ONLY_APPLET)
  340. || ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r));
  341. pathname += 2; /* skip "./" */
  342. fname = bb_get_last_path_component_nostrip(pathname);
  343. if (!strrstr(fname, ".ko")) {
  344. dbg1_error_msg("'%s' is not a module", pathname);
  345. return TRUE; /* not a module, continue search */
  346. }
  347. cur = module_count++;
  348. modinfo = xrealloc_vector(modinfo, 12, cur);
  349. modinfo[cur].pathname = xstrdup(pathname);
  350. /*modinfo[cur].aliases = NULL; - xrealloc_vector did it */
  351. /*modinfo[cur+1].pathname = NULL;*/
  352. if (!pathname_matches_modname(fname, modname_to_match)) {
  353. dbg1_error_msg("'%s' module name doesn't match", pathname);
  354. return TRUE; /* module name doesn't match, continue search */
  355. }
  356. dbg1_error_msg("'%s' module name matches", pathname);
  357. module_found_idx = cur;
  358. if (parse_module(&modinfo[cur], pathname) != 0)
  359. return TRUE; /* failed to open/read it, no point in trying loading */
  360. if (!is_remove) {
  361. if (load_module(pathname, module_load_options) == 0) {
  362. /* Load was successful, there is nothing else to do.
  363. * This can happen ONLY for "top-level" module load,
  364. * not a dep, because deps don't do dirscan. */
  365. exit(EXIT_SUCCESS);
  366. }
  367. }
  368. return TRUE;
  369. }
  370. static int load_dep_bb(void)
  371. {
  372. char *line;
  373. FILE *fp = fopen_for_read(DEPFILE_BB);
  374. if (!fp)
  375. return 0;
  376. dep_bb_seen = 1;
  377. dbg1_error_msg("loading "DEPFILE_BB);
  378. /* Why? There is a rare scenario: we did not find modprobe.dep.bb,
  379. * we scanned the dir and found no module by name, then we search
  380. * for alias (full scan), and we decided to generate modprobe.dep.bb.
  381. * But we see modprobe.dep.bb.new! Other modprobe is at work!
  382. * We wait and other modprobe renames it to modprobe.dep.bb.
  383. * Now we can use it.
  384. * But we already have modinfo[] filled, and "module_count = 0"
  385. * makes us start anew. Yes, we leak modinfo[].xxx pointers -
  386. * there is not much of data there anyway. */
  387. module_count = 0;
  388. memset(&modinfo[0], 0, sizeof(modinfo[0]));
  389. while ((line = xmalloc_fgetline(fp)) != NULL) {
  390. char* space;
  391. char* linebuf;
  392. int cur;
  393. if (!line[0]) {
  394. free(line);
  395. continue;
  396. }
  397. space = strchrnul(line, ' ');
  398. cur = module_count++;
  399. modinfo = xrealloc_vector(modinfo, 12, cur);
  400. /*modinfo[cur+1].pathname = NULL; - xrealloc_vector did it */
  401. modinfo[cur].pathname = line; /* we take ownership of malloced block here */
  402. if (*space)
  403. *space++ = '\0';
  404. modinfo[cur].aliases = space;
  405. linebuf = xmalloc_fgetline(fp);
  406. modinfo[cur].deps = linebuf ? linebuf : xzalloc(1);
  407. if (modinfo[cur].deps[0]) {
  408. /* deps are not "", so next line must be empty */
  409. line = xmalloc_fgetline(fp);
  410. /* Refuse to work with damaged config file */
  411. if (line && line[0])
  412. bb_error_msg_and_die("error in %s at '%s'", DEPFILE_BB, line);
  413. free(line);
  414. }
  415. }
  416. return 1;
  417. }
  418. static int start_dep_bb_writeout(void)
  419. {
  420. int fd;
  421. /* depmod -n: write result to stdout */
  422. if (is_depmod && (option_mask32 & DEPMOD_OPT_n))
  423. return STDOUT_FILENO;
  424. fd = open(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644);
  425. if (fd < 0) {
  426. if (errno == EEXIST) {
  427. int count = 5 * 20;
  428. dbg1_error_msg(DEPFILE_BB".new exists, waiting for "DEPFILE_BB);
  429. while (1) {
  430. usleep(1000*1000 / 20);
  431. if (load_dep_bb()) {
  432. dbg1_error_msg(DEPFILE_BB" appeared");
  433. return -2; /* magic number */
  434. }
  435. if (!--count)
  436. break;
  437. }
  438. bb_error_msg("deleting stale %s", DEPFILE_BB".new");
  439. fd = open_or_warn(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC);
  440. }
  441. }
  442. dbg1_error_msg("opened "DEPFILE_BB".new:%d", fd);
  443. return fd;
  444. }
  445. static void write_out_dep_bb(int fd)
  446. {
  447. int i;
  448. FILE *fp;
  449. /* We want good error reporting. fdprintf is not good enough. */
  450. fp = xfdopen_for_write(fd);
  451. i = 0;
  452. while (modinfo[i].pathname) {
  453. fprintf(fp, "%s%s%s\n" "%s%s\n",
  454. modinfo[i].pathname, modinfo[i].aliases[0] ? " " : "", modinfo[i].aliases,
  455. modinfo[i].deps, modinfo[i].deps[0] ? "\n" : "");
  456. i++;
  457. }
  458. /* Badly formatted depfile is a no-no. Be paranoid. */
  459. errno = 0;
  460. if (ferror(fp) | fclose(fp)) /* | instead of || is intended */
  461. goto err;
  462. if (fd == STDOUT_FILENO) /* it was depmod -n */
  463. goto ok;
  464. if (rename(DEPFILE_BB".new", DEPFILE_BB) != 0) {
  465. err:
  466. bb_perror_msg("can't create '%s'", DEPFILE_BB);
  467. unlink(DEPFILE_BB".new");
  468. } else {
  469. ok:
  470. wrote_dep_bb_ok = 1;
  471. dbg1_error_msg("created "DEPFILE_BB);
  472. }
  473. }
  474. static module_info** find_alias(const char *alias)
  475. {
  476. int i;
  477. int dep_bb_fd;
  478. int infoidx;
  479. module_info **infovec;
  480. dbg1_error_msg("find_alias('%s')", alias);
  481. try_again:
  482. /* First try to find by name (cheaper) */
  483. i = 0;
  484. while (modinfo[i].pathname) {
  485. if (pathname_matches_modname(modinfo[i].pathname, alias)) {
  486. dbg1_error_msg("found '%s' in module '%s'",
  487. alias, modinfo[i].pathname);
  488. if (!modinfo[i].aliases) {
  489. parse_module(&modinfo[i], modinfo[i].pathname);
  490. }
  491. infovec = xzalloc(2 * sizeof(infovec[0]));
  492. infovec[0] = &modinfo[i];
  493. return infovec;
  494. }
  495. i++;
  496. }
  497. /* Ok, we definitely have to scan module bodies. This is a good
  498. * moment to generate modprobe.dep.bb, if it does not exist yet */
  499. dep_bb_fd = dep_bb_seen ? -1 : start_dep_bb_writeout();
  500. if (dep_bb_fd == -2) /* modprobe.dep.bb appeared? */
  501. goto try_again;
  502. /* Scan all module bodies, extract modinfo (it contains aliases) */
  503. i = 0;
  504. infoidx = 0;
  505. infovec = NULL;
  506. while (modinfo[i].pathname) {
  507. char *desc, *s;
  508. if (!modinfo[i].aliases) {
  509. parse_module(&modinfo[i], modinfo[i].pathname);
  510. }
  511. /* "alias1 symbol:sym1 alias2 symbol:sym2" */
  512. desc = str_2_list(modinfo[i].aliases);
  513. /* Does matching substring exist? */
  514. for (s = desc; *s; s += strlen(s) + 1) {
  515. /* Aliases in module bodies can be defined with
  516. * shell patterns. Example:
  517. * "pci:v000010DEd000000D9sv*sd*bc*sc*i*".
  518. * Plain strcmp() won't catch that */
  519. if (fnmatch(s, alias, 0) == 0) {
  520. dbg1_error_msg("found alias '%s' in module '%s'",
  521. alias, modinfo[i].pathname);
  522. infovec = xrealloc_vector(infovec, 1, infoidx);
  523. infovec[infoidx++] = &modinfo[i];
  524. break;
  525. }
  526. }
  527. free(desc);
  528. i++;
  529. }
  530. /* Create module.dep.bb if needed */
  531. if (dep_bb_fd >= 0) {
  532. write_out_dep_bb(dep_bb_fd);
  533. }
  534. dbg1_error_msg("find_alias '%s' returns %d results", alias, infoidx);
  535. return infovec;
  536. }
  537. #if ENABLE_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED
  538. // TODO: open only once, invent config_rewind()
  539. static int already_loaded(const char *name)
  540. {
  541. int ret;
  542. char *line;
  543. FILE *fp;
  544. ret = 5 * 2;
  545. again:
  546. fp = fopen_for_read("/proc/modules");
  547. if (!fp)
  548. return 0;
  549. while ((line = xmalloc_fgetline(fp)) != NULL) {
  550. char *live;
  551. char *after_name;
  552. // Examples from kernel 3.14.6:
  553. //pcspkr 12718 0 - Live 0xffffffffa017e000
  554. //snd_timer 28690 2 snd_seq,snd_pcm, Live 0xffffffffa025e000
  555. //i915 801405 2 - Live 0xffffffffa0096000
  556. after_name = is_prefixed_with(line, name);
  557. if (!after_name || *after_name != ' ') {
  558. free(line);
  559. continue;
  560. }
  561. live = strstr(line, " Live");
  562. free(line);
  563. if (!live) {
  564. /* State can be Unloading, Loading, or Live.
  565. * modprobe must not return prematurely if we see "Loading":
  566. * it can cause further programs to assume load completed,
  567. * but it did not (yet)!
  568. * Wait up to 5*20 ms for it to resolve.
  569. */
  570. ret -= 2;
  571. if (ret == 0)
  572. break; /* huh? report as "not loaded" */
  573. fclose(fp);
  574. usleep(20*1000);
  575. goto again;
  576. }
  577. ret = 1;
  578. break;
  579. }
  580. fclose(fp);
  581. return ret & 1;
  582. }
  583. #else
  584. #define already_loaded(name) 0
  585. #endif
  586. static int rmmod(const char *filename)
  587. {
  588. int r;
  589. char modname[MODULE_NAME_LEN];
  590. filename2modname(filename, modname);
  591. r = delete_module(modname, O_NONBLOCK | O_EXCL);
  592. dbg1_error_msg("delete_module('%s', O_NONBLOCK | O_EXCL):%d", modname, r);
  593. if (r != 0 && !(option_mask32 & OPT_q)) {
  594. bb_perror_msg("remove '%s'", modname);
  595. }
  596. return r;
  597. }
  598. /*
  599. * Given modules definition and module name (or alias, or symbol)
  600. * load/remove the module respecting dependencies.
  601. * NB: also called by depmod with bogus name "/",
  602. * just in order to force modprobe.dep.bb creation.
  603. */
  604. #if !ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS
  605. #define process_module(a,b) process_module(a)
  606. #define cmdline_options ""
  607. #endif
  608. static int process_module(char *name, const char *cmdline_options)
  609. {
  610. char *s, *deps, *options;
  611. module_info **infovec;
  612. module_info *info;
  613. int infoidx;
  614. bool is_remove = (ENABLE_RMMOD && ONLY_APPLET)
  615. || ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r));
  616. int exitcode = EXIT_SUCCESS;
  617. dbg1_error_msg("process_module('%s','%s')", name, cmdline_options);
  618. replace(name, '-', '_');
  619. dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove);
  620. if (is_rmmod) {
  621. /* Does not remove dependencies, no need to scan, just remove.
  622. * (compat note: this allows and strips .ko suffix)
  623. */
  624. rmmod(name);
  625. return EXIT_SUCCESS;
  626. }
  627. /*
  628. * We used to have "is_remove != already_loaded(name)" check here, but
  629. * modprobe -r pci:v00008086d00007010sv00000000sd00000000bc01sc01i80
  630. * won't unload modules (there are more than one)
  631. * which have this alias.
  632. */
  633. if (!is_remove && already_loaded(name)) {
  634. dbg1_error_msg("nothing to do for '%s'", name);
  635. return EXIT_SUCCESS;
  636. }
  637. options = NULL;
  638. if (!is_remove) {
  639. char *opt_filename = xasprintf("/etc/modules/%s", name);
  640. options = xmalloc_open_read_close(opt_filename, NULL);
  641. if (options)
  642. replace(options, '\n', ' ');
  643. #if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS
  644. if (cmdline_options) {
  645. /* NB: cmdline_options always have one leading ' '
  646. * (see main()), we remove it here */
  647. char *op = xasprintf(options ? "%s %s" : "%s %s" + 3,
  648. cmdline_options + 1, options);
  649. free(options);
  650. options = op;
  651. }
  652. #endif
  653. free(opt_filename);
  654. module_load_options = options;
  655. dbg1_error_msg("process_module('%s'): options:'%s'", name, options);
  656. }
  657. if (!module_count) {
  658. /* Scan module directory. This is done only once.
  659. * It will attempt module load, and will exit(EXIT_SUCCESS)
  660. * on success.
  661. */
  662. module_found_idx = -1;
  663. recursive_action(".",
  664. ACTION_RECURSE, /* flags */
  665. fileAction, /* file action */
  666. NULL, /* dir action */
  667. name, /* user data */
  668. 0 /* depth */
  669. );
  670. dbg1_error_msg("dirscan complete");
  671. /* Module was not found, or load failed, or is_remove */
  672. if (module_found_idx >= 0) { /* module was found */
  673. infovec = xzalloc(2 * sizeof(infovec[0]));
  674. infovec[0] = &modinfo[module_found_idx];
  675. } else { /* search for alias, not a plain module name */
  676. infovec = find_alias(name);
  677. }
  678. } else {
  679. infovec = find_alias(name);
  680. }
  681. if (!infovec) {
  682. /* both dirscan and find_alias found nothing */
  683. if (!is_remove && !is_depmod) { /* it wasn't rmmod or depmod */
  684. bb_error_msg("module '%s' not found", name);
  685. //TODO: _and_die()? or should we continue (un)loading modules listed on cmdline?
  686. /* "modprobe non-existing-module; echo $?" must print 1 */
  687. exitcode = EXIT_FAILURE;
  688. }
  689. goto ret;
  690. }
  691. /* There can be more than one module for the given alias. For example,
  692. * "pci:v00008086d00007010sv00000000sd00000000bc01sc01i80" matches
  693. * ata_piix because it has alias "pci:v00008086d00007010sv*sd*bc*sc*i*"
  694. * and ata_generic, it has alias "pci:v*d*sv*sd*bc01sc01i*"
  695. * Standard modprobe loads them both. We achieve it by returning
  696. * a *list* of modinfo pointers from find_alias().
  697. */
  698. /* modprobe -r? unload module(s) */
  699. if (is_remove) {
  700. infoidx = 0;
  701. while ((info = infovec[infoidx++]) != NULL) {
  702. int r = rmmod(bb_get_last_path_component_nostrip(info->pathname));
  703. if (r != 0) {
  704. goto ret; /* error */
  705. }
  706. }
  707. /* modprobe -r: we do not stop here -
  708. * continue to unload modules on which the module depends:
  709. * "-r --remove: option causes modprobe to remove a module.
  710. * If the modules it depends on are also unused, modprobe
  711. * will try to remove them, too."
  712. */
  713. }
  714. infoidx = 0;
  715. while ((info = infovec[infoidx++]) != NULL) {
  716. /* Iterate thru dependencies, trying to (un)load them */
  717. deps = str_2_list(info->deps);
  718. for (s = deps; *s; s += strlen(s) + 1) {
  719. //if (strcmp(name, s) != 0) // N.B. do loops exist?
  720. dbg1_error_msg("recurse on dep '%s'", s);
  721. process_module(s, NULL);
  722. dbg1_error_msg("recurse on dep '%s' done", s);
  723. }
  724. free(deps);
  725. if (is_remove)
  726. continue;
  727. /* We are modprobe: load it */
  728. if (options && strstr(options, "blacklist")) {
  729. dbg1_error_msg("'%s': blacklisted", info->pathname);
  730. continue;
  731. }
  732. if (info->open_read_failed) {
  733. /* We already tried it, didn't work. Don't try load again */
  734. exitcode = EXIT_FAILURE;
  735. continue;
  736. }
  737. errno = 0;
  738. if (load_module(info->pathname, options) != 0) {
  739. if (EEXIST != errno) {
  740. bb_error_msg("'%s': %s",
  741. info->pathname,
  742. moderror(errno));
  743. } else {
  744. dbg1_error_msg("'%s': %s",
  745. info->pathname,
  746. moderror(errno));
  747. }
  748. exitcode = EXIT_FAILURE;
  749. }
  750. }
  751. ret:
  752. free(infovec);
  753. free(options);
  754. return exitcode;
  755. }
  756. #undef cmdline_options
  757. /* For reference, module-init-tools v3.4 options:
  758. # insmod
  759. Usage: insmod filename [args]
  760. # rmmod --help
  761. Usage: rmmod [-fhswvV] modulename ...
  762. -f (or --force) forces a module unload, and may crash your
  763. machine. This requires the Forced Module Removal option
  764. when the kernel was compiled.
  765. -h (or --help) prints this help text
  766. -s (or --syslog) says use syslog, not stderr
  767. -v (or --verbose) enables more messages
  768. -V (or --version) prints the version code
  769. -w (or --wait) begins module removal even if it is used
  770. and will stop new users from accessing the module (so it
  771. should eventually fall to zero).
  772. # modprobe
  773. Usage: modprobe [-v] [-V] [-C config-file] [-d <dirname> ] [-n] [-i] [-q]
  774. [-b] [-o <modname>] [ --dump-modversions ] <modname> [parameters...]
  775. modprobe -r [-n] [-i] [-v] <modulename> ...
  776. modprobe -l -t <dirname> [ -a <modulename> ...]
  777. # depmod --help
  778. depmod 3.13 -- part of module-init-tools
  779. depmod -[aA] [-n -e -v -q -V -r -u -w -m]
  780. [-b basedirectory] [forced_version]
  781. depmod [-n -e -v -q -r -u -w] [-F kernelsyms] module1.ko module2.ko ...
  782. If no arguments (except options) are given, "depmod -a" is assumed.
  783. depmod will output a dependency list suitable for the modprobe utility.
  784. Options:
  785. -a, --all Probe all modules
  786. -A, --quick Only does the work if there's a new module
  787. -e, --errsyms Report not supplied symbols
  788. -m, --map Create the legacy map files
  789. -n, --show Write the dependency file on stdout only
  790. -P, --symbol-prefix Architecture symbol prefix
  791. -V, --version Print the release version
  792. -v, --verbose Enable verbose mode
  793. -w, --warn Warn on duplicates
  794. -h, --help Print this usage message
  795. The following options are useful for people managing distributions:
  796. -b basedirectory
  797. --basedir basedirectory
  798. Use an image of a module tree
  799. -F kernelsyms
  800. --filesyms kernelsyms
  801. Use the file instead of the current kernel symbols
  802. -E Module.symvers
  803. --symvers Module.symvers
  804. Use Module.symvers file to check symbol versions
  805. */
  806. //usage:#if ENABLE_MODPROBE_SMALL
  807. //usage:#define depmod_trivial_usage "[-n]"
  808. //usage:#define depmod_full_usage "\n\n"
  809. //usage: "Generate modules.dep.bb"
  810. //usage: "\n"
  811. //usage: "\n -n Dry run: print file to stdout"
  812. //usage:#define insmod_trivial_usage
  813. //usage: "FILE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...")
  814. //usage:#define insmod_full_usage "\n\n"
  815. //usage: "Load kernel module"
  816. //usage:#define rmmod_trivial_usage
  817. //usage: "MODULE..."
  818. //usage:#define rmmod_full_usage "\n\n"
  819. //usage: "Unload kernel modules"
  820. //usage:#define modprobe_trivial_usage
  821. //usage: "[-rq] MODULE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...")
  822. //usage:#define modprobe_full_usage "\n\n"
  823. //usage: " -r Remove MODULE"
  824. //usage: "\n -q Quiet"
  825. //usage:#endif
  826. int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  827. int modprobe_main(int argc UNUSED_PARAM, char **argv)
  828. {
  829. #if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD
  830. int exitcode;
  831. #endif
  832. struct utsname uts;
  833. IF_FEATURE_CMDLINE_MODULE_OPTIONS(char *options = NULL;)
  834. INIT_G();
  835. /* Prevent ugly corner cases with no modules at all */
  836. modinfo = xzalloc(sizeof(modinfo[0]));
  837. if ((MOD_APPLET_CNT == 2 && ENABLE_DEPMOD && ENABLE_MODPROBE)
  838. || is_depmod || is_modprobe
  839. ) {
  840. /* Goto modules directory */
  841. xchdir(CONFIG_DEFAULT_MODULES_DIR);
  842. uname(&uts); /* never fails */
  843. }
  844. /* depmod? */
  845. if (is_depmod) {
  846. /* Supported:
  847. * -n: print result to stdout
  848. * -a: process all modules (default)
  849. * optional VERSION parameter
  850. * Ignored:
  851. * -A: do work only if a module is newer than depfile
  852. * -e: report any symbols which a module needs
  853. * which are not supplied by other modules or the kernel
  854. * -F FILE: System.map (symbols for -e)
  855. * -q, -r, -u: noop
  856. * Not supported:
  857. * -b BASEDIR: (TODO!) modules are in
  858. * $BASEDIR/lib/modules/$VERSION
  859. * -m: create legacy "modules.*map" files (deprecated; in
  860. * kmod's depmod, prints a warning message and continues)
  861. * -v: human readable deps to stdout
  862. * -V: version (don't want to support it - people may depend
  863. * on it as an indicator of "standard" depmod)
  864. * -h: help (well duh)
  865. * module1.o module2.o parameters (just ignored for now)
  866. */
  867. getopt32(argv, "na" "AeF:qru" /* "b:vV", NULL */, NULL);
  868. argv += optind;
  869. /* if (argv[0] && argv[1]) bb_show_usage(); */
  870. /* Goto $VERSION directory */
  871. xchdir(argv[0] ? argv[0] : uts.release);
  872. /* Force full module scan by asking to find a bogus module.
  873. * This will generate modules.dep.bb as a side effect. */
  874. process_module((char*)"/", NULL);
  875. return !wrote_dep_bb_ok;
  876. }
  877. #if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD
  878. /* modprobe, insmod, rmmod require at least one argument */
  879. opt_complementary = "-1";
  880. /* only -q (quiet) and -r (rmmod),
  881. * the rest are accepted and ignored (compat) */
  882. getopt32(argv, "qrfsvwb");
  883. argv += optind;
  884. if (is_modprobe) {
  885. /* Goto $VERSION directory */
  886. xchdir(uts.release);
  887. }
  888. /* are we rmmod? -> simulate modprobe -r, but don't bother the flag if
  889. * there're no other applets here */
  890. if (is_rmmod) {
  891. if (!ONLY_APPLET)
  892. option_mask32 |= OPT_r;
  893. } else if (!ENABLE_MODPROBE || !(option_mask32 & OPT_r)) {
  894. # if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS
  895. /* If not rmmod/-r, parse possible module options given on command line.
  896. * insmod/modprobe takes one module name, the rest are parameters. */
  897. char **arg = argv;
  898. while (*++arg) {
  899. /* Enclose options in quotes */
  900. char *s = options;
  901. options = xasprintf("%s \"%s\"", s ? s : "", *arg);
  902. free(s);
  903. *arg = NULL;
  904. }
  905. # else
  906. argv[1] = NULL;
  907. # endif
  908. }
  909. if (is_insmod) {
  910. size_t len;
  911. void *map;
  912. len = MAXINT(ssize_t);
  913. map = xmalloc_open_zipped_read_close(*argv, &len);
  914. if (!map)
  915. bb_perror_msg_and_die("can't read '%s'", *argv);
  916. if (init_module(map, len,
  917. (IF_FEATURE_CMDLINE_MODULE_OPTIONS(options ? options : ) "")
  918. ) != 0
  919. ) {
  920. bb_error_msg_and_die("can't insert '%s': %s",
  921. *argv, moderror(errno));
  922. }
  923. return EXIT_SUCCESS;
  924. }
  925. /* Try to load modprobe.dep.bb */
  926. if (!is_rmmod) {
  927. load_dep_bb();
  928. }
  929. /* Load/remove modules.
  930. * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */
  931. exitcode = EXIT_SUCCESS;
  932. do {
  933. exitcode |= process_module(*argv, options);
  934. } while (*++argv);
  935. if (ENABLE_FEATURE_CLEAN_UP) {
  936. IF_FEATURE_CMDLINE_MODULE_OPTIONS(free(options);)
  937. }
  938. return exitcode;
  939. #endif /* MODPROBE || INSMOD || RMMOD */
  940. }
  941. #endif /* MOD_APPLET_CNT > 0 */