aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modutils/modprobe-small.c50
1 files changed, 41 insertions, 9 deletions
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c
index 6b0a4400c..598965968 100644
--- a/modutils/modprobe-small.c
+++ b/modutils/modprobe-small.c
@@ -536,17 +536,49 @@ static module_info** find_alias(const char *alias)
536// TODO: open only once, invent config_rewind() 536// TODO: open only once, invent config_rewind()
537static int already_loaded(const char *name) 537static int already_loaded(const char *name)
538{ 538{
539 int ret = 0; 539 int ret, namelen;
540 char *s; 540 char *line;
541 parser_t *parser = config_open2("/proc/modules", xfopen_for_read); 541 FILE *fp;
542 while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) { 542
543 if (strcmp(s, name) == 0) { 543 ret = 5 * 2;
544 ret = 1; 544 again:
545 break; 545 fp = fopen_for_read("/proc/modules");
546 if (!fp)
547 return 0;
548 namelen = strlen(name);
549 while ((line = xmalloc_fgetline(fp)) != NULL) {
550 char *live;
551
552 // Examples from kernel 3.14.6:
553 //pcspkr 12718 0 - Live 0xffffffffa017e000
554 //snd_timer 28690 2 snd_seq,snd_pcm, Live 0xffffffffa025e000
555 //i915 801405 2 - Live 0xffffffffa0096000
556 if (strncmp(line, name, namelen) != 0 || line[namelen] != ' ') {
557 free(line);
558 continue;
546 } 559 }
560 live = strstr(line, " Live");
561 free(line);
562 if (!live) {
563 /* State can be Unloading, Loading, or Live.
564 * modprobe must not return prematurely if we see "Loading":
565 * it can cause further programs to assume load completed,
566 * but it did not (yet)!
567 * Wait up to 5*20 ms for it to resolve.
568 */
569 ret -= 2;
570 if (ret == 0)
571 break; /* huh? report as "not loaded" */
572 fclose(fp);
573 usleep(20*1000);
574 goto again;
575 }
576 ret = 1;
577 break;
547 } 578 }
548 config_close(parser); 579 fclose(fp);
549 return ret; 580
581 return ret | 1;
550} 582}
551#else 583#else
552#define already_loaded(name) 0 584#define already_loaded(name) 0