~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to fsck/fsck.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
#include <sys/types.h>
31
31
#include <sys/wait.h>
32
 
#include <sys/signal.h>
33
32
#include <sys/stat.h>
34
33
#include <sys/file.h>
35
34
#include <fcntl.h>
42
41
#include <paths.h>
43
42
#include <unistd.h>
44
43
#include <errno.h>
45
 
#include <malloc.h>
46
44
#include <signal.h>
47
45
#include <dirent.h>
48
46
#include <blkid.h>
52
50
#include "nls.h"
53
51
#include "pathnames.h"
54
52
#include "ismounted.h"
55
 
 
 
53
#include "c.h"
56
54
#include "fsck.h"
57
 
#include "c.h"
 
55
 
 
56
#define XALLOC_EXIT_CODE        EXIT_ERROR
 
57
#include "xalloc.h"
58
58
 
59
59
static const char *ignored_types[] = {
60
60
        "ignore",
106
106
int max_running = 0;
107
107
volatile int cancel_requested = 0;
108
108
int kill_sent = 0;
109
 
char *progname;
110
109
char *fstype = NULL;
111
110
struct fs_info *filesys_info = NULL, *filesys_last = NULL;
112
111
struct fsck_instance *instance_list;
119
118
 
120
119
        if (!s)
121
120
                return 0;
122
 
        ret = malloc(strlen(s)+1);
123
 
        if (ret)
124
 
                strcpy(ret, s);
 
121
        ret = xmalloc(strlen(s)+1);
 
122
        strcpy(ret, s);
125
123
        return ret;
126
124
}
127
125
 
242
240
                        "/sys/dev/block/%d:%d/queue/rotational",
243
241
                        major(disk), minor(disk));
244
242
 
245
 
        if (rc < 0 || rc + 1 > sizeof(path))
 
243
        if (rc < 0 || (unsigned int) (rc + 1) > sizeof(path))
246
244
                return 0;
247
245
 
248
246
        f = fopen(path, "r");
249
247
        if (!f)
250
248
                return 0;
251
249
 
252
 
        rc = fscanf(f, "%u", &x);
 
250
        rc = fscanf(f, "%d", &x);
 
251
        if (rc != 1) {
 
252
                if (ferror(f))
 
253
                        warn(_("failed to read: %s"), path);
 
254
                else
 
255
                        warnx(_("parse error: %s"), path);
 
256
        }
253
257
        fclose(f);
254
258
 
255
259
        return rc == 1 ? !x : 0;
257
261
 
258
262
static void lock_disk(struct fsck_instance *inst)
259
263
{
260
 
        dev_t disk = inst->fs->disk ? : get_disk(inst->fs->device);
 
264
        dev_t disk = inst->fs->disk ? inst->fs->disk : get_disk(inst->fs->device);
261
265
        char *diskname;
262
266
 
263
267
        if (!disk || is_irrotational_disk(disk))
287
291
        }
288
292
 
289
293
        if (verbose)
290
 
                printf("%s.\n", inst->lock >= 0 ? _("success") : _("failed"));
 
294
                /* TRANSLATORS: These are followups to "Locking disk...". */
 
295
                printf("%s.\n", inst->lock >= 0 ? _("succeeded") : _("failed"));
291
296
 
292
297
        free(diskname);
293
298
        return;
