failtest.c 22 KB

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