Commit 9d9a9897 authored by Rusty Russell's avatar Rusty Russell

tdb2: Implement tdb_get_flags, tdb_add_flag and tdb_remove_flag.

parent ed81f394
......@@ -758,6 +758,59 @@ int tdb_close(struct tdb_context *tdb)
return ret;
}
unsigned int tdb_get_flags(struct tdb_context *tdb)
{
return tdb->flags;
}
void tdb_add_flag(struct tdb_context *tdb, unsigned flag)
{
if (tdb->flags & TDB_INTERNAL) {
tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_add_flag: internal db");
return;
}
switch (flag) {
case TDB_NOLOCK:
tdb->flags |= TDB_NOLOCK;
break;
case TDB_NOMMAP:
tdb->flags |= TDB_NOMMAP;
tdb_munmap(tdb);
break;
case TDB_NOSYNC:
tdb->flags |= TDB_NOSYNC;
break;
default:
tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_add_flag: Unknown flag %u", flag);
}
}
void tdb_remove_flag(struct tdb_context *tdb, unsigned flag)
{
if (tdb->flags & TDB_INTERNAL) {
tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_remove_flag: internal db");
return;
}
switch (flag) {
case TDB_NOLOCK:
tdb->flags &= ~TDB_NOLOCK;
break;
case TDB_NOMMAP:
tdb->flags &= ~TDB_NOMMAP;
tdb_mmap(tdb);
break;
case TDB_NOSYNC:
tdb->flags &= ~TDB_NOSYNC;
break;
default:
tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_remove_flag: Unknown flag %u", flag);
}
}
const char *tdb_errorstr(enum TDB_ERROR ecode)
{
/* Gcc warns if you miss a case in the switch, so use that. */
......
......@@ -379,6 +379,37 @@ enum TDB_ERROR tdb_summary(struct tdb_context *tdb,
enum tdb_summary_flags flags,
char **summary);
/**
* tdb_get_flags - return the flags for a tdb
* @tdb: the tdb context returned from tdb_open()
*
* This returns the flags on the current tdb. Some of these are caused by
* the flags argument to tdb_open(), others (such as TDB_CONVERT) are
* intuited.
*/
unsigned int tdb_get_flags(struct tdb_context *tdb);
/**
* tdb_add_flag - set a flag for a tdb
* @tdb: the tdb context returned from tdb_open()
* @flag: one of TDB_NOLOCK, TDB_NOMMAP or TDB_NOSYNC.
*
* You can use this to set a flag on the TDB. You cannot set these flags
* on a TDB_INTERNAL tdb.
*/
void tdb_add_flag(struct tdb_context *tdb, unsigned flag);
/**
* tdb_remove_flag - unset a flag for a tdb
* @tdb: the tdb context returned from tdb_open()
* @flag: one of TDB_NOLOCK, TDB_NOMMAP or TDB_NOSYNC.
*
* You can use this to clear a flag on the TDB. You cannot clear flags
* on a TDB_INTERNAL tdb.
*/
void tdb_remove_flag(struct tdb_context *tdb, unsigned flag);
/**
* enum tdb_attribute_type - descriminator for union tdb_attribute.
*/
......
#include <ccan/tdb2/tdb.c>
#include <ccan/tdb2/free.c>
#include <ccan/tdb2/lock.c>
#include <ccan/tdb2/io.c>
#include <ccan/tdb2/hash.c>
#include <ccan/tdb2/check.c>
#include <ccan/tdb2/traverse.c>
#include <ccan/tdb2/transaction.c>
#include <ccan/tap/tap.h>
#include "logging.h"
int main(int argc, char *argv[])
{
unsigned int i;
struct tdb_context *tdb;
int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT,
TDB_NOMMAP|TDB_CONVERT };
plan_tests(87);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
tdb = tdb_open("run-add-remove-flags.tdb", flags[i],
O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
ok1(tdb);
if (!tdb)
continue;
ok1(tdb_get_flags(tdb) == tdb->flags);
tap_log_messages = 0;
tdb_add_flag(tdb, TDB_NOLOCK);
if (flags[i] & TDB_INTERNAL)
ok1(tap_log_messages == 1);
else {
ok1(tap_log_messages == 0);
ok1(tdb_get_flags(tdb) & TDB_NOLOCK);
}
tap_log_messages = 0;
tdb_add_flag(tdb, TDB_NOMMAP);
if (flags[i] & TDB_INTERNAL)
ok1(tap_log_messages == 1);
else {
ok1(tap_log_messages == 0);
ok1(tdb_get_flags(tdb) & TDB_NOMMAP);
ok1(tdb->map_ptr == NULL);
}
tap_log_messages = 0;
tdb_add_flag(tdb, TDB_NOSYNC);
if (flags[i] & TDB_INTERNAL)
ok1(tap_log_messages == 1);
else {
ok1(tap_log_messages == 0);
ok1(tdb_get_flags(tdb) & TDB_NOSYNC);
}
ok1(tdb_get_flags(tdb) == tdb->flags);
tap_log_messages = 0;
tdb_remove_flag(tdb, TDB_NOLOCK);
if (flags[i] & TDB_INTERNAL)
ok1(tap_log_messages == 1);
else {
ok1(tap_log_messages == 0);
ok1(!(tdb_get_flags(tdb) & TDB_NOLOCK));
}
tap_log_messages = 0;
tdb_remove_flag(tdb, TDB_NOMMAP);
if (flags[i] & TDB_INTERNAL)
ok1(tap_log_messages == 1);
else {
ok1(tap_log_messages == 0);
ok1(!(tdb_get_flags(tdb) & TDB_NOMMAP));
ok1(tdb->map_ptr != NULL);
}
tap_log_messages = 0;
tdb_remove_flag(tdb, TDB_NOSYNC);
if (flags[i] & TDB_INTERNAL)
ok1(tap_log_messages == 1);
else {
ok1(tap_log_messages == 0);
ok1(!(tdb_get_flags(tdb) & TDB_NOSYNC));
}
tdb_close(tdb);
}
ok1(tap_log_messages == 0);
return exit_status();
}
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