1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060 |
- #include "libbb.h"
- #include <sys/utsname.h> /* uname() */
- #include <fnmatch.h>
- #include <sys/syscall.h>
- #define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
- #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
- #ifdef __NR_finit_module
- # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags)
- #endif
- #undef MODULE_NAME_LEN
- #define MODULE_NAME_LEN 64
- #if 1
- # define dbg1_error_msg(...) ((void)0)
- # define dbg2_error_msg(...) ((void)0)
- #else
- # define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__)
- # define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__)
- #endif
- #define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb"
- #if ENABLE_LSMOD
- int lsmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
- int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
- {
- xprint_and_close_file(xfopen_for_read("/proc/modules"));
- return EXIT_SUCCESS;
- }
- #endif
- #define MOD_APPLET_CNT (ENABLE_MODPROBE + ENABLE_DEPMOD + ENABLE_INSMOD + ENABLE_RMMOD)
- #if MOD_APPLET_CNT > 0
- #define ONLY_APPLET (MOD_APPLET_CNT == 1)
- #define is_modprobe (ENABLE_MODPROBE && (ONLY_APPLET || applet_name[0] == 'm'))
- #define is_depmod (ENABLE_DEPMOD && (ONLY_APPLET || applet_name[0] == 'd'))
- #define is_insmod (ENABLE_INSMOD && (ONLY_APPLET || applet_name[0] == 'i'))
- #define is_rmmod (ENABLE_RMMOD && (ONLY_APPLET || applet_name[0] == 'r'))
- enum {
- DEPMOD_OPT_n = (1 << 0),
- OPT_q = (1 << 0),
- OPT_r = (1 << 1),
- };
- typedef struct module_info {
- char *pathname;
- char *aliases;
- char *deps;
- smallint open_read_failed;
- } module_info;
- struct globals {
- module_info *modinfo;
- char *module_load_options;
- smallint dep_bb_seen;
- smallint wrote_dep_bb_ok;
- unsigned module_count;
- int module_found_idx;
- unsigned stringbuf_idx;
- unsigned stringbuf_size;
- char *stringbuf;
-
-
- };
- #define G (*ptr_to_globals)
- #define modinfo (G.modinfo )
- #define dep_bb_seen (G.dep_bb_seen )
- #define wrote_dep_bb_ok (G.wrote_dep_bb_ok )
- #define module_count (G.module_count )
- #define module_found_idx (G.module_found_idx )
- #define module_load_options (G.module_load_options)
- #define stringbuf_idx (G.stringbuf_idx )
- #define stringbuf_size (G.stringbuf_size )
- #define stringbuf (G.stringbuf )
- #define INIT_G() do { \
- SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
- } while (0)
- static void append(const char *s)
- {
- unsigned len = strlen(s);
- if (stringbuf_idx + len + 15 > stringbuf_size) {
- stringbuf_size = stringbuf_idx + len + 127;
- dbg2_error_msg("grow stringbuf to %u", stringbuf_size);
- stringbuf = xrealloc(stringbuf, stringbuf_size);
- }
- memcpy(stringbuf + stringbuf_idx, s, len);
- stringbuf_idx += len;
- }
- static void appendc(char c)
- {
-
- stringbuf[stringbuf_idx++] = c;
- }
- static void bksp(void)
- {
- if (stringbuf_idx)
- stringbuf_idx--;
- }
- static void reset_stringbuf(void)
- {
- stringbuf_idx = 0;
- }
- static char* copy_stringbuf(void)
- {
- char *copy = xzalloc(stringbuf_idx + 1);
- return memcpy(copy, stringbuf, stringbuf_idx);
- }
- static char* find_keyword(char *ptr, size_t len, const char *word)
- {
- if (!ptr)
- return NULL;
- len -= strlen(word) - 1;
- while ((ssize_t)len > 0) {
- char *old = ptr;
- char *after_word;
-
- ptr = memchr(ptr, word[0], len);
- if (ptr == NULL)
- break;
- after_word = is_prefixed_with(ptr, word);
- if (after_word)
- return after_word;
- ++ptr;
- len -= (ptr - old);
- }
- return NULL;
- }
- static void replace(char *s, char what, char with)
- {
- while (*s) {
- if (what == *s)
- *s = with;
- ++s;
- }
- }
- static char *filename2modname(const char *filename, char *modname)
- {
- int i;
- const char *from;
-
-
-
-
- from = filename;
- for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '\0' && from[i] != '.'; i++)
- modname[i] = (from[i] == '-') ? '_' : from[i];
- modname[i] = '\0';
- return modname;
- }
- static int pathname_matches_modname(const char *pathname, const char *modname)
- {
- int r;
- char name[MODULE_NAME_LEN];
- filename2modname(bb_get_last_path_component_nostrip(pathname), name);
- r = (strcmp(name, modname) == 0);
- return r;
- }
- static char* str_2_list(const char *str)
- {
- int len = strlen(str) + 1;
- char *dst = xmalloc(len + 1);
- dst[len] = '\0';
- memcpy(dst, str, len);
- replace(dst, ' ', '\0');
- return dst;
- }
- static const char *moderror(int err)
- {
- switch (err) {
- case ENOEXEC:
- return "invalid module format";
- case ENOENT:
- return "unknown symbol in module or invalid parameter";
- case ESRCH:
- return "module has wrong symbol version";
- case EINVAL:
- return "unknown symbol in module or invalid parameter"
- + sizeof("unknown symbol in module or");
- default:
- return strerror(err);
- }
- }
- static int load_module(const char *fname, const char *options)
- {
- #if 1
- int r;
- size_t len = MAXINT(ssize_t);
- char *module_image;
- if (!options)
- options = "";
- dbg1_error_msg("load_module('%s','%s')", fname, options);
-
- r = 1;
- # ifdef __NR_finit_module
- {
- int fd = open(fname, O_RDONLY | O_CLOEXEC);
- if (fd >= 0) {
- r = finit_module(fd, options, 0) != 0;
- close(fd);
- }
- }
- # endif
- if (r != 0) {
- module_image = xmalloc_open_zipped_read_close(fname, &len);
- r = (!module_image || init_module(module_image, len, options) != 0);
- free(module_image);
- }
- dbg1_error_msg("load_module:%d", r);
- return r;
- #else
-
- dbg1_error_msg("load_module('%s','%s')", fname, options);
- return 1;
- #endif
- }
- static int parse_module(module_info *info, const char *pathname)
- {
- char *module_image;
- char *ptr;
- size_t len;
- size_t pos;
- dbg1_error_msg("parse_module('%s')", pathname);
-
- errno = 0;
- len = 64 * 1024 * 1024;
- module_image = xmalloc_open_zipped_read_close(pathname, &len);
-
-
- reset_stringbuf();
- pos = 0;
- while (1) {
- unsigned start = stringbuf_idx;
- ptr = find_keyword(module_image + pos, len - pos, "alias=");
- if (!ptr) {
- ptr = find_keyword(module_image + pos, len - pos, "__ksymtab_");
- if (!ptr)
- break;
-
- if (strcmp(ptr, "gpl") == 0 || strcmp(ptr, "strings") == 0)
- goto skip;
- dbg2_error_msg("alias:'symbol:%s'", ptr);
- append("symbol:");
- } else {
- dbg2_error_msg("alias:'%s'", ptr);
- }
- append(ptr);
- appendc(' ');
-
- if (start) {
- char *found, *last;
- stringbuf[stringbuf_idx] = '\0';
- last = stringbuf + start;
-
- if (strncmp(stringbuf, last, stringbuf_idx - start) == 0)
-
- found = stringbuf;
- else
-
- found = strstr(stringbuf, last-1);
- if (found < last-1) {
-
- dbg2_error_msg("redundant:'%s'", last);
- stringbuf_idx = start;
- goto skip;
- }
- }
- skip:
- pos = (ptr - module_image);
- }
- bksp();
- info->aliases = copy_stringbuf();
- replace(info->aliases, '-', '_');
-
- reset_stringbuf();
- ptr = find_keyword(module_image, len, "depends=");
- if (ptr && *ptr) {
- replace(ptr, ',', ' ');
- replace(ptr, '-', '_');
- dbg2_error_msg("dep:'%s'", ptr);
- append(ptr);
- }
- free(module_image);
- info->deps = copy_stringbuf();
- info->open_read_failed = (module_image == NULL);
- return info->open_read_failed;
- }
- static FAST_FUNC int fileAction(const char *pathname,
- struct stat *sb UNUSED_PARAM,
- void *modname_to_match,
- int depth UNUSED_PARAM)
- {
- int cur;
- const char *fname;
- bool is_remove = (ENABLE_RMMOD && ONLY_APPLET)
- || ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r));
- pathname += 2;
- fname = bb_get_last_path_component_nostrip(pathname);
- if (!strrstr(fname, ".ko")) {
- dbg1_error_msg("'%s' is not a module", pathname);
- return TRUE;
- }
- cur = module_count++;
- modinfo = xrealloc_vector(modinfo, 12, cur);
- modinfo[cur].pathname = xstrdup(pathname);
-
-
- if (!pathname_matches_modname(fname, modname_to_match)) {
- dbg1_error_msg("'%s' module name doesn't match", pathname);
- return TRUE;
- }
- dbg1_error_msg("'%s' module name matches", pathname);
- module_found_idx = cur;
- if (parse_module(&modinfo[cur], pathname) != 0)
- return TRUE;
- if (!is_remove) {
- if (load_module(pathname, module_load_options) == 0) {
-
- exit(EXIT_SUCCESS);
- }
- }
- return TRUE;
- }
- static int load_dep_bb(void)
- {
- char *line;
- FILE *fp = fopen_for_read(DEPFILE_BB);
- if (!fp)
- return 0;
- dep_bb_seen = 1;
- dbg1_error_msg("loading "DEPFILE_BB);
-
- module_count = 0;
- memset(&modinfo[0], 0, sizeof(modinfo[0]));
- while ((line = xmalloc_fgetline(fp)) != NULL) {
- char* space;
- char* linebuf;
- int cur;
- if (!line[0]) {
- free(line);
- continue;
- }
- space = strchrnul(line, ' ');
- cur = module_count++;
- modinfo = xrealloc_vector(modinfo, 12, cur);
-
- modinfo[cur].pathname = line;
- if (*space)
- *space++ = '\0';
- modinfo[cur].aliases = space;
- linebuf = xmalloc_fgetline(fp);
- modinfo[cur].deps = linebuf ? linebuf : xzalloc(1);
- if (modinfo[cur].deps[0]) {
-
- line = xmalloc_fgetline(fp);
-
- if (line && line[0])
- bb_error_msg_and_die("error in %s at '%s'", DEPFILE_BB, line);
- free(line);
- }
- }
- return 1;
- }
- static int start_dep_bb_writeout(void)
- {
- int fd;
-
- if (is_depmod && (option_mask32 & DEPMOD_OPT_n))
- return STDOUT_FILENO;
- fd = open(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644);
- if (fd < 0) {
- if (errno == EEXIST) {
- int count = 5 * 20;
- dbg1_error_msg(DEPFILE_BB".new exists, waiting for "DEPFILE_BB);
- while (1) {
- usleep(1000*1000 / 20);
- if (load_dep_bb()) {
- dbg1_error_msg(DEPFILE_BB" appeared");
- return -2;
- }
- if (!--count)
- break;
- }
- bb_error_msg("deleting stale %s", DEPFILE_BB".new");
- fd = open_or_warn(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC);
- }
- }
- dbg1_error_msg("opened "DEPFILE_BB".new:%d", fd);
- return fd;
- }
- static void write_out_dep_bb(int fd)
- {
- int i;
- FILE *fp;
-
- fp = xfdopen_for_write(fd);
- i = 0;
- while (modinfo[i].pathname) {
- fprintf(fp, "%s%s%s\n" "%s%s\n",
- modinfo[i].pathname, modinfo[i].aliases[0] ? " " : "", modinfo[i].aliases,
- modinfo[i].deps, modinfo[i].deps[0] ? "\n" : "");
- i++;
- }
-
- errno = 0;
- if (ferror(fp) | fclose(fp))
- goto err;
- if (fd == STDOUT_FILENO)
- goto ok;
- if (rename(DEPFILE_BB".new", DEPFILE_BB) != 0) {
- err:
- bb_perror_msg("can't create '%s'", DEPFILE_BB);
- unlink(DEPFILE_BB".new");
- } else {
- ok:
- wrote_dep_bb_ok = 1;
- dbg1_error_msg("created "DEPFILE_BB);
- }
- }
- static module_info** find_alias(const char *alias)
- {
- int i;
- int dep_bb_fd;
- int infoidx;
- module_info **infovec;
- dbg1_error_msg("find_alias('%s')", alias);
- try_again:
-
- i = 0;
- while (modinfo[i].pathname) {
- if (pathname_matches_modname(modinfo[i].pathname, alias)) {
- dbg1_error_msg("found '%s' in module '%s'",
- alias, modinfo[i].pathname);
- if (!modinfo[i].aliases) {
- parse_module(&modinfo[i], modinfo[i].pathname);
- }
- infovec = xzalloc(2 * sizeof(infovec[0]));
- infovec[0] = &modinfo[i];
- return infovec;
- }
- i++;
- }
-
- dep_bb_fd = dep_bb_seen ? -1 : start_dep_bb_writeout();
- if (dep_bb_fd == -2)
- goto try_again;
-
- i = 0;
- infoidx = 0;
- infovec = NULL;
- while (modinfo[i].pathname) {
- char *desc, *s;
- if (!modinfo[i].aliases) {
- parse_module(&modinfo[i], modinfo[i].pathname);
- }
-
- desc = str_2_list(modinfo[i].aliases);
-
- for (s = desc; *s; s += strlen(s) + 1) {
-
- if (fnmatch(s, alias, 0) == 0) {
- dbg1_error_msg("found alias '%s' in module '%s'",
- alias, modinfo[i].pathname);
- infovec = xrealloc_vector(infovec, 1, infoidx);
- infovec[infoidx++] = &modinfo[i];
- break;
- }
- }
- free(desc);
- i++;
- }
-
- if (dep_bb_fd >= 0) {
- write_out_dep_bb(dep_bb_fd);
- }
- dbg1_error_msg("find_alias '%s' returns %d results", alias, infoidx);
- return infovec;
- }
- #if ENABLE_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED
- static int already_loaded(const char *name)
- {
- int ret;
- char *line;
- FILE *fp;
- ret = 5 * 2;
- again:
- fp = fopen_for_read("/proc/modules");
- if (!fp)
- return 0;
- while ((line = xmalloc_fgetline(fp)) != NULL) {
- char *live;
- char *after_name;
-
-
-
-
- after_name = is_prefixed_with(line, name);
- if (!after_name || *after_name != ' ') {
- free(line);
- continue;
- }
- live = strstr(line, " Live");
- free(line);
- if (!live) {
-
- ret -= 2;
- if (ret == 0)
- break;
- fclose(fp);
- usleep(20*1000);
- goto again;
- }
- ret = 1;
- break;
- }
- fclose(fp);
- return ret & 1;
- }
- #else
- #define already_loaded(name) 0
- #endif
- static int rmmod(const char *filename)
- {
- int r;
- char modname[MODULE_NAME_LEN];
- filename2modname(filename, modname);
- r = delete_module(modname, O_NONBLOCK | O_EXCL);
- dbg1_error_msg("delete_module('%s', O_NONBLOCK | O_EXCL):%d", modname, r);
- if (r != 0 && !(option_mask32 & OPT_q)) {
- bb_perror_msg("remove '%s'", modname);
- }
- return r;
- }
- #if !ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS
- #define process_module(a,b) process_module(a)
- #define cmdline_options ""
- #endif
- static int process_module(char *name, const char *cmdline_options)
- {
- char *s, *deps, *options;
- module_info **infovec;
- module_info *info;
- int infoidx;
- bool is_remove = (ENABLE_RMMOD && ONLY_APPLET)
- || ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r));
- int exitcode = EXIT_SUCCESS;
- dbg1_error_msg("process_module('%s','%s')", name, cmdline_options);
- replace(name, '-', '_');
- dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove);
- if (is_rmmod) {
-
- rmmod(name);
- return EXIT_SUCCESS;
- }
-
- if (!is_remove && already_loaded(name)) {
- dbg1_error_msg("nothing to do for '%s'", name);
- return EXIT_SUCCESS;
- }
- options = NULL;
- if (!is_remove) {
- char *opt_filename = xasprintf("/etc/modules/%s", name);
- options = xmalloc_open_read_close(opt_filename, NULL);
- if (options)
- replace(options, '\n', ' ');
- #if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS
- if (cmdline_options) {
-
- char *op = xasprintf(options ? "%s %s" : "%s %s" + 3,
- cmdline_options + 1, options);
- free(options);
- options = op;
- }
- #endif
- free(opt_filename);
- module_load_options = options;
- dbg1_error_msg("process_module('%s'): options:'%s'", name, options);
- }
- if (!module_count) {
-
- module_found_idx = -1;
- recursive_action(".",
- ACTION_RECURSE,
- fileAction,
- NULL,
- name,
- 0
- );
- dbg1_error_msg("dirscan complete");
-
- if (module_found_idx >= 0) {
- infovec = xzalloc(2 * sizeof(infovec[0]));
- infovec[0] = &modinfo[module_found_idx];
- } else {
- infovec = find_alias(name);
- }
- } else {
- infovec = find_alias(name);
- }
- if (!infovec) {
-
- if (!is_remove && !is_depmod) {
- bb_error_msg("module '%s' not found", name);
-
- exitcode = EXIT_FAILURE;
- }
- goto ret;
- }
-
-
- if (is_remove) {
- infoidx = 0;
- while ((info = infovec[infoidx++]) != NULL) {
- int r = rmmod(bb_get_last_path_component_nostrip(info->pathname));
- if (r != 0) {
- goto ret;
- }
- }
-
- }
- infoidx = 0;
- while ((info = infovec[infoidx++]) != NULL) {
-
- deps = str_2_list(info->deps);
- for (s = deps; *s; s += strlen(s) + 1) {
-
- dbg1_error_msg("recurse on dep '%s'", s);
- process_module(s, NULL);
- dbg1_error_msg("recurse on dep '%s' done", s);
- }
- free(deps);
- if (is_remove)
- continue;
-
- if (options && strstr(options, "blacklist")) {
- dbg1_error_msg("'%s': blacklisted", info->pathname);
- continue;
- }
- if (info->open_read_failed) {
-
- exitcode = EXIT_FAILURE;
- continue;
- }
- errno = 0;
- if (load_module(info->pathname, options) != 0) {
- if (EEXIST != errno) {
- bb_error_msg("'%s': %s",
- info->pathname,
- moderror(errno));
- } else {
- dbg1_error_msg("'%s': %s",
- info->pathname,
- moderror(errno));
- }
- exitcode = EXIT_FAILURE;
- }
- }
- ret:
- free(infovec);
- free(options);
- return exitcode;
- }
- #undef cmdline_options
- int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
- int modprobe_main(int argc UNUSED_PARAM, char **argv)
- {
- #if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD
- int exitcode;
- #endif
- struct utsname uts;
- IF_FEATURE_CMDLINE_MODULE_OPTIONS(char *options = NULL;)
- INIT_G();
-
- modinfo = xzalloc(sizeof(modinfo[0]));
- if ((MOD_APPLET_CNT == 2 && ENABLE_DEPMOD && ENABLE_MODPROBE)
- || is_depmod || is_modprobe
- ) {
-
- xchdir(CONFIG_DEFAULT_MODULES_DIR);
- uname(&uts);
- }
-
- if (is_depmod) {
-
- getopt32(argv, "na" "AeF:qru" , NULL);
- argv += optind;
-
-
- xchdir(argv[0] ? argv[0] : uts.release);
-
- process_module((char*)"/", NULL);
- return !wrote_dep_bb_ok;
- }
- #if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD
-
-
- getopt32(argv, "^" "qrfsvwb" "\0" "-1");
- argv += optind;
- if (is_modprobe) {
-
- xchdir(uts.release);
- }
-
- if (is_rmmod) {
- if (!ONLY_APPLET)
- option_mask32 |= OPT_r;
- } else if (!ENABLE_MODPROBE || !(option_mask32 & OPT_r)) {
- # if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS
-
- char **arg = argv;
- while (*++arg) {
-
- char *s = options;
- options = xasprintf("%s \"%s\"", s ? s : "", *arg);
- free(s);
- *arg = NULL;
- }
- # else
- argv[1] = NULL;
- # endif
- }
- if (is_insmod) {
- size_t len;
- void *map;
- len = MAXINT(ssize_t);
- map = xmalloc_open_zipped_read_close(*argv, &len);
- if (!map)
- bb_perror_msg_and_die("can't read '%s'", *argv);
- if (init_module(map, len,
- (IF_FEATURE_CMDLINE_MODULE_OPTIONS(options ? options : ) "")
- ) != 0
- ) {
- bb_error_msg_and_die("can't insert '%s': %s",
- *argv, moderror(errno));
- }
- return EXIT_SUCCESS;
- }
-
- if (!is_rmmod) {
- load_dep_bb();
- }
-
- exitcode = EXIT_SUCCESS;
- do {
- exitcode |= process_module(*argv, options);
- } while (*++argv);
- if (ENABLE_FEATURE_CLEAN_UP) {
- IF_FEATURE_CMDLINE_MODULE_OPTIONS(free(options);)
- }
- return exitcode;
- #endif
- }
- #endif
|