/* Destructively merge a new config tree into an existing one */ int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft, struct dm_config_tree *newdata, config_merge_t merge_type) { struct dm_config_node *root = cft->root; struct dm_config_node *cn, *nextn, *oldn, *cn2; const struct dm_config_node *tn; struct config_source *cs, *csn; for (cn = newdata->root; cn; cn = nextn) { nextn = cn->sib; if (merge_type == CONFIG_MERGE_TYPE_TAGS) { /* Ignore tags section */ if (!strcmp(cn->key, "tags")) continue; /* If there's a tags node, skip if host tags don't match */ if ((tn = dm_config_find_node(cn->child, "tags"))) { if (!_match_host_tags(&cmd->tags, tn)) continue; } } if (!(oldn = dm_config_find_node(root, cn->key))) { _insert_config_node(&cft->root, cn); if (merge_type == CONFIG_MERGE_TYPE_TAGS) { /* Remove any "tags" nodes */ for (cn2 = cn->child; cn2; cn2 = cn2->sib) { if (!strcmp(cn2->key, "tags")) { cn->child = cn2->sib; continue; } if (cn2->sib && !strcmp(cn2->sib->key, "tags")) { cn2->sib = cn2->sib->sib; continue; } } } continue; } _merge_section(oldn, cn, merge_type); } /* * Persistent filter loading is based on timestamp, * so we need to know the newest timestamp to make right decision * whether the .cache isn't older then any of configs */ cs = dm_config_get_custom(cft); csn = dm_config_get_custom(newdata); if (cs && csn && (cs->timestamp < csn->timestamp)) cs->timestamp = csn->timestamp; return 1; }
/* Destructively merge a new config tree into an existing one */ int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft, struct config_tree *newdata) { const struct config_node *root = cft->root; struct config_node *cn, *nextn, *oldn, *cn2; const struct config_node *tn; for (cn = newdata->root; cn; cn = nextn) { nextn = cn->sib; /* Ignore tags section */ if (!strcmp(cn->key, "tags")) continue; /* If there's a tags node, skip if host tags don't match */ if ((tn = find_config_node(cn->child, "tags"))) { if (!_match_host_tags(&cmd->tags, tn)) continue; } if (!(oldn = (struct config_node *)find_config_node(root, cn->key))) { _insert_config_node(&cft->root, cn); /* Remove any "tags" nodes */ for (cn2 = cn->child; cn2; cn2 = cn2->sib) { if (!strcmp(cn2->key, "tags")) { cn->child = cn2->sib; continue; } if (cn2->sib && !strcmp(cn2->sib->key, "tags")) { cn2->sib = cn2->sib->sib; continue; } } continue; } _merge_section(oldn, cn); } return 1; }