Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

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

    r3232 r3621  
    1616#include <fnmatch.h>
    1717
    18 //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
     18#if 1
    1919#define DBG(...) ((void)0)
     20#else
     21#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
     22#endif
    2023
    2124/* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t),
     
    8891//usage:#define modprobe_trivial_usage
    8992//usage:    "[-alrqvsD" IF_FEATURE_MODPROBE_BLACKLIST("b") "]"
    90 //usage:    " MODULE [symbol=value]..."
     93//usage:    " MODULE [SYMBOL=VALUE]..."
    9194//usage:#define modprobe_full_usage "\n\n"
    9295//usage:       "    -a  Load multiple MODULEs"
     
    148151#define MODULE_FLAG_BLACKLISTED         0x0008
    149152
    150 struct module_entry { /* I'll call it ME. */
    151     unsigned flags;
    152     char *modname; /* stripped of /path/, .ext and s/-/_/g */
    153     const char *probed_name; /* verbatim as seen on cmdline */
    154     char *options; /* options from config files */
    155     llist_t *realnames; /* strings. if this module is an alias, */
    156     /* real module name is one of these. */
    157 //Can there really be more than one? Example from real kernel?
    158     llist_t *deps; /* strings. modules we depend on */
    159 };
    160 
    161 #define DB_HASH_SIZE 256
    162 
    163153struct globals {
    164154    llist_t *probes; /* MEs of module(s) requested on cmdline */
     
    168158    smallint need_symbols;
    169159    struct utsname uts;
    170     llist_t *db[DB_HASH_SIZE]; /* MEs of all modules ever seen (caching for speed) */
     160    module_db db;
    171161} FIX_ALIASING;
    172162#define G (*ptr_to_globals)
    173163#define INIT_G() do { \
    174         SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
     164    SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
    175165} while (0)
    176166
     
    193183}
    194184
    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  */
    199 static struct module_entry *helper_get_module(const char *module, int create)
    200 {
    201     char modname[MODULE_NAME_LEN];
    202     struct module_entry *e;
    203     llist_t *l;
    204     unsigned i;
    205     unsigned hash;
    206 
    207     filename2modname(module, modname);
    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) {
    215         e = (struct module_entry *) l->data;
    216         if (strcmp(e->modname, modname) == 0)
    217             return e;
    218     }
    219     if (!create)
    220         return NULL;
    221 
    222     e = xzalloc(sizeof(*e));
    223     e->modname = xstrdup(modname);
    224     llist_add_to(&G.db[hash], e);
    225 
    226     return e;
    227 }
    228 static ALWAYS_INLINE struct module_entry *get_or_add_modentry(const char *module)
    229 {
    230     return helper_get_module(module, 1);
    231 }
    232 static ALWAYS_INLINE struct module_entry *get_modentry(const char *module)
    233 {
    234     return helper_get_module(module, 0);
     185static struct module_entry *get_or_add_modentry(const char *module)
     186{
     187    return moddb_get_or_create(&G.db, module);
    235188}
    236189
     
    253206    G.num_unresolved_deps++;
    254207    if (ENABLE_FEATURE_MODUTILS_SYMBOLS
    255      && strncmp(m->modname, "symbol:", 7) == 0
     208     && is_prefixed_with(m->modname, "symbol:")
    256209    ) {
    257210        G.need_symbols = 1;
     
    262215                    struct stat *statbuf UNUSED_PARAM,
    263216                    void *userdata UNUSED_PARAM,
    264                     int depth UNUSED_PARAM)
     217                    int depth)
    265218{
    266219    char *tokens[3];
     
    268221    struct module_entry *m;
    269222    int rc = TRUE;
    270 
    271     if (bb_basename(filename)[0] == '.')
     223    const char *base, *ext;
     224
     225    /* Skip files that begin with a "." */
     226    base = bb_basename(filename);
     227    if (base[0] == '.')
    272228        goto error;
     229
     230    /* In dir recursion, skip files that do not end with a ".conf"
     231     * depth==0: read_config("modules.{symbols,alias}") must work,
     232     * "include FILE_NOT_ENDING_IN_CONF" must work too.
     233     */
     234    if (depth != 0) {
     235        ext = strrchr(base, '.');
     236        if (ext == NULL || strcmp(ext + 1, "conf"))
     237            goto error;
     238    }
    273239
    274240    p = config_open2(filename, fopen_for_read);
     
    315281            m->options = gather_options_str(m->options, tokens[2]);
    316282        } else if (strcmp(tokens[0], "include") == 0) {
    317             /* include <filename> */
     283            /* include <filename>/<dirname> (yes, directories also must work) */
    318284            read_config(tokens[1]);
    319285        } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST
     
    332298{
    333299    return recursive_action(path, ACTION_RECURSE | ACTION_QUIET,
    334                 config_file_action, NULL, NULL, 1);
     300                config_file_action, NULL, NULL,
     301                /*depth:*/ 0);
    335302}
    336303
     
    339306    /* probed_name may be NULL. modname always exists. */
    340307    return m->probed_name ? m->probed_name : m->modname;
     308}
     309
     310/* Like strsep(&stringp, "\n\t ") but quoted text goes to single token
     311 * even if it contains whitespace.
     312 */
     313static char *strsep_quotes(char **stringp)
     314{
     315    char *s, *start = *stringp;
     316
     317    if (!start)
     318        return NULL;
     319
     320    for (s = start; ; s++) {
     321        switch (*s) {
     322        case '"':
     323            s = strchrnul(s + 1, '"'); /* find trailing quote */
     324            if (*s != '\0')
     325                s++; /* skip trailing quote */
     326            /* fall through */
     327        case '\0':
     328        case '\n':
     329        case '\t':
     330        case ' ':
     331            if (*s != '\0') {
     332                *s = '\0';
     333                *stringp = s + 1;
     334            } else {
     335                *stringp = NULL;
     336            }
     337            return start;
     338        }
     339    }
    341340}
    342341
     
    346345    char *kcmdline;
    347346    char *kptr;
    348     int len;
    349347
    350348    kcmdline_buf = xmalloc_open_read_close("/proc/cmdline", NULL);
     
    353351
    354352    kcmdline = kcmdline_buf;
    355     len = strlen(modulename);
    356     while ((kptr = strsep(&kcmdline, "\n\t ")) != NULL) {
    357         if (strncmp(modulename, kptr, len) != 0)
    358             continue;
    359         kptr += len;
    360         if (*kptr != '.')
     353    while ((kptr = strsep_quotes(&kcmdline)) != NULL) {
     354        char *after_modulename = is_prefixed_with(kptr, modulename);
     355        if (!after_modulename || *after_modulename != '.')
    361356            continue;
    362357        /* It is "modulename.xxxx" */
    363         kptr++;
     358        kptr = after_modulename + 1;
    364359        if (strchr(kptr, '=') != NULL) {
    365360            /* It is "modulename.opt=[val]" */
     
    418413        rc = 0;
    419414        fn = llist_pop(&m->deps); /* we leak it */
    420         m2 = get_or_add_modentry(fn);
     415        m2 = get_or_add_modentry(bb_get_last_path_component_nostrip(fn));
    421416
    422417        if (option_mask32 & OPT_REMOVE) {
     
    426421                if (rc) {
    427422                    if (first) {
    428                         bb_error_msg("can't unload module %s: %s",
    429                             humanly_readable_name(m2),
    430                             moderror(rc));
     423                        bb_perror_msg("can't unload module '%s'",
     424                            humanly_readable_name(m2));
    431425                        break;
    432426                    }
     
    500494        if (colon == NULL)
    501495            continue;
    502         *colon = 0;
    503 
    504         m = get_modentry(tokens[0]);
     496        *colon = '\0';
     497
     498        m = moddb_get(&G.db, bb_get_last_path_component_nostrip(tokens[0]));
    505499        if (m == NULL)
    506500            continue;
     
    547541    if (opt & OPT_LIST_ONLY) {
    548542        int i;
    549         char name[MODULE_NAME_LEN];
    550543        char *colon, *tokens[2];
    551544        parser_t *p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read);
     
    559552                continue;
    560553            *colon = '\0';
    561             filename2modname(tokens[0], name);
    562554            if (!argv[0])
    563555                puts(tokens[0]);
    564556            else {
     557                char name[MODULE_NAME_LEN];
     558                filename2modname(
     559                    bb_get_last_path_component_nostrip(tokens[0]),
     560                    name
     561                );
    565562                for (i = 0; argv[i]; i++) {
    566563                    if (fnmatch(argv[i], name, 0) == 0) {
     
    584581             */
    585582            if (bb_delete_module(NULL, O_NONBLOCK | O_EXCL) != 0)
    586                 bb_perror_msg_and_die("rmmod");
     583                bb_perror_nomsg_and_die();
    587584        }
    588585        return EXIT_SUCCESS;
     
    660657    }
    661658
     659    if (ENABLE_FEATURE_CLEAN_UP)
     660        moddb_free(&G.db);
     661
    662662    return (rc != 0);
    663663}
Note: See TracChangeset for help on using the changeset viewer.