From f959d51e5ee06aad70d26ee38d4ef2be29c4f266 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 29 Apr 2012 13:22:52 +0200 Subject: [PATCH] Conf: Cleaned up use of journal Introduced a new function cf_revert() for reverting the configuration to its pristine state. It is automatically called upon cf_free_context(). Also, everything except cf_reload() now should work with journalling disabled. In this case, nothing is ever rolled back. --- ucw/conf-context.c | 6 ++++-- ucw/conf-input.c | 10 +++++++++- ucw/conf-internal.h | 2 +- ucw/conf-journal.c | 10 ++++------ ucw/conf-test.c | 26 +++++++++++++++++--------- ucw/conf.h | 8 ++++++++ 6 files changed, 43 insertions(+), 19 deletions(-) diff --git a/ucw/conf-context.c b/ucw/conf-context.c index f4929644..9572f06e 100644 --- a/ucw/conf-context.c +++ b/ucw/conf-context.c @@ -17,7 +17,7 @@ static struct cf_context cf_default_context; static void cf_init_context(struct cf_context *cc) { - cc->need_journal = 1; + cc->enable_journal = 1; clist_init(&cc->conf_entries); } @@ -32,9 +32,11 @@ cf_new_context(void) void cf_free_context(struct cf_context *cc) { - // FIXME: Roll back all transactions ASSERT(!cc->is_active); ASSERT(cc != &cf_default_context); + struct cf_context *prev = cf_switch_context(cc); + cf_revert(); + cf_switch_context(prev); xfree(cc->parser); xfree(cc); } diff --git a/ucw/conf-input.c b/ucw/conf-input.c index 3dc5db1d..9fa3a42f 100644 --- a/ucw/conf-input.c +++ b/ucw/conf-input.c @@ -329,7 +329,7 @@ struct conf_entry { /* We remember a list of actions to apply upon reload */ static void cf_remember_entry(struct cf_context *cc, uns type, const char *arg) { - if (!cc->need_journal) + if (!cc->enable_journal) return; struct conf_entry *ce = cf_malloc(sizeof(*ce)); ce->type = type; @@ -341,6 +341,7 @@ int cf_reload(const char *file) { struct cf_context *cc = cf_get_context(); + ASSERT(cc->enable_journal); cf_journal_swap(); struct cf_journal_item *oldj = cf_journal_new_transaction(1); uns ec = cc->everything_committed; @@ -406,3 +407,10 @@ cf_set(const char *string) cf_journal_rollback_transaction(0, oldj); return err; } + +void +cf_revert(void) +{ + cf_journal_swap(); + cf_journal_delete(); +} diff --git a/ucw/conf-internal.h b/ucw/conf-internal.h index 95ef6e6f..67a96cf5 100644 --- a/ucw/conf-internal.h +++ b/ucw/conf-internal.h @@ -49,7 +49,7 @@ struct cf_context { uns other_options; // used internally by cf_getopt() clist conf_entries; // files/strings to reload struct cf_journal_item *journal; // journalling - int need_journal; + int enable_journal; struct old_pools *pools; struct item_stack stack[MAX_STACK_SIZE]; // interpreter stack uns stack_level; diff --git a/ucw/conf-journal.c b/ucw/conf-journal.c index 6412328a..1cd51a6a 100644 --- a/ucw/conf-journal.c +++ b/ucw/conf-journal.c @@ -33,14 +33,14 @@ cf_set_journalling(int enable) { struct cf_context *cc = cf_get_context(); ASSERT(!cc->journal); - cc->need_journal = enable; + cc->enable_journal = enable; } void cf_journal_block(void *ptr, uns len) { struct cf_context *cc = cf_get_context(); - if (!cc->need_journal) + if (!cc->enable_journal) return; struct cf_journal_item *ji = cf_malloc(sizeof(struct cf_journal_item) + len); ji->prev = cc->journal; @@ -105,8 +105,8 @@ void cf_journal_rollback_transaction(uns new_pool, struct cf_journal_item *oldj) { struct cf_context *cc = cf_get_context(); - if (!cc->need_journal) - die("Cannot rollback the configuration, because the journal is disabled."); + if (!cc->enable_journal) + return; cf_journal_swap(); cc->journal = oldj; if (new_pool) @@ -126,5 +126,3 @@ cf_journal_delete(void) mp_delete(p->pool); } } - -/* TODO: more space efficient journal */ diff --git a/ucw/conf-test.c b/ucw/conf-test.c index fb353f91..2eb516bd 100644 --- a/ucw/conf-test.c +++ b/ucw/conf-test.c @@ -2,6 +2,7 @@ * Insane tester of reading configuration files * * (c) 2006 Robert Spalek + * (c) 2012 Martin Mares */ #include @@ -15,7 +16,6 @@ #include static int verbose; -static int new_context; static int reload; struct sub_sect_1 { @@ -173,7 +173,7 @@ static struct option long_opts[] = { }; static char *help = "\ -Usage: conf-test [ctxt] \n\ +Usage: conf-test [ctxt] [nojournal] \n\ \n\ Options:\n" CF_USAGE "\ -r, --reload\t\tReload configuration\n\ @@ -195,12 +195,19 @@ int main(int argc, char *argv[]) { log_init(argv[0]); - struct cf_context *cc = NULL, *prev = NULL; - if (argc > 1 && !strcmp(argv[1], "ctxt")) { - cc = cf_new_context(); - prev = cf_switch_context(cc); - argc--, argv++; + + // Special arguments which have to be parsed before cf_getopt() + while (argc > 1) { + if (!strcmp(argv[1], "ctxt")) { + cc = cf_new_context(); + prev = cf_switch_context(cc); + argc--, argv++; + } else if (!strcmp(argv[1], "nojournal")) { + cf_set_journalling(0); + argc--, argv++; + } else + break; } cf_declare_section("top", &cf_top, 0); @@ -209,7 +216,6 @@ main(int argc, char *argv[]) int opt; while ((opt = cf_getopt(argc, argv, short_opts, long_opts, NULL)) >= 0) switch (opt) { - case 'n': new_context++; break; case 'r': reload++; break; case 'v': verbose++; break; default: usage("unknown option %c\n", opt); @@ -228,10 +234,12 @@ main(int argc, char *argv[]) bclose(out); } - if (new_context) { + if (cc) { cf_switch_context(prev); cf_free_context(cc); } + printf("%08x\n", ip); + return 0; } diff --git a/ucw/conf.h b/ucw/conf.h index fc228eb8..9e93eb0f 100644 --- a/ucw/conf.h +++ b/ucw/conf.h @@ -63,6 +63,7 @@ struct cf_context *cf_switch_context(struct cf_context *cc); * configuration specified in the file are undone. **/ int cf_load(const char *file); + /** * Reload configuration from @file, replace the old one. * If @file is NULL, reload all loaded configuration files and re-apply @@ -71,6 +72,7 @@ int cf_load(const char *file); * settings are rolled back to the state before calling this function. **/ int cf_reload(const char *file); + /** * Parse some part of configuration passed in @string. * The syntax is the same as in the <>. @@ -97,6 +99,12 @@ void cf_open_group(void); **/ int cf_close_group(void); +/** + * Return all configuration items to their initial state before loading the + * configuration file. If journalling is disabled, it does nothing. + **/ +void cf_revert(void); + /*** === Data types [[conf_types]] ***/ enum cf_class { /** Class of the configuration item. **/ -- 2.39.2