Commit 27647f94 authored by Rusty Russell's avatar Rusty Russell

tdb2: return TDB_ERR_RDONLY from transactions on R/O databases, log nesting

Rather than rturning TDB_ERR_EINVAL, return TDB_ERR_RDONLY, and log
when we fail due to nesting.
parent a3e4ebff
...@@ -418,18 +418,34 @@ static const struct tdb1_methods transaction1_methods = { ...@@ -418,18 +418,34 @@ static const struct tdb1_methods transaction1_methods = {
static int _tdb1_transaction_start(struct tdb_context *tdb) static int _tdb1_transaction_start(struct tdb_context *tdb)
{ {
/* some sanity checks */ /* some sanity checks */
if ((tdb->flags & TDB_RDONLY) || (tdb->flags & TDB_INTERNAL) || tdb->tdb1.traverse_read) { if (tdb->flags & TDB_INTERNAL) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
"tdb1_transaction_start: cannot start a" TDB_LOG_USE_ERROR,
" transaction on a read-only or" "tdb1_transaction_start:"
" internal db"); " cannot start a"
" transaction on an"
" internal tdb");
return -1;
}
if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_RDONLY,
TDB_LOG_USE_ERROR,
"tdb_transaction_start:"
" cannot start a"
" transaction on a "
" read-only tdb");
return -1; return -1;
} }
/* cope with nested tdb1_transaction_start() calls */ /* cope with nested tdb1_transaction_start() calls */
if (tdb->tdb1.transaction != NULL) { if (tdb->tdb1.transaction != NULL) {
if (!(tdb->flags & TDB_ALLOW_NESTING)) { if (!(tdb->flags & TDB_ALLOW_NESTING)) {
tdb->last_error = TDB_ERR_EINVAL; tdb->last_error
= tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR,
"tdb_transaction_start:"
" already inside transaction");
return -1; return -1;
} }
tdb->stats.transaction_nest++; tdb->stats.transaction_nest++;
......
...@@ -15,7 +15,7 @@ int main(int argc, char *argv[]) ...@@ -15,7 +15,7 @@ int main(int argc, char *argv[])
hsize.base.next = &tap_log_attr; hsize.base.next = &tap_log_attr;
hsize.tdb1_hashsize.hsize = 1024; hsize.tdb1_hashsize.hsize = 1024;
plan_tests(29); plan_tests(30);
key.dsize = strlen("hi"); key.dsize = strlen("hi");
key.dptr = (void *)"hi"; key.dptr = (void *)"hi";
...@@ -33,6 +33,7 @@ int main(int argc, char *argv[]) ...@@ -33,6 +33,7 @@ int main(int argc, char *argv[])
ok1(memcmp(data.dptr, "world", strlen("world")) == 0); ok1(memcmp(data.dptr, "world", strlen("world")) == 0);
free(data.dptr); free(data.dptr);
ok1(tdb_transaction_start(tdb) == TDB_ERR_EINVAL); ok1(tdb_transaction_start(tdb) == TDB_ERR_EINVAL);
ok1(tap_log_messages == 1);
ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS); ok1(tdb_fetch(tdb, key, &data) == TDB_SUCCESS);
ok1(data.dsize == strlen("world")); ok1(data.dsize == strlen("world"));
...@@ -55,7 +56,7 @@ int main(int argc, char *argv[]) ...@@ -55,7 +56,7 @@ int main(int argc, char *argv[])
ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS); ok1(tdb_transaction_commit(tdb) == TDB_SUCCESS);
ok1(!tdb_exists(tdb, key)); ok1(!tdb_exists(tdb, key));
tdb_transaction_cancel(tdb); tdb_transaction_cancel(tdb);
ok1(tap_log_messages == 0); ok1(tap_log_messages == 1);
/* Surprise! Kills inner "committed" transaction. */ /* Surprise! Kills inner "committed" transaction. */
ok1(tdb_exists(tdb, key)); ok1(tdb_exists(tdb, key));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment