summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2016-08-08 10:43:18 +0200
committerPeter Rajnoha <prajnoha@redhat.com>2016-08-09 18:49:11 +0200
commite8985c71bc7c6e8316adf97f2397ac32ab67191b (patch)
treeb4495e03952dd2e5e2d8b9051d9a25005f85b0bb
parent54bf15555be1808eb292cfc3edeece236a1c9744 (diff)
downloadlvm2-e8985c71bc7c6e8316adf97f2397ac32ab67191b.tar.gz
config: add support for CFG_DISALLOW_INTERACTIVE flag to mark settings as not suitable for override in interactive mode
Some settings are not suitable for override in interactive/shell mode because such settings may confuse the code and it may end up with unexpected behaviour. This is because of the fact that once we're in the interactive/shell mode, we have already applied some settings for the shell itself and we can't override them further because we're already using those settings to drive the interactive/shell mode. Such settings would get ignored silently or, in worse case, they would mess up the existing configuration.
-rw-r--r--lib/commands/toolcontext.c3
-rw-r--r--lib/config/config.c31
-rw-r--r--lib/config/config.h33
-rw-r--r--lib/config/config_settings.h1
-rw-r--r--tools/lvmcmdline.c3
5 files changed, 57 insertions, 14 deletions
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index a7f76ba91..eaabf984f 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -950,6 +950,9 @@ static void _destroy_config(struct cmd_context *cmd)
* they will get loaded again automatically.
*/
dm_list_iterate_items_safe(profile, tmp_profile, &cmd->profile_params->profiles) {
+ if (cmd->is_interactive && (profile == cmd->profile_params->shell_profile))
+ continue;
+
config_destroy(profile->cft);
profile->cft = NULL;
dm_list_move(&cmd->profile_params->profiles_to_load, &profile->list);
diff --git a/lib/config/config.c b/lib/config/config.c
index a569444dd..46ef8e7eb 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -385,6 +385,13 @@ int override_config_tree_from_string(struct cmd_context *cmd,
return 0;
}
+ if (cmd->is_interactive &&
+ !config_force_check(cmd, CONFIG_STRING, cft_new)) {
+ log_error("Ignoring invalid configuration string.");
+ dm_config_destroy(cft_new);
+ return_0;
+ }
+
if (!(cs = dm_pool_zalloc(cft_new->mem, sizeof(struct config_source)))) {
log_error("Failed to allocate config source.");
dm_config_destroy(cft_new);
@@ -984,6 +991,20 @@ static int _config_def_check_node_is_profilable(struct cft_check_handle *handle,
return 1;
}
+static int _config_def_check_node_is_allowed(struct cft_check_handle *handle,
+ const char *rp, struct dm_config_node *cn,
+ const cfg_def_item_t *def)
+{
+ if (handle->disallowed_flags & def->flags) {
+ log_warn_suppress(handle->suppress_messages,
+ "Configuration %s \"%s\" is not allowed here.",
+ cn->v ? "option" : "section", rp);
+ return 0;
+ }
+
+ return 1;
+}
+
static int _config_def_check_node(struct cft_check_handle *handle,
const char *vp, char *pvp, char *rp, char *prp,
size_t buf_size, struct dm_config_node *cn)
@@ -1034,6 +1055,9 @@ static int _config_def_check_node(struct cft_check_handle *handle,
!_config_def_check_node_is_profilable(handle, rp, cn, def))
return_0;
+ if (!_config_def_check_node_is_allowed(handle, rp, cn, def))
+ return_0;
+
handle->status[def->id] |= CFG_VALID;
return 1;
}
@@ -2130,6 +2154,13 @@ int config_force_check(struct cmd_context *cmd, config_source_t source, struct d
/* provide warning messages only if config/checks=1 */
handle->suppress_messages = !find_config_tree_bool(cmd, config_checks_CFG, NULL);
+ /*
+ * Some settings can't be changed if we're running commands interactively
+ * within lvm shell so check for them in case we're in this interactive mode.
+ */
+ if (cmd->is_interactive)
+ handle->disallowed_flags |= CFG_DISALLOW_INTERACTIVE;
+
r = config_def_check(handle);
dm_pool_free(cmd->libmem, handle);
diff --git a/lib/config/config.h b/lib/config/config.h
index 659b8b00b..aa95202d5 100644
--- a/lib/config/config.h
+++ b/lib/config/config.h
@@ -48,6 +48,7 @@ struct profile_params {
struct profile *global_metadata_profile; /* profile (as given by --metadataprofile cmd arg) that overrides any other VG/LV-based profile */
struct dm_list profiles_to_load; /* list of profiles which are only added, but still need to be loaded for any use */
struct dm_list profiles; /* list of profiles which are loaded already and which are ready for use */
+ struct profile *shell_profile; /* master profile used in interactive/shell mode */
};
#define CFG_PATH_MAX_LEN 128
@@ -98,31 +99,34 @@ typedef union {
/* whether the configuration item name is variable */
-#define CFG_NAME_VARIABLE 0x001
+#define CFG_NAME_VARIABLE 0x0001
/* whether empty value is allowed */
-#define CFG_ALLOW_EMPTY 0x002
+#define CFG_ALLOW_EMPTY 0x0002
/* whether the configuration item is for advanced use only */
-#define CFG_ADVANCED 0x004
+#define CFG_ADVANCED 0x0004
/* whether the configuration item is not officially supported */
-#define CFG_UNSUPPORTED 0x008
+#define CFG_UNSUPPORTED 0x0008
/* whether the configuration item is customizable by a profile */
-#define CFG_PROFILABLE 0x010
-/* whether the configuration item is customizable by a profile */
-/* and whether it can be attached to VG/LV metadata at the same time
+#define CFG_PROFILABLE 0x0010
+/* whether the configuration item is customizable by a profile
+ * and whether it can be attached to VG/LV metadata at the same time
* The CFG_PROFILABLE_METADATA flag incorporates CFG_PROFILABLE flag!!! */
-#define CFG_PROFILABLE_METADATA 0x030
+#define CFG_PROFILABLE_METADATA 0x0030
/* whether the default value is undefned */
-#define CFG_DEFAULT_UNDEFINED 0x040
+#define CFG_DEFAULT_UNDEFINED 0x0040
/* whether the default value is commented out on output */
-#define CFG_DEFAULT_COMMENTED 0x080
+#define CFG_DEFAULT_COMMENTED 0x0080
/* whether the default value is calculated during run time */
-#define CFG_DEFAULT_RUN_TIME 0x100
+#define CFG_DEFAULT_RUN_TIME 0x0100
/* whether the configuration setting is disabled (and hence defaults always used) */
-#define CFG_DISABLED 0x200
+#define CFG_DISABLED 0x0200
/* whether to print integers in octal form (prefixed by "0") */
-#define CFG_FORMAT_INT_OCTAL 0x400
+#define CFG_FORMAT_INT_OCTAL 0x0400
/* whether to disable checks for the whole config section subtree */
-#define CFG_SECTION_NO_CHECK 0x800
+#define CFG_SECTION_NO_CHECK 0x0800
+/* whether to disallow a possibility to override configuration
+ * setting for commands run interactively (e.g. in lvm shell) */
+#define CFG_DISALLOW_INTERACTIVE 0x1000
/* configuration definition item structure */
typedef struct cfg_def_item {
@@ -212,6 +216,7 @@ struct cft_check_handle {
unsigned check_diff:1; /* check if the value used differs from default one */
unsigned ignoreadvanced:1; /* do not include advnced configs */
unsigned ignoreunsupported:1; /* do not include unsupported configs */
+ uint16_t disallowed_flags; /* set of disallowed flags */
uint8_t status[CFG_COUNT]; /* flags for each configuration item - the result of the check */
};
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 9c46667cb..7d2cdd582 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -52,6 +52,7 @@
* CFG_DISABLED - configuration is disabled (defaults always used)
* CFG_FORMAT_INT_OCTAL - print integer number in octal form (also prefixed by "0")
* CFG_SECTION_NO_CHECK - do not check content of the section at all - use with care!!!
+ * CFG_DISALLOW_INTERACTIVE - disallow configuration node for use in interactive environment (e.g. cmds run in lvm shell)
*
* type: Allowed type for the value of simple configuation setting, one of:
* CFG_TYPE_BOOL
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index cb41534ba..af3879910 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1430,6 +1430,9 @@ static int _prepare_profiles(struct cmd_context *cmd)
log_debug(_setting_global_profile_msg, _command_profile_source_name, profile->name);
cmd->profile_params->global_command_profile = profile;
+
+ if (!cmd->arg_values)
+ cmd->profile_params->shell_profile = profile;
}