[libvirt] [PATCH] 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 --- src/conf/domain_conf.c | 42 ++++++++++++++++++++++ .../qemuxml2argv-metadata-duplicate.xml | 34 ++++++++++++++++++ .../qemuxml2xmlout-metadata-duplicate.xml | 31 ++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 4 files changed, 108 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-metadata-duplicate.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata-duplicate.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6da02b0..5467bef 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -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; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-metadata-duplicate.xml b/tests/qemuxml2argvdata/qemuxml2argv-metadata-duplicate.xml new file mode 100644 index 0000000..13fb449 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-metadata-duplicate.xml @@ -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> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata-duplicate.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata-duplicate.xml new file mode 100644 index 0000000..e32fb67 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata-duplicate.xml @@ -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> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 58917c3..2bec2b2 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -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"); -- 2.2.2

On 04.03.2015 10:06, Peter Krempa wrote:
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 --- src/conf/domain_conf.c | 42 ++++++++++++++++++++++ .../qemuxml2argv-metadata-duplicate.xml | 34 ++++++++++++++++++ .../qemuxml2xmlout-metadata-duplicate.xml | 31 ++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 4 files changed, 108 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-metadata-duplicate.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata-duplicate.xml
ACK Michal

On Thu, Mar 05, 2015 at 15:03:22 +0100, Michal Privoznik wrote:
On 04.03.2015 10:06, Peter Krempa wrote:
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 --- src/conf/domain_conf.c | 42 ++++++++++++++++++++++ .../qemuxml2argv-metadata-duplicate.xml | 34 ++++++++++++++++++ .../qemuxml2xmlout-metadata-duplicate.xml | 31 ++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 4 files changed, 108 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-metadata-duplicate.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata-duplicate.xml
ACK
Pushed; Thanks Peter
participants (2)
-
Michal Privoznik
-
Peter Krempa