master - config: runtime default for backup/backup_dir, backup/archive_dir
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0da1e5d9f8bdb2...
Commit: 0da1e5d9f8bdb2e4d385faf7c0f4604e63100acc
Parent: f6adef9825710ad93f96474a9719ef9fcf655721
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Mar 3 13:24:30 2014 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Mar 6 11:15:21 2014 +0100
config: runtime default for backup/backup_dir, backup/archive_dir
The backup/backup_dir and backup/archive_dir default value is evaluated
in runtime and takes LVM_SYSTEM_DIR into consideration...
---
lib/commands/toolcontext.c | 21 ++-------------------
lib/config/config.c | 26 ++++++++++++++++++++++++++
lib/config/config.h | 6 ++++--
lib/config/config_settings.h | 4 ++--
4 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 4b3d265..ce4349d 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1238,7 +1238,6 @@ static int _init_hostname(struct cmd_context *cmd)
static int _init_backup(struct cmd_context *cmd)
{
- static char default_dir[PATH_MAX];
uint32_t days, min;
const char *dir;
@@ -1257,16 +1256,8 @@ static int _init_backup(struct cmd_context *cmd)
min = (uint32_t) find_config_tree_int(cmd, backup_retain_min_CFG, NULL);
- if (dm_snprintf
- (default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
- DEFAULT_ARCHIVE_SUBDIR) == -1) {
- log_error("Couldn't create default archive path '%s/%s'.",
- cmd->system_dir, DEFAULT_ARCHIVE_SUBDIR);
- return 0;
- }
-
if (!(dir = find_config_tree_str(cmd, backup_archive_dir_CFG, NULL)))
- dir = default_dir;
+ return_0;
if (!archive_init(cmd, dir, days, min,
cmd->default_settings.archive)) {
@@ -1277,16 +1268,8 @@ static int _init_backup(struct cmd_context *cmd)
/* set up the backup */
cmd->default_settings.backup = find_config_tree_bool(cmd, backup_backup_CFG, NULL);
- if (dm_snprintf
- (default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
- DEFAULT_BACKUP_SUBDIR) == -1) {
- log_error("Couldn't create default backup path '%s/%s'.",
- cmd->system_dir, DEFAULT_BACKUP_SUBDIR);
- return 0;
- }
-
if (!(dir = find_config_tree_str(cmd, backup_backup_dir_CFG, NULL)))
- dir = default_dir;
+ return_0;
if (!backup_init(cmd, dir, cmd->default_settings.backup)) {
log_debug("backup_init failed.");
diff --git a/lib/config/config.c b/lib/config/config.c
index 65a2ba8..75b90fb 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -1648,3 +1648,29 @@ const char *get_default_devices_cache_CFG(struct cmd_context *cmd, struct profil
}
return dm_pool_strdup(cmd->mem, buf);
}
+
+const char *get_default_backup_backup_dir_CFG(struct cmd_context *cmd, struct profile *profile)
+{
+ static char buf[PATH_MAX];
+
+ if (dm_snprintf(buf, sizeof(buf), "%s/%s", cmd->system_dir, DEFAULT_BACKUP_SUBDIR) == -1) {
+ log_error("Couldn't create default backup path '%s/%s'.",
+ cmd->system_dir, DEFAULT_BACKUP_SUBDIR);
+ return NULL;
+ }
+
+ return dm_pool_strdup(cmd->mem, buf);
+}
+
+const char *get_default_backup_archive_dir_CFG(struct cmd_context *cmd, struct profile *profile)
+{
+ static char buf[PATH_MAX];
+
+ if (dm_snprintf (buf, sizeof(buf), "%s/%s", cmd->system_dir, DEFAULT_ARCHIVE_SUBDIR) == -1) {
+ log_error("Couldn't create default archive path '%s/%s'.",
+ cmd->system_dir, DEFAULT_ARCHIVE_SUBDIR);
+ return NULL;
+ }
+
+ return dm_pool_strdup(cmd->mem, buf);
+}
diff --git a/lib/config/config.h b/lib/config/config.h
index b7e0a16..a042c60 100644
--- a/lib/config/config.h
+++ b/lib/config/config.h
@@ -227,10 +227,12 @@ float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *pr
int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profile);
/*
- * Functions for individual configuration settings for
- * which the default value is evaluated at runtime.
+ * Functions for configuration settings for which the default
+ * value is evaluated at runtime based on command context.
*/
const char *get_default_devices_cache_dir_CFG(struct cmd_context *cmd, struct profile *profile);
const char *get_default_devices_cache_CFG(struct cmd_context *cmd, struct profile *profile);
+const char *get_default_backup_backup_dir_CFG(struct cmd_context *cmd, struct profile *profile);
+const char *get_default_backup_archive_dir_CFG(struct cmd_context *cmd, struct profile *profile);
#endif
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index fd59328..d6ccf0e 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -142,9 +142,9 @@ cfg(log_activate_file_CFG, "activate_file", log_CFG_SECTION, CFG_DEFAULT_UNDEFIN
cfg_array(log_debug_classes_CFG, "debug_classes", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#Smemory#Sdevices#Sactivation#Sallocation#Slvmetad#Smetadata#Scache#Slocking", vsn(2, 2, 99), NULL)
cfg(backup_backup_CFG, "backup", backup_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_BACKUP_ENABLED, vsn(1, 0, 0), NULL)
-cfg(backup_backup_dir_CFG, "backup_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
+cfg_runtime(backup_backup_dir_CFG, "backup_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), NULL)
cfg(backup_archive_CFG, "archive", backup_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ARCHIVE_ENABLED, vsn(1, 0, 0), NULL)
-cfg(backup_archive_dir_CFG, "archive_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
+cfg_runtime(backup_archive_dir_CFG, "archive_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), NULL)
cfg(backup_retain_min_CFG, "retain_min", backup_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_ARCHIVE_NUMBER, vsn(1, 0, 0), NULL)
cfg(backup_retain_days_CFG, "retain_days", backup_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_ARCHIVE_DAYS, vsn(1, 0, 0), NULL)
10 years, 1 month
master - config: runtime default for devices/cache, devices/cache_dir
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f6adef9825710a...
Commit: f6adef9825710ad93f96474a9719ef9fcf655721
Parent: b53ec372864cea412505327012cc46dc06dec366
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Mar 3 12:47:32 2014 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Mar 6 11:07:54 2014 +0100
config: runtime default for devices/cache, devices/cache_dir
The devices/cache and devices/cache_dir are evaluated in runtime this way:
- if devices/cache is set, use it
- if devices_cache/dir or devices/cache_file_prefix is set, make up a
path out of that for devices/cache in runtime, taking into account
the LVM_SYSTEM_DIR environment variable if set
- otherwise make up the path out of default which is:
<LVM_SYSTEM_DIR>/<cache_dir>/<cache_file_prefix>.cache
With the runtime defaults, we can encode this easily now. Also, the lvm
dumpconfig can show proper and exact information about this setting then
(the variant that shows default values).
---
lib/commands/toolcontext.c | 32 ++--------------------------
lib/config/config.c | 46 ++++++++++++++++++++++++++++++++++++++++++
lib/config/config.h | 7 ++++++
lib/config/config_settings.h | 6 ++--
4 files changed, 59 insertions(+), 32 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index ce1f5af..4b3d265 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -893,8 +893,7 @@ bad:
static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
{
- static char cache_file[PATH_MAX];
- const char *dev_cache = NULL, *cache_dir, *cache_file_prefix;
+ const char *dev_cache;
struct dev_filter *f3 = NULL, *f4 = NULL, *toplevel_components[2] = { 0 };
struct stat st;
const struct dm_config_node *cn;
@@ -907,33 +906,8 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
init_ignore_suspended_devices(find_config_tree_bool(cmd, devices_ignore_suspended_devices_CFG, NULL));
init_ignore_lvm_mirrors(find_config_tree_bool(cmd, devices_ignore_lvm_mirrors_CFG, NULL));
- /*
- * If 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'.
- */
- cache_dir = find_config_tree_str(cmd, devices_cache_dir_CFG, NULL);
- cache_file_prefix = find_config_tree_str(cmd, devices_cache_file_prefix_CFG, NULL);
-
- if (cache_dir || cache_file_prefix) {
- if (dm_snprintf(cache_file, sizeof(cache_file),
- "%s%s%s/%s.cache",
- cache_dir ? "" : cmd->system_dir,
- cache_dir ? "" : "/",
- cache_dir ? : DEFAULT_CACHE_SUBDIR,
- cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
- log_error("Persistent cache filename too long.");
- goto bad;
- }
- } else if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)) &&
- (dm_snprintf(cache_file, sizeof(cache_file),
- "%s/%s/%s.cache",
- cmd->system_dir, DEFAULT_CACHE_SUBDIR,
- DEFAULT_CACHE_FILE_PREFIX) < 0)) {
- log_error("Persistent cache filename too long.");
- goto bad;
- }
-
- if (!dev_cache)
- dev_cache = cache_file;
+ if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)))
+ goto_bad;
if (!(f4 = persistent_filter_create(cmd->dev_types, f3, dev_cache))) {
log_verbose("Failed to create persistent device filter.");
diff --git a/lib/config/config.c b/lib/config/config.c
index 5c6b5ba..65a2ba8 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -1602,3 +1602,49 @@ int load_pending_profiles(struct cmd_context *cmd)
return 1;
}
+
+const char *get_default_devices_cache_dir_CFG(struct cmd_context *cmd, struct profile *profile)
+{
+ static char buf[PATH_MAX];
+
+ if (dm_snprintf(buf, sizeof(buf), "%s/%s/", cmd->system_dir, DEFAULT_CACHE_SUBDIR) < 0) {
+ log_error("Persistent cache directory name too long.");
+ return NULL;
+ }
+
+ return dm_pool_strdup(cmd->mem, buf);
+}
+
+const char *get_default_devices_cache_CFG(struct cmd_context *cmd, struct profile *profile)
+{
+ const char *cache_dir = NULL, *cache_file_prefix = NULL;
+ static char buf[PATH_MAX];
+
+ /*
+ * If 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'.
+ */
+ if (find_config_tree_node(cmd, devices_cache_dir_CFG, profile))
+ cache_dir = find_config_tree_str(cmd, devices_cache_dir_CFG, profile);
+ if (find_config_tree_node(cmd, devices_cache_file_prefix_CFG, profile))
+ cache_file_prefix = find_config_tree_str_allow_empty(cmd, devices_cache_file_prefix_CFG, profile);
+
+ if (cache_dir || cache_file_prefix) {
+ if (dm_snprintf(buf, sizeof(buf),
+ "%s%s%s/%s.cache",
+ cache_dir ? "" : cmd->system_dir,
+ cache_dir ? "" : "/",
+ cache_dir ? : DEFAULT_CACHE_SUBDIR,
+ cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
+ log_error("Persistent cache filename too long.");
+ return NULL;
+ }
+ return dm_pool_strdup(cmd->mem, buf);
+ }
+
+ if (dm_snprintf(buf, sizeof(buf), "%s/%s/%s.cache", cmd->system_dir,
+ DEFAULT_CACHE_SUBDIR, DEFAULT_CACHE_FILE_PREFIX) < 0) {
+ log_error("Persistent cache filename too long.");
+ return NULL;
+ }
+ return dm_pool_strdup(cmd->mem, buf);
+}
diff --git a/lib/config/config.h b/lib/config/config.h
index aec72a0..b7e0a16 100644
--- a/lib/config/config.h
+++ b/lib/config/config.h
@@ -226,4 +226,11 @@ int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *
float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *profile);
int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profile);
+/*
+ * Functions for individual configuration settings for
+ * which the default value is evaluated at runtime.
+ */
+const char *get_default_devices_cache_dir_CFG(struct cmd_context *cmd, struct profile *profile);
+const char *get_default_devices_cache_CFG(struct cmd_context *cmd, struct profile *profile);
+
#endif
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 8d3d304..fd59328 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -92,9 +92,9 @@ cfg(devices_obtain_device_list_from_udev_CFG, "obtain_device_list_from_udev", de
cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL)
cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(devices_global_filter_CFG, "global_filter", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 98), NULL)
-cfg(devices_cache_CFG, "cache", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
-cfg(devices_cache_dir_CFG, "cache_dir", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL)
-cfg(devices_cache_file_prefix_CFG, "cache_file_prefix", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL)
+cfg_runtime(devices_cache_CFG, "cache", devices_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), NULL)
+cfg_runtime(devices_cache_dir_CFG, "cache_dir", devices_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 2, 19), NULL)
+cfg(devices_cache_file_prefix_CFG, "cache_file_prefix", devices_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_CACHE_FILE_PREFIX, vsn(1, 2, 19), NULL)
cfg(devices_write_cache_state_CFG, "write_cache_state", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(1, 0, 0), NULL)
cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT | CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(devices_sysfs_scan_CFG, "sysfs_scan", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SYSFS_SCAN, vsn(1, 0, 8), NULL)
10 years, 1 month
master - config: add CFG_DEFAULT_RUN_TIME for config options with runtime defaults
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b53ec372864cea...
Commit: b53ec372864cea412505327012cc46dc06dec366
Parent: e2870c94cf501f15ff9b1201bf468b40c1efd6d3
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Mar 3 12:34:11 2014 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Mar 6 10:54:17 2014 +0100
config: add CFG_DEFAULT_RUN_TIME for config options with runtime defaults
Previously, we declared a default value as undefined ("NULL") for
settings which require runtime context to be set first (e.g. settings
for paths that rely on SYSTEM_DIR environment variable or they depend
on any other setting in some way).
If we want to output default values as they are really used in runtime,
we should make it possible to define a default value as function which
is evaluated, not just providing a firm constant value as it was before.
This patch defines simple prototypes for such functions. Also, there's
new helper macros "cfg_runtime" and "cfg_array_runtime" - they provide
exactly the same functionality as the original "cfg" and "cfg_array"
macros when defining the configuration settings in config_settings.h,
but they don't set the constant default value. Instead, they automatically
link the configuration setting definition with one of these functions:
typedef int (*t_fn_CFG_TYPE_BOOL) (struct cmd_context *cmd, struct profile *profile);
typedef int (*t_fn_CFG_TYPE_INT) (struct cmd_context *cmd, struct profile *profile);
typedef float (*t_fn_CFG_TYPE_FLOAT) (struct cmd_context *cmd, struct profile *profile);
typedef const char* (*t_fn_CFG_TYPE_STRING) (struct cmd_context *cmd, struct profile *profile);
typedef const char* (*t_fn_CFG_TYPE_ARRAY) (struct cmd_context *cmd, struct profile *profile);
(The new macros actually set the CFG_DEFAULT_RUNTIME flag properly and
set the default value link to the function accordingly).
Then such configuration setting requires a function of selected type to
be defined. This function has a predefined name:
get_default_<id>
...where the <id> is the id of the setting as defined in
config_settings.h. For example "backup_archive_dir_CFG" if defined
as a setting with default value evaluated in runtime with "cfg_runtime"
will automatically have "get_default_backup_archive_dir_CFG" function
linked to this setting to get the default value.
---
lib/config/config.c | 27 ++++++++++++++++-----------
lib/config/config.h | 24 ++++++++++++++++++++++++
lib/config/config_settings.h | 23 ++++++++++++++++-------
tools/dumpconfig.c | 2 ++
4 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/lib/config/config.c b/lib/config/config.c
index cef00a0..5c6b5ba 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -62,11 +62,15 @@ struct config_source {
static struct cfg_def_item _cfg_def_items[CFG_COUNT + 1] = {
#define cfg_section(id, name, parent, flags, since_version, comment) {id, parent, name, CFG_TYPE_SECTION, {0}, flags, since_version, comment},
#define cfg(id, name, parent, flags, type, default_value, since_version, comment) {id, parent, name, type, {.v_##type = default_value}, flags, since_version, comment},
+#define cfg_runtime(id, name, parent, flags, type, since_version, comment) {id, parent, name, type, {.fn_##type = get_default_##id}, flags | CFG_DEFAULT_RUN_TIME, since_version, comment},
#define cfg_array(id, name, parent, flags, types, default_value, since_version, comment) {id, parent, name, CFG_TYPE_ARRAY | types, {.v_CFG_TYPE_STRING = default_value}, flags, since_version, comment},
+#define cfg_array_runtime(id, name, parent, flags, types, since_version, comment) {id, parent, name, CFG_TYPE_ARRAY | types, {.fn_CFG_TYPE_STRING = get_default_##id}, flags | CFG_DEFAULT_RUN_TIME, since_version, comment},
#include "config_settings.h"
#undef cfg_section
#undef cfg
+#undef cfg_runtime
#undef cfg_array
+#undef cfg_array_runtime
};
config_source_t config_get_source_type(struct dm_config_tree *cft)
@@ -474,7 +478,8 @@ time_t config_file_timestamp(struct dm_config_tree *cft)
}
#define cfg_def_get_item_p(id) (&_cfg_def_items[id])
-#define cfg_def_get_default_value(item,type) item->default_value.v_##type
+#define cfg_def_get_default_value(cmd,item,type,profile) ((item->flags & CFG_DEFAULT_RUN_TIME) ? item->default_value.fn_##type(cmd,profile) : item->default_value.v_##type)
+
static int _cfg_def_make_path(char *buf, size_t buf_size, int id, cfg_def_item_t *item, int xlate)
{
@@ -844,7 +849,7 @@ const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile
if (item->type != CFG_TYPE_STRING)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as string.", path);
- str = dm_config_tree_find_str(cmd->cft, path, cfg_def_get_default_value(item, CFG_TYPE_STRING));
+ str = dm_config_tree_find_str(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
@@ -870,7 +875,7 @@ const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, st
if (!(item->flags & CFG_ALLOW_EMPTY))
log_error(INTERNAL_ERROR "%s cfg tree element not declared to allow empty values.", path);
- str = dm_config_tree_find_str_allow_empty(cmd->cft, path, cfg_def_get_default_value(item, CFG_TYPE_STRING));
+ str = dm_config_tree_find_str_allow_empty(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
@@ -894,7 +899,7 @@ int find_config_tree_int(struct cmd_context *cmd, int id, struct profile *profil
if (item->type != CFG_TYPE_INT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as integer.", path);
- i = dm_config_tree_find_int(cmd->cft, path, cfg_def_get_default_value(item, CFG_TYPE_INT));
+ i = dm_config_tree_find_int(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
@@ -918,7 +923,7 @@ int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *
if (item->type != CFG_TYPE_INT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as integer.", path);
- i64 = dm_config_tree_find_int64(cmd->cft, path, cfg_def_get_default_value(item, CFG_TYPE_INT));
+ i64 = dm_config_tree_find_int64(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
@@ -942,7 +947,7 @@ float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *pr
if (item->type != CFG_TYPE_FLOAT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as float.", path);
- f = dm_config_tree_find_float(cmd->cft, path, cfg_def_get_default_value(item, CFG_TYPE_FLOAT));
+ f = dm_config_tree_find_float(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_FLOAT, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
@@ -966,7 +971,7 @@ int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profi
if (item->type != CFG_TYPE_BOOL)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as boolean.", path);
- b = dm_config_tree_find_bool(cmd->cft, path, cfg_def_get_default_value(item, CFG_TYPE_BOOL));
+ b = dm_config_tree_find_bool(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_BOOL, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
@@ -1353,19 +1358,19 @@ static struct dm_config_node *_add_def_node(struct dm_config_tree *cft,
break;
case CFG_TYPE_BOOL:
cn->v->type = DM_CFG_INT;
- cn->v->v.i = cfg_def_get_default_value(def, CFG_TYPE_BOOL);
+ cn->v->v.i = cfg_def_get_default_value(spec->cmd, def, CFG_TYPE_BOOL, NULL);
break;
case CFG_TYPE_INT:
cn->v->type = DM_CFG_INT;
- cn->v->v.i = cfg_def_get_default_value(def, CFG_TYPE_INT);
+ cn->v->v.i = cfg_def_get_default_value(spec->cmd, def, CFG_TYPE_INT, NULL);
break;
case CFG_TYPE_FLOAT:
cn->v->type = DM_CFG_FLOAT;
- cn->v->v.f = cfg_def_get_default_value(def, CFG_TYPE_FLOAT);
+ cn->v->v.f = cfg_def_get_default_value(spec->cmd, def, CFG_TYPE_FLOAT, NULL);
break;
case CFG_TYPE_STRING:
cn->v->type = DM_CFG_STRING;
- if (!(str = cfg_def_get_default_value(def, CFG_TYPE_STRING)))
+ if (!(str = cfg_def_get_default_value(spec->cmd, def, CFG_TYPE_STRING, NULL)))
str = "";
cn->v->v.str = str;
break;
diff --git a/lib/config/config.h b/lib/config/config.h
index f716efb..aec72a0 100644
--- a/lib/config/config.h
+++ b/lib/config/config.h
@@ -63,11 +63,28 @@ typedef enum {
CFG_TYPE_STRING = 1 << 5, /* setting */
} cfg_def_type_t;
+typedef struct cfg_def_item cfg_def_item_t;
+
+/* function types to evaluate default value at runtime */
+typedef int (*t_fn_CFG_TYPE_BOOL) (struct cmd_context *cmd, struct profile *profile);
+typedef int (*t_fn_CFG_TYPE_INT) (struct cmd_context *cmd, struct profile *profile);
+typedef float (*t_fn_CFG_TYPE_FLOAT) (struct cmd_context *cmd, struct profile *profile);
+typedef const char* (*t_fn_CFG_TYPE_STRING) (struct cmd_context *cmd, struct profile *profile);
+typedef const char* (*t_fn_CFG_TYPE_ARRAY) (struct cmd_context *cmd, struct profile *profile);
+
/* configuration definition item value (for item's default value) */
typedef union {
+ /* static value - returns a variable */
const int v_CFG_TYPE_BOOL, v_CFG_TYPE_INT;
const float v_CFG_TYPE_FLOAT;
const char *v_CFG_TYPE_STRING, *v_CFG_TYPE_ARRAY;
+
+ /* run-time value - evaluates a function */
+ t_fn_CFG_TYPE_BOOL fn_CFG_TYPE_BOOL;
+ t_fn_CFG_TYPE_INT fn_CFG_TYPE_INT;
+ t_fn_CFG_TYPE_FLOAT fn_CFG_TYPE_FLOAT;
+ t_fn_CFG_TYPE_STRING fn_CFG_TYPE_STRING;
+ t_fn_CFG_TYPE_ARRAY fn_CFG_TYPE_ARRAY;
} cfg_def_value_t;
/* configuration definition item flags: */
@@ -84,6 +101,8 @@ typedef union {
#define CFG_PROFILABLE 0x10
/* whether the default value is undefned */
#define CFG_DEFAULT_UNDEFINED 0x20
+/* whether the defualt value is calculated during run time */
+#define CFG_DEFAULT_RUN_TIME 0x40
/* configuration definition item structure */
typedef struct cfg_def_item {
@@ -109,6 +128,7 @@ typedef enum {
/* configuration definition tree specification */
struct config_def_tree_spec {
+ struct cmd_context *cmd; /* command context (for run-time defaults */
cfg_def_tree_t type; /* tree type */
uint16_t version; /* tree at this LVM2 version */
int ignoreadvanced:1; /* do not include advanced configs */
@@ -130,11 +150,15 @@ struct config_def_tree_spec {
enum {
#define cfg_section(id, name, parent, flags, since_version, comment) id,
#define cfg(id, name, parent, flags, type, default_value, since_version, comment) id,
+#define cfg_runtime(id, name, parent, flags, type, since_version, comment) id,
#define cfg_array(id, name, parent, flags, types, default_value, since_version, comment) id,
+#define cfg_array_runtime(id, name, parent, flags, types, since_version, comment) id,
#include "config_settings.h"
#undef cfg_section
#undef cfg
+#undef cfg_runtime
#undef cfg_array
+#undef cfg_array_runtime
};
struct profile *add_profile(struct cmd_context *cmd, const char *profile_name);
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index eb89e87..8d3d304 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -14,15 +14,24 @@
/*
* MACROS:
- * cfg_section(id, name, parent, flags, since_version, comment)
- * cfg(id, name, parent, flags, type, default_value, since_version, comment)
- * cfg_array(id, name, parent, flags, types, default_value, since_version, comment)
+ * - define a configuration section:
+ * cfg_section(id, name, parent, flags, since_version, comment)
*
- * VARIABLES:
- * cfg_section: define a new configuration section
- * cfg: define a new configuration setting of a simple type
- * cfg_array: define a new configuration setting of array type
+ * - define a configuration setting of simple type:
+ * cfg(id, name, parent, flags, type, default_value, since_version, comment)
+ *
+ * - define a configuration array of one or more types:
+ * cfg_array(id, name, parent, flags, types, default_value, since_version, comment)
+ *
+ * If default value can't be assigned statically because it depends on some
+ * run-time checks or if it depends on other settings already defined,
+ * the configuration setting or array can be defined with the
+ * "{cfg|cfg_array}_runtime" macro. In this case the default value
+ * is evaluated by automatically calling "get_default_<id>" function.
+ * See config.h and "function types to evaluate default value at runtime".
*
+ *
+ * VARIABLES:
* id: unique identifier
* name: configuration node name
* parent: id of parent configuration node
diff --git a/tools/dumpconfig.c b/tools/dumpconfig.c
index cb88bc6..dd86733 100644
--- a/tools/dumpconfig.c
+++ b/tools/dumpconfig.c
@@ -97,6 +97,8 @@ int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
struct cft_check_handle *cft_check_handle = NULL;
int r = ECMD_PROCESSED;
+ tree_spec.cmd = cmd;
+
if (arg_count(cmd, configtype_ARG) && arg_count(cmd, validate_ARG)) {
log_error("Only one of --type and --validate permitted.");
return EINVALID_CMD_LINE;
10 years, 1 month
master - config: use mempool for config paths used in find_config_tree_* functions
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e2870c94cf501f...
Commit: e2870c94cf501f15ff9b1201bf468b40c1efd6d3
Parent: c5a4e60c112893b5624cede0dac89bd5de7e14a4
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Mar 3 12:29:25 2014 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Mar 6 10:50:47 2014 +0100
config: use mempool for config paths used in find_config_tree_* functions
Using mempool is much safer than using the global static variable.
The global variable would be rewritten on each find_config_tree_* call
and we need to be very careful not to get into this problem (we don't
do now, but we can with the patches for "runtime defaults" that will follow).
---
lib/commands/toolcontext.c | 10 +++---
lib/config/config.c | 68 +++++++++++++++++++++++++++++--------------
2 files changed, 51 insertions(+), 27 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index a709284..ce1f5af 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1479,6 +1479,11 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
goto out;
}
+ if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
+ log_error("Command memory pool creation failed");
+ goto out;
+ }
+
if (!_init_lvm_conf(cmd))
goto_out;
@@ -1512,11 +1517,6 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
if (!_init_filters(cmd, 1))
goto_out;
- if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
- log_error("Command memory pool creation failed");
- goto out;
- }
-
memlock_init(cmd);
if (!_init_formats(cmd))
diff --git a/lib/config/config.c b/lib/config/config.c
index e51c26f..cef00a0 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -56,8 +56,6 @@ struct config_source {
} source;
};
-char _cfg_path[CFG_PATH_MAX_LEN];
-
/*
* Map each ID to respective definition of the configuration item.
*/
@@ -477,8 +475,6 @@ time_t config_file_timestamp(struct dm_config_tree *cft)
#define cfg_def_get_item_p(id) (&_cfg_def_items[id])
#define cfg_def_get_default_value(item,type) item->default_value.v_##type
-#define cfg_def_get_path(item) (_cfg_def_make_path(_cfg_path,CFG_PATH_MAX_LEN,item->id,item, 0),_cfg_path)
-#define cfg_def_get_path_xlated(item) (_cfg_def_make_path(_cfg_path,CFG_PATH_MAX_LEN,item->id,item, 1),_cfg_path)
static int _cfg_def_make_path(char *buf, size_t buf_size, int id, cfg_def_item_t *item, int xlate)
{
@@ -504,6 +500,21 @@ static int _cfg_def_make_path(char *buf, size_t buf_size, int id, cfg_def_item_t
return count + n;
}
+static char *_cfg_def_get_path(struct dm_pool *mem, cfg_def_item_t *item, int xlate)
+{
+ char *path;
+
+ if (!(path = dm_pool_alloc(mem, CFG_PATH_MAX_LEN))) {
+ log_error("Failed to allocate buffer for configuration path.");
+ return NULL;
+ }
+
+ if (!_cfg_def_make_path(path, CFG_PATH_MAX_LEN, item->id, item, xlate))
+ return_0;
+
+ return path;
+}
+
int config_def_get_path(char *buf, size_t buf_size, int id)
{
return _cfg_def_make_path(buf, buf_size, id, cfg_def_get_item_p(id), 0);
@@ -702,7 +713,7 @@ int config_def_check(struct cmd_context *cmd, struct cft_check_handle *handle)
{
cfg_def_item_t *def;
struct dm_config_node *cn;
- char *vp = _cfg_path, rp[CFG_PATH_MAX_LEN];
+ char vp[CFG_PATH_MAX_LEN], rp[CFG_PATH_MAX_LEN];
size_t rplen;
int id, r = 1;
@@ -742,7 +753,7 @@ int config_def_check(struct cmd_context *cmd, struct cft_check_handle *handle)
}
for (id = 1; id < CFG_COUNT; id++) {
def = cfg_def_get_item_p(id);
- if (!cfg_def_get_path(def)) {
+ if (!_cfg_def_make_path(vp, CFG_PATH_MAX_LEN, def->id, def, 0)) {
dm_hash_destroy(cmd->cft_def_hash);
cmd->cft_def_hash = NULL;
r = 0; goto out;
@@ -800,31 +811,35 @@ out:
const struct dm_config_node *find_config_tree_node(struct cmd_context *cmd, int id, struct profile *profile)
{
+ char *path;
int profile_applied = 0;
const struct dm_config_node *cn;
if (profile && !cmd->profile_params->global_profile)
profile_applied = override_config_tree_from_profile(cmd, profile);
- cn = dm_config_tree_find_node(cmd->cft, cfg_def_get_path(cfg_def_get_item_p(id)));
+ path = _cfg_def_get_path(cmd->mem, cfg_def_get_item_p(id), 0);
+
+ cn = dm_config_tree_find_node(cmd->cft, path);
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ dm_pool_free(cmd->mem, path);
return cn;
}
const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
- const char *path;
+ char *path;
int profile_applied = 0;
const char *str;
if (profile && !cmd->profile_params->global_profile)
profile_applied = override_config_tree_from_profile(cmd, profile);
- path = cfg_def_get_path(item);
+ path = _cfg_def_get_path(cmd->mem, item, 0);
if (item->type != CFG_TYPE_STRING)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as string.", path);
@@ -834,20 +849,21 @@ const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ dm_pool_free(cmd->mem, path);
return str;
}
const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
- const char *path;
+ char *path;
int profile_applied = 0;
const char *str;
if (profile && !cmd->profile_params->global_profile)
profile_applied = override_config_tree_from_profile(cmd, profile);
- path = cfg_def_get_path(item);
+ path = _cfg_def_get_path(cmd->mem, item, 0);
if (item->type != CFG_TYPE_STRING)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as string.", path);
@@ -859,20 +875,21 @@ const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, st
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ dm_pool_free(cmd->mem, path);
return str;
}
int find_config_tree_int(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
- const char *path;
+ char *path;
int profile_applied = 0;
int i;
if (profile && !cmd->profile_params->global_profile)
profile_applied = override_config_tree_from_profile(cmd, profile);
- path = cfg_def_get_path(item);
+ path = _cfg_def_get_path(cmd->mem, item, 0);
if (item->type != CFG_TYPE_INT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as integer.", path);
@@ -882,20 +899,21 @@ int find_config_tree_int(struct cmd_context *cmd, int id, struct profile *profil
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ dm_pool_free(cmd->mem, path);
return i;
}
int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
- const char *path;
+ char *path;
int profile_applied = 0;
int i64;
if (profile && !cmd->profile_params->global_profile)
profile_applied = override_config_tree_from_profile(cmd, profile);
- path = cfg_def_get_path(item);
+ path = _cfg_def_get_path(cmd->mem, item, 0);
if (item->type != CFG_TYPE_INT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as integer.", path);
@@ -905,20 +923,21 @@ int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ dm_pool_free(cmd->mem, path);
return i64;
}
float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
- const char *path;
+ char *path;
int profile_applied = 0;
float f;
if (profile && !cmd->profile_params->global_profile)
profile_applied = override_config_tree_from_profile(cmd, profile);
- path = cfg_def_get_path(item);
+ path = _cfg_def_get_path(cmd->mem, item, 0);
if (item->type != CFG_TYPE_FLOAT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as float.", path);
@@ -928,20 +947,21 @@ float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *pr
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ dm_pool_free(cmd->mem, path);
return f;
}
int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
- const char *path = cfg_def_get_path(item);
+ char *path;
int profile_applied = 0;
int b;
if (profile && !cmd->profile_params->global_profile)
profile_applied = override_config_tree_from_profile(cmd, profile);
- path = cfg_def_get_path(item);
+ path = _cfg_def_get_path(cmd->mem, item, 0);
if (item->type != CFG_TYPE_BOOL)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as boolean.", path);
@@ -951,6 +971,7 @@ int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profi
if (profile_applied)
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
+ dm_pool_free(cmd->mem, path);
return b;
}
@@ -1091,6 +1112,7 @@ int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
struct out_baton {
FILE *fp;
struct config_def_tree_spec *tree_spec;
+ struct dm_pool *mem;
};
static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, void *baton)
@@ -1098,8 +1120,8 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
struct out_baton *out = baton;
struct cfg_def_item *cfg_def;
char version[9]; /* 8+1 chars for max version of 7.15.511 */
- const char *path;
const char *node_type_name = cn->v ? "option" : "section";
+ char *path;
if (cn->id < 0)
return 1;
@@ -1112,8 +1134,9 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
cfg_def = cfg_def_get_item_p(cn->id);
if (out->tree_spec->withcomments) {
- path = cfg_def_get_path_xlated(cfg_def);
+ path = _cfg_def_get_path(out->mem, cfg_def, 1);
fprintf(out->fp, "%s# Configuration %s %s.\n", line, node_type_name, path);
+ dm_pool_free(out->mem, path);
if (cfg_def->comment)
fprintf(out->fp, "%s# %s\n", line, cfg_def->comment);
@@ -1171,7 +1194,8 @@ int config_write(struct dm_config_tree *cft,
};
const struct dm_config_node *cn;
struct out_baton baton = {
- .tree_spec = tree_spec
+ .tree_spec = tree_spec,
+ .mem = cft->mem
};
int r = 1;
10 years, 1 month
master - config: fixup default values for selected config settings
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c5a4e60c112893...
Commit: c5a4e60c112893b5624cede0dac89bd5de7e14a4
Parent: 52aa3dbcabe85b38b51c68c27fb2397eb0fb1efd
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Mar 6 09:41:11 2014 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Mar 6 09:49:57 2014 +0100
config: fixup default values for selected config settings
These settings don't have any default value predefined:
log/file
log/activate_file
global/library_dir
This settings has default value but not yet declared in config_settings.h:
global/locking_library (default is DEFAULT_LOCKING_LIB)
---
lib/config/config_settings.h | 8 ++++----
lib/locking/external_locking.c | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 32ca0cf..eb89e87 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -122,14 +122,14 @@ cfg(allocation_thin_pool_chunk_size_CFG, "thin_pool_chunk_size", allocation_CFG_
cfg(log_verbose_CFG, "verbose", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_VERBOSE, vsn(1, 0, 0), NULL)
cfg(log_silent_CFG, "silent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SILENT, vsn(2, 2, 98), NULL)
cfg(log_syslog_CFG, "syslog", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SYSLOG, vsn(1, 0, 0), NULL)
-cfg(log_file_CFG, "file", log_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
+cfg(log_file_CFG, "file", log_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(log_overwrite_CFG, "overwrite", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_OVERWRITE, vsn(1, 0, 0), NULL)
cfg(log_level_CFG, "level", log_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_LOGLEVEL, vsn(1, 0, 0), NULL)
cfg(log_indent_CFG, "indent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_INDENT, vsn(1, 0, 0), NULL)
cfg(log_command_names_CFG, "command_names", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_CMD_NAME, vsn(1, 0, 0), NULL)
cfg(log_prefix_CFG, "prefix", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_MSG_PREFIX, vsn(1, 0, 0), NULL)
cfg(log_activation_CFG, "activation", log_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(1, 0, 0), NULL)
-cfg(log_activate_file_CFG, "activate_file", log_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
+cfg(log_activate_file_CFG, "activate_file", log_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(log_debug_classes_CFG, "debug_classes", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#Smemory#Sdevices#Sactivation#Sallocation#Slvmetad#Smetadata#Scache#Slocking", vsn(2, 2, 99), NULL)
cfg(backup_backup_CFG, "backup", backup_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_BACKUP_ENABLED, vsn(1, 0, 0), NULL)
@@ -158,8 +158,8 @@ cfg(global_fallback_to_clustered_locking_CFG, "fallback_to_clustered_locking", g
cfg(global_fallback_to_local_locking_CFG, "fallback_to_local_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_LOCAL_LOCKING, vsn(2, 2, 42), NULL)
cfg(global_locking_dir_CFG, "locking_dir", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_LOCK_DIR, vsn(1, 0, 0), NULL)
cfg(global_prioritise_write_locks_CFG, "prioritise_write_locks", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_PRIORITISE_WRITE_LOCKS, vsn(2, 2, 52), NULL)
-cfg(global_library_dir_CFG, "library_dir", global_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
-cfg(global_locking_library_CFG, "locking_library", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
+cfg(global_library_dir_CFG, "library_dir", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
+cfg(global_locking_library_CFG, "locking_library", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_LOCKING_LIB, vsn(1, 0, 0), NULL)
cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ABORT_ON_INTERNAL_ERRORS, vsn(2, 2, 57), NULL)
cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_corruption", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION, vsn(2, 2, 96), NULL)
cfg(global_metadata_read_only_CFG, "metadata_read_only", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_METADATA_READ_ONLY, vsn(2, 2, 75), NULL)
diff --git a/lib/locking/external_locking.c b/lib/locking/external_locking.c
index 8b63a29..1e669bb 100644
--- a/lib/locking/external_locking.c
+++ b/lib/locking/external_locking.c
@@ -81,7 +81,7 @@ int init_external_locking(struct locking_type *locking, struct cmd_context *cmd,
locking->flags = 0;
if (!(libname = find_config_tree_str(cmd, global_locking_library_CFG, NULL)))
- libname = DEFAULT_LOCKING_LIB;
+ return_0;
if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1)))
return_0;
10 years, 1 month
master - cmirrord: Clean-up stray warning message
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=52aa3dbcabe85b...
Commit: 52aa3dbcabe85b38b51c68c27fb2397eb0fb1efd
Parent: 2c42f608904a853328341eac3cfd3c48033a3238
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Wed Mar 5 10:44:20 2014 -0600
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Wed Mar 5 10:44:20 2014 -0600
cmirrord: Clean-up stray warning message
cmirrord polls for messages on the kernel and cluster interfaces.
Sometimes it is possible for messages to be received on the cluster
interface and be waiting for processing while the node is in the
process of leaving the cluster group. When this happens, the
messages received on the cluster interface are attempted to be
dispatched, but an error is returned because the connection is no
longer valid. It is a harmless situation. So, if we get the
specific error (CS_ERR_BAD_HANDLE) and we know that we have left
the group, then simply don't print the message.
---
daemons/cmirrord/cluster.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/daemons/cmirrord/cluster.c b/daemons/cmirrord/cluster.c
index fea739a..67391f1 100644
--- a/daemons/cmirrord/cluster.c
+++ b/daemons/cmirrord/cluster.c
@@ -984,9 +984,16 @@ static int do_cluster_work(void *data __attribute__((unused)))
dm_list_iterate_items_safe(entry, tmp, &clog_cpg_list) {
r = cpg_dispatch(entry->handle, CS_DISPATCH_ALL);
- if (r != CS_OK)
- LOG_ERROR("cpg_dispatch failed: %s",
- str_ais_error(r));
+ if (r != CS_OK) {
+ if ((entry->cpg_state == INVALID) &&
+ (entry->state == LEAVING) &&
+ (r == CS_ERR_BAD_HANDLE))
+ /* It's ok if we've left the cluster */
+ r = CS_OK;
+ else
+ LOG_ERROR("cpg_dispatch failed: %s",
+ str_ais_error(r));
+ }
if (entry->free_me) {
free(entry);
10 years, 1 month
master - udev: run pvscan --cache via systemd-run in udev if the PV label is detected lost
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2c42f608904a85...
Commit: 2c42f608904a853328341eac3cfd3c48033a3238
Parent: 3c9887467f3c33d5ea10503c74ad85c4b119d3df
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Mar 5 14:25:08 2014 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Mar 5 14:30:58 2014 +0100
udev: run pvscan --cache via systemd-run in udev if the PV label is detected lost
If the PV label is lost (e.g. by doing a dd on the device), call
"systemd-run pvscan --cache <major>:<minor>" in 69-dm-lvm-metad.rules
to inform lvmetad about this state.
The reason for this is that ENV{SYSTEMD_WANTS}="lvm2-pvscan@<major>:<minor>"
logic will not cause the pvscan to be fired in this case since this works
only on proper device addition/removal cycle - the lvm2-pvscan service's
ExecStop is called only on proper REMOVE event - the service is bound to
device existence. Hence we need pvscan call via systemd-run (that
instantiates a quick transient service just to call the command).
See also https://bugzilla.redhat.com/show_bug.cgi?id=1063813.
---
WHATS_NEW | 1 +
udev/Makefile.in | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 8b5f31a..7deba2f 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.106 -
====================================
+ Run pvscan --cache via systemd-run in udev if the PV label is detected lost.
Fix memleak when lvmetad discovers PV to appear on another device.
Fix calculation of maximum size of COW device for snapshot (2.02.99).
Do not allow stripe size to be bigger then extent size for lvresize.
diff --git a/udev/Makefile.in b/udev/Makefile.in
index 40a4671..a2e2571 100644
--- a/udev/Makefile.in
+++ b/udev/Makefile.in
@@ -47,7 +47,7 @@ BLKID_RULE=IMPORT{program}=\"${SBIN}\/blkid -o udev -p \$$tempnode\"
endif
ifeq ("@UDEV_SYSTEMD_BACKGROUND_JOBS@", "yes")
-PVSCAN_RULE=ENV{SYSTEMD_ALIAS}=\"\/dev\/block\/\$$major:\$$minor\"\nENV{ID_MODEL}=\"LVM PV \$$env{ID_FS_UUID_ENC} on \/dev\/\$$name\"\nENV{SYSTEMD_WANTS}=\"lvm2-pvscan@\$$major:\$$minor.service\"
+PVSCAN_RULE=ACTION\!=\"remove\", ENV{LVM_PV_GONE}==\"1\", RUN\+=\"@bindir@/systemd-run $(LVM_EXEC)\/lvm pvscan --cache \$$major\:\$$minor\", GOTO=\"lvm_end\"\nENV{SYSTEMD_ALIAS}=\"\/dev\/block\/\$$major:\$$minor\"\nENV{ID_MODEL}=\"LVM PV \$$env{ID_FS_UUID_ENC} on \/dev\/\$$name\"\nENV{SYSTEMD_WANTS}=\"lvm2-pvscan@\$$major:\$$minor.service\"
else
PVSCAN_RULE=RUN\+\=\"$(LVM_EXEC)/lvm pvscan --background --cache --activate ay --major \$$major --minor \$$minor\", ENV{LVM_SCANNED}=\"1\"
endif
10 years, 1 month
master - test: Use correct path to /dev in lvchange-raid.sh.
by Petr Rockai
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3c9887467f3c33...
Commit: 3c9887467f3c33d5ea10503c74ad85c4b119d3df
Parent: 08aedff1fc86d731f19993c259aaeee19cad7b8c
Author: Petr Rockai <me(a)mornfall.net>
AuthorDate: Wed Mar 5 10:21:49 2014 +0100
Committer: Petr Rockai <me(a)mornfall.net>
CommitterDate: Wed Mar 5 10:22:39 2014 +0100
test: Use correct path to /dev in lvchange-raid.sh.
---
test/shell/lvchange-raid.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/shell/lvchange-raid.sh b/test/shell/lvchange-raid.sh
index 8fc91a3..0807fff 100644
--- a/test/shell/lvchange-raid.sh
+++ b/test/shell/lvchange-raid.sh
@@ -216,7 +216,7 @@ run_refresh_check() {
# Disable dev2 and do some I/O to make the kernel notice
aux disable_dev "$dev2"
- dd if=/dev/urandom of=/dev/$sizelv bs=1k count=$size
+ dd if=/dev/urandom of=$DM_DEV_DIR/$sizelv bs=1k count=$size
sync
# Check for 'p'artial flag
10 years, 1 month
master - tests: testing usable of /dev/kmsg
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=08aedff1fc86d7...
Commit: 08aedff1fc86d731f19993c259aaeee19cad7b8c
Parent: 9a99cb8c7947e19291794aa80d5bcdc73fa6245f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Mar 4 17:50:17 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 4 17:54:33 2014 +0100
tests: testing usable of /dev/kmsg
It's not so easy to recongnize unusable /dev/kmsg
Reorder the code in a way if the first regular read of /dev/kmsg
fail, fallback to klogctl interface.
Call drain_dmesg also for the case there is no user log output.
---
test/lib/harness.c | 49 +++++++++++++++++++++----------------------------
1 files changed, 21 insertions(+), 28 deletions(-)
diff --git a/test/lib/harness.c b/test/lib/harness.c
index 4e9c54f..7ee45c8 100644
--- a/test/lib/harness.c
+++ b/test/lib/harness.c
@@ -260,24 +260,6 @@ static int drain(int fd)
static int drain_fds(int fd1, int fd2, long timeout)
{
- int ret;
- fd_set set;
- struct timeval selectwait = { .tv_usec = timeout };
-
- FD_ZERO(&set);
- FD_SET(fd1, &set);
- if (fd2 >= 0)
- FD_SET(fd2, &set);
-
- if ((ret = select(fd2 > fd1 ? fd2 + 1 : fd1 + 1, &set, NULL, NULL, &selectwait)) <= 0)
- return ret;
-
- if (FD_ISSET(fd1, &set) && drain(fd1) > 0)
- return fd1 + 1;
-
- if (fd2 >= 0 && FD_ISSET(fd2, &set) && drain(fd2) > 0)
- return fd2 + 1;
-
return -1;
}
@@ -422,6 +404,7 @@ static void run(int i, char *f) {
int collect_debug = 0;
int fd_debuglog = -1;
int fd_kmsg;
+ fd_set set;
int ret;
//close(fds[1]);
@@ -439,11 +422,6 @@ static void run(int i, char *f) {
if ((fd_kmsg = open("/dev/kmsg", O_RDONLY | O_NONBLOCK)) < 0) {
if (errno != ENOENT) /* Older kernels (<3.5) do not support /dev/kmsg */
perror("open /dev/kmsg");
- } else if (read(fd_kmsg, NULL, 0) == -1) {
- /* There is /dev/kmsg, but unreadable -> ignore it (RHEL6?) */
- /* Expected error, stay quiet so log looks nice, perror("read /dev/kmsg"); */
- close(fd_kmsg);
- fd_kmsg = -1;
} else if (lseek(fd_kmsg, 0L, SEEK_END) == (off_t) -1)
perror("lseek /dev/kmsg");
@@ -452,6 +430,8 @@ static void run(int i, char *f) {
clear_dmesg();
while ((w = wait4(pid, &st, WNOHANG, &usage)) == 0) {
+ struct timeval selectwait = { .tv_usec = 500000 }; /* 0.5s */
+
if ((fullbuffer && fullbuffer++ == 8000) ||
(no_write > 180 * 2)) /* a 3 minute timeout */
{
@@ -475,7 +455,15 @@ static void run(int i, char *f) {
break;
}
- if ((ret = drain_fds(fds[0], fd_kmsg, 500000)) <= 0) {
+ if (clobber_dmesg)
+ drain_dmesg();
+
+ FD_ZERO(&set);
+ FD_SET(fds[0], &set);
+ if (fd_kmsg >= 0)
+ FD_SET(fd_kmsg, &set);
+
+ if ((ret = select(fd_kmsg > fds[0] ? fd_kmsg + 1 : fds[0] + 1, &set, NULL, NULL, &selectwait)) <= 0) {
/* Still checking debug log size if it's not growing too much */
if (!unlimited && testdirdebug[0] &&
(stat(testdirdebug, &statbuf) == 0) &&
@@ -484,13 +472,18 @@ static void run(int i, char *f) {
statbuf.st_size);
goto timeout;
}
-
no_write++;
continue;
- } else if (ret == (fds[0] + 1))
+ }
+
+ if (FD_ISSET(fds[0], &set) && drain(fds[0]) > 0)
no_write = 0;
- if (clobber_dmesg)
- drain_dmesg();
+ else if (fd_kmsg >= 0 && FD_ISSET(fd_kmsg, &set) && (drain(fd_kmsg) < 0)) {
+ close(fd_kmsg);
+ fd_kmsg = -1; /* Likely /dev/kmsg is not readable */
+ if ((clobber_dmesg = strcmp(getenv("LVM_TEST_CAN_CLOBBER_DMESG") ? : "0", "0")))
+ clear_dmesg();
+ }
}
if (w != pid) {
perror("waitpid");
10 years, 1 month
master - tests: hide error message
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9a99cb8c7947e1...
Commit: 9a99cb8c7947e19291794aa80d5bcdc73fa6245f
Parent: a01e2ff81c9e7f629d9011b7d69d9f2780a98484
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Mar 4 16:41:07 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 4 16:41:07 2014 +0100
tests: hide error message
Make the logging looks normal for this case
---
test/lib/harness.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/lib/harness.c b/test/lib/harness.c
index d02e9de..4e9c54f 100644
--- a/test/lib/harness.c
+++ b/test/lib/harness.c
@@ -441,7 +441,7 @@ static void run(int i, char *f) {
perror("open /dev/kmsg");
} else if (read(fd_kmsg, NULL, 0) == -1) {
/* There is /dev/kmsg, but unreadable -> ignore it (RHEL6?) */
- perror("read /dev/kmsg");
+ /* Expected error, stay quiet so log looks nice, perror("read /dev/kmsg"); */
close(fd_kmsg);
fd_kmsg = -1;
} else if (lseek(fd_kmsg, 0L, SEEK_END) == (off_t) -1)
10 years, 1 month