failtest.c 24 KB

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