fsck.c revision 5e38fed9c5e5c0741ff00fc7001b44a075bfb64c
1ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/* 2ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj * pfsck --- A generic, parallelizing front-end for the fsck program. 3752f90673ebbb6b2f55fc5e46606dea371313713sewardj * It will automatically try to run fsck programs in parallel if the 4ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj * devices are on separate spindles. It is based on the same ideas as 5ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj * the generic front end for fsck by David Engel and Fred van Kempen, 6f8ed9d874a7b8651654591c68c6d431c758d787csewardj * but it has been completely rewritten from scratch to support 7752f90673ebbb6b2f55fc5e46606dea371313713sewardj * parallel execution. 8752f90673ebbb6b2f55fc5e46606dea371313713sewardj * 9f8ed9d874a7b8651654591c68c6d431c758d787csewardj * Written by Theodore Ts'o, <tytso@mit.edu> 1089ae8477745fd2a15453557d729a50e627325ee2sewardj * 11752f90673ebbb6b2f55fc5e46606dea371313713sewardj * Usage: fsck [-ACVRNTM] [-s] [-t fstype] [fs-options] device 127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj * 13752f90673ebbb6b2f55fc5e46606dea371313713sewardj * Miquel van Smoorenburg (miquels@drinkel.ow.org) 20-Oct-1994: 14752f90673ebbb6b2f55fc5e46606dea371313713sewardj * o Changed -t fstype to behave like with mount when -A (all file 15752f90673ebbb6b2f55fc5e46606dea371313713sewardj * systems) or -M (like mount) is specified. 16752f90673ebbb6b2f55fc5e46606dea371313713sewardj * o fsck looks if it can find the fsck.type program to decide 177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj * if it should ignore the fs type. This way more fsck programs 18752f90673ebbb6b2f55fc5e46606dea371313713sewardj * can be added without changing this front-end. 19752f90673ebbb6b2f55fc5e46606dea371313713sewardj * o -R flag skip root file system. 20752f90673ebbb6b2f55fc5e46606dea371313713sewardj * 21752f90673ebbb6b2f55fc5e46606dea371313713sewardj * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o. 22752f90673ebbb6b2f55fc5e46606dea371313713sewardj * 23752f90673ebbb6b2f55fc5e46606dea371313713sewardj * %Begin-Header% 24752f90673ebbb6b2f55fc5e46606dea371313713sewardj * This file may be redistributed under the terms of the GNU Public 25752f90673ebbb6b2f55fc5e46606dea371313713sewardj * License. 267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj * %End-Header% 277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj */ 28752f90673ebbb6b2f55fc5e46606dea371313713sewardj 29f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include <sys/types.h> 30f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include <sys/wait.h> 31f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include <sys/signal.h> 32f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include <sys/stat.h> 33f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include <limits.h> 34f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include <stdio.h> 35f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include <ctype.h> 36887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include <string.h> 37887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include <time.h> 38ac9af021b93dfe6f35c01d9c6fd15a3d67685843sewardj#if HAVE_STDLIB_H 39887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include <stdlib.h> 40ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj#endif 4157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#if HAVE_ERRNO_H 42ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj#include <errno.h> 4357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#endif 4457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#if HAVE_PATHS_H 4557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include <paths.h> 4657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#endif 4757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#if HAVE_UNISTD_H 4857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include <unistd.h> 4957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#endif 5057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#if HAVE_ERRNO_H 5157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include <errno.h> 5257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#endif 53dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#if HAVE_MALLOC_H 54dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include <malloc.h> 55dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#endif 56dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj 5757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "../version.h" 58dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "nls-enable.h" 5957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "fsck.h" 60dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "blkid/blkid.h" 6157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 62dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#ifndef _PATH_MNTTAB 63dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#define _PATH_MNTTAB "/etc/fstab" 64dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#endif 65dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj 6657c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic const char *ignored_types[] = { 6757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "ignore", 6857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "iso9660", 6957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "nfs", 7057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "proc", 7157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "sw", 7257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "swap", 7357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "tmpfs", 7457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "devpts", 7557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj NULL 7657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj}; 7757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 7857c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic const char *really_wanted[] = { 7957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "minix", 8057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "ext2", 8157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "ext3", 8257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "jfs", 8357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "reiserfs", 8457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "xiafs", 8557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj "xfs", 8657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj NULL 8757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj}; 8857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 8957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#define BASE_MD "/dev/md" 9057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 9157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* 9257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * Global variables for options 93dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj */ 94dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjchar *devices[MAX_DEVICES]; 95dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjchar *args[MAX_ARGS]; 96dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjint num_devices, num_args; 97dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj 9857c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint verbose = 0; 9957c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint doall = 0; 10057c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint noexecute = 0; 10157c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint serialize = 0; 10257c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint skip_root = 0; 10357c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint like_mount = 0; 10457c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint notitle = 0; 10557c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint parallel_root = 0; 10657c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint progress = 0; 1072f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardjint force_all_parallel = 0; 10857c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint num_running = 0; 10957c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint max_running = 0; 11057c10c89904f7fdc4244fcbf704625e7169aafe6sewardjvolatile int cancel_requested = 0; 11157c10c89904f7fdc4244fcbf704625e7169aafe6sewardjint kill_sent = 0; 11257c10c89904f7fdc4244fcbf704625e7169aafe6sewardjchar *progname; 11357c10c89904f7fdc4244fcbf704625e7169aafe6sewardjchar *fstype = NULL; 11457c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstruct fs_info *filesys_info = NULL, *filesys_last = NULL; 11557c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstruct fsck_instance *instance_list; 11657c10c89904f7fdc4244fcbf704625e7169aafe6sewardjconst char *fsck_prefix_path = "/sbin:/sbin/fs.d:/sbin/fs:/etc/fs:/etc"; 11757c10c89904f7fdc4244fcbf704625e7169aafe6sewardjchar *fsck_path = 0; 11857c10c89904f7fdc4244fcbf704625e7169aafe6sewardjblkid_cache cache = NULL; 11957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 12057c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic char *string_copy(const char *s) 12157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{ 12257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj char *ret; 12357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 12457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (!s) 12557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return 0; 12657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj ret = malloc(strlen(s)+1); 12757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (ret) 12857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj strcpy(ret, s); 12957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return ret; 13057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj} 13157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 13257c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic int ignore(struct fs_info *); 13357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 13457c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic char *skip_over_blank(char *cp) 13557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{ 13657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj while (*cp && isspace(*cp)) 13757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj cp++; 13857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return cp; 13957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj} 14057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 14157c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic char *skip_over_word(char *cp) 14257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{ 14357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj while (*cp && !isspace(*cp)) 14457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj cp++; 14557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return cp; 14657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj} 14757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 14857c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic void strip_line(char *line) 14957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{ 1502f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj char *p; 15157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 15257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj while (*line) { 15357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj p = line + strlen(line) - 1; 15457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if ((*p == '\n') || (*p == '\r')) 15557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj *p = 0; 15657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj else 15757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj break; 15857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj } 15957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj} 16057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 16157c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic char *parse_word(char **buf) 16257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{ 16357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj char *word, *next; 16457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 16557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj word = *buf; 16657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (*word == 0) 16757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return 0; 16857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 16957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj word = skip_over_blank(word); 170dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj next = skip_over_word(word); 17157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (*next) 17257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj *next++ = 0; 17357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj *buf = next; 17457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return word; 17557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj} 17657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 17757c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic void parse_escape(char *word) 17857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{ 17957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj char *p, *q; 18057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj int ac, i; 18157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 18257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (!word) 18357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return; 18457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 18557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj for (p = word, q = word; *p; p++, q++) { 18657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj *q = *p; 18757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (*p != '\\') 188ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj continue; 189ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj if (*++p == 0) 190ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj break; 191496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj if (*p == 't') { 192496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj *q = '\t'; 193496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj continue; 194496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj } 195496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj if (*p == 'n') { 196496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj *q = '\n'; 197496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj continue; 198496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj } 199496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj if (!isdigit(*p)) { 200496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj *q = *p; 201496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj continue; 202496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj } 203496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj ac = 0; 204dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj for (i = 0; i < 3; i++, p++) { 205496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj if (!isdigit(*p)) 206f6c8ebf1294fea43756683ba7089b746168abb8esewardj break; 207f6c8ebf1294fea43756683ba7089b746168abb8esewardj ac = (ac * 8) + (*p - '0'); 208496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj } 209dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj *q = ac; 210496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj p--; 211f6c8ebf1294fea43756683ba7089b746168abb8esewardj } 212f6c8ebf1294fea43756683ba7089b746168abb8esewardj *q = 0; 213496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj} 214496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj 215c97096c44637ae5775ed305b19f16f0b505f17d8sewardjstatic void free_instance(struct fsck_instance *i) 216e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj{ 21757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (i->prog) 21857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj free(i->prog); 219e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj if (i->device) 220c9a43665879a03886b27a65b68af2a2c11b04f59sewardj free(i->device); 221cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (i->base_device) 222c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj free(i->base_device); 223c9a43665879a03886b27a65b68af2a2c11b04f59sewardj free(i); 224c9a43665879a03886b27a65b68af2a2c11b04f59sewardj return; 225c9a43665879a03886b27a65b68af2a2c11b04f59sewardj} 226c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 2279b96767debeeb1f78378f0e7e295fe6762c64002sewardjstatic struct fs_info *create_fs_device(const char *device, const char *mntpnt, 228c9a43665879a03886b27a65b68af2a2c11b04f59sewardj const char *type, const char *opts, 229c9a43665879a03886b27a65b68af2a2c11b04f59sewardj int freq, int passno) 230c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{ 231c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj struct fs_info *fs; 232c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj 2332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (!(fs = malloc(sizeof(struct fs_info)))) 234c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj return NULL; 235c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj 236d1725d18b61bf7912a9099686179faef5815dba1sewardj fs->device = string_copy(device); 237e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj fs->mountpt = string_copy(mntpnt); 238e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj fs->type = string_copy(type); 23957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj fs->opts = string_copy(opts ? opts : ""); 24035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj fs->freq = freq; 24157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj fs->passno = passno; 24257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj fs->flags = 0; 24357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj fs->next = NULL; 244c97096c44637ae5775ed305b19f16f0b505f17d8sewardj 2457d00913f2ac5014a145a899b6ee4b8511539221fsewardj if (!filesys_info) 2467d00913f2ac5014a145a899b6ee4b8511539221fsewardj filesys_info = fs; 2477d00913f2ac5014a145a899b6ee4b8511539221fsewardj else 2487d00913f2ac5014a145a899b6ee4b8511539221fsewardj filesys_last->next = fs; 249e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj filesys_last = fs; 250af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj 251af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj return fs; 25257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj} 253af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj 254af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj 255cfe046e178666280b87da998b1b52ecda03ecd89sewardj 256c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardjstatic int parse_fstab_line(char *line, struct fs_info **ret_fs) 257af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj{ 258af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj char *dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp; 259af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj struct fs_info *fs; 260af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj 261c97096c44637ae5775ed305b19f16f0b505f17d8sewardj *ret_fs = 0; 262ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj strip_line(line); 26357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if ((cp = strchr(line, '#'))) 26457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj *cp = 0; /* Ignore everything after the comment char */ 26557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj cp = line; 266ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj 267c9a43665879a03886b27a65b68af2a2c11b04f59sewardj device = parse_word(&cp); 268cfe046e178666280b87da998b1b52ecda03ecd89sewardj mntpnt = parse_word(&cp); 269c9a43665879a03886b27a65b68af2a2c11b04f59sewardj type = parse_word(&cp); 270c9a43665879a03886b27a65b68af2a2c11b04f59sewardj opts = parse_word(&cp); 271c9a43665879a03886b27a65b68af2a2c11b04f59sewardj freq = parse_word(&cp); 272c9a43665879a03886b27a65b68af2a2c11b04f59sewardj passno = parse_word(&cp); 2732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (!device) 2752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return 0; /* Allow blank lines */ 2761e6ad745ebafd0524da1da27a4b85524fa84f777sewardj 2771e6ad745ebafd0524da1da27a4b85524fa84f777sewardj if (!mntpnt || !type) 2781e6ad745ebafd0524da1da27a4b85524fa84f777sewardj return -1; 27937a505b5a6814921fcfff1eac950a9ef7651e42bsewardj 28057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj parse_escape(device); 28137a505b5a6814921fcfff1eac950a9ef7651e42bsewardj parse_escape(mntpnt); 28237a505b5a6814921fcfff1eac950a9ef7651e42bsewardj parse_escape(type); 283207557ab2ea38239b670785c976b89d50bbb0eccsewardj parse_escape(opts); 284ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj parse_escape(freq); 285ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj parse_escape(passno); 28657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 28757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj dev = blkid_get_devname(cache, device, NULL); 28857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (dev) 28957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj device = dev; 290ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj 291e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj if (strchr(type, ',')) 292ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj type = 0; 293ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj 294ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj fs = create_fs_device(device, mntpnt, type ? type : "auto", opts, 295c97096c44637ae5775ed305b19f16f0b505f17d8sewardj freq ? atoi(freq) : -1, 296c97096c44637ae5775ed305b19f16f0b505f17d8sewardj passno ? atoi(passno) : -1); 297c97096c44637ae5775ed305b19f16f0b505f17d8sewardj if (dev) 298c97096c44637ae5775ed305b19f16f0b505f17d8sewardj free(dev); 2992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 3002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (!fs) 301a58ea668d4725b87a146cf43cc48b8ea6ead84casewardj return -1; 30217442fe8094d0f82266e5a05509f62cac8f7539esewardj *ret_fs = fs; 30357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return 0; 30437a505b5a6814921fcfff1eac950a9ef7651e42bsewardj} 305ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj 306ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardjstatic void interpret_type(struct fs_info *fs) 307ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj{ 308ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj char *t; 30957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 310ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj if (strcmp(fs->type, "auto") != 0) 31117442fe8094d0f82266e5a05509f62cac8f7539esewardj return; 31217442fe8094d0f82266e5a05509f62cac8f7539esewardj t = blkid_get_tag_value(cache, "TYPE", fs->device); 31317442fe8094d0f82266e5a05509f62cac8f7539esewardj if (t) { 31417442fe8094d0f82266e5a05509f62cac8f7539esewardj free(fs->type); 3152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj fs->type = t; 3162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 31717442fe8094d0f82266e5a05509f62cac8f7539esewardj} 31817442fe8094d0f82266e5a05509f62cac8f7539esewardj 3191e6ad745ebafd0524da1da27a4b85524fa84f777sewardj/* 32037a505b5a6814921fcfff1eac950a9ef7651e42bsewardj * Load the filesystem database from /etc/fstab 321c97096c44637ae5775ed305b19f16f0b505f17d8sewardj */ 32257c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic void load_fs_info(const char *filename) 323dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj{ 324695cff9303ef5dc8079117acfd632b44edb1f010sewardj FILE *f; 32557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj char buf[1024]; 32635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj int lineno = 0; 32757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj int old_fstab = 1; 32857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj struct fs_info *fs; 3294345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 330ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj if ((f = fopen(filename, "r")) == NULL) { 331c97096c44637ae5775ed305b19f16f0b505f17d8sewardj fprintf(stderr, _("WARNING: couldn't open %s: %s\n"), 3328ea867b06de73d909c29e243407713c291c8414esewardj filename, strerror(errno)); 3338ea867b06de73d909c29e243407713c291c8414esewardj return; 3348ea867b06de73d909c29e243407713c291c8414esewardj } 33577352545d8416a36a4e6310aaea6b0205508aea2sewardj while (!feof(f)) { 3368ea867b06de73d909c29e243407713c291c8414esewardj lineno++; 33703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj if (!fgets(buf, sizeof(buf), f)) 33803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj break; 33903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj buf[sizeof(buf)-1] = 0; 34003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj if (parse_fstab_line(buf, &fs) < 0) { 34143c56461a667ca81fe29f1db01450d6ff1d62949sewardj fprintf(stderr, _("WARNING: bad format " 34243c56461a667ca81fe29f1db01450d6ff1d62949sewardj "on line %d of %s\n"), lineno, filename); 34343c56461a667ca81fe29f1db01450d6ff1d62949sewardj continue; 34443c56461a667ca81fe29f1db01450d6ff1d62949sewardj } 34543c56461a667ca81fe29f1db01450d6ff1d62949sewardj if (!fs) 34643c56461a667ca81fe29f1db01450d6ff1d62949sewardj continue; 34743c56461a667ca81fe29f1db01450d6ff1d62949sewardj if (fs->passno < 0) 3488ea867b06de73d909c29e243407713c291c8414esewardj fs->passno = 0; 3498ea867b06de73d909c29e243407713c291c8414esewardj else 3508ea867b06de73d909c29e243407713c291c8414esewardj old_fstab = 0; 3511ff4756e1731485e6bf3cd96717cd8398daec1f2florian } 3521ff4756e1731485e6bf3cd96717cd8398daec1f2florian 3531ff4756e1731485e6bf3cd96717cd8398daec1f2florian fclose(f); 3541ff4756e1731485e6bf3cd96717cd8398daec1f2florian 3558ea867b06de73d909c29e243407713c291c8414esewardj if (old_fstab) { 3568ea867b06de73d909c29e243407713c291c8414esewardj fprintf(stderr, _("\007\007\007" 3578ea867b06de73d909c29e243407713c291c8414esewardj "WARNING: Your /etc/fstab does not contain the fsck passno\n" 35857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj " field. I will kludge around things for you, but you\n" 3591ff4756e1731485e6bf3cd96717cd8398daec1f2florian " should fix your /etc/fstab file as soon as you can.\n\n")); 3608ea867b06de73d909c29e243407713c291c8414esewardj 36157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj for (fs = filesys_info; fs; fs = fs->next) { 362dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj fs->passno = 1; 3638ea867b06de73d909c29e243407713c291c8414esewardj } 36457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj } 3658ea867b06de73d909c29e243407713c291c8414esewardj} 3668ea867b06de73d909c29e243407713c291c8414esewardj 3678ea867b06de73d909c29e243407713c291c8414esewardj/* Lookup filesys in /etc/fstab and return the corresponding entry. */ 3682d3f77c12d2911173fd182d0b6e954196dee9135sewardjstatic struct fs_info *lookup(char *filesys) 3692d3f77c12d2911173fd182d0b6e954196dee9135sewardj{ 37057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj struct fs_info *fs; 37157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 37257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj /* No filesys name given. */ 3732d3f77c12d2911173fd182d0b6e954196dee9135sewardj if (filesys == NULL) 3742d3f77c12d2911173fd182d0b6e954196dee9135sewardj return NULL; 37557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 37657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj for (fs = filesys_info; fs; fs = fs->next) { 37757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (!strcmp(filesys, fs->device) || 3782d3f77c12d2911173fd182d0b6e954196dee9135sewardj (fs->mountpt && !strcmp(filesys, fs->mountpt))) 379dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj break; 3802d3f77c12d2911173fd182d0b6e954196dee9135sewardj } 381dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj 3822d3f77c12d2911173fd182d0b6e954196dee9135sewardj return fs; 383dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj} 384695cff9303ef5dc8079117acfd632b44edb1f010sewardj 385dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Find fsck program for a given fs type. */ 386dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic char *find_fsck(char *type) 3872d3f77c12d2911173fd182d0b6e954196dee9135sewardj{ 3882d3f77c12d2911173fd182d0b6e954196dee9135sewardj char *s; 389c97096c44637ae5775ed305b19f16f0b505f17d8sewardj const char *tpl; 390ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj static char prog[256]; 39157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj char *p = string_copy(fsck_path); 39257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj struct stat st; 39357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 394fbcaf3312f39fb73d54821636c6168db76245f61sewardj /* Are we looking for a program or just a type? */ 395ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj tpl = (strncmp(type, "fsck.", 5) ? "%s/fsck.%s" : "%s/%s"); 39657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 39735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj for(s = strtok(p, ":"); s; s = strtok(NULL, ":")) { 398c97096c44637ae5775ed305b19f16f0b505f17d8sewardj sprintf(prog, tpl, s, type); 39992d168d0f2a985ed9f7ae4e6bba9565a13921b31sewardj if (stat(prog, &st) == 0) break; 400fbcaf3312f39fb73d54821636c6168db76245f61sewardj } 401ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj free(p); 40240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj return(s ? prog : NULL); 403ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj} 40457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 40557c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic int progress_active(NOARGS) 40657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{ 40757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj struct fsck_instance *inst; 40857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj 40957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj for (inst = instance_list; inst; inst = inst->next) { 41057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (inst->flags & FLAG_DONE) 41157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj continue; 41257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (inst->flags & FLAG_PROGRESS) 41357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj return 1; 414ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj } 41541f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj return 0; 41671a35e7351fc1202ef2960d3f0315d9181624fe2sewardj} 41771a35e7351fc1202ef2960d3f0315d9181624fe2sewardj 41871a35e7351fc1202ef2960d3f0315d9181624fe2sewardj/* 419cfe046e178666280b87da998b1b52ecda03ecd89sewardj * Execute a particular fsck program, and link it into the list of 42066de22767fc526eff52133c18d4a42a9b25d5f18sewardj * child processes we are waiting for. 42141f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj */ 42241f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardjstatic int execute(const char *type, const char *device, const char *mntpt, 42341f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj int interactive) 42441f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj{ 42541f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj char *s, *argv[80], prog[80]; 42641f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj int argc, i; 42741f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj struct fsck_instance *inst, *p; 42841f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj pid_t pid; 42941f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 430e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj inst = malloc(sizeof(struct fsck_instance)); 431e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj if (!inst) 432e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj return ENOMEM; 43341f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj memset(inst, 0, sizeof(struct fsck_instance)); 43441f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 43571a35e7351fc1202ef2960d3f0315d9181624fe2sewardj sprintf(prog, "fsck.%s", type); 4361fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj argv[0] = string_copy(prog); 4371fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj argc = 1; 4381fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj 4391fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj for (i=0; i <num_args; i++) 4401fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj argv[argc++] = string_copy(args[i]); 4411fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj 4421fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj if (progress & !progress_active()) { 4431fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj if ((strcmp(type, "ext2") == 0) || 444e13074c2c1321d069fb95806bdce64f9a3512341sewardj (strcmp(type, "ext3") == 0)) { 445e13074c2c1321d069fb95806bdce64f9a3512341sewardj argv[argc++] = string_copy("-C0"); 446e13074c2c1321d069fb95806bdce64f9a3512341sewardj inst->flags |= FLAG_PROGRESS; 447e13074c2c1321d069fb95806bdce64f9a3512341sewardj } 44871a35e7351fc1202ef2960d3f0315d9181624fe2sewardj } 44971a35e7351fc1202ef2960d3f0315d9181624fe2sewardj 4509690d927540d730525a5f7f14663f3ceaa7818dasewardj argv[argc++] = string_copy(device); 4519b96767debeeb1f78378f0e7e295fe6762c64002sewardj argv[argc] = 0; 4529b96767debeeb1f78378f0e7e295fe6762c64002sewardj 4538f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj s = find_fsck(prog); 454ce646f23d71ac432c340667387aa4a5ce7d18099sewardj if (s == NULL) { 455f53b7359a342e7d79090615169c6583a1a75fbcesewardj fprintf(stderr, _("fsck: %s: not found\n"), prog); 456f53b7359a342e7d79090615169c6583a1a75fbcesewardj return ENOENT; 457f53b7359a342e7d79090615169c6583a1a75fbcesewardj } 458f53b7359a342e7d79090615169c6583a1a75fbcesewardj 4598f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj if (verbose || noexecute) { 4608f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj printf("[%s (%d) -- %s] ", s, num_running, 461b51f0f4f33256638ed953156a2635aa739b232f1sewardj mntpt ? mntpt : device); 4629854007808ab24cad3f971eab63face1cb1e6089sewardj for (i=0; i < argc; i++) 4639854007808ab24cad3f971eab63face1cb1e6089sewardj printf("%s ", argv[i]); 4649854007808ab24cad3f971eab63face1cb1e6089sewardj printf("\n"); 4659854007808ab24cad3f971eab63face1cb1e6089sewardj } 466343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj 4670033ddccac6f90789fe2e78e86b8a649931d77b4sewardj /* Fork and execute the correct program. */ 4680033ddccac6f90789fe2e78e86b8a649931d77b4sewardj if (noexecute) 469eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj pid = -1; 470eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj else if ((pid = fork()) < 0) { 471478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj perror("fork"); 4720033ddccac6f90789fe2e78e86b8a649931d77b4sewardj return errno; 47357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj } else if (pid == 0) { 47457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj if (!interactive) 475b51f0f4f33256638ed953156a2635aa739b232f1sewardj close(0); 476b51f0f4f33256638ed953156a2635aa739b232f1sewardj (void) execv(s, argv); 477b51f0f4f33256638ed953156a2635aa739b232f1sewardj perror(argv[0]); 478b51f0f4f33256638ed953156a2635aa739b232f1sewardj exit(EXIT_ERROR); 4792831b00c4950d6c2b061def05fd67528fe132ececerion } 4802831b00c4950d6c2b061def05fd67528fe132ececerion 481b51f0f4f33256638ed953156a2635aa739b232f1sewardj for (i=0; i < argc; i++) 4829690d927540d730525a5f7f14663f3ceaa7818dasewardj free(argv[i]); 4838f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj 4845c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion inst->pid = pid; 4855c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion inst->prog = string_copy(prog); 486f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion inst->type = string_copy(type); 487f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion inst->device = string_copy(device); 4888b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj inst->base_device = base_device(device); 4898b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj inst->start_time = time(0); 490e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj inst->next = NULL; 4918b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj 4928b1715b543b95a21be7f7aa27149cb3e4570cb61sewardj /* 493e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj * Find the end of the list, so we add the instance on at the end. 4945c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion */ 4959690d927540d730525a5f7f14663f3ceaa7818dasewardj for (p = instance_list; p && p->next; p = p->next); 4969690d927540d730525a5f7f14663f3ceaa7818dasewardj 4979690d927540d730525a5f7f14663f3ceaa7818dasewardj if (p) 49889d4e9828ce36532c957566ebb46947109a7b53dsewardj p->next = inst; 499343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj else 500343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj instance_list = inst; 501343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj 502343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj return 0; 5032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 5042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 5052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* 5060033ddccac6f90789fe2e78e86b8a649931d77b4sewardj * Send a signal to all outstanding fsck child processes 5070033ddccac6f90789fe2e78e86b8a649931d77b4sewardj */ 5080033ddccac6f90789fe2e78e86b8a649931d77b4sewardjstatic int kill_all(int signum) 5090033ddccac6f90789fe2e78e86b8a649931d77b4sewardj{ 5100033ddccac6f90789fe2e78e86b8a649931d77b4sewardj struct fsck_instance *inst; 5119690d927540d730525a5f7f14663f3ceaa7818dasewardj int n = 0; 5120033ddccac6f90789fe2e78e86b8a649931d77b4sewardj 5130033ddccac6f90789fe2e78e86b8a649931d77b4sewardj for (inst = instance_list; inst; inst = inst->next) { 5140033ddccac6f90789fe2e78e86b8a649931d77b4sewardj if (inst->flags & FLAG_DONE) 5150033ddccac6f90789fe2e78e86b8a649931d77b4sewardj continue; 5160033ddccac6f90789fe2e78e86b8a649931d77b4sewardj kill(inst->pid, signum); 5170033ddccac6f90789fe2e78e86b8a649931d77b4sewardj n++; 5180033ddccac6f90789fe2e78e86b8a649931d77b4sewardj } 519a238471814bd386aeb58a76718b41e68b1a794b2sewardj return n; 5200033ddccac6f90789fe2e78e86b8a649931d77b4sewardj} 521b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj 522b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj/* 523b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj * Wait for one child process to exit; when it does, unlink it from 524b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj * the list of executing child processes, and return it. 5258c7f1abe9e022f6382634efea09c9cac89ec6336sewardj */ 5268c7f1abe9e022f6382634efea09c9cac89ec6336sewardjstatic struct fsck_instance *wait_one(int flags) 5278c7f1abe9e022f6382634efea09c9cac89ec6336sewardj{ 5288c7f1abe9e022f6382634efea09c9cac89ec6336sewardj int status; 5299690d927540d730525a5f7f14663f3ceaa7818dasewardj int sig; 5308c7f1abe9e022f6382634efea09c9cac89ec6336sewardj struct fsck_instance *inst, *inst2, *prev; 5319690d927540d730525a5f7f14663f3ceaa7818dasewardj pid_t pid; 5329690d927540d730525a5f7f14663f3ceaa7818dasewardj 5339b96767debeeb1f78378f0e7e295fe6762c64002sewardj if (!instance_list) 5349b96767debeeb1f78378f0e7e295fe6762c64002sewardj return NULL; 5359b96767debeeb1f78378f0e7e295fe6762c64002sewardj 5369b96767debeeb1f78378f0e7e295fe6762c64002sewardj if (noexecute) { 537cf780b4c356a274cc48a6829963f8bc79a1b34e8sewardj inst = instance_list; 5386e797c5fbd90ecc6531f9d8c4929848664a13714sewardj prev = 0; 53984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj#ifdef RANDOM_DEBUG 540291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj while (inst->next && (random() & 1)) { 541291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj prev = inst; 54284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj inst = inst->next; 543291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj } 544fd33277c458b31596eb4fb15959467ac047c75dasewardj#endif 5458eda6304ecfaa1d0aa70773a2c07f996717f8f54sewardj inst->exit_status = 0; 546cf7879021370aabcccb1a9347244fcc7d5680141sewardj goto ret_inst; 547b5874aa03bb38bf754aa8c1cb1e400f3d7e86b9fsewardj } 5488f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj 549baf971ad7f6e005109f3301ec9d19c98066b3840sewardj /* 5508f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj * gcc -Wall fails saving throw against stupidity 551b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj * (inst and prev are thought to be uninitialized variables) 552cfded9ab7c059881ecdbe967ddfcc1ce207986casewardj */ 553b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj inst = prev = NULL; 554b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 555b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj do { 55652ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardj pid = waitpid(-1, &status, flags); 5576c299f3acab617581ea504e45fbb6cab24c2b29fsewardj if (cancel_requested && !kill_sent) { 5586c299f3acab617581ea504e45fbb6cab24c2b29fsewardj kill_all(SIGTERM); 5596c299f3acab617581ea504e45fbb6cab24c2b29fsewardj kill_sent++; 560b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj } 561b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj if ((pid == 0) && (flags & WNOHANG)) 562b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj return NULL; 563b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj if (pid < 0) { 56452ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardj if ((errno == EINTR) || (errno == EAGAIN)) 565b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj continue; 566b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj if (errno == ECHILD) { 567b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj fprintf(stderr, 5688f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj _("%s: wait: No more child process?!?\n"), 5696c299f3acab617581ea504e45fbb6cab24c2b29fsewardj progname); 5706c299f3acab617581ea504e45fbb6cab24c2b29fsewardj return NULL; 5716c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } 572b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj perror("wait"); 573b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj continue; 5746d52228c83cccffb6cadf7f0cdfe34df057b6fefflorian } 575baf971ad7f6e005109f3301ec9d19c98066b3840sewardj for (prev = 0, inst = instance_list; 5766c299f3acab617581ea504e45fbb6cab24c2b29fsewardj inst; 5776c299f3acab617581ea504e45fbb6cab24c2b29fsewardj prev = inst, inst = inst->next) { 5786c299f3acab617581ea504e45fbb6cab24c2b29fsewardj if (inst->pid == pid) 5798f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj break; 580883b00b3d97a9873371557d7b1f2ac5db7985e43sewardj } 5818f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj } while (!inst); 5828f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj 583883b00b3d97a9873371557d7b1f2ac5db7985e43sewardj if (WIFEXITED(status)) 5848f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj status = WEXITSTATUS(status); 5858f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj else if (WIFSIGNALED(status)) { 5868f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj sig = WTERMSIG(status); 5876c299f3acab617581ea504e45fbb6cab24c2b29fsewardj if (sig == SIGINT) { 5888f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj status = EXIT_UNCORRECTED; 5892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 5902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj printf(_("Warning... %s for device %s exited " 5918f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj "with signal %d.\n"), 5923bca906f6e715c544eb49c278bedef093c14c0d7sewardj inst->prog, inst->device, sig); 593b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj status = EXIT_ERROR; 5946c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } 5956c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } else { 5966c299f3acab617581ea504e45fbb6cab24c2b29fsewardj printf(_("%s %s: status is %x, should never happen.\n"), 5976c299f3acab617581ea504e45fbb6cab24c2b29fsewardj inst->prog, inst->device, status); 5988f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj status = EXIT_ERROR; 5998f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj } 6008f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj inst->exit_status = status; 6018f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj if (progress && (inst->flags & FLAG_PROGRESS) && 6028f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj !progress_active()) { 6038f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj for (inst2 = instance_list; inst2; inst2 = inst2->next) { 6048f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj if (inst2->flags & FLAG_DONE) 6058f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj continue; 6068f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj if (strcmp(inst2->type, "ext2") && 6078f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj strcmp(inst2->type, "ext3")) 6088f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj continue; 6096c299f3acab617581ea504e45fbb6cab24c2b29fsewardj /* 6106c299f3acab617581ea504e45fbb6cab24c2b29fsewardj * If we've just started the fsck, wait a tiny 6116c299f3acab617581ea504e45fbb6cab24c2b29fsewardj * bit before sending the kill, to give it 6126c299f3acab617581ea504e45fbb6cab24c2b29fsewardj * time to set up the signal handler 6136c299f3acab617581ea504e45fbb6cab24c2b29fsewardj */ 6146c299f3acab617581ea504e45fbb6cab24c2b29fsewardj if (inst2->start_time < time(0)+2) { 6156c299f3acab617581ea504e45fbb6cab24c2b29fsewardj if (fork() == 0) { 6166c299f3acab617581ea504e45fbb6cab24c2b29fsewardj sleep(1); 6176c299f3acab617581ea504e45fbb6cab24c2b29fsewardj kill(inst2->pid, SIGUSR1); 6188f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj exit(0); 6198f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj } 6208f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj } else 6216c299f3acab617581ea504e45fbb6cab24c2b29fsewardj kill(inst2->pid, SIGUSR1); 6226c299f3acab617581ea504e45fbb6cab24c2b29fsewardj inst2->flags |= FLAG_PROGRESS; 6236c299f3acab617581ea504e45fbb6cab24c2b29fsewardj break; 6246c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } 6256c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } 6266c299f3acab617581ea504e45fbb6cab24c2b29fsewardjret_inst: 6276c299f3acab617581ea504e45fbb6cab24c2b29fsewardj if (prev) 6286c299f3acab617581ea504e45fbb6cab24c2b29fsewardj prev->next = inst->next; 6293bca906f6e715c544eb49c278bedef093c14c0d7sewardj else 6303bca906f6e715c544eb49c278bedef093c14c0d7sewardj instance_list = inst->next; 6313bca906f6e715c544eb49c278bedef093c14c0d7sewardj if (verbose > 1) 6328f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj printf(_("Finished with %s (exit status %d)\n"), 6336c299f3acab617581ea504e45fbb6cab24c2b29fsewardj inst->device, inst->exit_status); 6346c299f3acab617581ea504e45fbb6cab24c2b29fsewardj num_running--; 6356c299f3acab617581ea504e45fbb6cab24c2b29fsewardj return inst; 6364aa412af1d8166cc11f39a6e721df49431d23618sewardj} 6376c299f3acab617581ea504e45fbb6cab24c2b29fsewardj 6386c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#define FLAG_WAIT_ALL 0 6396c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#define FLAG_WAIT_ATLEAST_ONE 1 6406c299f3acab617581ea504e45fbb6cab24c2b29fsewardj/* 6416c299f3acab617581ea504e45fbb6cab24c2b29fsewardj * Wait until all executing child processes have exited; return the 64266d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj * logical OR of all of their exit code values. 64366d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj */ 64452ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardjstatic int wait_many(int flags) 6451c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian{ 6466c299f3acab617581ea504e45fbb6cab24c2b29fsewardj struct fsck_instance *inst; 6473bca906f6e715c544eb49c278bedef093c14c0d7sewardj int global_status = 0; 6482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj int wait_flags = 0; 6492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 6501c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian while ((inst = wait_one(wait_flags))) { 6511c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian global_status |= inst->exit_status; 6522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj free_instance(inst); 6532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#ifdef RANDOM_DEBUG 6542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (noexecute && (flags & WNOHANG) && !(random() % 3)) 6552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj break; 6566c299f3acab617581ea504e45fbb6cab24c2b29fsewardj#endif 6573bca906f6e715c544eb49c278bedef093c14c0d7sewardj if (flags & FLAG_WAIT_ATLEAST_ONE) 6583bca906f6e715c544eb49c278bedef093c14c0d7sewardj wait_flags = WNOHANG; 6594cb918d355cef4e7640d374346852db4556f3524sewardj } 66017442fe8094d0f82266e5a05509f62cac8f7539esewardj return global_status; 66117442fe8094d0f82266e5a05509f62cac8f7539esewardj} 662c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 663fc1b541264539587f12721ca0b73ef04580ed2bdsewardj/* 664b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj * Run the fsck program on a particular device 6652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj * 6662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj * If the type is specified using -t, and it isn't prefixed with "no" 6672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj * (as in "noext2") and only one filesystem type is specified, then 6682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj * use that type regardless of what is specified in /etc/fstab. 6692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj * 6702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj * If the type isn't specified by the user, then use either the type 6712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj * specified in /etc/fstab, or DEFAULT_FSTYPE. 6722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 6732019a976f07ff418dde2dfc7cc74667ef66d7764sewardjstatic void fsck_device(struct fs_info *fs, int interactive) 6742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 6752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj const char *type; 6762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj int retval; 6772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 6782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj interpret_type(fs); 6792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 6802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (strcmp(fs->type, "auto") != 0) 6811c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian type = fs->type; 6821c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian else if (fstype && strncmp(fstype, "no", 2) && 6832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj strncmp(fstype, "opts=", 5) && strncmp(fstype, "loop", 4) && 6842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj !strchr(fstype, ',')) 6852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj type = fstype; 6862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj else 6872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj type = DEFAULT_FSTYPE; 6881c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 6891c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian num_running++; 6902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj retval = execute(type, fs->device, fs->mountpt, interactive); 6912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (retval) { 6922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj fprintf(stderr, _("%s: Error %d while executing fsck.%s " 693b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj "for %s\n"), progname, retval, type, fs->device); 694b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj num_running--; 695b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj } 696b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj} 697b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 698b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 699b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/* 700b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj * Deal with the fsck -t argument. 701b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj */ 702b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjstruct fs_type_compile { 703b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj char **list; 704b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj int *type; 705b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj int negate; 706b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj} fs_type_compiled; 707b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 708b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj#define FS_TYPE_NORMAL 0 709b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj#define FS_TYPE_OPT 1 710b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj#define FS_TYPE_NEGOPT 2 711b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 712b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjstatic const char *fs_type_syntax_error = 713b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjN_("Either all or none of the filesystem types passed to -t must be prefixed\n" 714b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj "with 'no' or '!'.\n"); 715b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 716b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjstatic void compile_fs_type(char *fs_type, struct fs_type_compile *cmp) 717d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj{ 718d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj char *cp, *list, *s; 719b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj int num = 2; 7202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj int negate, first_negate = 1; 7212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 7222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (fs_type) { 7232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for (cp=fs_type; *cp; cp++) { 7245906a6b242b06c27fdc583d4547eab10b86a9800florian if (*cp == ',') 7252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj num++; 7262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 727b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj } 728b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 72940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj cmp->list = malloc(num * sizeof(char *)); 73040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj cmp->type = malloc(num * sizeof(int)); 7312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (!cmp->list || !cmp->type) { 7322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj fprintf(stderr, _("Couldn't allocate memory for " 73340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj "filesystem types\n")); 73440c802659108a96bb87cbc1a30b7b77e2abd0829sewardj exit(EXIT_ERROR); 73540c802659108a96bb87cbc1a30b7b77e2abd0829sewardj } 73640c802659108a96bb87cbc1a30b7b77e2abd0829sewardj memset(cmp->list, 0, num * sizeof(char *)); 73740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj memset(cmp->type, 0, num * sizeof(int)); 73840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj cmp->negate = 0; 73940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj 74040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj if (!fs_type) 74140c802659108a96bb87cbc1a30b7b77e2abd0829sewardj return; 742b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 7431ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj list = string_copy(fs_type); 7440f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj num = 0; 7450f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj s = strtok(list, ","); 7460f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj while(s) { 7470f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj negate = 0; 748b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj if (strncmp(s, "no", 2) == 0) { 749b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj s += 2; 750b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj negate = 1; 751b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj } else if (*s == '!') { 752b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj s++; 753b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj negate = 1; 754b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj } 755b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj if (strcmp(s, "loop") == 0) 756b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj /* loop is really short-hand for opts=loop */ 757e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj goto loop_special_case; 758e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj else if (strncmp(s, "opts=", 5) == 0) { 75944ce46d5945ed83d96695d280510cc2a858894dcsewardj s += 5; 76044ce46d5945ed83d96695d280510cc2a858894dcsewardj loop_special_case: 76144ce46d5945ed83d96695d280510cc2a858894dcsewardj cmp->type[num] = negate ? FS_TYPE_NEGOPT : FS_TYPE_OPT; 76244ce46d5945ed83d96695d280510cc2a858894dcsewardj } else { 763e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj if (first_negate) { 764e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj cmp->negate = negate; 765e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj first_negate = 0; 766e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj } 767e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj if ((negate && !cmp->negate) || 768e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj (!negate && cmp->negate)) { 769e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj fprintf(stderr, _(fs_type_syntax_error)); 770e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj exit(EXIT_USAGE); 771e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj } 772e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj } 773e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj#if 0 774e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj printf("Adding %s to list (type %d).\n", s, cmp->type[num]); 775e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj#endif 776e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj cmp->list[num++] = string_copy(s); 777e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj s = strtok(NULL, ","); 778e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj } 779e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj free(list); 780e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj} 781e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj 782e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj/* 783e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj * This function returns true if a particular option appears in a 784e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj * comma-delimited options list 785310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardj */ 786310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardjstatic int opt_in_list(char *opt, char *optlist) 787310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardj{ 788e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj char *list, *s; 789e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj 790e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj if (!optlist) 7912fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 0; 7922fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj list = string_copy(optlist); 7932fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 7942fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj s = strtok(list, ","); 7952fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj while(s) { 7962fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (strcmp(s, opt) == 0) { 7972fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj free(list); 7982fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 1; 7992fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 8002fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj s = strtok(NULL, ","); 8012fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 8022fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj free(list); 8032fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 0; 8042fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj} 8052fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8062fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj/* See if the filesystem matches the criteria given by the -t option */ 8072fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjstatic int fs_match(struct fs_info *fs, struct fs_type_compile *cmp) 8082fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{ 8092fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj int n, ret = 0, checked_type = 0; 8102fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj char *cp; 8112fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8122fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (cmp->list == 0 || cmp->list[0] == 0) 8132fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 1; 8141ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj 8152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj for (n=0; (cp = cmp->list[n]); n++) { 8162fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj switch (cmp->type[n]) { 8172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj case FS_TYPE_NORMAL: 8182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj checked_type++; 8191ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj if (strcmp(cp, fs->type) == 0) { 8202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj ret = 1; 8212fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 8222fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj break; 8231ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj case FS_TYPE_NEGOPT: 8242fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (opt_in_list(cp, fs->opts)) 8252fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 0; 8262fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj break; 8272fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj case FS_TYPE_OPT: 8281ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj if (!opt_in_list(cp, fs->opts)) 8292fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 0; 8302fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj break; 8312fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 8322fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 83338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj if (checked_type == 0) 83438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj return 1; 83538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj return (cmp->negate ? !ret : ret); 8361806918ae2783af5808f00876581e01c7b650a0dsewardj} 83738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj 83838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj/* Check if we should ignore this filesystem. */ 83938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic int ignore(struct fs_info *fs) 8402fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{ 8412fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj const char **ip; 8422fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj int wanted = 0; 8432fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8442fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj /* 8452fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * If the pass number is 0, ignore it. 8462fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj */ 8472fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (fs->passno == 0) 8482fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 1; 8492fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8502fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj interpret_type(fs); 8512fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8522fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj /* 8532fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * If a specific fstype is specified, and it doesn't match, 8542fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * ignore it. 8552fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj */ 8562fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (!fs_match(fs, &fs_type_compiled)) return 1; 8572fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 85838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /* Are we ignoring this type? */ 85938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj for(ip = ignored_types; *ip; ip++) 86038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj if (strcmp(fs->type, *ip) == 0) return 1; 8612fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8622fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj /* Do we really really want to check this fs? */ 86338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj for(ip = really_wanted; *ip; ip++) 8642fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (strcmp(fs->type, *ip) == 0) { 8652fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj wanted = 1; 8662fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj break; 8672fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 8682fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8692fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj /* See if the <fsck.fs> program is available. */ 87038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj if (find_fsck(fs->type) == NULL) { 87138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj if (wanted) 8722fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj fprintf(stderr, _("fsck: cannot check %s: fsck.%s not found\n"), 8732fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj fs->device, fs->type); 8742fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 1; 8752fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 8762fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8772fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj /* We can and want to check this file system type. */ 8782fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 0; 8792fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj} 8802fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8812fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj/* 8822fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * Returns TRUE if a partition on the same disk is already being 8832fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * checked. 88438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj */ 8855ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardjstatic int device_already_active(char *device) 88638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj{ 88738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj struct fsck_instance *inst; 88838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj char *base; 88938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj 8902fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (force_all_parallel) 8912fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 0; 8922fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 8932fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj#ifdef BASE_MD 89438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /* Don't check a soft raid disk with any other disk */ 89538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj if (instance_list && 89638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1) || 8972fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj !strncmp(device, BASE_MD, sizeof(BASE_MD)-1))) 89838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj return 1; 89938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj#endif 9002fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 9012fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj base = base_device(device); 9022fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj /* 903a8c7b0f2ac208ed08763d0873131962a65669d58sewardj * If we don't know the base device, assume that the device is 904a8c7b0f2ac208ed08763d0873131962a65669d58sewardj * already active if there are any fsck instances running. 9057deaf9552b546b847528cf39b38898fb7742b5f5carll */ 9062fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (!base) 9072fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return (instance_list != 0); 9082fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj for (inst = instance_list; inst; inst = inst->next) { 9092fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (!inst->base_device || !strcmp(base, inst->base_device)) { 9102fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj free(base); 9112fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 1; 9122fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 91338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj } 914d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj free(base); 9152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj return 0; 916d71ba837242cc470f622335b1c650bce8886a533sewardj} 91738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj 9182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj/* Check all file systems, using the /etc/fstab table. */ 9192fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjstatic int check_all(NOARGS) 9202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{ 9212fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj struct fs_info *fs = NULL; 9221dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj int status = EXIT_OK; 9231dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj int not_done_yet = 1; 9241dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj int passno = 1; 9251dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj int pass_done; 9261dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj 9271dd3ec1c8a8d28f1d81f42a599b390595466c805sewardj if (verbose) 9282fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj printf(_("Checking all file systems.\n")); 9295f438dd73072211989c6d496845bdc9b777ecbecsewardj 9305f438dd73072211989c6d496845bdc9b777ecbecsewardj /* 931c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj * Do an initial scan over the filesystem; mark filesystems 932c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj * which should be ignored as done, and resolve any "auto" 933c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj * filesystem types (done as a side-effect of calling ignore()). 934c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj */ 935c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj for (fs = filesys_info; fs; fs = fs->next) { 936c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj if (ignore(fs)) 937c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj fs->flags |= FLAG_DONE; 938c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj } 939c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj 940c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj /* 941c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj * Find and check the root filesystem. 942c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj */ 943c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj if (!parallel_root) { 944c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj for (fs = filesys_info; fs; fs = fs->next) { 945c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj if (!strcmp(fs->mountpt, "/")) 946c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj break; 947c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj } 948c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj if (fs) { 949c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj if (!skip_root && !ignore(fs)) { 9505f438dd73072211989c6d496845bdc9b777ecbecsewardj fsck_device(fs, 1); 9515f438dd73072211989c6d496845bdc9b777ecbecsewardj status |= wait_many(FLAG_WAIT_ALL); 952ad2c9ea0c360fced134b2dd0d4b28c0be3639cfbsewardj if (status > EXIT_NONDESTRUCT) 95338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj return status; 9542fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 9552fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj fs->flags |= FLAG_DONE; 95638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj } 95738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj } 95838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj /* 95938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj * This is for the bone-headed user who enters the root 9602fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * filesystem twice. Skip root will skep all root entries. 9612fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj */ 9622fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (skip_root) 9632fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj for (fs = filesys_info; fs; fs = fs->next) 9642fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (!strcmp(fs->mountpt, "/")) 9652fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj fs->flags |= FLAG_DONE; 966d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj 967d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj while (not_done_yet) { 968d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj not_done_yet = 0; 969d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj pass_done = 1; 9702fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj 9712fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj for (fs = filesys_info; fs; fs = fs->next) { 9722fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (cancel_requested) 9732fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj break; 9742fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (fs->flags & FLAG_DONE) 9752fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj continue; 9762fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj /* 9772fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * If the filesystem's pass number is higher 9782fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * than the current pass number, then we don't 9792fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * do it yet. 9802fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj */ 9812fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj if (fs->passno > passno) { 9822fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj not_done_yet++; 983e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj continue; 984e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj } 985e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj /* 986e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj * If a filesystem on a particular device has 987e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj * already been spawned, then we need to defer 988e6b9bd927408d9a7b0a95a9d930b387659f65218sewardj * this to another pass. 9892fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj */ 990336803528188cd4fe8b4fcfa7c48ca1056811046sewardj if (device_already_active(fs->device)) { 991336803528188cd4fe8b4fcfa7c48ca1056811046sewardj pass_done = 0; 992336803528188cd4fe8b4fcfa7c48ca1056811046sewardj continue; 9932fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 994336803528188cd4fe8b4fcfa7c48ca1056811046sewardj /* 995336803528188cd4fe8b4fcfa7c48ca1056811046sewardj * Spawn off the fsck process 996336803528188cd4fe8b4fcfa7c48ca1056811046sewardj */ 997336803528188cd4fe8b4fcfa7c48ca1056811046sewardj fsck_device(fs, serialize); 998336803528188cd4fe8b4fcfa7c48ca1056811046sewardj fs->flags |= FLAG_DONE; 999336803528188cd4fe8b4fcfa7c48ca1056811046sewardj 1000d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj /* 1001d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj * Only do one filesystem at a time, or if we 1002d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj * have a limit on the number of fsck's extant 1003d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj * at one time, apply that limit. 1004d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj */ 1005d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj if (serialize || 1006d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj (max_running && (num_running >= max_running))) { 1007d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj pass_done = 0; 1008e13074c2c1321d069fb95806bdce64f9a3512341sewardj break; 1009e13074c2c1321d069fb95806bdce64f9a3512341sewardj } 1010e13074c2c1321d069fb95806bdce64f9a3512341sewardj } 1011e13074c2c1321d069fb95806bdce64f9a3512341sewardj if (cancel_requested) 10122fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj break; 10131ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj if (verbose > 1) 10141ddee21008ffdb2ac7f8e6a73445f150f753606fsewardj printf(_("--waiting-- (pass %d)\n"), passno); 10152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj status |= wait_many(pass_done ? FLAG_WAIT_ALL : 1016c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj FLAG_WAIT_ATLEAST_ONE); 1017c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj if (pass_done) { 1018c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj if (verbose > 1) 1019c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj printf("----------------------------------\n"); 102079e5a4845df6d09250b142c4e160a95cf7688fc8florian passno++; 1021c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj } else 1022c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj not_done_yet++; 1023c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj } 1024c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj if (cancel_requested && !kill_sent) { 1025c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj kill_all(SIGTERM); 102679e5a4845df6d09250b142c4e160a95cf7688fc8florian kill_sent++; 1027c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj } 1028c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj status |= wait_many(FLAG_WAIT_ATLEAST_ONE); 1029c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj return status; 103026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj} 103126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj 103226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardjstatic void usage(NOARGS) 103326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj{ 103426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj fprintf(stderr, 103526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj _("Usage: fsck [-ACNPRTV] [-t fstype] [fs-options] [filesys ...]\n")); 1036cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj exit(EXIT_USAGE); 1037cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj} 103826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj 103926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj#ifdef HAVE_SIGNAL_H 104026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardjstatic void signal_cancel(int sig) 104126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj{ 104226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj cancel_requested++; 104326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj} 104426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj#endif 104526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj 104626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardjstatic void PRS(int argc, char *argv[]) 104726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj{ 104826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj int i, j; 104926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj char *arg, *dev, *tmp = 0; 105026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj char options[128]; 105126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj int opt = 0; 1052b17e16fb3709b8282646009caffa2ead7bcf363fflorian int opts_for_fsck = 0; 1053b17e16fb3709b8282646009caffa2ead7bcf363fflorian#ifdef HAVE_SIGNAL_H 1054b17e16fb3709b8282646009caffa2ead7bcf363fflorian struct sigaction sa; 1055b17e16fb3709b8282646009caffa2ead7bcf363fflorian 1056b17e16fb3709b8282646009caffa2ead7bcf363fflorian /* 1057b17e16fb3709b8282646009caffa2ead7bcf363fflorian * Set up signal action 105826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj */ 105926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj memset(&sa, 0, sizeof(struct sigaction)); 106026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj sa.sa_handler = signal_cancel; 1061b17e16fb3709b8282646009caffa2ead7bcf363fflorian sigaction(SIGINT, &sa, 0); 1062b17e16fb3709b8282646009caffa2ead7bcf363fflorian sigaction(SIGTERM, &sa, 0); 1063b17e16fb3709b8282646009caffa2ead7bcf363fflorian#endif 106479e5a4845df6d09250b142c4e160a95cf7688fc8florian 106526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj num_devices = 0; 106626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj num_args = 0; 106779e5a4845df6d09250b142c4e160a95cf7688fc8florian instance_list = 0; 106826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj 106926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj progname = argv[0]; 1070b17e16fb3709b8282646009caffa2ead7bcf363fflorian 1071b17e16fb3709b8282646009caffa2ead7bcf363fflorian for (i=1; i < argc; i++) { 1072b17e16fb3709b8282646009caffa2ead7bcf363fflorian arg = argv[i]; 1073b17e16fb3709b8282646009caffa2ead7bcf363fflorian if (!arg) 1074b17e16fb3709b8282646009caffa2ead7bcf363fflorian continue; 1075b17e16fb3709b8282646009caffa2ead7bcf363fflorian if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) { 107679e5a4845df6d09250b142c4e160a95cf7688fc8florian if (num_devices >= MAX_DEVICES) { 107726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj fprintf(stderr, _("%s: too many devices\n"), 107826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj progname); 107979e5a4845df6d09250b142c4e160a95cf7688fc8florian exit(EXIT_ERROR); 1080b17e16fb3709b8282646009caffa2ead7bcf363fflorian } 1081b17e16fb3709b8282646009caffa2ead7bcf363fflorian dev = blkid_get_devname(cache, arg, NULL); 108279e5a4845df6d09250b142c4e160a95cf7688fc8florian if (!dev && strchr(arg, '=')) { 1083b17e16fb3709b8282646009caffa2ead7bcf363fflorian /* 1084b17e16fb3709b8282646009caffa2ead7bcf363fflorian * Check to see if we failed because 108579e5a4845df6d09250b142c4e160a95cf7688fc8florian * /proc/partitions isn't found. 1086b17e16fb3709b8282646009caffa2ead7bcf363fflorian */ 1087b17e16fb3709b8282646009caffa2ead7bcf363fflorian if (access("/proc/partitions", R_OK) < 0) { 108879e5a4845df6d09250b142c4e160a95cf7688fc8florian fprintf(stderr, "Couldn't open /proc/partitions: %s\n", 108926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj strerror(errno)); 109026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj fprintf(stderr, "Is /proc mounted?\n"); 109179e5a4845df6d09250b142c4e160a95cf7688fc8florian exit(EXIT_ERROR); 1092b17e16fb3709b8282646009caffa2ead7bcf363fflorian } 1093b17e16fb3709b8282646009caffa2ead7bcf363fflorian /* 109479e5a4845df6d09250b142c4e160a95cf7688fc8florian * Check to see if this is because 1095b17e16fb3709b8282646009caffa2ead7bcf363fflorian * we're not running as root 1096b17e16fb3709b8282646009caffa2ead7bcf363fflorian */ 109779e5a4845df6d09250b142c4e160a95cf7688fc8florian if (geteuid()) 1098b17e16fb3709b8282646009caffa2ead7bcf363fflorian fprintf(stderr, 1099b17e16fb3709b8282646009caffa2ead7bcf363fflorian "Must be root to scan for matching filesystems: %s\n", arg); 110079e5a4845df6d09250b142c4e160a95cf7688fc8florian else 110126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj fprintf(stderr, 110226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj "Couldn't find matching filesystem: %s\n", arg); 110379e5a4845df6d09250b142c4e160a95cf7688fc8florian exit(EXIT_ERROR); 1104b17e16fb3709b8282646009caffa2ead7bcf363fflorian } 1105b17e16fb3709b8282646009caffa2ead7bcf363fflorian devices[num_devices++] = dev ? dev : string_copy(arg); 1106b22838d88488f42a46a6d01f5df441c391fb3bbaflorian continue; 1107b22838d88488f42a46a6d01f5df441c391fb3bbaflorian } 1108b22838d88488f42a46a6d01f5df441c391fb3bbaflorian if (arg[0] != '-' || opts_for_fsck) { 1109b22838d88488f42a46a6d01f5df441c391fb3bbaflorian if (num_args >= MAX_ARGS) { 1110b22838d88488f42a46a6d01f5df441c391fb3bbaflorian fprintf(stderr, _("%s: too many arguments\n"), 1111b22838d88488f42a46a6d01f5df441c391fb3bbaflorian progname); 1112b22838d88488f42a46a6d01f5df441c391fb3bbaflorian exit(EXIT_ERROR); 1113b22838d88488f42a46a6d01f5df441c391fb3bbaflorian } 1114b22838d88488f42a46a6d01f5df441c391fb3bbaflorian args[num_args++] = string_copy(arg); 1115b22838d88488f42a46a6d01f5df441c391fb3bbaflorian continue; 1116b22838d88488f42a46a6d01f5df441c391fb3bbaflorian } 1117b22838d88488f42a46a6d01f5df441c391fb3bbaflorian for (j=1; arg[j]; j++) { 111879e5a4845df6d09250b142c4e160a95cf7688fc8florian if (opts_for_fsck) { 111937c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian options[++opt] = arg[j]; 112037c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian continue; 112179e5a4845df6d09250b142c4e160a95cf7688fc8florian } 112237c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian switch (arg[j]) { 112337c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian case 'A': 1124b22838d88488f42a46a6d01f5df441c391fb3bbaflorian doall++; 1125b22838d88488f42a46a6d01f5df441c391fb3bbaflorian break; 1126b22838d88488f42a46a6d01f5df441c391fb3bbaflorian case 'C': 1127b22838d88488f42a46a6d01f5df441c391fb3bbaflorian progress++; 1128b22838d88488f42a46a6d01f5df441c391fb3bbaflorian break; 112937c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian case 'V': 113079e5a4845df6d09250b142c4e160a95cf7688fc8florian verbose++; 113137c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian break; 113237c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian case 'N': 1133b22838d88488f42a46a6d01f5df441c391fb3bbaflorian noexecute++; 1134b22838d88488f42a46a6d01f5df441c391fb3bbaflorian break; 1135b22838d88488f42a46a6d01f5df441c391fb3bbaflorian case 'R': 1136b22838d88488f42a46a6d01f5df441c391fb3bbaflorian skip_root++; 1137b22838d88488f42a46a6d01f5df441c391fb3bbaflorian break; 1138b22838d88488f42a46a6d01f5df441c391fb3bbaflorian case 'T': 1139b22838d88488f42a46a6d01f5df441c391fb3bbaflorian notitle++; 1140b22838d88488f42a46a6d01f5df441c391fb3bbaflorian break; 1141b22838d88488f42a46a6d01f5df441c391fb3bbaflorian case 'M': 1142b22838d88488f42a46a6d01f5df441c391fb3bbaflorian like_mount++; 1143b22838d88488f42a46a6d01f5df441c391fb3bbaflorian break; 1144b22838d88488f42a46a6d01f5df441c391fb3bbaflorian case 'P': 1145b22838d88488f42a46a6d01f5df441c391fb3bbaflorian parallel_root++; 1146b22838d88488f42a46a6d01f5df441c391fb3bbaflorian break; 1147b22838d88488f42a46a6d01f5df441c391fb3bbaflorian case 's': 1148b22838d88488f42a46a6d01f5df441c391fb3bbaflorian serialize++; 1149b22838d88488f42a46a6d01f5df441c391fb3bbaflorian break; 1150b22838d88488f42a46a6d01f5df441c391fb3bbaflorian case 't': 1151b22838d88488f42a46a6d01f5df441c391fb3bbaflorian if (fstype) 1152b22838d88488f42a46a6d01f5df441c391fb3bbaflorian usage(); 1153b22838d88488f42a46a6d01f5df441c391fb3bbaflorian if (arg[j+1]) 1154b22838d88488f42a46a6d01f5df441c391fb3bbaflorian tmp = arg+j+1; 1155b22838d88488f42a46a6d01f5df441c391fb3bbaflorian else if ((i+1) < argc) 1156b22838d88488f42a46a6d01f5df441c391fb3bbaflorian tmp = argv[++i]; 115779e5a4845df6d09250b142c4e160a95cf7688fc8florian else 115837c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian usage(); 115937c57f396b7a6dc1fc3a7e59e85bbf7eac627a88florian fstype = string_copy(tmp); 1160cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj compile_fs_type(fstype, &fs_type_compiled); 1161cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj goto next_arg; 1162cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll case '-': 1163cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll opts_for_fsck++; 1164cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj break; 1165cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj case '?': 1166cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj usage(); 1167cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj break; 1168cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj default: 1169cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj options[++opt] = arg[j]; 1170cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj break; 1171cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj } 1172cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj } 1173cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj next_arg: 1174daa4084cffd771efef294a484e64868f3eeeb0e4florian if (opt) { 1175cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj options[0] = '-'; 1176cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj options[++opt] = '\0'; 117720c6bca02d9b3c985607b4639ffc70eb504cc237florian if (num_args >= MAX_ARGS) { 117820c6bca02d9b3c985607b4639ffc70eb504cc237florian fprintf(stderr, 117920c6bca02d9b3c985607b4639ffc70eb504cc237florian _("%s: too many arguments\n"), 118020c6bca02d9b3c985607b4639ffc70eb504cc237florian progname); 118120c6bca02d9b3c985607b4639ffc70eb504cc237florian exit(EXIT_ERROR); 118220c6bca02d9b3c985607b4639ffc70eb504cc237florian } 118320c6bca02d9b3c985607b4639ffc70eb504cc237florian args[num_args++] = string_copy(options); 1184cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj opt = 0; 1185cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj } 1186cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj } 1187cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj if (getenv("FSCK_FORCE_ALL_PARALLEL")) 1188cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj force_all_parallel++; 1189cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj if ((tmp = getenv("FSCK_MAX_INST"))) 1190cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj max_running = atoi(tmp); 1191cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj} 119279e5a4845df6d09250b142c4e160a95cf7688fc8florian 1193cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardjint main(int argc, char *argv[]) 1194cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj{ 119579e5a4845df6d09250b142c4e160a95cf7688fc8florian int i, status = 0; 1196cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj int interactive = 0; 1197cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj char *oldpath = getenv("PATH"); 119879e5a4845df6d09250b142c4e160a95cf7688fc8florian const char *fstab; 1199cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj struct fs_info *fs; 1200cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj 1201cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj setvbuf(stdout, NULL, _IONBF, BUFSIZ); 1202cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj setvbuf(stderr, NULL, _IONBF, BUFSIZ); 1203cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj 1204cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj#ifdef ENABLE_NLS 120579e5a4845df6d09250b142c4e160a95cf7688fc8florian setlocale(LC_MESSAGES, ""); 1206cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj setlocale(LC_CTYPE, ""); 1207cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 1208cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj textdomain(NLS_CAT_NAME); 1209cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj#endif 1210cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj blkid_get_cache(&cache, NULL); 1211cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj PRS(argc, argv); 1212cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj 1213cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj if (!notitle) 1214cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj printf("fsck %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); 1215cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj 1216cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj fstab = getenv("FSTAB_FILE"); 1217cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj if (!fstab) 12184bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian fstab = _PATH_MNTTAB; 12194bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian load_fs_info(fstab); 12204bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian 12214bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian /* Update our search path to include uncommon directories. */ 12224bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian if (oldpath) { 12234bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian fsck_path = malloc (strlen (fsck_prefix_path) + 1 + 12244bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian strlen (oldpath) + 1); 12254bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian strcpy (fsck_path, fsck_prefix_path); 12264bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian strcat (fsck_path, ":"); 1227cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll strcat (fsck_path, oldpath); 1228cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj } else { 1229cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj fsck_path = string_copy(fsck_prefix_path); 1230cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj } 1231cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj 1232cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj if ((num_devices == 1) || (serialize)) 1233cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj interactive = 1; 1234cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj 1235cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll /* If -A was specified ("check all"), do that! */ 1236cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj if (doall) 1237cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj return check_all(); 1238c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj 1239c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj if (num_devices == 0) { 1240c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj serialize++; 12414c96e61dd85c172b999d6afc88ce6640aeba9962sewardj interactive++; 12424c96e61dd85c172b999d6afc88ce6640aeba9962sewardj return check_all(); 12434c96e61dd85c172b999d6afc88ce6640aeba9962sewardj } 12444c96e61dd85c172b999d6afc88ce6640aeba9962sewardj for (i = 0 ; i < num_devices; i++) { 12454c96e61dd85c172b999d6afc88ce6640aeba9962sewardj if (cancel_requested) { 12464c96e61dd85c172b999d6afc88ce6640aeba9962sewardj if (!kill_sent) { 12474c96e61dd85c172b999d6afc88ce6640aeba9962sewardj kill_all(SIGTERM); 12484c96e61dd85c172b999d6afc88ce6640aeba9962sewardj kill_sent++; 12494c96e61dd85c172b999d6afc88ce6640aeba9962sewardj } 12504c96e61dd85c172b999d6afc88ce6640aeba9962sewardj break; 12517deaf9552b546b847528cf39b38898fb7742b5f5carll } 12527deaf9552b546b847528cf39b38898fb7742b5f5carll fs = lookup(devices[i]); 12539571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj if (!fs) { 12549571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj fs = create_fs_device(devices[i], 0, "auto", 12557deaf9552b546b847528cf39b38898fb7742b5f5carll 0, -1, -1); 12567deaf9552b546b847528cf39b38898fb7742b5f5carll if (!fs) 1257cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj continue; 1258cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj } 1259cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj fsck_device(fs, interactive); 12605eff1c502e995d1f9668cc9def72d5db59f21b13sewardj if (serialize || 12615eff1c502e995d1f9668cc9def72d5db59f21b13sewardj (max_running && (num_running >= max_running))) { 12625eff1c502e995d1f9668cc9def72d5db59f21b13sewardj struct fsck_instance *inst; 1263164f9275c465cd09ecd09276b8542282f5def250sewardj 1264c9a43665879a03886b27a65b68af2a2c11b04f59sewardj inst = wait_one(0); 1265c9a43665879a03886b27a65b68af2a2c11b04f59sewardj if (inst) { 1266c9a43665879a03886b27a65b68af2a2c11b04f59sewardj status |= inst->exit_status; 12679571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj free_instance(inst); 1268c9a43665879a03886b27a65b68af2a2c11b04f59sewardj } 12699571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj if (verbose > 1) 12709571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj printf("----------------------------------\n"); 1271c9a43665879a03886b27a65b68af2a2c11b04f59sewardj } 12722fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj } 12732fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj status |= wait_many(FLAG_WAIT_ALL); 1274f294eb389e8e703e2d4476aea7ca579a160a0a89cerion free(fsck_path); 12752fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj blkid_put_cache(cache); 1276206c36410bd92f385b972e36a3a40e38675294e2cerion return status; 1277c9a43665879a03886b27a65b68af2a2c11b04f59sewardj} 12782fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj