fsck.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * fsck --- 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. /* All filesystem specific hooks have been removed.
  29. * If filesystem cannot be determined, we will execute
  30. * "fsck.auto". Currently this also happens if you specify
  31. * UUID=xxx or LABEL=xxx as an object to check.
  32. * Detection code for that is also probably has to be in fsck.auto.
  33. *
  34. * In other words, this is _really_ is just a driver program which
  35. * spawns actual fsck.something for each filesystem to check.
  36. * It doesn't guess filesystem types from on-disk format.
  37. */
  38. #include "libbb.h"
  39. #define EXIT_OK 0
  40. #define EXIT_NONDESTRUCT 1
  41. #define EXIT_DESTRUCT 2
  42. #define EXIT_UNCORRECTED 4
  43. #define EXIT_ERROR 8
  44. #define EXIT_USAGE 16
  45. #define FSCK_CANCELED 32 /* Aborted with a signal or ^C */
  46. /*
  47. * Internal structure for mount table entries.
  48. */
  49. struct fs_info {
  50. struct fs_info *next;
  51. char *device;
  52. char *mountpt;
  53. char *type;
  54. char *opts;
  55. int freq;
  56. int passno;
  57. int flags;
  58. };
  59. #define FLAG_DONE 1
  60. #define FLAG_PROGRESS 2
  61. /*
  62. * Structure to allow exit codes to be stored
  63. */
  64. struct fsck_instance {
  65. struct fsck_instance *next;
  66. int pid;
  67. int flags;
  68. int exit_status;
  69. time_t start_time;
  70. char *prog;
  71. char *type;
  72. char *device;
  73. char *base_device; /* /dev/hda for /dev/hdaN etc */
  74. };
  75. static const char ignored_types[] ALIGN1 =
  76. "ignore\0"
  77. "iso9660\0"
  78. "nfs\0"
  79. "proc\0"
  80. "sw\0"
  81. "swap\0"
  82. "tmpfs\0"
  83. "devpts\0";
  84. #if 0
  85. static const char really_wanted[] ALIGN1 =
  86. "minix\0"
  87. "ext2\0"
  88. "ext3\0"
  89. "jfs\0"
  90. "reiserfs\0"
  91. "xiafs\0"
  92. "xfs\0";
  93. #endif
  94. #define BASE_MD "/dev/md"
  95. static char **devices;
  96. static char **args;
  97. static int num_devices;
  98. static int num_args;
  99. static int verbose;
  100. #define FS_TYPE_FLAG_NORMAL 0
  101. #define FS_TYPE_FLAG_OPT 1
  102. #define FS_TYPE_FLAG_NEGOPT 2
  103. static char **fs_type_list;
  104. static uint8_t *fs_type_flag;
  105. static smallint fs_type_negated;
  106. static volatile smallint cancel_requested;
  107. static smallint doall;
  108. static smallint noexecute;
  109. static smallint serialize;
  110. static smallint skip_root;
  111. /* static smallint like_mount; */
  112. static smallint notitle;
  113. static smallint parallel_root;
  114. static smallint force_all_parallel;
  115. /* "progress indicator" code is somewhat buggy and ext[23] specific.
  116. * We should be filesystem agnostic. IOW: there should be a well-defined
  117. * API for fsck.something, NOT ad-hoc hacks in generic fsck. */
  118. #define DO_PROGRESS_INDICATOR 0
  119. #if DO_PROGRESS_INDICATOR
  120. static smallint progress;
  121. static int progress_fd;
  122. #endif
  123. static int num_running;
  124. static int max_running;
  125. static char *fstype;
  126. static struct fs_info *filesys_info;
  127. static struct fs_info *filesys_last;
  128. static struct fsck_instance *instance_list;
  129. /*
  130. * Return the "base device" given a particular device; this is used to
  131. * assure that we only fsck one partition on a particular drive at any
  132. * one time. Otherwise, the disk heads will be seeking all over the
  133. * place. If the base device cannot be determined, return NULL.
  134. *
  135. * The base_device() function returns an allocated string which must
  136. * be freed.
  137. */
  138. #if ENABLE_FEATURE_DEVFS
  139. /*
  140. * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3
  141. * pathames.
  142. */
  143. static const char *const devfs_hier[] = {
  144. "host", "bus", "target", "lun", NULL
  145. };
  146. #endif
  147. static char *base_device(const char *device)
  148. {
  149. char *str, *cp;
  150. #if ENABLE_FEATURE_DEVFS
  151. const char *const *hier;
  152. const char *disk;
  153. int len;
  154. #endif
  155. cp = str = xstrdup(device);
  156. /* Skip over /dev/; if it's not present, give up. */
  157. if (strncmp(cp, "/dev/", 5) != 0)
  158. goto errout;
  159. cp += 5;
  160. /*
  161. * For md devices, we treat them all as if they were all
  162. * on one disk, since we don't know how to parallelize them.
  163. */
  164. if (cp[0] == 'm' && cp[1] == 'd') {
  165. cp[2] = 0;
  166. return str;
  167. }
  168. /* Handle DAC 960 devices */
  169. if (strncmp(cp, "rd/", 3) == 0) {
  170. cp += 3;
  171. if (cp[0] != 'c' || !isdigit(cp[1])
  172. || cp[2] != 'd' || !isdigit(cp[3]))
  173. goto errout;
  174. cp[4] = 0;
  175. return str;
  176. }
  177. /* Now let's handle /dev/hd* and /dev/sd* devices.... */
  178. if ((cp[0] == 'h' || cp[0] == 's') && cp[1] == 'd') {
  179. cp += 2;
  180. /* If there's a single number after /dev/hd, skip it */
  181. if (isdigit(*cp))
  182. cp++;
  183. /* What follows must be an alpha char, or give up */
  184. if (!isalpha(*cp))
  185. goto errout;
  186. cp[1] = 0;
  187. return str;
  188. }
  189. #if ENABLE_FEATURE_DEVFS
  190. /* Now let's handle devfs (ugh) names */
  191. len = 0;
  192. if (strncmp(cp, "ide/", 4) == 0)
  193. len = 4;
  194. if (strncmp(cp, "scsi/", 5) == 0)
  195. len = 5;
  196. if (len) {
  197. cp += len;
  198. /*
  199. * Now we proceed down the expected devfs hierarchy.
  200. * i.e., .../host1/bus2/target3/lun4/...
  201. * If we don't find the expected token, followed by
  202. * some number of digits at each level, abort.
  203. */
  204. for (hier = devfs_hier; *hier; hier++) {
  205. len = strlen(*hier);
  206. if (strncmp(cp, *hier, len) != 0)
  207. goto errout;
  208. cp += len;
  209. while (*cp != '/' && *cp != 0) {
  210. if (!isdigit(*cp))
  211. goto errout;
  212. cp++;
  213. }
  214. cp++;
  215. }
  216. cp[-1] = 0;
  217. return str;
  218. }
  219. /* Now handle devfs /dev/disc or /dev/disk names */
  220. disk = 0;
  221. if (strncmp(cp, "discs/", 6) == 0)
  222. disk = "disc";
  223. else if (strncmp(cp, "disks/", 6) == 0)
  224. disk = "disk";
  225. if (disk) {
  226. cp += 6;
  227. if (strncmp(cp, disk, 4) != 0)
  228. goto errout;
  229. cp += 4;
  230. while (*cp != '/' && *cp != 0) {
  231. if (!isdigit(*cp))
  232. goto errout;
  233. cp++;
  234. }
  235. *cp = 0;
  236. return str;
  237. }
  238. #endif
  239. errout:
  240. free(str);
  241. return NULL;
  242. }
  243. static void free_instance(struct fsck_instance *p)
  244. {
  245. free(p->prog);
  246. free(p->device);
  247. free(p->base_device);
  248. free(p);
  249. }
  250. static struct fs_info *create_fs_device(const char *device, const char *mntpnt,
  251. const char *type, const char *opts,
  252. int freq, int passno)
  253. {
  254. struct fs_info *fs;
  255. fs = xzalloc(sizeof(*fs));
  256. fs->device = xstrdup(device);
  257. fs->mountpt = xstrdup(mntpnt);
  258. fs->type = xstrdup(type);
  259. fs->opts = xstrdup(opts ? opts : "");
  260. fs->freq = freq;
  261. fs->passno = passno;
  262. /*fs->flags = 0; */
  263. /*fs->next = NULL; */
  264. if (!filesys_info)
  265. filesys_info = fs;
  266. else
  267. filesys_last->next = fs;
  268. filesys_last = fs;
  269. return fs;
  270. }
  271. static void strip_line(char *line)
  272. {
  273. char *p = line + strlen(line) - 1;
  274. while (*line) {
  275. if (*p != '\n' && *p != '\r')
  276. break;
  277. *p-- = '\0';
  278. }
  279. }
  280. static char *parse_word(char **buf)
  281. {
  282. char *word, *next;
  283. word = *buf;
  284. if (*word == '\0')
  285. return NULL;
  286. word = skip_whitespace(word);
  287. next = skip_non_whitespace(word);
  288. if (*next)
  289. *next++ = '\0';
  290. *buf = next;
  291. return word;
  292. }
  293. static void parse_escape(char *word)
  294. {
  295. char *q, c;
  296. const char *p;
  297. if (!word)
  298. return;
  299. for (p = q = word; *p; q++) {
  300. c = *p++;
  301. if (c != '\\') {
  302. *q = c;
  303. } else {
  304. *q = bb_process_escape_sequence(&p);
  305. }
  306. }
  307. *q = '\0';
  308. }
  309. static int parse_fstab_line(char *line, struct fs_info **ret_fs)
  310. {
  311. char *device, *mntpnt, *type, *opts, *freq, *passno, *cp;
  312. struct fs_info *fs;
  313. *ret_fs = 0;
  314. strip_line(line);
  315. cp = strchr(line, '#');
  316. if (cp)
  317. *cp = '\0'; /* Ignore everything after the comment char */
  318. cp = line;
  319. device = parse_word(&cp);
  320. if (!device) return 0; /* Allow blank lines */
  321. mntpnt = parse_word(&cp);
  322. type = parse_word(&cp);
  323. opts = parse_word(&cp);
  324. freq = parse_word(&cp);
  325. passno = parse_word(&cp);
  326. if (!mntpnt || !type)
  327. return -1;
  328. parse_escape(device);
  329. parse_escape(mntpnt);
  330. parse_escape(type);
  331. parse_escape(opts);
  332. parse_escape(freq);
  333. parse_escape(passno);
  334. if (strchr(type, ','))
  335. type = NULL;
  336. fs = create_fs_device(device, mntpnt, type ? type : "auto", opts,
  337. freq ? atoi(freq) : -1,
  338. passno ? atoi(passno) : -1);
  339. *ret_fs = fs;
  340. return 0;
  341. }
  342. /* Load the filesystem database from /etc/fstab */
  343. static void load_fs_info(const char *filename)
  344. {
  345. FILE *f;
  346. int lineno = 0;
  347. int old_fstab = 1;
  348. struct fs_info *fs;
  349. f = fopen_or_warn(filename, "r");
  350. if (f == NULL) {
  351. return;
  352. }
  353. while (1) {
  354. int r;
  355. char *buf = xmalloc_getline(f);
  356. if (!buf) break;
  357. r = parse_fstab_line(buf, &fs);
  358. free(buf);
  359. lineno++;
  360. if (r < 0) {
  361. bb_error_msg("WARNING: bad format "
  362. "on line %d of %s", lineno, filename);
  363. continue;
  364. }
  365. if (!fs)
  366. continue;
  367. if (fs->passno < 0)
  368. fs->passno = 0;
  369. else
  370. old_fstab = 0;
  371. }
  372. fclose(f);
  373. if (old_fstab) {
  374. fputs("\007"
  375. "WARNING: Your /etc/fstab does not contain the fsck passno field.\n"
  376. "I will kludge around things for you, but you should fix\n"
  377. "your /etc/fstab file as soon as you can.\n\n", stderr);
  378. for (fs = filesys_info; fs; fs = fs->next) {
  379. fs->passno = 1;
  380. }
  381. }
  382. }
  383. /* Lookup filesys in /etc/fstab and return the corresponding entry. */
  384. static struct fs_info *lookup(char *filesys)
  385. {
  386. struct fs_info *fs;
  387. for (fs = filesys_info; fs; fs = fs->next) {
  388. if (strcmp(filesys, fs->device) == 0
  389. || (fs->mountpt && strcmp(filesys, fs->mountpt) == 0)
  390. )
  391. break;
  392. }
  393. return fs;
  394. }
  395. #if DO_PROGRESS_INDICATOR
  396. static int progress_active(void)
  397. {
  398. struct fsck_instance *inst;
  399. for (inst = instance_list; inst; inst = inst->next) {
  400. if (inst->flags & FLAG_DONE)
  401. continue;
  402. if (inst->flags & FLAG_PROGRESS)
  403. return 1;
  404. }
  405. return 0;
  406. }
  407. #endif
  408. /*
  409. * Send a signal to all outstanding fsck child processes
  410. */
  411. static void kill_all_if_cancel_requested(void)
  412. {
  413. static smallint kill_sent;
  414. struct fsck_instance *inst;
  415. if (!cancel_requested || kill_sent)
  416. return;
  417. for (inst = instance_list; inst; inst = inst->next) {
  418. if (inst->flags & FLAG_DONE)
  419. continue;
  420. kill(inst->pid, SIGTERM);
  421. }
  422. kill_sent = 1;
  423. }
  424. /*
  425. * Wait for one child process to exit; when it does, unlink it from
  426. * the list of executing child processes, and return it.
  427. */
  428. static struct fsck_instance *wait_one(int flags)
  429. {
  430. int status;
  431. int sig;
  432. struct fsck_instance *inst, *prev;
  433. pid_t pid;
  434. if (!instance_list)
  435. return NULL;
  436. if (noexecute) {
  437. inst = instance_list;
  438. prev = NULL;
  439. #ifdef RANDOM_DEBUG
  440. while (inst->next && (random() & 1)) {
  441. prev = inst;
  442. inst = inst->next;
  443. }
  444. #endif
  445. inst->exit_status = 0;
  446. goto ret_inst;
  447. }
  448. inst = prev = NULL; /* for gcc */
  449. do {
  450. pid = waitpid(-1, &status, flags);
  451. kill_all_if_cancel_requested();
  452. if (pid == 0 && (flags & WNOHANG))
  453. return NULL;
  454. if (pid < 0) {
  455. if (errno == EINTR || errno == EAGAIN)
  456. continue;
  457. if (errno == ECHILD) {
  458. bb_error_msg("wait: no more child process?!?");
  459. return NULL;
  460. }
  461. bb_perror_msg("wait");
  462. continue;
  463. }
  464. prev = NULL;
  465. inst = instance_list;
  466. while (inst) {
  467. if (inst->pid == pid)
  468. break;
  469. prev = inst;
  470. inst = inst->next;
  471. }
  472. } while (!inst);
  473. if (WIFEXITED(status))
  474. status = WEXITSTATUS(status);
  475. else if (WIFSIGNALED(status)) {
  476. sig = WTERMSIG(status);
  477. status = EXIT_UNCORRECTED;
  478. if (sig != SIGINT) {
  479. printf("Warning... %s %s exited "
  480. "with signal %d\n",
  481. inst->prog, inst->device, sig);
  482. status = EXIT_ERROR;
  483. }
  484. } else {
  485. printf("%s %s: status is %x, should never happen\n",
  486. inst->prog, inst->device, status);
  487. status = EXIT_ERROR;
  488. }
  489. inst->exit_status = status;
  490. #if DO_PROGRESS_INDICATOR
  491. if (progress && (inst->flags & FLAG_PROGRESS) && !progress_active()) {
  492. struct fsck_instance *inst2;
  493. for (inst2 = instance_list; inst2; inst2 = inst2->next) {
  494. if (inst2->flags & FLAG_DONE)
  495. continue;
  496. if (strcmp(inst2->type, "ext2") != 0
  497. && strcmp(inst2->type, "ext3") != 0
  498. ) {
  499. continue;
  500. }
  501. /* ext[23], we will send USR1
  502. * (request to start displaying progress bar)
  503. *
  504. * If we've just started the fsck, wait a tiny
  505. * bit before sending the kill, to give it
  506. * time to set up the signal handler
  507. */
  508. if (inst2->start_time >= time(NULL) - 1)
  509. sleep(1);
  510. kill(inst2->pid, SIGUSR1);
  511. inst2->flags |= FLAG_PROGRESS;
  512. break;
  513. }
  514. }
  515. #endif
  516. ret_inst:
  517. if (prev)
  518. prev->next = inst->next;
  519. else
  520. instance_list = inst->next;
  521. if (verbose > 1)
  522. printf("Finished with %s (exit status %d)\n",
  523. inst->device, inst->exit_status);
  524. num_running--;
  525. return inst;
  526. }
  527. #define FLAG_WAIT_ALL 0
  528. #define FLAG_WAIT_ATLEAST_ONE 1
  529. /*
  530. * Wait until all executing child processes have exited; return the
  531. * logical OR of all of their exit code values.
  532. */
  533. static int wait_many(int flags)
  534. {
  535. struct fsck_instance *inst;
  536. int global_status = 0;
  537. int wait_flags = 0;
  538. while ((inst = wait_one(wait_flags))) {
  539. global_status |= inst->exit_status;
  540. free_instance(inst);
  541. #ifdef RANDOM_DEBUG
  542. if (noexecute && (flags & WNOHANG) && !(random() % 3))
  543. break;
  544. #endif
  545. if (flags & FLAG_WAIT_ATLEAST_ONE)
  546. wait_flags = WNOHANG;
  547. }
  548. return global_status;
  549. }
  550. /*
  551. * Execute a particular fsck program, and link it into the list of
  552. * child processes we are waiting for.
  553. */
  554. static void execute(const char *type, const char *device, const char *mntpt,
  555. int interactive)
  556. {
  557. char *argv[num_args + 4]; /* see count below: */
  558. int argc;
  559. int i;
  560. struct fsck_instance *inst;
  561. pid_t pid;
  562. inst = xzalloc(sizeof(*inst));
  563. argv[0] = xasprintf("fsck.%s", type); /* 1 */
  564. for (i = 0; i < num_args; i++)
  565. argv[i+1] = args[i]; /* num_args */
  566. argc = num_args + 1;
  567. #if DO_PROGRESS_INDICATOR
  568. if (progress && !progress_active()) {
  569. if (strcmp(type, "ext2") == 0
  570. || strcmp(type, "ext3") == 0
  571. ) {
  572. argv[argc++] = xasprintf("-C%d", progress_fd); /* 1 */
  573. inst->flags |= FLAG_PROGRESS;
  574. }
  575. }
  576. #endif
  577. argv[argc++] = xstrdup(device); /* 1 */
  578. argv[argc] = NULL; /* 1 */
  579. if (verbose || noexecute) {
  580. printf("[%s (%d) -- %s]", argv[0], num_running,
  581. mntpt ? mntpt : device);
  582. for (i = 0; i < argc; i++)
  583. printf(" %s", argv[i]);
  584. puts("");
  585. }
  586. /* Fork and execute the correct program. */
  587. pid = -1;
  588. if (!noexecute) {
  589. pid = spawn(argv);
  590. if (pid < 0)
  591. bb_perror_msg("%s", argv[0]);
  592. }
  593. for (i = num_args+1; i < argc; i++)
  594. free(argv[i]);
  595. inst->pid = pid;
  596. inst->prog = argv[0];
  597. inst->type = xstrdup(type);
  598. inst->device = xstrdup(device);
  599. inst->base_device = base_device(device);
  600. inst->start_time = time(NULL);
  601. /* Add to the list of running fsck's.
  602. * (was adding to the end, but adding to the front is simpler...) */
  603. inst->next = instance_list;
  604. instance_list = inst;
  605. }
  606. /*
  607. * Run the fsck program on a particular device
  608. *
  609. * If the type is specified using -t, and it isn't prefixed with "no"
  610. * (as in "noext2") and only one filesystem type is specified, then
  611. * use that type regardless of what is specified in /etc/fstab.
  612. *
  613. * If the type isn't specified by the user, then use either the type
  614. * specified in /etc/fstab, or "auto".
  615. */
  616. static void fsck_device(struct fs_info *fs, int interactive)
  617. {
  618. const char *type;
  619. if (strcmp(fs->type, "auto") != 0) {
  620. type = fs->type;
  621. if (verbose > 2)
  622. bb_info_msg("using filesystem type '%s' %s",
  623. type, "from fstab");
  624. } else if (fstype
  625. && (fstype[0] != 'n' || fstype[1] != 'o') /* != "no" */
  626. && strncmp(fstype, "opts=", 5) != 0
  627. && strncmp(fstype, "loop", 4) != 0
  628. && !strchr(fstype, ',')
  629. ) {
  630. type = fstype;
  631. if (verbose > 2)
  632. bb_info_msg("using filesystem type '%s' %s",
  633. type, "from -t");
  634. } else {
  635. type = "auto";
  636. if (verbose > 2)
  637. bb_info_msg("using filesystem type '%s' %s",
  638. type, "(default)");
  639. }
  640. num_running++;
  641. execute(type, fs->device, fs->mountpt, interactive);
  642. }
  643. /*
  644. * Returns TRUE if a partition on the same disk is already being
  645. * checked.
  646. */
  647. static int device_already_active(char *device)
  648. {
  649. struct fsck_instance *inst;
  650. char *base;
  651. if (force_all_parallel)
  652. return 0;
  653. #ifdef BASE_MD
  654. /* Don't check a soft raid disk with any other disk */
  655. if (instance_list
  656. && (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1)
  657. || !strncmp(device, BASE_MD, sizeof(BASE_MD)-1))
  658. ) {
  659. return 1;
  660. }
  661. #endif
  662. base = base_device(device);
  663. /*
  664. * If we don't know the base device, assume that the device is
  665. * already active if there are any fsck instances running.
  666. */
  667. if (!base)
  668. return (instance_list != NULL);
  669. for (inst = instance_list; inst; inst = inst->next) {
  670. if (!inst->base_device || !strcmp(base, inst->base_device)) {
  671. free(base);
  672. return 1;
  673. }
  674. }
  675. free(base);
  676. return 0;
  677. }
  678. /*
  679. * This function returns true if a particular option appears in a
  680. * comma-delimited options list
  681. */
  682. static int opt_in_list(char *opt, char *optlist)
  683. {
  684. char *s;
  685. int len;
  686. if (!optlist)
  687. return 0;
  688. len = strlen(opt);
  689. s = optlist - 1;
  690. while (1) {
  691. s = strstr(s + 1, opt);
  692. if (!s)
  693. return 0;
  694. /* neither "opt.." nor "xxx,opt.."? */
  695. if (s != optlist && s[-1] != ',')
  696. continue;
  697. /* neither "..opt" nor "..opt,xxx"? */
  698. if (s[len] != '\0' && s[len] != ',')
  699. continue;
  700. return 1;
  701. }
  702. }
  703. /* See if the filesystem matches the criteria given by the -t option */
  704. static int fs_match(struct fs_info *fs)
  705. {
  706. int n, ret, checked_type;
  707. char *cp;
  708. if (!fs_type_list)
  709. return 1;
  710. ret = 0;
  711. checked_type = 0;
  712. n = 0;
  713. while (1) {
  714. cp = fs_type_list[n];
  715. if (!cp)
  716. break;
  717. switch (fs_type_flag[n]) {
  718. case FS_TYPE_FLAG_NORMAL:
  719. checked_type++;
  720. if (strcmp(cp, fs->type) == 0)
  721. ret = 1;
  722. break;
  723. case FS_TYPE_FLAG_NEGOPT:
  724. if (opt_in_list(cp, fs->opts))
  725. return 0;
  726. break;
  727. case FS_TYPE_FLAG_OPT:
  728. if (!opt_in_list(cp, fs->opts))
  729. return 0;
  730. break;
  731. }
  732. n++;
  733. }
  734. if (checked_type == 0)
  735. return 1;
  736. return (fs_type_negated ? !ret : ret);
  737. }
  738. /* Check if we should ignore this filesystem. */
  739. static int ignore(struct fs_info *fs)
  740. {
  741. /*
  742. * If the pass number is 0, ignore it.
  743. */
  744. if (fs->passno == 0)
  745. return 1;
  746. /*
  747. * If a specific fstype is specified, and it doesn't match,
  748. * ignore it.
  749. */
  750. if (!fs_match(fs))
  751. return 1;
  752. /* Are we ignoring this type? */
  753. if (index_in_strings(ignored_types, fs->type) >= 0)
  754. return 1;
  755. /* We can and want to check this file system type. */
  756. return 0;
  757. }
  758. /* Check all file systems, using the /etc/fstab table. */
  759. static int check_all(void)
  760. {
  761. struct fs_info *fs;
  762. int status = EXIT_OK;
  763. smallint not_done_yet;
  764. smallint pass_done;
  765. int passno;
  766. if (verbose)
  767. puts("Checking all filesystems");
  768. /*
  769. * Do an initial scan over the filesystem; mark filesystems
  770. * which should be ignored as done, and resolve any "auto"
  771. * filesystem types (done as a side-effect of calling ignore()).
  772. */
  773. for (fs = filesys_info; fs; fs = fs->next) {
  774. if (ignore(fs))
  775. fs->flags |= FLAG_DONE;
  776. }
  777. /*
  778. * Find and check the root filesystem.
  779. */
  780. if (!parallel_root) {
  781. for (fs = filesys_info; fs; fs = fs->next) {
  782. if (LONE_CHAR(fs->mountpt, '/'))
  783. break;
  784. }
  785. if (fs) {
  786. if (!skip_root && !ignore(fs)) {
  787. fsck_device(fs, 1);
  788. status |= wait_many(FLAG_WAIT_ALL);
  789. if (status > EXIT_NONDESTRUCT)
  790. return status;
  791. }
  792. fs->flags |= FLAG_DONE;
  793. }
  794. }
  795. /*
  796. * This is for the bone-headed user who enters the root
  797. * filesystem twice. Skip root will skip all root entries.
  798. */
  799. if (skip_root)
  800. for (fs = filesys_info; fs; fs = fs->next)
  801. if (LONE_CHAR(fs->mountpt, '/'))
  802. fs->flags |= FLAG_DONE;
  803. not_done_yet = 1;
  804. passno = 1;
  805. while (not_done_yet) {
  806. not_done_yet = 0;
  807. pass_done = 1;
  808. for (fs = filesys_info; fs; fs = fs->next) {
  809. if (cancel_requested)
  810. break;
  811. if (fs->flags & FLAG_DONE)
  812. continue;
  813. /*
  814. * If the filesystem's pass number is higher
  815. * than the current pass number, then we don't
  816. * do it yet.
  817. */
  818. if (fs->passno > passno) {
  819. not_done_yet = 1;
  820. continue;
  821. }
  822. /*
  823. * If a filesystem on a particular device has
  824. * already been spawned, then we need to defer
  825. * this to another pass.
  826. */
  827. if (device_already_active(fs->device)) {
  828. pass_done = 0;
  829. continue;
  830. }
  831. /*
  832. * Spawn off the fsck process
  833. */
  834. fsck_device(fs, serialize);
  835. fs->flags |= FLAG_DONE;
  836. /*
  837. * Only do one filesystem at a time, or if we
  838. * have a limit on the number of fsck's extant
  839. * at one time, apply that limit.
  840. */
  841. if (serialize
  842. || (max_running && (num_running >= max_running))
  843. ) {
  844. pass_done = 0;
  845. break;
  846. }
  847. }
  848. if (cancel_requested)
  849. break;
  850. if (verbose > 1)
  851. printf("--waiting-- (pass %d)\n", passno);
  852. status |= wait_many(pass_done ? FLAG_WAIT_ALL :
  853. FLAG_WAIT_ATLEAST_ONE);
  854. if (pass_done) {
  855. if (verbose > 1)
  856. puts("----------------------------------");
  857. passno++;
  858. } else
  859. not_done_yet = 1;
  860. }
  861. kill_all_if_cancel_requested();
  862. status |= wait_many(FLAG_WAIT_ATLEAST_ONE);
  863. return status;
  864. }
  865. /*
  866. * Deal with the fsck -t argument.
  867. * Huh, for mount "-t novfat,nfs" means "neither vfat nor nfs"!
  868. * Why here we require "-t novfat,nonfs" ??
  869. */
  870. static void compile_fs_type(char *fs_type)
  871. {
  872. char *s;
  873. int num = 2;
  874. smallint negate;
  875. if (fs_type) {
  876. s = fs_type;
  877. while ((s = strchr(s, ','))) {
  878. num++;
  879. s++;
  880. }
  881. }
  882. fs_type_list = xzalloc(num * sizeof(fs_type_list[0]));
  883. fs_type_flag = xzalloc(num * sizeof(fs_type_flag[0]));
  884. fs_type_negated = -1; /* not yet known is it negated or not */
  885. if (!fs_type)
  886. return;
  887. num = 0;
  888. s = fs_type;
  889. while (1) {
  890. char *comma;
  891. negate = 0;
  892. if (s[0] == 'n' && s[1] == 'o') { /* "no.." */
  893. s += 2;
  894. negate = 1;
  895. } else if (s[0] == '!') {
  896. s++;
  897. negate = 1;
  898. }
  899. if (strcmp(s, "loop") == 0)
  900. /* loop is really short-hand for opts=loop */
  901. goto loop_special_case;
  902. if (strncmp(s, "opts=", 5) == 0) {
  903. s += 5;
  904. loop_special_case:
  905. fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT;
  906. } else {
  907. if (fs_type_negated == -1)
  908. fs_type_negated = negate;
  909. if (fs_type_negated != negate)
  910. bb_error_msg_and_die(
  911. "either all or none of the filesystem types passed to -t must be prefixed "
  912. "with 'no' or '!'");
  913. }
  914. comma = strchr(s, ',');
  915. fs_type_list[num++] = comma ? xstrndup(s, comma-s) : xstrdup(s);
  916. if (!comma)
  917. break;
  918. s = comma + 1;
  919. }
  920. }
  921. static void parse_args(int argc, char **argv)
  922. {
  923. int i, j;
  924. char *arg, *tmp;
  925. char *options = NULL;
  926. int optpos = 0;
  927. int opts_for_fsck = 0;
  928. /* in bss, so already zeroed
  929. num_devices = 0;
  930. num_args = 0;
  931. instance_list = NULL;
  932. */
  933. /* TODO: getopt32 */
  934. for (i = 1; i < argc; i++) {
  935. arg = argv[i];
  936. /* "/dev/blk" or "/path" or "UUID=xxx" or "LABEL=xxx" */
  937. if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) {
  938. // FIXME: must check that arg is a blkdev, or resolve
  939. // "/path", "UUID=xxx" or "LABEL=xxx" into block device name
  940. // ("UUID=xxx"/"LABEL=xxx" can probably shifted to fsck.auto duties)
  941. devices = xrealloc(devices, (num_devices+1) * sizeof(devices[0]));
  942. devices[num_devices++] = xstrdup(arg);
  943. continue;
  944. }
  945. if (arg[0] != '-' || opts_for_fsck) {
  946. args = xrealloc(args, (num_args+1) * sizeof(args[0]));
  947. args[num_args++] = xstrdup(arg);
  948. continue;
  949. }
  950. for (j = 1; arg[j]; j++) {
  951. if (opts_for_fsck) {
  952. optpos++;
  953. /* one extra for '\0' */
  954. options = xrealloc(options, optpos + 2);
  955. options[optpos] = arg[j];
  956. continue;
  957. }
  958. switch (arg[j]) {
  959. case 'A':
  960. doall = 1;
  961. break;
  962. #if DO_PROGRESS_INDICATOR
  963. case 'C':
  964. progress = 1;
  965. if (arg[++j]) { /* -Cn */
  966. progress_fd = xatoi_u(&arg[j]);
  967. goto next_arg;
  968. }
  969. /* -C n */
  970. progress_fd = xatoi_u(argv[++i]);
  971. goto next_arg;
  972. #endif
  973. case 'V':
  974. verbose++;
  975. break;
  976. case 'N':
  977. noexecute = 1;
  978. break;
  979. case 'R':
  980. skip_root = 1;
  981. break;
  982. case 'T':
  983. notitle = 1;
  984. break;
  985. /* case 'M':
  986. like_mount = 1;
  987. break; */
  988. case 'P':
  989. parallel_root = 1;
  990. break;
  991. case 's':
  992. serialize = 1;
  993. break;
  994. case 't':
  995. if (fstype)
  996. bb_show_usage();
  997. if (arg[++j])
  998. tmp = &arg[j];
  999. else if (++i < argc)
  1000. tmp = argv[i];
  1001. else
  1002. bb_show_usage();
  1003. fstype = xstrdup(tmp);
  1004. compile_fs_type(fstype);
  1005. goto next_arg;
  1006. case '-':
  1007. opts_for_fsck++;
  1008. break;
  1009. case '?':
  1010. bb_show_usage();
  1011. break;
  1012. default:
  1013. optpos++;
  1014. /* one extra for '\0' */
  1015. options = xrealloc(options, optpos + 2);
  1016. options[optpos] = arg[j];
  1017. break;
  1018. }
  1019. }
  1020. next_arg:
  1021. if (optpos) {
  1022. options[0] = '-';
  1023. options[optpos + 1] = '\0';
  1024. args = xrealloc(args, (num_args+1) * sizeof(args[0]));
  1025. args[num_args++] = options;
  1026. optpos = 0;
  1027. options = NULL;
  1028. }
  1029. }
  1030. if (getenv("FSCK_FORCE_ALL_PARALLEL"))
  1031. force_all_parallel = 1;
  1032. tmp = getenv("FSCK_MAX_INST");
  1033. if (tmp)
  1034. max_running = xatoi(tmp);
  1035. }
  1036. static void signal_cancel(int sig ATTRIBUTE_UNUSED)
  1037. {
  1038. cancel_requested = 1;
  1039. }
  1040. int fsck_main(int argc, char **argv);
  1041. int fsck_main(int argc, char **argv)
  1042. {
  1043. int i, status = 0;
  1044. int interactive;
  1045. const char *fstab;
  1046. struct fs_info *fs;
  1047. struct sigaction sa;
  1048. memset(&sa, 0, sizeof(sa));
  1049. sa.sa_handler = signal_cancel;
  1050. sigaction(SIGINT, &sa, 0);
  1051. sigaction(SIGTERM, &sa, 0);
  1052. setbuf(stdout, NULL);
  1053. parse_args(argc, argv);
  1054. if (!notitle)
  1055. puts("fsck (busybox "BB_VER", "BB_BT")");
  1056. /* Even plain "fsck /dev/hda1" needs fstab to get fs type,
  1057. * so we are scanning it anyway */
  1058. fstab = getenv("FSTAB_FILE");
  1059. if (!fstab)
  1060. fstab = "/etc/fstab";
  1061. load_fs_info(fstab);
  1062. interactive = (num_devices == 1) | serialize;
  1063. /* If -A was specified ("check all"), do that! */
  1064. if (doall)
  1065. return check_all();
  1066. if (num_devices == 0) {
  1067. serialize = 1;
  1068. interactive = 1;
  1069. return check_all();
  1070. }
  1071. for (i = 0; i < num_devices; i++) {
  1072. if (cancel_requested) {
  1073. kill_all_if_cancel_requested();
  1074. break;
  1075. }
  1076. fs = lookup(devices[i]);
  1077. if (!fs)
  1078. fs = create_fs_device(devices[i], 0, "auto", 0, -1, -1);
  1079. fsck_device(fs, interactive);
  1080. if (serialize
  1081. || (max_running && (num_running >= max_running))
  1082. ) {
  1083. struct fsck_instance *inst;
  1084. inst = wait_one(0);
  1085. if (inst) {
  1086. status |= inst->exit_status;
  1087. free_instance(inst);
  1088. }
  1089. if (verbose > 1)
  1090. puts("----------------------------------");
  1091. }
  1092. }
  1093. status |= wait_many(FLAG_WAIT_ALL);
  1094. return status;
  1095. }