From: Rusty Russell Date: Thu, 17 Mar 2011 11:42:21 +0000 (+1030) Subject: tdb2: Implement tdb_get_flags, tdb_add_flag and tdb_remove_flag. X-Git-Url: https://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=9d9a9897b608af3a6acd623cc09557f9985b03e6 tdb2: Implement tdb_get_flags, tdb_add_flag and tdb_remove_flag. --- diff --git a/ccan/tdb2/tdb.c b/ccan/tdb2/tdb.c index 42e75f9d..b5e54576 100644 --- a/ccan/tdb2/tdb.c +++ b/ccan/tdb2/tdb.c @@ -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. */ diff --git a/ccan/tdb2/tdb2.h b/ccan/tdb2/tdb2.h index 684bc049..47661da2 100644 --- a/ccan/tdb2/tdb2.h +++ b/ccan/tdb2/tdb2.h @@ -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. */ diff --git a/ccan/tdb2/test/run-add-remove-flags.c b/ccan/tdb2/test/run-add-remove-flags.c new file mode 100644 index 00000000..7c74e536 --- /dev/null +++ b/ccan/tdb2/test/run-add-remove-flags.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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(); +}