321
326
{
322
327
        struct fs_info *fs;
323
328
 
324
 
        if (!(fs = malloc(sizeof(struct fs_info))))
325
 
                return NULL;
 
329
        fs = xmalloc(sizeof(struct fs_info));
326
330
 
327
331
        fs->device = string_copy(device);
328
332
        fs->mountpt = string_copy(mntpnt);
417
421
        struct fs_info *fs;
418
422
 
419
423
        if ((f = fopen(filename, "r")) == NULL) {
420
 
                fprintf(stderr, _("WARNING: couldn't open %s: %s\n"),
421
 
                        filename, strerror(errno));
 
424
                warn(_("WARNING: couldn't open %s"), filename);
422
425
                return;
423
426
        }
424
427
        while (!feof(f)) {
427
430
                        break;
428
431
                buf[sizeof(buf)-1] = 0;
429
432
                if (parse_fstab_line(buf, &fs) < 0) {
430
 
                        fprintf(stderr, _("WARNING: bad format "
431
 
                                "on line %d of %s\n"), lineno, filename);
 
433
                        warnx(_("WARNING: bad format "
 
434
                                "on line %d of %s"), lineno, filename);
432
435
                        continue;
433
436
                }
434
437
                if (!fs)
442
445
        fclose(f);
443
446
 
444
447
        if (old_fstab && filesys_info) {
445
 
                fputs(_(
 
448
                warnx(_(
446
449
                "WARNING: Your /etc/fstab does not contain the fsck passno\n"
447
450
                "       field.  I will kludge around things for you, but you\n"
448
 
                "       should fix your /etc/fstab file as soon as you can.\n\n"), stderr);
 
451
                "       should fix your /etc/fstab file as soon as you can.\n"));
449
452
 
450
453
                for (fs = filesys_info; fs; fs = fs->next) {
451
454
                        fs->passno = 1;
515
518
        struct fsck_instance *inst, *p;
516
519
        pid_t   pid;
517
520
 
518
 
        inst = malloc(sizeof(struct fsck_instance));
519
 
        if (!inst)
520
 
                return ENOMEM;
 
521
        inst = xmalloc(sizeof(struct fsck_instance));
521
522
        memset(inst, 0, sizeof(struct fsck_instance));
522
523
 
523
524
        sprintf(prog, "fsck.%s", type);
550
551
 
551
552
        s = find_fsck(prog);
552
553
        if (s == NULL) {
553
 
                fprintf(stderr, _("fsck: %s: not found\n"), prog);
 
554
                warnx(_("%s: not found"), prog);
554
555
                free(inst);
555
556
                return ENOENT;
556
557
        }
670
671
                        if ((errno == EINTR) || (errno == EAGAIN))
671
672
                                continue;
672
673
                        if (errno == ECHILD) {
673
 
                                fprintf(stderr,
674
 
                                        _("%s: wait: No more child process?!?\n"),
675
 
                                        progname);
 
674
                                warnx(_("wait: no more child process?!?"));
676
675
                                return NULL;
677
676
                        }
678
677
                        perror("wait");
693
692
                if (sig == SIGINT) {
694
693
                        status = EXIT_UNCORRECTED;
695
694
                } else {
696
 
                        printf(_("Warning... %s for device %s exited "
697
 
                               "with signal %d.\n"),
 
695
                        warnx(_("Warning... %s for device %s exited "
 
696
                               "with signal %d."),
698
697
                               inst->prog, inst->fs->device, sig);
699
698
                        status = EXIT_ERROR;
700
699
                }
701
700
        } else {
702
 
                printf(_("%s %s: status is %x, should never happen.\n"),
 
701
                warnx(_("%s %s: status is %x, should never happen."),
703
702
                       inst->prog, inst->fs->device, status);
704
703
                status = EXIT_ERROR;
705
704
        }
724
723
                                if (fork() == 0) {
725
724
                                        sleep(1);
726
725
                                        kill(inst2->pid, SIGUSR1);
727
 
                                        exit(0);
 
726
                                        exit(EXIT_OK);
728
727
                                }
729
728
                        } else
730
729
                                kill(inst2->pid, SIGUSR1);
798
797
        num_running++;
799
798
        retval = execute(type, fs, interactive);
800
799
        if (retval) {
801
 
                fprintf(stderr, _("%s: Error %d while executing fsck.%s "
802
 
                        "for %s\n"), progname, retval, type, fs->device);
 
800
                warnx(_("error %d while executing fsck.%s for %s"),
 
801
                        retval, type, fs->device);
803
802
                num_running--;
804
803
                return EXIT_ERROR;
805
804
        }
820
819
#define FS_TYPE_OPT     1
821
820
#define FS_TYPE_NEGOPT  2
822
821
 
823
 
static const char *fs_type_syntax_error =
824
 
N_("Either all or none of the filesystem types passed to -t must be prefixed\n"
825
 
   "with 'no' or '!'.\n");
826
 
 
827
822
static void compile_fs_type(char *fs_type, struct fs_type_compile *cmp)
828
823
{
829
824
        char    *cp, *list, *s;
837
832
                }
838
833
        }
839
834
 
840
 
        cmp->list = malloc(num * sizeof(char *));
841
 
        cmp->type = malloc(num * sizeof(int));
842
 
        if (!cmp->list || !cmp->type) {
843
 
                fputs(_("Couldn't allocate memory for filesystem types\n"),
844
 
                      stderr);
845
 
                exit(EXIT_ERROR);
846
 
        }
 
835
        cmp->list = xmalloc(num * sizeof(char *));
 
836
        cmp->type = xmalloc(num * sizeof(int));
847
837
        memset(cmp->list, 0, num * sizeof(char *));
848
838
        memset(cmp->type, 0, num * sizeof(int));
849
839
        cmp->negate = 0;
877
867
                        }
878
868
                        if ((negate && !cmp->negate) ||
879
869
                            (!negate && cmp->negate)) {
880
 
                                fputs(_(fs_type_syntax_error), stderr);
881
 
                                exit(EXIT_USAGE);
 
870
                                errx(EXIT_USAGE,
 
871
                                        _("Either all or none of the filesystem types passed to -t must be prefixed\n"
 
872
                                          "with 'no' or '!'."));
882
873
                        }
883
874
                }
884
875
#if 0
885
876
                printf("Adding %s to list (type %d).\n", s, cmp->type[num]);
886
877
#endif
887
 
                cmp->list[num++] = string_copy(s);
 
878
                cmp->list[num++] = string_copy(s);
888
879
                s = strtok(NULL, ",");
889
880
        }
890
881
        free(list);
910
901
                }
911
902
                s = strtok(NULL, ",");
912
903
        }
913
 
        free(list);
 
904
        free(list);
914
905
        return 0;
915
906
}
916
907
 
978
969
         * If this is a bind mount, ignore it.
979
970
         */
980
971
        if (opt_in_list("bind", fs->opts)) {
981
 
                fprintf(stderr,
982
 
                        _("%s: skipping bad line in /etc/fstab: bind mount with nonzero fsck pass number\n"),
 
972
                warnx(_("%s: skipping bad line in /etc/fstab: "
 
973
                        "bind mount with nonzero fsck pass number"),
983
974
                        fs->mountpt);
984
975
                return 1;
985
976
        }
1022
1013
        /* See if the <fsck.fs> program is available. */
1023
1014
        if (find_fsck(fs->type) == NULL) {
1024
1015
                if (wanted)
1025
 
                        fprintf(stderr, _("fsck: cannot check %s: fsck.%s not found\n"),
 
1016
                        warnx(_("cannot check %s: fsck.%s not found"),
1026
1017
                                fs->device, fs->type);
1027
1018
                return 1;
1028
1019
        }
1217
1208
        return status;
1218
1209
}
1219
1210
 
1220
 
static void usage(NOARGS)
 
1211
static void __attribute__((__noreturn__)) usage(void)
1221
1212
{
1222
 
        fputs(_("Usage: fsck [-AMNPRTV] [ -C [ fd ] ] [-t fstype] [fs-options] [filesys ...]\n"), stderr);
 
1213
        printf(_("\nUsage:\n"
 
1214
                 " %s [fsck-options] [fs-options] [filesys ...]\n"),
 
1215
                program_invocation_short_name);
 
1216
 
 
1217
        puts(_( "\nOptions:\n"
 
1218
                " -A         check all filesystems\n"
 
1219
                " -R         skip root filesystem; useful only with `-A'\n"
 
1220
                " -M         do not check mounted filesystems\n"
 
1221
                " -t <type>  specify filesystem types to be checked;\n"
 
1222
                "              type is allowed to be comma-separated list\n"
 
1223
                " -P         check filesystems in parallel, including root\n"
 
1224
                " -s         serialize fsck operations\n"
 
1225
                " -l         lock the device using flock()\n"
 
1226
                " -N         do not execute, just show what would be done\n"
 
1227
                " -T         do not show the title on startup\n"
 
1228
                " -C <fd>    display progress bar; file descriptor is for GUIs\n"
 
1229
                " -V         explain what is being done\n"
 
1230
                " -?         display this help and exit\n\n"
 
1231
                "See fsck.* commands for fs-options."));
 
1232
 
1223
1233
        exit(EXIT_USAGE);
1224
1234
}
1225
1235
 
1249
1259
        num_args = 0;
1250
1260
        instance_list = 0;
1251
1261
 
1252
 
        progname = argv[0];
1253
 
 
1254
1262
        for (i=1; i < argc; i++) {
1255
1263
                arg = argv[i];
1256
1264
                if (!arg)
1257
1265
                        continue;
1258
1266
                if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) {
1259
 
                        if (num_devices >= MAX_DEVICES) {
1260
 
                                fprintf(stderr, _("%s: too many devices\n"),
1261
 
                                        progname);
1262
 
                                exit(EXIT_ERROR);
1263
 
                        }
 
1267
                        if (num_devices >= MAX_DEVICES)
 
1268
                                errx(EXIT_ERROR, _("too many devices"));
1264
1269
                        dev = fsprobe_get_devname_by_spec(arg);
1265
1270
                        if (!dev && strchr(arg, '=')) {
1266
1271
                                /*
1268
1273
                                 * /proc/partitions isn't found.
1269
1274
                                 */
1270
1275
                                if (access(_PATH_PROC_PARTITIONS, R_OK) < 0) {
1271
 
                                        fprintf(stderr, _("Couldn't open %s: %s\n"),
1272
 
                                                _PATH_PROC_PARTITIONS, strerror(errno));
1273
 
                                        fprintf(stderr, _("Is /proc mounted?\n"));
1274
 
                                        exit(EXIT_ERROR);
 
1276
                                        warn(_("couldn't open %s"),
 
1277
                                                _PATH_PROC_PARTITIONS);
 
1278
                                        errx(EXIT_ERROR, _("Is /proc mounted?"));
1275
1279
                                }
1276
1280
                                /*
1277
1281
                                 * Check to see if this is because
1278
1282
                                 * we're not running as root
1279
1283
                                 */
1280
1284
                                if (geteuid())
1281
 
                                        fprintf(stderr,
1282
 
                _("Must be root to scan for matching filesystems: %s\n"), arg);
 
1285
                                        errx(EXIT_ERROR,
 
1286
                                                _("must be root to scan for matching filesystems: %s"),
 
1287
                                                arg);
1283
1288
                                else
1284
 
                                        fprintf(stderr,
1285
 
                _("Couldn't find matching filesystem: %s\n"), arg);
1286
 
                                exit(EXIT_ERROR);
 
1289
                                        errx(EXIT_ERROR,
 
1290
                                                _("couldn't find matching filesystem: %s"),
 
1291
                                                arg);
1287
1292
                        }
1288
1293
                        devices[num_devices++] = dev ? dev : string_copy(arg);
1289
1294
                        continue;
1290
1295
                }
1291
1296
                if (arg[0] != '-' || opts_for_fsck) {
1292
 
                        if (num_args >= MAX_ARGS) {
1293
 
                                fprintf(stderr, _("%s: too many arguments\n"),
1294
 
                                        progname);
1295
 
                                exit(EXIT_ERROR);
1296
 
                        }
 
1297
                        if (num_args >= MAX_ARGS)
 
1298
                                errx(EXIT_ERROR, _("too many arguments"));
1297
1299
                        args[num_args++] = string_copy(arg);
1298
1300
                        continue;
1299
1301
                }
1304
1306
                        }
