modprobe-small: preparatory patch for modprobe.dep.bb creation patches,
Code size impact ~0.
This commit is contained in:
parent
f62ab2d774
commit
24a131ea4d
@ -14,14 +14,17 @@
|
|||||||
#include <sys/utsname.h> /* uname() */
|
#include <sys/utsname.h> /* uname() */
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
|
||||||
|
extern int init_module(void *module, unsigned long len, const char *options);
|
||||||
|
extern int delete_module(const char *module, unsigned flags);
|
||||||
|
extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);
|
||||||
|
|
||||||
|
|
||||||
#define dbg1_error_msg(...) ((void)0)
|
#define dbg1_error_msg(...) ((void)0)
|
||||||
#define dbg2_error_msg(...) ((void)0)
|
#define dbg2_error_msg(...) ((void)0)
|
||||||
//#define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__)
|
//#define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__)
|
||||||
//#define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__)
|
//#define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__)
|
||||||
|
|
||||||
extern int init_module(void *module, unsigned long len, const char *options);
|
#define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb"
|
||||||
extern int delete_module(const char *module, unsigned flags);
|
|
||||||
extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OPT_q = (1 << 0), /* be quiet */
|
OPT_q = (1 << 0), /* be quiet */
|
||||||
@ -63,6 +66,12 @@ static void appendc(char c)
|
|||||||
stringbuf[stringbuf_idx++] = c;
|
stringbuf[stringbuf_idx++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bksp(void)
|
||||||
|
{
|
||||||
|
if (stringbuf_idx)
|
||||||
|
stringbuf_idx--;
|
||||||
|
}
|
||||||
|
|
||||||
static void append(const char *s)
|
static void append(const char *s)
|
||||||
{
|
{
|
||||||
size_t len = strlen(s);
|
size_t len = strlen(s);
|
||||||
@ -115,6 +124,19 @@ static void replace(char *s, char what, char with)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Take "word word", return malloced "word",NUL,"word",NUL,NUL */
|
||||||
|
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);
|
||||||
|
//TODO: protect against 2+ spaces: "word word"
|
||||||
|
replace(dst, ' ', '\0');
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED
|
#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED
|
||||||
static char *xmalloc_open_zipped_read_close(const char *fname, size_t *sizep)
|
static char *xmalloc_open_zipped_read_close(const char *fname, size_t *sizep)
|
||||||
{
|
{
|
||||||
@ -187,13 +209,13 @@ static int load_module(const char *fname, const char *options)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* parse_module(const char *pathname, const char *name)
|
static char* parse_module(const char *pathname)
|
||||||
{
|
{
|
||||||
char *module_image;
|
char *module_image;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
dbg1_error_msg("parse_module('%s','%s')", pathname, name);
|
dbg1_error_msg("parse_module('%s')", pathname);
|
||||||
|
|
||||||
/* Read (possibly compressed) module */
|
/* Read (possibly compressed) module */
|
||||||
len = 64 * 1024 * 1024; /* 64 Mb at most */
|
len = 64 * 1024 * 1024; /* 64 Mb at most */
|
||||||
@ -202,11 +224,7 @@ static char* parse_module(const char *pathname, const char *name)
|
|||||||
reset_stringbuf();
|
reset_stringbuf();
|
||||||
|
|
||||||
/* First desc line's format is
|
/* First desc line's format is
|
||||||
* "modname alias1 symbol:sym1 alias2 symbol:sym2 " (note trailing ' ')
|
* "alias1 symbol:sym1 alias2 symbol:sym2" */
|
||||||
*/
|
|
||||||
append(name);
|
|
||||||
appendc(' ');
|
|
||||||
/* Aliases */
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
ptr = find_keyword(module_image + pos, len - pos, "alias=");
|
ptr = find_keyword(module_image + pos, len - pos, "alias=");
|
||||||
@ -217,19 +235,20 @@ static char* parse_module(const char *pathname, const char *name)
|
|||||||
/* DOCME: __ksymtab_gpl and __ksymtab_strings occur
|
/* DOCME: __ksymtab_gpl and __ksymtab_strings occur
|
||||||
* in many modules. What do they mean? */
|
* in many modules. What do they mean? */
|
||||||
if (strcmp(ptr, "gpl") != 0 && strcmp(ptr, "strings") != 0) {
|
if (strcmp(ptr, "gpl") != 0 && strcmp(ptr, "strings") != 0) {
|
||||||
dbg2_error_msg("alias: 'symbol:%s'", ptr);
|
dbg2_error_msg("alias:'symbol:%s'", ptr);
|
||||||
append("symbol:");
|
append("symbol:");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dbg2_error_msg("alias: '%s'", ptr);
|
dbg2_error_msg("alias:'%s'", ptr);
|
||||||
}
|
}
|
||||||
append(ptr);
|
append(ptr);
|
||||||
appendc(' ');
|
appendc(' ');
|
||||||
pos = (ptr - module_image);
|
pos = (ptr - module_image);
|
||||||
}
|
}
|
||||||
|
bksp(); /* remove last ' ' */
|
||||||
appendc('\0');
|
appendc('\0');
|
||||||
|
|
||||||
/* Second line: "dependency1 depandency2 " (note trailing ' ') */
|
/* Second line: "dependency1 depandency2" */
|
||||||
ptr = find_keyword(module_image, len, "depends=");
|
ptr = find_keyword(module_image, len, "depends=");
|
||||||
if (ptr && *ptr) {
|
if (ptr && *ptr) {
|
||||||
replace(ptr, ',', ' ');
|
replace(ptr, ',', ' ');
|
||||||
@ -237,28 +256,31 @@ static char* parse_module(const char *pathname, const char *name)
|
|||||||
dbg2_error_msg("dep:'%s'", ptr);
|
dbg2_error_msg("dep:'%s'", ptr);
|
||||||
append(ptr);
|
append(ptr);
|
||||||
}
|
}
|
||||||
appendc(' '); appendc('\0');
|
appendc('\0');
|
||||||
|
|
||||||
free(module_image);
|
free(module_image);
|
||||||
return copy_stringbuf();
|
return copy_stringbuf();
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* pathname_2_modname(const char *pathname)
|
static int pathname_matches_modname(const char *pathname, const char *modname)
|
||||||
{
|
{
|
||||||
const char *fname = bb_get_last_path_component_nostrip(pathname);
|
const char *fname = bb_get_last_path_component_nostrip(pathname);
|
||||||
const char *suffix = strrstr(fname, ".ko");
|
const char *suffix = strrstr(fname, ".ko");
|
||||||
|
//TODO: can do without malloc?
|
||||||
char *name = xstrndup(fname, suffix - fname);
|
char *name = xstrndup(fname, suffix - fname);
|
||||||
|
int r;
|
||||||
replace(name, '-', '_');
|
replace(name, '-', '_');
|
||||||
return name;
|
r = (strcmp(name, modname) == 0);
|
||||||
|
free(name);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FAST_FUNC int fileAction(const char *pathname,
|
static FAST_FUNC int fileAction(const char *pathname,
|
||||||
struct stat *sb UNUSED_PARAM,
|
struct stat *sb UNUSED_PARAM,
|
||||||
void *data,
|
void *modname_to_match,
|
||||||
int depth UNUSED_PARAM)
|
int depth UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
int cur;
|
int cur;
|
||||||
char *name;
|
|
||||||
const char *fname;
|
const char *fname;
|
||||||
|
|
||||||
pathname += 2; /* skip "./" */
|
pathname += 2; /* skip "./" */
|
||||||
@ -270,21 +292,20 @@ static FAST_FUNC int fileAction(const char *pathname,
|
|||||||
|
|
||||||
cur = module_count++;
|
cur = module_count++;
|
||||||
modinfo = xrealloc_vector(modinfo, 12, cur);
|
modinfo = xrealloc_vector(modinfo, 12, cur);
|
||||||
|
//TODO: use zeroing version of xrealloc_vector?
|
||||||
modinfo[cur].pathname = xstrdup(pathname);
|
modinfo[cur].pathname = xstrdup(pathname);
|
||||||
modinfo[cur].desc = NULL;
|
modinfo[cur].desc = NULL;
|
||||||
modinfo[cur+1].pathname = NULL;
|
modinfo[cur+1].pathname = NULL;
|
||||||
modinfo[cur+1].desc = NULL;
|
modinfo[cur+1].desc = NULL;
|
||||||
|
|
||||||
name = pathname_2_modname(fname);
|
if (!pathname_matches_modname(fname, modname_to_match)) {
|
||||||
if (strcmp(name, data) != 0) {
|
|
||||||
free(name);
|
|
||||||
dbg1_error_msg("'%s' module name doesn't match", pathname);
|
dbg1_error_msg("'%s' module name doesn't match", pathname);
|
||||||
return TRUE; /* module name doesn't match, continue search */
|
return TRUE; /* module name doesn't match, continue search */
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg1_error_msg("'%s' module name matches", pathname);
|
dbg1_error_msg("'%s' module name matches", pathname);
|
||||||
module_found_idx = cur;
|
module_found_idx = cur;
|
||||||
modinfo[cur].desc = parse_module(pathname, name);
|
modinfo[cur].desc = parse_module(pathname);
|
||||||
|
|
||||||
if (!(option_mask32 & OPT_r)) {
|
if (!(option_mask32 & OPT_r)) {
|
||||||
if (load_module(pathname, module_load_options) == 0) {
|
if (load_module(pathname, module_load_options) == 0) {
|
||||||
@ -292,11 +313,9 @@ static FAST_FUNC int fileAction(const char *pathname,
|
|||||||
* This can happen ONLY for "top-level" module load,
|
* This can happen ONLY for "top-level" module load,
|
||||||
* not a dep, because deps dont do dirscan. */
|
* not a dep, because deps dont do dirscan. */
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
/*free(name);return RECURSE_RESULT_ABORT;*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(name);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,16 +327,13 @@ static module_info* find_alias(const char *alias)
|
|||||||
/* First try to find by name (cheaper) */
|
/* First try to find by name (cheaper) */
|
||||||
i = 0;
|
i = 0;
|
||||||
while (modinfo[i].pathname) {
|
while (modinfo[i].pathname) {
|
||||||
char *name = pathname_2_modname(modinfo[i].pathname);
|
if (pathname_matches_modname(modinfo[i].pathname, alias)) {
|
||||||
if (strcmp(name, alias) == 0) {
|
|
||||||
dbg1_error_msg("found '%s' in module '%s'",
|
dbg1_error_msg("found '%s' in module '%s'",
|
||||||
alias, modinfo[i].pathname);
|
alias, modinfo[i].pathname);
|
||||||
if (!modinfo[i].desc)
|
if (!modinfo[i].desc)
|
||||||
modinfo[i].desc = parse_module(modinfo[i].pathname, name);
|
modinfo[i].desc = parse_module(modinfo[i].pathname);
|
||||||
free(name);
|
|
||||||
return &modinfo[i];
|
return &modinfo[i];
|
||||||
}
|
}
|
||||||
free(name);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,16 +342,13 @@ static module_info* find_alias(const char *alias)
|
|||||||
while (modinfo[i].pathname) {
|
while (modinfo[i].pathname) {
|
||||||
char *desc, *s;
|
char *desc, *s;
|
||||||
if (!modinfo[i].desc) {
|
if (!modinfo[i].desc) {
|
||||||
char *name = pathname_2_modname(modinfo[i].pathname);
|
modinfo[i].desc = parse_module(modinfo[i].pathname);
|
||||||
modinfo[i].desc = parse_module(modinfo[i].pathname, name);
|
|
||||||
free(name);
|
|
||||||
}
|
}
|
||||||
/* "modname alias1 symbol:sym1 alias2 symbol:sym2 " */
|
/* "alias1 symbol:sym1 alias2 symbol:sym2" */
|
||||||
desc = xstrdup(modinfo[i].desc);
|
desc = str_2_list(modinfo[i].desc);
|
||||||
/* Does matching substring exist? */
|
/* Does matching substring exist? */
|
||||||
replace(desc, ' ', '\0');
|
|
||||||
for (s = desc; *s; s += strlen(s) + 1) {
|
for (s = desc; *s; s += strlen(s) + 1) {
|
||||||
/* aliases in module bodies can be defined with
|
/* Aliases in module bodies can be defined with
|
||||||
* shell patterns. Example:
|
* shell patterns. Example:
|
||||||
* "pci:v000010DEd000000D9sv*sd*bc*sc*i*".
|
* "pci:v000010DEd000000D9sv*sd*bc*sc*i*".
|
||||||
* Plain strcmp() won't catch that */
|
* Plain strcmp() won't catch that */
|
||||||
@ -463,10 +476,8 @@ static void process_module(char *name, const char *cmdline_options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Second line of desc contains dependencies */
|
/* Second line of desc contains dependencies */
|
||||||
deps = xstrdup(info->desc + strlen(info->desc) + 1);
|
deps = str_2_list(info->desc + strlen(info->desc) + 1);
|
||||||
|
|
||||||
/* Transform deps to string list */
|
|
||||||
replace(deps, ' ', '\0');
|
|
||||||
/* Iterate thru dependencies, trying to (un)load them */
|
/* Iterate thru dependencies, trying to (un)load them */
|
||||||
for (s = deps; *s; s += strlen(s) + 1) {
|
for (s = deps; *s; s += strlen(s) + 1) {
|
||||||
//if (strcmp(name, s) != 0) // N.B. do loops exist?
|
//if (strcmp(name, s) != 0) // N.B. do loops exist?
|
||||||
@ -481,12 +492,12 @@ static void process_module(char *name, const char *cmdline_options)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
if (load_module(info->pathname, options) != 0) {
|
if (load_module(info->pathname, options) != 0) {
|
||||||
if (EEXIST != errno) {
|
if (EEXIST != errno) {
|
||||||
bb_error_msg("insert '%s' %s: %s",
|
bb_error_msg("'%s': %s",
|
||||||
info->pathname, options,
|
info->pathname,
|
||||||
moderror(errno));
|
moderror(errno));
|
||||||
} else {
|
} else {
|
||||||
dbg1_error_msg("insert '%s' %s: %s",
|
dbg1_error_msg("'%s': %s",
|
||||||
info->pathname, options,
|
info->pathname,
|
||||||
moderror(errno));
|
moderror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user