~daniel-mehrmann/e2fsprogs/master

« back to all changes in this revision

Viewing changes to .pc/git-update-to-3b0018beee/misc/fsck.c

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2012-06-14 13:01:21 UTC
  • mfrom: (8.4.18 sid)
  • Revision ID: package-import@ubuntu.com-20120614130121-t2gct0d09jepx0y6
Tags: 1.42.4-3ubuntu1
* Merge from Debian unstable (LP: #978012), remainging changes:
  - debian/control.in: 
      Build-depend on gettext:any instead of on gettext for (cross-building)
      Drop build dependency on dc, which hasn't been needed for some time.
      Update maintainer field.
  - debian/rules:
      Block pkg-create-dbgsym from operating on this package.
      Build without dietlibc-dev, which is in universe 
  - debian/control:
      Regenerate with ./debian/rules debian/control

Show diffs side-by-side

added added

removed removed

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