[lvm-devel] master - libdm-config: Implement dm_config_flatten.

Petr Rockai mornfall at fedoraproject.org
Thu Nov 20 15:53:00 UTC 2014


Gitweb:        http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=274a7a68b80fdce9e9398ffbe45e788b13b04642
Commit:        274a7a68b80fdce9e9398ffbe45e788b13b04642
Parent:        956c19284195f3200a1370166bd8847e5d159588
Author:        Petr Rockai <prockai at redhat.com>
AuthorDate:    Wed Nov 19 18:37:31 2014 +0100
Committer:     Petr Rockai <prockai at redhat.com>
CommitterDate: Thu Nov 20 16:51:06 2014 +0100

libdm-config: Implement dm_config_flatten.

---
 libdm/libdevmapper.h |    5 ++++
 libdm/libdm-config.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 6e237c0..3400c28 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1848,6 +1848,11 @@ struct dm_config_tree *dm_config_insert_cascaded_tree(struct dm_config_tree *fir
  */
 struct dm_config_tree *dm_config_remove_cascaded_tree(struct dm_config_tree *cft);
 
+/*
+ * Create a new, uncascaded config tree equivalent to the input cascade.
+ */
+struct dm_config_tree *dm_config_flatten(struct dm_config_tree *cft);
+
 void dm_config_destroy(struct dm_config_tree *cft);
 
 /* Simple output line by line. */
diff --git a/libdm/libdm-config.c b/libdm/libdm-config.c
index c026385..e6b2b90 100644
--- a/libdm/libdm-config.c
+++ b/libdm/libdm-config.c
@@ -1315,3 +1315,56 @@ struct dm_pool *dm_config_memory(struct dm_config_tree *cft)
 {
 	return cft->mem;
 }
+
+static int _override_path(const char *path, struct dm_config_node *node, void *baton)
+{
+	struct dm_config_tree *cft = baton;
+	struct dm_config_node dummy, *target;
+	dummy.child = cft->root;
+	if (!(target = _find_or_make_node(cft->mem, &dummy, path)))
+		return_0;
+	if (!(target->v = _clone_config_value(cft->mem, node->v)))
+		return_0;
+	cft->root = dummy.child;
+	return 1;
+}
+
+static int _enumerate(const char *path, struct dm_config_node *cn, int (*cb)(const char *, struct dm_config_node *, void *), void *baton)
+{
+	char *sub = NULL;
+
+	while (cn) {
+		if (dm_asprintf(&sub, "%s/%s", path, cn->key) < 0)
+			return_0;
+		if (cn->child) {
+			if (!_enumerate(sub, cn->child, cb, baton))
+				goto_bad;
+		} else
+			if (!cb(sub, cn, baton))
+				goto_bad;
+		dm_free(sub);
+		cn = cn->sib;
+	}
+	return 1;
+bad:
+	dm_free(sub);
+	return 0;
+}
+
+struct dm_config_tree *dm_config_flatten(struct dm_config_tree *cft)
+{
+	struct dm_config_tree *res = dm_config_create(), *done = NULL, *current = NULL;
+
+	if (!res)
+		return_NULL;
+
+	while (done != cft) {
+		current = cft;
+		while (current->cascade != done)
+			current = current->cascade;
+		_enumerate("", current->root, _override_path, res);
+		done = current;
+	}
+
+	return res;
+}




More information about the lvm-devel mailing list