Most of the time we want gvir_config_object_attach to replace existing nodes, but sometimes (for <devices> subnodes) we want it to append the new node and to keep the existing nodes with the same name. This commit solves this by adding 2 distinct helpers, _attach_add and _attach_replace. This should fix some unexpected behaviour of various _set_ functions which were appending new nodes instead of replacing the existing one. --- libvirt-gconfig/libvirt-gconfig-domain.c | 20 +++++++++++--------- libvirt-gconfig/libvirt-gconfig-object-private.h | 6 ++++-- libvirt-gconfig/libvirt-gconfig-object.c | 20 ++++++++++++++++++-- .../libvirt-gconfig-storage-pool-target.c | 4 ++-- libvirt-gconfig/libvirt-gconfig-storage-pool.c | 8 ++++---- .../libvirt-gconfig-storage-vol-target.c | 4 ++-- libvirt-gconfig/libvirt-gconfig-storage-vol.c | 8 ++++---- libvirt-gconfig/libvirt-gconfig.sym | 1 - 8 files changed, 45 insertions(+), 26 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c index fba1ee2..cf5aa17 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain.c +++ b/libvirt-gconfig/libvirt-gconfig-domain.c @@ -290,8 +290,8 @@ void gvir_config_domain_set_clock(GVirConfigDomain *domain, g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain)); g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_CLOCK(klock)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(domain), - GVIR_CONFIG_OBJECT(klock)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain), + GVIR_CONFIG_OBJECT(klock)); } void gvir_config_domain_set_os(GVirConfigDomain *domain, @@ -300,8 +300,8 @@ void gvir_config_domain_set_os(GVirConfigDomain *domain, g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain)); g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_OS(os)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(domain), - GVIR_CONFIG_OBJECT(os)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain), + GVIR_CONFIG_OBJECT(os)); } void gvir_config_domain_set_seclabel(GVirConfigDomain *domain, @@ -310,8 +310,8 @@ void gvir_config_domain_set_seclabel(GVirConfigDomain *domain, g_return_if_fail(GVIR_CONFIG_IS_DOMAIN(domain)); g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_SECLABEL(seclabel)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(domain), - GVIR_CONFIG_OBJECT(seclabel)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain), + GVIR_CONFIG_OBJECT(seclabel)); } void gvir_config_domain_set_lifecycle(GVirConfigDomain *domain, @@ -354,10 +354,12 @@ void gvir_config_domain_set_devices(GVirConfigDomain *domain, g_warn_if_reached(); continue; } - gvir_config_object_attach(devices_node, GVIR_CONFIG_OBJECT(it->data)); + gvir_config_object_attach_add(devices_node, + GVIR_CONFIG_OBJECT(it->data)); } - gvir_config_object_attach(GVIR_CONFIG_OBJECT(domain), devices_node); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(domain), + devices_node); g_object_unref(G_OBJECT(devices_node)); } @@ -372,7 +374,7 @@ void gvir_config_domain_add_device(GVirConfigDomain *domain, devices_node = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain), "devices"); - gvir_config_object_attach(devices_node, GVIR_CONFIG_OBJECT(device)); + gvir_config_object_attach_add(devices_node, GVIR_CONFIG_OBJECT(device)); g_object_unref(G_OBJECT(devices_node)); } diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h index 922b0f3..781e1a3 100644 --- a/libvirt-gconfig/libvirt-gconfig-object-private.h +++ b/libvirt-gconfig/libvirt-gconfig-object-private.h @@ -76,8 +76,10 @@ void gvir_config_object_delete_children(GVirConfigObject *object, const char *ch void gvir_config_object_set_child(GVirConfigObject *object, xmlNodePtr child); -void gvir_config_object_attach(GVirConfigObject *parent, - GVirConfigObject *child); +void gvir_config_object_attach_add(GVirConfigObject *parent, + GVirConfigObject *child); +void gvir_config_object_attach_replace(GVirConfigObject *parent, + GVirConfigObject *child); void gvir_config_object_set_attribute(GVirConfigObject *object, ...) G_GNUC_NULL_TERMINATED; void gvir_config_object_set_attribute_with_type(GVirConfigObject *object, diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c index dbb63a5..2e28208 100644 --- a/libvirt-gconfig/libvirt-gconfig-object.c +++ b/libvirt-gconfig/libvirt-gconfig-object.c @@ -803,12 +803,16 @@ gvir_config_object_set_attribute_with_type(GVirConfigObject *object, ...) va_end(args); } -G_GNUC_INTERNAL void -gvir_config_object_attach(GVirConfigObject *parent, GVirConfigObject *child) +static void +gvir_config_object_attach(GVirConfigObject *parent, GVirConfigObject *child, gboolean replace) { g_return_if_fail(GVIR_CONFIG_IS_OBJECT(parent)); g_return_if_fail(GVIR_CONFIG_IS_OBJECT(child)); + if (replace) { + gvir_config_object_delete_children(parent, + (char *)child->priv->node->name); + } xmlUnlinkNode(child->priv->node); xmlAddChild(parent->priv->node, child->priv->node); if (child->priv->doc != NULL) { @@ -821,6 +825,18 @@ gvir_config_object_attach(GVirConfigObject *parent, GVirConfigObject *child) } G_GNUC_INTERNAL void +gvir_config_object_attach_replace(GVirConfigObject *parent, GVirConfigObject *child) +{ + gvir_config_object_attach(parent, child, TRUE); +} + +G_GNUC_INTERNAL void +gvir_config_object_attach_add(GVirConfigObject *parent, GVirConfigObject *child) +{ + gvir_config_object_attach(parent, child, FALSE); +} + +G_GNUC_INTERNAL void gvir_config_object_remove_attribute(GVirConfigObject *object, const char *attr_name) { diff --git a/libvirt-gconfig/libvirt-gconfig-storage-pool-target.c b/libvirt-gconfig/libvirt-gconfig-storage-pool-target.c index 56a8c98..0d7f164 100644 --- a/libvirt-gconfig/libvirt-gconfig-storage-pool-target.c +++ b/libvirt-gconfig/libvirt-gconfig-storage-pool-target.c @@ -86,6 +86,6 @@ void gvir_config_storage_pool_target_set_permissions(GVirConfigStoragePoolTarget g_return_if_fail(GVIR_CONFIG_IS_STORAGE_POOL_TARGET(target)); g_return_if_fail(GVIR_CONFIG_IS_STORAGE_PERMISSIONS(perms)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(target), - GVIR_CONFIG_OBJECT(perms)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(target), + GVIR_CONFIG_OBJECT(perms)); } diff --git a/libvirt-gconfig/libvirt-gconfig-storage-pool.c b/libvirt-gconfig/libvirt-gconfig-storage-pool.c index 3955251..c524c17 100644 --- a/libvirt-gconfig/libvirt-gconfig-storage-pool.c +++ b/libvirt-gconfig/libvirt-gconfig-storage-pool.c @@ -137,8 +137,8 @@ void gvir_config_storage_pool_set_source(GVirConfigStoragePool *pool, g_return_if_fail(GVIR_CONFIG_IS_STORAGE_POOL(pool)); g_return_if_fail(GVIR_CONFIG_IS_STORAGE_POOL_SOURCE(source)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(pool), - GVIR_CONFIG_OBJECT(source)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(pool), + GVIR_CONFIG_OBJECT(source)); } void gvir_config_storage_pool_set_target(GVirConfigStoragePool *pool, @@ -147,6 +147,6 @@ void gvir_config_storage_pool_set_target(GVirConfigStoragePool *pool, g_return_if_fail(GVIR_CONFIG_IS_STORAGE_POOL(pool)); g_return_if_fail(GVIR_CONFIG_IS_STORAGE_POOL_TARGET(target)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(pool), - GVIR_CONFIG_OBJECT(target)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(pool), + GVIR_CONFIG_OBJECT(target)); } diff --git a/libvirt-gconfig/libvirt-gconfig-storage-vol-target.c b/libvirt-gconfig/libvirt-gconfig-storage-vol-target.c index d7dfca7..3786e2b 100644 --- a/libvirt-gconfig/libvirt-gconfig-storage-vol-target.c +++ b/libvirt-gconfig/libvirt-gconfig-storage-vol-target.c @@ -90,6 +90,6 @@ void gvir_config_storage_vol_target_set_permissions(GVirConfigStorageVolTarget * g_return_if_fail(GVIR_CONFIG_IS_STORAGE_VOL_TARGET(target)); g_return_if_fail(GVIR_CONFIG_IS_STORAGE_PERMISSIONS(perms)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(target), - GVIR_CONFIG_OBJECT(perms)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(target), + GVIR_CONFIG_OBJECT(perms)); } diff --git a/libvirt-gconfig/libvirt-gconfig-storage-vol.c b/libvirt-gconfig/libvirt-gconfig-storage-vol.c index 777efef..6281c02 100644 --- a/libvirt-gconfig/libvirt-gconfig-storage-vol.c +++ b/libvirt-gconfig/libvirt-gconfig-storage-vol.c @@ -107,8 +107,8 @@ void gvir_config_storage_vol_set_target(GVirConfigStorageVol *vol, g_return_if_fail(GVIR_CONFIG_IS_STORAGE_VOL(vol)); g_return_if_fail(GVIR_CONFIG_IS_STORAGE_VOL_TARGET(target)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(vol), - GVIR_CONFIG_OBJECT(target)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(vol), + GVIR_CONFIG_OBJECT(target)); } void gvir_config_storage_vol_set_backing_store(GVirConfigStorageVol *vol, @@ -117,6 +117,6 @@ void gvir_config_storage_vol_set_backing_store(GVirConfigStorageVol *vol, g_return_if_fail(GVIR_CONFIG_IS_STORAGE_VOL(vol)); g_return_if_fail(GVIR_CONFIG_IS_STORAGE_VOL_BACKING_STORE(backing_store)); - gvir_config_object_attach(GVIR_CONFIG_OBJECT(vol), - GVIR_CONFIG_OBJECT(backing_store)); + gvir_config_object_attach_replace(GVIR_CONFIG_OBJECT(vol), + GVIR_CONFIG_OBJECT(backing_store)); } diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym index 9bfe1d9..0fcbd13 100644 --- a/libvirt-gconfig/libvirt-gconfig.sym +++ b/libvirt-gconfig/libvirt-gconfig.sym @@ -239,7 +239,6 @@ LIBVIRT_GCONFIG_0.0.4 { gvir_config_object_get_schema; gvir_config_object_to_xml; gvir_config_object_validate; - gvir_config_object_attach; gvir_config_object_set_attribute; gvir_config_object_set_attribute_with_type; -- 1.7.7.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list