Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/e2fsprogs/fsck.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/e2fsprogs/fsck.c
r3232 r3621 34 34 * It doesn't guess filesystem types from on-disk format. 35 35 */ 36 //config:config FSCK 37 //config: bool "fsck" 38 //config: default y 39 //config: help 40 //config: fsck is used to check and optionally repair one or more filesystems. 41 //config: In actuality, fsck is simply a front-end for the various file system 42 //config: checkers (fsck.fstype) available under Linux. 43 44 //applet:IF_FSCK(APPLET(fsck, BB_DIR_SBIN, BB_SUID_DROP)) 45 46 //kbuild:lib-$(CONFIG_FSCK) += fsck.o 36 47 37 48 //usage:#define fsck_trivial_usage 38 //usage: "[-ANPRTV] [- C FD] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..."49 //usage: "[-ANPRTV] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..." 39 50 //usage:#define fsck_full_usage "\n\n" 40 51 //usage: "Check and repair filesystems\n" … … 45 56 //usage: "\n -T Don't show title on startup" 46 57 //usage: "\n -V Verbose" 47 //usage: "\n -C n Write status information to specified filedescriptor" 58 //DO_PROGRESS_INDICATOR is off: 59 ////usage: "\n -C FD Write status information to specified file descriptor" 48 60 //usage: "\n -t TYPE List of filesystem types to check" 49 61 50 62 #include "libbb.h" 63 #include "common_bufsiz.h" 51 64 52 65 /* "progress indicator" code is somewhat buggy and ext[23] specific. … … 126 139 #define BASE_MD "/dev/md" 127 140 128 static char **args; 129 static int num_args; 130 static int verbose; 141 struct globals { 142 char **args; 143 int num_args; 144 int verbose; 131 145 132 146 #define FS_TYPE_FLAG_NORMAL 0 133 147 #define FS_TYPE_FLAG_OPT 1 134 148 #define FS_TYPE_FLAG_NEGOPT 2 135 static char **fs_type_list; 136 static uint8_t *fs_type_flag; 137 static smallint fs_type_negated; 138 139 static smallint noexecute; 140 static smallint serialize; 141 static smallint skip_root; 142 /* static smallint like_mount; */ 143 static smallint parallel_root; 144 static smallint force_all_parallel; 149 char **fs_type_list; 150 uint8_t *fs_type_flag; 151 smallint fs_type_negated; 152 153 smallint noexecute; 154 smallint serialize; 155 smallint skip_root; 156 /* smallint like_mount; */ 157 smallint parallel_root; 158 smallint force_all_parallel; 159 smallint kill_sent; 145 160 146 161 #if DO_PROGRESS_INDICATOR 147 static smallint progress; 148 static int progress_fd; 149 #endif 150 151 static int num_running; 152 static int max_running; 153 static char *fstype; 154 static struct fs_info *filesys_info; 155 static struct fs_info *filesys_last; 156 static struct fsck_instance *instance_list; 162 smallint progress; 163 int progress_fd; 164 #endif 165 166 int num_running; 167 int max_running; 168 char *fstype; 169 struct fs_info *filesys_info; 170 struct fs_info *filesys_last; 171 struct fsck_instance *instance_list; 172 } FIX_ALIASING; 173 #define G (*(struct globals*)bb_common_bufsiz1) 174 #define INIT_G() do { \ 175 setup_common_bufsiz(); \ 176 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 177 } while (0) 157 178 158 179 /* … … 200 221 201 222 /* Handle DAC 960 devices */ 202 if ( strncmp(cp, "rd/", 3) == 0) {223 if (is_prefixed_with(cp, "rd/")) { 203 224 cp += 3; 204 225 if (cp[0] != 'c' || !isdigit(cp[1]) … … 225 246 /* Now let's handle devfs (ugh) names */ 226 247 len = 0; 227 if ( strncmp(cp, "ide/", 4) == 0)248 if (is_prefixed_with(cp, "ide/")) 228 249 len = 4; 229 if ( strncmp(cp, "scsi/", 5) == 0)250 if (is_prefixed_with(cp, "scsi/")) 230 251 len = 5; 231 252 if (len) { … … 238 259 */ 239 260 for (hier = devfs_hier; *hier; hier++) { 240 len = strlen(*hier);241 if ( strncmp(cp, *hier, len) != 0)261 cp = is_prefixed_with(cp, *hier); 262 if (!cp) 242 263 goto errout; 243 cp += len; 244 while (*cp != '/' && *cp != 0) { 264 while (*cp != '/' && *cp != '\0') { 245 265 if (!isdigit(*cp)) 246 266 goto errout; 247 267 cp++; 248 268 } 269 //FIXME: what if *cp = '\0' now? cp++ moves past it!!! 249 270 cp++; 250 271 } 251 cp[-1] = 0;272 cp[-1] = '\0'; 252 273 return str; 253 274 } 254 275 255 276 /* Now handle devfs /dev/disc or /dev/disk names */ 256 disk = 0;257 if ( strncmp(cp, "discs/", 6) == 0)277 disk = NULL; 278 if (is_prefixed_with(cp, "discs/")) 258 279 disk = "disc"; 259 else if ( strncmp(cp, "disks/", 6) == 0)280 else if (is_prefixed_with(cp, "disks/")) 260 281 disk = "disk"; 261 282 if (disk) { 262 283 cp += 6; 263 if (strncmp(cp, disk, 4) != 0) 284 cp = is_prefixed_with(cp, disk); 285 if (!cp) 264 286 goto errout; 265 cp += 4; 266 while (*cp != '/' && *cp != 0) { 287 while (*cp != '/' && *cp != '\0') { 267 288 if (!isdigit(*cp)) 268 289 goto errout; 269 290 cp++; 270 291 } 271 *cp = 0;292 *cp = '\0'; 272 293 return str; 273 294 } … … 303 324 /*fs->next = NULL; */ 304 325 305 if (! filesys_info)306 filesys_info = fs;326 if (!G.filesys_info) 327 G.filesys_info = fs; 307 328 else 308 filesys_last->next = fs;309 filesys_last = fs;329 G.filesys_last->next = fs; 330 G.filesys_last = fs; 310 331 311 332 return fs; … … 317 338 FILE *fstab; 318 339 struct mntent mte; 340 char buf[1024]; 319 341 320 342 fstab = setmntent(filename, "r"); … … 325 347 326 348 // Loop through entries 327 while (getmntent_r(fstab, &mte, b b_common_bufsiz1, COMMON_BUFSIZE)) {328 //bb_ info_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir,349 while (getmntent_r(fstab, &mte, buf, sizeof(buf))) { 350 //bb_error_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir, 329 351 // mte.mnt_type, mte.mnt_opts, 330 352 // mte.mnt_passno); … … 341 363 struct fs_info *fs; 342 364 343 for (fs = filesys_info; fs; fs = fs->next) {365 for (fs = G.filesys_info; fs; fs = fs->next) { 344 366 if (strcmp(filesys, fs->device) == 0 345 367 || (fs->mountpt && strcmp(filesys, fs->mountpt) == 0) … … 356 378 struct fsck_instance *inst; 357 379 358 for (inst = instance_list; inst; inst = inst->next) {380 for (inst = G.instance_list; inst; inst = inst->next) { 359 381 if (inst->flags & FLAG_DONE) 360 382 continue; … … 372 394 static void kill_all_if_got_signal(void) 373 395 { 374 static smallint kill_sent;375 376 396 struct fsck_instance *inst; 377 397 378 if (!bb_got_signal || kill_sent)398 if (!bb_got_signal || G.kill_sent) 379 399 return; 380 400 381 for (inst = instance_list; inst; inst = inst->next) {401 for (inst = G.instance_list; inst; inst = inst->next) { 382 402 if (inst->flags & FLAG_DONE) 383 403 continue; 384 404 kill(inst->pid, SIGTERM); 385 405 } 386 kill_sent = 1;406 G.kill_sent = 1; 387 407 } 388 408 … … 399 419 pid_t pid; 400 420 401 if (! instance_list)421 if (!G.instance_list) 402 422 return -1; 403 /* if ( noexecute) { already returned -1; } */423 /* if (G.noexecute) { already returned -1; } */ 404 424 405 425 while (1) { … … 419 439 } 420 440 prev = NULL; 421 inst = instance_list;441 inst = G.instance_list; 422 442 do { 423 443 if (inst->pid == pid) … … 429 449 child_died: 430 450 431 if (WIFEXITED(status)) 432 status = WEXITSTATUS(status); 433 else if (WIFSIGNALED(status)) { 451 status = WEXITSTATUS(status); 452 if (WIFSIGNALED(status)) { 434 453 sig = WTERMSIG(status); 435 454 status = EXIT_UNCORRECTED; … … 440 459 status = EXIT_ERROR; 441 460 } 442 } else {443 printf("%s %s: status is %x, should never happen\n",444 inst->prog, inst->device, status);445 status = EXIT_ERROR;446 461 } 447 462 … … 449 464 if (progress && (inst->flags & FLAG_PROGRESS) && !progress_active()) { 450 465 struct fsck_instance *inst2; 451 for (inst2 = instance_list; inst2; inst2 = inst2->next) {466 for (inst2 = G.instance_list; inst2; inst2 = inst2->next) { 452 467 if (inst2->flags & FLAG_DONE) 453 468 continue; … … 476 491 prev->next = inst->next; 477 492 else 478 instance_list = inst->next;479 if ( verbose > 1)493 G.instance_list = inst->next; 494 if (G.verbose > 1) 480 495 printf("Finished with %s (exit status %d)\n", 481 496 inst->device, status); 482 num_running--;497 G.num_running--; 483 498 free_instance(inst); 484 499 … … 516 531 pid_t pid; 517 532 518 args[0] = xasprintf("fsck.%s", type);533 G.args[0] = xasprintf("fsck.%s", type); 519 534 520 535 #if DO_PROGRESS_INDICATOR … … 523 538 || strcmp(type, "ext3") == 0 524 539 ) { 525 args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */540 G.args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */ 526 541 inst->flags |= FLAG_PROGRESS; 527 542 } … … 529 544 #endif 530 545 531 args[num_args - 2] = (char*)device;532 /* args[num_args - 1] = NULL; - already is */533 534 if ( verbose ||noexecute) {535 printf("[%s (%d) -- %s]", args[0],num_running,546 G.args[G.num_args - 2] = (char*)device; 547 /* G.args[G.num_args - 1] = NULL; - already is */ 548 549 if (G.verbose || G.noexecute) { 550 printf("[%s (%d) -- %s]", G.args[0], G.num_running, 536 551 mntpt ? mntpt : device); 537 for (i = 0; args[i]; i++)538 printf(" %s", args[i]);552 for (i = 0; G.args[i]; i++) 553 printf(" %s", G.args[i]); 539 554 bb_putchar('\n'); 540 555 } … … 542 557 /* Fork and execute the correct program. */ 543 558 pid = -1; 544 if (! noexecute) {545 pid = spawn( args);559 if (!G.noexecute) { 560 pid = spawn(G.args); 546 561 if (pid < 0) 547 bb_simple_perror_msg( args[0]);562 bb_simple_perror_msg(G.args[0]); 548 563 } 549 564 550 565 #if DO_PROGRESS_INDICATOR 551 free( args[XXX]);566 free(G.args[XXX]); 552 567 #endif 553 568 554 569 /* No child, so don't record an instance */ 555 570 if (pid <= 0) { 556 free( args[0]);571 free(G.args[0]); 557 572 return; 558 573 } … … 560 575 inst = xzalloc(sizeof(*inst)); 561 576 inst->pid = pid; 562 inst->prog = args[0];577 inst->prog = G.args[0]; 563 578 inst->device = xstrdup(device); 564 579 inst->base_device = base_device(device); … … 569 584 /* Add to the list of running fsck's. 570 585 * (was adding to the end, but adding to the front is simpler...) */ 571 inst->next = instance_list;572 instance_list = inst;586 inst->next = G.instance_list; 587 G.instance_list = inst; 573 588 } 574 589 … … 589 604 if (strcmp(fs->type, "auto") != 0) { 590 605 type = fs->type; 591 if ( verbose > 2)592 bb_info_msg("using filesystem type '%s' %s",606 if (G.verbose > 2) 607 printf("using filesystem type '%s' %s\n", 593 608 type, "from fstab"); 594 } else if ( fstype595 && ( fstype[0] != 'n' ||fstype[1] != 'o') /* != "no" */596 && strncmp(fstype, "opts=", 5) != 0597 && strncmp(fstype, "loop", 4) != 0598 && !strchr( fstype, ',')609 } else if (G.fstype 610 && (G.fstype[0] != 'n' || G.fstype[1] != 'o') /* != "no" */ 611 && !is_prefixed_with(G.fstype, "opts=") 612 && !is_prefixed_with(G.fstype, "loop") 613 && !strchr(G.fstype, ',') 599 614 ) { 600 type = fstype;601 if ( verbose > 2)602 bb_info_msg("using filesystem type '%s' %s",615 type = G.fstype; 616 if (G.verbose > 2) 617 printf("using filesystem type '%s' %s\n", 603 618 type, "from -t"); 604 619 } else { 605 620 type = "auto"; 606 if ( verbose > 2)607 bb_info_msg("using filesystem type '%s' %s",621 if (G.verbose > 2) 622 printf("using filesystem type '%s' %s\n", 608 623 type, "(default)"); 609 624 } 610 625 611 num_running++;626 G.num_running++; 612 627 execute(type, fs->device, fs->mountpt /*, interactive */); 613 628 } … … 622 637 char *base; 623 638 624 if ( force_all_parallel)639 if (G.force_all_parallel) 625 640 return 0; 626 641 627 642 #ifdef BASE_MD 628 643 /* Don't check a soft raid disk with any other disk */ 629 if ( instance_list630 && ( !strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1)631 || !strncmp(device, BASE_MD, sizeof(BASE_MD)-1))644 if (G.instance_list 645 && (is_prefixed_with(G.instance_list->device, BASE_MD) 646 || is_prefixed_with(device, BASE_MD)) 632 647 ) { 633 648 return 1; … … 641 656 */ 642 657 if (!base) 643 return ( instance_list != NULL);644 645 for (inst = instance_list; inst; inst = inst->next) {658 return (G.instance_list != NULL); 659 660 for (inst = G.instance_list; inst; inst = inst->next) { 646 661 if (!inst->base_device || !strcmp(base, inst->base_device)) { 647 662 free(base); … … 688 703 char *cp; 689 704 690 if (! fs_type_list)705 if (!G.fs_type_list) 691 706 return 1; 692 707 … … 695 710 n = 0; 696 711 while (1) { 697 cp = fs_type_list[n];712 cp = G.fs_type_list[n]; 698 713 if (!cp) 699 714 break; 700 switch ( fs_type_flag[n]) {715 switch (G.fs_type_flag[n]) { 701 716 case FS_TYPE_FLAG_NORMAL: 702 717 checked_type++; … … 718 733 return 1; 719 734 720 return ( fs_type_negated ? !ret : ret);735 return (G.fs_type_negated ? !ret : ret); 721 736 } 722 737 … … 754 769 int passno; 755 770 756 if ( verbose)771 if (G.verbose) 757 772 puts("Checking all filesystems"); 758 773 … … 762 777 * filesystem types (done as a side-effect of calling ignore()). 763 778 */ 764 for (fs = filesys_info; fs; fs = fs->next)779 for (fs = G.filesys_info; fs; fs = fs->next) 765 780 if (ignore(fs)) 766 781 fs->flags |= FLAG_DONE; … … 769 784 * Find and check the root filesystem. 770 785 */ 771 if (! parallel_root) {772 for (fs = filesys_info; fs; fs = fs->next) {786 if (!G.parallel_root) { 787 for (fs = G.filesys_info; fs; fs = fs->next) { 773 788 if (LONE_CHAR(fs->mountpt, '/')) { 774 if (! skip_root && !ignore(fs)) {789 if (!G.skip_root && !ignore(fs)) { 775 790 fsck_device(fs /*, 1*/); 776 791 status |= wait_many(FLAG_WAIT_ALL); … … 788 803 * "Skip root" will skip _all_ root entries. 789 804 */ 790 if ( skip_root)791 for (fs = filesys_info; fs; fs = fs->next)805 if (G.skip_root) 806 for (fs = G.filesys_info; fs; fs = fs->next) 792 807 if (LONE_CHAR(fs->mountpt, '/')) 793 808 fs->flags |= FLAG_DONE; … … 799 814 pass_done = 1; 800 815 801 for (fs = filesys_info; fs; fs = fs->next) {816 for (fs = G.filesys_info; fs; fs = fs->next) { 802 817 if (bb_got_signal) 803 818 break; … … 825 840 * Spawn off the fsck process 826 841 */ 827 fsck_device(fs /*, serialize*/);842 fsck_device(fs /*, G.serialize*/); 828 843 fs->flags |= FLAG_DONE; 829 844 … … 833 848 * at one time, apply that limit. 834 849 */ 835 if ( serialize836 || ( max_running && (num_running >= max_running))850 if (G.serialize 851 || (G.num_running >= G.max_running) 837 852 ) { 838 853 pass_done = 0; … … 842 857 if (bb_got_signal) 843 858 break; 844 if ( verbose > 1)859 if (G.verbose > 1) 845 860 printf("--waiting-- (pass %d)\n", passno); 846 861 status |= wait_many(pass_done ? FLAG_WAIT_ALL : 847 862 FLAG_WAIT_ATLEAST_ONE); 848 863 if (pass_done) { 849 if ( verbose > 1)864 if (G.verbose > 1) 850 865 puts("----------------------------------"); 851 866 passno++; … … 875 890 } 876 891 877 fs_type_list = xzalloc(num * sizeof(fs_type_list[0]));878 fs_type_flag = xzalloc(num * sizeof(fs_type_flag[0]));879 fs_type_negated = -1; /* not yet known is it negated or not */892 G.fs_type_list = xzalloc(num * sizeof(G.fs_type_list[0])); 893 G.fs_type_flag = xzalloc(num * sizeof(G.fs_type_flag[0])); 894 G.fs_type_negated = -1; /* not yet known is it negated or not */ 880 895 881 896 num = 0; … … 896 911 /* loop is really short-hand for opts=loop */ 897 912 goto loop_special_case; 898 if ( strncmp(s, "opts=", 5) == 0) {913 if (is_prefixed_with(s, "opts=")) { 899 914 s += 5; 900 915 loop_special_case: 901 fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT;916 G.fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT; 902 917 } else { 903 if ( fs_type_negated == -1)904 fs_type_negated = negate;905 if ( fs_type_negated != negate)918 if (G.fs_type_negated == -1) 919 G.fs_type_negated = negate; 920 if (G.fs_type_negated != negate) 906 921 bb_error_msg_and_die( 907 922 "either all or none of the filesystem types passed to -t must be prefixed " 908 923 "with 'no' or '!'"); 909 924 } 910 comma = strchr (s, ',');911 fs_type_list[num++] = comma ? xstrndup(s, comma-s) : xstrdup(s);912 if ( !comma)925 comma = strchrnul(s, ','); 926 G.fs_type_list[num++] = xstrndup(s, comma-s); 927 if (*comma == '\0') 913 928 break; 914 929 s = comma + 1; … … 918 933 static char **new_args(void) 919 934 { 920 args = xrealloc_vector(args, 2,num_args);921 return & args[num_args++];935 G.args = xrealloc_vector(G.args, 2, G.num_args); 936 return &G.args[G.num_args++]; 922 937 } 923 938 … … 936 951 smallint notitle; 937 952 953 INIT_G(); 954 938 955 /* we want wait() to be interruptible */ 939 956 signal_no_SA_RESTART_empty_mask(SIGINT, record_signo); … … 945 962 devices = NULL; 946 963 num_devices = 0; 947 new_args(); /* args[0] = NULL, will be replaced by fsck.<type> */948 /* instance_list = NULL; - in bss, so already zeroed */964 new_args(); /* G.args[0] = NULL, will be replaced by fsck.<type> */ 965 /* G.instance_list = NULL; - in bss, so already zeroed */ 949 966 950 967 while (*++argv) { … … 995 1012 #endif 996 1013 case 'V': 997 verbose++;1014 G.verbose++; 998 1015 break; 999 1016 case 'N': 1000 noexecute = 1;1017 G.noexecute = 1; 1001 1018 break; 1002 1019 case 'R': 1003 skip_root = 1;1020 G.skip_root = 1; 1004 1021 break; 1005 1022 case 'T': … … 1010 1027 break; */ 1011 1028 case 'P': 1012 parallel_root = 1;1029 G.parallel_root = 1; 1013 1030 break; 1014 1031 case 's': 1015 serialize = 1;1032 G.serialize = 1; 1016 1033 break; 1017 1034 case 't': 1018 if ( fstype)1035 if (G.fstype) 1019 1036 bb_show_usage(); 1020 1037 if (arg[++j]) … … 1024 1041 else 1025 1042 bb_show_usage(); 1026 fstype = xstrdup(tmp);1027 compile_fs_type( fstype);1043 G.fstype = xstrdup(tmp); 1044 compile_fs_type(G.fstype); 1028 1045 goto next_arg; 1029 1046 case '?': … … 1046 1063 } 1047 1064 if (getenv("FSCK_FORCE_ALL_PARALLEL")) 1048 force_all_parallel = 1;1065 G.force_all_parallel = 1; 1049 1066 tmp = getenv("FSCK_MAX_INST"); 1067 G.max_running = INT_MAX; 1050 1068 if (tmp) 1051 max_running = xatoi(tmp);1052 new_args(); /* args[num_args - 2] will be replaced by <device> */1053 new_args(); /* args[num_args - 1] is the last, NULL element */1069 G.max_running = xatoi(tmp); 1070 new_args(); /* G.args[G.num_args - 2] will be replaced by <device> */ 1071 new_args(); /* G.args[G.num_args - 1] is the last, NULL element */ 1054 1072 1055 1073 if (!notitle) … … 1063 1081 load_fs_info(fstab); 1064 1082 1065 /*interactive = (num_devices == 1) | serialize;*/1083 /*interactive = (num_devices == 1) | G.serialize;*/ 1066 1084 1067 1085 if (num_devices == 0) 1068 /*interactive =*/ serialize = doall = 1;1086 /*interactive =*/ G.serialize = doall = 1; 1069 1087 if (doall) 1070 1088 return check_all(); … … 1082 1100 fsck_device(fs /*, interactive */); 1083 1101 1084 if ( serialize1085 || ( max_running && (num_running >= max_running))1102 if (G.serialize 1103 || (G.num_running >= G.max_running) 1086 1104 ) { 1087 1105 int exit_status = wait_one(0); 1088 1106 if (exit_status >= 0) 1089 1107 status |= exit_status; 1090 if ( verbose > 1)1108 if (G.verbose > 1) 1091 1109 puts("----------------------------------"); 1092 1110 }
Note:
See TracChangeset
for help on using the changeset viewer.