[SCM] Samba Shared Repository - branch master updated
Martin Schwenke
martins at samba.org
Fri Jun 29 13:13:02 UTC 2018
The branch, master has been updated
via e84b502 ctdb-common: Correctly handle conf->reload()
from b6b1226 ctdb: Improve robust mutex test
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit e84b5020a410b9c2cf736efee60ee704f8ea8f9c
Author: Amitay Isaacs <amitay at gmail.com>
Date: Mon Jun 25 12:56:45 2018 +1000
ctdb-common: Correctly handle conf->reload()
Configuration reload should reset the values of configuration options
missing from the config file to default.
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
Autobuild-User(master): Martin Schwenke <martins at samba.org>
Autobuild-Date(master): Fri Jun 29 15:12:37 CEST 2018 on sn-devel-144
-----------------------------------------------------------------------
Summary of changes:
ctdb/common/conf.c | 147 +++++++++++++++++++++++++++++++++-----
ctdb/tests/cunit/conf_test_001.sh | 48 ++++++++++++-
ctdb/tests/src/conf_test.c | 53 ++++++++++++++
3 files changed, 226 insertions(+), 22 deletions(-)
Changeset truncated at 500 lines:
diff --git a/ctdb/common/conf.c b/ctdb/common/conf.c
index dccf661..3c1369e 100644
--- a/ctdb/common/conf.c
+++ b/ctdb/common/conf.c
@@ -161,6 +161,44 @@ static int conf_value_from_string(TALLOC_CTX *mem_ctx,
return ret;
}
+static bool conf_value_compare(struct conf_value *old, struct conf_value *new)
+{
+ if (old == NULL || new == NULL) {
+ return false;
+ }
+
+ if (old->type != new->type) {
+ return false;
+ }
+
+ switch (old->type) {
+ case CONF_STRING:
+ if (old->data.string == NULL && new->data.string == NULL) {
+ return true;
+ }
+ if (old->data.string != NULL && new->data.string != NULL) {
+ if (strcmp(old->data.string, new->data.string) == 0) {
+ return true;
+ }
+ }
+ break;
+
+ case CONF_INTEGER:
+ if (old->data.integer == new->data.integer) {
+ return true;
+ }
+ break;
+
+ case CONF_BOOLEAN:
+ if (old->data.boolean == new->data.boolean) {
+ return true;
+ }
+ break;
+ }
+
+ return false;
+}
+
static int conf_value_copy(TALLOC_CTX *mem_ctx,
struct conf_value *src,
struct conf_value *dst)
@@ -409,6 +447,12 @@ static bool conf_option_validate(struct conf_option *opt,
return ret;
}
+static bool conf_option_same_value(struct conf_option *opt,
+ struct conf_value *new_value)
+{
+ return conf_value_compare(opt->value, new_value);
+}
+
static int conf_option_new_value(struct conf_option *opt,
struct conf_value *new_value,
enum conf_update_mode mode)
@@ -416,36 +460,56 @@ static int conf_option_new_value(struct conf_option *opt,
int ret;
bool ok;
- ok = conf_option_validate(opt, new_value, mode);
- if (!ok) {
- D_ERR("conf: validation for option \"%s\" failed\n",
- opt->name);
- return EINVAL;
+ if (opt->new_value != &opt->default_value) {
+ TALLOC_FREE(opt->new_value);
}
- TALLOC_FREE(opt->new_value);
- opt->new_value = talloc_zero(opt, struct conf_value);
- if (opt->new_value == NULL) {
- return ENOMEM;
- }
+ if (new_value == &opt->default_value) {
+ /*
+ * This happens only during load/reload. Set the value to
+ * default value, so if the config option is dropped from
+ * config file, then it get's reset to default.
+ */
+ opt->new_value = &opt->default_value;
+ } else {
+ ok = conf_option_validate(opt, new_value, mode);
+ if (!ok) {
+ D_ERR("conf: validation for option \"%s\" failed\n",
+ opt->name);
+ return EINVAL;
+ }
- opt->new_value->type = opt->value->type;
- ret = conf_value_copy(opt, new_value, opt->new_value);
- if (ret != 0) {
- return ret;
+ opt->new_value = talloc_zero(opt, struct conf_value);
+ if (opt->new_value == NULL) {
+ return ENOMEM;
+ }
+
+ opt->new_value->type = opt->value->type;
+ ret = conf_value_copy(opt, new_value, opt->new_value);
+ if (ret != 0) {
+ return ret;
+ }
}
conf_option_set_ptr_value(opt);
- if (mode == CONF_MODE_API) {
- opt->temporary_modified = true;
- } else {
- opt->temporary_modified = false;
+ if (new_value != &opt->default_value) {
+ if (mode == CONF_MODE_API) {
+ opt->temporary_modified = true;
+ } else {
+ opt->temporary_modified = false;
+ }
}
return 0;
}
+static int conf_option_new_default_value(struct conf_option *opt,
+ enum conf_update_mode mode)
+{
+ return conf_option_new_value(opt, &opt->default_value, mode);
+}
+
static void conf_option_default(struct conf_option *opt)
{
if (! opt->default_set) {
@@ -462,7 +526,9 @@ static void conf_option_default(struct conf_option *opt)
static void conf_option_reset(struct conf_option *opt)
{
- TALLOC_FREE(opt->new_value);
+ if (opt->new_value != &opt->default_value) {
+ TALLOC_FREE(opt->new_value);
+ }
conf_option_set_ptr_value(opt);
}
@@ -483,6 +549,11 @@ static void conf_option_update(struct conf_option *opt)
conf_option_set_ptr_value(opt);
}
+static void conf_option_reset_temporary(struct conf_option *opt)
+{
+ opt->temporary_modified = false;
+}
+
static bool conf_option_is_default(struct conf_option *opt)
{
return (opt->value == &opt->default_value);
@@ -586,6 +657,25 @@ static void conf_all_default(struct conf_context *conf)
}
}
+static int conf_all_temporary_default(struct conf_context *conf,
+ enum conf_update_mode mode)
+{
+ struct conf_section *s;
+ struct conf_option *opt;
+ int ret;
+
+ for (s = conf->section; s != NULL; s = s->next) {
+ for (opt = s->option; opt != NULL; opt = opt->next) {
+ ret = conf_option_new_default_value(opt, mode);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
static void conf_all_reset(struct conf_context *conf)
{
struct conf_section *s;
@@ -606,6 +696,7 @@ static void conf_all_update(struct conf_context *conf)
for (s = conf->section; s != NULL; s = s->next) {
for (opt = s->option; opt != NULL; opt = opt->next) {
conf_option_update(opt);
+ conf_option_reset_temporary(opt);
}
}
}
@@ -920,6 +1011,7 @@ static int conf_load_internal(struct conf_context *conf)
{
struct conf_load_state state;
FILE *fp;
+ int ret;
bool ok;
fp = fopen(conf->filename, "r");
@@ -932,6 +1024,11 @@ static int conf_load_internal(struct conf_context *conf)
.mode = (conf->reload ? CONF_MODE_RELOAD : CONF_MODE_LOAD),
};
+ ret = conf_all_temporary_default(conf, state.mode);
+ if (ret != 0) {
+ return ret;
+ }
+
ok = tini_parse(fp,
false,
conf_load_section,
@@ -998,6 +1095,7 @@ static bool conf_load_option(const char *name,
TALLOC_CTX *tmp_ctx;
struct conf_value value;
int ret;
+ bool ok;
if (state->s == NULL) {
if (state->conf->ignore_unknown) {
@@ -1035,6 +1133,11 @@ static bool conf_load_option(const char *name,
return false;
}
+ ok = conf_option_same_value(opt, &value);
+ if (ok) {
+ goto done;
+ }
+
ret = conf_option_new_value(opt, &value, state->mode);
if (ret != 0) {
talloc_free(tmp_ctx);
@@ -1042,6 +1145,7 @@ static bool conf_load_option(const char *name,
return false;
}
+done:
talloc_free(tmp_ctx);
return true;
@@ -1104,6 +1208,11 @@ static int conf_set(struct conf_context *conf,
return ENOENT;
}
+ ok = conf_option_same_value(opt, value);
+ if (ok) {
+ return 0;
+ }
+
ret = conf_option_new_value(opt, value, CONF_MODE_API);
if (ret != 0) {
conf_option_reset(opt);
diff --git a/ctdb/tests/cunit/conf_test_001.sh b/ctdb/tests/cunit/conf_test_001.sh
index e83e04c..08a51b0 100755
--- a/ctdb/tests/cunit/conf_test_001.sh
+++ b/ctdb/tests/cunit/conf_test_001.sh
@@ -32,7 +32,12 @@ unit_test conf_test 4
ok_null
unit_test conf_test 5
-ok_null
+ok <<EOF
+[section1]
+ key1 = foobar # temporary
+ key2 = 20 # temporary
+ key3 = false # temporary
+EOF
unit_test conf_test 6
ok <<EOF
@@ -77,7 +82,7 @@ ok <<EOF
[section1]
key1 = value2
key2 = 20
- key3 = false
+ # key3 = true
EOF
unit_test conf_test 9 "$conffile"
@@ -90,7 +95,7 @@ ok <<EOF
[section1]
key1 = value2
# key2 = 10
- key3 = false # temporary
+ # key3 = true
EOF
unit_test conf_test 9 "$conffile"
@@ -122,3 +127,40 @@ required_result 2 <<EOF
key3 = false # temporary
EOF
unit_test conf_test 10 "$conffile"
+
+cat > "$conffile" <<EOF
+[section1]
+ key1 = value2
+ key2 = 20
+ key3 = false
+EOF
+
+touch "${conffile}.reload"
+
+ok <<EOF
+[section1]
+ # key1 = value1
+ # key2 = 10
+ # key3 = true
+EOF
+unit_test conf_test 11 "$conffile"
+
+cat > "$conffile" <<EOF
+[section1]
+ key1 = value2
+ key2 = 20
+ key3 = false
+EOF
+
+cat > "${conffile}.reload" <<EOF
+[section1]
+ key1 = value3
+EOF
+
+ok <<EOF
+[section1]
+ key1 = value3
+ # key2 = 10
+ # key3 = true
+EOF
+unit_test conf_test 11 "$conffile"
diff --git a/ctdb/tests/src/conf_test.c b/ctdb/tests/src/conf_test.c
index a1bca69..b727cf3 100644
--- a/ctdb/tests/src/conf_test.c
+++ b/ctdb/tests/src/conf_test.c
@@ -248,6 +248,8 @@ static void test6(void)
assert(b2_val == false);
assert(is_default == false);
+ conf_dump(conf, stdout);
+
conf_set_defaults(conf);
assert(strcmp(s_val, "default") == 0);
@@ -310,12 +312,21 @@ static void test7(void)
status = conf_valid(conf);
assert(status == true);
+ ret = conf_set_string(conf, "section1", "key1", "default");
+ assert(ret == 0);
+
ret = conf_set_string(conf, "section1", "key1", "foobar");
assert(ret == EINVAL);
+ ret = conf_set_integer(conf, "section1", "key2", 10);
+ assert(ret == 0);
+
ret = conf_set_integer(conf, "section1", "key2", 20);
assert(ret == EINVAL);
+ ret = conf_set_boolean(conf, "section1", "key3", true);
+ assert(ret == 0);
+
ret = conf_set_boolean(conf, "section1", "key3", false);
assert(ret == EINVAL);
@@ -398,6 +409,45 @@ static void test9(const char *filename, bool ignore_unknown)
exit(ret);
}
+static void test11(const char *filename)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
+ char reload[PATH_MAX];
+ struct conf_context *conf;
+ int ret;
+ bool status;
+
+ ret = snprintf(reload, sizeof(reload), "%s.reload", filename);
+ assert(ret < sizeof(reload));
+
+ ret = conf_init(mem_ctx, &conf);
+ assert(ret == 0);
+ assert(conf != NULL);
+
+ conf_define_section(conf, "section1", NULL);
+
+ conf_define_string(conf, "section1", "key1", "value1", NULL);
+ conf_define_integer(conf, "section1", "key2", 10, NULL);
+ conf_define_boolean(conf, "section1", "key3", true, NULL);
+
+ status = conf_valid(conf);
+ assert(status == true);
+
+ ret = conf_load(conf, filename, false);
+ assert(ret == 0);
+
+ ret = rename(reload, filename);
+ assert(ret == 0);
+
+ ret = conf_reload(conf);
+ assert(ret == 0);
+
+ conf_dump(conf, stdout);
+
+ talloc_free(mem_ctx);
+ exit(ret);
+}
+
int main(int argc, const char **argv)
{
int num;
@@ -454,6 +504,9 @@ int main(int argc, const char **argv)
test9(argv[2], false);
break;
+ case 11:
+ test11(argv[2]);
+ break;
}
return 0;
--
Samba Shared Repository
More information about the samba-cvs
mailing list