diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-19 02:02:33 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-19 02:02:33 +0000 |
commit | 1abf91aa253bb69ce2d21daca70726941d910d1c (patch) | |
tree | 17691bdaae09d19844ae0fa0395f25bda688169b | |
parent | a0e701d137a0d57befe9839ffadd30b69c05899e (diff) | |
download | busybox-w32-1abf91aa253bb69ce2d21daca70726941d910d1c.tar.gz busybox-w32-1abf91aa253bb69ce2d21daca70726941d910d1c.tar.bz2 busybox-w32-1abf91aa253bb69ce2d21daca70726941d910d1c.zip |
fsck: move functions around so that related ones are nearby
no actual code changes
-rw-r--r-- | e2fsprogs/fsck.c | 355 |
1 files changed, 185 insertions, 170 deletions
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index ea311df6d..681bfd15f 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c | |||
@@ -395,9 +395,7 @@ static void interpret_type(struct fs_info *fs) | |||
395 | #endif | 395 | #endif |
396 | #define interpret_type(fs) ((void)0) | 396 | #define interpret_type(fs) ((void)0) |
397 | 397 | ||
398 | /* | 398 | /* Load the filesystem database from /etc/fstab */ |
399 | * Load the filesystem database from /etc/fstab | ||
400 | */ | ||
401 | static void load_fs_info(const char *filename) | 399 | static void load_fs_info(const char *filename) |
402 | { | 400 | { |
403 | FILE *f; | 401 | FILE *f; |
@@ -471,86 +469,6 @@ static int progress_active(void) | |||
471 | } | 469 | } |
472 | 470 | ||
473 | /* | 471 | /* |
474 | * Execute a particular fsck program, and link it into the list of | ||
475 | * child processes we are waiting for. | ||
476 | */ | ||
477 | static int execute(const char *type, const char *device, const char *mntpt, | ||
478 | int interactive) | ||
479 | { | ||
480 | char *argv[num_args + 4]; /* see count below: */ | ||
481 | int argc; | ||
482 | int i; | ||
483 | struct fsck_instance *inst, *p; | ||
484 | pid_t pid; | ||
485 | |||
486 | inst = xzalloc(sizeof(*inst)); | ||
487 | |||
488 | argv[0] = xasprintf("fsck.%s", type); /* 1 */ | ||
489 | for (i = 0; i < num_args; i++) | ||
490 | argv[i+1] = args[i]; /* num_args */ | ||
491 | argc = num_args + 1; | ||
492 | |||
493 | if (progress && !progress_active()) { | ||
494 | if (strcmp(type, "ext2") == 0 | ||
495 | || strcmp(type, "ext3") == 0 | ||
496 | ) { | ||
497 | argv[argc++] = xasprintf("-C%d", progress_fd); /* 1 */ | ||
498 | inst->flags |= FLAG_PROGRESS; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | argv[argc++] = xstrdup(device); /* 1 */ | ||
503 | argv[argc] = 0; /* 1 */ | ||
504 | |||
505 | if (verbose || noexecute) { | ||
506 | printf("[%s (%d) -- %s]", argv[0], num_running, | ||
507 | mntpt ? mntpt : device); | ||
508 | for (i = 0; i < argc; i++) | ||
509 | printf(" %s", argv[i]); | ||
510 | puts(""); | ||
511 | } | ||
512 | |||
513 | /* Fork and execute the correct program. */ | ||
514 | if (noexecute) | ||
515 | pid = -1; | ||
516 | else if ((pid = fork()) < 0) { | ||
517 | bb_perror_msg("fork"); | ||
518 | return errno; | ||
519 | } | ||
520 | if (pid == 0) { | ||
521 | /* Child */ | ||
522 | if (!interactive) | ||
523 | close(0); | ||
524 | execvp(argv[0], argv); | ||
525 | bb_perror_msg_and_die("%s", argv[0]); | ||
526 | } | ||
527 | |||
528 | for (i = num_args+1; i < argc; i++) | ||
529 | free(argv[i]); | ||
530 | |||
531 | inst->pid = pid; | ||
532 | inst->prog = argv[0]; | ||
533 | inst->type = xstrdup(type); | ||
534 | inst->device = xstrdup(device); | ||
535 | inst->base_device = base_device(device); | ||
536 | inst->start_time = time(0); | ||
537 | inst->next = NULL; | ||
538 | |||
539 | /* | ||
540 | * Find the end of the list, so we add the instance on at the end. | ||
541 | */ | ||
542 | if (!instance_list) { | ||
543 | instance_list = inst; | ||
544 | return 0; | ||
545 | } | ||
546 | p = instance_list; | ||
547 | while (p->next) | ||
548 | p = p->next; | ||
549 | p->next = inst; | ||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | /* | ||
554 | * Send a signal to all outstanding fsck child processes | 472 | * Send a signal to all outstanding fsck child processes |
555 | */ | 473 | */ |
556 | static void kill_all_if_cancel_requested(void) | 474 | static void kill_all_if_cancel_requested(void) |
@@ -586,7 +504,7 @@ static struct fsck_instance *wait_one(int flags) | |||
586 | 504 | ||
587 | if (noexecute) { | 505 | if (noexecute) { |
588 | inst = instance_list; | 506 | inst = instance_list; |
589 | prev = 0; | 507 | prev = NULL; |
590 | #ifdef RANDOM_DEBUG | 508 | #ifdef RANDOM_DEBUG |
591 | while (inst->next && (random() & 1)) { | 509 | while (inst->next && (random() & 1)) { |
592 | prev = inst; | 510 | prev = inst; |
@@ -615,14 +533,16 @@ static struct fsck_instance *wait_one(int flags) | |||
615 | bb_error_msg("wait: no more child process?!?"); | 533 | bb_error_msg("wait: no more child process?!?"); |
616 | return NULL; | 534 | return NULL; |
617 | } | 535 | } |
618 | perror("wait"); | 536 | bb_perror_msg("wait"); |
619 | continue; | 537 | continue; |
620 | } | 538 | } |
621 | for (prev = 0, inst = instance_list; | 539 | prev = NULL; |
622 | inst; | 540 | inst = instance_list; |
623 | prev = inst, inst = inst->next) { | 541 | while (inst) { |
624 | if (inst->pid == pid) | 542 | if (inst->pid == pid) |
625 | break; | 543 | break; |
544 | prev = inst; | ||
545 | inst = inst->next; | ||
626 | } | 546 | } |
627 | } while (!inst); | 547 | } while (!inst); |
628 | 548 | ||
@@ -648,22 +568,21 @@ static struct fsck_instance *wait_one(int flags) | |||
648 | for (inst2 = instance_list; inst2; inst2 = inst2->next) { | 568 | for (inst2 = instance_list; inst2; inst2 = inst2->next) { |
649 | if (inst2->flags & FLAG_DONE) | 569 | if (inst2->flags & FLAG_DONE) |
650 | continue; | 570 | continue; |
651 | if (strcmp(inst2->type, "ext2") && | 571 | if (strcmp(inst2->type, "ext2") != 0 |
652 | strcmp(inst2->type, "ext3")) | 572 | && strcmp(inst2->type, "ext3") != 0 |
573 | ) { | ||
653 | continue; | 574 | continue; |
654 | /* | 575 | } |
576 | /* ext[23], we will send USR1 | ||
577 | * (request to start displaying progress bar) | ||
578 | * | ||
655 | * If we've just started the fsck, wait a tiny | 579 | * If we've just started the fsck, wait a tiny |
656 | * bit before sending the kill, to give it | 580 | * bit before sending the kill, to give it |
657 | * time to set up the signal handler | 581 | * time to set up the signal handler |
658 | */ | 582 | */ |
659 | if (inst2->start_time < time(0)+2) { | 583 | if (inst2->start_time >= time(NULL) - 1) |
660 | if (fork() == 0) { | 584 | sleep(1); |
661 | sleep(1); | 585 | kill(inst2->pid, SIGUSR1); |
662 | kill(inst2->pid, SIGUSR1); | ||
663 | exit(0); | ||
664 | } | ||
665 | } else | ||
666 | kill(inst2->pid, SIGUSR1); | ||
667 | inst2->flags |= FLAG_PROGRESS; | 586 | inst2->flags |= FLAG_PROGRESS; |
668 | break; | 587 | break; |
669 | } | 588 | } |
@@ -706,6 +625,86 @@ static int wait_many(int flags) | |||
706 | } | 625 | } |
707 | 626 | ||
708 | /* | 627 | /* |
628 | * Execute a particular fsck program, and link it into the list of | ||
629 | * child processes we are waiting for. | ||
630 | */ | ||
631 | static int execute(const char *type, const char *device, const char *mntpt, | ||
632 | int interactive) | ||
633 | { | ||
634 | char *argv[num_args + 4]; /* see count below: */ | ||
635 | int argc; | ||
636 | int i; | ||
637 | struct fsck_instance *inst, *p; | ||
638 | pid_t pid; | ||
639 | |||
640 | inst = xzalloc(sizeof(*inst)); | ||
641 | |||
642 | argv[0] = xasprintf("fsck.%s", type); /* 1 */ | ||
643 | for (i = 0; i < num_args; i++) | ||
644 | argv[i+1] = args[i]; /* num_args */ | ||
645 | argc = num_args + 1; | ||
646 | |||
647 | if (progress && !progress_active()) { | ||
648 | if (strcmp(type, "ext2") == 0 | ||
649 | || strcmp(type, "ext3") == 0 | ||
650 | ) { | ||
651 | argv[argc++] = xasprintf("-C%d", progress_fd); /* 1 */ | ||
652 | inst->flags |= FLAG_PROGRESS; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | argv[argc++] = xstrdup(device); /* 1 */ | ||
657 | argv[argc] = NULL; /* 1 */ | ||
658 | |||
659 | if (verbose || noexecute) { | ||
660 | printf("[%s (%d) -- %s]", argv[0], num_running, | ||
661 | mntpt ? mntpt : device); | ||
662 | for (i = 0; i < argc; i++) | ||
663 | printf(" %s", argv[i]); | ||
664 | puts(""); | ||
665 | } | ||
666 | |||
667 | /* Fork and execute the correct program. */ | ||
668 | pid = -1; | ||
669 | if (!noexecute) { | ||
670 | pid = fork(); /* TODO: NOMMU friendly way (vfork)? */ | ||
671 | if (pid < 0) | ||
672 | bb_perror_msg_and_die("fork"); | ||
673 | if (pid == 0) { | ||
674 | /* Child */ | ||
675 | if (!interactive) | ||
676 | close(0); | ||
677 | execvp(argv[0], argv); | ||
678 | bb_perror_msg_and_die("%s", argv[0]); | ||
679 | } | ||
680 | } | ||
681 | |||
682 | for (i = num_args+1; i < argc; i++) | ||
683 | free(argv[i]); | ||
684 | |||
685 | inst->pid = pid; | ||
686 | inst->prog = argv[0]; | ||
687 | inst->type = xstrdup(type); | ||
688 | inst->device = xstrdup(device); | ||
689 | inst->base_device = base_device(device); | ||
690 | inst->start_time = time(NULL); | ||
691 | inst->next = NULL; | ||
692 | |||
693 | /* | ||
694 | * Find the end of the list, so we add the instance on at the end. | ||
695 | */ | ||
696 | if (!instance_list) { | ||
697 | instance_list = inst; | ||
698 | return 0; | ||
699 | } | ||
700 | p = instance_list; | ||
701 | while (p->next) | ||
702 | p = p->next; | ||
703 | p->next = inst; | ||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | /* | ||
709 | * Run the fsck program on a particular device | 708 | * Run the fsck program on a particular device |
710 | * | 709 | * |
711 | * If the type is specified using -t, and it isn't prefixed with "no" | 710 | * If the type is specified using -t, and it isn't prefixed with "no" |
@@ -743,63 +742,6 @@ static void fsck_device(struct fs_info *fs, int interactive) | |||
743 | } | 742 | } |
744 | 743 | ||
745 | /* | 744 | /* |
746 | * Deal with the fsck -t argument. | ||
747 | */ | ||
748 | static void compile_fs_type(char *fs_type) | ||
749 | { | ||
750 | char *cp, *list, *s; | ||
751 | int num = 2; | ||
752 | int negate; | ||
753 | |||
754 | if (fs_type) { | ||
755 | cp = fs_type; | ||
756 | while ((cp = strchr(cp, ','))) { | ||
757 | num++; | ||
758 | cp++; | ||
759 | } | ||
760 | } | ||
761 | |||
762 | fs_type_list = xzalloc(num * sizeof(fs_type_list[0])); | ||
763 | fs_type_flag = xzalloc(num * sizeof(fs_type_flag[0])); | ||
764 | fs_type_negated = -1; | ||
765 | |||
766 | if (!fs_type) | ||
767 | return; | ||
768 | |||
769 | list = xstrdup(fs_type); | ||
770 | num = 0; | ||
771 | s = strtok(list, ","); | ||
772 | while (s) { | ||
773 | negate = 0; | ||
774 | if (s[0] == 'n' && s[1] == 'o') { /* "no.." */ | ||
775 | s += 2; | ||
776 | negate = 1; | ||
777 | } else if (s[0] == '!') { | ||
778 | s++; | ||
779 | negate = 1; | ||
780 | } | ||
781 | if (strcmp(s, "loop") == 0) | ||
782 | /* loop is really short-hand for opts=loop */ | ||
783 | goto loop_special_case; | ||
784 | if (strncmp(s, "opts=", 5) == 0) { | ||
785 | s += 5; | ||
786 | loop_special_case: | ||
787 | fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT; | ||
788 | } else { | ||
789 | if (fs_type_negated == -1) | ||
790 | fs_type_negated = negate; | ||
791 | if (fs_type_negated != negate) | ||
792 | bb_error_msg_and_die( | ||
793 | "Either all or none of the filesystem types passed to -t must be prefixed\n" | ||
794 | "with 'no' or '!'."); | ||
795 | } | ||
796 | fs_type_list[num++] = xstrdup(s); | ||
797 | s = strtok(NULL, ","); | ||
798 | } | ||
799 | free(list); | ||
800 | } | ||
801 | |||
802 | /* | ||
803 | * This function returns true if a particular option appears in a | 745 | * This function returns true if a particular option appears in a |
804 | * comma-delimited options list | 746 | * comma-delimited options list |
805 | */ | 747 | */ |
@@ -922,7 +864,7 @@ static int device_already_active(char *device) | |||
922 | * already active if there are any fsck instances running. | 864 | * already active if there are any fsck instances running. |
923 | */ | 865 | */ |
924 | if (!base) | 866 | if (!base) |
925 | return (instance_list != 0); | 867 | return (instance_list != NULL); |
926 | 868 | ||
927 | for (inst = instance_list; inst; inst = inst->next) { | 869 | for (inst = instance_list; inst; inst = inst->next) { |
928 | if (!inst->base_device || !strcmp(base, inst->base_device)) { | 870 | if (!inst->base_device || !strcmp(base, inst->base_device)) { |
@@ -1047,9 +989,70 @@ static int check_all(void) | |||
1047 | return status; | 989 | return status; |
1048 | } | 990 | } |
1049 | 991 | ||
1050 | static void signal_cancel(int sig ATTRIBUTE_UNUSED) | 992 | /* |
993 | * Deal with the fsck -t argument. | ||
994 | * Huh, for mount "-t novfat,nfs" means "neither vfat nor nfs"! | ||
995 | * Why here we require "-t novfat,nonfs" ?? | ||
996 | */ | ||
997 | static void compile_fs_type(char *fs_type) | ||
1051 | { | 998 | { |
1052 | cancel_requested = 1; | 999 | char *s; |
1000 | int num = 2; | ||
1001 | smallint negate; | ||
1002 | |||
1003 | if (fs_type) { | ||
1004 | s = fs_type; | ||
1005 | while ((s = strchr(s, ','))) { | ||
1006 | num++; | ||
1007 | s++; | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | fs_type_list = xzalloc(num * sizeof(fs_type_list[0])); | ||
1012 | fs_type_flag = xzalloc(num * sizeof(fs_type_flag[0])); | ||
1013 | fs_type_negated = -1; /* not yet known is it negated or not */ | ||
1014 | |||
1015 | if (!fs_type) | ||
1016 | return; | ||
1017 | |||
1018 | // list = xstrdup(fs_type); | ||
1019 | num = 0; | ||
1020 | // s = strtok(list, ","); | ||
1021 | s = fs_type; | ||
1022 | while (1) { | ||
1023 | char *comma; | ||
1024 | |||
1025 | negate = 0; | ||
1026 | if (s[0] == 'n' && s[1] == 'o') { /* "no.." */ | ||
1027 | s += 2; | ||
1028 | negate = 1; | ||
1029 | } else if (s[0] == '!') { | ||
1030 | s++; | ||
1031 | negate = 1; | ||
1032 | } | ||
1033 | if (strcmp(s, "loop") == 0) | ||
1034 | /* loop is really short-hand for opts=loop */ | ||
1035 | goto loop_special_case; | ||
1036 | if (strncmp(s, "opts=", 5) == 0) { | ||
1037 | s += 5; | ||
1038 | loop_special_case: | ||
1039 | fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT; | ||
1040 | } else { | ||
1041 | if (fs_type_negated == -1) | ||
1042 | fs_type_negated = negate; | ||
1043 | if (fs_type_negated != negate) | ||
1044 | bb_error_msg_and_die( | ||
1045 | "either all or none of the filesystem types passed to -t must be prefixed " | ||
1046 | "with 'no' or '!'"); | ||
1047 | } | ||
1048 | comma = strchr(s, ','); | ||
1049 | fs_type_list[num++] = comma ? xstrndup(s, comma-s) : xstrdup(s); | ||
1050 | if (!comma) | ||
1051 | break; | ||
1052 | s = comma + 1; | ||
1053 | // s = strtok(NULL, ","); | ||
1054 | } | ||
1055 | // free(list); | ||
1053 | } | 1056 | } |
1054 | 1057 | ||
1055 | static void parse_args(int argc, char *argv[]) | 1058 | static void parse_args(int argc, char *argv[]) |
@@ -1059,23 +1062,17 @@ static void parse_args(int argc, char *argv[]) | |||
1059 | char *options = NULL; | 1062 | char *options = NULL; |
1060 | int optpos = 0; | 1063 | int optpos = 0; |
1061 | int opts_for_fsck = 0; | 1064 | int opts_for_fsck = 0; |
1062 | struct sigaction sa; | ||
1063 | |||
1064 | /* | ||
1065 | * Set up signal action | ||
1066 | */ | ||
1067 | memset(&sa, 0, sizeof(sa)); | ||
1068 | sa.sa_handler = signal_cancel; | ||
1069 | sigaction(SIGINT, &sa, 0); | ||
1070 | sigaction(SIGTERM, &sa, 0); | ||
1071 | 1065 | ||
1066 | /* in bss | ||
1072 | num_devices = 0; | 1067 | num_devices = 0; |
1073 | num_args = 0; | 1068 | num_args = 0; |
1074 | instance_list = 0; | 1069 | instance_list = NULL; |
1070 | */ | ||
1075 | 1071 | ||
1076 | /* TODO: getopt32 */ | 1072 | /* TODO: getopt32 */ |
1077 | for (i = 1; i < argc; i++) { | 1073 | for (i = 1; i < argc; i++) { |
1078 | arg = argv[i]; | 1074 | arg = argv[i]; |
1075 | /* "/dev/blk" or "/path" or "UUID=xxx" or "LABEL=xxx" */ | ||
1079 | if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) { | 1076 | if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) { |
1080 | #if 0 | 1077 | #if 0 |
1081 | char *dev; | 1078 | char *dev; |
@@ -1095,7 +1092,7 @@ static void parse_args(int argc, char *argv[]) | |||
1095 | */ | 1092 | */ |
1096 | if (geteuid()) | 1093 | if (geteuid()) |
1097 | bb_error_msg_and_die( | 1094 | bb_error_msg_and_die( |
1098 | "must be root to scan for matching filesystems: %s\n", arg); | 1095 | "must be root to scan for matching filesystems: %s", arg); |
1099 | else | 1096 | else |
1100 | bb_error_msg_and_die( | 1097 | bb_error_msg_and_die( |
1101 | "cannot find matching filesystem: %s", arg); | 1098 | "cannot find matching filesystem: %s", arg); |
@@ -1103,6 +1100,8 @@ static void parse_args(int argc, char *argv[]) | |||
1103 | devices = xrealloc(devices, (num_devices+1) * sizeof(devices[0])); | 1100 | devices = xrealloc(devices, (num_devices+1) * sizeof(devices[0])); |
1104 | devices[num_devices++] = dev ? dev : xstrdup(arg); | 1101 | devices[num_devices++] = dev ? dev : xstrdup(arg); |
1105 | #endif | 1102 | #endif |
1103 | // FIXME: must check that arg is a blkdev, or resolve | ||
1104 | // "/path", "UUID=xxx" or "LABEL=xxx" into block device name | ||
1106 | devices = xrealloc(devices, (num_devices+1) * sizeof(devices[0])); | 1105 | devices = xrealloc(devices, (num_devices+1) * sizeof(devices[0])); |
1107 | devices[num_devices++] = xstrdup(arg); | 1106 | devices[num_devices++] = xstrdup(arg); |
1108 | continue; | 1107 | continue; |
@@ -1197,12 +1196,26 @@ static void parse_args(int argc, char *argv[]) | |||
1197 | max_running = xatoi(tmp); | 1196 | max_running = xatoi(tmp); |
1198 | } | 1197 | } |
1199 | 1198 | ||
1199 | static void signal_cancel(int sig ATTRIBUTE_UNUSED) | ||
1200 | { | ||
1201 | cancel_requested = 1; | ||
1202 | } | ||
1203 | |||
1200 | int fsck_main(int argc, char *argv[]) | 1204 | int fsck_main(int argc, char *argv[]) |
1201 | { | 1205 | { |
1202 | int i, status = 0; | 1206 | int i, status = 0; |
1203 | int interactive = 0; | 1207 | int interactive = 0; |
1204 | const char *fstab; | 1208 | const char *fstab; |
1205 | struct fs_info *fs; | 1209 | struct fs_info *fs; |
1210 | struct sigaction sa; | ||
1211 | |||
1212 | /* | ||
1213 | * Set up signal action | ||
1214 | */ | ||
1215 | memset(&sa, 0, sizeof(sa)); | ||
1216 | sa.sa_handler = signal_cancel; | ||
1217 | sigaction(SIGINT, &sa, 0); | ||
1218 | sigaction(SIGTERM, &sa, 0); | ||
1206 | 1219 | ||
1207 | setbuf(stdout, NULL); | 1220 | setbuf(stdout, NULL); |
1208 | /*setvbuf(stdout, NULL, _IONBF, BUFSIZ);*/ | 1221 | /*setvbuf(stdout, NULL, _IONBF, BUFSIZ);*/ |
@@ -1214,6 +1227,8 @@ int fsck_main(int argc, char *argv[]) | |||
1214 | if (!notitle) | 1227 | if (!notitle) |
1215 | puts("fsck (busybox "BB_VER", "BB_BT")"); | 1228 | puts("fsck (busybox "BB_VER", "BB_BT")"); |
1216 | 1229 | ||
1230 | /* Even plain "fsck /dev/hda1" needs fstab to get fs type, | ||
1231 | * so we are scanning it anyway */ | ||
1217 | fstab = getenv("FSTAB_FILE"); | 1232 | fstab = getenv("FSTAB_FILE"); |
1218 | if (!fstab) | 1233 | if (!fstab) |
1219 | fstab = "/etc/fstab"; | 1234 | fstab = "/etc/fstab"; |