1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-02-09 13:57:55 +03:00

config: fix incorrect profile initialization on cmd context refresh

When cmd refresh is called, we need to move any already loaded profiles
to profiles_to_load list which will cause their reload on subsequent
use. In addition to that, we need to take into account any change
in config/profile configuration setting on cmd context refresh
since this setting could be overriden with --config.

Also, when running commands in the shell, we need to remove the
global profile used from the configuration cascade so the profile
is not incorrectly reused next time when the --profile option is
not specified anymore for the next command in the shell.

This bug only affected profile specified by --profile cmd line
arg, not profiles referenced from LVM metadata.
This commit is contained in:
Peter Rajnoha 2014-05-19 13:59:23 +02:00
parent c42f72867a
commit 9a324df3b3
4 changed files with 52 additions and 19 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.107 -
==================================
Fix wrong profile reuse from previous run if another cmd is run in lvm shell.
Move cache description from lvm(8) to lvmcache(7) man page.
Display skipped prompt in silent mode.
Make reporting commands show help about possible sort keys on '-O help'.

View File

@ -630,8 +630,9 @@ static int _init_profiles(struct cmd_context *cmd)
{
const char *dir;
struct profile_params *pp;
int initialized = cmd->profile_params != NULL;
if (!(pp = dm_pool_zalloc(cmd->libmem, sizeof(*pp)))) {
if (!initialized && !(pp = dm_pool_zalloc(cmd->libmem, sizeof(*pp)))) {
log_error("profile_params alloc failed");
return 0;
}
@ -639,11 +640,15 @@ static int _init_profiles(struct cmd_context *cmd)
if (!(dir = find_config_tree_str(cmd, config_profile_dir_CFG, NULL)))
return_0;
pp->dir = dm_pool_strdup(cmd->libmem, dir);
dm_list_init(&pp->profiles_to_load);
dm_list_init(&pp->profiles);
if (initialized) {
dm_strncpy(cmd->profile_params->dir, dir, sizeof(pp->dir));
} else {
dm_strncpy(pp->dir, dir, sizeof(pp->dir));
dm_list_init(&pp->profiles_to_load);
dm_list_init(&pp->profiles);
cmd->profile_params = pp;
}
cmd->profile_params = pp;
return 1;
}
@ -693,7 +698,7 @@ static void _destroy_config(struct cmd_context *cmd)
{
struct config_tree_list *cfl;
struct dm_config_tree *cft;
struct profile *profile;
struct profile *profile, *tmp_profile;
/*
* Configuration cascade:
@ -713,12 +718,17 @@ static void _destroy_config(struct cmd_context *cmd)
/* CONFIG_PROFILE */
if (cmd->profile_params) {
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
dm_list_iterate_items(profile, &cmd->profile_params->profiles_to_load)
/*
* Destroy config trees for any loaded profiles and
* move these profiles to profile_to_load list.
* Whenever these profiles are referenced later,
* they will get loaded again automatically.
*/
dm_list_iterate_items_safe(profile, tmp_profile, &cmd->profile_params->profiles) {
config_destroy(profile->cft);
dm_list_iterate_items(profile, &cmd->profile_params->profiles)
config_destroy(profile->cft);
dm_list_init(&cmd->profile_params->profiles_to_load);
dm_list_init(&cmd->profile_params->profiles);
profile->cft = NULL;
dm_list_move(&cmd->profile_params->profiles_to_load, &profile->list);
}
}
/* CONFIG_STRING */
@ -1595,6 +1605,8 @@ int refresh_filters(struct cmd_context *cmd)
int refresh_toolcontext(struct cmd_context *cmd)
{
struct dm_config_tree *cft_cmdline, *cft_tmp;
const char *profile_name;
struct profile *profile;
log_verbose("Reloading config files");
@ -1617,7 +1629,13 @@ int refresh_toolcontext(struct cmd_context *cmd)
_destroy_dev_types(cmd);
_destroy_tags(cmd);
/* save config string passed on the command line */
cft_cmdline = remove_config_tree_by_source(cmd, CONFIG_STRING);
/* save the global profile name used */
profile_name = cmd->profile_params->global_profile ?
cmd->profile_params->global_profile->name : NULL;
_destroy_config(cmd);
cmd->config_initialized = 0;
@ -1634,6 +1652,13 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (cft_cmdline)
cmd->cft = dm_config_insert_cascaded_tree(cft_cmdline, cft_tmp);
/* Reload the global profile. */
if (profile_name) {
if (!(profile = add_profile(cmd, profile_name)) ||
!override_config_tree_from_profile(cmd, profile))
return_0;
}
/* Uses cmd->cft i.e. cft_cmdline + lvm.conf */
_init_logging(cmd);
@ -1657,6 +1682,9 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (!_process_config(cmd))
return_0;
if (!_init_profiles(cmd))
return_0;
if (!(cmd->dev_types = create_dev_types(cmd->proc_dir,
find_config_tree_node(cmd, devices_types_CFG, NULL))))
return_0;

View File

@ -41,7 +41,7 @@ struct profile {
};
struct profile_params {
const char *dir; /* subdir in LVM_SYSTEM_DIR where LVM looks for profiles */
char dir[PATH_MAX]; /* subdir in LVM_SYSTEM_DIR where LVM looks for profiles */
struct profile *global_profile; /* profile that overrides any other VG/LV-based profile ('--profile' cmd line arg) */
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 */

View File

@ -1081,11 +1081,11 @@ static const char *_copy_command_line(struct cmd_context *cmd, int argc, char **
int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
{
struct dm_config_tree *config_string_cft, *config_profile_cft;
struct profile *profile;
int ret = 0;
int locking_type;
int monitoring;
struct dm_config_tree *old_cft;
struct profile *profile;
init_error_message_produced(0);
@ -1124,9 +1124,8 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
if (arg_count(cmd, config_ARG) || !cmd->config_initialized || config_files_changed(cmd)) {
/* Reinitialise various settings inc. logging, filters */
if (!refresh_toolcontext(cmd)) {
old_cft = remove_config_tree_by_source(cmd, CONFIG_STRING);
if (old_cft)
dm_config_destroy(old_cft);
if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
dm_config_destroy(config_string_cft);
log_error("Updated config file invalid. Aborting.");
return ECMD_FAILED;
}
@ -1204,8 +1203,13 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
lvmcache_destroy(cmd, 1, 0);
}
if ((old_cft = remove_config_tree_by_source(cmd, CONFIG_STRING))) {
dm_config_destroy(old_cft);
if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
dm_config_destroy(config_string_cft);
config_profile_cft = remove_config_tree_by_source(cmd, CONFIG_PROFILE);
cmd->profile_params->global_profile = NULL;
if (config_string_cft || config_profile_cft) {
/* Move this? */
if (!refresh_toolcontext(cmd))
stack;