diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-29 00:19:44 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-29 00:19:44 +0000 |
| commit | e1ee48e0fdfe18aadb410b62f21516bf4b8ea581 (patch) | |
| tree | 4748c9fb94e17582693115bb55deab463903e570 /modutils | |
| parent | 2f86d13dff6f2a5d4b8ac9350d306ca119a7e0e8 (diff) | |
| download | busybox-w32-e1ee48e0fdfe18aadb410b62f21516bf4b8ea581.tar.gz busybox-w32-e1ee48e0fdfe18aadb410b62f21516bf4b8ea581.tar.bz2 busybox-w32-e1ee48e0fdfe18aadb410b62f21516bf4b8ea581.zip | |
modprobe: support for /etc/modprobe.d, by Timo Teras.
function old new delta
include_conf_file_act - 929 +929
include_conf_recursive - 30 +30
include_conf_file2 - 30 +30
include_conf_file - 14 +14
include_conf_dir_act - 14 +14
build_dep 1011 875 -136
include_conf 922 - -922
------------------------------------------------------------------------------
(add/remove: 5/1 grow/shrink: 0/1 up/down: 1017/-1058) Total: -41 bytes
Diffstat (limited to 'modutils')
| -rw-r--r-- | modutils/modprobe.c | 169 |
1 files changed, 106 insertions, 63 deletions
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 1a4f5d4d4..0c59e8ab3 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
| @@ -48,6 +48,10 @@ struct mod_list_t { /* two-way list of modules to process */ | |||
| 48 | struct mod_list_t * m_next; | 48 | struct mod_list_t * m_next; |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | struct include_conf_t { | ||
| 52 | struct dep_t *first; | ||
| 53 | struct dep_t *current; | ||
| 54 | }; | ||
| 51 | 55 | ||
| 52 | static struct dep_t *depend; | 56 | static struct dep_t *depend; |
| 53 | 57 | ||
| @@ -242,21 +246,60 @@ static int is_conf_command(char *buffer, const char *command) | |||
| 242 | * This function reads aliases and default module options from a configuration file | 246 | * This function reads aliases and default module options from a configuration file |
| 243 | * (/etc/modprobe.conf syntax). It supports includes (only files, no directories). | 247 | * (/etc/modprobe.conf syntax). It supports includes (only files, no directories). |
| 244 | */ | 248 | */ |
| 245 | static void include_conf(struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd) | 249 | |
| 250 | static int FAST_FUNC include_conf_file_act(const char *filename, | ||
| 251 | struct stat *statbuf UNUSED_PARAM, | ||
| 252 | void *userdata, | ||
| 253 | int depth UNUSED_PARAM); | ||
| 254 | |||
| 255 | static int FAST_FUNC include_conf_dir_act(const char *filename UNUSED_PARAM, | ||
| 256 | struct stat *statbuf UNUSED_PARAM, | ||
| 257 | void *userdata UNUSED_PARAM, | ||
| 258 | int depth) | ||
| 259 | { | ||
| 260 | if (depth > 1) | ||
| 261 | return SKIP; | ||
| 262 | |||
| 263 | return TRUE; | ||
| 264 | } | ||
| 265 | |||
| 266 | static int inline include_conf_recursive(struct include_conf_t *conf, const char *filename) | ||
| 267 | { | ||
| 268 | return recursive_action(filename, ACTION_RECURSE, | ||
| 269 | include_conf_file_act, | ||
| 270 | include_conf_dir_act, | ||
| 271 | conf, 1); | ||
| 272 | } | ||
| 273 | |||
| 274 | static int FAST_FUNC include_conf_file_act(const char *filename, | ||
| 275 | struct stat *statbuf UNUSED_PARAM, | ||
| 276 | void *userdata, | ||
| 277 | int depth UNUSED_PARAM) | ||
| 246 | { | 278 | { |
| 279 | struct include_conf_t *conf = (struct include_conf_t *) userdata; | ||
| 280 | struct dep_t **first = &conf->first; | ||
| 281 | struct dep_t **current = &conf->current; | ||
| 247 | int continuation_line = 0; | 282 | int continuation_line = 0; |
| 283 | int fd; | ||
| 284 | |||
| 285 | if (bb_basename(filename)[0] == '.') | ||
| 286 | return TRUE; | ||
| 287 | |||
| 288 | fd = open(filename, O_RDONLY); | ||
| 289 | if (fd < 0) | ||
| 290 | return FALSE; | ||
| 248 | 291 | ||
| 249 | // alias parsing is not 100% correct (no correct handling of continuation lines within an alias)! | 292 | // alias parsing is not 100% correct (no correct handling of continuation lines within an alias)! |
| 250 | 293 | ||
| 251 | while (reads(fd, buffer, buflen)) { | 294 | while (reads(fd, line_buffer, sizeof(line_buffer))) { |
| 252 | int l; | 295 | int l; |
| 253 | 296 | ||
| 254 | *strchrnul(buffer, '#') = '\0'; | 297 | *strchrnul(line_buffer, '#') = '\0'; |
| 255 | 298 | ||
| 256 | l = strlen(buffer); | 299 | l = strlen(line_buffer); |
| 257 | 300 | ||
| 258 | while (l && isspace(buffer[l-1])) { | 301 | while (l && isspace(line_buffer[l-1])) { |
| 259 | buffer[l-1] = '\0'; | 302 | line_buffer[l-1] = '\0'; |
| 260 | l--; | 303 | l--; |
| 261 | } | 304 | } |
| 262 | 305 | ||
| @@ -268,10 +311,10 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf | |||
| 268 | if (continuation_line) | 311 | if (continuation_line) |
| 269 | continue; | 312 | continue; |
| 270 | 313 | ||
| 271 | if (is_conf_command(buffer, "alias")) { | 314 | if (is_conf_command(line_buffer, "alias")) { |
| 272 | char *alias, *mod; | 315 | char *alias, *mod; |
| 273 | 316 | ||
| 274 | if (parse_tag_value(buffer + 6, &alias, &mod)) { | 317 | if (parse_tag_value(line_buffer + 6, &alias, &mod)) { |
| 275 | /* handle alias as a module dependent on the aliased module */ | 318 | /* handle alias as a module dependent on the aliased module */ |
| 276 | if (!*current) { | 319 | if (!*current) { |
| 277 | (*first) = (*current) = xzalloc(sizeof(struct dep_t)); | 320 | (*first) = (*current) = xzalloc(sizeof(struct dep_t)); |
| @@ -292,11 +335,11 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf | |||
| 292 | } | 335 | } |
| 293 | /*(*current)->m_next = NULL; - done by xzalloc */ | 336 | /*(*current)->m_next = NULL; - done by xzalloc */ |
| 294 | } | 337 | } |
| 295 | } else if (is_conf_command(buffer, "options")) { | 338 | } else if (is_conf_command(line_buffer, "options")) { |
| 296 | char *mod, *opt; | 339 | char *mod, *opt; |
| 297 | 340 | ||
| 298 | /* split the line in the module/alias name, and options */ | 341 | /* split the line in the module/alias name, and options */ |
| 299 | if (parse_tag_value(buffer + 8, &mod, &opt)) { | 342 | if (parse_tag_value(line_buffer + 8, &mod, &opt)) { |
| 300 | struct dep_t *dt; | 343 | struct dep_t *dt; |
| 301 | 344 | ||
| 302 | /* find the corresponding module */ | 345 | /* find the corresponding module */ |
| @@ -315,22 +358,17 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf | |||
| 315 | } | 358 | } |
| 316 | } | 359 | } |
| 317 | } | 360 | } |
| 318 | } else if (is_conf_command(buffer, "include")) { | 361 | } else if (is_conf_command(line_buffer, "include")) { |
| 319 | int fdi; | 362 | char *includefile; |
| 320 | char *filename; | 363 | |
| 321 | 364 | includefile = skip_whitespace(line_buffer + 8); | |
| 322 | filename = skip_whitespace(buffer + 8); | 365 | include_conf_recursive(conf, includefile); |
| 323 | fdi = open(filename, O_RDONLY); | ||
| 324 | if (fdi >= 0) { | ||
| 325 | include_conf(first, current, buffer, buflen, fdi); | ||
| 326 | close(fdi); | ||
| 327 | } | ||
| 328 | } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST && | 366 | } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST && |
| 329 | (is_conf_command(buffer, "blacklist"))) { | 367 | (is_conf_command(line_buffer, "blacklist"))) { |
| 330 | char *mod; | 368 | char *mod; |
| 331 | struct dep_t *dt; | 369 | struct dep_t *dt; |
| 332 | 370 | ||
| 333 | mod = skip_whitespace(buffer + 10); | 371 | mod = skip_whitespace(line_buffer + 10); |
| 334 | for (dt = *first; dt; dt = dt->m_next) { | 372 | for (dt = *first; dt; dt = dt->m_next) { |
| 335 | if (strcmp(dt->m_name, mod) == 0) | 373 | if (strcmp(dt->m_name, mod) == 0) |
| 336 | break; | 374 | break; |
| @@ -339,6 +377,23 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf | |||
| 339 | dt->m_isblacklisted = 1; | 377 | dt->m_isblacklisted = 1; |
| 340 | } | 378 | } |
| 341 | } /* while (reads(...)) */ | 379 | } /* while (reads(...)) */ |
| 380 | |||
| 381 | close(fd); | ||
| 382 | return TRUE; | ||
| 383 | } | ||
| 384 | |||
| 385 | static int include_conf_file(struct include_conf_t *conf, | ||
| 386 | const char *filename) | ||
| 387 | { | ||
| 388 | return include_conf_file_act(filename, NULL, conf, 0); | ||
| 389 | } | ||
| 390 | |||
| 391 | static int include_conf_file2(struct include_conf_t *conf, | ||
| 392 | const char *filename, const char *oldname) | ||
| 393 | { | ||
| 394 | if (include_conf_file(conf, filename) == TRUE) | ||
| 395 | return TRUE; | ||
| 396 | return include_conf_file(conf, oldname); | ||
| 342 | } | 397 | } |
| 343 | 398 | ||
| 344 | /* | 399 | /* |
| @@ -350,8 +405,7 @@ static struct dep_t *build_dep(void) | |||
| 350 | { | 405 | { |
| 351 | int fd; | 406 | int fd; |
| 352 | struct utsname un; | 407 | struct utsname un; |
| 353 | struct dep_t *first = NULL; | 408 | struct include_conf_t conf = { NULL, NULL }; |
| 354 | struct dep_t *current = NULL; | ||
| 355 | char *filename; | 409 | char *filename; |
| 356 | int continuation_line = 0; | 410 | int continuation_line = 0; |
| 357 | int k_version; | 411 | int k_version; |
| @@ -421,14 +475,14 @@ static struct dep_t *build_dep(void) | |||
| 421 | mod = xstrndup(mods, dot - mods); | 475 | mod = xstrndup(mods, dot - mods); |
| 422 | 476 | ||
| 423 | /* enqueue new module */ | 477 | /* enqueue new module */ |
| 424 | if (!current) { | 478 | if (!conf.current) { |
| 425 | first = current = xzalloc(sizeof(struct dep_t)); | 479 | conf.first = conf.current = xzalloc(sizeof(struct dep_t)); |
| 426 | } else { | 480 | } else { |
| 427 | current->m_next = xzalloc(sizeof(struct dep_t)); | 481 | conf.current->m_next = xzalloc(sizeof(struct dep_t)); |
| 428 | current = current->m_next; | 482 | conf.current = conf.current->m_next; |
| 429 | } | 483 | } |
| 430 | current->m_name = mod; | 484 | conf.current->m_name = mod; |
| 431 | current->m_path = xstrdup(modpath); | 485 | conf.current->m_path = xstrdup(modpath); |
| 432 | /*current->m_options = NULL; - xzalloc did it*/ | 486 | /*current->m_options = NULL; - xzalloc did it*/ |
| 433 | /*current->m_isalias = 0;*/ | 487 | /*current->m_isalias = 0;*/ |
| 434 | /*current->m_depcnt = 0;*/ | 488 | /*current->m_depcnt = 0;*/ |
| @@ -482,8 +536,8 @@ static struct dep_t *build_dep(void) | |||
| 482 | dep = xstrndup(deps, next - deps - ext + 1); | 536 | dep = xstrndup(deps, next - deps - ext + 1); |
| 483 | 537 | ||
| 484 | /* Add the new dependable module name */ | 538 | /* Add the new dependable module name */ |
| 485 | current->m_deparr = xrealloc_vector(current->m_deparr, 2, current->m_depcnt); | 539 | conf.current->m_deparr = xrealloc_vector(conf.current->m_deparr, 2, conf.current->m_depcnt); |
| 486 | current->m_deparr[current->m_depcnt++] = dep; | 540 | conf.current->m_deparr[conf.current->m_depcnt++] = dep; |
| 487 | 541 | ||
| 488 | p = next + 2; | 542 | p = next + 2; |
| 489 | } while (next < end); | 543 | } while (next < end); |
| @@ -500,52 +554,41 @@ static struct dep_t *build_dep(void) | |||
| 500 | * >=2.6: we only care about modprobe.conf | 554 | * >=2.6: we only care about modprobe.conf |
| 501 | * <=2.4: we care about modules.conf and conf.modules | 555 | * <=2.4: we care about modules.conf and conf.modules |
| 502 | */ | 556 | */ |
| 503 | if (ENABLE_FEATURE_2_6_MODULES | 557 | { |
| 504 | && (fd = open("/etc/modprobe.conf", O_RDONLY)) < 0) | 558 | int r = FALSE; |
| 505 | if (ENABLE_FEATURE_2_4_MODULES | 559 | |
| 506 | && (fd = open("/etc/modules.conf", O_RDONLY)) < 0) | 560 | if (ENABLE_FEATURE_2_6_MODULES) { |
| 507 | if (ENABLE_FEATURE_2_4_MODULES) | 561 | if (include_conf_file(&conf, "/etc/modprobe.conf")) |
| 508 | fd = open("/etc/conf.modules", O_RDONLY); | 562 | r = TRUE; |
| 509 | 563 | if (include_conf_recursive(&conf, "/etc/modprobe.d")) | |
| 510 | if (fd >= 0) { | 564 | r = TRUE; |
| 511 | include_conf(&first, ¤t, line_buffer, sizeof(line_buffer), fd); | 565 | } |
| 512 | close(fd); | 566 | if (ENABLE_FEATURE_2_4_MODULES && !r) |
| 567 | include_conf_file2(&conf, | ||
| 568 | "/etc/modules.conf", | ||
| 569 | "/etc/conf.modules"); | ||
| 513 | } | 570 | } |
| 514 | 571 | ||
| 515 | /* Only 2.6 has a modules.alias file */ | 572 | /* Only 2.6 has a modules.alias file */ |
| 516 | if (ENABLE_FEATURE_2_6_MODULES) { | 573 | if (ENABLE_FEATURE_2_6_MODULES) { |
| 517 | /* Parse kernel-declared module aliases */ | 574 | /* Parse kernel-declared module aliases */ |
| 518 | filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.alias", un.release); | 575 | filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.alias", un.release); |
| 519 | fd = open(filename, O_RDONLY); | 576 | include_conf_file2(&conf, |
| 520 | if (fd < 0) { | 577 | filename, |
| 521 | /* Ok, that didn't work. Fall back to looking in /lib/modules */ | 578 | CONFIG_DEFAULT_MODULES_DIR"/modules.alias"); |
| 522 | fd = open(CONFIG_DEFAULT_MODULES_DIR"/modules.alias", O_RDONLY); | ||
| 523 | } | ||
| 524 | if (ENABLE_FEATURE_CLEAN_UP) | 579 | if (ENABLE_FEATURE_CLEAN_UP) |
| 525 | free(filename); | 580 | free(filename); |
| 526 | 581 | ||
| 527 | if (fd >= 0) { | ||
| 528 | include_conf(&first, ¤t, line_buffer, sizeof(line_buffer), fd); | ||
| 529 | close(fd); | ||
| 530 | } | ||
| 531 | |||
| 532 | /* Parse kernel-declared symbol aliases */ | 582 | /* Parse kernel-declared symbol aliases */ |
| 533 | filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.symbols", un.release); | 583 | filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.symbols", un.release); |
| 534 | fd = open(filename, O_RDONLY); | 584 | include_conf_file2(&conf, |
| 535 | if (fd < 0) { | 585 | filename, |
| 536 | /* Ok, that didn't work. Fall back to looking in /lib/modules */ | 586 | CONFIG_DEFAULT_MODULES_DIR"/modules.symbols"); |
| 537 | fd = open(CONFIG_DEFAULT_MODULES_DIR"/modules.symbols", O_RDONLY); | ||
| 538 | } | ||
| 539 | if (ENABLE_FEATURE_CLEAN_UP) | 587 | if (ENABLE_FEATURE_CLEAN_UP) |
| 540 | free(filename); | 588 | free(filename); |
| 541 | |||
| 542 | if (fd >= 0) { | ||
| 543 | include_conf(&first, ¤t, line_buffer, sizeof(line_buffer), fd); | ||
| 544 | close(fd); | ||
| 545 | } | ||
| 546 | } | 589 | } |
| 547 | 590 | ||
| 548 | return first; | 591 | return conf.first; |
| 549 | } | 592 | } |
| 550 | 593 | ||
| 551 | /* return 1 = loaded, 0 = not loaded, -1 = can't tell */ | 594 | /* return 1 = loaded, 0 = not loaded, -1 = can't tell */ |
