2 * pfsck --- A generic, parallelizing front-end for the fsck program.
3 * It will automatically try to run fsck programs in parallel if the
4 * devices are on separate spindles. It is based on the same ideas as
5 * the generic front end for fsck by David Engel and Fred van Kempen,
6 * but it has been completely rewritten from scratch to support
9 * Written by Theodore Ts'o, <tytso@mit.edu>
11 * Miquel van Smoorenburg (miquels@drinkel.ow.org) 20-Oct-1994:
12 * o Changed -t fstype to behave like with mount when -A (all file
13 * systems) or -M (like mount) is specified.
14 * o fsck looks if it can find the fsck.type program to decide
15 * if it should ignore the fs type. This way more fsck programs
16 * can be added without changing this front-end.
17 * o -R flag skip root file system.
19 * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
20 * 2001, 2002, 2003, 2004, 2005 by Theodore Ts'o.
23 * This file may be redistributed under the terms of the GNU Public
28 #define _XOPEN_SOURCE 600 /* for inclusion of sa_handler in Solaris */
30 #include <sys/types.h>
32 #include <sys/signal.h>
61 #include "../version.h"
62 #include "nls-enable.h"
64 #include "blkid/blkid.h"
67 #define _PATH_MNTTAB "/etc/fstab"
70 static const char *ignored_types[] = {
82 static const char *really_wanted[] = {
95 #define BASE_MD "/dev/md"
98 * Global variables for options
100 char *devices[MAX_DEVICES];
101 char *args[MAX_ARGS];
102 int num_devices, num_args;
109 int ignore_mounted = 0;
111 int parallel_root = 0;
114 int force_all_parallel = 0;
117 volatile int cancel_requested = 0;
121 struct fs_info *filesys_info = NULL, *filesys_last = NULL;
122 struct fsck_instance *instance_list;
123 const char *fsck_prefix_path = "/sbin:/sbin/fs.d:/sbin/fs:/etc/fs:/etc";
125 blkid_cache cache = NULL;
127 static char *string_copy(const char *s)
133 ret = malloc(strlen(s)+1);
139 static int string_to_int(const char *s)
144 l = strtol(s, &p, 0);
145 if (*p || l == LONG_MIN || l == LONG_MAX || l < 0 || l > INT_MAX)
151 static int ignore(struct fs_info *);
153 static char *skip_over_blank(char *cp)
155 while (*cp && isspace(*cp))
160 static char *skip_over_word(char *cp)
162 while (*cp && !isspace(*cp))
167 static void strip_line(char *line)
172 p = line + strlen(line) - 1;
173 if ((*p == '\n') || (*p == '\r'))
180 static char *parse_word(char **buf)
188 word = skip_over_blank(word);
189 next = skip_over_word(word);
196 static void parse_escape(char *word)
204 for (p = word, q = word; *p; p++, q++) {
223 for (i = 0; i < 3; i++, p++) {
226 ac = (ac * 8) + (*p - '0');
234 static void free_instance(struct fsck_instance *i)
241 free(i->base_device);
246 static struct fs_info *create_fs_device(const char *device, const char *mntpnt,
247 const char *type, const char *opts,
248 int freq, int passno)
252 if (!(fs = malloc(sizeof(struct fs_info))))
255 fs->device = string_copy(device);
256 fs->mountpt = string_copy(mntpnt);
257 fs->type = string_copy(type);
258 fs->opts = string_copy(opts ? opts : "");
267 filesys_last->next = fs;
275 static int parse_fstab_line(char *line, struct fs_info **ret_fs)
277 char *dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp;
284 device = parse_word(&cp);
285 if (!device || *device == '#')
286 return 0; /* Ignore blank lines and comments */
287 mntpnt = parse_word(&cp);
288 type = parse_word(&cp);
289 opts = parse_word(&cp);
290 freq = parse_word(&cp);
291 passno = parse_word(&cp);
293 if (!mntpnt || !type)
296 parse_escape(device);
297 parse_escape(mntpnt);
301 parse_escape(passno);
303 dev = blkid_get_devname(cache, device, NULL);
307 if (strchr(type, ','))
310 fs = create_fs_device(device, mntpnt, type ? type : "auto", opts,
311 freq ? atoi(freq) : -1,
312 passno ? atoi(passno) : -1);
322 static void interpret_type(struct fs_info *fs)
326 if (strcmp(fs->type, "auto") != 0)
328 t = blkid_get_tag_value(cache, "TYPE", fs->device);
336 * Load the filesystem database from /etc/fstab
338 static void load_fs_info(const char *filename)
346 if ((f = fopen(filename, "r")) == NULL) {
347 fprintf(stderr, _("WARNING: couldn't open %s: %s\n"),
348 filename, strerror(errno));
353 if (!fgets(buf, sizeof(buf), f))
355 buf[sizeof(buf)-1] = 0;
356 if (parse_fstab_line(buf, &fs) < 0) {
357 fprintf(stderr, _("WARNING: bad format "
358 "on line %d of %s\n"), lineno, filename);
371 if (old_fstab && filesys_info) {
372 fputs(_("\007\007\007"
373 "WARNING: Your /etc/fstab does not contain the fsck passno\n"
374 " field. I will kludge around things for you, but you\n"
375 " should fix your /etc/fstab file as soon as you can.\n\n"), stderr);
377 for (fs = filesys_info; fs; fs = fs->next) {
383 /* Lookup filesys in /etc/fstab and return the corresponding entry. */
384 static struct fs_info *lookup(char *filesys)
388 /* No filesys name given. */
392 for (fs = filesys_info; fs; fs = fs->next) {
393 if (!strcmp(filesys, fs->device) ||
394 (fs->mountpt && !strcmp(filesys, fs->mountpt)))
401 /* Find fsck program for a given fs type. */
402 static char *find_fsck(char *type)
406 static char prog[256];
407 char *p = string_copy(fsck_path);
410 /* Are we looking for a program or just a type? */
411 tpl = (strncmp(type, "fsck.", 5) ? "%s/fsck.%s" : "%s/%s");
413 for(s = strtok(p, ":"); s; s = strtok(NULL, ":")) {
414 sprintf(prog, tpl, s, type);
415 if (stat(prog, &st) == 0) break;
418 return(s ? prog : NULL);
421 static int progress_active(NOARGS)
423 struct fsck_instance *inst;
425 for (inst = instance_list; inst; inst = inst->next) {
426 if (inst->flags & FLAG_DONE)
428 if (inst->flags & FLAG_PROGRESS)
435 * Execute a particular fsck program, and link it into the list of
436 * child processes we are waiting for.
438 static int execute(const char *type, const char *device, const char *mntpt,
441 char *s, *argv[80], prog[80];
443 struct fsck_instance *inst, *p;
446 inst = malloc(sizeof(struct fsck_instance));
449 memset(inst, 0, sizeof(struct fsck_instance));
451 sprintf(prog, "fsck.%s", type);
452 argv[0] = string_copy(prog);
455 for (i=0; i <num_args; i++)
456 argv[argc++] = string_copy(args[i]);
459 if ((strcmp(type, "ext2") == 0) ||
460 (strcmp(type, "ext3") == 0) ||
461 (strcmp(type, "ext4") == 0) ||
462 (strcmp(type, "ext4dev") == 0)) {
466 if (!progress_active()) {
467 snprintf(tmp, 80, "-C%d", progress_fd);
468 inst->flags |= FLAG_PROGRESS;
469 } else if (progress_fd)
470 snprintf(tmp, 80, "-C%d", progress_fd * -1);
472 argv[argc++] = string_copy(tmp);
476 argv[argc++] = string_copy(device);
481 fprintf(stderr, _("fsck: %s: not found\n"), prog);
486 if (verbose || noexecute) {
487 printf("[%s (%d) -- %s] ", s, num_running,
488 mntpt ? mntpt : device);
489 for (i=0; i < argc; i++)
490 printf("%s ", argv[i]);
494 /* Fork and execute the correct program. */
497 else if ((pid = fork()) < 0) {
501 } else if (pid == 0) {
504 (void) execv(s, argv);
510 for (i=0; i < argc; i++)
514 inst->prog = string_copy(prog);
515 inst->type = string_copy(type);
516 inst->device = string_copy(device);
517 inst->base_device = base_device(device);
518 inst->start_time = time(0);
522 * Find the end of the list, so we add the instance on at the end.
524 for (p = instance_list; p && p->next; p = p->next);
529 instance_list = inst;
535 * Send a signal to all outstanding fsck child processes
537 static int kill_all(int signum)
539 struct fsck_instance *inst;
542 for (inst = instance_list; inst; inst = inst->next) {
543 if (inst->flags & FLAG_DONE)
545 kill(inst->pid, signum);
552 * Wait for one child process to exit; when it does, unlink it from
553 * the list of executing child processes, and return it.
555 static struct fsck_instance *wait_one(int flags)
559 struct fsck_instance *inst, *inst2, *prev;
566 inst = instance_list;
569 while (inst->next && (random() & 1)) {
574 inst->exit_status = 0;
579 * gcc -Wall fails saving throw against stupidity
580 * (inst and prev are thought to be uninitialized variables)
585 pid = waitpid(-1, &status, flags);
586 if (cancel_requested && !kill_sent) {
590 if ((pid == 0) && (flags & WNOHANG))
593 if ((errno == EINTR) || (errno == EAGAIN))
595 if (errno == ECHILD) {
597 _("%s: wait: No more child process?!?\n"),
604 for (prev = 0, inst = instance_list;
606 prev = inst, inst = inst->next) {
607 if (inst->pid == pid)
612 if (WIFEXITED(status))
613 status = WEXITSTATUS(status);
614 else if (WIFSIGNALED(status)) {
615 sig = WTERMSIG(status);
617 status = EXIT_UNCORRECTED;
619 printf(_("Warning... %s for device %s exited "
620 "with signal %d.\n"),
621 inst->prog, inst->device, sig);
625 printf(_("%s %s: status is %x, should never happen.\n"),
626 inst->prog, inst->device, status);
629 inst->exit_status = status;
630 inst->flags |= FLAG_DONE;
631 if (progress && (inst->flags & FLAG_PROGRESS) &&
632 !progress_active()) {
633 for (inst2 = instance_list; inst2; inst2 = inst2->next) {
634 if (inst2->flags & FLAG_DONE)
636 if (strcmp(inst2->type, "ext2") &&
637 strcmp(inst2->type, "ext3") &&
638 strcmp(inst2->type, "ext4") &&
639 strcmp(inst2->type, "ext4dev"))
642 * If we've just started the fsck, wait a tiny
643 * bit before sending the kill, to give it
644 * time to set up the signal handler
646 if (inst2->start_time < time(0)+2) {
649 kill(inst2->pid, SIGUSR1);
653 kill(inst2->pid, SIGUSR1);
654 inst2->flags |= FLAG_PROGRESS;
660 prev->next = inst->next;
662 instance_list = inst->next;
664 printf(_("Finished with %s (exit status %d)\n"),
665 inst->device, inst->exit_status);
670 #define FLAG_WAIT_ALL 0
671 #define FLAG_WAIT_ATLEAST_ONE 1
673 * Wait until all executing child processes have exited; return the
674 * logical OR of all of their exit code values.
676 static int wait_many(int flags)
678 struct fsck_instance *inst;
679 int global_status = 0;
682 while ((inst = wait_one(wait_flags))) {
683 global_status |= inst->exit_status;
686 if (noexecute && (flags & WNOHANG) && !(random() % 3))
689 if (flags & FLAG_WAIT_ATLEAST_ONE)
690 wait_flags = WNOHANG;
692 return global_status;
696 * Run the fsck program on a particular device
698 * If the type is specified using -t, and it isn't prefixed with "no"
699 * (as in "noext2") and only one filesystem type is specified, then
700 * use that type regardless of what is specified in /etc/fstab.
702 * If the type isn't specified by the user, then use either the type
703 * specified in /etc/fstab, or DEFAULT_FSTYPE.
705 static void fsck_device(struct fs_info *fs, int interactive)
712 if (strcmp(fs->type, "auto") != 0)
714 else if (fstype && strncmp(fstype, "no", 2) &&
715 strncmp(fstype, "opts=", 5) && strncmp(fstype, "loop", 4) &&
716 !strchr(fstype, ','))
719 type = DEFAULT_FSTYPE;
722 retval = execute(type, fs->device, fs->mountpt, interactive);
724 fprintf(stderr, _("%s: Error %d while executing fsck.%s "
725 "for %s\n"), progname, retval, type, fs->device);
732 * Deal with the fsck -t argument.
734 struct fs_type_compile {
740 #define FS_TYPE_NORMAL 0
741 #define FS_TYPE_OPT 1
742 #define FS_TYPE_NEGOPT 2
744 static const char *fs_type_syntax_error =
745 N_("Either all or none of the filesystem types passed to -t must be prefixed\n"
746 "with 'no' or '!'.\n");
748 static void compile_fs_type(char *fs_type, struct fs_type_compile *cmp)
752 int negate, first_negate = 1;
755 for (cp=fs_type; *cp; cp++) {
761 cmp->list = malloc(num * sizeof(char *));
762 cmp->type = malloc(num * sizeof(int));
763 if (!cmp->list || !cmp->type) {
764 fputs(_("Couldn't allocate memory for filesystem types\n"),
768 memset(cmp->list, 0, num * sizeof(char *));
769 memset(cmp->type, 0, num * sizeof(int));
775 list = string_copy(fs_type);
777 s = strtok(list, ",");
780 if (strncmp(s, "no", 2) == 0) {
783 } else if (*s == '!') {
787 if (strcmp(s, "loop") == 0)
788 /* loop is really short-hand for opts=loop */
789 goto loop_special_case;
790 else if (strncmp(s, "opts=", 5) == 0) {
793 cmp->type[num] = negate ? FS_TYPE_NEGOPT : FS_TYPE_OPT;
796 cmp->negate = negate;
799 if ((negate && !cmp->negate) ||
800 (!negate && cmp->negate)) {
801 fputs(_(fs_type_syntax_error), stderr);
806 printf("Adding %s to list (type %d).\n", s, cmp->type[num]);
808 cmp->list[num++] = string_copy(s);
809 s = strtok(NULL, ",");
815 * This function returns true if a particular option appears in a
816 * comma-delimited options list
818 static int opt_in_list(const char *opt, char *optlist)
824 list = string_copy(optlist);
826 s = strtok(list, ",");
828 if (strcmp(s, opt) == 0) {
832 s = strtok(NULL, ",");
838 /* See if the filesystem matches the criteria given by the -t option */
839 static int fs_match(struct fs_info *fs, struct fs_type_compile *cmp)
841 int n, ret = 0, checked_type = 0;
844 if (cmp->list == 0 || cmp->list[0] == 0)
847 for (n=0; (cp = cmp->list[n]); n++) {
848 switch (cmp->type[n]) {
851 if (strcmp(cp, fs->type) == 0) {
856 if (opt_in_list(cp, fs->opts))
860 if (!opt_in_list(cp, fs->opts))
865 if (checked_type == 0)
867 return (cmp->negate ? !ret : ret);
870 /* Check if we should ignore this filesystem. */
871 static int ignore(struct fs_info *fs)
877 * If the pass number is 0, ignore it.
883 * If this is a bind mount, ignore it.
885 if (opt_in_list("bind", fs->opts)) {
887 _("%s: skipping bad line in /etc/fstab: bind mount with nonzero fsck pass number\n"),
895 * If a specific fstype is specified, and it doesn't match,
898 if (!fs_match(fs, &fs_type_compiled)) return 1;
900 /* Are we ignoring this type? */
901 for(ip = ignored_types; *ip; ip++)
902 if (strcmp(fs->type, *ip) == 0) return 1;
904 /* Do we really really want to check this fs? */
905 for(ip = really_wanted; *ip; ip++)
906 if (strcmp(fs->type, *ip) == 0) {
911 /* See if the <fsck.fs> program is available. */
912 if (find_fsck(fs->type) == NULL) {
914 fprintf(stderr, _("fsck: cannot check %s: fsck.%s not found\n"),
915 fs->device, fs->type);
919 /* We can and want to check this file system type. */
924 * Returns TRUE if a partition on the same disk is already being
927 static int device_already_active(char *device)
929 struct fsck_instance *inst;
932 if (force_all_parallel)
936 /* Don't check a soft raid disk with any other disk */
938 (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1) ||
939 !strncmp(device, BASE_MD, sizeof(BASE_MD)-1)))
943 base = base_device(device);
945 * If we don't know the base device, assume that the device is
946 * already active if there are any fsck instances running.
949 return (instance_list != 0);
950 for (inst = instance_list; inst; inst = inst->next) {
951 if (!inst->base_device || !strcmp(base, inst->base_device)) {
960 /* Check all file systems, using the /etc/fstab table. */
961 static int check_all(NOARGS)
963 struct fs_info *fs = NULL;
964 int status = EXIT_OK;
965 int not_done_yet = 1;
970 fputs(_("Checking all file systems.\n"), stdout);
973 * Do an initial scan over the filesystem; mark filesystems
974 * which should be ignored as done, and resolve any "auto"
975 * filesystem types (done as a side-effect of calling ignore()).
977 for (fs = filesys_info; fs; fs = fs->next) {
979 fs->flags |= FLAG_DONE;
983 * Find and check the root filesystem.
985 if (!parallel_root) {
986 for (fs = filesys_info; fs; fs = fs->next) {
987 if (!strcmp(fs->mountpt, "/"))
991 if (!skip_root && !ignore(fs) &&
992 !(ignore_mounted && is_mounted(fs->device))) {
994 status |= wait_many(FLAG_WAIT_ALL);
995 if (status > EXIT_NONDESTRUCT)
998 fs->flags |= FLAG_DONE;
1002 * This is for the bone-headed user who enters the root
1003 * filesystem twice. Skip root will skep all root entries.
1006 for (fs = filesys_info; fs; fs = fs->next)
1007 if (!strcmp(fs->mountpt, "/"))
1008 fs->flags |= FLAG_DONE;
1010 while (not_done_yet) {
1014 for (fs = filesys_info; fs; fs = fs->next) {
1015 if (cancel_requested)
1017 if (fs->flags & FLAG_DONE)
1020 * If the filesystem's pass number is higher
1021 * than the current pass number, then we don't
1024 if (fs->passno > passno) {
1028 if (ignore_mounted && is_mounted(fs->device)) {
1029 fs->flags |= FLAG_DONE;
1033 * If a filesystem on a particular device has
1034 * already been spawned, then we need to defer
1035 * this to another pass.
1037 if (device_already_active(fs->device)) {
1042 * Spawn off the fsck process
1044 fsck_device(fs, serialize);
1045 fs->flags |= FLAG_DONE;
1048 * Only do one filesystem at a time, or if we
1049 * have a limit on the number of fsck's extant
1050 * at one time, apply that limit.
1053 (max_running && (num_running >= max_running))) {
1058 if (cancel_requested)
1061 printf(_("--waiting-- (pass %d)\n"), passno);
1062 status |= wait_many(pass_done ? FLAG_WAIT_ALL :
1063 FLAG_WAIT_ATLEAST_ONE);
1066 printf("----------------------------------\n");
1071 if (cancel_requested && !kill_sent) {
1075 status |= wait_many(FLAG_WAIT_ATLEAST_ONE);
1079 static void usage(NOARGS)
1081 fputs(_("Usage: fsck [-AMNPRTV] [ -C [ fd ] ] [-t fstype] [fs-options] [filesys ...]\n"), stderr);
1085 #ifdef HAVE_SIGNAL_H
1086 static void signal_cancel(int sig FSCK_ATTR((unused)))
1092 static void PRS(int argc, char *argv[])
1095 char *arg, *dev, *tmp = 0;
1098 int opts_for_fsck = 0;
1099 #ifdef HAVE_SIGNAL_H
1100 struct sigaction sa;
1103 * Set up signal action
1105 memset(&sa, 0, sizeof(struct sigaction));
1106 sa.sa_handler = signal_cancel;
1107 sigaction(SIGINT, &sa, 0);
1108 sigaction(SIGTERM, &sa, 0);
1117 for (i=1; i < argc; i++) {
1121 if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) {
1122 if (num_devices >= MAX_DEVICES) {
1123 fprintf(stderr, _("%s: too many devices\n"),
1127 dev = blkid_get_devname(cache, arg, NULL);
1128 if (!dev && strchr(arg, '=')) {
1130 * Check to see if we failed because
1131 * /proc/partitions isn't found.
1133 if (access("/proc/partitions", R_OK) < 0) {
1134 fprintf(stderr, "Couldn't open /proc/partitions: %s\n",
1136 fprintf(stderr, "Is /proc mounted?\n");
1140 * Check to see if this is because
1141 * we're not running as root
1145 "Must be root to scan for matching filesystems: %s\n", arg);
1148 "Couldn't find matching filesystem: %s\n", arg);
1151 devices[num_devices++] = dev ? dev : string_copy(arg);
1154 if (arg[0] != '-' || opts_for_fsck) {
1155 if (num_args >= MAX_ARGS) {
1156 fprintf(stderr, _("%s: too many arguments\n"),
1160 args[num_args++] = string_copy(arg);
1163 for (j=1; arg[j]; j++) {
1164 if (opts_for_fsck) {
1165 options[++opt] = arg[j];
1175 progress_fd = string_to_int(arg+j+1);
1176 if (progress_fd < 0)
1180 } else if ((i+1) < argc &&
1181 !strncmp(argv[i+1], "-", 1) == 0) {
1182 progress_fd = string_to_int(argv[i]);
1183 if (progress_fd < 0)
1218 else if ((i+1) < argc)
1222 fstype = string_copy(tmp);
1223 compile_fs_type(fstype, &fs_type_compiled);
1232 options[++opt] = arg[j];
1239 options[++opt] = '\0';
1240 if (num_args >= MAX_ARGS) {
1242 _("%s: too many arguments\n"),
1246 args[num_args++] = string_copy(options);
1250 if (getenv("FSCK_FORCE_ALL_PARALLEL"))
1251 force_all_parallel++;
1252 if ((tmp = getenv("FSCK_MAX_INST")))
1253 max_running = atoi(tmp);
1256 int main(int argc, char *argv[])
1259 int interactive = 0;
1260 char *oldpath = getenv("PATH");
1264 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
1265 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
1268 setlocale(LC_MESSAGES, "");
1269 setlocale(LC_CTYPE, "");
1270 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
1271 textdomain(NLS_CAT_NAME);
1273 blkid_get_cache(&cache, NULL);
1277 printf("fsck %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
1279 fstab = getenv("FSTAB_FILE");
1281 fstab = _PATH_MNTTAB;
1282 load_fs_info(fstab);
1284 /* Update our search path to include uncommon directories. */
1286 fsck_path = malloc (strlen (fsck_prefix_path) + 1 +
1287 strlen (oldpath) + 1);
1289 fprintf(stderr, "%s: Unable to allocate memory for fsck_path\n", progname);
1292 strcpy (fsck_path, fsck_prefix_path);
1293 strcat (fsck_path, ":");
1294 strcat (fsck_path, oldpath);
1296 fsck_path = string_copy(fsck_prefix_path);
1299 if ((num_devices == 1) || (serialize))
1302 /* If -A was specified ("check all"), do that! */
1306 if (num_devices == 0) {
1311 for (i = 0 ; i < num_devices; i++) {
1312 if (cancel_requested) {
1319 fs = lookup(devices[i]);
1321 fs = create_fs_device(devices[i], 0, "auto",
1326 if (ignore_mounted && is_mounted(fs->device))
1328 fsck_device(fs, interactive);
1330 (max_running && (num_running >= max_running))) {
1331 struct fsck_instance *inst;
1335 status |= inst->exit_status;
1336 free_instance(inst);
1339 printf("----------------------------------\n");
1342 status |= wait_many(FLAG_WAIT_ALL);
1344 blkid_put_cache(cache);