[libvirt] [PATCH] Revert "virsh: Increase device-detach intelligence"
by Osier Yang
This reverts commit ea7182c29f185e7c1527b10fbe16dc4ba1f45a88.
Conflicts are resolved.
This is a temporary reverting for it introduces regression of device
detaching (any device XML doesn't uses the same order as libvirt
generates, or has uses decimal for some attrs (e.g. "slot") will
cause the failure, as virsh compares the XML simply earlier before internal
parsing). We could take the patch back when the new API for normalizing
XML is ready.
---
tools/virsh.c | 292 +++-----------------------------------------------------
1 files changed, 16 insertions(+), 276 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 04c1f6e..fb940b8 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -60,7 +60,6 @@
#include "command.h"
#include "virkeycode.h"
#include "virnetdevbandwidth.h"
-#include "util/bitmap.h"
#include "conf/domain_conf.h"
static char *progname;
@@ -12571,251 +12570,6 @@ cmdAttachDevice(vshControl *ctl, const vshCmd *cmd)
return true;
}
-/**
- * Check if n1 is superset of n2, meaning n1 contains all elements and
- * attributes as n2 at least. Including children.
- * @n1 first node
- * @n2 second node
- * returns true in case n1 covers n2, false otherwise.
- */
-static bool
-vshNodeIsSuperset(xmlNodePtr n1, xmlNodePtr n2)
-{
- xmlNodePtr child1, child2;
- xmlAttrPtr attr;
- char *prop1, *prop2;
- bool found;
- bool visited;
- bool ret = false;
- long n1_child_size, n2_child_size, n1_iter;
- virBitmapPtr bitmap;
-
- if (!n1 && !n2)
- return true;
-
- if (!n1 || !n2)
- return false;
-
- if (!xmlStrEqual(n1->name, n2->name))
- return false;
-
- /* Iterate over n2 attributes and check if n1 contains them*/
- attr = n2->properties;
- while (attr) {
- if (attr->type == XML_ATTRIBUTE_NODE) {
- prop1 = virXMLPropString(n1, (const char *) attr->name);
- prop2 = virXMLPropString(n2, (const char *) attr->name);
- if (STRNEQ_NULLABLE(prop1, prop2)) {
- xmlFree(prop1);
- xmlFree(prop2);
- return false;
- }
- xmlFree(prop1);
- xmlFree(prop2);
- }
- attr = attr->next;
- }
-
- n1_child_size = virXMLChildElementCount(n1);
- n2_child_size = virXMLChildElementCount(n2);
- if (n1_child_size < 0 || n2_child_size < 0 ||
- n1_child_size < n2_child_size)
- return false;
-
- if (n1_child_size == 0 && n2_child_size == 0)
- return true;
-
- if (!(bitmap = virBitmapAlloc(n1_child_size))) {
- virReportOOMError();
- return false;
- }
-
- child2 = n2->children;
- while (child2) {
- if (child2->type != XML_ELEMENT_NODE) {
- child2 = child2->next;
- continue;
- }
-
- child1 = n1->children;
- n1_iter = 0;
- found = false;
- while (child1) {
- if (child1->type != XML_ELEMENT_NODE) {
- child1 = child1->next;
- continue;
- }
-
- if (virBitmapGetBit(bitmap, n1_iter, &visited) < 0) {
- vshError(NULL, "%s", _("Bad child elements counting."));
- goto cleanup;
- }
-
- if (visited) {
- child1 = child1->next;
- n1_iter++;
- continue;
- }
-
- if (xmlStrEqual(child1->name, child2->name)) {
- found = true;
- if (virBitmapSetBit(bitmap, n1_iter) < 0) {
- vshError(NULL, "%s", _("Bad child elements counting."));
- goto cleanup;
- }
-
- if (!vshNodeIsSuperset(child1, child2))
- goto cleanup;
-
- break;
- }
-
- child1 = child1->next;
- n1_iter++;
- }
-
- if (!found)
- goto cleanup;
-
- child2 = child2->next;
- }
-
- ret = true;
-
-cleanup:
- virBitmapFree(bitmap);
- return ret;
-}
-
-/**
- * vshCompleteXMLFromDomain:
- * @ctl vshControl for error messages printing
- * @dom domain
- * @oldXML device XML before
- * @newXML and after completion
- *
- * For given domain and (probably incomplete) device XML specification try to
- * find such device in domain and complete missing parts. This is however
- * possible only when given device XML is sufficiently precise so it addresses
- * only one device.
- *
- * Returns -2 when no such device exists in domain, -3 when given XML selects many
- * (is too ambiguous), 0 in case of success. Otherwise returns -1. @newXML
- * is touched only in case of success.
- */
-static int
-vshCompleteXMLFromDomain(vshControl *ctl, virDomainPtr dom, char *oldXML,
- char **newXML)
-{
- int funcRet = -1;
- char *domXML = NULL;
- xmlDocPtr domDoc = NULL, devDoc = NULL;
- xmlNodePtr node = NULL;
- xmlXPathContextPtr domCtxt = NULL, devCtxt = NULL;
- xmlNodePtr *devices = NULL;
- xmlSaveCtxtPtr sctxt = NULL;
- int devices_size;
- char *xpath = NULL;
- xmlBufferPtr buf = NULL;
- int i = 0;
- int indx = -1;
-
- if (!(domXML = virDomainGetXMLDesc(dom, 0))) {
- vshError(ctl, _("couldn't get XML description of domain %s"),
- virDomainGetName(dom));
- goto cleanup;
- }
-
- domDoc = virXMLParseStringCtxt(domXML, _("(domain_definition)"), &domCtxt);
- if (!domDoc) {
- vshError(ctl, _("Failed to parse domain definition xml"));
- goto cleanup;
- }
-
- devDoc = virXMLParseStringCtxt(oldXML, _("(device_definition)"), &devCtxt);
- if (!devDoc) {
- vshError(ctl, _("Failed to parse device definition xml"));
- goto cleanup;
- }
-
- node = xmlDocGetRootElement(devDoc);
-
- buf = xmlBufferCreate();
- if (!buf) {
- vshError(ctl, "%s", _("out of memory"));
- goto cleanup;
- }
-
- /* Get all possible devices */
- virAsprintf(&xpath, "/domain/devices/%s", node->name);
- if (!xpath) {
- virReportOOMError();
- goto cleanup;
- }
- devices_size = virXPathNodeSet(xpath, domCtxt, &devices);
-
- if (devices_size < 0) {
- /* error */
- vshError(ctl, "%s", _("error when selecting nodes"));
- goto cleanup;
- } else if (devices_size == 0) {
- /* no such device */
- funcRet = -2;
- goto cleanup;
- }
-
- /* and refine */
- for (i = 0; i < devices_size; i++) {
- if (vshNodeIsSuperset(devices[i], node)) {
- if (indx >= 0) {
- funcRet = -3; /* ambiguous */
- goto cleanup;
- }
- indx = i;
- }
- }
-
- if (indx < 0) {
- funcRet = -2; /* no such device */
- goto cleanup;
- }
-
- vshDebug(ctl, VSH_ERR_DEBUG, "Found device at pos %d\n", indx);
-
- if (newXML) {
- sctxt = xmlSaveToBuffer(buf, NULL, 0);
- if (!sctxt) {
- vshError(ctl, "%s", _("failed to create document saving context"));
- goto cleanup;
- }
-
- xmlSaveTree(sctxt, devices[indx]);
- xmlSaveClose(sctxt);
- *newXML = (char *) xmlBufferContent(buf);
- if (!*newXML) {
- virReportOOMError();
- goto cleanup;
- }
- buf->content = NULL;
- }
-
- vshDebug(ctl, VSH_ERR_DEBUG, "Old xml:\n%s\nNew xml:\n%s\n", oldXML,
- newXML ? NULLSTR(*newXML) : "(null)");
-
- funcRet = 0;
-
-cleanup:
- xmlBufferFree(buf);
- VIR_FREE(devices);
- xmlXPathFreeContext(devCtxt);
- xmlXPathFreeContext(domCtxt);
- xmlFreeDoc(devDoc);
- xmlFreeDoc(domDoc);
- VIR_FREE(domXML);
- VIR_FREE(xpath);
- return funcRet;
-}
-
/*
* "detach-device" command
*/
@@ -12835,11 +12589,10 @@ static const vshCmdOptDef opts_detach_device[] = {
static bool
cmdDetachDevice(vshControl *ctl, const vshCmd *cmd)
{
- virDomainPtr dom = NULL;
+ virDomainPtr dom;
const char *from = NULL;
- char *buffer = NULL, *new_buffer = NULL;
+ char *buffer;
int ret;
- bool funcRet = false;
unsigned int flags;
if (!vshConnectionUsability(ctl, ctl->conn))
@@ -12848,50 +12601,37 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
- if (vshCommandOptString(cmd, "file", &from) <= 0)
- goto cleanup;
+ if (vshCommandOptString(cmd, "file", &from) <= 0) {
+ virDomainFree(dom);
+ return false;
+ }
if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) {
virshReportError(ctl);
- goto cleanup;
- }
-
- ret = vshCompleteXMLFromDomain(ctl, dom, buffer, &new_buffer);
- if (ret < 0) {
- if (ret == -2) {
- vshError(ctl, _("no such device in %s"), virDomainGetName(dom));
- } else if (ret == -3) {
- vshError(ctl, "%s", _("given XML selects too many devices. "
- "Please, be more specific"));
- } else {
- /* vshCompleteXMLFromDomain() already printed error message,
- * so nothing to do here. */
- }
- goto cleanup;
+ virDomainFree(dom);
+ return false;
}
if (vshCommandOptBool(cmd, "persistent")) {
flags = VIR_DOMAIN_AFFECT_CONFIG;
if (virDomainIsActive(dom) == 1)
flags |= VIR_DOMAIN_AFFECT_LIVE;
- ret = virDomainDetachDeviceFlags(dom, new_buffer, flags);
+ ret = virDomainDetachDeviceFlags(dom, buffer, flags);
} else {
- ret = virDomainDetachDevice(dom, new_buffer);
+ ret = virDomainDetachDevice(dom, buffer);
}
+ VIR_FREE(buffer);
if (ret < 0) {
vshError(ctl, _("Failed to detach device from %s"), from);
- goto cleanup;
+ virDomainFree(dom);
+ return false;
+ } else {
+ vshPrint(ctl, "%s", _("Device detached successfully\n"));
}
- vshPrint(ctl, "%s", _("Device detached successfully\n"));
- funcRet = true;
-
-cleanup:
- VIR_FREE(new_buffer);
- VIR_FREE(buffer);
virDomainFree(dom);
- return funcRet;
+ return true;
}
--
1.7.7.3
12 years, 11 months
[libvirt] [PATCH] nwfilter: fix typing error in filter
by Stefan Berger
Fix a typing error in the no-ip-spoofing filter.
Return DHCP request packets passing through this filter. Have
the user use another filter to actually allow DHCP requests to be
sent (action='accept').
---
examples/xml/nwfilter/no-ip-spoofing.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: libvirt-acl/examples/xml/nwfilter/no-ip-spoofing.xml
===================================================================
--- libvirt-acl.orig/examples/xml/nwfilter/no-ip-spoofing.xml
+++ libvirt-acl/examples/xml/nwfilter/no-ip-spoofing.xml
@@ -1,7 +1,7 @@
<filter name='no-ip-spoofing' chain='ipv4-ip' priority='-710'>
- <!-- allow DHCP requests -->
- <rule action='accept' direction='out' priority='100'>
- <ip srcipaddr='0.0.0.0' protocol='udp' srcportstart='68' srcportend='68'/>
+ <!-- allow DHCP requests sent from 0.0.0.0 -->
+ <rule action='return' direction='out' priority='100'>
+ <ip srcipaddr='0.0.0.0' protocol='udp' srcportstart='68'
dstportstart='67'/>
</rule>
<!-- allow all known IP addresses -->
12 years, 11 months
[libvirt] blockJob events broken
by Adam Litke
Hi Dan,
I noticed that since d09f6ba5feb655925175dc80122ca2a1e14db2b9, blockJob events
are not being delivered to registered clients. I did verify that VM lifecycle
events are still working fine though. I am confused why your patch has only
affected my blockJob events. Do you have any ideas?
--
Adam Litke <agl(a)us.ibm.com>
IBM Linux Technology Center
12 years, 11 months
[libvirt] [PATCH 3/3][TCK] nwfilter: test access via index and iterators
by Stefan Berger
Test access to variables using index and iterators
---
scripts/nwfilter/nwfilterxml2fwallout/iter-test3.fwall | 37 +++++++++++++++++
scripts/nwfilter/nwfilterxml2xmlin/iter-test3.xml | 13 +++++
2 files changed, 50 insertions(+)
Index: libvirt-tck/scripts/nwfilter/nwfilterxml2fwallout/iter-test3.fwall
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/nwfilter/nwfilterxml2fwallout/iter-test3.fwall
@@ -0,0 +1,37 @@
+#iptables -L FI-vnet0 -n
+Chain FI-vnet0 (1 references)
+target prot opt source destination
+RETURN tcp -- 1.1.1.1 0.0.0.0/0 DSCP match 0x01tcp spt:80 state NEW,ESTABLISHED ctdir REPLY
+RETURN tcp -- 1.1.1.1 0.0.0.0/0 DSCP match 0x01tcp spt:90 state NEW,ESTABLISHED ctdir REPLY
+RETURN udp -- 2.2.2.2 0.0.0.0/0 DSCP match 0x02udp spt:80 state NEW,ESTABLISHED ctdir REPLY
+RETURN udp -- 2.2.2.2 0.0.0.0/0 DSCP match 0x02udp spt:90 state NEW,ESTABLISHED ctdir REPLY
+RETURN sctp -- 2.2.2.2 0.0.0.0/0 DSCP match 0x03sctp spt:80 dpt:1100 state NEW,ESTABLISHED ctdir REPLY
+#iptables -L FO-vnet0 -n
+Chain FO-vnet0 (1 references)
+target prot opt source destination
+ACCEPT tcp -- 0.0.0.0/0 1.1.1.1 DSCP match 0x01tcp dpt:80 state ESTABLISHED ctdir ORIGINAL
+ACCEPT tcp -- 0.0.0.0/0 1.1.1.1 DSCP match 0x01tcp dpt:90 state ESTABLISHED ctdir ORIGINAL
+ACCEPT udp -- 0.0.0.0/0 2.2.2.2 DSCP match 0x02udp dpt:80 state ESTABLISHED ctdir ORIGINAL
+ACCEPT udp -- 0.0.0.0/0 2.2.2.2 DSCP match 0x02udp dpt:90 state ESTABLISHED ctdir ORIGINAL
+ACCEPT sctp -- 0.0.0.0/0 2.2.2.2 DSCP match 0x03sctp spt:1100 dpt:80 state ESTABLISHED ctdir ORIGINAL
+#iptables -L HI-vnet0 -n
+Chain HI-vnet0 (1 references)
+target prot opt source destination
+RETURN tcp -- 1.1.1.1 0.0.0.0/0 DSCP match 0x01tcp spt:80 state NEW,ESTABLISHED ctdir REPLY
+RETURN tcp -- 1.1.1.1 0.0.0.0/0 DSCP match 0x01tcp spt:90 state NEW,ESTABLISHED ctdir REPLY
+RETURN udp -- 2.2.2.2 0.0.0.0/0 DSCP match 0x02udp spt:80 state NEW,ESTABLISHED ctdir REPLY
+RETURN udp -- 2.2.2.2 0.0.0.0/0 DSCP match 0x02udp spt:90 state NEW,ESTABLISHED ctdir REPLY
+RETURN sctp -- 2.2.2.2 0.0.0.0/0 DSCP match 0x03sctp spt:80 dpt:1100 state NEW,ESTABLISHED ctdir REPLY
+#iptables -L libvirt-host-in -n | grep vnet0 | tr -s " "
+HI-vnet0 all -- 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet0
+#iptables -L libvirt-in -n | grep vnet0 | tr -s " "
+FI-vnet0 all -- 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-in vnet0
+#iptables -L libvirt-in-post -n | grep vnet0
+ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in vnet0
+#iptables -L libvirt-out -n | grep vnet0 | tr -s " "
+FO-vnet0 all -- 0.0.0.0/0 0.0.0.0/0 [goto] PHYSDEV match --physdev-out vnet0
+#iptables -L FORWARD -n --line-number | grep libvirt
+1 libvirt-in all -- 0.0.0.0/0 0.0.0.0/0
+2 libvirt-out all -- 0.0.0.0/0 0.0.0.0/0
+3 libvirt-in-post all -- 0.0.0.0/0 0.0.0.0/0
+
Index: libvirt-tck/scripts/nwfilter/nwfilterxml2xmlin/iter-test3.xml
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/nwfilter/nwfilterxml2xmlin/iter-test3.xml
@@ -0,0 +1,13 @@
+<filter name='tck-testcase' chain='root'>
+ <uuid>5c6d49af-b071-6127-b4ec-6f8ed4b55335</uuid>
+ <rule action='accept' direction='out'>
+ <tcp srcipaddr='$A[ 0]' srcportstart='$B[ @0 ] ' dscp='1'/>
+ </rule>
+ <rule action='accept' direction='out'>
+ <udp srcipaddr='$A[1 ]' srcportstart='$B[ @2 ]' dscp='2'/>
+ </rule>
+ <rule action='accept' direction='out'>
+ <sctp srcipaddr='$A[ 1 ] ' srcportstart='$B[2 ] ' dstportstart='$C[ 2 ]'
+ dscp='3'/>
+ </rule>
+</filter>
12 years, 11 months
[libvirt] [PATCH] virsh: Two new fields for command domblklist
by Osier Yang
Disk "type" and "device" are generally interesting stuffs the
user who wants to known too. Though it's likely breaks the script
which parses the command output by field (e.g. awk), putting
them in the head is better, as it coheres with the user's habit
more. (Trying to find the small word (type, device) after a
very long file path (could be) sounds not a good idea).
---
tools/virsh.c | 14 +++++++++++---
tools/virsh.pod | 14 +++++++-------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 3af2fd7..31c2b5c 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1905,7 +1905,7 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd)
*/
static const vshCmdInfo info_domblklist[] = {
{"help", N_("list all domain blocks")},
- {"desc", N_("Get the names of block devices for a domain.")},
+ {"desc", N_("Get the summary of block devices for a domain.")},
{NULL, NULL}
};
@@ -1950,14 +1950,19 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
if (ndisks < 0)
goto cleanup;
- vshPrint(ctl, "%-10s %s\n", _("Target"), _("Source"));
+ vshPrint(ctl, "%-10s %-10s %-10s %s\n", _("Type"),
+ _("Device"), _("Target"), _("Source"));
vshPrint(ctl, "------------------------------------------------\n");
for (i = 0; i < ndisks; i++) {
+ char *type;
+ char *device;
char *target;
char *source;
ctxt->node = disks[i];
+ type = virXPathString("string(./@type)", ctxt);
+ device = virXPathString("string(./@device)", ctxt);
target = virXPathString("string(./target/@dev)", ctxt);
if (!target) {
vshError(ctl, "unable to query block list");
@@ -1967,7 +1972,10 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
"|./source/@dev"
"|./source/@dir"
"|./source/@name)", ctxt);
- vshPrint(ctl, "%-10s %s\n", target, source ? source : "-");
+ vshPrint(ctl, "%-10s %-10s %-10s %s\n", type, device,
+ target, source ? source : "-");
+ VIR_FREE(type);
+ VIR_FREE(device);
VIR_FREE(target);
VIR_FREE(source);
}
diff --git a/tools/virsh.pod b/tools/virsh.pod
index bae6a13..6ae9a90 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -514,13 +514,13 @@ also B<domblklist> for listing these names).
=item B<domblklist> I<domain> [I<--inactive>]
-Print a table showing the names of all block devices associated with
-I<domain>, as well as the path to the source of each device. If
-I<--inactive> is specified, query the block devices that will be used
-on the next boot, rather than those currently in use by a running
-domain. Other contexts that require a block device name (such as
-I<domblkinfo> or I<snapshot-create> for disk snapshots) will accept
-either target or unique source names printed by this command.
+Print a table showing the brief information of all block devices
+associated with I<domain>. If I<--inactive> is specified, query the
+block devices that will be used on the next boot, rather than those
+currently in use by a running domain. Other contexts that require a
+block device name (such as I<domblkinfo> or I<snapshot-create> for
+disk snapshots) will accept either target or unique source names
+printed by this command.
=item B<domiflist> I<domain> [I<--inactive>]
--
1.7.7.3
12 years, 11 months
[libvirt] [PATCH v2][TCK] add test for get and define save image xml
by Xiaoqiang Hu
v2: change save image path from working dir to libvirt-tck cache dir
v1: add test for get and define save image xml and there are types of save image
file covered in the test: persistent, transient and invalid domain save image
---
scripts/qemu/400-save-image-xml.t | 107 +++++++++++++++++++++++++++++++++++++
1 files changed, 107 insertions(+), 0 deletions(-)
create mode 100644 scripts/qemu/400-save-image-xml.t
diff --git a/scripts/qemu/400-save-image-xml.t b/scripts/qemu/400-save-image-xml.t
new file mode 100644
index 0000000..a1430c7
--- /dev/null
+++ b/scripts/qemu/400-save-image-xml.t
@@ -0,0 +1,107 @@
+# -*- perl -*-
+#
+# Copyright (C) 2012-2013 Red Hat, Inc.
+# Copyright (C) 2012-2013 Xiaoqiang Hu <xhu(a)redhat.com>
+#
+# This program is free software; You can redistribute it and/or modify
+# it under the GNU General Public License as published by the Free
+# Software Foundation; either version 2, or (at your option) any
+# later version
+#
+# The file "LICENSE" distributed along with this file provides full
+# details of the terms and conditions
+#
+
+=pod
+
+=head1 NAME
+
+qemu/400-save-image-xml.t: test get and define xml from save image
+
+=head1 DESCRIPTION
+
+The test case validates that it is possible to define and get domain xml
+from save image. There are three types of save image file covered in the
+test: persistent, transient and invalid domain save image
+=cut
+
+use strict;
+use warnings;
+
+use Test::More tests => 10;
+
+use Sys::Virt::TCK;
+use Test::Exception;
+use File::Basename;
+
+my $tck = Sys::Virt::TCK->new();
+my $savefile = $tck->bucket_dir("400-save-image-xml")."/"."tck.img";
+my $conn = eval { $tck->setup(); };
+BAIL_OUT "failed to setup test harness: $@" if $@;
+END {
+ $tck->cleanup if $tck;
+ unlink $savefile if -f $savefile;
+}
+
+SKIP:{
+ skip "Only relevant to QEMU driver", 10 unless $conn->get_type() eq "QEMU";
+
+ # scenario 1 - get/define xml from transient domain save image
+ my $xml = $tck->generic_domain("tck")->as_xml;
+ diag "Creating a new transient domain";
+ my $dom;
+ ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object");
+
+ unlink $savefile if -f $savefile;
+ eval { $dom->save($savefile); };
+ SKIP: {
+ skip "save/restore not implemented", 9 if $@ && err_not_implemented($@);
+ ok(!$@, "domain saved");
+ die $@ if $@;
+
+ my $savedxmldesc;
+ diag "Checking that transient domain has gone away";
+ ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain",
+ Sys::Virt::Error::ERR_NO_DOMAIN);
+ eval { $savedxmldesc = $conn->get_save_image_xml_description($savefile, 0); };
+ SKIP: {
+ skip "get/define save img xml not implemented", 7 if $@ && err_not_implemented($@);
+ $savedxmldesc = $conn->get_save_image_xml_description($savefile, 0);
+ $savedxmldesc =~ s/destroy/restart/g;
+ $conn->define_save_image_xml($savefile, $savedxmldesc, 0);
+
+ $savedxmldesc = $conn->get_save_image_xml_description($savefile, 0);
+ ok(!($savedxmldesc =~ m/destroy/), "the transient domain save image xml has been updated");
+
+ # scenario 2 - get/define xml from persistent domain save image
+ my $xml = $tck->generic_domain("tck")->as_xml;
+ diag "Creating a new persistent domain";
+ ok_domain(sub { $dom = $conn->define_domain($xml) }, "created persistent domain object");
+
+ unlink $savefile if -f $savefile;
+ diag "Starting inactive domain";
+ $dom->create;
+
+ $dom->save($savefile);
+ diag "Checking that persistent domain is stopped";
+ ok_domain(sub { $conn->get_domain_by_name("tck") }, "persistent domain is still there", "tck");
+ is($dom->get_id, -1, "running domain with ID == -1");
+
+ $savedxmldesc = $conn->get_save_image_xml_description($savefile, 0);
+ $savedxmldesc =~ s/destroy/restart/g;
+ $conn->define_save_image_xml($savefile, $savedxmldesc, 0);
+
+ $savedxmldesc = $conn->get_save_image_xml_description($savefile, 0);
+ ok(!($savedxmldesc =~ m/destroy/), "the persistent save image xml has been updated");
+
+ # scenario 3 - get/define xml from invalid domain save image
+ unlink $savefile if -f $savefile;
+ diag "Creating an invalid save img file";
+ `dd if=/dev/null of=$savefile bs=1M count=100 >& /dev/null 2>&1`;
+ ok($? == 0, "created 100M raw img file: $savefile");
+ diag "Getting xml from invalid save image";
+ ok_error(sub { $conn->get_save_image_xml_description($savefile, 0) }, "failed to get invalid domain save image xml" );
+ }
+ }
+}
+# end
--
1.7.1
12 years, 11 months
[libvirt] [PATCH 1/1] Added check for maximum number of vcpus exceeding topology limit
by Martin Kletzander
Earlier, when the number of vcpus was greater than the topology allowed,
libvirt didn't raise an error and continued, resulting in running qemu
with parameters making no sense. Even though qemu did not report any
error itself, the number of vcpus was set to maximum allowed by the
topology.
---
src/conf/domain_conf.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 180dd2b..06ddd02 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8010,6 +8010,13 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
if (def->cpu == NULL)
goto error;
+ if (def->maxvcpus >
+ def->cpu->sockets * def->cpu->cores * def->cpu->threads) {
+ virDomainReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("Maximum CPUs greater than topology limit"));
+ goto error;
+ }
+
if (def->cpu->cells_cpus > def->maxvcpus) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Number of CPUs in <numa> exceeds the"
--
1.7.3.4
12 years, 11 months
[libvirt] [PATCH] build: fix build on mingw with netcf available
by Eric Blake
The autobuilder pointed out an odd failure on mingw:
../../src/interface/netcf_driver.c:644:5: error: unknown field 'close_used_without_including_unistd_h' specified in initializer
cc1: warnings being treated as errors
This is because the gnulib headers #define close in order to work
around some odd mingw problems with close(), but it happens to
also affect field members declared with a name of struct foo.close.
As long as the same headers are included for the definition and use
of the struct, the #define doesn't matter, but the netcf file hit
an instance where things were in a different order. Fix this for
all clients that use a struct member named 'close'.
* src/driver.h: Include <unistd.h> before using 'close'.
---
I don't have netcf for mingw locally, so I'd like a review before
pushing this, since I couldn't confirm whether it fixed the
broken build on the autobuilder.
src/driver.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/driver.h b/src/driver.h
index ec4abf3..24636a4 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -8,6 +8,7 @@
# include "config.h"
+# include <unistd.h>
# include <libxml/uri.h>
# include "internal.h"
--
1.7.7.5
12 years, 11 months
[libvirt] [PATCH] Disable netcf if building without libvirtd
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Although the netcf interface driver can in theory be used by
the stateless drivers, in practice none of them want to use
it because they have different ways of dealing with interfaces.
Furthermore, if you have mingw32-netcf installed, then the
libvirt mingw32 build will fail with
../../src/interface/netcf_driver.c:644:5: error: unknown field 'close_used_without_including_unistd_h' specified in initializer
* configure.ac: disable netcf if built without libvirtd
---
configure.ac | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index b12e9fb..729ba9b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1613,6 +1613,9 @@ AC_ARG_WITH([netcf],
NETCF_CFLAGS=
NETCF_LIBS=
+if test "$with_libvirtd" = "no" ; then
+ with_netcf=no
+fi
if test "$with_netcf" = "yes" || test "$with_netcf" = "check"; then
PKG_CHECK_MODULES(NETCF, netcf >= $NETCF_REQUIRED,
[with_netcf=yes], [
--
1.7.7.5
12 years, 11 months
[libvirt] [PATCH libvirt-glib] Add support for shutdown event to avoid console warnings
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
---
libvirt-gobject/libvirt-gobject-connection.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c
index d5f9c45..f0c9ff6 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -376,6 +376,9 @@ static int domain_event_cb(virConnectPtr conn G_GNUC_UNUSED,
}
break;
+ case VIR_DOMAIN_EVENT_SHUTDOWN:
+ break;
+
default:
g_warn_if_reached();
}
--
1.7.7.5
12 years, 11 months