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