failtest.c 23 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  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 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. off_t orig = lseek(fd, 0, SEEK_CUR);
  202. /* Special file? Erk... */
  203. assert(orig != -1);
  204. s->next = next;
  205. s->fd = fd;
  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, orig, 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. fd_set closed;
  222. /* Figure out the set of live fds. */
  223. FD_ZERO(&closed);
  224. for (i = history_num - 2; i >= 0; i--) {
  225. /* FIXME: Handle dup. */
  226. if (history[i].type == FAILTEST_CLOSE) {
  227. assert(!FD_ISSET(history[i].u.close.fd, &closed));
  228. FD_SET(history[i].u.close.fd, &closed);
  229. } else if (history[i].type == FAILTEST_OPEN) {
  230. int fd = history[i].u.open.ret;
  231. /* Only do successful, writable fds. */
  232. if (fd < 0)
  233. continue;
  234. /* If it wasn't closed again... */
  235. if (!FD_ISSET(fd, &closed)) {
  236. if ((history[i].u.open.flags & O_RDWR)
  237. == O_RDWR) {
  238. files = save_file(files, fd);
  239. } else if ((history[i].u.open.flags & O_WRONLY)
  240. == O_WRONLY) {
  241. /* FIXME: Handle O_WRONLY. Open with
  242. * O_RDWR? */
  243. abort();
  244. }
  245. } else
  246. FD_CLR(history[i].u.open.ret, &closed);
  247. }
  248. }
  249. return files;
  250. }
  251. static void restore_files(struct saved_file *s)
  252. {
  253. while (s) {
  254. struct saved_file *next = s->next;
  255. off_t orig = lseek(s->fd, 0, SEEK_CUR);
  256. lseek(s->fd, 0, SEEK_SET);
  257. write(s->fd, s->contents, s->len);
  258. free(s->contents);
  259. lseek(s->fd, orig, SEEK_SET);
  260. free(s);
  261. s = next;
  262. }
  263. }
  264. static bool should_fail(struct failtest_call *call)
  265. {
  266. int status;
  267. int control[2], output[2];
  268. enum info_type type = UNEXPECTED;
  269. char *out = NULL;
  270. size_t outlen = 0;
  271. struct saved_file *files;
  272. if (call == &unrecorded_call)
  273. return false;
  274. if (failpath) {
  275. /* + means continue after end, like normal. */
  276. if (*failpath == '+')
  277. failpath = NULL;
  278. else {
  279. if (tolower(*failpath) != info_to_arg[call->type])
  280. errx(1, "Failpath expected '%c' got '%c'\n",
  281. info_to_arg[call->type], *failpath);
  282. call->fail = isupper(*(failpath++));
  283. return call->fail;
  284. }
  285. }
  286. if (!failtest_hook(history, history_num)) {
  287. call->fail = false;
  288. return false;
  289. }
  290. files = save_files();
  291. /* We're going to fail in the child. */
  292. call->fail = true;
  293. if (pipe(control) != 0 || pipe(output) != 0)
  294. err(1, "opening pipe");
  295. /* Prevent double-printing (in child and parent) */
  296. fflush(stdout);
  297. child = fork();
  298. if (child == -1)
  299. err(1, "forking failed");
  300. if (child == 0) {
  301. if (tracefd != -1) {
  302. struct timeval now;
  303. char str[50], *p;
  304. gettimeofday(&now, NULL);
  305. if (now.tv_usec < start.tv_usec) {
  306. now.tv_sec--;
  307. now.tv_usec += 1000000;
  308. }
  309. now.tv_usec -= start.tv_usec;
  310. now.tv_sec -= start.tv_sec;
  311. sprintf(str, "%u (%u.%02u): ", getpid(),
  312. (int)now.tv_sec, (int)now.tv_usec / 10000);
  313. trace_str(str);
  314. p = failpath_string();
  315. trace_str(p);
  316. free(p);
  317. trace_str("(");
  318. p = strchr(history[history_num-1].file, '/');
  319. if (p)
  320. trace_str(p+1);
  321. else
  322. trace_str(history[history_num-1].file);
  323. sprintf(str, ":%u)\n", history[history_num-1].line);
  324. trace_str(str);
  325. }
  326. close(control[0]);
  327. close(output[0]);
  328. dup2(output[1], STDOUT_FILENO);
  329. dup2(output[1], STDERR_FILENO);
  330. if (output[1] != STDOUT_FILENO && output[1] != STDERR_FILENO)
  331. close(output[1]);
  332. control_fd = control[1];
  333. return true;
  334. }
  335. signal(SIGUSR1, hand_down);
  336. close(control[1]);
  337. close(output[1]);
  338. /* We grab output so we can display it; we grab writes so we
  339. * can compare. */
  340. do {
  341. struct pollfd pfd[2];
  342. int ret;
  343. pfd[0].fd = output[0];
  344. pfd[0].events = POLLIN|POLLHUP;
  345. pfd[1].fd = control[0];
  346. pfd[1].events = POLLIN|POLLHUP;
  347. if (type == SUCCESS)
  348. ret = poll(pfd, 1, failtest_timeout_ms);
  349. else
  350. ret = poll(pfd, 2, failtest_timeout_ms);
  351. if (ret <= 0)
  352. hand_down(SIGUSR1);
  353. if (pfd[0].revents & POLLIN) {
  354. ssize_t len;
  355. out = realloc(out, outlen + 8192);
  356. len = read(output[0], out + outlen, 8192);
  357. outlen += len;
  358. } else if (type != SUCCESS && (pfd[1].revents & POLLIN)) {
  359. if (read_all(control[0], &type, sizeof(type))) {
  360. if (type == WRITE) {
  361. if (!read_write_info(control[0]))
  362. break;
  363. } else if (type == RELEASE_LOCKS) {
  364. release_locks();
  365. /* FIXME: Tell them we're done... */
  366. }
  367. }
  368. } else if (pfd[0].revents & POLLHUP) {
  369. break;
  370. }
  371. } while (type != FAILURE);
  372. close(output[0]);
  373. close(control[0]);
  374. waitpid(child, &status, 0);
  375. if (!WIFEXITED(status))
  376. child_fail(out, outlen, "Killed by signal %u: ",
  377. WTERMSIG(status));
  378. /* Child printed failure already, just pass up exit code. */
  379. if (type == FAILURE) {
  380. fprintf(stderr, "%.*s", (int)outlen, out);
  381. tell_parent(type);
  382. exit(WEXITSTATUS(status) ? WEXITSTATUS(status) : 1);
  383. }
  384. if (WEXITSTATUS(status) != 0)
  385. child_fail(out, outlen, "Exited with status %i: ",
  386. WEXITSTATUS(status));
  387. free(out);
  388. signal(SIGUSR1, SIG_DFL);
  389. restore_files(files);
  390. /* We continue onwards without failing. */
  391. call->fail = false;
  392. return false;
  393. }
  394. static void cleanup_calloc(struct calloc_call *call)
  395. {
  396. free(call->ret);
  397. }
  398. void *failtest_calloc(size_t nmemb, size_t size,
  399. const char *file, unsigned line)
  400. {
  401. struct failtest_call *p;
  402. struct calloc_call call;
  403. call.nmemb = nmemb;
  404. call.size = size;
  405. p = add_history(FAILTEST_CALLOC, file, line, &call);
  406. if (should_fail(p)) {
  407. p->u.calloc.ret = NULL;
  408. p->error = ENOMEM;
  409. } else {
  410. p->u.calloc.ret = calloc(nmemb, size);
  411. set_cleanup(p, cleanup_calloc, struct calloc_call);
  412. }
  413. errno = p->error;
  414. return p->u.calloc.ret;
  415. }
  416. static void cleanup_malloc(struct malloc_call *call)
  417. {
  418. free(call->ret);
  419. }
  420. void *failtest_malloc(size_t size, const char *file, unsigned line)
  421. {
  422. struct failtest_call *p;
  423. struct malloc_call call;
  424. call.size = size;
  425. p = add_history(FAILTEST_MALLOC, file, line, &call);
  426. if (should_fail(p)) {
  427. p->u.calloc.ret = NULL;
  428. p->error = ENOMEM;
  429. } else {
  430. p->u.calloc.ret = malloc(size);
  431. set_cleanup(p, cleanup_malloc, struct malloc_call);
  432. }
  433. errno = p->error;
  434. return p->u.calloc.ret;
  435. }
  436. static void cleanup_realloc(struct realloc_call *call)
  437. {
  438. free(call->ret);
  439. }
  440. /* Walk back and find out if we got this ptr from a previous routine. */
  441. static void fixup_ptr_history(void *ptr, unsigned int last)
  442. {
  443. int i;
  444. /* Start at end of history, work back. */
  445. for (i = last - 1; i >= 0; i--) {
  446. switch (history[i].type) {
  447. case FAILTEST_REALLOC:
  448. if (history[i].u.realloc.ret == ptr) {
  449. history[i].cleanup = NULL;
  450. return;
  451. }
  452. break;
  453. case FAILTEST_MALLOC:
  454. if (history[i].u.malloc.ret == ptr) {
  455. history[i].cleanup = NULL;
  456. return;
  457. }
  458. break;
  459. case FAILTEST_CALLOC:
  460. if (history[i].u.calloc.ret == ptr) {
  461. history[i].cleanup = NULL;
  462. return;
  463. }
  464. break;
  465. default:
  466. break;
  467. }
  468. }
  469. }
  470. void *failtest_realloc(void *ptr, size_t size, const char *file, unsigned line)
  471. {
  472. struct failtest_call *p;
  473. struct realloc_call call;
  474. call.size = size;
  475. p = add_history(FAILTEST_REALLOC, file, line, &call);
  476. /* FIXME: Try one child moving allocation, one not. */
  477. if (should_fail(p)) {
  478. p->u.realloc.ret = NULL;
  479. p->error = ENOMEM;
  480. } else {
  481. fixup_ptr_history(ptr, history_num-1);
  482. p->u.realloc.ret = realloc(ptr, size);
  483. set_cleanup(p, cleanup_realloc, struct realloc_call);
  484. }
  485. errno = p->error;
  486. return p->u.realloc.ret;
  487. }
  488. void failtest_free(void *ptr)
  489. {
  490. fixup_ptr_history(ptr, history_num);
  491. free(ptr);
  492. }
  493. static void cleanup_open(struct open_call *call)
  494. {
  495. close(call->ret);
  496. }
  497. int failtest_open(const char *pathname,
  498. const char *file, unsigned line, ...)
  499. {
  500. struct failtest_call *p;
  501. struct open_call call;
  502. va_list ap;
  503. call.pathname = strdup(pathname);
  504. va_start(ap, line);
  505. call.flags = va_arg(ap, int);
  506. if (call.flags & O_CREAT) {
  507. call.mode = va_arg(ap, mode_t);
  508. va_end(ap);
  509. }
  510. p = add_history(FAILTEST_OPEN, file, line, &call);
  511. /* Avoid memory leak! */
  512. if (p == &unrecorded_call)
  513. free((char *)call.pathname);
  514. if (should_fail(p)) {
  515. p->u.open.ret = -1;
  516. /* FIXME: Play with error codes? */
  517. p->error = EACCES;
  518. } else {
  519. p->u.open.ret = open(pathname, call.flags, call.mode);
  520. set_cleanup(p, cleanup_open, struct open_call);
  521. p->u.open.dup_fd = p->u.open.ret;
  522. }
  523. errno = p->error;
  524. return p->u.open.ret;
  525. }
  526. static void cleanup_pipe(struct pipe_call *call)
  527. {
  528. if (!call->closed[0])
  529. close(call->fds[0]);
  530. if (!call->closed[1])
  531. close(call->fds[1]);
  532. }
  533. int failtest_pipe(int pipefd[2], const char *file, unsigned line)
  534. {
  535. struct failtest_call *p;
  536. struct pipe_call call;
  537. p = add_history(FAILTEST_PIPE, file, line, &call);
  538. if (should_fail(p)) {
  539. p->u.open.ret = -1;
  540. /* FIXME: Play with error codes? */
  541. p->error = EMFILE;
  542. } else {
  543. p->u.pipe.ret = pipe(p->u.pipe.fds);
  544. p->u.pipe.closed[0] = p->u.pipe.closed[1] = false;
  545. set_cleanup(p, cleanup_pipe, struct pipe_call);
  546. }
  547. /* This causes valgrind to notice if they use pipefd[] after failure */
  548. memcpy(pipefd, p->u.pipe.fds, sizeof(p->u.pipe.fds));
  549. errno = p->error;
  550. return p->u.pipe.ret;
  551. }
  552. static void cleanup_read(struct read_call *call)
  553. {
  554. lseek(call->fd, call->off, SEEK_SET);
  555. }
  556. ssize_t failtest_pread(int fd, void *buf, size_t count, off_t off,
  557. const char *file, unsigned line)
  558. {
  559. struct failtest_call *p;
  560. struct read_call call;
  561. call.fd = fd;
  562. call.buf = buf;
  563. call.count = count;
  564. call.off = off;
  565. p = add_history(FAILTEST_READ, file, line, &call);
  566. /* FIXME: Try partial read returns. */
  567. if (should_fail(p)) {
  568. p->u.read.ret = -1;
  569. p->error = EIO;
  570. } else {
  571. p->u.read.ret = pread(fd, buf, count, off);
  572. set_cleanup(p, cleanup_read, struct read_call);
  573. }
  574. errno = p->error;
  575. return p->u.read.ret;
  576. }
  577. static void cleanup_write(struct write_call *call)
  578. {
  579. lseek(call->dup_fd, call->off, SEEK_SET);
  580. write(call->dup_fd, call->saved_contents, call->saved_len);
  581. lseek(call->dup_fd, call->off, SEEK_SET);
  582. ftruncate(call->dup_fd, call->old_filelen);
  583. free(call->saved_contents);
  584. }
  585. ssize_t failtest_pwrite(int fd, const void *buf, size_t count, off_t off,
  586. const char *file, unsigned line)
  587. {
  588. struct failtest_call *p;
  589. struct write_call call;
  590. call.fd = call.dup_fd = fd;
  591. call.buf = buf;
  592. call.count = count;
  593. call.off = off;
  594. p = add_history(FAILTEST_WRITE, file, line, &call);
  595. /* Save old contents if we can */
  596. if (p->u.write.off != -1) {
  597. ssize_t ret;
  598. p->u.write.old_filelen = lseek(fd, 0, SEEK_END);
  599. /* Write past end of file? Nothing to save.*/
  600. if (p->u.write.old_filelen <= p->u.write.off)
  601. p->u.write.saved_len = 0;
  602. /* Write which goes over end of file? Partial save. */
  603. else if (p->u.write.off + count > p->u.write.old_filelen)
  604. p->u.write.saved_len = p->u.write.old_filelen
  605. - p->u.write.off;
  606. /* Full save. */
  607. else
  608. p->u.write.saved_len = count;
  609. p->u.write.saved_contents = malloc(p->u.write.saved_len);
  610. lseek(fd, p->u.write.off, SEEK_SET);
  611. ret = read(fd, p->u.write.saved_contents, p->u.write.saved_len);
  612. if (ret != p->u.write.saved_len)
  613. err(1, "Expected %i bytes, got %i",
  614. (int)p->u.write.saved_len, (int)ret);
  615. lseek(fd, p->u.write.off, SEEK_SET);
  616. set_cleanup(p, cleanup_write, struct write_call);
  617. }
  618. /* If we're a child, tell parent about write. */
  619. if (control_fd != -1) {
  620. enum info_type type = WRITE;
  621. write_all(control_fd, &type, sizeof(type));
  622. write_all(control_fd, &p->u.write, sizeof(p->u.write));
  623. write_all(control_fd, buf, count);
  624. }
  625. /* FIXME: Try partial write returns. */
  626. if (should_fail(p)) {
  627. p->u.write.ret = -1;
  628. p->error = EIO;
  629. } else {
  630. /* FIXME: We assume same write order in parent and child */
  631. if (child_writes_num != 0) {
  632. if (child_writes[0].fd != fd)
  633. errx(1, "Child wrote to fd %u, not %u?",
  634. child_writes[0].fd, fd);
  635. if (child_writes[0].off != p->u.write.off)
  636. errx(1, "Child wrote to offset %zu, not %zu?",
  637. (size_t)child_writes[0].off,
  638. (size_t)p->u.write.off);
  639. if (child_writes[0].count != count)
  640. errx(1, "Child wrote length %zu, not %zu?",
  641. child_writes[0].count, count);
  642. if (memcmp(child_writes[0].buf, buf, count)) {
  643. child_fail(NULL, 0,
  644. "Child wrote differently to"
  645. " fd %u than we did!\n", fd);
  646. }
  647. free((char *)child_writes[0].buf);
  648. child_writes_num--;
  649. memmove(&child_writes[0], &child_writes[1],
  650. sizeof(child_writes[0]) * child_writes_num);
  651. /* Is this is a socket or pipe, child wrote it
  652. already. */
  653. if (p->u.write.off == (off_t)-1) {
  654. p->u.write.ret = count;
  655. errno = p->error;
  656. return p->u.write.ret;
  657. }
  658. }
  659. p->u.write.ret = pwrite(fd, buf, count, off);
  660. }
  661. errno = p->error;
  662. return p->u.write.ret;
  663. }
  664. ssize_t failtest_read(int fd, void *buf, size_t count,
  665. const char *file, unsigned line)
  666. {
  667. return failtest_pread(fd, buf, count, lseek(fd, 0, SEEK_CUR),
  668. file, line);
  669. }
  670. ssize_t failtest_write(int fd, const void *buf, size_t count,
  671. const char *file, unsigned line)
  672. {
  673. return failtest_pwrite(fd, buf, count, lseek(fd, 0, SEEK_CUR),
  674. file, line);
  675. }
  676. static struct lock_info *WARN_UNUSED_RESULT
  677. add_lock(struct lock_info *locks, int fd, off_t start, off_t end, int type)
  678. {
  679. unsigned int i;
  680. struct lock_info *l;
  681. for (i = 0; i < lock_num; i++) {
  682. l = &locks[i];
  683. if (l->fd != fd)
  684. continue;
  685. /* Four cases we care about:
  686. * Start overlap:
  687. * l = | |
  688. * new = | |
  689. * Mid overlap:
  690. * l = | |
  691. * new = | |
  692. * End overlap:
  693. * l = | |
  694. * new = | |
  695. * Total overlap:
  696. * l = | |
  697. * new = | |
  698. */
  699. if (start > l->start && end < l->end) {
  700. /* Mid overlap: trim entry, add new one. */
  701. off_t new_start, new_end;
  702. new_start = end + 1;
  703. new_end = l->end;
  704. l->end = start - 1;
  705. locks = add_lock(locks,
  706. fd, new_start, new_end, l->type);
  707. l = &locks[i];
  708. } else if (start <= l->start && end >= l->end) {
  709. /* Total overlap: eliminate entry. */
  710. l->end = 0;
  711. l->start = 1;
  712. } else if (end >= l->start && end < l->end) {
  713. /* Start overlap: trim entry. */
  714. l->start = end + 1;
  715. } else if (start > l->start && start <= l->end) {
  716. /* End overlap: trim entry. */
  717. l->end = start-1;
  718. }
  719. /* Nothing left? Remove it. */
  720. if (l->end < l->start) {
  721. memmove(l, l + 1, (--lock_num - i) * sizeof(l[0]));
  722. i--;
  723. }
  724. }
  725. if (type != F_UNLCK) {
  726. locks = realloc(locks, (lock_num + 1) * sizeof(*locks));
  727. l = &locks[lock_num++];
  728. l->fd = fd;
  729. l->start = start;
  730. l->end = end;
  731. l->type = type;
  732. }
  733. return locks;
  734. }
  735. /* We only trap this so we can dup fds in case we need to restore. */
  736. int failtest_close(int fd)
  737. {
  738. int new_fd = -1, i;
  739. if (fd < 0)
  740. return close(fd);
  741. /* Trace history to find source of fd, and if we need to cleanup writes. */
  742. for (i = history_num-1; i >= 0; i--) {
  743. switch (history[i].type) {
  744. case FAILTEST_WRITE:
  745. if (history[i].u.write.fd != fd)
  746. break;
  747. if (!history[i].cleanup)
  748. break;
  749. /* We need to save fd so we can restore file. */
  750. if (new_fd == -1)
  751. new_fd = dup(fd);
  752. history[i].u.write.dup_fd = new_fd;
  753. break;
  754. case FAILTEST_READ:
  755. /* We don't need to cleanup reads on closed fds. */
  756. if (history[i].u.read.fd != fd)
  757. break;
  758. history[i].cleanup = NULL;
  759. break;
  760. case FAILTEST_PIPE:
  761. /* From a pipe? We don't ever restore pipes... */
  762. if (history[i].u.pipe.fds[0] == fd) {
  763. assert(new_fd == -1);
  764. history[i].u.pipe.closed[0] = true;
  765. goto out;
  766. }
  767. if (history[i].u.pipe.fds[1] == fd) {
  768. assert(new_fd == -1);
  769. history[i].u.pipe.closed[1] = true;
  770. goto out;
  771. }
  772. break;
  773. case FAILTEST_OPEN:
  774. if (history[i].u.open.ret == fd) {
  775. history[i].u.open.dup_fd = new_fd;
  776. goto out;
  777. }
  778. break;
  779. default:
  780. break;
  781. }
  782. }
  783. out:
  784. locks = add_lock(locks, fd, 0, off_max(), F_UNLCK);
  785. return close(fd);
  786. }
  787. /* Zero length means "to end of file" */
  788. static off_t end_of(off_t start, off_t len)
  789. {
  790. if (len == 0)
  791. return off_max();
  792. return start + len - 1;
  793. }
  794. /* FIXME: This only handles locks, really. */
  795. int failtest_fcntl(int fd, const char *file, unsigned line, int cmd, ...)
  796. {
  797. struct failtest_call *p;
  798. struct fcntl_call call;
  799. va_list ap;
  800. call.fd = fd;
  801. call.cmd = cmd;
  802. /* Argument extraction. */
  803. switch (cmd) {
  804. case F_SETFL:
  805. case F_SETFD:
  806. va_start(ap, cmd);
  807. call.arg.l = va_arg(ap, long);
  808. va_end(ap);
  809. return fcntl(fd, cmd, call.arg.l);
  810. case F_GETFD:
  811. case F_GETFL:
  812. return fcntl(fd, cmd);
  813. case F_GETLK:
  814. get_locks();
  815. va_start(ap, cmd);
  816. call.arg.fl = *va_arg(ap, struct flock *);
  817. va_end(ap);
  818. return fcntl(fd, cmd, &call.arg.fl);
  819. case F_SETLK:
  820. case F_SETLKW:
  821. va_start(ap, cmd);
  822. call.arg.fl = *va_arg(ap, struct flock *);
  823. va_end(ap);
  824. break;
  825. default:
  826. /* This means you need to implement it here. */
  827. err(1, "failtest: unknown fcntl %u", cmd);
  828. }
  829. p = add_history(FAILTEST_FCNTL, file, line, &call);
  830. get_locks();
  831. if (should_fail(p)) {
  832. p->u.fcntl.ret = -1;
  833. if (p->u.fcntl.cmd == F_SETLK)
  834. p->error = EAGAIN;
  835. else
  836. p->error = EDEADLK;
  837. } else {
  838. p->u.fcntl.ret = fcntl(p->u.fcntl.fd, p->u.fcntl.cmd,
  839. &p->u.fcntl.arg.fl);
  840. if (p->u.fcntl.ret == -1)
  841. p->error = errno;
  842. else {
  843. /* We don't handle anything else yet. */
  844. assert(p->u.fcntl.arg.fl.l_whence == SEEK_SET);
  845. locks = add_lock(locks,
  846. p->u.fcntl.fd,
  847. p->u.fcntl.arg.fl.l_start,
  848. end_of(p->u.fcntl.arg.fl.l_start,
  849. p->u.fcntl.arg.fl.l_len),
  850. p->u.fcntl.arg.fl.l_type);
  851. }
  852. }
  853. errno = p->error;
  854. return p->u.fcntl.ret;
  855. }
  856. void failtest_init(int argc, char *argv[])
  857. {
  858. unsigned int i;
  859. for (i = 1; i < argc; i++) {
  860. if (!strncmp(argv[i], "--failpath=", strlen("--failpath="))) {
  861. failpath = argv[i] + strlen("--failpath=");
  862. } else if (strcmp(argv[i], "--tracepath") == 0) {
  863. tracefd = dup(STDERR_FILENO);
  864. failtest_timeout_ms = -1;
  865. }
  866. }
  867. gettimeofday(&start, NULL);
  868. }
  869. /* Free up memory, so valgrind doesn't report leaks. */
  870. static void free_everything(void)
  871. {
  872. unsigned int i;
  873. /* We don't do this in cleanup: needed even for failed opens. */
  874. for (i = 0; i < history_num; i++) {
  875. if (history[i].type == FAILTEST_OPEN)
  876. free((char *)history[i].u.open.pathname);
  877. }
  878. free(history);
  879. }
  880. void failtest_exit(int status)
  881. {
  882. int i;
  883. if (control_fd == -1) {
  884. free_everything();
  885. exit(status);
  886. }
  887. if (failtest_exit_check) {
  888. if (!failtest_exit_check(history, history_num))
  889. child_fail(NULL, 0, "failtest_exit_check failed\n");
  890. }
  891. /* Cleanup everything, in reverse order. */
  892. for (i = history_num - 1; i >= 0; i--)
  893. if (history[i].cleanup)
  894. history[i].cleanup(&history[i].u);
  895. free_everything();
  896. tell_parent(SUCCESS);
  897. exit(0);
  898. }