fsck.c 28 KB

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