1305
1307
                        switch (arg[j]) {
1306
1308
                        case 'A':
1307
 
                                doall++;
 
1309
                                doall = 1;
1308
1310
                                break;
1309
1311
                        case 'C':
1310
 
                                progress++;
 
1312
                                progress = 1;
1311
1313
                                if (arg[j+1]) {
1312
1314
                                        progress_fd = string_to_int(arg+j+1);
1313
1315
                                        if (progress_fd < 0)
1326
1328
                                }
1327
1329
                                break;
1328
1330
                        case 'l':
1329
 
                                lockdisk++;
 
1331
                                lockdisk = 1;
1330
1332
                                break;
1331
1333
                        case 'V':
1332
1334
                                verbose++;
1333
1335
                                break;
1334
1336
                        case 'N':
1335
 
                                noexecute++;
 
1337
                                noexecute = 1;
1336
1338
                                break;
1337
1339
                        case 'R':
1338
 
                                skip_root++;
 
1340
                                skip_root = 1;
1339
1341
                                break;
1340
1342
                        case 'T':
1341
 
                                notitle++;
 
1343
                                notitle = 1;
1342
1344
                                break;
1343
1345
                        case 'M':
1344
 
                                ignore_mounted++;
 
1346
                                ignore_mounted = 1;
1345
1347
                                break;
1346
1348
                        case 'P':
1347
 
                                parallel_root++;
 
1349
                                parallel_root = 1;
1348
1350
                                break;
1349
1351
                        case 's':
1350
 
                                serialize++;
 
1352
                                serialize = 1;
1351
1353
                                break;
1352
1354
                        case 't':
1353
1355
                                tmp = 0;
1377
1379
                if (opt) {
1378
1380
                        options[0] = '-';
1379
1381
                        options[++opt] = '\0';
1380
 
                        if (num_args >= MAX_ARGS) {
1381
 
                                fprintf(stderr,
1382
 
                                        _("%s: too many arguments\n"),
1383
 
                                        progname);
1384
 
                                exit(EXIT_ERROR);
1385
 
                        }
 
1382
                        if (num_args >= MAX_ARGS)
 
1383
                                errx(EXIT_ERROR, _("too many arguments"));
1386
1384
                        args[num_args++] = string_copy(options);
1387
1385
                        opt = 0;
1388
1386
                }
1413
1411
        PRS(argc, argv);
1414
1412
 
1415
1413
        if (!notitle)
1416
 
                printf(_("fsck from %s\n"), PACKAGE_STRING);
 
1414
                printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING);
1417
1415
 
1418
1416
        fstab = getenv("FSTAB_FILE");
1419
1417
        if (!fstab)
1422
1420
 
1423
1421
        /* Update our search path to include uncommon directories. */
1424
1422
        if (oldpath) {
1425
 
                fsck_path = malloc (strlen (fsck_prefix_path) + 1 +
 
1423
                fsck_path = xmalloc (strlen (fsck_prefix_path) + 1 +
1426
1424
                                    strlen (oldpath) + 1);
1427
 
                if (!fsck_path) {
1428
 
                        fprintf(stderr, _("%s: Unable to allocate memory for fsck_path\n"), progname);
1429
 
                        exit(EXIT_ERROR);
1430
 
                }
1431
1425
                strcpy (fsck_path, fsck_prefix_path);
1432
1426
                strcat (fsck_path, ":");
1433
1427
                strcat (fsck_path, oldpath);
1439
1433
                interactive = 1;
1440
1434
 
1441
1435
        if (lockdisk && (doall || num_devices > 1)) {
1442
 
                fprintf(stderr, _("%s: the -l option can be used with one "
1443
 
                                  "device only -- ignore\n"), progname);
 
1436
                warnx(_("the -l option can be used with one "
 
1437
                                  "device only -- ignore"));
1444
1438
                lockdisk = 0;
1445
1439
        }
1446
1440