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