conf: Remove duplicate entries in <metadata> by namespace

Since the APIs support just one element per namespace and while
modifying an element all duplicates would be removed, let's do this
right away in the post parse callback.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1190590
This commit is contained in:
Peter Krempa 2015-03-03 17:50:59 +01:00
parent 5aee81a0cb
commit 7909300498
4 changed files with 108 additions and 0 deletions

View File

@ -3148,6 +3148,45 @@ virDomainDefRejectDuplicateControllers(virDomainDefPtr def)
}
/**
* virDomainDefRemoveDuplicateMetadata:
* @def: Remove duplicate metadata for this def
*
* This function removes metadata elements in @def that share the namespace.
* The first metadata entry of every duplicate namespace is kept.
*/
static void
virDomainDefRemoveDuplicateMetadata(virDomainDefPtr def)
{
xmlNodePtr child;
xmlNodePtr next;
if (!def || !def->metadata)
return;
for (child = def->metadata->children; child; child = child->next) {
/* check that every other child of @root doesn't share the namespace of
* the current one and delete them possibly */
next = child->next;
while (next) {
xmlNodePtr dupl = NULL;
if (child->ns && next->ns &&
STREQ_NULLABLE((const char *) child->ns->href,
(const char *) next->ns->href))
dupl = next;
next = next->next;
if (dupl) {
xmlUnlinkNode(dupl);
xmlFreeNode(dupl);
}
}
}
}
static int
virDomainDefPostParseInternal(virDomainDefPtr def,
virCapsPtr caps ATTRIBUTE_UNUSED)
@ -3316,6 +3355,9 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
}
}
/* clean up possibly duplicated metadata entries */
virDomainDefRemoveDuplicateMetadata(def);
return 0;
}

View File

@ -0,0 +1,34 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<memballoon model='virtio'/>
</devices>
<!-- intentional mis-indentation -->
<metadata>
<app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
<app3:foo xmlns:app3="http://foo.org/">fooish</app3:foo>
<app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
<app2:bar xmlns:app2="http://bar.com/" maman="baz">barish</app2:bar>
<app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
<app2:bar xmlns:app2="http://bar.com/" maman="baz">barish</app2:bar>
</metadata>
</domain>

View File

@ -0,0 +1,31 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<metadata>
<app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
<app2:bar xmlns:app2="http://bar.com/" maman="baz">barish</app2:bar>
</metadata>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<controller type='usb' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -367,6 +367,7 @@ mymain(void)
DO_TEST_DIFFERENT("usb-ich9-ehci-addr");
DO_TEST_DIFFERENT("metadata");
DO_TEST_DIFFERENT("metadata-duplicate");
DO_TEST("tpm-passthrough");
DO_TEST("pci-bridge");