diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-10 14:14:20 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-10 14:14:20 +0000 |
| commit | 784369987f3014d5841e319fdef5211fc6b97236 (patch) | |
| tree | 42f733d8fea04030e3d623f4944aa078768c45cc /modutils | |
| parent | 7621ac20f231fc5d4b0bdeabb14dcc22794fd4cb (diff) | |
| download | busybox-w32-784369987f3014d5841e319fdef5211fc6b97236.tar.gz busybox-w32-784369987f3014d5841e319fdef5211fc6b97236.tar.bz2 busybox-w32-784369987f3014d5841e319fdef5211fc6b97236.zip | |
modprobe-small: add depfile loading
Diffstat (limited to 'modutils')
| -rw-r--r-- | modutils/modprobe-small.c | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 72209610a..1a9d98422 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
| @@ -33,7 +33,8 @@ enum { | |||
| 33 | 33 | ||
| 34 | typedef struct module_info { | 34 | typedef struct module_info { |
| 35 | char *pathname; | 35 | char *pathname; |
| 36 | char *desc; | 36 | char *aliases; |
| 37 | char *deps; | ||
| 37 | } module_info; | 38 | } module_info; |
| 38 | 39 | ||
| 39 | /* | 40 | /* |
| @@ -209,7 +210,7 @@ static int load_module(const char *fname, const char *options) | |||
| 209 | #endif | 210 | #endif |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | static char* parse_module(const char *pathname) | 213 | static void parse_module(module_info *info, const char *pathname) |
| 213 | { | 214 | { |
| 214 | char *module_image; | 215 | char *module_image; |
| 215 | char *ptr; | 216 | char *ptr; |
| @@ -220,11 +221,10 @@ static char* parse_module(const char *pathname) | |||
| 220 | /* Read (possibly compressed) module */ | 221 | /* Read (possibly compressed) module */ |
| 221 | len = 64 * 1024 * 1024; /* 64 Mb at most */ | 222 | len = 64 * 1024 * 1024; /* 64 Mb at most */ |
| 222 | module_image = read_module(pathname, &len); | 223 | module_image = read_module(pathname, &len); |
| 224 | //TODO: optimize redundant module body reads | ||
| 223 | 225 | ||
| 226 | /* "alias1 symbol:sym1 alias2 symbol:sym2" */ | ||
| 224 | reset_stringbuf(); | 227 | reset_stringbuf(); |
| 225 | |||
| 226 | /* First desc line's format is | ||
| 227 | * "alias1 symbol:sym1 alias2 symbol:sym2" */ | ||
| 228 | pos = 0; | 228 | pos = 0; |
| 229 | while (1) { | 229 | while (1) { |
| 230 | ptr = find_keyword(module_image + pos, len - pos, "alias="); | 230 | ptr = find_keyword(module_image + pos, len - pos, "alias="); |
| @@ -247,8 +247,10 @@ static char* parse_module(const char *pathname) | |||
| 247 | } | 247 | } |
| 248 | bksp(); /* remove last ' ' */ | 248 | bksp(); /* remove last ' ' */ |
| 249 | appendc('\0'); | 249 | appendc('\0'); |
| 250 | info->aliases = copy_stringbuf(); | ||
| 250 | 251 | ||
| 251 | /* Second line: "dependency1 depandency2" */ | 252 | /* "dependency1 depandency2" */ |
| 253 | reset_stringbuf(); | ||
| 252 | ptr = find_keyword(module_image, len, "depends="); | 254 | ptr = find_keyword(module_image, len, "depends="); |
| 253 | if (ptr && *ptr) { | 255 | if (ptr && *ptr) { |
| 254 | replace(ptr, ',', ' '); | 256 | replace(ptr, ',', ' '); |
| @@ -257,9 +259,9 @@ static char* parse_module(const char *pathname) | |||
| 257 | append(ptr); | 259 | append(ptr); |
| 258 | } | 260 | } |
| 259 | appendc('\0'); | 261 | appendc('\0'); |
| 262 | info->deps = copy_stringbuf(); | ||
| 260 | 263 | ||
| 261 | free(module_image); | 264 | free(module_image); |
| 262 | return copy_stringbuf(); | ||
| 263 | } | 265 | } |
| 264 | 266 | ||
| 265 | static int pathname_matches_modname(const char *pathname, const char *modname) | 267 | static int pathname_matches_modname(const char *pathname, const char *modname) |
| @@ -294,9 +296,8 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
| 294 | modinfo = xrealloc_vector(modinfo, 12, cur); | 296 | modinfo = xrealloc_vector(modinfo, 12, cur); |
| 295 | //TODO: use zeroing version of xrealloc_vector? | 297 | //TODO: use zeroing version of xrealloc_vector? |
| 296 | modinfo[cur].pathname = xstrdup(pathname); | 298 | modinfo[cur].pathname = xstrdup(pathname); |
| 297 | modinfo[cur].desc = NULL; | 299 | modinfo[cur].aliases = NULL; |
| 298 | modinfo[cur+1].pathname = NULL; | 300 | modinfo[cur+1].pathname = NULL; |
| 299 | modinfo[cur+1].desc = NULL; | ||
| 300 | 301 | ||
| 301 | if (!pathname_matches_modname(fname, modname_to_match)) { | 302 | if (!pathname_matches_modname(fname, modname_to_match)) { |
| 302 | dbg1_error_msg("'%s' module name doesn't match", pathname); | 303 | dbg1_error_msg("'%s' module name doesn't match", pathname); |
| @@ -305,7 +306,7 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
| 305 | 306 | ||
| 306 | dbg1_error_msg("'%s' module name matches", pathname); | 307 | dbg1_error_msg("'%s' module name matches", pathname); |
| 307 | module_found_idx = cur; | 308 | module_found_idx = cur; |
| 308 | modinfo[cur].desc = parse_module(pathname); | 309 | parse_module(&modinfo[cur], pathname); |
| 309 | 310 | ||
| 310 | if (!(option_mask32 & OPT_r)) { | 311 | if (!(option_mask32 & OPT_r)) { |
| 311 | if (load_module(pathname, module_load_options) == 0) { | 312 | if (load_module(pathname, module_load_options) == 0) { |
| @@ -319,6 +320,43 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
| 319 | return TRUE; | 320 | return TRUE; |
| 320 | } | 321 | } |
| 321 | 322 | ||
| 323 | static void load_dep_bb(void) | ||
| 324 | { | ||
| 325 | char *line; | ||
| 326 | FILE *fp = fopen(DEPFILE_BB, "r"); | ||
| 327 | |||
| 328 | if (!fp) | ||
| 329 | return; | ||
| 330 | |||
| 331 | while ((line = xmalloc_fgetline(fp)) != NULL) { | ||
| 332 | char* space; | ||
| 333 | int cur; | ||
| 334 | |||
| 335 | if (!line[0]) { | ||
| 336 | free(line); | ||
| 337 | continue; | ||
| 338 | } | ||
| 339 | space = strchrnul(line, ' '); | ||
| 340 | cur = module_count++; | ||
| 341 | modinfo = xrealloc_vector(modinfo, 12, cur); | ||
| 342 | //TODO: use zeroing version of xrealloc_vector? | ||
| 343 | modinfo[cur+1].pathname = NULL; | ||
| 344 | modinfo[cur].pathname = line; /* we take ownership of malloced block here */ | ||
| 345 | if (*space) | ||
| 346 | *space++ = '\0'; | ||
| 347 | modinfo[cur].aliases = space; | ||
| 348 | modinfo[cur].deps = xmalloc_fgetline(fp) ? : xzalloc(1); | ||
| 349 | if (modinfo[cur].deps[0]) { | ||
| 350 | /* deps are not "", so next line must be empty */ | ||
| 351 | line = xmalloc_fgetline(fp); | ||
| 352 | /* Refuse to work with damaged config file */ | ||
| 353 | if (line && line[0]) | ||
| 354 | bb_error_msg_and_die("error in %s at '%s'", DEPFILE_BB, line); | ||
| 355 | free(line); | ||
| 356 | } | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 322 | static module_info* find_alias(const char *alias) | 360 | static module_info* find_alias(const char *alias) |
| 323 | { | 361 | { |
| 324 | int i; | 362 | int i; |
| @@ -330,8 +368,9 @@ static module_info* find_alias(const char *alias) | |||
| 330 | if (pathname_matches_modname(modinfo[i].pathname, alias)) { | 368 | if (pathname_matches_modname(modinfo[i].pathname, alias)) { |
| 331 | dbg1_error_msg("found '%s' in module '%s'", | 369 | dbg1_error_msg("found '%s' in module '%s'", |
| 332 | alias, modinfo[i].pathname); | 370 | alias, modinfo[i].pathname); |
| 333 | if (!modinfo[i].desc) | 371 | if (!modinfo[i].aliases) { |
| 334 | modinfo[i].desc = parse_module(modinfo[i].pathname); | 372 | parse_module(&modinfo[i], modinfo[i].pathname); |
| 373 | } | ||
| 335 | return &modinfo[i]; | 374 | return &modinfo[i]; |
| 336 | } | 375 | } |
| 337 | i++; | 376 | i++; |
| @@ -341,11 +380,11 @@ static module_info* find_alias(const char *alias) | |||
| 341 | i = 0; | 380 | i = 0; |
| 342 | while (modinfo[i].pathname) { | 381 | while (modinfo[i].pathname) { |
| 343 | char *desc, *s; | 382 | char *desc, *s; |
| 344 | if (!modinfo[i].desc) { | 383 | if (!modinfo[i].aliases) { |
| 345 | modinfo[i].desc = parse_module(modinfo[i].pathname); | 384 | parse_module(&modinfo[i], modinfo[i].pathname); |
| 346 | } | 385 | } |
| 347 | /* "alias1 symbol:sym1 alias2 symbol:sym2" */ | 386 | /* "alias1 symbol:sym1 alias2 symbol:sym2" */ |
| 348 | desc = str_2_list(modinfo[i].desc); | 387 | desc = str_2_list(modinfo[i].aliases); |
| 349 | /* Does matching substring exist? */ | 388 | /* Does matching substring exist? */ |
| 350 | for (s = desc; *s; s += strlen(s) + 1) { | 389 | for (s = desc; *s; s += strlen(s) + 1) { |
| 351 | /* Aliases in module bodies can be defined with | 390 | /* Aliases in module bodies can be defined with |
| @@ -475,10 +514,8 @@ static void process_module(char *name, const char *cmdline_options) | |||
| 475 | goto ret; | 514 | goto ret; |
| 476 | } | 515 | } |
| 477 | 516 | ||
| 478 | /* Second line of desc contains dependencies */ | ||
| 479 | deps = str_2_list(info->desc + strlen(info->desc) + 1); | ||
| 480 | |||
| 481 | /* Iterate thru dependencies, trying to (un)load them */ | 517 | /* Iterate thru dependencies, trying to (un)load them */ |
| 518 | deps = str_2_list(info->deps); | ||
| 482 | for (s = deps; *s; s += strlen(s) + 1) { | 519 | for (s = deps; *s; s += strlen(s) + 1) { |
| 483 | //if (strcmp(name, s) != 0) // N.B. do loops exist? | 520 | //if (strcmp(name, s) != 0) // N.B. do loops exist? |
| 484 | dbg1_error_msg("recurse on dep '%s'", s); | 521 | dbg1_error_msg("recurse on dep '%s'", s); |
| @@ -600,6 +637,8 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
| 600 | argv[1] = NULL; | 637 | argv[1] = NULL; |
| 601 | #endif | 638 | #endif |
| 602 | 639 | ||
| 640 | load_dep_bb(); | ||
| 641 | |||
| 603 | /* Load/remove modules. | 642 | /* Load/remove modules. |
| 604 | * Only rmmod loops here, insmod/modprobe has only argv[0] */ | 643 | * Only rmmod loops here, insmod/modprobe has only argv[0] */ |
| 605 | do { | 644 | do { |
