aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-19 02:02:33 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-19 02:02:33 +0000
commit1abf91aa253bb69ce2d21daca70726941d910d1c (patch)
tree17691bdaae09d19844ae0fa0395f25bda688169b
parenta0e701d137a0d57befe9839ffadd30b69c05899e (diff)
downloadbusybox-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.c355
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 */
401static void load_fs_info(const char *filename) 399static 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 */
477static 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 */
556static void kill_all_if_cancel_requested(void) 474static 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 */
631static 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 */
748static 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
1050static 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 */
997static 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
1055static void parse_args(int argc, char *argv[]) 1058static 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
1199static void signal_cancel(int sig ATTRIBUTE_UNUSED)
1200{
1201 cancel_requested = 1;
1202}
1203
1200int fsck_main(int argc, char *argv[]) 1204int 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";