modprobe-small.c 29 KB

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