diff --git a/cxx/tests/exceptions.cpp b/cxx/tests/exceptions.cpp index e4be5aa3fc1..b300e66aefa 100644 --- a/cxx/tests/exceptions.cpp +++ b/cxx/tests/exceptions.cpp @@ -27,7 +27,7 @@ void test_env_exceptions (void) { DbEnv env(0); TC(env.open(".", DB_INIT_MPOOL | DB_CREATE | DB_PRIVATE, 0777), 0); DbTxn *txn; - TC(env.txn_begin(0, &txn, 0), EINVAL); // not configured for transations + TC(env.txn_begin(0, &txn, 0), EINVAL); // not configured for transactions } { DbEnv env(0); diff --git a/newbrt/brttypes.h b/newbrt/brttypes.h index c48bb087a77..66bc5af724f 100644 --- a/newbrt/brttypes.h +++ b/newbrt/brttypes.h @@ -44,7 +44,7 @@ typedef struct loggedbrtheader { u_int32_t nodesize; DISKOFF freelist; DISKOFF unused_memory; - u_int32_t n_named_roots; + u_int32_t n_named_roots; // -1 for the union below to be "one". union { struct { char **names; diff --git a/newbrt/log.c b/newbrt/log.c index 959d8599e0a..78c1da13b9e 100644 --- a/newbrt/log.c +++ b/newbrt/log.c @@ -91,6 +91,8 @@ int toku_logger_open (const char *directory, TOKULOGGER logger) { logger->lsn.lsn = 0; // WRONG!!! This should actually be calculated by looking at the log file. + logger->is_open = 1; + return toku_logger_log_bytes(logger, 0, ""); } @@ -102,6 +104,10 @@ int toku_logger_panicked(TOKULOGGER logger) { if (logger==0) return 0; return logger->is_panicked; } +int toku_logger_is_open(TOKULOGGER logger) { + if (logger==0) return 0; + return logger->is_open; +} static int log_format_version=0; @@ -291,6 +297,7 @@ int toku_logger_txn_begin (TOKUTXN parent_tokutxn, TOKUTXN *tokutxn, TXNID txnid result->txnid64 = txnid64; result->logger = logger; result->parent = parent_tokutxn; + result->oldest_logentry = result->newest_logentry = 0; *tokutxn = result; return 0; } diff --git a/newbrt/log.h b/newbrt/log.h index a260e854880..81592c12704 100644 --- a/newbrt/log.h +++ b/newbrt/log.h @@ -6,6 +6,8 @@ #include "../include/db.h" #include "brttypes.h" #include "kv-pair.h" +#include + int toku_logger_create(TOKULOGGER */*resultp*/); int toku_logger_open(const char */*directory*/, TOKULOGGER); int toku_logger_log_bytes(TOKULOGGER logger, int nbytes, void *bytes); @@ -13,6 +15,7 @@ int toku_logger_close(TOKULOGGER *logger); int toku_logger_log_checkpoint (TOKULOGGER, LSN*); void toku_logger_panic(TOKULOGGER, int/*err*/); int toku_logger_panicked(TOKULOGGER /*logger*/); +int toku_logger_is_open(TOKULOGGER); int toku_logger_log_phys_add_or_delete_in_leaf (DB *db, TOKUTXN txn, DISKOFF diskoff, int is_add, const struct kv_pair *pair); @@ -62,4 +65,70 @@ int toku_read_and_print_logmagic (FILE *f, u_int32_t *version); TXNID toku_txn_get_txnid (TOKUTXN); LSN toku_txn_get_last_lsn (TOKUTXN); +static inline int toku_copy_FILENUM(FILENUM *target, FILENUM val) { *target = val; return 0; } +static inline void toku_free_FILENUM(FILENUM val __attribute__((__unused__))) {} + +static inline int toku_copy_DISKOFF(DISKOFF *target, DISKOFF val) { *target = val; return 0; } +static inline void toku_free_DISKOFF(DISKOFF val __attribute__((__unused__))) {} + +static inline int toku_copy_TXNID(TXNID *target, TXNID val) { *target = val; return 0; } +static inline void toku_free_TXNID(TXNID val __attribute__((__unused__))) {} + +static inline int toku_copy_u_int8_t(u_int8_t *target, u_int8_t val) { *target = val; return 0; } +static inline void toku_free_u_int8_t(u_int8_t val __attribute__((__unused__))) {} + +static inline int toku_copy_u_int32_t(u_int32_t *target, u_int32_t val) { *target = val; return 0; } +static inline void toku_free_u_int32_t(u_int32_t val __attribute__((__unused__))) {} + +static inline int toku_copy_INTPAIRARRAY(INTPAIRARRAY *target, INTPAIRARRAY val) { + target->size = val.size; + target->array = toku_memdup(val.array, val.size*sizeof(val.array[0])); + if (target->array==0) return errno; + return 0; +} +static inline void toku_free_INTPAIRARRAY(INTPAIRARRAY val) { + toku_free(val.array); +} + +static inline int toku_copy_BYTESTRING(BYTESTRING *target, BYTESTRING val) { + target->len = val.len; + target->data = toku_memdup(val.data, val.len); + if (target->data==0) return errno; + return 0; +} +static inline void toku_free_BYTESTRING(BYTESTRING val) { + toku_free(val.data); +} + +static inline int toku_copy_LOGGEDBRTHEADER(LOGGEDBRTHEADER *target, LOGGEDBRTHEADER val) { + *target = val; + if ((int32_t)val.n_named_roots!=-1) { + int r; + target->u.many.names = toku_memdup(target->u.many.names, val.n_named_roots*sizeof(target->u.many.names[0])); + if (target->u.many.names==0) { r=errno; if (0) { died0: toku_free(target->u.many.names); } return r; } + target->u.many.roots = toku_memdup(target->u.many.roots, val.n_named_roots*sizeof(target->u.many.roots[0])); + if (target->u.many.roots==0) { r=errno; if (0) { died1: toku_free(target->u.many.names); } goto died0; } + u_int32_t i; + for (i=0; iu.many.names[i] = toku_strdup(target->u.many.names[i]); + if (target->u.many.names[i]==0) { + u_int32_t j; + r=errno; + for (j=0; ju.many.names[j]); + goto died1; + } + } + } + return 0; +} +static inline void toku_free_LOGGEDBRTHEADER(LOGGEDBRTHEADER val) { + if ((int32_t)val.n_named_roots==-1) return; + u_int32_t i; + for (i=0; icmd = %d;\n", lt->command); + DO_FIELDS(ft, lt, + ({ + fprintf(cf, " r=toku_copy_%s(&lentry->u.%s.%s, %s);\n", ft->type, lt->name, ft->name, ft->name); + fprintf(cf, " if (r!=0) { if(0) { died%d: toku_free_%s(lentry->u.%s.%s); } goto died%d; }\n", i+1, ft->type, lt->name, ft->name, i); + i++; + })); + fprintf(cf, " if (0) { goto died%d; }\n", i); // Need to use that label. + fprintf(cf, " lentry->next = 0;\n"); + fprintf(cf, " if (txn->oldest_logentry==0) txn->oldest_logentry = lentry;\n"); + fprintf(cf, " else txn->newest_logentry->next = lentry;\n"); + fprintf(cf, " txn->newest_logentry = lentry;\n"); fprintf(cf, " return r;\n"); } fprintf(cf, "}\n\n"); diff --git a/src/ydb.c b/src/ydb.c index 50b350b0c36..766efb93cf9 100644 --- a/src/ydb.c +++ b/src/ydb.c @@ -700,7 +700,7 @@ static int toku_txn_abort(DB_TXN * txn) { static int toku_txn_begin(DB_ENV * env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t flags) { HANDLE_PANICKED_ENV(env); - if (!env->i->logger) return EINVAL; + if (!toku_logger_is_open(env->i->logger)) return do_error(env, EINVAL, "Environment does not have logging enabled\n"); flags=flags; DB_TXN *MALLOC(result); if (result == 0)