Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (7 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/modutils/modprobe.c

    r2725 r3232  
    99 */
    1010
    11 //applet:IF_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_DROP))
     11//applet:IF_MODPROBE(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP))
     12
     13#include "libbb.h"
     14#include "modutils.h"
     15#include <sys/utsname.h>
     16#include <fnmatch.h>
     17
     18//#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
     19#define DBG(...) ((void)0)
     20
     21/* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t),
     22 * we expect the full dependency list to be specified in modules.dep.
     23 * Older versions would only export the direct dependency list.
     24 */
     25
    1226
    1327//usage:#if !ENABLE_MODPROBE_SMALL
     
    7387//usage:
    7488//usage:#define modprobe_trivial_usage
    75 //usage:    "[-alrqvs"
    76 //usage:    IF_FEATURE_MODPROBE_BLACKLIST("b")
    77 //usage:    "] MODULE [symbol=value]..."
     89//usage:    "[-alrqvsD" IF_FEATURE_MODPROBE_BLACKLIST("b") "]"
     90//usage:    " MODULE [symbol=value]..."
    7891//usage:#define modprobe_full_usage "\n\n"
    79 //usage:       "Options:"
    80 //usage:     "\n    -a  Load multiple MODULEs"
     92//usage:       "    -a  Load multiple MODULEs"
    8193//usage:     "\n    -l  List (MODULE is a pattern)"
    8294//usage:     "\n    -r  Remove MODULE (stacks) or do autoclean"
     
    8496//usage:     "\n    -v  Verbose"
    8597//usage:     "\n    -s  Log to syslog"
     98//usage:     "\n    -D  Show dependencies"
    8699//usage:    IF_FEATURE_MODPROBE_BLACKLIST(
    87100//usage:     "\n    -b  Apply blacklist to module names too"
     
    89102//usage:#endif /* !ENABLE_MODPROBE_SMALL */
    90103
    91 #include "libbb.h"
    92 #include "modutils.h"
    93 #include <sys/utsname.h>
    94 #include <fnmatch.h>
    95 
    96 //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
    97 #define DBG(...) ((void)0)
    98 
    99 /* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t),
    100  * we expect the full dependency list to be specified in modules.dep.
    101  * Older versions would only export the direct dependency list.
     104/* Note: usage text doesn't document various 2.4 options
     105 * we pull in through INSMOD_OPTS define
     106 * Note2: -b is always accepted, but if !FEATURE_MODPROBE_BLACKLIST,
     107 * it is a no-op.
    102108 */
    103 
    104 /* Note that usage text doesn't document various 2.4 options
    105  * we pull in through INSMOD_OPTS define */
    106 
    107 #define MODPROBE_COMPLEMENTARY "q-v:v-q:l--ar:a--lr:r--al"
    108 #define MODPROBE_OPTS  "alr" IF_FEATURE_MODPROBE_BLACKLIST("b")
     109#define MODPROBE_OPTS  "alrDb"
     110/* -a and -D _are_ in fact compatible */
     111#define MODPROBE_COMPLEMENTARY ("q-v:v-q:l--arD:r--alD:a--lr:D--rl")
     112//#define MODPROBE_OPTS  "acd:lnrt:C:b"
    109113//#define MODPROBE_COMPLEMENTARY "q-v:v-q:l--acr:a--lr:r--al"
    110 //#define MODPROBE_OPTS  "acd:lnrt:C:" IF_FEATURE_MODPROBE_BLACKLIST("b")
    111114enum {
    112     MODPROBE_OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */
    113     //MODPROBE_OPT_DUMP_ONLY= (INSMOD_OPT_UNUSED << x), /* c */
    114     //MODPROBE_OPT_DIRNAME  = (INSMOD_OPT_UNUSED << x), /* d */
    115     MODPROBE_OPT_LIST_ONLY  = (INSMOD_OPT_UNUSED << 1), /* l */
    116     //MODPROBE_OPT_SHOW_ONLY= (INSMOD_OPT_UNUSED << x), /* n */
    117     MODPROBE_OPT_REMOVE     = (INSMOD_OPT_UNUSED << 2), /* r */
    118     //MODPROBE_OPT_RESTRICT = (INSMOD_OPT_UNUSED << x), /* t */
    119     //MODPROBE_OPT_VERONLY  = (INSMOD_OPT_UNUSED << x), /* V */
    120     //MODPROBE_OPT_CONFIGFILE=(INSMOD_OPT_UNUSED << x), /* C */
    121     MODPROBE_OPT_BLACKLIST  = (INSMOD_OPT_UNUSED << 3) * ENABLE_FEATURE_MODPROBE_BLACKLIST,
     115    OPT_INSERT_ALL   = (INSMOD_OPT_UNUSED << 0), /* a */
     116    //OPT_DUMP_ONLY  = (INSMOD_OPT_UNUSED << x), /* c */
     117    //OPT_DIRNAME    = (INSMOD_OPT_UNUSED << x), /* d */
     118    OPT_LIST_ONLY    = (INSMOD_OPT_UNUSED << 1), /* l */
     119    //OPT_SHOW_ONLY  = (INSMOD_OPT_UNUSED << x), /* n */
     120    OPT_REMOVE       = (INSMOD_OPT_UNUSED << 2), /* r */
     121    //OPT_RESTRICT   = (INSMOD_OPT_UNUSED << x), /* t */
     122    //OPT_VERONLY    = (INSMOD_OPT_UNUSED << x), /* V */
     123    //OPT_CONFIGFILE = (INSMOD_OPT_UNUSED << x), /* C */
     124    OPT_SHOW_DEPS    = (INSMOD_OPT_UNUSED << 3), /* D */
     125    OPT_BLACKLIST    = (INSMOD_OPT_UNUSED << 4) * ENABLE_FEATURE_MODPROBE_BLACKLIST,
    122126};
     127#if ENABLE_LONG_OPTS
     128static const char modprobe_longopts[] ALIGN1 =
     129    /* nobody asked for long opts (yet) */
     130    // "all\0"          No_argument "a"
     131    // "list\0"         No_argument "l"
     132    // "remove\0"       No_argument "r"
     133    // "quiet\0"        No_argument "q"
     134    // "verbose\0"      No_argument "v"
     135    // "syslog\0"       No_argument "s"
     136    /* module-init-tools 3.11.1 has only long opt --show-depends
     137     * but no short -D, we provide long opt for scripts which
     138     * were written for 3.11.1: */
     139    "show-depends\0"     No_argument "D"
     140    // "use-blacklist\0" No_argument "b"
     141    ;
     142#endif
    123143
    124144#define MODULE_FLAG_LOADED              0x0001
     
    139159};
    140160
     161#define DB_HASH_SIZE 256
     162
    141163struct globals {
    142     llist_t *db; /* MEs of all modules ever seen (caching for speed) */
    143164    llist_t *probes; /* MEs of module(s) requested on cmdline */
    144165    char *cmdline_mopts; /* module options from cmdline */
     
    146167    /* bool. "Did we have 'symbol:FOO' requested on cmdline?" */
    147168    smallint need_symbols;
     169    struct utsname uts;
     170    llist_t *db[DB_HASH_SIZE]; /* MEs of all modules ever seen (caching for speed) */
    148171} FIX_ALIASING;
    149 #define G (*(struct globals*)&bb_common_bufsiz1)
    150 #define INIT_G() do { } while (0)
     172#define G (*ptr_to_globals)
     173#define INIT_G() do { \
     174        SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
     175} while (0)
    151176
    152177
     
    168193}
    169194
     195/* These three functions called many times, optimizing for speed.
     196 * Users reported minute-long delays when they runn iptables repeatedly
     197 * (iptables use modprobe to install needed kernel modules).
     198 */
    170199static struct module_entry *helper_get_module(const char *module, int create)
    171200{
     
    173202    struct module_entry *e;
    174203    llist_t *l;
     204    unsigned i;
     205    unsigned hash;
    175206
    176207    filename2modname(module, modname);
    177     for (l = G.db; l != NULL; l = l->link) {
     208
     209    hash = 0;
     210    for (i = 0; modname[i]; i++)
     211        hash = ((hash << 5) + hash) + modname[i];
     212    hash %= DB_HASH_SIZE;
     213
     214    for (l = G.db[hash]; l; l = l->link) {
    178215        e = (struct module_entry *) l->data;
    179216        if (strcmp(e->modname, modname) == 0)
     
    185222    e = xzalloc(sizeof(*e));
    186223    e->modname = xstrdup(modname);
    187     llist_add_to(&G.db, e);
     224    llist_add_to(&G.db[hash], e);
    188225
    189226    return e;
    190227}
    191 static struct module_entry *get_or_add_modentry(const char *module)
     228static ALWAYS_INLINE struct module_entry *get_or_add_modentry(const char *module)
    192229{
    193230    return helper_get_module(module, 1);
    194231}
    195 static struct module_entry *get_modentry(const char *module)
     232static ALWAYS_INLINE struct module_entry *get_modentry(const char *module)
    196233{
    197234    return helper_get_module(module, 0);
     
    203240
    204241    m = get_or_add_modentry(name);
    205     if (!(option_mask32 & MODPROBE_OPT_REMOVE)
     242    if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS))
    206243     && (m->flags & MODULE_FLAG_LOADED)
    207244    ) {
     
    253290            filename2modname(tokens[1], wildcard);
    254291
    255             for (l = G.probes; l != NULL; l = l->link) {
     292            for (l = G.probes; l; l = l->link) {
    256293                m = (struct module_entry *) l->data;
    257294                if (fnmatch(wildcard, m->modname, 0) != 0)
     
    354391static int do_modprobe(struct module_entry *m)
    355392{
    356     struct module_entry *m2 = m2; /* for compiler */
    357     char *fn, *options;
    358393    int rc, first;
    359     llist_t *l;
    360394
    361395    if (!(m->flags & MODULE_FLAG_FOUND_IN_MODDEP)) {
     
    367401    DBG("do_modprob'ing %s", m->modname);
    368402
    369     if (!(option_mask32 & MODPROBE_OPT_REMOVE))
     403    if (!(option_mask32 & OPT_REMOVE))
    370404        m->deps = llist_rev(m->deps);
    371405
    372     for (l = m->deps; l != NULL; l = l->link)
    373         DBG("dep: %s", l->data);
     406    if (0) {
     407        llist_t *l;
     408        for (l = m->deps; l; l = l->link)
     409            DBG("dep: %s", l->data);
     410    }
    374411
    375412    first = 1;
    376413    rc = 0;
    377414    while (m->deps) {
     415        struct module_entry *m2;
     416        char *fn, *options;
     417
    378418        rc = 0;
    379419        fn = llist_pop(&m->deps); /* we leak it */
    380420        m2 = get_or_add_modentry(fn);
    381421
    382         if (option_mask32 & MODPROBE_OPT_REMOVE) {
     422        if (option_mask32 & OPT_REMOVE) {
    383423            /* modprobe -r */
    384424            if (m2->flags & MODULE_FLAG_LOADED) {
     
    400440        }
    401441
    402         if (m2->flags & MODULE_FLAG_LOADED) {
    403             DBG("%s is already loaded, skipping", fn);
    404             continue;
    405         }
    406 
    407442        options = m2->options;
    408443        m2->options = NULL;
     
    410445        if (m == m2)
    411446            options = gather_options_str(options, G.cmdline_mopts);
     447
     448        if (option_mask32 & OPT_SHOW_DEPS) {
     449            printf(options ? "insmod %s/%s/%s %s\n"
     450                    : "insmod %s/%s/%s\n",
     451                CONFIG_DEFAULT_MODULES_DIR, G.uts.release, fn,
     452                options);
     453            free(options);
     454            continue;
     455        }
     456
     457        if (m2->flags & MODULE_FLAG_LOADED) {
     458            DBG("%s is already loaded, skipping", fn);
     459            free(options);
     460            continue;
     461        }
     462
    412463        rc = bb_init_module(fn, options);
    413464        DBG("loaded %s '%s', rc:%d", fn, options, rc);
     
    457508        /* Optimization... */
    458509        if ((m->flags & MODULE_FLAG_LOADED)
    459          && !(option_mask32 & MODPROBE_OPT_REMOVE)
     510         && !(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS))
    460511        ) {
    461512            DBG("skip deps of %s, it's already loaded", tokens[0]);
     
    478529int modprobe_main(int argc UNUSED_PARAM, char **argv)
    479530{
    480     struct utsname uts;
    481531    int rc;
    482532    unsigned opt;
    483533    struct module_entry *me;
    484534
     535    INIT_G();
     536
     537    IF_LONG_OPTS(applet_long_options = modprobe_longopts;)
    485538    opt_complementary = MODPROBE_COMPLEMENTARY;
    486539    opt = getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS);
     
    489542    /* Goto modules location */
    490543    xchdir(CONFIG_DEFAULT_MODULES_DIR);
    491     uname(&uts);
    492     xchdir(uts.release);
    493 
    494     if (opt & MODPROBE_OPT_LIST_ONLY) {
     544    uname(&G.uts);
     545    xchdir(G.uts.release);
     546
     547    if (opt & OPT_LIST_ONLY) {
     548        int i;
    495549        char name[MODULE_NAME_LEN];
    496550        char *colon, *tokens[2];
    497551        parser_t *p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read);
     552
     553        for (i = 0; argv[i]; i++)
     554            replace(argv[i], '-', '_');
    498555
    499556        while (config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL)) {
     
    506563                puts(tokens[0]);
    507564            else {
    508                 int i;
    509565                for (i = 0; argv[i]; i++) {
    510566                    if (fnmatch(argv[i], name, 0) == 0) {
     
    522578
    523579    if (!argv[0]) {
    524         if (opt & MODPROBE_OPT_REMOVE) {
     580        if (opt & OPT_REMOVE) {
    525581            /* "modprobe -r" (w/o params).
    526582             * "If name is NULL, all unused modules marked
     
    542598    }
    543599
    544     if (opt & (MODPROBE_OPT_INSERT_ALL | MODPROBE_OPT_REMOVE)) {
     600    if (opt & (OPT_INSERT_ALL | OPT_REMOVE)) {
    545601        /* Each argument is a module name */
    546602        do {
     
    552608        DBG("probing just module %s", *argv);
    553609        add_probe(argv[0]);
    554         G.cmdline_mopts = parse_cmdline_module_options(argv);
     610        G.cmdline_mopts = parse_cmdline_module_options(argv, /*quote_spaces:*/ 1);
    555611    }
    556612
     
    576632             * only if '-b' is given.
    577633             */
    578             if (!(opt & MODPROBE_OPT_BLACKLIST)
     634            if (!(opt & OPT_BLACKLIST)
    579635             || !(me->flags & MODULE_FLAG_BLACKLISTED)
    580636            ) {
     
    593649            if (!(m2->flags & MODULE_FLAG_BLACKLISTED)
    594650             && (!(m2->flags & MODULE_FLAG_LOADED)
    595                 || (opt & MODPROBE_OPT_REMOVE))
     651                || (opt & (OPT_REMOVE | OPT_SHOW_DEPS)))
    596652            ) {
    597653//TODO: we can pass "me" as 2nd param to do_modprobe,
Note: See TracChangeset for help on using the changeset viewer.