enable login utils
[framework/base/util-linux-ng.git] / fsck / fsck.c
1 /*
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
7  * parallel execution.
8  *
9  * Written by Theodore Ts'o, <tytso@mit.edu>
10  *
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.
18  *
19  * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
20  *               2001, 2002, 2003, 2004, 2005 by  Theodore Ts'o.
21  *
22  * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
23  *
24  * This file may be redistributed under the terms of the GNU Public
25  * License.
26  */
27
28 #define _XOPEN_SOURCE 600 /* for inclusion of sa_handler in Solaris */
29
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <sys/stat.h>
33 #include <sys/file.h>
34 #include <fcntl.h>
35 #include <limits.h>
36 #include <stdio.h>
37 #include <ctype.h>
38 #include <string.h>
39 #include <time.h>
40 #include <stdlib.h>
41 #include <paths.h>
42 #include <unistd.h>
43 #include <errno.h>
44 #include <signal.h>
45 #include <dirent.h>
46 #include <blkid.h>
47
48 #include "fsprobe.h"
49
50 #include "nls.h"
51 #include "pathnames.h"
52 #include "ismounted.h"
53 #include "c.h"
54 #include "fsck.h"
55
56 #define XALLOC_EXIT_CODE        EXIT_ERROR
57 #include "xalloc.h"
58
59 static const char *ignored_types[] = {
60         "ignore",
61         "iso9660",
62         "nfs",
63         "proc",
64         "sw",
65         "swap",
66         "tmpfs",
67         "devpts",
68         NULL
69 };
70
71 static const char *really_wanted[] = {
72         "minix",
73         "ext2",
74         "ext3",
75         "ext4",
76         "ext4dev",
77         "jfs",
78         "reiserfs",
79         "xiafs",
80         "xfs",
81         NULL
82 };
83
84 #define BASE_MD "/dev/md"
85
86 /*
87  * Global variables for options
88  */
89 char *devices[MAX_DEVICES];
90 char *args[MAX_ARGS];
91 int num_devices, num_args;
92
93 int lockdisk = 0;
94 int verbose = 0;
95 int doall = 0;
96 int noexecute = 0;
97 int serialize = 0;
98 int skip_root = 0;
99 int ignore_mounted = 0;
100 int notitle = 0;
101 int parallel_root = 0;
102 int progress = 0;
103 int progress_fd = 0;
104 int force_all_parallel = 0;
105 int num_running = 0;
106 int max_running = 0;
107 volatile int cancel_requested = 0;
108 int kill_sent = 0;
109 char *fstype = NULL;
110 struct fs_info *filesys_info = NULL, *filesys_last = NULL;
111 struct fsck_instance *instance_list;
112 const char fsck_prefix_path[] = FS_SEARCH_PATH;
113 char *fsck_path = 0;
114
115 static char *string_copy(const char *s)
116 {
117         char    *ret;
118
119         if (!s)
120                 return 0;
121         ret = xmalloc(strlen(s)+1);
122         strcpy(ret, s);
123         return ret;
124 }
125
126 static int string_to_int(const char *s)
127 {
128         long l;
129         char *p;
130
131         l = strtol(s, &p, 0);
132         if (*p || l == LONG_MIN || l == LONG_MAX || l < 0 || l > INT_MAX)
133                 return -1;
134         else
135                 return (int) l;
136 }
137
138 static int ignore(struct fs_info *);
139
140 static char *skip_over_blank(char *cp)
141 {
142         while (*cp && isspace(*cp))
143                 cp++;
144         return cp;
145 }
146
147 static char *skip_over_word(char *cp)
148 {
149         while (*cp && !isspace(*cp))
150                 cp++;
151         return cp;
152 }
153
154 static void strip_line(char *line)
155 {
156         char    *p;
157
158         while (*line) {
159                 p = line + strlen(line) - 1;
160                 if ((*p == '\n') || (*p == '\r'))
161                         *p = 0;
162                 else
163                         break;
164         }
165 }
166
167 static char *parse_word(char **buf)
168 {
169         char *word, *next;
170
171         word = *buf;
172         if (*word == 0)
173                 return 0;
174
175         word = skip_over_blank(word);
176         next = skip_over_word(word);
177         if (*next)
178                 *next++ = 0;
179         *buf = next;
180         return word;
181 }
182
183 static void parse_escape(char *word)
184 {
185         char    *p, *q;
186         int     ac, i;
187
188         if (!word)
189                 return;
190
191         for (p = word, q = word; *p; p++, q++) {
192                 *q = *p;
193                 if (*p != '\\')
194                         continue;
195                 if (*++p == 0)
196                         break;
197                 if (*p == 't') {
198                         *q = '\t';
199                         continue;
200                 }
201                 if (*p == 'n') {
202                         *q = '\n';
203                         continue;
204                 }
205                 if (!isdigit(*p)) {
206                         *q = *p;
207                         continue;
208                 }
209                 ac = 0;
210                 for (i = 0; i < 3; i++, p++) {
211                         if (!isdigit(*p))
212                                 break;
213                         ac = (ac * 8) + (*p - '0');
214                 }
215                 *q = ac;
216                 p--;
217         }
218         *q = 0;
219 }
220
221 static dev_t get_disk(const char *device)
222 {
223         struct stat st;
224         dev_t disk;
225
226         if (!stat(device, &st) &&
227             !blkid_devno_to_wholedisk(st.st_rdev, NULL, 0, &disk))
228                 return disk;
229
230         return 0;
231 }
232
233 static int is_irrotational_disk(dev_t disk)
234 {
235         char path[PATH_MAX];
236         FILE *f;
237         int rc, x;
238
239         rc = snprintf(path, sizeof(path),
240                         "/sys/dev/block/%d:%d/queue/rotational",
241                         major(disk), minor(disk));
242
243         if (rc < 0 || (unsigned int) (rc + 1) > sizeof(path))
244                 return 0;
245
246         f = fopen(path, "r");
247         if (!f)
248                 return 0;
249
250         rc = fscanf(f, "%d", &x);
251         if (rc != 1) {
252                 if (ferror(f))
253                         warn(_("failed to read: %s"), path);
254                 else
255                         warnx(_("parse error: %s"), path);
256         }
257         fclose(f);
258
259         return rc == 1 ? !x : 0;
260 }
261
262 static void lock_disk(struct fsck_instance *inst)
263 {
264         dev_t disk = inst->fs->disk ? inst->fs->disk : get_disk(inst->fs->device);
265         char *diskname;
266
267         if (!disk || is_irrotational_disk(disk))
268                 return;
269
270         diskname = blkid_devno_to_devname(disk);
271         if (!diskname)
272                 return;
273
274         if (verbose)
275                 printf(_("Locking disk %s ... "), diskname);
276
277         inst->lock = open(diskname, O_CLOEXEC | O_RDONLY);
278         if (inst->lock >= 0) {
279                 int rc = -1;
280
281                 /* inform users that we're waiting on the lock */
282                 if (verbose &&
283                     (rc = flock(inst->lock, LOCK_EX | LOCK_NB)) != 0 &&
284                     errno == EWOULDBLOCK)
285                         printf(_("(waiting) "));
286
287                 if (rc != 0 && flock(inst->lock, LOCK_EX) != 0) {
288                         close(inst->lock);                      /* failed */
289                         inst->lock = -1;
290                 }
291         }
292
293         if (verbose)
294                 /* TRANSLATORS: These are followups to "Locking disk...". */
295                 printf("%s.\n", inst->lock >= 0 ? _("succeeded") : _("failed"));
296
297         free(diskname);
298         return;
299 }
300
301 static void unlock_disk(struct fsck_instance *inst)
302 {
303         if (inst->lock >= 0) {
304                 /* explicitly unlock, don't rely on close(), maybe some library
305                  * (e.g. liblkid) has still open the device.
306                  */
307                 flock(inst->lock, LOCK_UN);
308                 close(inst->lock);
309         }
310 }
311
312
313
314 static void free_instance(struct fsck_instance *i)
315 {
316         if (lockdisk)
317                 unlock_disk(i);
318         free(i->prog);
319         free(i);
320         return;
321 }
322
323 static struct fs_info *create_fs_device(const char *device, const char *mntpnt,
324                                         const char *type, const char *opts,
325                                         int freq, int passno)
326 {
327         struct fs_info *fs;
328
329         fs = xmalloc(sizeof(struct fs_info));
330
331         fs->device = string_copy(device);
332         fs->mountpt = string_copy(mntpnt);
333         fs->type = string_copy(type);
334         fs->opts = string_copy(opts ? opts : "");
335         fs->freq = freq;
336         fs->passno = passno;
337         fs->flags = 0;
338         fs->next = NULL;
339         fs->disk = 0;
340         fs->stacked = 0;
341
342         if (!filesys_info)
343                 filesys_info = fs;
344         else
345                 filesys_last->next = fs;
346         filesys_last = fs;
347
348         return fs;
349 }
350
351
352
353 static int parse_fstab_line(char *line, struct fs_info **ret_fs)
354 {
355         char    *dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp;
356         struct fs_info *fs;
357
358         *ret_fs = 0;
359         strip_line(line);
360         cp = line;
361
362         device = parse_word(&cp);
363         if (!device || *device == '#')
364                 return 0;       /* Ignore blank lines and comments */
365         mntpnt = parse_word(&cp);
366         type = parse_word(&cp);
367         opts = parse_word(&cp);
368         freq = parse_word(&cp);
369         passno = parse_word(&cp);
370
371         if (!mntpnt || !type)
372                 return -1;
373
374         parse_escape(device);
375         parse_escape(mntpnt);
376         parse_escape(type);
377         parse_escape(opts);
378         parse_escape(freq);
379         parse_escape(passno);
380
381         dev = fsprobe_get_devname_by_spec(device);
382         if (dev)
383                 device = dev;
384
385         if (strchr(type, ','))
386                 type = 0;
387
388         fs = create_fs_device(device, mntpnt, type ? type : "auto", opts,
389                               freq ? atoi(freq) : -1,
390                               passno ? atoi(passno) : -1);
391         free(dev);
392
393         if (!fs)
394                 return -1;
395         *ret_fs = fs;
396         return 0;
397 }
398
399 static void interpret_type(struct fs_info *fs)
400 {
401         char    *t;
402
403         if (strcmp(fs->type, "auto") != 0)
404                 return;
405         t = fsprobe_get_fstype_by_devname(fs->device);
406         if (t) {
407                 free(fs->type);
408                 fs->type = t;
409         }
410 }
411
412 /*
413  * Load the filesystem database from /etc/fstab
414  */
415 static void load_fs_info(const char *filename)
416 {
417         FILE    *f;
418         char    buf[1024];
419         int     lineno = 0;
420         int     old_fstab = 1;
421         struct fs_info *fs;
422
423         if ((f = fopen(filename, "r")) == NULL) {
424                 warn(_("WARNING: couldn't open %s"), filename);
425                 return;
426         }
427         while (!feof(f)) {
428                 lineno++;
429                 if (!fgets(buf, sizeof(buf), f))
430                         break;
431                 buf[sizeof(buf)-1] = 0;
432                 if (parse_fstab_line(buf, &fs) < 0) {
433                         warnx(_("WARNING: bad format "
434                                 "on line %d of %s"), lineno, filename);
435                         continue;
436                 }
437                 if (!fs)
438                         continue;
439                 if (fs->passno < 0)
440                         fs->passno = 0;
441                 else
442                         old_fstab = 0;
443         }
444
445         fclose(f);
446
447         if (old_fstab && filesys_info) {
448                 warnx(_(
449                 "WARNING: Your /etc/fstab does not contain the fsck passno\n"
450                 "       field.  I will kludge around things for you, but you\n"
451                 "       should fix your /etc/fstab file as soon as you can.\n"));
452
453                 for (fs = filesys_info; fs; fs = fs->next) {
454                         fs->passno = 1;
455                 }
456         }
457 }
458
459 /* Lookup filesys in /etc/fstab and return the corresponding entry. */
460 static struct fs_info *lookup(char *filesys)
461 {
462         struct fs_info *fs;
463
464         /* No filesys name given. */
465         if (filesys == NULL)
466                 return NULL;
467
468         for (fs = filesys_info; fs; fs = fs->next) {
469                 if (!strcmp(filesys, fs->device) ||
470                     (fs->mountpt && !strcmp(filesys, fs->mountpt)))
471                         break;
472         }
473
474         return fs;
475 }
476
477 /* Find fsck program for a given fs type. */
478 static char *find_fsck(char *type)
479 {
480   char *s;
481   const char *tpl;
482   static char prog[256];
483   char *p = string_copy(fsck_path);
484   struct stat st;
485
486   /* Are we looking for a program or just a type? */
487   tpl = (strncmp(type, "fsck.", 5) ? "%s/fsck.%s" : "%s/%s");
488
489   for(s = strtok(p, ":"); s; s = strtok(NULL, ":")) {
490         sprintf(prog, tpl, s, type);
491         if (stat(prog, &st) == 0) break;
492   }
493   free(p);
494   return(s ? prog : NULL);
495 }
496
497 static int progress_active(NOARGS)
498 {
499         struct fsck_instance *inst;
500
501         for (inst = instance_list; inst; inst = inst->next) {
502                 if (inst->flags & FLAG_DONE)
503                         continue;
504                 if (inst->flags & FLAG_PROGRESS)
505                         return 1;
506         }
507         return 0;
508 }
509
510 /*
511  * Execute a particular fsck program, and link it into the list of
512  * child processes we are waiting for.
513  */
514 static int execute(const char *type, struct fs_info *fs, int interactive)
515 {
516         char *s, *argv[80], prog[80];
517         int  argc, i;
518         struct fsck_instance *inst, *p;
519         pid_t   pid;
520
521         inst = xmalloc(sizeof(struct fsck_instance));
522         memset(inst, 0, sizeof(struct fsck_instance));
523
524         sprintf(prog, "fsck.%s", type);
525         argv[0] = string_copy(prog);
526         argc = 1;
527
528         for (i=0; i <num_args; i++)
529                 argv[argc++] = string_copy(args[i]);
530
531         if (progress) {
532                 if ((strcmp(type, "ext2") == 0) ||
533                     (strcmp(type, "ext3") == 0) ||
534                     (strcmp(type, "ext4") == 0) ||
535                     (strcmp(type, "ext4dev") == 0)) {
536                         char tmp[80];
537
538                         tmp[0] = 0;
539                         if (!progress_active()) {
540                                 snprintf(tmp, 80, "-C%d", progress_fd);
541                                 inst->flags |= FLAG_PROGRESS;
542                         } else if (progress_fd)
543                                 snprintf(tmp, 80, "-C%d", progress_fd * -1);
544                         if (tmp[0])
545                                 argv[argc++] = string_copy(tmp);
546                 }
547         }
548
549         argv[argc++] = string_copy(fs->device);
550         argv[argc] = 0;
551
552         s = find_fsck(prog);
553         if (s == NULL) {
554                 warnx(_("%s: not found"), prog);
555                 free(inst);
556                 return ENOENT;
557         }
558
559         if (verbose || noexecute) {
560                 printf("[%s (%d) -- %s] ", s, num_running,
561                        fs->mountpt ? fs->mountpt : fs->device);
562                 for (i=0; i < argc; i++)
563                         printf("%s ", argv[i]);
564                 printf("\n");
565         }
566
567
568         inst->fs = fs;
569         inst->lock = -1;
570
571         if (lockdisk)
572                 lock_disk(inst);
573
574         /* Fork and execute the correct program. */
575         if (noexecute)
576                 pid = -1;
577         else if ((pid = fork()) < 0) {
578                 perror("fork");
579                 free(inst);
580                 return errno;
581         } else if (pid == 0) {
582                 if (!interactive)
583                         close(0);
584                 (void) execv(s, argv);
585                 perror(argv[0]);
586                 free(inst);
587                 exit(EXIT_ERROR);
588         }
589
590         for (i=0; i < argc; i++)
591                 free(argv[i]);
592
593         inst->pid = pid;
594         inst->prog = string_copy(prog);
595         inst->type = string_copy(type);
596         inst->start_time = time(0);
597         inst->next = NULL;
598
599         /*
600          * Find the end of the list, so we add the instance on at the end.
601          */
602         for (p = instance_list; p && p->next; p = p->next);
603
604         if (p)
605                 p->next = inst;
606         else
607                 instance_list = inst;
608
609         return 0;
610 }
611
612 /*
613  * Send a signal to all outstanding fsck child processes
614  */
615 static int kill_all(int signum)
616 {
617         struct fsck_instance *inst;
618         int     n = 0;
619
620         for (inst = instance_list; inst; inst = inst->next) {
621                 if (inst->flags & FLAG_DONE)
622                         continue;
623                 kill(inst->pid, signum);
624                 n++;
625         }
626         return n;
627 }
628
629 /*
630  * Wait for one child process to exit; when it does, unlink it from
631  * the list of executing child processes, and return it.
632  */
633 static struct fsck_instance *wait_one(int flags)
634 {
635         int     status;
636         int     sig;
637         struct fsck_instance *inst, *inst2, *prev;
638         pid_t   pid;
639
640         if (!instance_list)
641                 return NULL;
642
643         if (noexecute) {
644                 inst = instance_list;
645                 prev = 0;
646 #ifdef RANDOM_DEBUG
647                 while (inst->next && (random() & 1)) {
648                         prev = inst;
649                         inst = inst->next;
650                 }
651 #endif
652                 inst->exit_status = 0;
653                 goto ret_inst;
654         }
655
656         /*
657          * gcc -Wall fails saving throw against stupidity
658          * (inst and prev are thought to be uninitialized variables)
659          */
660         inst = prev = NULL;
661
662         do {
663                 pid = waitpid(-1, &status, flags);
664                 if (cancel_requested && !kill_sent) {
665                         kill_all(SIGTERM);
666                         kill_sent++;
667                 }
668                 if ((pid == 0) && (flags & WNOHANG))
669                         return NULL;
670                 if (pid < 0) {
671                         if ((errno == EINTR) || (errno == EAGAIN))
672                                 continue;
673                         if (errno == ECHILD) {
674                                 warnx(_("wait: no more child process?!?"));
675                                 return NULL;
676                         }
677                         perror("wait");
678                         continue;
679                 }
680                 for (prev = 0, inst = instance_list;
681                      inst;
682                      prev = inst, inst = inst->next) {
683                         if (inst->pid == pid)
684                                 break;
685                 }
686         } while (!inst);
687
688         if (WIFEXITED(status))
689                 status = WEXITSTATUS(status);
690         else if (WIFSIGNALED(status)) {
691                 sig = WTERMSIG(status);
692                 if (sig == SIGINT) {
693                         status = EXIT_UNCORRECTED;
694                 } else {
695                         warnx(_("Warning... %s for device %s exited "
696                                "with signal %d."),
697                                inst->prog, inst->fs->device, sig);
698                         status = EXIT_ERROR;
699                 }
700         } else {
701                 warnx(_("%s %s: status is %x, should never happen."),
702                        inst->prog, inst->fs->device, status);
703                 status = EXIT_ERROR;
704         }
705         inst->exit_status = status;
706         inst->flags |= FLAG_DONE;
707         if (progress && (inst->flags & FLAG_PROGRESS) &&
708             !progress_active()) {
709                 for (inst2 = instance_list; inst2; inst2 = inst2->next) {
710                         if (inst2->flags & FLAG_DONE)
711                                 continue;
712                         if (strcmp(inst2->type, "ext2") &&
713                             strcmp(inst2->type, "ext3") &&
714                             strcmp(inst2->type, "ext4") &&
715                             strcmp(inst2->type, "ext4dev"))
716                                 continue;
717                         /*
718                          * If we've just started the fsck, wait a tiny
719                          * bit before sending the kill, to give it
720                          * time to set up the signal handler
721                          */
722                         if (inst2->start_time < time(0)+2) {
723                                 if (fork() == 0) {
724                                         sleep(1);
725                                         kill(inst2->pid, SIGUSR1);
726                                         exit(EXIT_OK);
727                                 }
728                         } else
729                                 kill(inst2->pid, SIGUSR1);
730                         inst2->flags |= FLAG_PROGRESS;
731                         break;
732                 }
733         }
734 ret_inst:
735         if (prev)
736                 prev->next = inst->next;
737         else
738                 instance_list = inst->next;
739         if (verbose > 1)
740                 printf(_("Finished with %s (exit status %d)\n"),
741                        inst->fs->device, inst->exit_status);
742         num_running--;
743         return inst;
744 }
745
746 #define FLAG_WAIT_ALL           0
747 #define FLAG_WAIT_ATLEAST_ONE   1
748 /*
749  * Wait until all executing child processes have exited; return the
750  * logical OR of all of their exit code values.
751  */
752 static int wait_many(int flags)
753 {
754         struct fsck_instance *inst;
755         int     global_status = 0;
756         int     wait_flags = 0;
757
758         while ((inst = wait_one(wait_flags))) {
759                 global_status |= inst->exit_status;
760                 free_instance(inst);
761 #ifdef RANDOM_DEBUG
762                 if (noexecute && (flags & WNOHANG) && !(random() % 3))
763                         break;
764 #endif
765                 if (flags & FLAG_WAIT_ATLEAST_ONE)
766                         wait_flags = WNOHANG;
767         }
768         return global_status;
769 }
770
771 /*
772  * Run the fsck program on a particular device
773  *
774  * If the type is specified using -t, and it isn't prefixed with "no"
775  * (as in "noext2") and only one filesystem type is specified, then
776  * use that type regardless of what is specified in /etc/fstab.
777  *
778  * If the type isn't specified by the user, then use either the type
779  * specified in /etc/fstab, or DEFAULT_FSTYPE.
780  */
781 static int fsck_device(struct fs_info *fs, int interactive)
782 {
783         const char *type;
784         int retval;
785
786         interpret_type(fs);
787
788         if (strcmp(fs->type, "auto") != 0)
789                 type = fs->type;
790         else if (fstype && strncmp(fstype, "no", 2) &&
791             strncmp(fstype, "opts=", 5) && strncmp(fstype, "loop", 4) &&
792             !strchr(fstype, ','))
793                 type = fstype;
794         else
795                 type = DEFAULT_FSTYPE;
796
797         num_running++;
798         retval = execute(type, fs, interactive);
799         if (retval) {
800                 warnx(_("error %d while executing fsck.%s for %s"),
801                         retval, type, fs->device);
802                 num_running--;
803                 return EXIT_ERROR;
804         }
805         return 0;
806 }
807
808
809 /*
810  * Deal with the fsck -t argument.
811  */
812 struct fs_type_compile {
813         char **list;
814         int *type;
815         int  negate;
816 } fs_type_compiled;
817
818 #define FS_TYPE_NORMAL  0
819 #define FS_TYPE_OPT     1
820 #define FS_TYPE_NEGOPT  2
821
822 static void compile_fs_type(char *fs_type, struct fs_type_compile *cmp)
823 {
824         char    *cp, *list, *s;
825         int     num = 2;
826         int     negate, first_negate = 1;
827
828         if (fs_type) {
829                 for (cp=fs_type; *cp; cp++) {
830                         if (*cp == ',')
831                                 num++;
832                 }
833         }
834
835         cmp->list = xmalloc(num * sizeof(char *));
836         cmp->type = xmalloc(num * sizeof(int));
837         memset(cmp->list, 0, num * sizeof(char *));
838         memset(cmp->type, 0, num * sizeof(int));
839         cmp->negate = 0;
840
841         if (!fs_type)
842                 return;
843
844         list = string_copy(fs_type);
845         num = 0;
846         s = strtok(list, ",");
847         while(s) {
848                 negate = 0;
849                 if (strncmp(s, "no", 2) == 0) {
850                         s += 2;
851                         negate = 1;
852                 } else if (*s == '!') {
853                         s++;
854                         negate = 1;
855                 }
856                 if (strcmp(s, "loop") == 0)
857                         /* loop is really short-hand for opts=loop */
858                         goto loop_special_case;
859                 else if (strncmp(s, "opts=", 5) == 0) {
860                         s += 5;
861                 loop_special_case:
862                         cmp->type[num] = negate ? FS_TYPE_NEGOPT : FS_TYPE_OPT;
863                 } else {
864                         if (first_negate) {
865                                 cmp->negate = negate;
866                                 first_negate = 0;
867                         }
868                         if ((negate && !cmp->negate) ||
869                             (!negate && cmp->negate)) {
870                                 errx(EXIT_USAGE,
871                                         _("Either all or none of the filesystem types passed to -t must be prefixed\n"
872                                           "with 'no' or '!'."));
873                         }
874                 }
875 #if 0
876                 printf("Adding %s to list (type %d).\n", s, cmp->type[num]);
877 #endif
878                 cmp->list[num++] = string_copy(s);
879                 s = strtok(NULL, ",");
880         }
881         free(list);
882 }
883
884 /*
885  * This function returns true if a particular option appears in a
886  * comma-delimited options list
887  */
888 static int opt_in_list(const char *opt, char *optlist)
889 {
890         char    *list, *s;
891
892         if (!optlist)
893                 return 0;
894         list = string_copy(optlist);
895
896         s = strtok(list, ",");
897         while(s) {
898                 if (strcmp(s, opt) == 0) {
899                         free(list);
900                         return 1;
901                 }
902                 s = strtok(NULL, ",");
903         }
904         free(list);
905         return 0;
906 }
907
908 /* See if the filesystem matches the criteria given by the -t option */
909 static int fs_match(struct fs_info *fs, struct fs_type_compile *cmp)
910 {
911         int n, ret = 0, checked_type = 0;
912         char *cp;
913
914         if (cmp->list == 0 || cmp->list[0] == 0)
915                 return 1;
916
917         for (n=0; (cp = cmp->list[n]); n++) {
918                 switch (cmp->type[n]) {
919                 case FS_TYPE_NORMAL:
920                         checked_type++;
921                         if (strcmp(cp, fs->type) == 0) {
922                                 ret = 1;
923                         }
924                         break;
925                 case FS_TYPE_NEGOPT:
926                         if (opt_in_list(cp, fs->opts))
927                                 return 0;
928                         break;
929                 case FS_TYPE_OPT:
930                         if (!opt_in_list(cp, fs->opts))
931                                 return 0;
932                         break;
933                 }
934         }
935         if (checked_type == 0)
936                 return 1;
937         return (cmp->negate ? !ret : ret);
938 }
939
940 /*
941  * Check if a device exists
942  */
943 static int device_exists(const char *device)
944 {
945         struct stat st;
946
947         if (stat(device, &st) == -1)
948                 return 0;
949
950         if (!S_ISBLK(st.st_mode))
951                 return 0;
952
953         return 1;
954 }
955
956 /* Check if we should ignore this filesystem. */
957 static int ignore(struct fs_info *fs)
958 {
959         const char **ip;
960         int wanted = 0;
961
962         /*
963          * If the pass number is 0, ignore it.
964          */
965         if (fs->passno == 0)
966                 return 1;
967
968         /*
969          * If this is a bind mount, ignore it.
970          */
971         if (opt_in_list("bind", fs->opts)) {
972                 warnx(_("%s: skipping bad line in /etc/fstab: "
973                         "bind mount with nonzero fsck pass number"),
974                         fs->mountpt);
975                 return 1;
976         }
977
978         /*
979          * ignore devices that don't exist and have the "nofail" mount option
980          */
981         if (!device_exists(fs->device)) {
982                 if (opt_in_list("nofail", fs->opts)) {
983                         if (verbose)
984                                 printf(_("%s: skipping nonexistent device\n"),
985                                                                 fs->device);
986                         return 1;
987                 }
988                 if (verbose)
989                         printf(_("%s: nonexistent device (\"nofail\" fstab "
990                                  "option may be used to skip this device)\n"),
991                                  fs->device);
992         }
993
994         interpret_type(fs);
995
996         /*
997          * If a specific fstype is specified, and it doesn't match,
998          * ignore it.
999          */
1000         if (!fs_match(fs, &fs_type_compiled)) return 1;
1001
1002         /* Are we ignoring this type? */
1003         for(ip = ignored_types; *ip; ip++)
1004                 if (strcmp(fs->type, *ip) == 0) return 1;
1005
1006         /* Do we really really want to check this fs? */
1007         for(ip = really_wanted; *ip; ip++)
1008                 if (strcmp(fs->type, *ip) == 0) {
1009                         wanted = 1;
1010                         break;
1011                 }
1012
1013         /* See if the <fsck.fs> program is available. */
1014         if (find_fsck(fs->type) == NULL) {
1015                 if (wanted)
1016                         warnx(_("cannot check %s: fsck.%s not found"),
1017                                 fs->device, fs->type);
1018                 return 1;
1019         }
1020
1021         /* We can and want to check this file system type. */
1022         return 0;
1023 }
1024
1025 static int count_slaves(dev_t disk)
1026 {
1027         DIR *dir;
1028         struct dirent *dp;
1029         char dirname[PATH_MAX];
1030         int count = 0;
1031
1032         snprintf(dirname, sizeof(dirname),
1033                         "/sys/dev/block/%u:%u/slaves/",
1034                         major(disk), minor(disk));
1035
1036         if (!(dir = opendir(dirname)))
1037                 return -1;
1038
1039         while ((dp = readdir(dir)) != 0) {
1040 #ifdef _DIRENT_HAVE_D_TYPE
1041                 if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
1042                         continue;
1043 #endif
1044                 if (dp->d_name[0] == '.' &&
1045                     ((dp->d_name[1] == 0) ||
1046                      ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
1047                         continue;
1048
1049                 count++;
1050         }
1051         closedir(dir);
1052         return count;
1053 }
1054
1055 /*
1056  * Returns TRUE if a partition on the same disk is already being
1057  * checked.
1058  */
1059 static int disk_already_active(struct fs_info *fs)
1060 {
1061         struct fsck_instance *inst;
1062
1063         if (force_all_parallel)
1064                 return 0;
1065
1066         if (instance_list && instance_list->fs->stacked)
1067                 /* any instance for a stacked device is already running */
1068                 return 1;
1069
1070         if (!fs->disk) {
1071                 fs->disk = get_disk(fs->device);
1072                 if (fs->disk)
1073                         fs->stacked = count_slaves(fs->disk);
1074         }
1075
1076         /*
1077          * If we don't know the base device, assume that the device is
1078          * already active if there are any fsck instances running.
1079          *
1080          * Don't check a stacked device with any other disk too.
1081          */
1082         if (!fs->disk || fs->stacked)
1083                 return (instance_list != 0);
1084
1085         for (inst = instance_list; inst; inst = inst->next) {
1086                 if (!inst->fs->disk || fs->disk == inst->fs->disk)
1087                         return 1;
1088         }
1089         return 0;
1090 }
1091
1092 /* Check all file systems, using the /etc/fstab table. */
1093 static int check_all(NOARGS)
1094 {
1095         struct fs_info *fs = NULL;
1096         int status = EXIT_OK;
1097         int not_done_yet = 1;
1098         int passno = 1;
1099         int pass_done;
1100
1101         if (verbose)
1102                 fputs(_("Checking all file systems.\n"), stdout);
1103
1104         /*
1105          * Do an initial scan over the filesystem; mark filesystems
1106          * which should be ignored as done, and resolve any "auto"
1107          * filesystem types (done as a side-effect of calling ignore()).
1108          */
1109         for (fs = filesys_info; fs; fs = fs->next) {
1110                 if (ignore(fs))
1111                         fs->flags |= FLAG_DONE;
1112         }
1113
1114         /*
1115          * Find and check the root filesystem.
1116          */
1117         if (!parallel_root) {
1118                 for (fs = filesys_info; fs; fs = fs->next) {
1119                         if (!strcmp(fs->mountpt, "/"))
1120                                 break;
1121                 }
1122                 if (fs) {
1123                         if (!skip_root && !ignore(fs) &&
1124                             !(ignore_mounted && is_mounted(fs->device))) {
1125                                 status |= fsck_device(fs, 1);
1126                                 status |= wait_many(FLAG_WAIT_ALL);
1127                                 if (status > EXIT_NONDESTRUCT)
1128                                         return status;
1129                         }
1130                         fs->flags |= FLAG_DONE;
1131                 }
1132         }
1133         /*
1134          * This is for the bone-headed user who enters the root
1135          * filesystem twice.  Skip root will skep all root entries.
1136          */
1137         if (skip_root)
1138                 for (fs = filesys_info; fs; fs = fs->next)
1139                         if (!strcmp(fs->mountpt, "/"))
1140                                 fs->flags |= FLAG_DONE;
1141
1142         while (not_done_yet) {
1143                 not_done_yet = 0;
1144                 pass_done = 1;
1145
1146                 for (fs = filesys_info; fs; fs = fs->next) {
1147                         if (cancel_requested)
1148                                 break;
1149                         if (fs->flags & FLAG_DONE)
1150                                 continue;
1151                         /*
1152                          * If the filesystem's pass number is higher
1153                          * than the current pass number, then we don't
1154                          * do it yet.
1155                          */
1156                         if (fs->passno > passno) {
1157                                 not_done_yet++;
1158                                 continue;
1159                         }
1160                         if (ignore_mounted && is_mounted(fs->device)) {
1161                                 fs->flags |= FLAG_DONE;
1162                                 continue;
1163                         }
1164                         /*
1165                          * If a filesystem on a particular device has
1166                          * already been spawned, then we need to defer
1167                          * this to another pass.
1168                          */
1169                         if (disk_already_active(fs)) {
1170                                 pass_done = 0;
1171                                 continue;
1172                         }
1173                         /*
1174                          * Spawn off the fsck process
1175                          */
1176                         status |= fsck_device(fs, serialize);
1177                         fs->flags |= FLAG_DONE;
1178
1179                         /*
1180                          * Only do one filesystem at a time, or if we
1181                          * have a limit on the number of fsck's extant
1182                          * at one time, apply that limit.
1183                          */
1184                         if (serialize ||
1185                             (max_running && (num_running >= max_running))) {
1186                                 pass_done = 0;
1187                                 break;
1188                         }
1189                 }
1190                 if (cancel_requested)
1191                         break;
1192                 if (verbose > 1)
1193                         printf(_("--waiting-- (pass %d)\n"), passno);
1194                 status |= wait_many(pass_done ? FLAG_WAIT_ALL :
1195                                     FLAG_WAIT_ATLEAST_ONE);
1196                 if (pass_done) {
1197                         if (verbose > 1)
1198                                 printf("----------------------------------\n");
1199                         passno++;
1200                 } else
1201                         not_done_yet++;
1202         }
1203         if (cancel_requested && !kill_sent) {
1204                 kill_all(SIGTERM);
1205                 kill_sent++;
1206         }
1207         status |= wait_many(FLAG_WAIT_ATLEAST_ONE);
1208         return status;
1209 }
1210
1211 static void __attribute__((__noreturn__)) usage(void)
1212 {
1213         printf(_("\nUsage:\n"
1214                  " %s [fsck-options] [fs-options] [filesys ...]\n"),
1215                 program_invocation_short_name);
1216
1217         puts(_( "\nOptions:\n"
1218                 " -A         check all filesystems\n"
1219                 " -R         skip root filesystem; useful only with `-A'\n"
1220                 " -M         do not check mounted filesystems\n"
1221                 " -t <type>  specify filesystem types to be checked;\n"
1222                 "              type is allowed to be comma-separated list\n"
1223                 " -P         check filesystems in parallel, including root\n"
1224                 " -s         serialize fsck operations\n"
1225                 " -l         lock the device using flock()\n"
1226                 " -N         do not execute, just show what would be done\n"
1227                 " -T         do not show the title on startup\n"
1228                 " -C <fd>    display progress bar; file descriptor is for GUIs\n"
1229                 " -V         explain what is being done\n"
1230                 " -?         display this help and exit\n\n"
1231                 "See fsck.* commands for fs-options."));
1232
1233         exit(EXIT_USAGE);
1234 }
1235
1236 static void signal_cancel(int sig FSCK_ATTR((unused)))
1237 {
1238         cancel_requested++;
1239 }
1240
1241 static void PRS(int argc, char *argv[])
1242 {
1243         int     i, j;
1244         char    *arg, *dev, *tmp = 0;
1245         char    options[128];
1246         int     opt = 0;
1247         int     opts_for_fsck = 0;
1248         struct sigaction        sa;
1249
1250         /*
1251          * Set up signal action
1252          */
1253         memset(&sa, 0, sizeof(struct sigaction));
1254         sa.sa_handler = signal_cancel;
1255         sigaction(SIGINT, &sa, 0);
1256         sigaction(SIGTERM, &sa, 0);
1257
1258         num_devices = 0;
1259         num_args = 0;
1260         instance_list = 0;
1261
1262         for (i=1; i < argc; i++) {
1263                 arg = argv[i];
1264                 if (!arg)
1265                         continue;
1266                 if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) {
1267                         if (num_devices >= MAX_DEVICES)
1268                                 errx(EXIT_ERROR, _("too many devices"));
1269                         dev = fsprobe_get_devname_by_spec(arg);
1270                         if (!dev && strchr(arg, '=')) {
1271                                 /*
1272                                  * Check to see if we failed because
1273                                  * /proc/partitions isn't found.
1274                                  */
1275                                 if (access(_PATH_PROC_PARTITIONS, R_OK) < 0) {
1276                                         warn(_("couldn't open %s"),
1277                                                 _PATH_PROC_PARTITIONS);
1278                                         errx(EXIT_ERROR, _("Is /proc mounted?"));
1279                                 }
1280                                 /*
1281                                  * Check to see if this is because
1282                                  * we're not running as root
1283                                  */
1284                                 if (geteuid())
1285                                         errx(EXIT_ERROR,
1286                                                 _("must be root to scan for matching filesystems: %s"),
1287                                                 arg);
1288                                 else
1289                                         errx(EXIT_ERROR,
1290                                                 _("couldn't find matching filesystem: %s"),
1291                                                 arg);
1292                         }
1293                         devices[num_devices++] = dev ? dev : string_copy(arg);
1294                         continue;
1295                 }
1296                 if (arg[0] != '-' || opts_for_fsck) {
1297                         if (num_args >= MAX_ARGS)
1298                                 errx(EXIT_ERROR, _("too many arguments"));
1299                         args[num_args++] = string_copy(arg);
1300                         continue;
1301                 }
1302                 for (j=1; arg[j]; j++) {
1303                         if (opts_for_fsck) {
1304                                 options[++opt] = arg[j];
1305                                 continue;
1306                         }
1307                         switch (arg[j]) {
1308                         case 'A':
1309                                 doall = 1;
1310                                 break;
1311                         case 'C':
1312                                 progress = 1;
1313                                 if (arg[j+1]) {
1314                                         progress_fd = string_to_int(arg+j+1);
1315                                         if (progress_fd < 0)
1316                                                 progress_fd = 0;
1317                                         else
1318                                                 goto next_arg;
1319                                 } else if ((i+1) < argc &&
1320                                            !strncmp(argv[i+1], "-", 1) == 0) {
1321                                         progress_fd = string_to_int(argv[i]);
1322                                         if (progress_fd < 0)
1323                                                 progress_fd = 0;
1324                                         else {
1325                                                 ++i;
1326                                                 goto next_arg;
1327                                         }
1328                                 }
1329                                 break;
1330                         case 'l':
1331                                 lockdisk = 1;
1332                                 break;
1333                         case 'V':
1334                                 verbose++;
1335                                 break;
1336                         case 'N':
1337                                 noexecute = 1;
1338                                 break;
1339                         case 'R':
1340                                 skip_root = 1;
1341                                 break;
1342                         case 'T':
1343                                 notitle = 1;
1344                                 break;
1345                         case 'M':
1346                                 ignore_mounted = 1;
1347                                 break;
1348                         case 'P':
1349                                 parallel_root = 1;
1350                                 break;
1351                         case 's':
1352                                 serialize = 1;
1353                                 break;
1354                         case 't':
1355                                 tmp = 0;
1356                                 if (fstype)
1357                                         usage();
1358                                 if (arg[j+1])
1359                                         tmp = arg+j+1;
1360                                 else if ((i+1) < argc)
1361                                         tmp = argv[++i];
1362                                 else
1363                                         usage();
1364                                 fstype = string_copy(tmp);
1365                                 compile_fs_type(fstype, &fs_type_compiled);
1366                                 goto next_arg;
1367                         case '-':
1368                                 opts_for_fsck++;
1369                                 break;
1370                         case '?':
1371                                 usage();
1372                                 break;
1373                         default:
1374                                 options[++opt] = arg[j];
1375                                 break;
1376                         }
1377                 }
1378         next_arg:
1379                 if (opt) {
1380                         options[0] = '-';
1381                         options[++opt] = '\0';
1382                         if (num_args >= MAX_ARGS)
1383                                 errx(EXIT_ERROR, _("too many arguments"));
1384                         args[num_args++] = string_copy(options);
1385                         opt = 0;
1386                 }
1387         }
1388         if (getenv("FSCK_FORCE_ALL_PARALLEL"))
1389                 force_all_parallel++;
1390         if ((tmp = getenv("FSCK_MAX_INST")))
1391             max_running = atoi(tmp);
1392 }
1393
1394 int main(int argc, char *argv[])
1395 {
1396         int i, status = 0;
1397         int interactive = 0;
1398         char *oldpath = getenv("PATH");
1399         const char *fstab;
1400         struct fs_info *fs;
1401
1402         setvbuf(stdout, NULL, _IONBF, BUFSIZ);
1403         setvbuf(stderr, NULL, _IONBF, BUFSIZ);
1404
1405         setlocale(LC_MESSAGES, "");
1406         setlocale(LC_CTYPE, "");
1407         bindtextdomain(PACKAGE, LOCALEDIR);
1408         textdomain(PACKAGE);
1409
1410         fsprobe_init();
1411         PRS(argc, argv);
1412
1413         if (!notitle)
1414                 printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING);
1415
1416         fstab = getenv("FSTAB_FILE");
1417         if (!fstab)
1418                 fstab = _PATH_MNTTAB;
1419         load_fs_info(fstab);
1420
1421         /* Update our search path to include uncommon directories. */
1422         if (oldpath) {
1423                 fsck_path = xmalloc (strlen (fsck_prefix_path) + 1 +
1424                                     strlen (oldpath) + 1);
1425                 strcpy (fsck_path, fsck_prefix_path);
1426                 strcat (fsck_path, ":");
1427                 strcat (fsck_path, oldpath);
1428         } else {
1429                 fsck_path = string_copy(fsck_prefix_path);
1430         }
1431
1432         if ((num_devices == 1) || (serialize))
1433                 interactive = 1;
1434
1435         if (lockdisk && (doall || num_devices > 1)) {
1436                 warnx(_("the -l option can be used with one "
1437                                   "device only -- ignore"));
1438                 lockdisk = 0;
1439         }
1440
1441         /* If -A was specified ("check all"), do that! */
1442         if (doall)
1443                 return check_all();
1444
1445         if (num_devices == 0) {
1446                 serialize++;
1447                 interactive++;
1448                 return check_all();
1449         }
1450         for (i = 0 ; i < num_devices; i++) {
1451                 if (cancel_requested) {
1452                         if (!kill_sent) {
1453                                 kill_all(SIGTERM);
1454                                 kill_sent++;
1455                         }
1456                         break;
1457                 }
1458                 fs = lookup(devices[i]);
1459                 if (!fs) {
1460                         fs = create_fs_device(devices[i], 0, "auto",
1461                                               0, -1, -1);
1462                         if (!fs)
1463                                 continue;
1464                 }
1465                 if (ignore_mounted && is_mounted(fs->device))
1466                         continue;
1467                 status |= fsck_device(fs, interactive);
1468                 if (serialize ||
1469                     (max_running && (num_running >= max_running))) {
1470                         struct fsck_instance *inst;
1471
1472                         inst = wait_one(0);
1473                         if (inst) {
1474                                 status |= inst->exit_status;
1475                                 free_instance(inst);
1476                         }
1477                         if (verbose > 1)
1478                                 printf("----------------------------------\n");
1479                 }
1480         }
1481         status |= wait_many(FLAG_WAIT_ALL);
1482         free(fsck_path);
1483         fsprobe_exit();
1484         return status;
1485 }
1486