failtest.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. /* Licensed under LGPL - see LICENSE file for details */
  2. #include <ccan/failtest/failtest.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <stdarg.h>
  7. #include <ctype.h>
  8. #include <err.h>
  9. #include <unistd.h>
  10. #include <poll.h>
  11. #include <errno.h>
  12. #include <sys/types.h>
  13. #include <sys/wait.h>
  14. #include <sys/stat.h>
  15. #include <sys/time.h>
  16. #include <signal.h>
  17. #include <assert.h>
  18. #include <ccan/time/time.h>
  19. #include <ccan/read_write_all/read_write_all.h>
  20. #include <ccan/failtest/failtest_proto.h>
  21. #include <ccan/build_assert/build_assert.h>
  22. #include <ccan/str/str.h>
  23. enum failtest_result (*failtest_hook)(struct tlist_calls *);
  24. static int tracefd = -1;
  25. unsigned int failtest_timeout_ms = 20000;
  26. const char *failpath;
  27. const char *debugpath;
  28. enum info_type {
  29. WRITE,
  30. RELEASE_LOCKS,
  31. FAILURE,
  32. SUCCESS,
  33. UNEXPECTED
  34. };
  35. struct lock_info {
  36. int fd;
  37. /* end is inclusive: you can't have a 0-byte lock. */
  38. off_t start, end;
  39. int type;
  40. };
  41. bool (*failtest_exit_check)(struct tlist_calls *history);
  42. static struct tlist_calls history = TLIST_INIT(history);
  43. static int control_fd = -1;
  44. static struct timeval start;
  45. static unsigned int probe_count = 0;
  46. static struct write_call *child_writes = NULL;
  47. static unsigned int child_writes_num = 0;
  48. static pid_t lock_owner;
  49. static struct lock_info *locks = NULL;
  50. static unsigned int lock_num = 0;
  51. static pid_t orig_pid;
  52. static const char info_to_arg[] = "mceoxprwf";
  53. /* Dummy call used for failtest_undo wrappers. */
  54. static struct failtest_call unrecorded_call;
  55. static struct failtest_call *add_history_(enum failtest_call_type type,
  56. const char *file,
  57. unsigned int line,
  58. const void *elem,
  59. size_t elem_size)
  60. {
  61. struct failtest_call *call;
  62. /* NULL file is how we suppress failure. */
  63. if (!file)
  64. return &unrecorded_call;
  65. call = malloc(sizeof *call);
  66. call->type = type;
  67. call->file = file;
  68. call->line = line;
  69. call->cleanup = NULL;
  70. memcpy(&call->u, elem, elem_size);
  71. tlist_add_tail(&history, call, list);
  72. return call;
  73. }
  74. #define add_history(type, file, line, elem) \
  75. add_history_((type), (file), (line), (elem), sizeof(*(elem)))
  76. /* We do a fake call inside a sizeof(), to check types. */
  77. #define set_cleanup(call, clean, type) \
  78. (call)->cleanup = (void *)((void)sizeof(clean((type *)NULL),1), (clean))
  79. static bool read_write_info(int fd)
  80. {
  81. struct write_call *w;
  82. char *buf;
  83. /* We don't need all of this, but it's simple. */
  84. child_writes = realloc(child_writes,
  85. (child_writes_num+1) * sizeof(child_writes[0]));
  86. w = &child_writes[child_writes_num];
  87. if (!read_all(fd, w, sizeof(*w)))
  88. return false;
  89. w->buf = buf = malloc(w->count);
  90. if (!read_all(fd, buf, w->count))
  91. return false;
  92. child_writes_num++;
  93. return true;
  94. }
  95. static char *failpath_string(void)
  96. {
  97. struct failtest_call *i;
  98. char *ret = strdup("");
  99. unsigned len = 0;
  100. /* Inefficient, but who cares? */
  101. tlist_for_each(&history, i, list) {
  102. ret = realloc(ret, len + 2);
  103. ret[len] = info_to_arg[i->type];
  104. if (i->fail)
  105. ret[len] = toupper(ret[len]);
  106. ret[++len] = '\0';
  107. }
  108. return ret;
  109. }
  110. static void tell_parent(enum info_type type)
  111. {
  112. if (control_fd != -1)
  113. write_all(control_fd, &type, sizeof(type));
  114. }
  115. static void child_fail(const char *out, size_t outlen, const char *fmt, ...)
  116. {
  117. va_list ap;
  118. char *path = failpath_string();
  119. va_start(ap, fmt);
  120. vfprintf(stderr, fmt, ap);
  121. va_end(ap);
  122. fprintf(stderr, "%.*s", (int)outlen, out);
  123. printf("To reproduce: --failpath=%s\n", path);
  124. free(path);
  125. tell_parent(FAILURE);
  126. exit(1);
  127. }
  128. static void trace(const char *fmt, ...)
  129. {
  130. va_list ap;
  131. if (tracefd == -1)
  132. return;
  133. va_start(ap, fmt);
  134. vdprintf(tracefd, fmt, ap);
  135. va_end(ap);
  136. }
  137. static pid_t child;
  138. static void hand_down(int signum)
  139. {
  140. kill(child, signum);
  141. }
  142. static void release_locks(void)
  143. {
  144. /* Locks were never acquired/reacquired? */
  145. if (lock_owner == 0)
  146. return;
  147. /* We own them? Release them all. */
  148. if (lock_owner == getpid()) {
  149. unsigned int i;
  150. struct flock fl;
  151. fl.l_type = F_UNLCK;
  152. fl.l_whence = SEEK_SET;
  153. fl.l_start = 0;
  154. fl.l_len = 0;
  155. for (i = 0; i < lock_num; i++)
  156. fcntl(locks[i].fd, F_SETLK, &fl);
  157. } else {
  158. /* Our parent must have them; pass request up. */
  159. enum info_type type = RELEASE_LOCKS;
  160. assert(control_fd != -1);
  161. write_all(control_fd, &type, sizeof(type));
  162. }
  163. lock_owner = 0;
  164. }
  165. /* off_t is a signed type. Getting its max is non-trivial. */
  166. static off_t off_max(void)
  167. {
  168. BUILD_ASSERT(sizeof(off_t) == 4 || sizeof(off_t) == 8);
  169. if (sizeof(off_t) == 4)
  170. return (off_t)0x7FFFFFF;
  171. else
  172. return (off_t)0x7FFFFFFFFFFFFFFULL;
  173. }
  174. static void get_locks(void)
  175. {
  176. unsigned int i;
  177. struct flock fl;
  178. if (lock_owner == getpid())
  179. return;
  180. if (lock_owner != 0) {
  181. enum info_type type = RELEASE_LOCKS;
  182. assert(control_fd != -1);
  183. write_all(control_fd, &type, sizeof(type));
  184. }
  185. fl.l_whence = SEEK_SET;
  186. for (i = 0; i < lock_num; i++) {
  187. fl.l_type = locks[i].type;
  188. fl.l_start = locks[i].start;
  189. if (locks[i].end == off_max())
  190. fl.l_len = 0;
  191. else
  192. fl.l_len = locks[i].end - locks[i].start + 1;
  193. if (fcntl(locks[i].fd, F_SETLKW, &fl) != 0)
  194. abort();
  195. }
  196. lock_owner = getpid();
  197. }
  198. struct saved_file {
  199. struct saved_file *next;
  200. int fd;
  201. void *contents;
  202. off_t off, len;
  203. };
  204. static struct saved_file *save_file(struct saved_file *next, int fd)
  205. {
  206. struct saved_file *s = malloc(sizeof(*s));
  207. s->next = next;
  208. s->fd = fd;
  209. s->off = lseek(fd, 0, SEEK_CUR);
  210. /* Special file? Erk... */
  211. assert(s->off != -1);
  212. s->len = lseek(fd, 0, SEEK_END);
  213. lseek(fd, 0, SEEK_SET);
  214. s->contents = malloc(s->len);
  215. if (read(fd, s->contents, s->len) != s->len)
  216. err(1, "Failed to save %zu bytes", (size_t)s->len);
  217. lseek(fd, s->off, SEEK_SET);
  218. return s;
  219. }
  220. /* We have little choice but to save and restore open files: mmap means we
  221. * can really intercept changes in the child.
  222. *
  223. * We could do non-mmap'ed files on demand, however. */
  224. static struct saved_file *save_files(void)
  225. {
  226. struct saved_file *files = NULL;
  227. struct failtest_call *i;
  228. /* Figure out the set of live fds. */
  229. tlist_for_each_rev(&history, i, list) {
  230. if (i->type == FAILTEST_OPEN) {
  231. int fd = i->u.open.ret;
  232. /* Only do successful, writable fds. */
  233. if (fd < 0)
  234. continue;
  235. /* If it was closed, cleanup == NULL. */
  236. if (!i->cleanup)
  237. continue;
  238. if ((i->u.open.flags & O_RDWR) == O_RDWR) {
  239. files = save_file(files, fd);
  240. } else if ((i->u.open.flags & O_WRONLY)
  241. == O_WRONLY) {
  242. /* FIXME: Handle O_WRONLY. Open with O_RDWR? */
  243. abort();
  244. }
  245. }
  246. }
  247. return files;
  248. }
  249. static void restore_files(struct saved_file *s)
  250. {
  251. while (s) {
  252. struct saved_file *next = s->next;
  253. lseek(s->fd, 0, SEEK_SET);
  254. if (write(s->fd, s->contents, s->len) != s->len)
  255. err(1, "Failed to restore %zu bytes", (size_t)s->len);
  256. if (ftruncate(s->fd, s->len) != 0)
  257. err(1, "Failed to trim file to length %zu",
  258. (size_t)s->len);
  259. free(s->contents);
  260. lseek(s->fd, s->off, SEEK_SET);
  261. free(s);
  262. s = next;
  263. }
  264. }
  265. static void free_files(struct saved_file *s)
  266. {
  267. while (s) {
  268. struct saved_file *next = s->next;
  269. free(s->contents);
  270. free(s);
  271. s = next;
  272. }
  273. }
  274. static void free_call(struct failtest_call *call)
  275. {
  276. /* We don't do this in cleanup: needed even for failed opens. */
  277. if (call->type == FAILTEST_OPEN)
  278. free((char *)call->u.open.pathname);
  279. tlist_del_from(&history, call, list);
  280. free(call);
  281. }
  282. /* Free up memory, so valgrind doesn't report leaks. */
  283. static void free_everything(void)
  284. {
  285. struct failtest_call *i;
  286. while ((i = tlist_top(&history, struct failtest_call, list)) != NULL)
  287. free_call(i);
  288. }
  289. static NORETURN void failtest_cleanup(bool forced_cleanup, int status)
  290. {
  291. struct failtest_call *i;
  292. /* For children, we don't care if they "failed" the testing. */
  293. if (control_fd != -1)
  294. status = 0;
  295. if (forced_cleanup) {
  296. /* We didn't actually do final operation: remove it. */
  297. i = tlist_tail(&history, struct failtest_call, list);
  298. free_call(i);
  299. }
  300. /* Cleanup everything, in reverse order. */
  301. tlist_for_each_rev(&history, i, list) {
  302. if (!i->cleanup)
  303. continue;
  304. if (!forced_cleanup) {
  305. printf("Leak at %s:%u: --failpath=%s\n",
  306. i->file, i->line, failpath_string());
  307. status = 1;
  308. }
  309. i->cleanup(&i->u);
  310. }
  311. free_everything();
  312. tell_parent(SUCCESS);
  313. exit(status);
  314. }
  315. static bool should_fail(struct failtest_call *call)
  316. {
  317. int status;
  318. int control[2], output[2];
  319. enum info_type type = UNEXPECTED;
  320. char *out = NULL;
  321. size_t outlen = 0;
  322. struct saved_file *files;
  323. /* Are we probing? */
  324. if (probe_count && --probe_count == 0 && control_fd != -1)
  325. failtest_cleanup(true, 0);
  326. if (call == &unrecorded_call)
  327. return false;
  328. if (failpath) {
  329. /* + means continue after end, like normal. */
  330. if (*failpath == '+')
  331. failpath = NULL;
  332. else if (*failpath == '\0') {
  333. /* Continue, but don't inject errors. */
  334. return call->fail = false;
  335. } else {
  336. if (tolower((unsigned char)*failpath)
  337. != info_to_arg[call->type])
  338. errx(1, "Failpath expected '%c' got '%c'\n",
  339. info_to_arg[call->type], *failpath);
  340. call->fail = cisupper(*(failpath++));
  341. return call->fail;
  342. }
  343. }
  344. /* Attach debugger if they asked for it. */
  345. if (debugpath) {
  346. char *path = failpath_string();
  347. if (streq(path, debugpath)) {
  348. char str[80];
  349. /* Don't timeout. */
  350. signal(SIGUSR1, SIG_IGN);
  351. sprintf(str, "xterm -e gdb /proc/%d/exe %d &",
  352. getpid(), getpid());
  353. if (system(str) == 0)
  354. sleep(5);
  355. } else if (!strstarts(path, debugpath)) {
  356. fprintf(stderr, "--debugpath not followed: %s\n", path);
  357. debugpath = NULL;
  358. }
  359. free(path);
  360. }
  361. if (failtest_hook) {
  362. switch (failtest_hook(&history)) {
  363. case FAIL_OK:
  364. break;
  365. case FAIL_PROBE:
  366. /* Already down probe path? Stop now. */
  367. if (!probe_count) {
  368. /* FIXME: We should run *parent* and
  369. * run probe until calls match up again. */
  370. probe_count = 3;
  371. break;
  372. } else {
  373. /* Child should give up now. */
  374. if (control_fd != -1)
  375. failtest_cleanup(true, 0);
  376. /* Parent, don't fail again. */
  377. }
  378. case FAIL_DONT_FAIL:
  379. call->fail = false;
  380. return false;
  381. default:
  382. abort();
  383. }
  384. }
  385. files = save_files();
  386. /* We're going to fail in the child. */
  387. call->fail = true;
  388. if (pipe(control) != 0 || pipe(output) != 0)
  389. err(1, "opening pipe");
  390. /* Prevent double-printing (in child and parent) */
  391. fflush(stdout);
  392. child = fork();
  393. if (child == -1)
  394. err(1, "forking failed");
  395. if (child == 0) {
  396. if (tracefd != -1) {
  397. struct timeval diff;
  398. const char *p;
  399. char *failpath;
  400. struct failtest_call *c;
  401. c = tlist_tail(&history, struct failtest_call, list);
  402. diff = time_sub(time_now(), start);
  403. failpath = failpath_string();
  404. trace("%u->%u (%u.%02u): %s (", getppid(), getpid(),
  405. (int)diff.tv_sec, (int)diff.tv_usec / 10000,
  406. failpath);
  407. free(failpath);
  408. p = strrchr(c->file, '/');
  409. if (p)
  410. trace("%s", p+1);
  411. else
  412. trace("%s", c->file);
  413. trace(":%u)\n", c->line);
  414. }
  415. close(control[0]);
  416. close(output[0]);
  417. dup2(output[1], STDOUT_FILENO);
  418. dup2(output[1], STDERR_FILENO);
  419. if (output[1] != STDOUT_FILENO && output[1] != STDERR_FILENO)
  420. close(output[1]);
  421. control_fd = control[1];
  422. /* Valgrind spots the leak if we don't free these. */
  423. free_files(files);
  424. return true;
  425. }
  426. signal(SIGUSR1, hand_down);
  427. close(control[1]);
  428. close(output[1]);
  429. /* We grab output so we can display it; we grab writes so we
  430. * can compare. */
  431. do {
  432. struct pollfd pfd[2];
  433. int ret;
  434. pfd[0].fd = output[0];
  435. pfd[0].events = POLLIN|POLLHUP;
  436. pfd[1].fd = control[0];
  437. pfd[1].events = POLLIN|POLLHUP;
  438. if (type == SUCCESS)
  439. ret = poll(pfd, 1, failtest_timeout_ms);
  440. else
  441. ret = poll(pfd, 2, failtest_timeout_ms);
  442. if (ret == 0)
  443. hand_down(SIGUSR1);
  444. if (ret < 0) {
  445. if (errno == EINTR)
  446. continue;
  447. err(1, "Poll returned %i", ret);
  448. }
  449. if (pfd[0].revents & POLLIN) {
  450. ssize_t len;
  451. out = realloc(out, outlen + 8192);
  452. len = read(output[0], out + outlen, 8192);
  453. outlen += len;
  454. } else if (type != SUCCESS && (pfd[1].revents & POLLIN)) {
  455. if (read_all(control[0], &type, sizeof(type))) {
  456. if (type == WRITE) {
  457. if (!read_write_info(control[0]))
  458. break;
  459. } else if (type == RELEASE_LOCKS) {
  460. release_locks();
  461. /* FIXME: Tell them we're done... */
  462. }
  463. }
  464. } else if (pfd[0].revents & POLLHUP) {
  465. break;
  466. }
  467. } while (type != FAILURE);
  468. close(output[0]);
  469. close(control[0]);
  470. waitpid(child, &status, 0);
  471. if (!WIFEXITED(status)) {
  472. if (WTERMSIG(status) == SIGUSR1)
  473. child_fail(out, outlen, "Timed out");
  474. else
  475. child_fail(out, outlen, "Killed by signal %u: ",
  476. WTERMSIG(status));
  477. }
  478. /* Child printed failure already, just pass up exit code. */
  479. if (type == FAILURE) {
  480. fprintf(stderr, "%.*s", (int)outlen, out);
  481. tell_parent(type);
  482. exit(WEXITSTATUS(status) ? WEXITSTATUS(status) : 1);
  483. }
  484. if (WEXITSTATUS(status) != 0)
  485. child_fail(out, outlen, "Exited with status %i: ",
  486. WEXITSTATUS(status));
  487. free(out);
  488. signal(SIGUSR1, SIG_DFL);
  489. restore_files(files);
  490. /* We continue onwards without failing. */
  491. call->fail = false;
  492. return false;
  493. }
  494. static void cleanup_calloc(struct calloc_call *call)
  495. {
  496. free(call->ret);
  497. }
  498. void *failtest_calloc(size_t nmemb, size_t size,
  499. const char *file, unsigned line)
  500. {
  501. struct failtest_call *p;
  502. struct calloc_call call;
  503. call.nmemb = nmemb;
  504. call.size = size;
  505. p = add_history(FAILTEST_CALLOC, file, line, &call);
  506. if (should_fail(p)) {
  507. p->u.calloc.ret = NULL;
  508. p->error = ENOMEM;
  509. } else {
  510. p->u.calloc.ret = calloc(nmemb, size);
  511. set_cleanup(p, cleanup_calloc, struct calloc_call);
  512. }
  513. errno = p->error;
  514. return p->u.calloc.ret;
  515. }
  516. static void cleanup_malloc(struct malloc_call *call)
  517. {
  518. free(call->ret);
  519. }
  520. void *failtest_malloc(size_t size, const char *file, unsigned line)
  521. {
  522. struct failtest_call *p;
  523. struct malloc_call call;
  524. call.size = size;
  525. p = add_history(FAILTEST_MALLOC, file, line, &call);
  526. if (should_fail(p)) {
  527. p->u.malloc.ret = NULL;
  528. p->error = ENOMEM;
  529. } else {
  530. p->u.malloc.ret = malloc(size);
  531. set_cleanup(p, cleanup_malloc, struct malloc_call);
  532. }
  533. errno = p->error;
  534. return p->u.malloc.ret;
  535. }
  536. static void cleanup_realloc(struct realloc_call *call)
  537. {
  538. free(call->ret);
  539. }
  540. /* Walk back and find out if we got this ptr from a previous routine. */
  541. static void fixup_ptr_history(void *ptr)
  542. {
  543. struct failtest_call *i;
  544. /* Start at end of history, work back. */
  545. tlist_for_each_rev(&history, i, list) {
  546. switch (i->type) {
  547. case FAILTEST_REALLOC:
  548. if (i->u.realloc.ret == ptr) {
  549. i->cleanup = NULL;
  550. return;
  551. }
  552. break;
  553. case FAILTEST_MALLOC:
  554. if (i->u.malloc.ret == ptr) {
  555. i->cleanup = NULL;
  556. return;
  557. }
  558. break;
  559. case FAILTEST_CALLOC:
  560. if (i->u.calloc.ret == ptr) {
  561. i->cleanup = NULL;
  562. return;
  563. }
  564. break;
  565. default:
  566. break;
  567. }
  568. }
  569. }
  570. void *failtest_realloc(void *ptr, size_t size, const char *file, unsigned line)
  571. {
  572. struct failtest_call *p;
  573. struct realloc_call call;
  574. call.size = size;
  575. p = add_history(FAILTEST_REALLOC, file, line, &call);
  576. /* FIXME: Try one child moving allocation, one not. */
  577. if (should_fail(p)) {
  578. p->u.realloc.ret = NULL;
  579. p->error = ENOMEM;
  580. } else {
  581. /* Don't catch this one in the history fixup... */
  582. p->u.realloc.ret = NULL;
  583. fixup_ptr_history(ptr);
  584. p->u.realloc.ret = realloc(ptr, size);
  585. set_cleanup(p, cleanup_realloc, struct realloc_call);
  586. }
  587. errno = p->error;
  588. return p->u.realloc.ret;
  589. }
  590. void failtest_free(void *ptr)
  591. {
  592. fixup_ptr_history(ptr);
  593. free(ptr);
  594. }
  595. static void cleanup_open(struct open_call *call)
  596. {
  597. close(call->ret);
  598. }
  599. int failtest_open(const char *pathname,
  600. const char *file, unsigned line, ...)
  601. {
  602. struct failtest_call *p;
  603. struct open_call call;
  604. va_list ap;
  605. call.pathname = strdup(pathname);
  606. va_start(ap, line);
  607. call.flags = va_arg(ap, int);
  608. if (call.flags & O_CREAT) {
  609. call.mode = va_arg(ap, int);
  610. va_end(ap);
  611. }
  612. p = add_history(FAILTEST_OPEN, file, line, &call);
  613. /* Avoid memory leak! */
  614. if (p == &unrecorded_call)
  615. free((char *)call.pathname);
  616. p->u.open.ret = open(pathname, call.flags, call.mode);
  617. if (p->u.open.ret == -1) {
  618. p->fail = false;
  619. p->error = errno;
  620. } else if (should_fail(p)) {
  621. close(p->u.open.ret);
  622. p->u.open.ret = -1;
  623. /* FIXME: Play with error codes? */
  624. p->error = EACCES;
  625. } else {
  626. set_cleanup(p, cleanup_open, struct open_call);
  627. }
  628. errno = p->error;
  629. return p->u.open.ret;
  630. }
  631. static void cleanup_pipe(struct pipe_call *call)
  632. {
  633. if (!call->closed[0])
  634. close(call->fds[0]);
  635. if (!call->closed[1])
  636. close(call->fds[1]);
  637. }
  638. int failtest_pipe(int pipefd[2], const char *file, unsigned line)
  639. {
  640. struct failtest_call *p;
  641. struct pipe_call call;
  642. p = add_history(FAILTEST_PIPE, file, line, &call);
  643. if (should_fail(p)) {
  644. p->u.open.ret = -1;
  645. /* FIXME: Play with error codes? */
  646. p->error = EMFILE;
  647. } else {
  648. p->u.pipe.ret = pipe(p->u.pipe.fds);
  649. p->u.pipe.closed[0] = p->u.pipe.closed[1] = false;
  650. set_cleanup(p, cleanup_pipe, struct pipe_call);
  651. }
  652. /* This causes valgrind to notice if they use pipefd[] after failure */
  653. memcpy(pipefd, p->u.pipe.fds, sizeof(p->u.pipe.fds));
  654. errno = p->error;
  655. return p->u.pipe.ret;
  656. }
  657. ssize_t failtest_pread(int fd, void *buf, size_t count, off_t off,
  658. const char *file, unsigned line)
  659. {
  660. struct failtest_call *p;
  661. struct read_call call;
  662. call.fd = fd;
  663. call.buf = buf;
  664. call.count = count;
  665. call.off = off;
  666. p = add_history(FAILTEST_READ, file, line, &call);
  667. /* FIXME: Try partial read returns. */
  668. if (should_fail(p)) {
  669. p->u.read.ret = -1;
  670. p->error = EIO;
  671. } else {
  672. p->u.read.ret = pread(fd, buf, count, off);
  673. }
  674. errno = p->error;
  675. return p->u.read.ret;
  676. }
  677. ssize_t failtest_pwrite(int fd, const void *buf, size_t count, off_t off,
  678. const char *file, unsigned line)
  679. {
  680. struct failtest_call *p;
  681. struct write_call call;
  682. call.fd = fd;
  683. call.buf = buf;
  684. call.count = count;
  685. call.off = off;
  686. p = add_history(FAILTEST_WRITE, file, line, &call);
  687. /* If we're a child, we need to make sure we write the same thing
  688. * to non-files as the parent does, so tell it. */
  689. if (control_fd != -1 && off == (off_t)-1) {
  690. enum info_type type = WRITE;
  691. write_all(control_fd, &type, sizeof(type));
  692. write_all(control_fd, &p->u.write, sizeof(p->u.write));
  693. write_all(control_fd, buf, count);
  694. }
  695. /* FIXME: Try partial write returns. */
  696. if (should_fail(p)) {
  697. p->u.write.ret = -1;
  698. p->error = EIO;
  699. } else {
  700. /* FIXME: We assume same write order in parent and child */
  701. if (off == (off_t)-1 && child_writes_num != 0) {
  702. if (child_writes[0].fd != fd)
  703. errx(1, "Child wrote to fd %u, not %u?",
  704. child_writes[0].fd, fd);
  705. if (child_writes[0].off != p->u.write.off)
  706. errx(1, "Child wrote to offset %zu, not %zu?",
  707. (size_t)child_writes[0].off,
  708. (size_t)p->u.write.off);
  709. if (child_writes[0].count != count)
  710. errx(1, "Child wrote length %zu, not %zu?",
  711. child_writes[0].count, count);
  712. if (memcmp(child_writes[0].buf, buf, count)) {
  713. child_fail(NULL, 0,
  714. "Child wrote differently to"
  715. " fd %u than we did!\n", fd);
  716. }
  717. free((char *)child_writes[0].buf);
  718. child_writes_num--;
  719. memmove(&child_writes[0], &child_writes[1],
  720. sizeof(child_writes[0]) * child_writes_num);
  721. /* Is this is a socket or pipe, child wrote it
  722. already. */
  723. if (p->u.write.off == (off_t)-1) {
  724. p->u.write.ret = count;
  725. errno = p->error;
  726. return p->u.write.ret;
  727. }
  728. }
  729. p->u.write.ret = pwrite(fd, buf, count, off);
  730. }
  731. errno = p->error;
  732. return p->u.write.ret;
  733. }
  734. ssize_t failtest_read(int fd, void *buf, size_t count,
  735. const char *file, unsigned line)
  736. {
  737. return failtest_pread(fd, buf, count, lseek(fd, 0, SEEK_CUR),
  738. file, line);
  739. }
  740. ssize_t failtest_write(int fd, const void *buf, size_t count,
  741. const char *file, unsigned line)
  742. {
  743. return failtest_pwrite(fd, buf, count, lseek(fd, 0, SEEK_CUR),
  744. file, line);
  745. }
  746. static struct lock_info *WARN_UNUSED_RESULT
  747. add_lock(struct lock_info *locks, int fd, off_t start, off_t end, int type)
  748. {
  749. unsigned int i;
  750. struct lock_info *l;
  751. for (i = 0; i < lock_num; i++) {
  752. l = &locks[i];
  753. if (l->fd != fd)
  754. continue;
  755. /* Four cases we care about:
  756. * Start overlap:
  757. * l = | |
  758. * new = | |
  759. * Mid overlap:
  760. * l = | |
  761. * new = | |
  762. * End overlap:
  763. * l = | |
  764. * new = | |
  765. * Total overlap:
  766. * l = | |
  767. * new = | |
  768. */
  769. if (start > l->start && end < l->end) {
  770. /* Mid overlap: trim entry, add new one. */
  771. off_t new_start, new_end;
  772. new_start = end + 1;
  773. new_end = l->end;
  774. l->end = start - 1;
  775. locks = add_lock(locks,
  776. fd, new_start, new_end, l->type);
  777. l = &locks[i];
  778. } else if (start <= l->start && end >= l->end) {
  779. /* Total overlap: eliminate entry. */
  780. l->end = 0;
  781. l->start = 1;
  782. } else if (end >= l->start && end < l->end) {
  783. /* Start overlap: trim entry. */
  784. l->start = end + 1;
  785. } else if (start > l->start && start <= l->end) {
  786. /* End overlap: trim entry. */
  787. l->end = start-1;
  788. }
  789. /* Nothing left? Remove it. */
  790. if (l->end < l->start) {
  791. memmove(l, l + 1, (--lock_num - i) * sizeof(l[0]));
  792. i--;
  793. }
  794. }
  795. if (type != F_UNLCK) {
  796. locks = realloc(locks, (lock_num + 1) * sizeof(*locks));
  797. l = &locks[lock_num++];
  798. l->fd = fd;
  799. l->start = start;
  800. l->end = end;
  801. l->type = type;
  802. }
  803. return locks;
  804. }
  805. /* We trap this so we can record it: we don't fail it. */
  806. int failtest_close(int fd, const char *file, unsigned line)
  807. {
  808. struct failtest_call *i;
  809. struct close_call call;
  810. struct failtest_call *p;
  811. call.fd = fd;
  812. p = add_history(FAILTEST_CLOSE, file, line, &call);
  813. p->fail = false;
  814. /* Consume close from failpath. */
  815. if (failpath)
  816. if (should_fail(p))
  817. abort();
  818. if (fd < 0)
  819. return close(fd);
  820. /* Trace history to find source of fd. */
  821. tlist_for_each_rev(&history, i, list) {
  822. switch (i->type) {
  823. case FAILTEST_PIPE:
  824. /* From a pipe? */
  825. if (i->u.pipe.fds[0] == fd) {
  826. assert(!i->u.pipe.closed[0]);
  827. i->u.pipe.closed[0] = true;
  828. if (i->u.pipe.closed[1])
  829. i->cleanup = NULL;
  830. goto out;
  831. }
  832. if (i->u.pipe.fds[1] == fd) {
  833. assert(!i->u.pipe.closed[1]);
  834. i->u.pipe.closed[1] = true;
  835. if (i->u.pipe.closed[0])
  836. i->cleanup = NULL;
  837. goto out;
  838. }
  839. break;
  840. case FAILTEST_OPEN:
  841. if (i->u.open.ret == fd) {
  842. assert((void *)i->cleanup
  843. == (void *)cleanup_open);
  844. i->cleanup = NULL;
  845. goto out;
  846. }
  847. break;
  848. default:
  849. break;
  850. }
  851. }
  852. out:
  853. locks = add_lock(locks, fd, 0, off_max(), F_UNLCK);
  854. return close(fd);
  855. }
  856. /* Zero length means "to end of file" */
  857. static off_t end_of(off_t start, off_t len)
  858. {
  859. if (len == 0)
  860. return off_max();
  861. return start + len - 1;
  862. }
  863. /* FIXME: This only handles locks, really. */
  864. int failtest_fcntl(int fd, const char *file, unsigned line, int cmd, ...)
  865. {
  866. struct failtest_call *p;
  867. struct fcntl_call call;
  868. va_list ap;
  869. call.fd = fd;
  870. call.cmd = cmd;
  871. /* Argument extraction. */
  872. switch (cmd) {
  873. case F_SETFL:
  874. case F_SETFD:
  875. va_start(ap, cmd);
  876. call.arg.l = va_arg(ap, long);
  877. va_end(ap);
  878. return fcntl(fd, cmd, call.arg.l);
  879. case F_GETFD:
  880. case F_GETFL:
  881. return fcntl(fd, cmd);
  882. case F_GETLK:
  883. get_locks();
  884. va_start(ap, cmd);
  885. call.arg.fl = *va_arg(ap, struct flock *);
  886. va_end(ap);
  887. return fcntl(fd, cmd, &call.arg.fl);
  888. case F_SETLK:
  889. case F_SETLKW:
  890. va_start(ap, cmd);
  891. call.arg.fl = *va_arg(ap, struct flock *);
  892. va_end(ap);
  893. break;
  894. default:
  895. /* This means you need to implement it here. */
  896. err(1, "failtest: unknown fcntl %u", cmd);
  897. }
  898. p = add_history(FAILTEST_FCNTL, file, line, &call);
  899. if (should_fail(p)) {
  900. p->u.fcntl.ret = -1;
  901. if (p->u.fcntl.cmd == F_SETLK)
  902. p->error = EAGAIN;
  903. else
  904. p->error = EDEADLK;
  905. } else {
  906. get_locks();
  907. p->u.fcntl.ret = fcntl(p->u.fcntl.fd, p->u.fcntl.cmd,
  908. &p->u.fcntl.arg.fl);
  909. if (p->u.fcntl.ret == -1)
  910. p->error = errno;
  911. else {
  912. /* We don't handle anything else yet. */
  913. assert(p->u.fcntl.arg.fl.l_whence == SEEK_SET);
  914. locks = add_lock(locks,
  915. p->u.fcntl.fd,
  916. p->u.fcntl.arg.fl.l_start,
  917. end_of(p->u.fcntl.arg.fl.l_start,
  918. p->u.fcntl.arg.fl.l_len),
  919. p->u.fcntl.arg.fl.l_type);
  920. }
  921. }
  922. errno = p->error;
  923. return p->u.fcntl.ret;
  924. }
  925. pid_t failtest_getpid(const char *file, unsigned line)
  926. {
  927. /* You must call failtest_init first! */
  928. assert(orig_pid);
  929. return orig_pid;
  930. }
  931. void failtest_init(int argc, char *argv[])
  932. {
  933. unsigned int i;
  934. orig_pid = getpid();
  935. for (i = 1; i < argc; i++) {
  936. if (!strncmp(argv[i], "--failpath=", strlen("--failpath="))) {
  937. failpath = argv[i] + strlen("--failpath=");
  938. } else if (strcmp(argv[i], "--tracepath") == 0) {
  939. tracefd = dup(STDERR_FILENO);
  940. failtest_timeout_ms = -1;
  941. } else if (!strncmp(argv[i], "--debugpath=",
  942. strlen("--debugpath="))) {
  943. debugpath = argv[i] + strlen("--debugpath=");
  944. }
  945. }
  946. start = time_now();
  947. }
  948. bool failtest_has_failed(void)
  949. {
  950. return control_fd != -1;
  951. }
  952. void failtest_exit(int status)
  953. {
  954. if (failtest_exit_check) {
  955. if (!failtest_exit_check(&history))
  956. child_fail(NULL, 0, "failtest_exit_check failed\n");
  957. }
  958. failtest_cleanup(false, status);
  959. }