mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
config: make it possible to do a raw config tree merge
Till now, we needed the config tree merge only for merging tag configs with lvm.conf. However, this type of merging did a few extra exceptions: - leaving out the tags section - merging values in activation/volume_list - merging values in devices/filter - merging values in devices/types Any other config values were replaced by new values. However, we'd like to do a 'raw merge' as well, simply bypassing the exceptions listed above. This will help us to create a single tree representing the cascaded configs like CONFIG_STRING -> CONFIG_PROFILE -> ... The reason for this patch is that when trees are cascaded, the first value found while traversing the cascade is used, not making any exceptions like we do for tag configs.
This commit is contained in:
parent
661406a417
commit
f1e2890012
@ -659,7 +659,7 @@ static struct dm_config_tree *_merge_config_files(struct cmd_context *cmd, struc
|
|||||||
|
|
||||||
dm_list_iterate_items(cfl, &cmd->config_files) {
|
dm_list_iterate_items(cfl, &cmd->config_files) {
|
||||||
/* Merge all config trees into cmd->cft using merge/tag rules */
|
/* Merge all config trees into cmd->cft using merge/tag rules */
|
||||||
if (!merge_config_tree(cmd, cft, cfl->cft))
|
if (!merge_config_tree(cmd, cft, cfl->cft, CONFIG_MERGE_TYPE_TAGS))
|
||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -955,7 +955,8 @@ static void _insert_config_node(struct dm_config_node **cn1,
|
|||||||
* Merge section cn2 into section cn1 (which has the same name)
|
* Merge section cn2 into section cn1 (which has the same name)
|
||||||
* overwriting any existing cn1 nodes with matching names.
|
* overwriting any existing cn1 nodes with matching names.
|
||||||
*/
|
*/
|
||||||
static void _merge_section(struct dm_config_node *cn1, struct dm_config_node *cn2)
|
static void _merge_section(struct dm_config_node *cn1, struct dm_config_node *cn2,
|
||||||
|
config_merge_t merge_type)
|
||||||
{
|
{
|
||||||
struct dm_config_node *cn, *nextn, *oldn;
|
struct dm_config_node *cn, *nextn, *oldn;
|
||||||
struct dm_config_value *cv;
|
struct dm_config_value *cv;
|
||||||
@ -963,9 +964,11 @@ static void _merge_section(struct dm_config_node *cn1, struct dm_config_node *cn
|
|||||||
for (cn = cn2->child; cn; cn = nextn) {
|
for (cn = cn2->child; cn; cn = nextn) {
|
||||||
nextn = cn->sib;
|
nextn = cn->sib;
|
||||||
|
|
||||||
|
if (merge_type == CONFIG_MERGE_TYPE_TAGS) {
|
||||||
/* Skip "tags" */
|
/* Skip "tags" */
|
||||||
if (!strcmp(cn->key, "tags"))
|
if (!strcmp(cn->key, "tags"))
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Subsection? */
|
/* Subsection? */
|
||||||
if (!cn->v)
|
if (!cn->v)
|
||||||
@ -976,6 +979,7 @@ static void _merge_section(struct dm_config_node *cn1, struct dm_config_node *cn
|
|||||||
_insert_config_node(&cn1->child, cn);
|
_insert_config_node(&cn1->child, cn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (merge_type == CONFIG_MERGE_TYPE_TAGS) {
|
||||||
/* Merge certain value lists */
|
/* Merge certain value lists */
|
||||||
if ((!strcmp(cn1->key, "activation") &&
|
if ((!strcmp(cn1->key, "activation") &&
|
||||||
!strcmp(cn->key, "volume_list")) ||
|
!strcmp(cn->key, "volume_list")) ||
|
||||||
@ -986,6 +990,7 @@ static void _merge_section(struct dm_config_node *cn1, struct dm_config_node *cn
|
|||||||
cv = cv->next;
|
cv = cv->next;
|
||||||
cv->next = oldn->v;
|
cv->next = oldn->v;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Replace values */
|
/* Replace values */
|
||||||
oldn->v = cn->v;
|
oldn->v = cn->v;
|
||||||
@ -1014,7 +1019,7 @@ static int _match_host_tags(struct dm_list *tags, const struct dm_config_node *t
|
|||||||
|
|
||||||
/* Destructively merge a new config tree into an existing one */
|
/* Destructively merge a new config tree into an existing one */
|
||||||
int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
|
int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
|
||||||
struct dm_config_tree *newdata)
|
struct dm_config_tree *newdata, config_merge_t merge_type)
|
||||||
{
|
{
|
||||||
struct dm_config_node *root = cft->root;
|
struct dm_config_node *root = cft->root;
|
||||||
struct dm_config_node *cn, *nextn, *oldn, *cn2;
|
struct dm_config_node *cn, *nextn, *oldn, *cn2;
|
||||||
@ -1023,6 +1028,7 @@ int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
|
|||||||
|
|
||||||
for (cn = newdata->root; cn; cn = nextn) {
|
for (cn = newdata->root; cn; cn = nextn) {
|
||||||
nextn = cn->sib;
|
nextn = cn->sib;
|
||||||
|
if (merge_type == CONFIG_MERGE_TYPE_TAGS) {
|
||||||
/* Ignore tags section */
|
/* Ignore tags section */
|
||||||
if (!strcmp(cn->key, "tags"))
|
if (!strcmp(cn->key, "tags"))
|
||||||
continue;
|
continue;
|
||||||
@ -1031,8 +1037,10 @@ int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
|
|||||||
if (!_match_host_tags(&cmd->tags, tn))
|
if (!_match_host_tags(&cmd->tags, tn))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!(oldn = dm_config_find_node(root, cn->key))) {
|
if (!(oldn = dm_config_find_node(root, cn->key))) {
|
||||||
_insert_config_node(&cft->root, cn);
|
_insert_config_node(&cft->root, cn);
|
||||||
|
if (merge_type == CONFIG_MERGE_TYPE_TAGS) {
|
||||||
/* Remove any "tags" nodes */
|
/* Remove any "tags" nodes */
|
||||||
for (cn2 = cn->child; cn2; cn2 = cn2->sib) {
|
for (cn2 = cn->child; cn2; cn2 = cn2->sib) {
|
||||||
if (!strcmp(cn2->key, "tags")) {
|
if (!strcmp(cn2->key, "tags")) {
|
||||||
@ -1044,9 +1052,10 @@ int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_merge_section(oldn, cn);
|
_merge_section(oldn, cn, merge_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -173,8 +173,19 @@ int config_file_changed(struct dm_config_tree *cft);
|
|||||||
int config_file_check(struct dm_config_tree *cft, const char **filename, struct stat *info);
|
int config_file_check(struct dm_config_tree *cft, const char **filename, struct stat *info);
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CONFIG_MERGE_TYPE_RAW, /* always replace old config values with new config values when merging */
|
||||||
|
CONFIG_MERGE_TYPE_TAGS /* apply some exceptions when merging tag configs:
|
||||||
|
- skip tags section
|
||||||
|
- do not replace, but merge values of these settings:
|
||||||
|
activation/volume_list
|
||||||
|
devices/filter
|
||||||
|
devices/types
|
||||||
|
*/
|
||||||
|
} config_merge_t;
|
||||||
|
|
||||||
int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
|
int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
|
||||||
struct dm_config_tree *newdata);
|
struct dm_config_tree *newdata, config_merge_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These versions check an override tree, if present, first.
|
* These versions check an override tree, if present, first.
|
||||||
|
Loading…
Reference in New Issue
Block a user