]> git.ipfire.org Git - thirdparty/util-linux.git/blob - disk-utils/fsck.c
Merge branch 'usage-part1' of https://github.com/rudimeier/util-linux
[thirdparty/util-linux.git] / disk-utils / fsck.c
1 /*
2 * fsck --- 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-2014 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 <sys/resource.h>
47 #include <sys/time.h>
48 #include <blkid.h>
49 #include <libmount.h>
50
51 #include "nls.h"
52 #include "pathnames.h"
53 #include "exitcodes.h"
54 #include "c.h"
55 #include "fileutils.h"
56 #include "monotonic.h"
57
58 #define STRTOXX_EXIT_CODE FSCK_EX_ERROR
59 #include "strutils.h"
60
61 #define XALLOC_EXIT_CODE FSCK_EX_ERROR
62 #include "xalloc.h"
63
64 #define CLOSE_EXIT_CODE FSCK_EX_ERROR
65 #include "closestream.h"
66
67 #ifndef DEFAULT_FSTYPE
68 # define DEFAULT_FSTYPE "ext2"
69 #endif
70
71 #define MAX_DEVICES 32
72 #define MAX_ARGS 32
73
74 #define FSCK_RUNTIME_DIRNAME "/run/fsck"
75
76 static const char *ignored_types[] = {
77 "ignore",
78 "iso9660",
79 "sw",
80 NULL
81 };
82
83 static const char *really_wanted[] = {
84 "minix",
85 "ext2",
86 "ext3",
87 "ext4",
88 "ext4dev",
89 "jfs",
90 "reiserfs"
91 };
92
93 /*
94 * Internal structure for mount table entries.
95 */
96 struct fsck_fs_data
97 {
98 const char *device;
99 dev_t disk;
100 unsigned int stacked:1,
101 done:1,
102 eval_device:1;
103 };
104
105 /*
106 * Structure to allow exit codes to be stored
107 */
108 struct fsck_instance {
109 int pid;
110 int flags; /* FLAG_{DONE|PROGRESS} */
111
112 int lock; /* flock()ed lockpath file descriptor or -1 */
113 char *lockpath; /* /run/fsck/<diskname>.lock or NULL */
114
115 int exit_status;
116 struct timeval start_time;
117 struct timeval end_time;
118 char * prog;
119 char * type;
120
121 struct rusage rusage;
122 struct libmnt_fs *fs;
123 struct fsck_instance *next;
124 };
125
126 #define FLAG_DONE 1
127 #define FLAG_PROGRESS 2
128
129 /*
130 * Global variables for options
131 */
132 static char *devices[MAX_DEVICES];
133 static char *args[MAX_ARGS];
134 static int num_devices, num_args;
135
136 static int lockdisk;
137 static int verbose;
138 static int doall;
139 static int noexecute;
140 static int serialize;
141 static int skip_root;
142 static int ignore_mounted;
143 static int notitle;
144 static int parallel_root;
145 static int progress;
146 static int progress_fd;
147 static int force_all_parallel;
148 static int report_stats;
149 static FILE *report_stats_file;
150
151 static int num_running;
152 static int max_running;
153
154 static volatile int cancel_requested;
155 static int kill_sent;
156 static char *fstype;
157 static struct fsck_instance *instance_list;
158
159 #define FSCK_DEFAULT_PATH "/sbin"
160 static char *fsck_path;
161
162
163 /* parsed fstab and mtab */
164 static struct libmnt_table *fstab, *mtab;
165 static struct libmnt_cache *mntcache;
166
167 static int count_slaves(dev_t disk);
168
169 static int string_to_int(const char *s)
170 {
171 long l;
172 char *p;
173
174 l = strtol(s, &p, 0);
175 if (*p || l == LONG_MIN || l == LONG_MAX || l < 0 || l > INT_MAX)
176 return -1;
177 else
178 return (int) l;
179 }
180
181 /* Do we really really want to check this fs? */
182 static int fs_check_required(const char *type)
183 {
184 size_t i;
185
186 for(i = 0; i < ARRAY_SIZE(really_wanted); i++) {
187 if (strcmp(type, really_wanted[i]) == 0)
188 return 1;
189 }
190
191 return 0;
192 }
193
194 static int is_mounted(struct libmnt_fs *fs)
195 {
196 int rc;
197 const char *src;
198
199 src = mnt_fs_get_source(fs);
200 if (!src)
201 return 0;
202 if (!mntcache)
203 mntcache = mnt_new_cache();
204 if (!mtab) {
205 mtab = mnt_new_table();
206 if (!mtab)
207 err(FSCK_EX_ERROR, ("failed to initialize libmount table"));
208 mnt_table_set_cache(mtab, mntcache);
209 mnt_table_parse_mtab(mtab, NULL);
210 }
211
212 rc = mnt_table_find_source(mtab, src, MNT_ITER_BACKWARD) ? 1 : 0;
213 if (verbose) {
214 if (rc)
215 printf(_("%s is mounted\n"), src);
216 else
217 printf(_("%s is not mounted\n"), src);
218 }
219 return rc;
220 }
221
222 static int ignore(struct libmnt_fs *);
223
224 static struct fsck_fs_data *fs_create_data(struct libmnt_fs *fs)
225 {
226 struct fsck_fs_data *data = mnt_fs_get_userdata(fs);
227
228 if (!data) {
229 data = xcalloc(1, sizeof(*data));
230 mnt_fs_set_userdata(fs, data);
231 }
232 return data;
233 }
234
235 /*
236 * fs from fstab might contains real device name as well as symlink,
237 * LABEL or UUID, this function returns canonicalized result.
238 */
239 static const char *fs_get_device(struct libmnt_fs *fs)
240 {
241 struct fsck_fs_data *data = mnt_fs_get_userdata(fs);
242
243 if (!data || !data->eval_device) {
244 const char *spec = mnt_fs_get_source(fs);
245
246 if (!data)
247 data = fs_create_data(fs);
248
249 data->eval_device = 1;
250 data->device = mnt_resolve_spec(spec, mnt_table_get_cache(fstab));
251 if (!data->device)
252 data->device = xstrdup(spec);
253 }
254
255 return data->device;
256 }
257
258 static dev_t fs_get_disk(struct libmnt_fs *fs, int check)
259 {
260 struct fsck_fs_data *data;
261 const char *device;
262 struct stat st;
263
264 data = mnt_fs_get_userdata(fs);
265 if (data && data->disk)
266 return data->disk;
267
268 if (!check)
269 return 0;
270
271 if (mnt_fs_is_netfs(fs) || mnt_fs_is_pseudofs(fs))
272 return 0;
273
274 device = fs_get_device(fs);
275 if (!device)
276 return 0;
277
278 data = fs_create_data(fs);
279
280 if (!stat(device, &st) &&
281 !blkid_devno_to_wholedisk(st.st_rdev, NULL, 0, &data->disk)) {
282
283 if (data->disk)
284 data->stacked = count_slaves(data->disk) > 0 ? 1 : 0;
285 return data->disk;
286 }
287 return 0;
288 }
289
290 static int fs_is_stacked(struct libmnt_fs *fs)
291 {
292 struct fsck_fs_data *data = mnt_fs_get_userdata(fs);
293 return data ? data->stacked : 0;
294 }
295
296 static int fs_is_done(struct libmnt_fs *fs)
297 {
298 struct fsck_fs_data *data = mnt_fs_get_userdata(fs);
299 return data ? data->done : 0;
300 }
301
302 static void fs_set_done(struct libmnt_fs *fs)
303 {
304 struct fsck_fs_data *data = fs_create_data(fs);
305
306 if (data)
307 data->done = 1;
308 }
309
310 static int is_irrotational_disk(dev_t disk)
311 {
312 char path[PATH_MAX];
313 FILE *f;
314 int rc, x;
315
316
317 rc = snprintf(path, sizeof(path),
318 "/sys/dev/block/%d:%d/queue/rotational",
319 major(disk), minor(disk));
320
321 if (rc < 0 || (unsigned int) rc >= sizeof(path))
322 return 0;
323
324 f = fopen(path, "r");
325 if (!f)
326 return 0;
327
328 rc = fscanf(f, "%d", &x);
329 if (rc != 1) {
330 if (ferror(f))
331 warn(_("cannot read %s"), path);
332 else
333 warnx(_("parse error: %s"), path);
334 }
335 fclose(f);
336
337 return rc == 1 ? !x : 0;
338 }
339
340 static void lock_disk(struct fsck_instance *inst)
341 {
342 dev_t disk = fs_get_disk(inst->fs, 1);
343 char *diskpath = NULL, *diskname;
344
345 inst->lock = -1;
346
347 if (!disk || is_irrotational_disk(disk))
348 goto done;
349
350 diskpath = blkid_devno_to_devname(disk);
351 if (!diskpath)
352 goto done;
353
354 if (access(FSCK_RUNTIME_DIRNAME, F_OK) != 0) {
355 int rc = mkdir(FSCK_RUNTIME_DIRNAME,
356 S_IWUSR|
357 S_IRUSR|S_IRGRP|S_IROTH|
358 S_IXUSR|S_IXGRP|S_IXOTH);
359 if (rc && errno != EEXIST) {
360 warn(_("cannot create directory %s"),
361 FSCK_RUNTIME_DIRNAME);
362 goto done;
363 }
364 }
365
366 diskname = stripoff_last_component(diskpath);
367 if (!diskname)
368 diskname = diskpath;
369
370 xasprintf(&inst->lockpath, FSCK_RUNTIME_DIRNAME "/%s.lock", diskname);
371
372 if (verbose)
373 printf(_("Locking disk by %s ... "), inst->lockpath);
374
375 inst->lock = open(inst->lockpath, O_RDONLY|O_CREAT|O_CLOEXEC,
376 S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
377 if (inst->lock >= 0) {
378 int rc = -1;
379
380 /* inform users that we're waiting on the lock */
381 if (verbose &&
382 (rc = flock(inst->lock, LOCK_EX | LOCK_NB)) != 0 &&
383 errno == EWOULDBLOCK)
384 printf(_("(waiting) "));
385
386 if (rc != 0 && flock(inst->lock, LOCK_EX) != 0) {
387 close(inst->lock); /* failed */
388 inst->lock = -1;
389 }
390 }
391
392 if (verbose)
393 /* TRANSLATORS: These are followups to "Locking disk...". */
394 printf("%s.\n", inst->lock >= 0 ? _("succeeded") : _("failed"));
395
396
397 done:
398 if (inst->lock < 0) {
399 free(inst->lockpath);
400 inst->lockpath = NULL;
401 }
402 free(diskpath);
403 return;
404 }
405
406 static void unlock_disk(struct fsck_instance *inst)
407 {
408 if (inst->lock < 0)
409 return;
410
411 if (verbose)
412 printf(_("Unlocking %s.\n"), inst->lockpath);
413
414 close(inst->lock); /* unlock */
415
416 free(inst->lockpath);
417
418 inst->lock = -1;
419 inst->lockpath = NULL;
420 }
421
422 static void free_instance(struct fsck_instance *i)
423 {
424 if (lockdisk)
425 unlock_disk(i);
426 free(i->prog);
427 free(i->lockpath);
428 mnt_unref_fs(i->fs);
429 free(i);
430 return;
431 }
432
433 static struct libmnt_fs *add_dummy_fs(const char *device)
434 {
435 struct libmnt_fs *fs = mnt_new_fs();
436
437 if (fs && mnt_fs_set_source(fs, device) == 0 &&
438 mnt_table_add_fs(fstab, fs) == 0) {
439 mnt_unref_fs(fs);
440 return fs;
441 }
442
443 mnt_unref_fs(fs);
444 err(FSCK_EX_ERROR, _("failed to setup description for %s"), device);
445 }
446
447 static void fs_interpret_type(struct libmnt_fs *fs)
448 {
449 const char *device;
450 const char *type = mnt_fs_get_fstype(fs);
451
452 if (type && strcmp(type, "auto") != 0)
453 return;
454
455 mnt_fs_set_fstype(fs, NULL);
456
457 device = fs_get_device(fs);
458 if (device) {
459 int ambi = 0;
460 char *tp;
461 struct libmnt_cache *cache = mnt_table_get_cache(fstab);
462
463 tp = mnt_get_fstype(device, &ambi, cache);
464 if (!ambi)
465 mnt_fs_set_fstype(fs, tp);
466 if (!cache)
467 free(tp);
468 }
469 }
470
471 static int parser_errcb(struct libmnt_table *tb __attribute__ ((__unused__)),
472 const char *filename, int line)
473 {
474 warnx(_("%s: parse error at line %d -- ignored"), filename, line);
475 return 1;
476 }
477
478 /*
479 * Load the filesystem database from /etc/fstab
480 */
481 static void load_fs_info(void)
482 {
483 const char *path;
484
485 fstab = mnt_new_table();
486 if (!fstab)
487 err(FSCK_EX_ERROR, ("failed to initialize libmount table"));
488
489 mnt_table_set_parser_errcb(fstab, parser_errcb);
490 mnt_table_set_cache(fstab, mntcache);
491
492 errno = 0;
493
494 /*
495 * Let's follow libmount defaults if $FSTAB_FILE is not specified
496 */
497 path = getenv("FSTAB_FILE");
498
499 if (mnt_table_parse_fstab(fstab, path)) {
500 if (!path)
501 path = mnt_get_fstab_path();
502
503 /* don't print error when there is no fstab at all */
504 if (access(path, F_OK) == 0) {
505 if (errno)
506 warn(_("%s: failed to parse fstab"), path);
507 else
508 warnx(_("%s: failed to parse fstab"), path);
509 }
510 }
511 }
512
513 /*
514 * Lookup filesys in /etc/fstab and return the corresponding entry.
515 * The @path has to be real path (no TAG) by mnt_resolve_spec().
516 */
517 static struct libmnt_fs *lookup(char *path)
518 {
519 struct libmnt_fs *fs;
520
521 if (!path)
522 return NULL;
523
524 fs = mnt_table_find_srcpath(fstab, path, MNT_ITER_FORWARD);
525 if (!fs) {
526 /*
527 * Maybe mountpoint has been specified on fsck command line.
528 * Yeah, crazy feature...
529 *
530 * Note that mnt_table_find_target() may canonicalize paths in
531 * the fstab to support symlinks. This is really unwanted,
532 * because readlink() on mountpoints may trigger automounts.
533 *
534 * So, disable the cache and compare the paths as strings
535 * without care about symlinks...
536 */
537 mnt_table_set_cache(fstab, NULL);
538 fs = mnt_table_find_target(fstab, path, MNT_ITER_FORWARD);
539 mnt_table_set_cache(fstab, mntcache);
540 }
541 return fs;
542 }
543
544 /* Find fsck program for a given fs type. */
545 static char *find_fsck(const char *type)
546 {
547 char *s;
548 const char *tpl;
549 static char prog[256];
550 char *p = xstrdup(fsck_path);
551
552 /* Are we looking for a program or just a type? */
553 tpl = (strncmp(type, "fsck.", 5) ? "%s/fsck.%s" : "%s/%s");
554
555 for(s = strtok(p, ":"); s; s = strtok(NULL, ":")) {
556 sprintf(prog, tpl, s, type);
557 if (access(prog, X_OK) == 0)
558 break;
559 }
560 free(p);
561
562 return(s ? prog : NULL);
563 }
564
565 static int progress_active(void)
566 {
567 struct fsck_instance *inst;
568
569 for (inst = instance_list; inst; inst = inst->next) {
570 if (inst->flags & FLAG_DONE)
571 continue;
572 if (inst->flags & FLAG_PROGRESS)
573 return 1;
574 }
575 return 0;
576 }
577
578 /*
579 * Process run statistics for finished fsck instances.
580 *
581 * If report_stats is 0, do nothing, otherwise print a selection of
582 * interesting rusage statistics as well as elapsed wallclock time.
583 */
584 static void print_stats(struct fsck_instance *inst)
585 {
586 struct timeval delta;
587
588 if (!inst || !report_stats || noexecute)
589 return;
590
591 timersub(&inst->end_time, &inst->start_time, &delta);
592
593 if (report_stats_file)
594 fprintf(report_stats_file, "%s %d %ld "
595 "%ld.%06ld %ld.%06ld %ld.%06ld\n",
596 fs_get_device(inst->fs),
597 inst->exit_status,
598 inst->rusage.ru_maxrss,
599 (long)delta.tv_sec, (long)delta.tv_usec,
600 (long)inst->rusage.ru_utime.tv_sec,
601 (long)inst->rusage.ru_utime.tv_usec,
602 (long)inst->rusage.ru_stime.tv_sec,
603 (long)inst->rusage.ru_stime.tv_usec);
604 else
605 fprintf(stdout, "%s: status %d, rss %ld, "
606 "real %ld.%06ld, user %ld.%06ld, sys %ld.%06ld\n",
607 fs_get_device(inst->fs),
608 inst->exit_status,
609 inst->rusage.ru_maxrss,
610 (long)delta.tv_sec, (long)delta.tv_usec,
611 (long)inst->rusage.ru_utime.tv_sec,
612 (long)inst->rusage.ru_utime.tv_usec,
613 (long)inst->rusage.ru_stime.tv_sec,
614 (long)inst->rusage.ru_stime.tv_usec);
615 }
616
617 /*
618 * Execute a particular fsck program, and link it into the list of
619 * child processes we are waiting for.
620 */
621 static int execute(const char *progname, const char *progpath,
622 const char *type, struct libmnt_fs *fs, int interactive)
623 {
624 char *argv[80];
625 int argc, i;
626 struct fsck_instance *inst, *p;
627 pid_t pid;
628
629 inst = xcalloc(1, sizeof(*inst));
630
631 argv[0] = xstrdup(progname);
632 argc = 1;
633
634 for (i=0; i <num_args; i++)
635 argv[argc++] = xstrdup(args[i]);
636
637 if (progress &&
638 ((strcmp(type, "ext2") == 0) ||
639 (strcmp(type, "ext3") == 0) ||
640 (strcmp(type, "ext4") == 0) ||
641 (strcmp(type, "ext4dev") == 0))) {
642
643 char tmp[80];
644 tmp[0] = 0;
645 if (!progress_active()) {
646 snprintf(tmp, 80, "-C%d", progress_fd);
647 inst->flags |= FLAG_PROGRESS;
648 } else if (progress_fd)
649 snprintf(tmp, 80, "-C%d", progress_fd * -1);
650 if (tmp[0])
651 argv[argc++] = xstrdup(tmp);
652 }
653
654 argv[argc++] = xstrdup(fs_get_device(fs));
655 argv[argc] = NULL;
656
657 if (verbose || noexecute) {
658 const char *tgt = mnt_fs_get_target(fs);
659
660 if (!tgt)
661 tgt = fs_get_device(fs);
662 printf("[%s (%d) -- %s] ", progpath, num_running, tgt);
663 for (i=0; i < argc; i++)
664 printf("%s ", argv[i]);
665 printf("\n");
666 }
667
668 mnt_ref_fs(fs);
669 inst->fs = fs;
670 inst->lock = -1;
671
672 if (lockdisk)
673 lock_disk(inst);
674
675 /* Fork and execute the correct program. */
676 if (noexecute)
677 pid = -1;
678 else if ((pid = fork()) < 0) {
679 warn(_("fork failed"));
680 free_instance(inst);
681 return errno;
682 } else if (pid == 0) {
683 if (!interactive)
684 close(0);
685 execv(progpath, argv);
686 err(FSCK_EX_ERROR, _("%s: execute failed"), progpath);
687 }
688
689 for (i=0; i < argc; i++)
690 free(argv[i]);
691
692 inst->pid = pid;
693 inst->prog = xstrdup(progname);
694 inst->type = xstrdup(type);
695 gettime_monotonic(&inst->start_time);
696 inst->next = NULL;
697
698 /*
699 * Find the end of the list, so we add the instance on at the end.
700 */
701 for (p = instance_list; p && p->next; p = p->next);
702
703 if (p)
704 p->next = inst;
705 else
706 instance_list = inst;
707
708 return 0;
709 }
710
711 /*
712 * Send a signal to all outstanding fsck child processes
713 */
714 static int kill_all(int signum)
715 {
716 struct fsck_instance *inst;
717 int n = 0;
718
719 for (inst = instance_list; inst; inst = inst->next) {
720 if (inst->flags & FLAG_DONE)
721 continue;
722 kill(inst->pid, signum);
723 n++;
724 }
725 return n;
726 }
727
728 /*
729 * Wait for one child process to exit; when it does, unlink it from
730 * the list of executing child processes, and return it.
731 */
732 static struct fsck_instance *wait_one(int flags)
733 {
734 int status = 0;
735 int sig;
736 struct fsck_instance *inst, *inst2, *prev;
737 pid_t pid;
738 struct rusage rusage;
739
740 if (!instance_list)
741 return NULL;
742
743 if (noexecute) {
744 inst = instance_list;
745 prev = NULL;
746 #ifdef RANDOM_DEBUG
747 while (inst->next && (random() & 1)) {
748 prev = inst;
749 inst = inst->next;
750 }
751 #endif
752 inst->exit_status = 0;
753 goto ret_inst;
754 }
755
756 /*
757 * gcc -Wall fails saving throw against stupidity
758 * (inst and prev are thought to be uninitialized variables)
759 */
760 inst = prev = NULL;
761
762 do {
763 pid = wait4(-1, &status, flags, &rusage);
764 if (cancel_requested && !kill_sent) {
765 kill_all(SIGTERM);
766 kill_sent++;
767 }
768 if ((pid == 0) && (flags & WNOHANG))
769 return NULL;
770 if (pid < 0) {
771 if ((errno == EINTR) || (errno == EAGAIN))
772 continue;
773 if (errno == ECHILD) {
774 warnx(_("wait: no more child process?!?"));
775 return NULL;
776 }
777 warn(_("waitpid failed"));
778 continue;
779 }
780 for (prev = NULL, inst = instance_list;
781 inst;
782 prev = inst, inst = inst->next) {
783 if (inst->pid == pid)
784 break;
785 }
786 } while (!inst);
787
788 if (WIFEXITED(status))
789 status = WEXITSTATUS(status);
790 else if (WIFSIGNALED(status)) {
791 sig = WTERMSIG(status);
792 if (sig == SIGINT) {
793 status = FSCK_EX_UNCORRECTED;
794 } else {
795 warnx(_("Warning... %s for device %s exited "
796 "with signal %d."),
797 inst->prog, fs_get_device(inst->fs), sig);
798 status = FSCK_EX_ERROR;
799 }
800 } else {
801 warnx(_("%s %s: status is %x, should never happen."),
802 inst->prog, fs_get_device(inst->fs), status);
803 status = FSCK_EX_ERROR;
804 }
805
806 inst->exit_status = status;
807 inst->flags |= FLAG_DONE;
808 gettime_monotonic(&inst->end_time);
809 memcpy(&inst->rusage, &rusage, sizeof(struct rusage));
810
811 if (progress && (inst->flags & FLAG_PROGRESS) &&
812 !progress_active()) {
813 for (inst2 = instance_list; inst2; inst2 = inst2->next) {
814 if (inst2->flags & FLAG_DONE)
815 continue;
816 if (strcmp(inst2->type, "ext2") &&
817 strcmp(inst2->type, "ext3") &&
818 strcmp(inst2->type, "ext4") &&
819 strcmp(inst2->type, "ext4dev"))
820 continue;
821 /*
822 * If we've just started the fsck, wait a tiny
823 * bit before sending the kill, to give it
824 * time to set up the signal handler
825 */
826 if (inst2->start_time.tv_sec < time(NULL) + 2) {
827 if (fork() == 0) {
828 sleep(1);
829 kill(inst2->pid, SIGUSR1);
830 exit(FSCK_EX_OK);
831 }
832 } else
833 kill(inst2->pid, SIGUSR1);
834 inst2->flags |= FLAG_PROGRESS;
835 break;
836 }
837 }
838 ret_inst:
839 if (prev)
840 prev->next = inst->next;
841 else
842 instance_list = inst->next;
843
844 print_stats(inst);
845
846 if (verbose > 1)
847 printf(_("Finished with %s (exit status %d)\n"),
848 fs_get_device(inst->fs), inst->exit_status);
849 num_running--;
850 return inst;
851 }
852
853 #define FLAG_WAIT_ALL 0
854 #define FLAG_WAIT_ATLEAST_ONE 1
855 /*
856 * Wait until all executing child processes have exited; return the
857 * logical OR of all of their exit code values.
858 */
859 static int wait_many(int flags)
860 {
861 struct fsck_instance *inst;
862 int global_status = 0;
863 int wait_flags = 0;
864
865 while ((inst = wait_one(wait_flags))) {
866 global_status |= inst->exit_status;
867 free_instance(inst);
868 #ifdef RANDOM_DEBUG
869 if (noexecute && (flags & WNOHANG) && !(random() % 3))
870 break;
871 #endif
872 if (flags & FLAG_WAIT_ATLEAST_ONE)
873 wait_flags = WNOHANG;
874 }
875 return global_status;
876 }
877
878 /*
879 * Run the fsck program on a particular device
880 *
881 * If the type is specified using -t, and it isn't prefixed with "no"
882 * (as in "noext2") and only one filesystem type is specified, then
883 * use that type regardless of what is specified in /etc/fstab.
884 *
885 * If the type isn't specified by the user, then use either the type
886 * specified in /etc/fstab, or DEFAULT_FSTYPE.
887 */
888 static int fsck_device(struct libmnt_fs *fs, int interactive)
889 {
890 char progname[80], *progpath;
891 const char *type;
892 int retval;
893
894 fs_interpret_type(fs);
895
896 type = mnt_fs_get_fstype(fs);
897
898 if (type && strcmp(type, "auto") != 0)
899 ;
900 else if (fstype && strncmp(fstype, "no", 2) &&
901 strncmp(fstype, "opts=", 5) && strncmp(fstype, "loop", 4) &&
902 !strchr(fstype, ','))
903 type = fstype;
904 else
905 type = DEFAULT_FSTYPE;
906
907 sprintf(progname, "fsck.%s", type);
908 progpath = find_fsck(progname);
909 if (progpath == NULL) {
910 if (fs_check_required(type)) {
911 retval = ENOENT;
912 goto err;
913 }
914 return 0;
915 }
916
917 num_running++;
918 retval = execute(progname, progpath, type, fs, interactive);
919 if (retval) {
920 num_running--;
921 goto err;
922 }
923 return 0;
924 err:
925 warnx(_("error %d (%m) while executing fsck.%s for %s"),
926 retval, type, fs_get_device(fs));
927 return FSCK_EX_ERROR;
928 }
929
930
931 /*
932 * Deal with the fsck -t argument.
933 */
934 static struct fs_type_compile {
935 char **list;
936 int *type;
937 int negate;
938 } fs_type_compiled;
939
940 #define FS_TYPE_NORMAL 0
941 #define FS_TYPE_OPT 1
942 #define FS_TYPE_NEGOPT 2
943
944 static void compile_fs_type(char *fs_type, struct fs_type_compile *cmp)
945 {
946 char *cp, *list, *s;
947 int num = 2;
948 int negate, first_negate = 1;
949
950 if (fs_type) {
951 for (cp=fs_type; *cp; cp++) {
952 if (*cp == ',')
953 num++;
954 }
955 }
956
957 cmp->list = xcalloc(num, sizeof(char *));
958 cmp->type = xcalloc(num, sizeof(int));
959 cmp->negate = 0;
960
961 if (!fs_type)
962 return;
963
964 list = xstrdup(fs_type);
965 num = 0;
966 s = strtok(list, ",");
967 while(s) {
968 negate = 0;
969 if (strncmp(s, "no", 2) == 0) {
970 s += 2;
971 negate = 1;
972 } else if (*s == '!') {
973 s++;
974 negate = 1;
975 }
976 if (strcmp(s, "loop") == 0)
977 /* loop is really short-hand for opts=loop */
978 goto loop_special_case;
979 else if (strncmp(s, "opts=", 5) == 0) {
980 s += 5;
981 loop_special_case:
982 cmp->type[num] = negate ? FS_TYPE_NEGOPT : FS_TYPE_OPT;
983 } else {
984 if (first_negate) {
985 cmp->negate = negate;
986 first_negate = 0;
987 }
988 if ((negate && !cmp->negate) ||
989 (!negate && cmp->negate)) {
990 errx(FSCK_EX_USAGE,
991 _("Either all or none of the filesystem types passed to -t must be prefixed\n"
992 "with 'no' or '!'."));
993 }
994 }
995
996 cmp->list[num++] = xstrdup(s);
997 s = strtok(NULL, ",");
998 }
999 free(list);
1000 }
1001
1002 /*
1003 * This function returns true if a particular option appears in a
1004 * comma-delimited options list
1005 */
1006 static int opt_in_list(const char *opt, const char *optlist)
1007 {
1008 char *list, *s;
1009
1010 if (!optlist)
1011 return 0;
1012 list = xstrdup(optlist);
1013
1014 s = strtok(list, ",");
1015 while(s) {
1016 if (strcmp(s, opt) == 0) {
1017 free(list);
1018 return 1;
1019 }
1020 s = strtok(NULL, ",");
1021 }
1022 free(list);
1023 return 0;
1024 }
1025
1026 /* See if the filesystem matches the criteria given by the -t option */
1027 static int fs_match(struct libmnt_fs *fs, struct fs_type_compile *cmp)
1028 {
1029 int n, ret = 0, checked_type = 0;
1030 char *cp;
1031
1032 if (cmp->list == NULL || cmp->list[0] == NULL)
1033 return 1;
1034
1035 for (n=0; (cp = cmp->list[n]); n++) {
1036 switch (cmp->type[n]) {
1037 case FS_TYPE_NORMAL:
1038 {
1039 const char *type = mnt_fs_get_fstype(fs);
1040
1041 checked_type++;
1042 if (type && strcmp(cp, type) == 0)
1043 ret = 1;
1044 break;
1045 }
1046 case FS_TYPE_NEGOPT:
1047 if (opt_in_list(cp, mnt_fs_get_options(fs)))
1048 return 0;
1049 break;
1050 case FS_TYPE_OPT:
1051 if (!opt_in_list(cp, mnt_fs_get_options(fs)))
1052 return 0;
1053 break;
1054 }
1055 }
1056 if (checked_type == 0)
1057 return 1;
1058 return (cmp->negate ? !ret : ret);
1059 }
1060
1061 /*
1062 * Check if a device exists
1063 */
1064 static int device_exists(const char *device)
1065 {
1066 struct stat st;
1067
1068 if (stat(device, &st) == -1)
1069 return 0;
1070 if (!S_ISBLK(st.st_mode))
1071 return 0;
1072 return 1;
1073 }
1074
1075 static int fs_ignored_type(struct libmnt_fs *fs)
1076 {
1077 const char **ip, *type;
1078
1079 if (mnt_fs_is_netfs(fs) || mnt_fs_is_pseudofs(fs) || mnt_fs_is_swaparea(fs))
1080 return 1;
1081
1082 type = mnt_fs_get_fstype(fs);
1083
1084 for(ip = ignored_types; type && *ip; ip++) {
1085 if (strcmp(type, *ip) == 0)
1086 return 1;
1087 }
1088
1089 return 0;
1090 }
1091
1092 /* Check if we should ignore this filesystem. */
1093 static int ignore(struct libmnt_fs *fs)
1094 {
1095 const char *type;
1096
1097 /*
1098 * If the pass number is 0, ignore it.
1099 */
1100 if (mnt_fs_get_passno(fs) == 0)
1101 return 1;
1102
1103 /*
1104 * If this is a bind mount, ignore it.
1105 */
1106 if (opt_in_list("bind", mnt_fs_get_options(fs))) {
1107 warnx(_("%s: skipping bad line in /etc/fstab: "
1108 "bind mount with nonzero fsck pass number"),
1109 mnt_fs_get_target(fs));
1110 return 1;
1111 }
1112
1113 /*
1114 * ignore devices that don't exist and have the "nofail" mount option
1115 */
1116 if (!device_exists(fs_get_device(fs))) {
1117 if (opt_in_list("nofail", mnt_fs_get_options(fs))) {
1118 if (verbose)
1119 printf(_("%s: skipping nonexistent device\n"),
1120 fs_get_device(fs));
1121 return 1;
1122 }
1123 if (verbose)
1124 printf(_("%s: nonexistent device (\"nofail\" fstab "
1125 "option may be used to skip this device)\n"),
1126 fs_get_device(fs));
1127 }
1128
1129 fs_interpret_type(fs);
1130
1131 /*
1132 * If a specific fstype is specified, and it doesn't match,
1133 * ignore it.
1134 */
1135 if (!fs_match(fs, &fs_type_compiled))
1136 return 1;
1137
1138 type = mnt_fs_get_fstype(fs);
1139 if (!type) {
1140 if (verbose)
1141 printf(_("%s: skipping unknown filesystem type\n"),
1142 fs_get_device(fs));
1143 return 1;
1144 }
1145
1146 /* Are we ignoring this type? */
1147 if (fs_ignored_type(fs))
1148 return 1;
1149
1150
1151
1152 /* See if the <fsck.fs> program is available. */
1153 if (find_fsck(type) == NULL) {
1154 if (fs_check_required(type))
1155 warnx(_("cannot check %s: fsck.%s not found"),
1156 fs_get_device(fs), type);
1157 return 1;
1158 }
1159
1160 /* We can and want to check this file system type. */
1161 return 0;
1162 }
1163
1164 static int count_slaves(dev_t disk)
1165 {
1166 DIR *dir;
1167 struct dirent *dp;
1168 char dirname[PATH_MAX];
1169 int count = 0;
1170
1171 snprintf(dirname, sizeof(dirname),
1172 "/sys/dev/block/%u:%u/slaves/",
1173 major(disk), minor(disk));
1174
1175 if (!(dir = opendir(dirname)))
1176 return -1;
1177
1178 while ((dp = readdir(dir)) != NULL) {
1179 #ifdef _DIRENT_HAVE_D_TYPE
1180 if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
1181 continue;
1182 #endif
1183 if (dp->d_name[0] == '.' &&
1184 ((dp->d_name[1] == 0) ||
1185 ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
1186 continue;
1187
1188 count++;
1189 }
1190
1191 closedir(dir);
1192 return count;
1193 }
1194
1195 /*
1196 * Returns TRUE if a partition on the same disk is already being
1197 * checked.
1198 */
1199 static int disk_already_active(struct libmnt_fs *fs)
1200 {
1201 struct fsck_instance *inst;
1202 dev_t disk;
1203
1204 if (force_all_parallel)
1205 return 0;
1206
1207 if (instance_list && fs_is_stacked(instance_list->fs))
1208 /* any instance for a stacked device is already running */
1209 return 1;
1210
1211 disk = fs_get_disk(fs, 1);
1212
1213 /*
1214 * If we don't know the base device, assume that the device is
1215 * already active if there are any fsck instances running.
1216 *
1217 * Don't check a stacked device with any other disk too.
1218 */
1219 if (!disk || fs_is_stacked(fs))
1220 return (instance_list != NULL);
1221
1222 for (inst = instance_list; inst; inst = inst->next) {
1223 dev_t idisk = fs_get_disk(inst->fs, 0);
1224
1225 if (!idisk || disk == idisk)
1226 return 1;
1227 }
1228
1229 return 0;
1230 }
1231
1232 /* Check all file systems, using the /etc/fstab table. */
1233 static int check_all(void)
1234 {
1235 int not_done_yet = 1;
1236 int passno = 1;
1237 int pass_done;
1238 int status = FSCK_EX_OK;
1239
1240 struct libmnt_fs *fs;
1241 struct libmnt_iter *itr = mnt_new_iter(MNT_ITER_FORWARD);
1242
1243 if (!itr)
1244 err(FSCK_EX_ERROR, _("failed to allocate iterator"));
1245
1246 /*
1247 * Do an initial scan over the filesystem; mark filesystems
1248 * which should be ignored as done, and resolve any "auto"
1249 * filesystem types (done as a side-effect of calling ignore()).
1250 */
1251 while (mnt_table_next_fs(fstab, itr, &fs) == 0) {
1252 if (ignore(fs)) {
1253 fs_set_done(fs);
1254 continue;
1255 }
1256 }
1257
1258 if (verbose)
1259 fputs(_("Checking all file systems.\n"), stdout);
1260
1261 /*
1262 * Find and check the root filesystem.
1263 */
1264 if (!parallel_root) {
1265 fs = mnt_table_find_target(fstab, "/", MNT_ITER_FORWARD);
1266 if (fs) {
1267 if (!skip_root &&
1268 !fs_is_done(fs) &&
1269 !(ignore_mounted && is_mounted(fs))) {
1270 status |= fsck_device(fs, 1);
1271 status |= wait_many(FLAG_WAIT_ALL);
1272 if (status > FSCK_EX_NONDESTRUCT) {
1273 mnt_free_iter(itr);
1274 return status;
1275 }
1276 }
1277 fs_set_done(fs);
1278 }
1279 }
1280
1281 /*
1282 * This is for the bone-headed user who enters the root
1283 * filesystem twice. Skip root will skip all root entries.
1284 */
1285 if (skip_root) {
1286 mnt_reset_iter(itr, MNT_ITER_FORWARD);
1287
1288 while(mnt_table_next_fs(fstab, itr, &fs) == 0) {
1289 const char *tgt = mnt_fs_get_target(fs);
1290
1291 if (tgt && strcmp(tgt, "/") == 0)
1292 fs_set_done(fs);
1293 }
1294 }
1295
1296 while (not_done_yet) {
1297 not_done_yet = 0;
1298 pass_done = 1;
1299
1300 mnt_reset_iter(itr, MNT_ITER_FORWARD);
1301
1302 while(mnt_table_next_fs(fstab, itr, &fs) == 0) {
1303
1304 if (cancel_requested)
1305 break;
1306 if (fs_is_done(fs))
1307 continue;
1308 /*
1309 * If the filesystem's pass number is higher
1310 * than the current pass number, then we don't
1311 * do it yet.
1312 */
1313 if (mnt_fs_get_passno(fs) > passno) {
1314 not_done_yet++;
1315 continue;
1316 }
1317 if (ignore_mounted && is_mounted(fs)) {
1318 fs_set_done(fs);
1319 continue;
1320 }
1321 /*
1322 * If a filesystem on a particular device has
1323 * already been spawned, then we need to defer
1324 * this to another pass.
1325 */
1326 if (disk_already_active(fs)) {
1327 pass_done = 0;
1328 continue;
1329 }
1330 /*
1331 * Spawn off the fsck process
1332 */
1333 status |= fsck_device(fs, serialize);
1334 fs_set_done(fs);
1335
1336 /*
1337 * Only do one filesystem at a time, or if we
1338 * have a limit on the number of fsck's extant
1339 * at one time, apply that limit.
1340 */
1341 if (serialize ||
1342 (max_running && (num_running >= max_running))) {
1343 pass_done = 0;
1344 break;
1345 }
1346 }
1347 if (cancel_requested)
1348 break;
1349 if (verbose > 1)
1350 printf(_("--waiting-- (pass %d)\n"), passno);
1351
1352 status |= wait_many(pass_done ? FLAG_WAIT_ALL :
1353 FLAG_WAIT_ATLEAST_ONE);
1354 if (pass_done) {
1355 if (verbose > 1)
1356 printf("----------------------------------\n");
1357 passno++;
1358 } else
1359 not_done_yet++;
1360 }
1361
1362 if (cancel_requested && !kill_sent) {
1363 kill_all(SIGTERM);
1364 kill_sent++;
1365 }
1366
1367 status |= wait_many(FLAG_WAIT_ATLEAST_ONE);
1368 mnt_free_iter(itr);
1369 return status;
1370 }
1371
1372 static void __attribute__((__noreturn__)) usage(void)
1373 {
1374 FILE *out = stdout;
1375 fputs(USAGE_HEADER, out);
1376 fprintf(out, _(" %s [options] -- [fs-options] [<filesystem> ...]\n"),
1377 program_invocation_short_name);
1378
1379 fputs(USAGE_SEPARATOR, out);
1380 fputs(_("Check and repair a Linux filesystem.\n"), out);
1381
1382 fputs(USAGE_OPTIONS, out);
1383 fputs(_(" -A check all filesystems\n"), out);
1384 fputs(_(" -C [<fd>] display progress bar; file descriptor is for GUIs\n"), out);
1385 fputs(_(" -l lock the device to guarantee exclusive access\n"), out);
1386 fputs(_(" -M do not check mounted filesystems\n"), out);
1387 fputs(_(" -N do not execute, just show what would be done\n"), out);
1388 fputs(_(" -P check filesystems in parallel, including root\n"), out);
1389 fputs(_(" -R skip root filesystem; useful only with '-A'\n"), out);
1390 fputs(_(" -r [<fd>] report statistics for each device checked;\n"
1391 " file descriptor is for GUIs\n"), out);
1392 fputs(_(" -s serialize the checking operations\n"), out);
1393 fputs(_(" -T do not show the title on startup\n"), out);
1394 fputs(_(" -t <type> specify filesystem types to be checked;\n"
1395 " <type> is allowed to be a comma-separated list\n"), out);
1396 fputs(_(" -V explain what is being done\n"), out);
1397
1398 fputs(USAGE_SEPARATOR, out);
1399 fputs(_(" -?, --help display this help and exit\n"), out);
1400 fputs(_(" --version output version information and exit\n"), out);
1401 fputs(USAGE_SEPARATOR, out);
1402 fputs(_("See the specific fsck.* commands for available fs-options."), out);
1403 fprintf(out, USAGE_MAN_TAIL("fsck(8)"));
1404 exit(FSCK_EX_OK);
1405 }
1406
1407 static void signal_cancel(int sig __attribute__((__unused__)))
1408 {
1409 cancel_requested++;
1410 }
1411
1412 static void parse_argv(int argc, char *argv[])
1413 {
1414 int i, j;
1415 char *arg, *dev, *tmp = NULL;
1416 char options[128];
1417 int opt = 0;
1418 int opts_for_fsck = 0;
1419 struct sigaction sa;
1420 int report_stats_fd = -1;
1421
1422 /*
1423 * Set up signal action
1424 */
1425 memset(&sa, 0, sizeof(struct sigaction));
1426 sa.sa_handler = signal_cancel;
1427 sigaction(SIGINT, &sa, NULL);
1428 sigaction(SIGTERM, &sa, NULL);
1429
1430 num_devices = 0;
1431 num_args = 0;
1432 instance_list = NULL;
1433
1434 for (i=1; i < argc; i++) {
1435 arg = argv[i];
1436 if (!arg)
1437 continue;
1438
1439 /* the only two longopts to satisfy UL standards */
1440 if (!opts_for_fsck && !strcmp(arg, "--help"))
1441 usage();
1442 if (!opts_for_fsck && !strcmp(arg, "--version")) {
1443 printf(UTIL_LINUX_VERSION);
1444 exit(FSCK_EX_OK);
1445 }
1446
1447 if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) {
1448 if (num_devices >= MAX_DEVICES)
1449 errx(FSCK_EX_ERROR, _("too many devices"));
1450
1451 dev = mnt_resolve_spec(arg, mntcache);
1452
1453 if (!dev && strchr(arg, '=')) {
1454 /*
1455 * Check to see if we failed because
1456 * /proc/partitions isn't found.
1457 */
1458 if (access(_PATH_PROC_PARTITIONS, R_OK) < 0) {
1459 warn(_("cannot open %s"),
1460 _PATH_PROC_PARTITIONS);
1461 errx(FSCK_EX_ERROR, _("Is /proc mounted?"));
1462 }
1463 /*
1464 * Check to see if this is because
1465 * we're not running as root
1466 */
1467 if (geteuid())
1468 errx(FSCK_EX_ERROR,
1469 _("must be root to scan for matching filesystems: %s"),
1470 arg);
1471 else
1472 errx(FSCK_EX_ERROR,
1473 _("couldn't find matching filesystem: %s"),
1474 arg);
1475 }
1476 devices[num_devices++] = dev ? dev : xstrdup(arg);
1477 continue;
1478 }
1479 if (arg[0] != '-' || opts_for_fsck) {
1480 if (num_args >= MAX_ARGS)
1481 errx(FSCK_EX_ERROR, _("too many arguments"));
1482 args[num_args++] = xstrdup(arg);
1483 continue;
1484 }
1485 for (j=1; arg[j]; j++) {
1486 if (opts_for_fsck) {
1487 options[++opt] = arg[j];
1488 continue;
1489 }
1490 switch (arg[j]) {
1491 case 'A':
1492 doall = 1;
1493 break;
1494 case 'C':
1495 progress = 1;
1496 if (arg[j+1]) { /* -C<fd> */
1497 progress_fd = string_to_int(arg+j+1);
1498 if (progress_fd < 0)
1499 progress_fd = 0;
1500 else
1501 goto next_arg;
1502 } else if (i+1 < argc && *argv[i+1] != '-') { /* -C <fd> */
1503 progress_fd = string_to_int(argv[i+1]);
1504 if (progress_fd < 0)
1505 progress_fd = 0;
1506 else {
1507 ++i;
1508 goto next_arg;
1509 }
1510 }
1511 break;
1512 case 'l':
1513 lockdisk = 1;
1514 break;
1515 case 'V':
1516 verbose++;
1517 break;
1518 case 'N':
1519 noexecute = 1;
1520 break;
1521 case 'R':
1522 skip_root = 1;
1523 break;
1524 case 'T':
1525 notitle = 1;
1526 break;
1527 case 'M':
1528 ignore_mounted = 1;
1529 break;
1530 case 'P':
1531 parallel_root = 1;
1532 break;
1533 case 'r':
1534 report_stats = 1;
1535 if (arg[j+1]) { /* -r<fd> */
1536 report_stats_fd = strtou32_or_err(arg+j+1, _("invalid argument of -r"));
1537 goto next_arg;
1538 } else if (i+1 < argc && *argv[i+1] >= '0' && *argv[i+1] <= '9') { /* -r <fd> */
1539 report_stats_fd = strtou32_or_err(argv[i+1], _("invalid argument of -r"));
1540 ++i;
1541 goto next_arg;
1542 }
1543 break;
1544 case 's':
1545 serialize = 1;
1546 break;
1547 case 't':
1548 tmp = NULL;
1549 if (fstype)
1550 errx(FSCK_EX_USAGE,
1551 _("option '%s' may be specified only once"), "-t");
1552 if (arg[j+1])
1553 tmp = arg+j+1;
1554 else if ((i+1) < argc)
1555 tmp = argv[++i];
1556 else
1557 errx(FSCK_EX_USAGE,
1558 _("option '%s' requires an argument"), "-t");
1559 fstype = xstrdup(tmp);
1560 compile_fs_type(fstype, &fs_type_compiled);
1561 goto next_arg;
1562 case '-':
1563 opts_for_fsck++;
1564 break;
1565 case '?':
1566 usage();
1567 break;
1568 default:
1569 options[++opt] = arg[j];
1570 break;
1571 }
1572 }
1573 next_arg:
1574 if (opt) {
1575 options[0] = '-';
1576 options[++opt] = '\0';
1577 if (num_args >= MAX_ARGS)
1578 errx(FSCK_EX_ERROR, _("too many arguments"));
1579 args[num_args++] = xstrdup(options);
1580 opt = 0;
1581 }
1582 }
1583
1584 /* Validate the report stats file descriptor to avoid disasters */
1585 if (report_stats_fd >= 0) {
1586 report_stats_file = fdopen(report_stats_fd, "w");
1587 if (!report_stats_file)
1588 err(FSCK_EX_ERROR,
1589 _("invalid argument of -r: %d"),
1590 report_stats_fd);
1591 }
1592
1593 if (getenv("FSCK_FORCE_ALL_PARALLEL"))
1594 force_all_parallel++;
1595 if ((tmp = getenv("FSCK_MAX_INST")))
1596 max_running = atoi(tmp);
1597 }
1598
1599 int main(int argc, char *argv[])
1600 {
1601 int i, status = 0;
1602 int interactive = 0;
1603 struct libmnt_fs *fs;
1604 const char *path = getenv("PATH");
1605
1606 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
1607 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
1608
1609 setlocale(LC_MESSAGES, "");
1610 setlocale(LC_CTYPE, "");
1611 bindtextdomain(PACKAGE, LOCALEDIR);
1612 textdomain(PACKAGE);
1613 atexit(close_stdout);
1614
1615 mnt_init_debug(0); /* init libmount debug mask */
1616 mntcache = mnt_new_cache(); /* no fatal error if failed */
1617
1618 parse_argv(argc, argv);
1619
1620 if (!notitle)
1621 printf(UTIL_LINUX_VERSION);
1622
1623 load_fs_info();
1624
1625 fsck_path = xstrdup(path && *path ? path : FSCK_DEFAULT_PATH);
1626
1627 if ((num_devices == 1) || (serialize))
1628 interactive = 1;
1629
1630 if (lockdisk && (doall || num_devices > 1)) {
1631 warnx(_("the -l option can be used with one "
1632 "device only -- ignore"));
1633 lockdisk = 0;
1634 }
1635
1636 /* If -A was specified ("check all"), do that! */
1637 if (doall)
1638 return check_all();
1639
1640 if (num_devices == 0) {
1641 serialize++;
1642 interactive++;
1643 return check_all();
1644 }
1645 for (i = 0 ; i < num_devices; i++) {
1646 if (cancel_requested) {
1647 if (!kill_sent) {
1648 kill_all(SIGTERM);
1649 kill_sent++;
1650 }
1651 break;
1652 }
1653 fs = lookup(devices[i]);
1654 if (!fs)
1655 fs = add_dummy_fs(devices[i]);
1656 else if (fs_ignored_type(fs))
1657 continue;
1658 if (ignore_mounted && is_mounted(fs))
1659 continue;
1660 status |= fsck_device(fs, interactive);
1661 if (serialize ||
1662 (max_running && (num_running >= max_running))) {
1663 struct fsck_instance *inst;
1664
1665 inst = wait_one(0);
1666 if (inst) {
1667 status |= inst->exit_status;
1668 free_instance(inst);
1669 }
1670 if (verbose > 1)
1671 printf("----------------------------------\n");
1672 }
1673 }
1674 status |= wait_many(FLAG_WAIT_ALL);
1675 free(fsck_path);
1676 mnt_unref_cache(mntcache);
1677 mnt_unref_table(fstab);
1678 mnt_unref_table(mtab);
1679 return status;
1680 }