X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb%2Ftest%2Fexternal-transaction.c;h=23d8471386413f39a2d7a7d311ad13c3e22b0021;hp=d899a6c669b01ef21621ae853437d561cd49689c;hb=729fc5b931c8eb26f192399d8aa7064f9af058df;hpb=176844c84ff5ae6a5f146c5d1b7a3927bd781739 diff --git a/ccan/tdb/test/external-transaction.c b/ccan/tdb/test/external-transaction.c index d899a6c6..23d84713 100644 --- a/ccan/tdb/test/external-transaction.c +++ b/ccan/tdb/test/external-transaction.c @@ -9,8 +9,12 @@ #include #include #include +#include #include #include +#include + +static struct tdb_context *tdb; static volatile sig_atomic_t alarmed; static void do_alarm(int signum) @@ -18,20 +22,61 @@ static void do_alarm(int signum) alarmed++; } +static void taplog(struct tdb_context *tdb, + enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + char line[200]; + + va_start(ap, fmt); + vsprintf(line, fmt, ap); + va_end(ap); + + diag("external: %s", line); +} + static int do_operation(enum operation op, const char *name) { + struct tdb_logging_context logctx = { taplog, NULL }; + TDB_DATA k = { .dptr = (void *)"a", .dsize = 1 }; TDB_DATA d = { .dptr = (void *)"b", .dsize = 1 }; - struct tdb_context *tdb; - tdb = tdb_open(name, 0, op == OPEN_WITH_CLEAR_IF_FIRST ? - TDB_CLEAR_IF_FIRST : TDB_DEFAULT, O_RDWR, 0); - if (!tdb) - return -1; + if (op <= KEEP_OPENED) { + tdb = tdb_open_ex(name, 0, op == OPEN_WITH_CLEAR_IF_FIRST ? + TDB_CLEAR_IF_FIRST : TDB_DEFAULT, O_RDWR, 0, + &logctx, NULL); + if (!tdb) + return -1; + } - if (op == OPEN || op == OPEN_WITH_CLEAR_IF_FIRST) { - tdb_close(tdb); + if (op == KEEP_OPENED) { return 0; + } else if (op == OPEN || op == OPEN_WITH_CLEAR_IF_FIRST || op == CLOSE) { + tdb_close(tdb); + tdb = NULL; + return 1; + } else if (op == STORE_KEEP_OPENED) { + if (tdb_store(tdb, k, d, 0) != 0) + return -2; + return 1; + } else if (op == FETCH_KEEP_OPENED) { + TDB_DATA ret; + ret = tdb_fetch(tdb, k); + if (ret.dptr == NULL) { + if (tdb_error(tdb) == TDB_ERR_NOEXIST) + return 1; + return -3; + } + if (ret.dsize != 1 || *(char *)ret.dptr != 'b') + return -4; + free(ret.dptr); + return 1; + } else if (op == CHECK_KEEP_OPENED) { + return tdb_check(tdb, NULL, 0) == 0; + } else if (op == NEEDS_RECOVERY_KEEP_OPENED) { + return tdb_needs_recovery(tdb); } alarmed = 0; @@ -41,21 +86,29 @@ static int do_operation(enum operation op, const char *name) if (tdb_transaction_start(tdb) != 0) goto maybe_alarmed; + alarm(0); if (tdb_store(tdb, k, d, 0) != 0) { tdb_transaction_cancel(tdb); tdb_close(tdb); + tdb = NULL; return -2; } if (tdb_transaction_commit(tdb) == 0) { tdb_delete(tdb, k); - tdb_close(tdb); + if (op != TRANSACTION_KEEP_OPENED) { + tdb_close(tdb); + tdb = NULL; + } return 1; } tdb_delete(tdb, k); maybe_alarmed: - tdb_close(tdb); + if (op != TRANSACTION_KEEP_OPENED) { + tdb_close(tdb); + tdb = NULL; + } if (alarmed) return 0; return -3; @@ -68,7 +121,7 @@ struct agent { /* Do this before doing any tdb stuff. Return handle, or NULL. */ struct agent *prepare_external_agent(void) { - int pid; + int pid, ret; int command[2], response[2]; struct sigaction act = { .sa_handler = do_alarm }; char name[1+PATH_MAX]; @@ -94,7 +147,7 @@ struct agent *prepare_external_agent(void) close(response[0]); sigaction(SIGALRM, &act, NULL); - while (read(command[0], name, sizeof(name)) != 0) { + while ((ret = read(command[0], name, sizeof(name))) > 0) { int result; result = do_operation(name[0], name+1); @@ -102,11 +155,12 @@ struct agent *prepare_external_agent(void) != sizeof(result)) err(1, "Writing response"); } + diag("external: read %i: %s", ret, strerror(errno)); exit(0); } /* Ask the external agent to try to do an operation. */ -bool external_agent_operation(struct agent *agent, +int external_agent_operation(struct agent *agent, enum operation op, const char *tdbname) { int res;