Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 19 participants
- 40171 discussions
[libvirt] [PATCHv3 1/2] conf: add <listen> subelement to domain <graphics> element
by Laine Stump 27 Jul '11
by Laine Stump 27 Jul '11
27 Jul '11
Once it's plugged in, the <listen element will be an optional
replacement for the "listen", "port", "tlsPort", and "autoport"
attributes that graphics elements already have. If the <listen>
type='address', it will have an attribute called 'address' which will
contain an IP address or dns name that the guest's display server
should listen on. If, however, type='network', the <listen> element
should have an attribute called 'network' that will be set to the name
of a network configuration to get the IP address from.
* docs/schemas/domain.rng: updated to allow the <listen> element
* docs/formatdomain.html.in: document the <listen> element and its
attributes.
* src/conf/domain_conf.[hc]:
1) The domain parser, formatter, and data structure are modified to
support 0 or more <listen> subelements to each <graphics>
element. The old style "legacy" attributes are also still
accepted, and will be stored internally just as if they were a
separate <listen> element. On output (i.e. format), the first
<listen> element will be duplicated in the legacy attributes of
the <graphic> element.
2) The following attributes have been removed from the unions in
virDomainGRaphicsDef for graphics types vnc, rdp, and spice:
listen
port
tlsPort
autoport
These attributes are all present in the <listen> subelement (aka
virDomainGraphicsListenDef)
3) Several helper functions were written to provide simple access
(both Get and Set) to the listen elements.
* src/libvirt_private.syms: export the listen helper functions
* src/qemu/qemu_command.c, src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/qemu/qemu_process.c, src/vbox/vbox_tmpl.c,
src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c
Modify all these files to use the listen helper functions rather
than directly referencing the (now missing) listen, port, tlsPort,
and autoport attributes. There can be multiple <listen> elements to
a single <graphics>, but the drivers all currently only support one,
so all replacements of direct access with a helper function indicate
index "0".
* tests/* - only 3 of these are new files added explicitly to test the
new <listen> element. All the others have been modified to reflect
the fact that any "legacy" attributes passed in to the domain parse
will be saved in a <listen> element (i.e. one of the
virDomainGraphicsListenDefs), and during the domain format function,
both the <listen> element as well as the legacy attributes will be
output.
---
docs/formatdomain.html.in | 70 ++
docs/schemas/domain.rng | 46 ++
src/conf/domain_conf.c | 681 ++++++++++++++++----
src/conf/domain_conf.h | 66 ++-
src/libvirt_private.syms | 12 +
src/qemu/qemu_command.c | 67 ++-
src/qemu/qemu_driver.c | 7 +-
src/qemu/qemu_hotplug.c | 32 +-
src/qemu/qemu_migration.c | 10 +-
src/qemu/qemu_process.c | 26 +-
src/vbox/vbox_tmpl.c | 49 +-
src/vmx/vmx.c | 37 +-
src/xenxs/xen_sxpr.c | 52 +-
src/xenxs/xen_xm.c | 79 ++-
.../qemuxml2argv-graphics-listen-network.xml | 32 +
.../qemuxml2argv-graphics-listen-network2.xml | 33 +
.../qemuxml2argv-graphics-spice-compression.xml | 1 +
.../qemuxml2argv-graphics-spice-qxl-vga.xml | 1 +
.../qemuxml2argv-graphics-spice-timeout.xml | 4 +-
.../qemuxml2argv-graphics-spice.xml | 1 +
.../qemuxml2argv-graphics-vnc-sasl.xml | 4 +-
.../qemuxml2argv-graphics-vnc-tls.xml | 4 +-
.../qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml | 4 +-
tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml | 4 +-
.../qemuxml2xmlout-graphics-listen-network2.xml | 33 +
tests/qemuxml2xmltest.c | 2 +
tests/sexpr2xmldata/sexpr2xml-curmem.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml | 4 +-
.../sexpr2xml-fv-serial-dev-2-ports.xml | 4 +-
.../sexpr2xml-fv-serial-dev-2nd-port.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml | 4 +-
.../sexpr2xml-fv-serial-tcp-telnet.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-sound.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-utc.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv-v2.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-fv.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml | 4 +-
.../sexpr2xml-pv-vfb-new-vncdisplay.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-pv-vfb-new.xml | 4 +-
tests/sexpr2xmldata/sexpr2xml-pv-vfb-orig.xml | 4 +-
.../sexpr2xmldata/sexpr2xml-pv-vfb-type-crash.xml | 4 +-
tests/vmx2xmldata/vmx2xml-graphics-vnc.xml | 4 +-
tests/xmconfigdata/test-escape-paths.xml | 4 +-
tests/xmconfigdata/test-fullvirt-force-hpet.xml | 4 +-
tests/xmconfigdata/test-fullvirt-force-nohpet.xml | 4 +-
tests/xmconfigdata/test-fullvirt-localtime.xml | 4 +-
tests/xmconfigdata/test-fullvirt-net-ioemu.xml | 4 +-
tests/xmconfigdata/test-fullvirt-net-netfront.xml | 4 +-
tests/xmconfigdata/test-fullvirt-new-cdrom.xml | 4 +-
tests/xmconfigdata/test-fullvirt-old-cdrom.xml | 4 +-
tests/xmconfigdata/test-fullvirt-parallel-tcp.xml | 4 +-
.../test-fullvirt-serial-dev-2-ports.xml | 4 +-
.../test-fullvirt-serial-dev-2nd-port.xml | 4 +-
tests/xmconfigdata/test-fullvirt-serial-file.xml | 4 +-
tests/xmconfigdata/test-fullvirt-serial-null.xml | 4 +-
tests/xmconfigdata/test-fullvirt-serial-pipe.xml | 4 +-
tests/xmconfigdata/test-fullvirt-serial-pty.xml | 4 +-
tests/xmconfigdata/test-fullvirt-serial-stdio.xml | 4 +-
.../test-fullvirt-serial-tcp-telnet.xml | 4 +-
tests/xmconfigdata/test-fullvirt-serial-tcp.xml | 4 +-
tests/xmconfigdata/test-fullvirt-serial-udp.xml | 4 +-
tests/xmconfigdata/test-fullvirt-serial-unix.xml | 4 +-
tests/xmconfigdata/test-fullvirt-sound.xml | 4 +-
tests/xmconfigdata/test-fullvirt-usbmouse.xml | 4 +-
.../test-fullvirt-usbtablet-no-bus.xml | 4 +-
tests/xmconfigdata/test-fullvirt-usbtablet.xml | 4 +-
tests/xmconfigdata/test-fullvirt-utc.xml | 4 +-
tests/xmconfigdata/test-no-source-cdrom.xml | 4 +-
tests/xmconfigdata/test-paravirt-net-e1000.xml | 4 +-
tests/xmconfigdata/test-paravirt-net-vifname.xml | 4 +-
.../test-paravirt-new-pvfb-vncdisplay.xml | 4 +-
tests/xmconfigdata/test-paravirt-new-pvfb.xml | 4 +-
.../test-paravirt-old-pvfb-vncdisplay.xml | 4 +-
tests/xmconfigdata/test-paravirt-old-pvfb.xml | 4 +-
tests/xmconfigdata/test-pci-devs.xml | 4 +-
91 files changed, 1274 insertions(+), 343 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-listen-network.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-listen-network2.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-listen-network2.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f40afc4..2bfd72b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1965,6 +1965,12 @@ qemu-kvm -net nic,model=? /dev/null
<graphics type='vnc' port='5904'/>
<graphics type='rdp' autoport='yes' multiUser='yes' />
<graphics type='desktop' fullscreen='yes'/>
+ <graphics type='vnc'>
+ <listen type='address' address='1.2.3.4' autoport='yes'/>
+ </graphics>
+ <graphics type='spice'>
+ <listen type='network' network='rednet' port='5920' tlsPort='5980'/>
+ </graphics>
</devices>
...</pre>
@@ -2110,6 +2116,70 @@ qemu-kvm -net nic,model=? /dev/null
</dd>
</dl>
+ <p>
+ Rather than putting the information used to setup the listening
+ socket for graphics types <code>vnc</code> and <code>spice</code> in
+ the <code>listen</code>, <code>port</code>, <code>tlsPort</code>,
+ and <code>autoport</code> attributes, a separate subelement
+ of <code><graphics></code>,
+ called <code><listen></code> can be specified (see the
+ examples above)<span class="since">since
+ 0.9.4</span>. <code><listen></code> accepts the following
+ attributes:
+ </p>
+ <dl>
+ <dt><code>type</code></dt>
+ <dd>Set to either <code>address</code>
+ or <code>network</code>. This tells whether this listen
+ element is specifying the address to be used directly, or by
+ naming a network (which will then be used to determine an
+ appropriate address for listening).
+ </dd>
+ </dl>
+ <dl>
+ <dt><code>address</code></dt>
+ <dd>if <code>type='address'</code>, the <code>address</code>
+ attribute will contain either an IP address or hostname (which
+ will be resolved to an IP address via a DNS query) to listen
+ on. In the "live" XML of a running domain, this attribute be
+ set to the IP address used for listening, even
+ if <code>type='network'</code>.
+ </dd>
+ </dl>
+ <dl>
+ <dt><code>network</code></dt>
+ <dd>if <code>type='network'</code>, the <code>network</code>
+ attribute will contain the name of a network in libvirt's list
+ of configured networks. The named network configuration will
+ be examined to determine an appropriate listen address. For
+ example, if the network has an IPv4 address in its
+ configuration (e.g. if it has a forward type
+ of <code>route</code>, <code>nat</code>, or no forward type
+ (isolated)), the first IPv4 address listed in the network's
+ configuration will be used. If the network is describing a
+ host bridge, the first IPv4 address associated with that
+ bridge device will be used, and if the network is describing
+ one of the 'direct' (macvtap) modes, the first IPv4 address of
+ the first forward dev will be used.
+ </dd>
+ </dl>
+ <dl>
+ <dt><code>port</code></dt>
+ <dd>The port to listen on.</dd>
+ </dl>
+ <dl>
+ <dt><code>tlsPort</code></dt>
+ <dd>The port to listen on for TLS connections (<code>graphics
+ type='spice'</code> only).</dd>
+ </dl>
+ <dl>
+ <dt><code>autoport</code></dt>
+ <dd>If set to 'yes', a listen port will be determined
+ automatically at runtime, and reflected in the domain's live
+ XML.
+ </dd>
+ </dl>
+
<h4><a name="elementsVideo">Video devices</a></h4>
<p>
A video device.
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index aa4ce69..b860c08 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1289,6 +1289,7 @@
</choice>
</attribute>
</optional>
+ <ref name="listenElements"/>
</group>
<group>
<attribute name="type">
@@ -1342,6 +1343,7 @@
</attribute>
</optional>
<interleave>
+ <ref name="listenElements"/>
<zeroOrMore>
<element name="channel">
<attribute name="name">
@@ -1478,6 +1480,7 @@
<ref name="addrIPorName"/>
</attribute>
</optional>
+ <ref name="listenElements"/>
</group>
<group>
<attribute name="type">
@@ -1500,6 +1503,49 @@
</choice>
</element>
</define>
+
+ <define name="listenElements">
+ <zeroOrMore>
+ <element name="listen">
+ <optional>
+ <attribute name="type">
+ <choice>
+ <value>address</value>
+ <value>network</value>
+ </choice>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="address">
+ <ref name="addrIPorName"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="network">
+ <text/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="port">
+ <ref name="PortNumber"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="tlsPort">
+ <ref name="PortNumber"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="autoport">
+ <choice>
+ <value>yes</value>
+ <value>no</value>
+ </choice>
+ </attribute>
+ </optional>
+ </element>
+ </zeroOrMore>
+ </define>
<!--
A video adapter description, allowing configuration of device
model, number of virtual heads, and video ram size
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 072c970..579aa56 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -331,6 +331,11 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST,
"desktop",
"spice")
+VIR_ENUM_IMPL(virDomainGraphicsListen, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST,
+ "default",
+ "address",
+ "network")
+
VIR_ENUM_IMPL(virDomainGraphicsAuthConnected,
VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_LAST,
"default",
@@ -625,14 +630,26 @@ virDomainGraphicsAuthDefClear(virDomainGraphicsAuthDefPtr def)
/* Don't free def */
}
+static void
+virDomainGraphicsListenDefClear(virDomainGraphicsListenDefPtr def)
+{
+ if (!def)
+ return;
+
+ VIR_FREE(def->address);
+ VIR_FREE(def->network);
+ return;
+}
+
void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
{
+ int ii;
+
if (!def)
return;
switch (def->type) {
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
- VIR_FREE(def->data.vnc.listenAddr);
VIR_FREE(def->data.vnc.socket);
VIR_FREE(def->data.vnc.keymap);
virDomainGraphicsAuthDefClear(&def->data.vnc.auth);
@@ -644,7 +661,6 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
break;
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
- VIR_FREE(def->data.rdp.listenAddr);
break;
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
@@ -652,12 +668,15 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
break;
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
- VIR_FREE(def->data.spice.listenAddr);
VIR_FREE(def->data.spice.keymap);
virDomainGraphicsAuthDefClear(&def->data.spice.auth);
break;
}
+ for (ii = 0; ii < def->nListens; ii++)
+ virDomainGraphicsListenDefClear(&def->listens[ii]);
+ VIR_FREE(def->listens);
+
VIR_FREE(def);
}
@@ -4010,19 +4029,118 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node,
return 0;
}
+static int
+virDomainGraphicsListenParseXML(virDomainGraphicsListenDefPtr def,
+ xmlNodePtr node,
+ enum virDomainGraphicsType graphicsType,
+ unsigned int flags)
+{
+ int ret = -1;
+ char *type = virXMLPropString(node, "type");
+ char *address = virXMLPropString(node, "address");
+ char *network = virXMLPropString(node, "network");
+ char *port = virXMLPropString(node, "port");
+ char *tlsPort = virXMLPropString(node, "tlsPort");
+ char *autoport = virXMLPropString(node, "autoport");
+
+ if (type && (def->type = virDomainGraphicsListenTypeFromString(type)) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("unknown graphics listen type '%s'"), type);
+ goto error;
+ }
+
+ if (address && address[0]) {
+ def->address = address;
+ address = NULL;
+ }
+
+ if (network && network[0]) {
+ if (def->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("network attribute not allowed when listen type is not network"));
+ goto error;
+ }
+ def->network = network;
+ network = NULL;
+ }
+
+ if (port) {
+ if (virStrToLong_i(port, NULL, 10, &def->port) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("cannot parse listen port %s"), port);
+ goto error;
+ }
+ /* legacy syntax for graphics type=vnc used -1 for
+ * autoport. We need to maintain it here because the legacy
+ * attributes in <graphics> must match those in
+ * <listen>. */
+ if ((graphicsType == VIR_DOMAIN_GRAPHICS_TYPE_VNC) &&
+ (def->port == -1)) {
+ if (flags & VIR_DOMAIN_XML_INACTIVE)
+ def->port = 0;
+ def->autoport = true;
+ }
+ } else {
+ def->autoport = true;
+ }
+
+ if (tlsPort &&
+ (graphicsType == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)) {
+ if (virStrToLong_i(tlsPort, NULL, 10, &def->tlsPort) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("cannot parse spice tlsPort %s"), tlsPort);
+ goto error;
+ }
+ }
+
+ if (autoport && STREQ(autoport, "yes")) {
+ if (flags & VIR_DOMAIN_XML_INACTIVE) {
+ def->port = 0;
+ def->tlsPort = 0;
+ }
+ def->autoport = true;
+ }
+
+ ret = 0;
+error:
+ if (ret < 0)
+ virDomainGraphicsListenDefClear(def);
+ VIR_FREE(type);
+ VIR_FREE(address);
+ VIR_FREE(network);
+ VIR_FREE(port);
+ VIR_FREE(tlsPort);
+ VIR_FREE(autoport);
+ return ret;
+}
+
/* Parse the XML definition for a graphics device */
static virDomainGraphicsDefPtr
-virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
+virDomainGraphicsDefParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
{
virDomainGraphicsDefPtr def;
char *type = NULL;
+ int nListens;
+ xmlNodePtr *listenNodes = NULL;
+ char *port = NULL;
+ char *tlsPort = NULL;
+ char *autoport = NULL;
+ char *listenAddr = NULL;
+ int portVal = 0;
+ int tlsPortVal = 0;
+ bool autoportVal = false;
+ xmlNodePtr save = ctxt->node;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
return NULL;
}
+ ctxt->node = node;
+
type = virXMLPropString(node, "type");
if (!type) {
@@ -4037,46 +4155,136 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
goto error;
}
- if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
- char *port = virXMLPropString(node, "port");
- char *autoport;
+ if ((def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) ||
+ (def->type == VIR_DOMAIN_GRAPHICS_TYPE_RDP) ||
+ (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)) {
- if (port) {
- if (virStrToLong_i(port, NULL, 10, &def->data.vnc.port) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse vnc port %s"), port);
- VIR_FREE(port);
+ /* parse the <listen> subelements for graphics types that support it */
+ nListens = virXPathNodeSet("./listen", ctxt, &listenNodes);
+ if (nListens < 0)
+ goto error;
+
+ if (nListens > 0) {
+ int ii;
+
+ if (VIR_ALLOC_N(def->listens, nListens) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ for (ii = 0; ii < nListens; ii++) {
+ int ret = virDomainGraphicsListenParseXML(&def->listens[ii],
+ listenNodes[ii],
+ def->type, flags);
+ if (ret < 0)
+ goto error;
+ def->nListens++;
+ }
+ VIR_FREE(listenNodes);
+ }
+
+ /* and now parse the "legacy" port/autoport/tlsPort/listen attributes */
+ if ((port = virXMLPropString(node, "port"))) {
+ if (virStrToLong_i(port, NULL, 10, &portVal) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("cannot parse graphics port %s"), port);
goto error;
}
- VIR_FREE(port);
- /* Legacy compat syntax, used -1 for auto-port */
- if (def->data.vnc.port == -1) {
+
+ /* Legacy compat syntax, used -1 for autoport, but only when type=vnc */
+ if ((def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) &&
+ (portVal == -1)) {
if (flags & VIR_DOMAIN_XML_INACTIVE)
- def->data.vnc.port = 0;
- def->data.vnc.autoport = 1;
+ portVal = 0;
+ autoportVal = true;
}
+ } else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
+ /* When port isn't specified for spice, for some
+ * reason it defaults to 5900, rather than turning on
+ * autoport like the others. */
+ portVal = 5900;
} else {
- def->data.vnc.port = 0;
- def->data.vnc.autoport = 1;
+ autoportVal = true;
}
- if ((autoport = virXMLPropString(node, "autoport")) != NULL) {
+ /* tlsPort is only used for spice */
+ if ((tlsPort = virXMLPropString(node, "tlsPort"))
+ && (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)) {
+ if (virStrToLong_i(tlsPort, NULL, 10, &tlsPortVal) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("cannot parse spice tlsPort %s"), tlsPort);
+ goto error;
+ }
+ }
+
+ if ((autoport = virXMLPropString(node, "autoport"))) {
if (STREQ(autoport, "yes")) {
- if (flags & VIR_DOMAIN_XML_INACTIVE)
- def->data.vnc.port = 0;
- def->data.vnc.autoport = 1;
+ if (flags & VIR_DOMAIN_XML_INACTIVE) {
+ portVal = 0;
+ tlsPort = 0;
+ }
+ autoportVal = true;;
}
- VIR_FREE(autoport);
}
- def->data.vnc.listenAddr = virXMLPropString(node, "listen");
+ listenAddr = virXMLPropString(node, "listen");
+ if (listenAddr && !listenAddr[0])
+ VIR_FREE(listenAddr);
+
+ if (def->nListens == 0) {
+ /* There were no <listen> elements, so we can just
+ * directly set these attributes as listens[0] */
+ if (portVal && (virDomainGraphicsListenSetPort(def, 0, portVal) < 0))
+ goto error;
+ if ((def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) &&
+ tlsPortVal && (virDomainGraphicsListenSetTlsPort(def, 0, tlsPortVal) < 0))
+ goto error;
+ if (autoportVal && (virDomainGraphicsListenSetAutoport(def, 0, autoportVal) < 0))
+ goto error;
+ if (listenAddr && (virDomainGraphicsListenSetAddress(def, 0, listenAddr, -1) < 0))
+ goto error;
+ } else {
+ /* There's already a listens[0] element, so we just verify
+ * that it matches these legacy attributes from <graphics>. */
+ if (port && (portVal != virDomainGraphicsListenGetPort(def, 0))) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("graphics port attribute %s must match port "
+ "attribute of first listen element (found %d)"),
+ port, virDomainGraphicsListenGetPort(def, 0));
+ goto error;
+ }
+ if ((def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) &&
+ tlsPort && (tlsPortVal != virDomainGraphicsListenGetTlsPort(def, 0))) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("graphics tlsPort attribute %s must match tlsPort "
+ "attribute of first listen element (found %d)"),
+ tlsPort, virDomainGraphicsListenGetTlsPort(def, 0));
+ goto error;
+ }
+ if (autoport && (autoportVal != virDomainGraphicsListenGetAutoport(def, 0))) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("graphics autoport attribute %s must match autoport "
+ "attribute of first listen element (found %s)"),
+ autoport,
+ virDomainGraphicsListenGetAutoport(def, 0) ? "yes" : "no");
+ goto error;
+ }
+ if (listenAddr && STRNEQ_NULLABLE(listenAddr,
+ virDomainGraphicsListenGetAddress(def, 0))) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("graphics listen attribute %s must match address "
+ "attribute of first listen element (found %s)"),
+ listenAddr, virDomainGraphicsListenGetAddress(def, 0));
+ goto error;
+ }
+ }
+ }
+
+ if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+
def->data.vnc.socket = virXMLPropString(node, "socket");
def->data.vnc.keymap = virXMLPropString(node, "keymap");
- if (def->data.vnc.listenAddr &&
- !def->data.vnc.listenAddr[0])
- VIR_FREE(def->data.vnc.listenAddr);
-
if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth,
def->type) < 0)
goto error;
@@ -4100,33 +4308,9 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
def->data.sdl.xauth = virXMLPropString(node, "xauth");
def->data.sdl.display = virXMLPropString(node, "display");
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_RDP) {
- char *port = virXMLPropString(node, "port");
- char *autoport;
char *replaceUser;
char *multiUser;
- if (port) {
- if (virStrToLong_i(port, NULL, 10, &def->data.rdp.port) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse rdp port %s"), port);
- VIR_FREE(port);
- goto error;
- }
- VIR_FREE(port);
- } else {
- def->data.rdp.port = 0;
- def->data.rdp.autoport = 1;
- }
-
- if ((autoport = virXMLPropString(node, "autoport")) != NULL) {
- if (STREQ(autoport, "yes")) {
- if (flags & VIR_DOMAIN_XML_INACTIVE)
- def->data.rdp.port = 0;
- def->data.rdp.autoport = 1;
- }
- VIR_FREE(autoport);
- }
-
if ((replaceUser = virXMLPropString(node, "replaceUser")) != NULL) {
if (STREQ(replaceUser, "yes")) {
def->data.rdp.replaceUser = 1;
@@ -4141,11 +4325,6 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
VIR_FREE(multiUser);
}
- def->data.rdp.listenAddr = virXMLPropString(node, "listen");
-
- if (def->data.rdp.listenAddr &&
- !def->data.rdp.listenAddr[0])
- VIR_FREE(def->data.rdp.listenAddr);
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP) {
char *fullscreen = virXMLPropString(node, "fullscreen");
@@ -4167,53 +4346,9 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
def->data.desktop.display = virXMLPropString(node, "display");
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
xmlNodePtr cur;
- char *port = virXMLPropString(node, "port");
- char *tlsPort;
- char *autoport;
- if (port) {
- if (virStrToLong_i(port, NULL, 10, &def->data.spice.port) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse spice port %s"), port);
- VIR_FREE(port);
- goto error;
- }
- VIR_FREE(port);
- } else {
- def->data.spice.port = 5900;
- }
-
- tlsPort = virXMLPropString(node, "tlsPort");
- if (tlsPort) {
- if (virStrToLong_i(tlsPort, NULL, 10, &def->data.spice.tlsPort) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse spice tlsPort %s"), tlsPort);
- VIR_FREE(tlsPort);
- goto error;
- }
- VIR_FREE(tlsPort);
- } else {
- def->data.spice.tlsPort = 0;
- }
-
- if ((autoport = virXMLPropString(node, "autoport")) != NULL) {
- if (STREQ(autoport, "yes")) {
- if (flags & VIR_DOMAIN_XML_INACTIVE) {
- def->data.spice.port = 0;
- def->data.spice.tlsPort = 0;
- }
- def->data.spice.autoport = 1;
- }
- VIR_FREE(autoport);
- }
-
- def->data.spice.listenAddr = virXMLPropString(node, "listen");
def->data.spice.keymap = virXMLPropString(node, "keymap");
- if (def->data.spice.listenAddr &&
- !def->data.spice.listenAddr[0])
- VIR_FREE(def->data.spice.listenAddr);
-
if (virDomainGraphicsAuthDefParseXML(node, &def->data.spice.auth,
def->type) < 0)
goto error;
@@ -4387,7 +4522,13 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
cleanup:
VIR_FREE(type);
+ VIR_FREE(listenNodes);
+ VIR_FREE(port);
+ VIR_FREE(tlsPort);
+ VIR_FREE(autoport);
+ VIR_FREE(listenAddr);
+ ctxt->node = save;
return def;
error:
@@ -5256,7 +5397,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "graphics")) {
dev->type = VIR_DOMAIN_DEVICE_GRAPHICS;
- if (!(dev->data.graphics = virDomainGraphicsDefParseXML(node, flags)))
+ if (!(dev->data.graphics = virDomainGraphicsDefParseXML(node, ctxt, flags)))
goto error;
} else {
virDomainReportError(VIR_ERR_XML_ERROR,
@@ -6505,6 +6646,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
goto no_memory;
for (i = 0 ; i < n ; i++) {
virDomainGraphicsDefPtr graphics = virDomainGraphicsDefParseXML(nodes[i],
+ ctxt,
flags);
if (!graphics)
goto error;
@@ -9411,12 +9553,61 @@ virDomainGraphicsAuthDefFormatAttr(virBufferPtr buf,
virDomainGraphicsAuthConnectedTypeToString(def->connected));
}
+
+static void
+virDomainGraphicsListenDefFormat(virBufferPtr buf,
+ virDomainGraphicsListenDefPtr def,
+ enum virDomainGraphicsType graphicsType,
+ unsigned int flags)
+{
+ virBufferAddLit(buf, " <listen");
+
+ if (def->type) {
+ virBufferAsprintf(buf, " type='%s'",
+ virDomainGraphicsListenTypeToString(def->type));
+ }
+
+ if (def->address &&
+ ((def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS)
+ || !(flags & VIR_DOMAIN_XML_INACTIVE))) {
+ /* address may also be set to show current status when type='network',
+ * but we don't want to print that if INACTIVE data is requested. */
+ virBufferAsprintf(buf, " address='%s'", def->address);
+ }
+
+ if (def->network &&
+ (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK)) {
+ virBufferAsprintf(buf, " network='%s'", def->network);
+ }
+
+ /* For VNC definitions, if the INACTIVE XML was requested and
+ * autoport is on, we don't print output the port. (Not sure why
+ * the same thing isn't done for RDP and SPICE, but the existing
+ * code that this is mimicking doesn't do it.) */
+ if (def->port &&
+ !((graphicsType == VIR_DOMAIN_GRAPHICS_TYPE_VNC) &&
+ def->autoport && (flags & VIR_DOMAIN_XML_INACTIVE))) {
+ virBufferAsprintf(buf, " port='%d'", def->port);
+ }
+ if (def->tlsPort)
+ virBufferAsprintf(buf, " tlsPort='%d'", def->tlsPort);
+ if (def->autoport)
+ virBufferAddLit(buf, " autoport='yes'");
+
+ virBufferAddLit(buf, "/>\n");
+}
+
+
static int
virDomainGraphicsDefFormat(virBufferPtr buf,
virDomainGraphicsDefPtr def,
unsigned int flags)
{
const char *type = virDomainGraphicsTypeToString(def->type);
+ int port = virDomainGraphicsListenGetPort(def, 0);
+ int tlsPort = virDomainGraphicsListenGetTlsPort(def, 0);
+ bool autoport = virDomainGraphicsListenGetAutoport(def, 0);
+ const char *listenAddr = virDomainGraphicsListenGetAddress(def, 0);
int children = 0;
int i;
@@ -9435,19 +9626,15 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " socket='%s'",
def->data.vnc.socket);
} else {
- if (def->data.vnc.port &&
- (!def->data.vnc.autoport || !(flags & VIR_DOMAIN_XML_INACTIVE)))
- virBufferAsprintf(buf, " port='%d'",
- def->data.vnc.port);
- else if (def->data.vnc.autoport)
+ if (port && !(autoport && (flags & VIR_DOMAIN_XML_INACTIVE)))
+ virBufferAsprintf(buf, " port='%d'", port);
+ else if (autoport)
virBufferAddLit(buf, " port='-1'");
- virBufferAsprintf(buf, " autoport='%s'",
- def->data.vnc.autoport ? "yes" : "no");
+ virBufferAsprintf(buf, " autoport='%s'", autoport ? "yes" : "no");
- if (def->data.vnc.listenAddr)
- virBufferAsprintf(buf, " listen='%s'",
- def->data.vnc.listenAddr);
+ if (listenAddr)
+ virBufferAsprintf(buf, " listen='%s'", listenAddr);
}
if (def->data.vnc.keymap)
@@ -9471,13 +9658,12 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
break;
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
- if (def->data.rdp.port)
- virBufferAsprintf(buf, " port='%d'",
- def->data.rdp.port);
- else if (def->data.rdp.autoport)
+ if (port)
+ virBufferAsprintf(buf, " port='%d'", port);
+ else if (autoport)
virBufferAddLit(buf, " port='0'");
- if (def->data.rdp.autoport)
+ if (autoport)
virBufferAsprintf(buf, " autoport='yes'");
if (def->data.rdp.replaceUser)
@@ -9486,8 +9672,8 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
if (def->data.rdp.multiUser)
virBufferAsprintf(buf, " multiUser='yes'");
- if (def->data.rdp.listenAddr)
- virBufferAsprintf(buf, " listen='%s'", def->data.rdp.listenAddr);
+ if (listenAddr)
+ virBufferAsprintf(buf, " listen='%s'", listenAddr);
break;
@@ -9502,20 +9688,17 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
break;
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
- if (def->data.spice.port)
- virBufferAsprintf(buf, " port='%d'",
- def->data.spice.port);
+ if (port)
+ virBufferAsprintf(buf, " port='%d'", port);
- if (def->data.spice.tlsPort)
- virBufferAsprintf(buf, " tlsPort='%d'",
- def->data.spice.tlsPort);
+ if (tlsPort)
+ virBufferAsprintf(buf, " tlsPort='%d'", tlsPort);
virBufferAsprintf(buf, " autoport='%s'",
- def->data.spice.autoport ? "yes" : "no");
+ autoport ? "yes" : "no");
- if (def->data.spice.listenAddr)
- virBufferAsprintf(buf, " listen='%s'",
- def->data.spice.listenAddr);
+ if (listenAddr)
+ virBufferAsprintf(buf, " listen='%s'", listenAddr);
if (def->data.spice.keymap)
virBufferEscapeString(buf, " keymap='%s'",
@@ -9526,6 +9709,17 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
}
+ if ((def->nListens > 0) && def->listens) {
+ int ii;
+ for (ii = 0; ii < def->nListens; ii++) {
+ if (!children) {
+ virBufferAddLit(buf, ">\n");
+ children = 1;
+ }
+ virDomainGraphicsListenDefFormat(buf, &def->listens[ii], def->type, flags);
+ }
+ }
+
if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
for (i = 0 ; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST ; i++) {
int mode = def->data.spice.channels[i];
@@ -11383,3 +11577,230 @@ virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface)
return NULL;
return iface->data.network.actual->data.direct.virtPortProfile;
}
+
+/* Return listens[ii] from the appropriate union for the graphics
+ * type, or NULL if this is an unsuitable type, or the index is out of
+ * bounds. If force0 is TRUE, ii == 0, and there is no listen array,
+ * allocate one with a single item. */
+static virDomainGraphicsListenDefPtr
+virDomainGraphicsGetListen(virDomainGraphicsDefPtr def, size_t ii, bool force0)
+{
+ if ((def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) ||
+ (def->type == VIR_DOMAIN_GRAPHICS_TYPE_RDP) ||
+ (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)) {
+
+ if (!def->listens && (ii == 0) && force0) {
+ if (VIR_ALLOC(def->listens) < 0)
+ virReportOOMError();
+ else
+ def->nListens = 1;
+ }
+
+ if (!def->listens || (def->nListens <= ii))
+ return NULL;
+
+ return &def->listens[ii];
+ }
+
+ /* it's a type that has no listens array */
+ return NULL;
+}
+
+/* Access functions for the fields in a virDomainGraphicsDef's
+ * "listens" array.
+ *
+ * NB: For simple backward compatibility with existing code, any of
+ * the "Set" functions will auto-create listens[0] to store the new
+ * setting, when necessary. Auto-creation beyond the first item is not
+ * supported.
+ *
+ * Return values: All "Get" functions return the requested item, or
+ * 0/NULL. (in the case of returned const char *, the caller should
+ * make a copy if they want to keep it around). All "Set" functions
+ * return 0 on success, -1 on failure. */
+
+bool
+virDomainGraphicsListenGetAutoport(virDomainGraphicsDefPtr def, size_t ii)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, false);
+
+ if (!listenInfo)
+ return false;
+ return listenInfo->autoport;
+}
+
+
+int
+virDomainGraphicsListenSetAutoport(virDomainGraphicsDefPtr def, size_t ii, bool val)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, true);
+
+ if (!listenInfo)
+ return -1;
+ listenInfo->autoport = val;
+ return 0;
+}
+
+
+int
+virDomainGraphicsListenGetPort(virDomainGraphicsDefPtr def, size_t ii)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, false);
+
+ if (!listenInfo)
+ return 0;
+ return listenInfo->port;
+}
+
+
+int
+virDomainGraphicsListenSetPort(virDomainGraphicsDefPtr def, size_t ii, int val)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, true);
+
+ if (!listenInfo)
+ return -1;
+ listenInfo->port = val;
+ return 0;
+}
+
+
+int
+virDomainGraphicsListenGetTlsPort(virDomainGraphicsDefPtr def, size_t ii)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, false);
+
+ if (!listenInfo || (def->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE))
+ return 0;
+ return listenInfo->tlsPort;
+}
+
+
+int
+virDomainGraphicsListenSetTlsPort(virDomainGraphicsDefPtr def, size_t ii, int val)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, true);
+
+ if (!listenInfo || (def->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE))
+ return -1;
+ listenInfo->tlsPort = val;
+ return 0;
+}
+
+
+int
+virDomainGraphicsListenGetType(virDomainGraphicsDefPtr def, size_t ii)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, false);
+
+ if (!listenInfo)
+ return VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_DEFAULT;
+ return listenInfo->type;
+}
+
+
+/* NB: This function assumes type has not previously been set. It
+ * *will not* free any existing address or network based on a change
+ * in value of type. */
+int
+virDomainGraphicsListenSetType(virDomainGraphicsDefPtr def, size_t ii, int val)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, true);
+
+ if (!listenInfo)
+ return -1;
+ listenInfo->type = val;
+ return 0;
+}
+
+
+const char *
+virDomainGraphicsListenGetAddress(virDomainGraphicsDefPtr def, size_t ii)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, false);
+
+ if (!listenInfo ||
+ (listenInfo->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS))
+ return NULL;
+ return listenInfo->address;
+}
+
+
+/* Make a copy of up to len characters of address, and store it in
+ * listens[ii].address */
+int
+virDomainGraphicsListenSetAddress(virDomainGraphicsDefPtr def,
+ size_t ii, const char *address, int len)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, true);
+
+ if (!listenInfo)
+ return -1;
+
+ listenInfo->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS;
+
+ if (!address) {
+ listenInfo->address = NULL;
+ return 0;
+ }
+
+ listenInfo->address = (len == -1) ? strdup(address) : strndup(address, len);
+ if (!listenInfo->address) {
+ virReportOOMError();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+const char *
+virDomainGraphicsListenGetNetwork(virDomainGraphicsDefPtr def, size_t ii)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, false);
+
+ if (!listenInfo ||
+ (listenInfo->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK))
+ return NULL;
+ return listenInfo->network;
+}
+
+
+/* Make a copy of up to len characters of address, and store it in
+ * listens[ii].network */
+int
+virDomainGraphicsListenSetNetwork(virDomainGraphicsDefPtr def,
+ size_t ii, const char *network, int len)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, true);
+
+ if (!listenInfo)
+ return -1;
+
+ listenInfo->type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK;
+
+ if (!network) {
+ listenInfo->network = NULL;
+ return 0;
+ }
+
+ listenInfo->network = (len == -1) ? strdup(network) : strndup(network, len);
+ if (!listenInfo->network) {
+ virReportOOMError();
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 212f0c5..1f3f92e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -760,15 +760,31 @@ enum virDomainGraphicsSpiceClipboardCopypaste {
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_LAST
};
+enum virDomainGraphicsListenType {
+ VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_DEFAULT = 0,
+ VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS,
+ VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK,
+
+ VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST,
+};
+
+typedef struct _virDomainGraphicsListenDef virDomainGraphicsListenDef;
+typedef virDomainGraphicsListenDef *virDomainGraphicsListenDefPtr;
+struct _virDomainGraphicsListenDef {
+ int type; /* enum virDomainGraphicsListenType */
+ char *address;
+ char *network;
+ int port;
+ int tlsPort;
+ bool autoport;
+};
+
typedef struct _virDomainGraphicsDef virDomainGraphicsDef;
typedef virDomainGraphicsDef *virDomainGraphicsDefPtr;
struct _virDomainGraphicsDef {
int type;
union {
struct {
- int port;
- unsigned int autoport :1;
- char *listenAddr;
char *keymap;
char *socket;
virDomainGraphicsAuthDef auth;
@@ -779,9 +795,6 @@ struct _virDomainGraphicsDef {
int fullscreen;
} sdl;
struct {
- int port;
- char *listenAddr;
- unsigned int autoport :1;
unsigned int replaceUser :1;
unsigned int multiUser :1;
} rdp;
@@ -790,12 +803,8 @@ struct _virDomainGraphicsDef {
unsigned int fullscreen :1;
} desktop;
struct {
- int port;
- int tlsPort;
- char *listenAddr;
char *keymap;
virDomainGraphicsAuthDef auth;
- unsigned int autoport :1;
int channels[VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST];
int image;
int jpeg;
@@ -805,6 +814,11 @@ struct _virDomainGraphicsDef {
int copypaste;
} spice;
} data;
+ /* nListens and listens are only useful if type is vnc, rdp, or
+ * spice. They've been extracted from the union only to simplify
+ * parsing code.*/
+ size_t nListens;
+ virDomainGraphicsListenDefPtr listens;
};
enum virDomainHostdevMode {
@@ -1484,6 +1498,37 @@ int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac);
int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net);
int virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac);
+bool virDomainGraphicsListenGetAutoport(virDomainGraphicsDefPtr def, size_t ii)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenSetAutoport(virDomainGraphicsDefPtr def, size_t ii,
+ bool val)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenGetPort(virDomainGraphicsDefPtr def, size_t ii)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenSetPort(virDomainGraphicsDefPtr def, size_t ii, int val)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenGetTlsPort(virDomainGraphicsDefPtr def, size_t ii)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenSetTlsPort(virDomainGraphicsDefPtr def, size_t ii,
+ int val)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenGetType(virDomainGraphicsDefPtr def, size_t ii)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenSetType(virDomainGraphicsDefPtr def, size_t ii, int val)
+ ATTRIBUTE_NONNULL(1);
+const char *virDomainGraphicsListenGetAddress(virDomainGraphicsDefPtr def,
+ size_t ii)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenSetAddress(virDomainGraphicsDefPtr def,
+ size_t ii, const char *address, int len)
+ ATTRIBUTE_NONNULL(1);
+const char *virDomainGraphicsListenGetNetwork(virDomainGraphicsDefPtr def,
+ size_t ii)
+ ATTRIBUTE_NONNULL(1);
+int virDomainGraphicsListenSetNetwork(virDomainGraphicsDefPtr def,
+ size_t ii, const char *network, int len)
+ ATTRIBUTE_NONNULL(1);
+
int virDomainNetGetActualType(virDomainNetDefPtr iface);
char *virDomainNetGetActualBridgeName(virDomainNetDefPtr iface);
char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface);
@@ -1644,6 +1689,7 @@ VIR_ENUM_DECL(virDomainHostdevSubsys)
VIR_ENUM_DECL(virDomainInput)
VIR_ENUM_DECL(virDomainInputBus)
VIR_ENUM_DECL(virDomainGraphics)
+VIR_ENUM_DECL(virDomainGraphicsListen)
VIR_ENUM_DECL(virDomainGraphicsAuthConnected)
VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName)
VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 853ee62..25c34ec 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -299,6 +299,18 @@ virDomainGetRootFilesystem;
virDomainGraphicsAuthConnectedTypeFromString;
virDomainGraphicsAuthConnectedTypeToString;
virDomainGraphicsDefFree;
+virDomainGraphicsListenGetAddress;
+virDomainGraphicsListenGetAutoport;
+virDomainGraphicsListenGetNetwork;
+virDomainGraphicsListenGetPort;
+virDomainGraphicsListenGetTlsPort;
+virDomainGraphicsListenGetType;
+virDomainGraphicsListenSetAddress;
+virDomainGraphicsListenSetAutoport;
+virDomainGraphicsListenSetNetwork;
+virDomainGraphicsListenSetPort;
+virDomainGraphicsListenSetTlsPort;
+virDomainGraphicsListenSetType;
virDomainGraphicsSpiceChannelModeTypeFromString;
virDomainGraphicsSpiceChannelModeTypeToString;
virDomainGraphicsSpiceChannelNameTypeFromString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f8fd4ee..4a39078 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4110,6 +4110,8 @@ qemuBuildCommandLine(virConnectPtr conn,
if ((def->ngraphics == 1) &&
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+ int port = virDomainGraphicsListenGetPort(def->graphics[0], 0);
+ const char *listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
virBuffer opt = VIR_BUFFER_INITIALIZER;
if (def->graphics[0]->data.vnc.socket ||
@@ -4125,20 +4127,20 @@ qemuBuildCommandLine(virConnectPtr conn,
def->graphics[0]->data.vnc.socket);
} else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
- const char *addr = def->graphics[0]->data.vnc.listenAddr ?
- def->graphics[0]->data.vnc.listenAddr :
- driver->vncListen;
- bool escapeAddr = strchr(addr, ':') != NULL;
+ bool escapeAddr;
+
+ if (!listenAddr)
+ listenAddr = driver->vncListen;
+
+ escapeAddr = strchr(listenAddr, ':') != NULL;
if (escapeAddr)
- virBufferAsprintf(&opt, "[%s]", addr);
+ virBufferAsprintf(&opt, "[%s]", listenAddr);
else
- virBufferAdd(&opt, addr, -1);
- virBufferAsprintf(&opt, ":%d",
- def->graphics[0]->data.vnc.port - 5900);
+ virBufferAdd(&opt, listenAddr, -1);
+ virBufferAsprintf(&opt, ":%d", port - 5900);
} else {
- virBufferAsprintf(&opt, "%d",
- def->graphics[0]->data.vnc.port - 5900);
+ virBufferAsprintf(&opt, "%d", port - 5900);
}
if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
@@ -4219,6 +4221,9 @@ qemuBuildCommandLine(virConnectPtr conn,
} else if ((def->ngraphics == 1) &&
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
virBuffer opt = VIR_BUFFER_INITIALIZER;
+ int port = virDomainGraphicsListenGetPort(def->graphics[0], 0);
+ int tlsPort = virDomainGraphicsListenGetTlsPort(def->graphics[0], 0);
+ const char *listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SPICE)) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -4226,15 +4231,15 @@ qemuBuildCommandLine(virConnectPtr conn,
goto error;
}
- virBufferAsprintf(&opt, "port=%u", def->graphics[0]->data.spice.port);
+ virBufferAsprintf(&opt, "port=%u", port);
- if (driver->spiceTLS && def->graphics[0]->data.spice.tlsPort != -1)
- virBufferAsprintf(&opt, ",tls-port=%u", def->graphics[0]->data.spice.tlsPort);
+ if (driver->spiceTLS && tlsPort != -1)
+ virBufferAsprintf(&opt, ",tls-port=%u", tlsPort);
- if (def->graphics[0]->data.spice.listenAddr)
- virBufferAsprintf(&opt, ",addr=%s", def->graphics[0]->data.spice.listenAddr);
- else if (driver->spiceListen)
- virBufferAsprintf(&opt, ",addr=%s", driver->spiceListen);
+ if (!listenAddr)
+ listenAddr = driver->spiceListen;
+ if (listenAddr)
+ virBufferAsprintf(&opt, ",addr=%s", listenAddr);
/* In the password case we set it via monitor command, to avoid
* making it visible on CLI, so there's no use of password=XXX
@@ -5976,7 +5981,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
/* -vnc unix:/some/big/path */
vnc->data.vnc.socket = strdup(val + 5);
if (!vnc->data.vnc.socket) {
- VIR_FREE(vnc);
+ virDomainGraphicsDefFree(vnc);
goto no_memory;
}
} else {
@@ -5985,34 +5990,40 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
* -vnc [2001:1:2:3:4:5:1234:1234]:4
* -vnc some.host.name:4
*/
+ int port;
char *opts;
const char *sep = ":";
+
if (val[0] == '[')
sep = "]:";
tmp = strstr(val, sep);
if (!tmp) {
- VIR_FREE(vnc);
+ virDomainGraphicsDefFree(vnc);
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("missing VNC port number in '%s'"), val);
goto error;
}
- if (virStrToLong_i(tmp+strlen(sep), &opts, 10,
- &vnc->data.vnc.port) < 0) {
- VIR_FREE(vnc);
+ if (virStrToLong_i(tmp+strlen(sep), &opts, 10, &port) < 0) {
+ virDomainGraphicsDefFree(vnc);
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse VNC port '%s'"), tmp+1);
goto error;
}
+ if (virDomainGraphicsListenSetPort(vnc, 0, port + 5900) < 0) {
+ virDomainGraphicsDefFree(vnc);
+ goto error;
+ }
+
if (val[0] == '[')
- vnc->data.vnc.listenAddr = strndup(val+1, tmp-(val+1));
+ virDomainGraphicsListenSetAddress(vnc, 0,
+ val+1, tmp-(val+1));
else
- vnc->data.vnc.listenAddr = strndup(val, tmp-val);
- if (!vnc->data.vnc.listenAddr) {
- VIR_FREE(vnc);
+ virDomainGraphicsListenSetAddress(vnc, 0,
+ val, tmp-val);
+ if (!virDomainGraphicsListenGetAddress(vnc, 0)) {
+ virDomainGraphicsDefFree(vnc);
goto no_memory;
}
- vnc->data.vnc.port += 5900;
- vnc->data.vnc.autoport = 0;
}
if (VIR_REALLOC_N(def->graphics, def->ngraphics+1) < 0) {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5df58b1..a6f7989 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4209,8 +4209,11 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
}
for (i = 0 ; i < def->ngraphics ; i++) {
if (def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
- def->graphics[i]->data.vnc.autoport)
- def->graphics[i]->data.vnc.port = QEMU_VNC_PORT_MIN;
+ virDomainGraphicsListenGetAutoport(def->graphics[i], 0) &&
+ (virDomainGraphicsListenSetPort(def->graphics[i], 0,
+ QEMU_VNC_PORT_MIN) < 0)) {
+ goto cleanup;
+ }
}
if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9746cb3..18b5164 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1052,6 +1052,9 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
virDomainGraphicsDefPtr dev)
{
virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
+ int oldPort, newPort, oldTlsPort, newTlsPort;
+ bool oldAutoport, newAutoport;
+ const char *oldListenAddr, *newListenAddr;
int ret = -1;
if (!olddev) {
@@ -1060,17 +1063,25 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
return -1;
}
+ oldAutoport = virDomainGraphicsListenGetAutoport(olddev, 0);
+ newAutoport = virDomainGraphicsListenGetAutoport(dev, 0);
+ oldPort = virDomainGraphicsListenGetPort(olddev, 0);
+ newPort = virDomainGraphicsListenGetPort(dev, 0);
+ oldTlsPort = virDomainGraphicsListenGetTlsPort(olddev, 0);
+ newTlsPort = virDomainGraphicsListenGetTlsPort(dev, 0);
+ oldListenAddr = virDomainGraphicsListenGetAddress(olddev, 0);
+ newListenAddr = virDomainGraphicsListenGetAddress(dev, 0);
+
switch (dev->type) {
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
- if ((olddev->data.vnc.autoport != dev->data.vnc.autoport) ||
- (!dev->data.vnc.autoport &&
- (olddev->data.vnc.port != dev->data.vnc.port))) {
+
+ if ((oldAutoport != newAutoport) ||
+ (!newAutoport && (oldPort != newPort))) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot change port settings on vnc graphics"));
return -1;
}
- if (STRNEQ_NULLABLE(olddev->data.vnc.listenAddr,
- dev->data.vnc.listenAddr)) {
+ if (STRNEQ_NULLABLE(oldListenAddr,newListenAddr)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot change listen address setting on vnc graphics"));
return -1;
@@ -1109,17 +1120,14 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
break;
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
- if ((olddev->data.spice.autoport != dev->data.spice.autoport) ||
- (!dev->data.spice.autoport &&
- (olddev->data.spice.port != dev->data.spice.port)) ||
- (!dev->data.spice.autoport &&
- (olddev->data.spice.tlsPort != dev->data.spice.tlsPort))) {
+ if ((oldAutoport != newAutoport) ||
+ (!newAutoport && (oldPort != newPort)) ||
+ (!newAutoport && (oldTlsPort != newTlsPort))) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot change port settings on spice graphics"));
return -1;
}
- if (STRNEQ_NULLABLE(olddev->data.spice.listenAddr,
- dev->data.spice.listenAddr)) {
+ if (STRNEQ_NULLABLE(oldListenAddr, newListenAddr)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot change listen address setting on spice graphics"));
return -1;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 9f6b372..679a957 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -196,8 +196,8 @@ qemuMigrationCookieGraphicsAlloc(struct qemud_driver *driver,
mig->type = def->type;
if (mig->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
- mig->port = def->data.vnc.port;
- listenAddr = def->data.vnc.listenAddr;
+ mig->port = virDomainGraphicsListenGetPort(def, 0);
+ listenAddr = virDomainGraphicsListenGetAddress(def, 0);
if (!listenAddr)
listenAddr = driver->vncListen;
@@ -205,12 +205,12 @@ qemuMigrationCookieGraphicsAlloc(struct qemud_driver *driver,
!(mig->tlsSubject = qemuDomainExtractTLSSubject(driver->vncTLSx509certdir)))
goto error;
} else {
- mig->port = def->data.spice.port;
+ mig->port = virDomainGraphicsListenGetPort(def, 0);
if (driver->spiceTLS)
- mig->tlsPort = def->data.spice.tlsPort;
+ mig->tlsPort = virDomainGraphicsListenGetTlsPort(def, 0);
else
mig->tlsPort = -1;
- listenAddr = def->data.spice.listenAddr;
+ listenAddr = virDomainGraphicsListenGetAddress(def, 0);
if (!listenAddr)
listenAddr = driver->spiceListen;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 646215e..29aba3a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2568,16 +2568,17 @@ int qemuProcessStart(virConnectPtr conn,
if (vm->def->ngraphics == 1) {
if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
!vm->def->graphics[0]->data.vnc.socket &&
- vm->def->graphics[0]->data.vnc.autoport) {
+ virDomainGraphicsListenGetAutoport(vm->def->graphics[0], 0)) {
int port = qemuProcessNextFreePort(driver, QEMU_VNC_PORT_MIN);
if (port < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Unable to find an unused VNC port"));
goto cleanup;
}
- vm->def->graphics[0]->data.vnc.port = port;
+ if (virDomainGraphicsListenSetPort(vm->def->graphics[0], 0, port) < 0)
+ goto cleanup;
} else if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
- vm->def->graphics[0]->data.spice.autoport) {
+ virDomainGraphicsListenGetAutoport(vm->def->graphics[0], 0)) {
int port = qemuProcessNextFreePort(driver, QEMU_VNC_PORT_MIN);
int tlsPort = -1;
if (port < 0) {
@@ -2596,8 +2597,10 @@ int qemuProcessStart(virConnectPtr conn,
}
}
- vm->def->graphics[0]->data.spice.port = port;
- vm->def->graphics[0]->data.spice.tlsPort = tlsPort;
+ if (virDomainGraphicsListenSetPort(vm->def->graphics[0], 0, port) < 0)
+ goto cleanup;
+ if (virDomainGraphicsListenSetTlsPort(vm->def->graphics[0], 0, tlsPort) < 0)
+ goto cleanup;
}
}
@@ -3098,14 +3101,17 @@ retry:
*/
if ((vm->def->ngraphics == 1) &&
vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
- vm->def->graphics[0]->data.vnc.autoport) {
- qemuProcessReturnPort(driver, vm->def->graphics[0]->data.vnc.port);
+ virDomainGraphicsListenGetAutoport(vm->def->graphics[0], 0)) {
+ qemuProcessReturnPort(driver,
+ virDomainGraphicsListenGetPort(vm->def->graphics[0], 0));
}
if ((vm->def->ngraphics == 1) &&
vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
- vm->def->graphics[0]->data.spice.autoport) {
- qemuProcessReturnPort(driver, vm->def->graphics[0]->data.spice.port);
- qemuProcessReturnPort(driver, vm->def->graphics[0]->data.spice.tlsPort);
+ virDomainGraphicsListenGetAutoport(vm->def->graphics[0], 0)) {
+ qemuProcessReturnPort(driver,
+ virDomainGraphicsListenGetPort(vm->def->graphics[0], 0));
+ qemuProcessReturnPort(driver,
+ virDomainGraphicsListenGetTlsPort(vm->def->graphics[0], 0));
}
vm->taint = 0;
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index ee0720a..553b28f 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -2461,17 +2461,27 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
char *netAddressUtf8 = NULL;
PRBool allowMultiConnection = PR_FALSE;
PRBool reuseSingleConnection = PR_FALSE;
+
+ /* We must set the graphics type before
+ * calling any of the
+ * virDomainGraphicsListen functions, as
+ * they return NULL for types that don't
+ * allow setting up listen addresses/ports. */
+ def->graphics[def->ngraphics]->type = VIR_DOMAIN_GRAPHICS_TYPE_RDP;
+
#if VBOX_API_VERSION < 3001
PRUint32 VRDPport = 0;
VRDxServer->vtbl->GetPort(VRDxServer, &VRDPport);
if (VRDPport) {
- def->graphics[def->ngraphics]->data.rdp.port = VRDPport;
+ virDomainGraphicsListenSetPort(def->graphics[def->ngraphics],
+ 0, VRDPport);
#elif VBOX_API_VERSION < 4000 /* 3001 <= VBOX_API_VERSION < 4000 */
PRUnichar *VRDPport = NULL;
VRDxServer->vtbl->GetPorts(VRDxServer, &VRDPport);
if (VRDPport) {
/* even if vbox supports mutilpe ports, single port for now here */
- def->graphics[def->ngraphics]->data.rdp.port = PRUnicharToInt(VRDPport);
+ virDomainGraphicsListenSetPort(def->graphics[def->ngraphics], 0,
+ PRUnicharToInt(VRDPport));
VBOX_UTF16_FREE(VRDPport);
#else /* VBOX_API_VERSION >= 4000 */
PRUnichar *VRDEPortsKey = NULL;
@@ -2481,15 +2491,14 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
VBOX_UTF16_FREE(VRDEPortsKey);
if (VRDEPortsValue) {
/* even if vbox supports mutilpe ports, single port for now here */
- def->graphics[def->ngraphics]->data.rdp.port = PRUnicharToInt(VRDEPortsValue);
+ virDomainGraphicsListenSetPort(def->graphics[def->ngraphics], 0,
+ PRUnicharToInt(VRDEPortsValue));
VBOX_UTF16_FREE(VRDEPortsValue);
#endif /* VBOX_API_VERSION >= 4000 */
} else {
- def->graphics[def->ngraphics]->data.rdp.autoport = 1;
+ virDomainGraphicsListenSetAutoport(def->graphics[def->ngraphics], 0, true);
}
- def->graphics[def->ngraphics]->type = VIR_DOMAIN_GRAPHICS_TYPE_RDP;
-
#if VBOX_API_VERSION >= 4000
PRUnichar *VRDENetAddressKey = NULL;
VBOX_UTF8_TO_UTF16("TCP/Address", &VRDENetAddressKey);
@@ -2501,7 +2510,8 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
if (netAddressUtf16) {
VBOX_UTF16_TO_UTF8(netAddressUtf16, &netAddressUtf8);
if (STRNEQ(netAddressUtf8, ""))
- def->graphics[def->ngraphics]->data.rdp.listenAddr = strdup(netAddressUtf8);
+ virDomainGraphicsListenSetAddress(def->graphics[def->ngraphics], 0,
+ netAddressUtf8, -1);
VBOX_UTF16_FREE(netAddressUtf16);
VBOX_UTF8_FREE(netAddressUtf8);
}
@@ -4532,16 +4542,18 @@ vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
machine->vtbl->GetVRDEServer(machine, &VRDxServer);
#endif /* VBOX_API_VERSION >= 4000 */
if (VRDxServer) {
+ int port = virDomainGraphicsListenGetPort(def->graphics[i], 0);
+ const char *listenAddr
+ = virDomainGraphicsListenGetAddress(def->graphics[i], 0);
+
VRDxServer->vtbl->SetEnabled(VRDxServer, PR_TRUE);
VIR_DEBUG("VRDP Support turned ON.");
#if VBOX_API_VERSION < 3001
- if (def->graphics[i]->data.rdp.port) {
- VRDxServer->vtbl->SetPort(VRDxServer,
- def->graphics[i]->data.rdp.port);
- VIR_DEBUG("VRDP Port changed to: %d",
- def->graphics[i]->data.rdp.port);
- } else if (def->graphics[i]->data.rdp.autoport) {
+ if (port) {
+ VRDxServer->vtbl->SetPort(VRDxServer, port);
+ VIR_DEBUG("VRDP Port changed to: %d", port);
+ } else if (virDomainGraphicsListenGetAutoport(def->graphics[i], 0)) {
/* Setting the port to 0 will reset its value to
* the default one which is 3389 currently
*/
@@ -4550,14 +4562,14 @@ vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
}
#elif VBOX_API_VERSION < 4000 /* 3001 <= VBOX_API_VERSION < 4000 */
PRUnichar *portUtf16 = NULL;
- portUtf16 = PRUnicharFromInt(def->graphics[i]->data.rdp.port);
+ portUtf16 = PRUnicharFromInt(port);
VRDxServer->vtbl->SetPorts(VRDxServer, portUtf16);
VBOX_UTF16_FREE(portUtf16);
#else /* VBOX_API_VERSION >= 4000 */
PRUnichar *VRDEPortsKey = NULL;
PRUnichar *VRDEPortsValue = NULL;
VBOX_UTF8_TO_UTF16("TCP/Ports", &VRDEPortsKey);
- VRDEPortsValue = PRUnicharFromInt(def->graphics[i]->data.rdp.port);
+ VRDEPortsValue = PRUnicharFromInt(port);
VRDxServer->vtbl->SetVRDEProperty(VRDxServer, VRDEPortsKey,
VRDEPortsValue);
VBOX_UTF16_FREE(VRDEPortsKey);
@@ -4576,14 +4588,13 @@ vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
VIR_DEBUG("VRDP set to allow multiple connection");
}
- if (def->graphics[i]->data.rdp.listenAddr) {
+ if (listenAddr) {
#if VBOX_API_VERSION >= 4000
PRUnichar *netAddressKey = NULL;
#endif
PRUnichar *netAddressUtf16 = NULL;
- VBOX_UTF8_TO_UTF16(def->graphics[i]->data.rdp.listenAddr,
- &netAddressUtf16);
+ VBOX_UTF8_TO_UTF16(listenAddr, &netAddressUtf16);
#if VBOX_API_VERSION < 4000
VRDxServer->vtbl->SetNetAddress(VRDxServer,
netAddressUtf16);
@@ -4594,7 +4605,7 @@ vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
VBOX_UTF16_FREE(netAddressKey);
#endif /* VBOX_API_VERSION >= 4000 */
VIR_DEBUG("VRDP listen address is set to: %s",
- def->graphics[i]->data.rdp.listenAddr);
+ listenAddr);
VBOX_UTF16_FREE(netAddressUtf16);
}
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index b37f03b..1ed41c8 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -1755,6 +1755,7 @@ virVMXParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def)
{
bool enabled = false;
long long port = 0;
+ char *listenAddr = NULL;
if (def == NULL || *def != NULL) {
VMX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
@@ -1780,7 +1781,7 @@ virVMXParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def)
if (virVMXGetConfigLong(conf, "RemoteDisplay.vnc.port", &port, -1,
true) < 0 ||
virVMXGetConfigString(conf, "RemoteDisplay.vnc.ip",
- &(*def)->data.vnc.listenAddr, true) < 0 ||
+ &listenAddr, true) < 0 ||
virVMXGetConfigString(conf, "RemoteDisplay.vnc.keymap",
&(*def)->data.vnc.keymap, true) < 0 ||
virVMXGetConfigString(conf, "RemoteDisplay.vnc.password",
@@ -1788,24 +1789,33 @@ virVMXParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def)
goto failure;
}
+ if (listenAddr) {
+ if (virDomainGraphicsListenSetAddress(*def, 0, listenAddr, -1) < 0)
+ goto failure;
+ VIR_FREE(listenAddr);
+ }
+
if (port < 0) {
VIR_WARN("VNC is enabled but VMX entry 'RemoteDisplay.vnc.port' "
"is missing, the VNC port is unknown");
- (*def)->data.vnc.port = 0;
- (*def)->data.vnc.autoport = 1;
+ /* port is already defaulted to 0, no need to set it */
+ if (virDomainGraphicsListenSetAutoport(*def, 0, true) < 0)
+ goto failure;
} else {
if (port < 5900 || port > 5964) {
VIR_WARN("VNC port %lld it out of [5900..5964] range", port);
}
- (*def)->data.vnc.port = port;
- (*def)->data.vnc.autoport = 0;
+ /* autoport is already defaulted to false, no need to set it */
+ if (virDomainGraphicsListenSetPort(*def, 0, port) < 0)
+ goto failure;
}
return 0;
failure:
+ VIR_FREE(listenAddr);
virDomainGraphicsDefFree(*def);
*def = NULL;
@@ -3196,6 +3206,7 @@ virVMXFormatConfig(virVMXContext *ctx, virCapsPtr caps, virDomainDefPtr def,
int
virVMXFormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer)
{
+ const char *listenAddr;
if (def->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
VMX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
return -1;
@@ -3203,22 +3214,20 @@ virVMXFormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer)
virBufferAsprintf(buffer, "RemoteDisplay.vnc.enabled = \"true\"\n");
- if (def->data.vnc.autoport) {
+ if (virDomainGraphicsListenGetAutoport(def, 0)) {
VIR_WARN("VNC autoport is enabled, but the automatically assigned "
"VNC port cannot be read back");
} else {
- if (def->data.vnc.port < 5900 || def->data.vnc.port > 5964) {
- VIR_WARN("VNC port %d it out of [5900..5964] range",
- def->data.vnc.port);
- }
+ int port = virDomainGraphicsListenGetPort(def, 0);
+ if (port < 5900 || port > 5964)
+ VIR_WARN("VNC port %d it out of [5900..5964] range", port);
- virBufferAsprintf(buffer, "RemoteDisplay.vnc.port = \"%d\"\n",
- def->data.vnc.port);
+ virBufferAsprintf(buffer, "RemoteDisplay.vnc.port = \"%d\"\n", port);
}
- if (def->data.vnc.listenAddr != NULL) {
+ if ((listenAddr = virDomainGraphicsListenGetAddress(def, 0))) {
virBufferAsprintf(buffer, "RemoteDisplay.vnc.ip = \"%s\"\n",
- def->data.vnc.listenAddr);
+ listenAddr);
}
if (def->data.vnc.keymap != NULL) {
diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c
index 4245a64..610119a 100644
--- a/src/xenxs/xen_sxpr.c
+++ b/src/xenxs/xen_sxpr.c
@@ -745,13 +745,17 @@ xenParseSxprGraphicsOld(virDomainDefPtr def,
if (port == -1 && xendConfigVersion < 2)
port = 5900 + def->id;
- if ((unused && STREQ(unused, "1")) || port == -1)
- graphics->data.vnc.autoport = 1;
- graphics->data.vnc.port = port;
+ if (((unused && STREQ(unused, "1")) || port == -1) &&
+ (virDomainGraphicsListenSetAutoport(graphics, 0, true) < 0)) {
+ goto error;
+ }
+
+ if (virDomainGraphicsListenSetPort(graphics, 0, port) < 0)
+ goto error;
if (listenAddr &&
- !(graphics->data.vnc.listenAddr = strdup(listenAddr)))
- goto no_memory;
+ virDomainGraphicsListenSetAddress(graphics, 0, listenAddr, -1))
+ goto error;
if (vncPasswd &&
!(graphics->data.vnc.auth.passwd = strdup(vncPasswd)))
@@ -794,6 +798,7 @@ xenParseSxprGraphicsOld(virDomainDefPtr def,
no_memory:
virReportOOMError();
+error:
virDomainGraphicsDefFree(graphics);
return -1;
}
@@ -858,16 +863,19 @@ xenParseSxprGraphicsNew(virDomainDefPtr def,
port = val;
}
- if ((unused && STREQ(unused, "1")) || port == -1)
- graphics->data.vnc.autoport = 1;
+ if (((unused && STREQ(unused, "1")) || port == -1) &&
+ (virDomainGraphicsListenSetAutoport(graphics, 0, true) < 0)) {
+ goto error;
+ }
if (port >= 0 && port < 5900)
port += 5900;
- graphics->data.vnc.port = port;
+ if (virDomainGraphicsListenSetPort(graphics, 0, port) < 0)
+ goto error;
if (listenAddr &&
- !(graphics->data.vnc.listenAddr = strdup(listenAddr)))
- goto no_memory;
+ virDomainGraphicsListenSetAddress(graphics, 0, listenAddr, -1))
+ goto error;
if (vncPasswd &&
!(graphics->data.vnc.auth.passwd = strdup(vncPasswd)))
@@ -1437,6 +1445,8 @@ static int
xenFormatSxprGraphicsNew(virDomainGraphicsDefPtr def,
virBufferPtr buf)
{
+ const char *listenAddr;
+
if (def->type != VIR_DOMAIN_GRAPHICS_TYPE_SDL &&
def->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
@@ -1456,15 +1466,17 @@ xenFormatSxprGraphicsNew(virDomainGraphicsDefPtr def,
virBufferAsprintf(buf, "(xauthority '%s')", def->data.sdl.xauth);
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBufferAddLit(buf, "(type vnc)");
- if (def->data.vnc.autoport) {
+ if (virDomainGraphicsListenGetAutoport(def, 0)) {
virBufferAddLit(buf, "(vncunused 1)");
} else {
virBufferAddLit(buf, "(vncunused 0)");
- virBufferAsprintf(buf, "(vncdisplay %d)", def->data.vnc.port-5900);
+ virBufferAsprintf(buf, "(vncdisplay %d)",
+ virDomainGraphicsListenGetPort(def, 0) - 5900);
}
- if (def->data.vnc.listenAddr)
- virBufferAsprintf(buf, "(vnclisten '%s')", def->data.vnc.listenAddr);
+ listenAddr = virDomainGraphicsListenGetAddress(def, 0);
+ if (listenAddr)
+ virBufferAsprintf(buf, "(vnclisten '%s')", listenAddr);
if (def->data.vnc.auth.passwd)
virBufferAsprintf(buf, "(vncpasswd '%s')", def->data.vnc.auth.passwd);
if (def->data.vnc.keymap)
@@ -1482,6 +1494,8 @@ xenFormatSxprGraphicsOld(virDomainGraphicsDefPtr def,
virBufferPtr buf,
int xendConfigVersion)
{
+ const char *listenAddr;
+
if (def->type != VIR_DOMAIN_GRAPHICS_TYPE_SDL &&
def->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
@@ -1499,15 +1513,17 @@ xenFormatSxprGraphicsOld(virDomainGraphicsDefPtr def,
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBufferAddLit(buf, "(vnc 1)");
if (xendConfigVersion >= 2) {
- if (def->data.vnc.autoport) {
+ if (virDomainGraphicsListenGetAutoport(def, 0)) {
virBufferAddLit(buf, "(vncunused 1)");
} else {
virBufferAddLit(buf, "(vncunused 0)");
- virBufferAsprintf(buf, "(vncdisplay %d)", def->data.vnc.port-5900);
+ virBufferAsprintf(buf, "(vncdisplay %d)",
+ virDomainGraphicsListenGetPort(def, 0) - 5900);
}
- if (def->data.vnc.listenAddr)
- virBufferAsprintf(buf, "(vnclisten '%s')", def->data.vnc.listenAddr);
+ listenAddr = virDomainGraphicsListenGetAddress(def, 0);
+ if (listenAddr)
+ virBufferAsprintf(buf, "(vnclisten '%s')", listenAddr);
if (def->data.vnc.auth.passwd)
virBufferAsprintf(buf, "(vncpasswd '%s')", def->data.vnc.auth.passwd);
if (def->data.vnc.keymap)
diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
index 0ad2179..0951647 100644
--- a/src/xenxs/xen_xm.c
+++ b/src/xenxs/xen_xm.c
@@ -213,6 +213,7 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
int vmlocaltime = 0;
unsigned long count;
char *script = NULL;
+ char *listenAddr = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -852,16 +853,27 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
if (xenXMConfigGetBool(conf, "vncunused", &val, 1) < 0)
goto cleanup;
- graphics->data.vnc.autoport = val ? 1 : 0;
+ if (virDomainGraphicsListenSetAutoport(graphics, 0, val) < 0)
+ goto cleanup;
- if (!graphics->data.vnc.autoport) {
+ if (!virDomainGraphicsListenGetAutoport(graphics, 0)) {
unsigned long vncdisplay;
if (xenXMConfigGetULong(conf, "vncdisplay", &vncdisplay, 0) < 0)
goto cleanup;
- graphics->data.vnc.port = (int)vncdisplay + 5900;
+ if (virDomainGraphicsListenSetPort(graphics, 0,
+ (int)vncdisplay + 5900) < 0)
+ goto cleanup;
}
- if (xenXMConfigCopyStringOpt(conf, "vnclisten", &graphics->data.vnc.listenAddr) < 0)
+
+ if (xenXMConfigCopyStringOpt(conf, "vnclisten", &listenAddr) < 0)
goto cleanup;
+ if (listenAddr &&
+ virDomainGraphicsListenSetAddress(graphics, 0,
+ listenAddr, -1) < 0) {
+ goto cleanup;
+ }
+ VIR_FREE(listenAddr);
+
if (xenXMConfigCopyStringOpt(conf, "vncpasswd", &graphics->data.vnc.auth.passwd) < 0)
goto cleanup;
if (xenXMConfigCopyStringOpt(conf, "keymap", &graphics->data.vnc.keymap) < 0)
@@ -928,11 +940,15 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
if (STRPREFIX(key, "vncunused=")) {
- if (STREQ(key + 10, "1"))
- graphics->data.vnc.autoport = 1;
+ if (STREQ(key + 10, "1") &&
+ (virDomainGraphicsListenSetAutoport(graphics,
+ 0, true) < 0)) {
+ goto cleanup;
+ }
} else if (STRPREFIX(key, "vnclisten=")) {
- if (!(graphics->data.vnc.listenAddr = strdup(key + 10)))
- goto no_memory;
+ if (virDomainGraphicsListenSetAddress(graphics, 0,
+ key+10, -1) < 0)
+ goto cleanup;
} else if (STRPREFIX(key, "vncpasswd=")) {
if (!(graphics->data.vnc.auth.passwd = strdup(key + 10)))
goto no_memory;
@@ -940,7 +956,10 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
if (!(graphics->data.vnc.keymap = strdup(key + 7)))
goto no_memory;
} else if (STRPREFIX(key, "vncdisplay=")) {
- graphics->data.vnc.port = strtol(key+11, NULL, 10) + 5900;
+ int port = strtol(key+11, NULL, 10) + 5900;
+ if (virDomainGraphicsListenSetPort(graphics, 0,
+ port) < 0)
+ goto cleanup;
}
} else {
if (STRPREFIX(key, "display=")) {
@@ -1067,6 +1086,7 @@ cleanup:
virDomainDiskDefFree(disk);
virDomainDefFree(def);
VIR_FREE(script);
+ VIR_FREE(listenAddr);
return NULL;
}
@@ -1646,21 +1666,29 @@ virConfPtr xenFormatXM(virConnectPtr conn,
def->graphics[0]->data.sdl.xauth) < 0)
goto no_memory;
} else {
+ int autoport;
+ int port;
+ const char *listenAddr;
+
if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
goto no_memory;
- if (xenXMConfigSetInt(conf, "vncunused",
- def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
+
+ autoport = virDomainGraphicsListenGetAutoport(def->graphics[0], 0) ? 1 : 0;
+ if (xenXMConfigSetInt(conf, "vncunused", autoport) < 0)
goto no_memory;
- if (!def->graphics[0]->data.vnc.autoport &&
- xenXMConfigSetInt(conf, "vncdisplay",
- def->graphics[0]->data.vnc.port - 5900) < 0)
+
+ port = virDomainGraphicsListenGetPort(def->graphics[0], 0);
+ if (!autoport &&
+ xenXMConfigSetInt(conf, "vncdisplay", port - 5900) < 0)
goto no_memory;
- if (def->graphics[0]->data.vnc.listenAddr &&
- xenXMConfigSetString(conf, "vnclisten",
- def->graphics[0]->data.vnc.listenAddr) < 0)
+
+ listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
+ if (listenAddr &&
+ xenXMConfigSetString(conf, "vnclisten", listenAddr) < 0)
goto no_memory;
+
if (def->graphics[0]->data.vnc.auth.passwd &&
xenXMConfigSetString(conf, "vncpasswd",
def->graphics[0]->data.vnc.auth.passwd) < 0)
@@ -1683,15 +1711,16 @@ virConfPtr xenFormatXM(virConnectPtr conn,
virBufferAsprintf(&buf, ",xauthority=%s",
def->graphics[0]->data.sdl.xauth);
} else {
+ bool autoport = virDomainGraphicsListenGetAutoport(def->graphics[0], 0);
+ int port = virDomainGraphicsListenGetPort(def->graphics[0], 0);
+ const char *listenAddr
+ = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
virBufferAddLit(&buf, "type=vnc");
- virBufferAsprintf(&buf, ",vncunused=%d",
- def->graphics[0]->data.vnc.autoport ? 1 : 0);
- if (!def->graphics[0]->data.vnc.autoport)
- virBufferAsprintf(&buf, ",vncdisplay=%d",
- def->graphics[0]->data.vnc.port - 5900);
- if (def->graphics[0]->data.vnc.listenAddr)
- virBufferAsprintf(&buf, ",vnclisten=%s",
- def->graphics[0]->data.vnc.listenAddr);
+ virBufferAsprintf(&buf, ",vncunused=%d", autoport ? 1 : 0);
+ if (!autoport)
+ virBufferAsprintf(&buf, ",vncdisplay=%d", port - 5900);
+ if (listenAddr)
+ virBufferAsprintf(&buf, ",vnclisten=%s", listenAddr);
if (def->graphics[0]->data.vnc.auth.passwd)
virBufferAsprintf(&buf, ",vncpasswd=%s",
def->graphics[0]->data.vnc.auth.passwd);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-listen-network.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-listen-network.xml
new file mode 100644
index 0000000..0d17fde
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-listen-network.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>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' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='5903' autoport='no'>
+ <listen type='network' network='Bobsnetwork' port='5903'/>
+ </graphics>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-listen-network2.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-listen-network2.xml
new file mode 100644
index 0000000..7239699
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-listen-network2.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>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' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc'>
+ <listen type='address' address='1.2.3.4' autoport='yes'/>
+ <listen type='network' network='Bobsnetwork' port='5903'/>
+ </graphics>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml
index 64a6890..cb0a389 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-compression.xml
@@ -22,6 +22,7 @@
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
<graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1' port='5903' tlsPort='5904'/>
<image compression='auto_glz'/>
<jpeg compression='auto'/>
<zlib compression='auto'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
index a38550c..e338c20 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-qxl-vga.xml
@@ -22,6 +22,7 @@
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
<graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1' port='5903' tlsPort='5904'/>
<channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/>
</graphics>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml
index 6389de5..dbba1c3 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml
@@ -71,7 +71,9 @@
</console>
<input type='tablet' bus='usb'/>
<input type='mouse' bus='ps2'/>
- <graphics type='spice' port='5900' autoport='no' passwd='sercet' passwdValidTo='2011-05-31T16:11:22' connected='disconnect'/>
+ <graphics type='spice' port='5900' autoport='no' passwd='sercet' passwdValidTo='2011-05-31T16:11:22' connected='disconnect'>
+ <listen port='5900'/>
+ </graphics>
<sound model='ac97'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</sound>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
index 79780c6..ba3103f 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
@@ -22,6 +22,7 @@
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
<graphics type='spice' port='5903' tlsPort='5904' autoport='no' listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1' port='5903' tlsPort='5904'/>
<channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/>
<image compression='auto_glz'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml
index eb6be7d..0099d02 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml
@@ -21,7 +21,9 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/>
+ <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1' port='5903'/>
+ </graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml
index eb6be7d..0099d02 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml
@@ -21,7 +21,9 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/>
+ <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1' port='5903'/>
+ </graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
index 6304104..5bd22c1 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
@@ -21,7 +21,9 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' listen='2001:1:2:3:4:5:1234:1234'/>
+ <graphics type='vnc' port='5903' autoport='no' listen='2001:1:2:3:4:5:1234:1234'>
+ <listen type='address' address='2001:1:2:3:4:5:1234:1234' port='5903'/>
+ </graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml
index 8a5fcd7..534ec05 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml
@@ -21,7 +21,9 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/>
+ <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1' port='5903'/>
+ </graphics>
<video>
<model type='xen' vram='4096' heads='1'/>
</video>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-listen-network2.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-listen-network2.xml
new file mode 100644
index 0000000..c9cdd9c
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-listen-network2.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>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' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='1.2.3.4'>
+ <listen type='address' address='1.2.3.4' autoport='yes'/>
+ <listen type='network' network='Bobsnetwork' port='5903'/>
+ </graphics>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index f1900c5..44737d4 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -139,6 +139,7 @@ mymain(void)
DO_TEST("disk-drive-cache-v1-wb");
DO_TEST("disk-drive-cache-v1-none");
DO_TEST("disk-scsi-device");
+ DO_TEST("graphics-listen-network");
DO_TEST("graphics-vnc");
DO_TEST("graphics-vnc-sasl");
DO_TEST("graphics-vnc-tls");
@@ -194,6 +195,7 @@ mymain(void)
DO_TEST_DIFFERENT("disk-scsi-device-auto");
DO_TEST_DIFFERENT("console-virtio");
DO_TEST_DIFFERENT("serial-target-port-auto");
+ DO_TEST_DIFFERENT("graphics-listen-network2");
virCapabilitiesFree(driver.caps);
diff --git a/tests/sexpr2xmldata/sexpr2xml-curmem.xml b/tests/sexpr2xmldata/sexpr2xml-curmem.xml
index 6be4d5d..1fef2c3 100644
--- a/tests/sexpr2xmldata/sexpr2xml-curmem.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-curmem.xml
@@ -31,6 +31,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='-1' autoport='yes'/>
+ <graphics type='vnc' port='-1' autoport='yes'>
+ <listen port='-1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml b/tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml
index 3f501e7..1bf0423 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml
@@ -43,6 +43,8 @@
</console>
<input type='tablet' bus='usb'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5925' autoport='yes' keymap='en-us'/>
+ <graphics type='vnc' port='5925' autoport='yes' keymap='en-us'>
+ <listen port='5925' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml b/tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml
index d0ead27..d0e17af 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml
@@ -39,6 +39,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml b/tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml
index 9e6deae..f367ce1 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml
@@ -39,6 +39,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml b/tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml
index da3b3ae..aadfd6e 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml
@@ -36,6 +36,8 @@
<target dev='vif3.0'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml b/tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml
index 4dc218f..48c56ed 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml
@@ -37,6 +37,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml b/tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml
index 57b8d27..c814d48 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml
@@ -37,6 +37,8 @@
<model type='netfront'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml b/tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml
index e39b638..cd63402 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml
@@ -41,6 +41,8 @@
<target port='0'/>
</parallel>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.xml
index 5e085f9..2ec86ad 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2-ports.xml
@@ -48,6 +48,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.xml
index 5619376..7c60c2c 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-dev-2nd-port.xml
@@ -44,6 +44,8 @@
<target type='serial' port='1'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml
index db010ad..17a426f 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml
@@ -44,6 +44,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml
index faeed77..075cfae 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml
@@ -42,6 +42,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml
index 0967ac7..13528b0 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml
@@ -44,6 +44,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml
index 3773d3b..b251501 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml
@@ -42,6 +42,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml
index d46df09..c0d92f3 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml
@@ -42,6 +42,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp-telnet.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp-telnet.xml
index 34f25ac..d3c5965 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp-telnet.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp-telnet.xml
@@ -46,6 +46,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml
index 6c69214..0fa52e8 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml
@@ -46,6 +46,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml
index bcc20dd..6dcbc15 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml
@@ -46,6 +46,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml b/tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml
index 93f20fa..be4562a 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml
@@ -44,6 +44,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5901' autoport='no'/>
+ <graphics type='vnc' port='5901' autoport='no'>
+ <listen port='5901'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml b/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml
index 1635584..4b97715 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml
@@ -36,7 +36,9 @@
<target dev='vif3.0'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
<sound model='sb16'/>
<sound model='es1370'/>
</devices>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-sound.xml b/tests/sexpr2xmldata/sexpr2xml-fv-sound.xml
index 1635584..4b97715 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-sound.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-sound.xml
@@ -36,7 +36,9 @@
<target dev='vif3.0'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
<sound model='sb16'/>
<sound model='es1370'/>
</devices>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml b/tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml
index 4870863..b6db288 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml
@@ -37,6 +37,8 @@
</interface>
<input type='mouse' bus='usb'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml b/tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml
index 74f4bdf..ce28666 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml
@@ -37,6 +37,8 @@
</interface>
<input type='tablet' bus='usb'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-utc.xml b/tests/sexpr2xmldata/sexpr2xml-fv-utc.xml
index 5dbc64d..10f6fed 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-utc.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-utc.xml
@@ -36,6 +36,8 @@
<target dev='vif3.0'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-v2.xml b/tests/sexpr2xmldata/sexpr2xml-fv-v2.xml
index e3c4e20..a70ff9f 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-v2.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-v2.xml
@@ -36,6 +36,8 @@
<target dev='vif3.0'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' keymap='ja'/>
+ <graphics type='vnc' port='-1' autoport='yes' keymap='ja'>
+ <listen port='-1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv.xml b/tests/sexpr2xmldata/sexpr2xml-fv.xml
index 5dbc64d..10f6fed 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv.xml
@@ -36,6 +36,8 @@
<target dev='vif3.0'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'>
+ <listen port='5903'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml b/tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml
index 5a82775..99d46f4 100644
--- a/tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml
@@ -41,6 +41,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes'/>
+ <graphics type='vnc' port='-1' autoport='yes'>
+ <listen port='-1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vfb-new-vncdisplay.xml b/tests/sexpr2xmldata/sexpr2xml-pv-vfb-new-vncdisplay.xml
index 0914bc9..c74b8f6 100644
--- a/tests/sexpr2xmldata/sexpr2xml-pv-vfb-new-vncdisplay.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vfb-new-vncdisplay.xml
@@ -24,6 +24,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='5925' autoport='no' listen='0.0.0.0' keymap='ja'/>
+ <graphics type='vnc' port='5925' autoport='no' listen='0.0.0.0' keymap='ja'>
+ <listen type='address' address='0.0.0.0' port='5925'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vfb-new.xml b/tests/sexpr2xmldata/sexpr2xml-pv-vfb-new.xml
index 0657fba..bab2c9a 100644
--- a/tests/sexpr2xmldata/sexpr2xml-pv-vfb-new.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vfb-new.xml
@@ -24,6 +24,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' keymap='ja'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' keymap='ja'>
+ <listen type='address' address='0.0.0.0' port='-1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vfb-orig.xml b/tests/sexpr2xmldata/sexpr2xml-pv-vfb-orig.xml
index 0657fba..bab2c9a 100644
--- a/tests/sexpr2xmldata/sexpr2xml-pv-vfb-orig.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vfb-orig.xml
@@ -24,6 +24,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' keymap='ja'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' keymap='ja'>
+ <listen type='address' address='0.0.0.0' port='-1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vfb-type-crash.xml b/tests/sexpr2xmldata/sexpr2xml-pv-vfb-type-crash.xml
index 766c78d..cd5af69 100644
--- a/tests/sexpr2xmldata/sexpr2xml-pv-vfb-type-crash.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-pv-vfb-type-crash.xml
@@ -29,6 +29,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='-1' autoport='yes'/>
+ <graphics type='vnc' port='-1' autoport='yes'>
+ <listen port='-1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml b/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml
index 047e034..08ab324 100644
--- a/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml
+++ b/tests/vmx2xmldata/vmx2xml-graphics-vnc.xml
@@ -12,7 +12,9 @@
<on_crash>destroy</on_crash>
<devices>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' keymap='de' passwd='password'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='de' passwd='password'>
+ <listen port='5903'/>
+ </graphics>
<video>
<model type='vmvga' vram='4096'/>
</video>
diff --git a/tests/xmconfigdata/test-escape-paths.xml b/tests/xmconfigdata/test-escape-paths.xml
index 9eaf90c..ebeb9b3 100644
--- a/tests/xmconfigdata/test-escape-paths.xml
+++ b/tests/xmconfigdata/test-escape-paths.xml
@@ -43,7 +43,9 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
<sound model='sb16'/>
<sound model='es1370'/>
</devices>
diff --git a/tests/xmconfigdata/test-fullvirt-force-hpet.xml b/tests/xmconfigdata/test-fullvirt-force-hpet.xml
index a662b97..e2e2e76 100644
--- a/tests/xmconfigdata/test-fullvirt-force-hpet.xml
+++ b/tests/xmconfigdata/test-fullvirt-force-hpet.xml
@@ -40,6 +40,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-force-nohpet.xml b/tests/xmconfigdata/test-fullvirt-force-nohpet.xml
index bcd9af6..f63ab60 100644
--- a/tests/xmconfigdata/test-fullvirt-force-nohpet.xml
+++ b/tests/xmconfigdata/test-fullvirt-force-nohpet.xml
@@ -40,6 +40,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-localtime.xml b/tests/xmconfigdata/test-fullvirt-localtime.xml
index be4f119..b89b8c4 100644
--- a/tests/xmconfigdata/test-fullvirt-localtime.xml
+++ b/tests/xmconfigdata/test-fullvirt-localtime.xml
@@ -38,6 +38,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-net-ioemu.xml b/tests/xmconfigdata/test-fullvirt-net-ioemu.xml
index 4a52a45..4c21896 100644
--- a/tests/xmconfigdata/test-fullvirt-net-ioemu.xml
+++ b/tests/xmconfigdata/test-fullvirt-net-ioemu.xml
@@ -38,6 +38,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-net-netfront.xml b/tests/xmconfigdata/test-fullvirt-net-netfront.xml
index efaf5b4..734c60b 100644
--- a/tests/xmconfigdata/test-fullvirt-net-netfront.xml
+++ b/tests/xmconfigdata/test-fullvirt-net-netfront.xml
@@ -38,6 +38,8 @@
<model type='netfront'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-new-cdrom.xml b/tests/xmconfigdata/test-fullvirt-new-cdrom.xml
index 4a52a45..4c21896 100644
--- a/tests/xmconfigdata/test-fullvirt-new-cdrom.xml
+++ b/tests/xmconfigdata/test-fullvirt-new-cdrom.xml
@@ -38,6 +38,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-old-cdrom.xml b/tests/xmconfigdata/test-fullvirt-old-cdrom.xml
index 97965d5..4a2c371 100644
--- a/tests/xmconfigdata/test-fullvirt-old-cdrom.xml
+++ b/tests/xmconfigdata/test-fullvirt-old-cdrom.xml
@@ -38,6 +38,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-parallel-tcp.xml b/tests/xmconfigdata/test-fullvirt-parallel-tcp.xml
index 22c6013..7de2515 100644
--- a/tests/xmconfigdata/test-fullvirt-parallel-tcp.xml
+++ b/tests/xmconfigdata/test-fullvirt-parallel-tcp.xml
@@ -43,6 +43,8 @@
<target port='0'/>
</parallel>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.xml b/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.xml
index be5f8ee..5b6ffc5 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-dev-2-ports.xml
@@ -50,6 +50,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.xml b/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.xml
index 03549f0..8be69e1 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-dev-2nd-port.xml
@@ -46,6 +46,8 @@
<target type='serial' port='1'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-file.xml b/tests/xmconfigdata/test-fullvirt-serial-file.xml
index 3e5aaf9..f1bcebc 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-file.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-file.xml
@@ -46,6 +46,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-null.xml b/tests/xmconfigdata/test-fullvirt-serial-null.xml
index 2fd9bf1..e7f13e1 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-null.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-null.xml
@@ -44,6 +44,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-pipe.xml b/tests/xmconfigdata/test-fullvirt-serial-pipe.xml
index 9292c25..17565c8 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-pipe.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-pipe.xml
@@ -46,6 +46,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-pty.xml b/tests/xmconfigdata/test-fullvirt-serial-pty.xml
index c4b189f..a49d6e9 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-pty.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-pty.xml
@@ -44,6 +44,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-stdio.xml b/tests/xmconfigdata/test-fullvirt-serial-stdio.xml
index 3852977..597ca69 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-stdio.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-stdio.xml
@@ -44,6 +44,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-tcp-telnet.xml b/tests/xmconfigdata/test-fullvirt-serial-tcp-telnet.xml
index 4acdfc8..41e237a 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-tcp-telnet.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-tcp-telnet.xml
@@ -48,6 +48,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-tcp.xml b/tests/xmconfigdata/test-fullvirt-serial-tcp.xml
index 48d6cb5..b28701d 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-tcp.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-tcp.xml
@@ -48,6 +48,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-udp.xml b/tests/xmconfigdata/test-fullvirt-serial-udp.xml
index 8c11b45..23e6cc1 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-udp.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-udp.xml
@@ -48,6 +48,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-serial-unix.xml b/tests/xmconfigdata/test-fullvirt-serial-unix.xml
index 3071c23..e60711b 100644
--- a/tests/xmconfigdata/test-fullvirt-serial-unix.xml
+++ b/tests/xmconfigdata/test-fullvirt-serial-unix.xml
@@ -46,6 +46,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-sound.xml b/tests/xmconfigdata/test-fullvirt-sound.xml
index f142bfc..7adaaee 100644
--- a/tests/xmconfigdata/test-fullvirt-sound.xml
+++ b/tests/xmconfigdata/test-fullvirt-sound.xml
@@ -38,7 +38,9 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
<sound model='sb16'/>
<sound model='es1370'/>
</devices>
diff --git a/tests/xmconfigdata/test-fullvirt-usbmouse.xml b/tests/xmconfigdata/test-fullvirt-usbmouse.xml
index c96e8f9..ee25495 100644
--- a/tests/xmconfigdata/test-fullvirt-usbmouse.xml
+++ b/tests/xmconfigdata/test-fullvirt-usbmouse.xml
@@ -39,6 +39,8 @@
</interface>
<input type='mouse' bus='usb'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-usbtablet-no-bus.xml b/tests/xmconfigdata/test-fullvirt-usbtablet-no-bus.xml
index 9370172..d09cfd2 100644
--- a/tests/xmconfigdata/test-fullvirt-usbtablet-no-bus.xml
+++ b/tests/xmconfigdata/test-fullvirt-usbtablet-no-bus.xml
@@ -38,6 +38,8 @@
</interface>
<input type='tablet'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-usbtablet.xml b/tests/xmconfigdata/test-fullvirt-usbtablet.xml
index b7bdfd0..6b35c37 100644
--- a/tests/xmconfigdata/test-fullvirt-usbtablet.xml
+++ b/tests/xmconfigdata/test-fullvirt-usbtablet.xml
@@ -39,6 +39,8 @@
</interface>
<input type='tablet' bus='usb'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-fullvirt-utc.xml b/tests/xmconfigdata/test-fullvirt-utc.xml
index 4a52a45..4c21896 100644
--- a/tests/xmconfigdata/test-fullvirt-utc.xml
+++ b/tests/xmconfigdata/test-fullvirt-utc.xml
@@ -38,6 +38,8 @@
<model type='e1000'/>
</interface>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-no-source-cdrom.xml b/tests/xmconfigdata/test-no-source-cdrom.xml
index a7a27d3..a074759 100644
--- a/tests/xmconfigdata/test-no-source-cdrom.xml
+++ b/tests/xmconfigdata/test-no-source-cdrom.xml
@@ -43,6 +43,8 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes'/>
+ <graphics type='vnc' port='-1' autoport='yes'>
+ <listen autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-paravirt-net-e1000.xml b/tests/xmconfigdata/test-paravirt-net-e1000.xml
index d709e69..4fd6940 100644
--- a/tests/xmconfigdata/test-paravirt-net-e1000.xml
+++ b/tests/xmconfigdata/test-paravirt-net-e1000.xml
@@ -28,6 +28,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-paravirt-net-vifname.xml b/tests/xmconfigdata/test-paravirt-net-vifname.xml
index b6c4739..9c7cb2c 100644
--- a/tests/xmconfigdata/test-paravirt-net-vifname.xml
+++ b/tests/xmconfigdata/test-paravirt-net-vifname.xml
@@ -29,6 +29,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-paravirt-new-pvfb-vncdisplay.xml b/tests/xmconfigdata/test-paravirt-new-pvfb-vncdisplay.xml
index 39325ea..6c2fe37 100644
--- a/tests/xmconfigdata/test-paravirt-new-pvfb-vncdisplay.xml
+++ b/tests/xmconfigdata/test-paravirt-new-pvfb-vncdisplay.xml
@@ -27,6 +27,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='5925' autoport='no' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='5925' autoport='no' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' port='5925'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-paravirt-new-pvfb.xml b/tests/xmconfigdata/test-paravirt-new-pvfb.xml
index 40c79cb..9c479aa 100644
--- a/tests/xmconfigdata/test-paravirt-new-pvfb.xml
+++ b/tests/xmconfigdata/test-paravirt-new-pvfb.xml
@@ -27,6 +27,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-paravirt-old-pvfb-vncdisplay.xml b/tests/xmconfigdata/test-paravirt-old-pvfb-vncdisplay.xml
index 39325ea..6c2fe37 100644
--- a/tests/xmconfigdata/test-paravirt-old-pvfb-vncdisplay.xml
+++ b/tests/xmconfigdata/test-paravirt-old-pvfb-vncdisplay.xml
@@ -27,6 +27,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='5925' autoport='no' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='5925' autoport='no' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' port='5925'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-paravirt-old-pvfb.xml b/tests/xmconfigdata/test-paravirt-old-pvfb.xml
index 40c79cb..9c479aa 100644
--- a/tests/xmconfigdata/test-paravirt-old-pvfb.xml
+++ b/tests/xmconfigdata/test-paravirt-old-pvfb.xml
@@ -27,6 +27,8 @@
<target type='xen' port='0'/>
</console>
<input type='mouse' bus='xen'/>
- <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'/>
+ <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' passwd='123poi'>
+ <listen type='address' address='127.0.0.1' autoport='yes'/>
+ </graphics>
</devices>
</domain>
diff --git a/tests/xmconfigdata/test-pci-devs.xml b/tests/xmconfigdata/test-pci-devs.xml
index 31df1c7..f823ad7 100644
--- a/tests/xmconfigdata/test-pci-devs.xml
+++ b/tests/xmconfigdata/test-pci-devs.xml
@@ -43,7 +43,9 @@
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='-1' autoport='yes'/>
+ <graphics type='vnc' port='-1' autoport='yes'>
+ <listen autoport='yes'/>
+ </graphics>
<hostdev mode='subsystem' type='pci' managed='no'>
<source>
<address domain='0x0001' bus='0x0c' slot='0x1b' function='0x2'/>
--
1.7.3.4
3
13
27 Jul '11
I am a newbie to linux and was given a task to fine out what could be wrong with the configuration of the software we are working on.
The error displayed on my screen is as capture below.Can you help me out.
ncftool> define netmask.xml
xmlXPathCompiledEval: evaluation failed
error: XSLT transformation failed
error: runtime error: file /usr/share/netcf/xml/suse-get.xsl line 204 element node
NB.
the content of my xml file is as shown bellow.What i noticed is whenever the prefix goes above 24,that is when the error comes up.but below 24 it works well.
thanks
<interface type="ethernet" name="eth5">
<start mode="onboot"/>
<mac address="00:21:28:44:E3:2B"/>
<protocol family="ipv4">
<ip address="204.10.0.25" prefix="26"/>
</protocol>
</interface>
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
"netmask.xml" 7 lines, 194 characters
Ehiwere matthew omogbai
Graduate Student,
Computer Networks Engineering.
Sweden
Private: 0046736942168
email: ehiwere(a)kth.se<mailto:ehiwere@kth.se>
MOTTO:The past is my heritage,
The present is my responsibility
The future is my challenge
"Chose to stand,not because there is no seat but because I want to be counted"
1
0
[libvirt] gnulib compiler warning detection broken on RHEL5 autoconf
by Daniel P. Berrange 27 Jul '11
by Daniel P. Berrange 27 Jul '11
27 Jul '11
I was wondering why I didn't see any compile warnings from the broken
gnutls code on RHEL5 when I noticed that we were building without any
compiler warning flags at all.
It seems configure fails on RHEL5 vintage autoconf
checking whether compiler handles -Wall... ./configure: line 75468: ${$as_gl_Warn+set}: bad substitution
I'm guessing it is the gl_WARN_ADD() macro that is at fault somehow.
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
2
6
[libvirt] [libvirt-test-API][PATCH 1/2] add remoteAccess directory and tls authentication testcase
by Guannan Ren 27 Jul '11
by Guannan Ren 27 Jul '11
27 Jul '11
---
repos/remoteAccess/tls_setup.py | 374 +++++++++++++++++++++++++++++++++++++++
1 files changed, 374 insertions(+), 0 deletions(-)
create mode 100644 repos/remoteAccess/__init__.py
create mode 100644 repos/remoteAccess/tls_setup.py
diff --git a/repos/remoteAccess/__init__.py b/repos/remoteAccess/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/repos/remoteAccess/tls_setup.py b/repos/remoteAccess/tls_setup.py
new file mode 100644
index 0000000..f703ee3
--- /dev/null
+++ b/repos/remoteAccess/tls_setup.py
@@ -0,0 +1,374 @@
+#!/usr/bin/env python
+""" Setup tls authentication between two hosts and configure libvirt
+ to use it for connection.
+ remoteAccess:tls_setup
+ target_machine
+ xx.xx.xx.xx
+ username
+ root
+ password
+ xxxxxx
+"""
+
+__author__ = 'Guannan Ren: gren(a)redhat.com'
+__date__ = 'Mon July 25, 2011'
+__version__ = '0.1.0'
+__credits__ = 'Copyright (C) 2011 Red Hat, Inc.'
+__all__ = ['usage']
+
+import os
+import re
+import sys
+import pexpect
+import string
+import commands
+import shutil
+
+def append_path(path):
+ """Append root path of package"""
+ if path in sys.path:
+ pass
+ else:
+ sys.path.append(path)
+
+pwd = os.getcwd()
+result = re.search('(.*)libvirt-test-API', pwd)
+append_path(result.group(0))
+
+from lib import connectAPI
+from utils.Python import utils
+from exception import LibvirtAPI
+
+CERTTOOL = "/usr/bin/certtool"
+CP = "/bin/cp"
+MKDIR = "/bin/mkdir"
+CA_FOLDER = "/etc/pki/CA"
+PRIVATE_KEY_FOLDER = "/etc/pki/libvirt/private"
+CERTIFICATE_FOLDER = "/etc/pki/libvirt"
+
+TEMP_TLS_FOLDER = "/tmp/libvirt_test_API_tls"
+CAKEY = os.path.join(TEMP_TLS_FOLDER, 'cakey.pem')
+CACERT = os.path.join(TEMP_TLS_FOLDER, 'cacert.pem')
+SERVERKEY = os.path.join(TEMP_TLS_FOLDER, 'serverkey.pem')
+SERVERCERT = os.path.join(TEMP_TLS_FOLDER, 'servercert.pem')
+CLIENTKEY = os.path.join(TEMP_TLS_FOLDER, 'clientkey.pem')
+CLIENTCERT = os.path.join(TEMP_TLS_FOLDER, 'clientcert.pem')
+
+def check_params(params):
+ """check out the arguments requried for migration"""
+ logger = params['logger']
+ keys = ['target_machine', 'username', 'password']
+ for key in keys:
+ if key not in params:
+ logger.error("Argument %s is required" % key)
+ return 1
+ return 0
+
+def CA_setting_up(util, logger):
+ """ setting up a Certificate Authority """
+ # Create a private key for CA
+ logger.info("generate CA certificates")
+
+ cakey_fd = open(CAKEY, 'w')
+ ret, out = util.exec_cmd([CERTTOOL, '--generate-privkey'], outfile=cakey_fd)
+ cakey_fd.close()
+ if ret != 0:
+ logger.error("failed to create CA private key")
+ return 1
+
+
+ # ca.info file
+ cainfo = os.path.join(TEMP_TLS_FOLDER, 'ca.info')
+ cainfo_fd = open(cainfo, 'w')
+ cainfo_str = "cn = Libvirt_test_API\n" + \
+ "ca\n" + \
+ "cert_signing_key\n"
+
+ cainfo_fd.write(cainfo_str)
+ cainfo_fd.close()
+
+ # Generate cacert.pem
+ cacert_args = [CERTTOOL, '--generate-self-signed', '--load-privkey', CAKEY, '--template', cainfo]
+ cacert_fd = open(CACERT, 'w')
+ ret, out = util.exec_cmd(cacert_args, outfile=cacert_fd)
+ cacert_fd.close()
+ if ret != 0:
+ logger.error("failed to create cacert.pem")
+ return 1
+
+ logger.info("done the CA certificates job")
+ return 0
+
+def tls_server_cert(target_machine, util, logger):
+ """ generating server certificates """
+ # Create tls server key
+ logger.info("generate server certificates")
+
+ serverkey_fd = open(SERVERKEY, 'w')
+ ret, out = util.exec_cmd([CERTTOOL, '--generate-privkey'], outfile=serverkey_fd)
+ serverkey_fd.close()
+ if ret != 0:
+ logger.error("failed to create server key")
+ return 1
+
+ # server.info
+ serverinfo = os.path.join(TEMP_TLS_FOLDER, 'server.info')
+ serverinfo_fd = open(serverinfo, 'w')
+ serverinfo_str = "organization = Libvirt_test_API\n" + \
+ "cn = %s\n" % target_machine + \
+ "tls_www_server\n" + \
+ "encryption_key\n" + \
+ "signing_key\n"
+
+ serverinfo_fd.write(serverinfo_str)
+ serverinfo_fd.close()
+
+ # Generate servercert.pem
+ servercert_args = [CERTTOOL,
+ '--generate-certificate',
+ '--load-privkey', SERVERKEY,
+ '--load-ca-certificate', CACERT,
+ '--load-ca-privkey', CAKEY,
+ '--template', serverinfo
+ ]
+ servercert_fd = open(SERVERCERT, 'w')
+ ret, out = util.exec_cmd(servercert_args, outfile=servercert_fd)
+ servercert_fd.close()
+ if ret != 0:
+ logger.error("failed to create servercert.pem")
+ return 1
+
+ logger.info("done the server certificates job")
+ return 0
+
+def tls_client_cert(local_machine, util, logger):
+ """ generating client certificates """
+ # Create tls client key
+ logger.info("generate client certificates")
+
+ clientkey_fd = open(CLIENTKEY, 'w')
+ ret, out = util.exec_cmd([CERTTOOL, '--generate-privkey'], outfile=clientkey_fd)
+ clientkey_fd.close()
+ if ret != 0:
+ logger.error("failed to create client key")
+ return 1
+
+ # client.info
+ clientinfo = os.path.join(TEMP_TLS_FOLDER, 'client.info')
+ clientinfo_fd = open(clientinfo, 'w')
+ clientinfo_str = "country = xxx\n" + \
+ "state = xxx\n" + \
+ "locality = xxx\n" + \
+ "organization = Libvirt_test_API\n" + \
+ "cn = %s\n" % local_machine + \
+ "tls_www_client\n" + \
+ "encryption_key\n" + \
+ "signing_key\n"
+
+ clientinfo_fd.write(clientinfo_str)
+ clientinfo_fd.close()
+
+ # Generate clientcert.pem
+ clientcert_args = [CERTTOOL,
+ '--generate-certificate',
+ '--load-privkey', CLIENTKEY,
+ '--load-ca-certificate', CACERT,
+ '--load-ca-privkey', CAKEY,
+ '--template', clientinfo,
+ ]
+
+ clientcert_fd = open(CLIENTCERT, 'w')
+ ret, out = util.exec_cmd(clientcert_args, outfile=clientcert_fd)
+ clientcert_fd.close()
+ if ret != 0:
+ logger.error("failed to create client certificates")
+ return 1
+
+ logger.info("done the client certificates job")
+ return 0
+
+def deliver_cert(target_machine, username, password, util, logger):
+ """ deliver CA, server and client certificates """
+ # transmit cacert.pem to remote host
+ logger.info("deliver CA, server and client certificates to both local and remote server")
+ ret = util.scp_file(target_machine, username, password, CA_FOLDER, CACERT)
+ if ret:
+ logger.error("scp cacert.pem to %s error" % target_machine)
+ return 1
+
+ # copy cacert.pem to local CA folder
+ cacert_cp = [CP, '-f', CACERT, CA_FOLDER]
+ ret, out = util.exec_cmd(cacert_cp)
+ if ret:
+ logger.error("copying cacert.pem to %s error" % CA_FOLDER)
+ return 1
+
+ # mkdir /etc/pki/libvirt/private on remote host
+ libvirt_priv_cmd = "mkdir -p %s" % PRIVATE_KEY_FOLDER
+ ret = util.remote_exec_pexpect(target_machine, username, password, libvirt_priv_cmd)
+ if ret:
+ logger.error("failed to make /etc/pki/libvirt/private on %s" % target_machine)
+ return 1
+
+ # transmit serverkey.pem to remote host
+ ret = util.scp_file(target_machine, username, password, PRIVATE_KEY_FOLDER, SERVERKEY)
+ if ret:
+ logger.error("failed to scp serverkey.pem to %s" % target_machine)
+ return 1
+
+ # transmit servercert.pem to remote host
+ ret = util.scp_file(target_machine, username, password, CERTIFICATE_FOLDER, SERVERCERT)
+ if ret:
+ logger.error("failed to scp servercert.pem to %s" % target_machine)
+ return 1
+
+ libvirt_priv_cmd_local = [MKDIR, '-p', PRIVATE_KEY_FOLDER]
+ ret, out = util.exec_cmd(libvirt_priv_cmd_local)
+ if ret:
+ logger.error("failed to make %s on local" % PRIVATE_KEY_FOLDER)
+ return 1
+
+ # copy clientkey.pem to local folder
+ clientkey_cp = [CP, '-f', CLIENTKEY, PRIVATE_KEY_FOLDER]
+ ret, out = util.exec_cmd(clientkey_cp)
+ if ret:
+ logger.error("failed to copy clientkey.pem to %s" % PRIVATE_KEY_FOLDER)
+ return 1
+
+ # copy clientcert.pem to local folder
+ clientcert_cp = [CP, '-f', CLIENTCERT, CERTIFICATE_FOLDER]
+ ret, out = util.exec_cmd(clientcert_cp)
+ if ret:
+ logger.error("failed to copy clientcert.pem to %s" % CERTIFICATE_FOLDER)
+ return 1
+
+ logger.info("done to delivery")
+ return 0
+
+def tls_libvirtd_set(target_machine, username, password, util, logger):
+ """ configure libvirtd.conf on tls server """
+ logger.info("setting libvirtd.conf on tls server")
+ # open libvirtd --listen option
+ listen_open_cmd = "echo 'LIBVIRTD_ARGS=\"--listen\"' >> /etc/sysconfig/libvirtd"
+ ret = util.remote_exec_pexpect(target_machine, username, password, listen_open_cmd)
+ if ret:
+ logger.error("failed to uncomment --listen in /etc/sysconfig/libvirtd")
+ return 1
+
+ listen_tcp_cmd = "echo \"listen_tcp = 1\" >> /etc/libvirt/libvirtd.conf"
+ ret = util.remote_exec_pexpect(target_machine, username, password, listen_tcp_cmd)
+ if ret:
+ logger.error("failed to uncomment listen_tcp in /etc/libvirt/libvirtd.conf")
+ return 1
+
+ # restart remote libvirtd service
+ libvirtd_restart_cmd = "service libvirtd restart"
+ ret = util.remote_exec_pexpect(target_machine, username, password, libvirtd_restart_cmd)
+ if ret:
+ logger.error("failed to restart libvirtd service")
+ return 1
+
+ logger.info("done to libvirtd configuration")
+ return 0
+
+def iptables_stop(target_machine, username, password, util, logger):
+ """ This is a temprory method in favor of migration """
+ logger.info("stop local and remote iptables temprorily")
+ iptables_stop_cmd = "service iptables stop"
+ ret = util.remote_exec_pexpect(target_machine, username, password, iptables_stop_cmd)
+ if ret:
+ logger.error("failed to stop remote iptables service")
+ return 1
+
+ iptables_stop = ["service", "iptables", "stop"]
+ ret, out = util.exec_cmd(iptables_stop)
+ if ret:
+ logger.error("failed to stop local iptables service")
+ return 1
+
+ logger.info("done the iptables stop job")
+ return 0
+
+def tls_setup(params):
+ """ generate tls certificates and configure libvirt """
+ logger = params['logger']
+ params_check_result = check_params(params)
+ if params_check_result:
+ return 1
+
+ target_machine = params['target_machine']
+ username = params['username']
+ password = params['password']
+
+ util = utils.Utils()
+ local_machine = util.get_local_hostname()
+
+ logger.info("the hostname of server is %s" % target_machine)
+ logger.info("the hostname of local machine is %s" % local_machine)
+
+ if not util.do_ping(target_machine, 0):
+ logger.error("failed to ping host %s" % target_machine)
+ return 1
+
+ if os.path.exists(TEMP_TLS_FOLDER):
+ shutil.rmtree(TEMP_TLS_FOLDER)
+
+ os.mkdir(TEMP_TLS_FOLDER)
+
+ if iptables_stop(target_machine, username, password, util, logger):
+ return 1
+
+ if CA_setting_up(util, logger):
+ return 1
+
+ if tls_server_cert(target_machine, util, logger):
+ return 1
+
+ if tls_client_cert(local_machine, util, logger):
+ return 1
+
+ if deliver_cert(target_machine, username, password, util, logger):
+ return 1
+
+ if tls_libvirtd_set(target_machine, username, password, util, logger):
+ return 1
+
+ uri = "qemu://%s/system" % target_machine
+
+ try:
+ conn = connectAPI.ConnectAPI()
+ virconn = conn.open(uri)
+ virconn.close()
+ logger.info("tls authentication success")
+ except LibvirtAPI, e:
+ logger.error("API error message: %s, error code is %s" % \
+ (e.response()['message'], e.response()['code']))
+ logger.error("tls authentication failed")
+ return 1
+
+ return 0
+
+def tls_setup_clean(params):
+ """ cleanup testing enviroment """
+ if os.path.exists(TEMP_TLS_FOLDER):
+ shutil.rmtree(TEMP_TLS_FOLDER)
+
+ logger = params['logger']
+ target_machine = params['target_machine']
+ username = params['username']
+ password = params['password']
+
+ util = utils.Utils()
+ cacert_rm = "rm -f %s/cacert.pem" % CA_FOLDER
+ ret = util.remote_exec_pexpect(target_machine, username, password, cacert_rm)
+ if ret:
+ logger.error("failed to remove cacert.pem on remote machine")
+
+ ca_libvirt_rm = "rm -rf %s" % CERTIFICATE_FOLDER
+ ret = util.remote_exec_pexpect(target_machine, username, password, ca_libvirt_rm)
+ if ret:
+ logger.error("failed to remove libvirt folder")
+
+ os.remove("%s/cacert.pem" % CA_FOLDER)
+ shutil.rmtree(CERTIFICATE_FOLDER)
+
--
1.7.1
3
5
27 Jul '11
---
daemon/libvirtd.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 9e044e2..61f5a2d 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -1572,6 +1572,12 @@ cleanup:
if (pid_file)
unlink (pid_file);
+ if (sock_file && sock_file[0] != '@')
+ unlink(sock_file);
+
+ if (sock_file_ro && sock_file_ro[0] != '@')
+ unlink(sock_file_ro);
+
VIR_FREE(sock_file);
VIR_FREE(sock_file_ro);
VIR_FREE(pid_file);
--
1.7.6
2
3
Hi,
I just notices that compiling libvirt against yail version 2 there were
some errors, mainly because yajl_parser_config is no longer used.
The patch below fixed this for me.
Regards
Brecht Sanders
--- src/util/json.c 2011-03-24 08:10:26 +0100
+++ src/util/json.c 2011-07-27 09:29:52 +0200
@@ -34,2 +34,3 @@
# include <yajl/yajl_parse.h>
+# include <yajl/yajl_version.h>
#endif
@@ -896,3 +897,5 @@
{
+#if YAJL_MAJOR < 2
yajl_parser_config cfg = { 1, 1 };
+#endif
yajl_handle hand;
@@ -903,3 +906,7 @@
+#if YAJL_MAJOR < 2
hand = yajl_alloc(&parserCallbacks, &cfg, NULL, &parser);
+#else
+ hand = yajl_alloc(&parserCallbacks, NULL, &parser);
+#endif
@@ -1004,3 +1011,5 @@
{
+#if YAJL_MAJOR < 2
yajl_gen_config conf = { 0, " " }; /* Turns off pretty printing
since QEMUcan't cope */
+#endif
yajl_gen g;
@@ -1012,3 +1021,7 @@
+#if YAJL_MAJOR < 2
g = yajl_gen_alloc(&conf, NULL);
+#else
+ g = yajl_gen_alloc(NULL);
+#endif
2
3
27 Jul '11
Every DomainNetDef has a bandwidth, as does every portgroup.
Whenever a DomainNetDef of type NETWORK is about to be used, a call is
made to networkAllocateActualDevice(). This function chooses the "best"
bandwidth object and places it in the DomainActualNetDef.
>From that point on, whenever some code needs to use the bandwidth data
for the interface, it's retrieved with virDomainNetGetActualBandwidth(),
which will always return the "best" info as determined in the
previous step.
---
docs/formatnetwork.html.in | 2 +
src/conf/domain_conf.c | 25 ++++++++++++++++++-
src/conf/domain_conf.h | 3 ++
src/conf/network_conf.c | 10 +++++++
src/conf/network_conf.h | 1 +
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 19 +++++++++++++-
src/util/network.c | 56 +++++++++++++++++++++++++++++++++++++++++++
src/util/network.h | 2 +
9 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index f0ff703..ddfa77c 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -129,6 +129,8 @@
numbers, The units for <code>average</code> and <code>peak</code> attributes
are kilobytes per second, and for the <code>burst</code> just kilobytes.
The rate is shared equally within domains connected to the network.
+ Moreover, <code>bandwidth</code> element can be included in
+ <code>portgroup</code> element.
<span class="since">Since 0.9.4</span>
</p>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 072c970..031862a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -753,6 +753,8 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def)
break;
}
+ virBandwidthDefFree(def->bandwidth);
+
VIR_FREE(def);
}
@@ -2621,6 +2623,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
virDomainActualNetDefPtr actual = NULL;
int ret = -1;
xmlNodePtr save_ctxt = ctxt->node;
+ xmlNodePtr bandwidth_node = NULL;
char *type = NULL;
char *mode = NULL;
@@ -2677,6 +2680,11 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
}
}
+ bandwidth_node = virXPathNode("./bandwidth", ctxt);
+ if (bandwidth_node &&
+ !(actual->bandwidth = virBandwidthDefParseNode(bandwidth_node)))
+ goto error;
+
*def = actual;
actual = NULL;
ret = 0;
@@ -8713,6 +8721,10 @@ virDomainActualNetDefFormat(virBufferPtr buf,
default:
break;
}
+
+ if (virBandwidthDefFormat(buf, def->bandwidth, " ") < 0)
+ goto error;
+
virBufferAddLit(buf, " </actual>\n");
ret = 0;
@@ -8855,7 +8867,8 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferAddLit(buf, " </tune>\n");
}
- if (virBandwidthDefFormat(buf, def->bandwidth, " ") < 0)
+ if (virBandwidthDefFormat(buf, virDomainNetGetActualBandwidth(def),
+ " ") < 0)
return -1;
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
@@ -11383,3 +11396,13 @@ virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface)
return NULL;
return iface->data.network.actual->data.direct.virtPortProfile;
}
+
+virBandwidthPtr
+virDomainNetGetActualBandwidth(virDomainNetDefPtr iface)
+{
+ if ((iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) &&
+ iface->data.network.actual && iface->data.network.actual->bandwidth) {
+ return iface->data.network.actual->bandwidth;
+ }
+ return iface->bandwidth;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 212f0c5..715d995 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -362,6 +362,7 @@ struct _virDomainActualNetDef {
virVirtualPortProfileParamsPtr virtPortProfile;
} direct;
} data;
+ virBandwidthPtr bandwidth;
};
/* Stores the virtual network interface configuration */
@@ -1490,6 +1491,8 @@ char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface);
int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface);
virVirtualPortProfileParamsPtr
virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface);
+virBandwidthPtr
+virDomainNetGetActualBandwidth(virDomainNetDefPtr iface);
int virDomainControllerInsert(virDomainDefPtr def,
virDomainControllerDefPtr controller);
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 1ef80dc..6714c20 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -92,6 +92,8 @@ virPortGroupDefClear(virPortGroupDefPtr def)
{
VIR_FREE(def->name);
VIR_FREE(def->virtPortProfile);
+ virBandwidthDefFree(def->bandwidth);
+ def->bandwidth = NULL;
}
static void
@@ -771,6 +773,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
xmlNodePtr save;
xmlNodePtr virtPortNode;
+ xmlNodePtr bandwidth_node;
char *isDefault = NULL;
int result = -1;
@@ -790,6 +793,12 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
goto error;
}
+ bandwidth_node = virXPathNode("./bandwidth", ctxt);
+ if (bandwidth_node &&
+ !(def->bandwidth = virBandwidthDefParseNode(bandwidth_node))) {
+ goto error;
+ }
+
result = 0;
error:
if (result < 0) {
@@ -1257,6 +1266,7 @@ virPortGroupDefFormat(virBufferPtr buf,
}
virBufferAddLit(buf, ">\n");
virVirtualPortProfileFormat(buf, def->virtPortProfile, " ");
+ virBandwidthDefFormat(buf, def->bandwidth, " ");
virBufferAddLit(buf, " </portgroup>\n");
}
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 6d0845e..869085e 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -123,6 +123,7 @@ struct _virPortGroupDef {
char *name;
bool isDefault;
virVirtualPortProfileParamsPtr virtPortProfile;
+ virBandwidthPtr bandwidth;
};
typedef struct _virNetworkDef virNetworkDef;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 853ee62..0fa26dd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -710,6 +710,7 @@ nlComm;
# network.h
+virBandwidthCopy;
virBandwidthDefFormat;
virBandwidthDefFree;
virBandwidthDefParseNode;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index b1c6b12..b8c6c97 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2811,6 +2811,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
(netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
(netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
virVirtualPortProfileParamsPtr virtport = NULL;
+ virPortGroupDefPtr portgroup = NULL;
/* <forward type='bridge|private|vepa|passthrough'> are all
* VIR_DOMAIN_NET_TYPE_DIRECT.
@@ -2839,11 +2840,10 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
}
/* Find the most specific virtportprofile and copy it */
+ portgroup = virPortGroupFindByName(netdef, iface->data.network.portgroup);
if (iface->data.network.virtPortProfile) {
virtport = iface->data.network.virtPortProfile;
} else {
- virPortGroupDefPtr portgroup
- = virPortGroupFindByName(netdef, iface->data.network.portgroup);
if (portgroup)
virtport = portgroup->virtPortProfile;
else
@@ -2859,6 +2859,21 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
*/
*iface->data.network.actual->data.direct.virtPortProfile = *virtport;
}
+
+ /* Find the most specific bandwidth config and copy it */
+ if (iface->bandwidth) {
+ if (virBandwidthCopy(&iface->data.network.actual->bandwidth,
+ iface->bandwidth) < 0) {
+ goto cleanup;
+ }
+ } else {
+ if (portgroup &&
+ virBandwidthCopy(&iface->data.network.actual->bandwidth,
+ portgroup->bandwidth) < 0) {
+ goto cleanup;
+ }
+ }
+
/* If there is only a single device, just return it (caller will detect
* any error if exclusive use is required but could not be acquired).
*/
diff --git a/src/util/network.c b/src/util/network.c
index 5561012..314cabe 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -1263,3 +1263,59 @@ cleanup:
virCommandFree(cmd);
return ret;
}
+
+/*
+ * virBandwidthCopy:
+ * @dest: destination
+ * @src: source
+ *
+ * Returns -1 on OOM error (which gets reported),
+ * 0 otherwise.
+ */
+int
+virBandwidthCopy(virBandwidthPtr *dest,
+ const virBandwidthPtr src)
+{
+ int ret = -1;
+
+ if (!dest) {
+ virSocketError(VIR_ERR_INVALID_ARG, "%s",
+ _("invalid argument supplied"));
+ return -1;
+ }
+
+ if (!src) {
+ /* nothing to be copied */
+ return 0;
+ }
+
+ if (VIR_ALLOC(*dest) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (src->in) {
+ if (VIR_ALLOC((*dest)->in) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ memcpy((*dest)->in, src->in, sizeof(*src->in));
+ }
+
+ if (src->out) {
+ if (VIR_ALLOC((*dest)->out) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ memcpy((*dest)->out, src->out, sizeof(*src->out));
+ }
+
+ ret = 0;
+
+cleanup:
+ if (ret < 0) {
+ virBandwidthDefFree(*dest);
+ *dest = NULL;
+ }
+ return ret;
+}
diff --git a/src/util/network.h b/src/util/network.h
index 139f6cc..6ceaa6d 100644
--- a/src/util/network.h
+++ b/src/util/network.h
@@ -158,4 +158,6 @@ int virBandwidthDefFormat(virBufferPtr buf,
int virBandwidthEnable(virBandwidthPtr bandwidth, const char *iface);
int virBandwidthDisable(const char *iface, bool may_fail);
+int virBandwidthCopy(virBandwidthPtr *dest, const virBandwidthPtr src);
+
#endif /* __VIR_NETWORK_H__ */
--
1.7.5.rc3
2
2
27 Jul '11
* tools/virsh.c: format strings display for virsh nodecpustats --percent.
* how to reproduce?
% virsh nodecpustats --percent
usage: 2.0%
user : 1.0%
system: 1.0%
idle : 98.0%
iowait: 0.0%
* after format strings
% virsh nodecpustats --percent
usage : 2.0%
user : 1.0%
system: 1.0%
idle : 98.0%
iowait: 0.0%
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
tools/virsh.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index e46da31..f1166a9 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -4459,11 +4459,11 @@ cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd)
usage = (user_time + sys_time) / total_time * 100;
vshPrint(ctl, "%-15s %5.1lf%%\n",
- _("usage:"), usage);
+ _("usage :"), usage);
vshPrint(ctl, "%-15s %5.1lf%%\n",
- _(" user :"), user_time / total_time * 100);
+ _("user :"), user_time / total_time * 100);
vshPrint(ctl, "%-15s %5.1lf%%\n",
- _(" system:"), sys_time / total_time * 100);
+ _("system:"), sys_time / total_time * 100);
vshPrint(ctl, "%-15s %5.1lf%%\n",
_("idle :"), idle_time / total_time * 100);
vshPrint(ctl, "%-15s %5.1lf%%\n",
--
1.7.1
3
2
27 Jul '11
Commit b31abc6f0 introduce commands blockpull and blockjob, but
forgot to add the docs meanwhile.
---
tools/virsh.pod | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 5b7fa9c..02c98c8 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -430,6 +430,27 @@ Get memory stats for a running domain.
Get block device size info for a domain.
+=item B<blockpull> I<domain> I<path> [I<bandwidth>]
+
+Populate a disk from its backing image. Once all data from its backing
+image has been pulled, the disk no longer depends on the backing image.
+It pulls data for the entire disk in the background, the process of the
+operation can be checked with B<blockjob>.
+
+I<path> specifies fully-qualified path of the disk.
+I<bandwidth> specifies copying bandwidth limit in Mbps.
+
+=item B<blockjob> I<domain> I<path> [I<--abort>] [I<--info>] [I<bandwidth>]
+
+Manage active block operations.
+
+I<path> specifies fully-qualified path of the disk.
+If I<--live> is specified, the active job on the specified disk will
+be aborted.
+If I<--info> is specified, the active job information on the specified
+disk will be printed.
+I<bandwidth> can be used to set bandwidth limit for the active job.
+
=item B<dominfo> I<domain-id>
Returns basic information about the domain.
--
1.7.6
2
2
27 Jul '11
We only want to raise the special value -2. -1 should return None
which tells the bindings to throw an exception.
---
python/libvirt-override.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 70e0238..bdff0e9 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -4138,8 +4138,10 @@ libvirt_virStreamRecv(PyObject *self ATTRIBUTE_UNUSED,
buf[ret > -1 ? ret : 0] = '\0';
DEBUG("StreamRecv ret=%d strlen=%d\n", ret, (int) strlen(buf));
- if (ret < 0)
+ if (ret == -2)
return libvirt_intWrap(ret);
+ if (ret < 0)
+ return VIR_PY_NONE;
return libvirt_charPtrSizeWrap((char *) buf, (Py_ssize_t) ret);
}
--
1.7.4.4
2
2
[libvirt] FYI: qemu -M option deprecated upstream, removed from -help output
by Richard W.M. Jones 26 Jul '11
by Richard W.M. Jones 26 Jul '11
26 Jul '11
I guess this may affect the qemu driver in future ... Thanks to
Markus Armbruster for bringing this to my/our attention.
commit 80f52a6694423da7a40e2ec39e14a5817184c7ef
Author: Jan Kiszka <>
Date: Sat Jul 23 12:39:46 2011 +0200
Deprecate -M command line options
Superseded by -machine. Therefore, this patch removes -M from the help
list and pushes -machine at the same place in the output.
commit 9052ea6bf4962b1342aa56d4341bb55176ed9e45
Author: Jan Kiszka <>
Date: Sat Jul 23 12:38:37 2011 +0200
Generalize -machine command line option
-machine somehow suggests that it selects the machine, but it doesn't.
Fix that before this command is set in stone.
Actually, -machine should supersede -M and allow to introduce arbitrary
per-machine options to the command line. That will change the internal
realization again, but we will be able to keep the user interface
stable.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine. Supports Linux and Windows.
http://et.redhat.com/~rjones/virt-df/
3
4
26 Jul '11
Fix the build if HAVE_AVAHI is not defined.
Signed-off-by: Stefan Berger <stefanb(a)linux.vnet.ibm.com>
---
src/rpc/virnetserver.c | 2 ++
1 file changed, 2 insertions(+)
Index: libvirt-acl/src/rpc/virnetserver.c
===================================================================
--- libvirt-acl.orig/src/rpc/virnetserver.c
+++ libvirt-acl/src/rpc/virnetserver.c
@@ -783,7 +783,9 @@ void virNetServerFree(virNetServerPtr sr
VIR_FREE(srv->clients);
VIR_FREE(srv->mdnsGroupName);
+#if HAVE_AVAHI
virNetServerMDNSFree(srv->mdns);
+#endif
#if HAVE_DBUS
if (srv->sysbus)
2
2
The following two patches fix up a couple of errors in the virsh manpage.
Dave
3
7
26 Jul '11
From: "Daniel P. Berrange" <berrange(a)redhat.com>
When an incoming RPC message is ready for processing,
virNetServerClientDispatchRead()
will invoke the 'dispatchFunc' callback. This is set to
virNetServerDispatchNewMessage
This function puts the message + client in a queue for processing by the thread
pool. The thread pool worker function is
virNetServerHandleJob
The first thing this does is acquire an extra reference on the 'client'.
Unfortunately, between the time the message+client are put on the thread pool
queue, and the time the worker runs, the client object may have had its last
reference removed.
We clearly need to add the reference to the client object before putting the
client on the processing queue
* src/rpc/virnetserverclient.c: Add a reference to the client when
invoking the dispatch function
* src/rpc/virnetserver.c: Don't acquire a reference to the client
when in the worker thread
---
src/rpc/virnetserver.c | 2 --
src/rpc/virnetserverclient.c | 2 ++
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 2b9dd4d..c93c3f8 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -131,8 +131,6 @@ static void virNetServerHandleJob(void *jobOpaque, void *opaque)
virNetServerProgramPtr prog = NULL;
size_t i;
- virNetServerClientRef(job->client);
-
virNetServerLock(srv);
VIR_DEBUG("server=%p client=%p message=%p",
srv, job->client, job->msg);
diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 317d59c..3c0dba8 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -763,10 +763,12 @@ readmore:
/* Send off to for normal dispatch to workers */
if (msg) {
+ client->refs++;
if (!client->dispatchFunc ||
client->dispatchFunc(client, msg, client->dispatchOpaque) < 0) {
virNetMessageFree(msg);
client->wantClose = true;
+ client->refs--;
return;
}
}
--
1.7.6
2
1
The cpu bandwidth is applied at the vcpu group level. We should apply it
at the vm group level too, because the vm may do heavy I/O, and it will affect
the other vm.
We apply cpu bandwidth at the vcpu and the vm group level, so we must ensure
that max(child_quota) <= parent_quota when we modify cpu bandwidth.
---
src/qemu/qemu_cgroup.c | 38 ++++++++++-------
src/qemu/qemu_driver.c | 103 ++++++++++++++++++++++++++++++++++++-----------
2 files changed, 101 insertions(+), 40 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index d6e4cbc..2a10bd2 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -435,6 +435,7 @@ int qemuSetupCgroupForVcpu(struct qemud_driver *driver, virDomainObjPtr vm)
unsigned int i;
unsigned long long period = vm->def->cputune.period;
long long quota = vm->def->cputune.quota;
+ long long vm_quota = 0;
if (driver->cgroup == NULL)
return 0; /* Not supported, so claim success */
@@ -447,26 +448,31 @@ int qemuSetupCgroupForVcpu(struct qemud_driver *driver, virDomainObjPtr vm)
goto cleanup;
}
+ /* Set cpu bandwidth for the vm */
+ if (period || quota) {
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
+ /* Ensure that we can multiply by vcpus without overflowing. */
+ if (quota > LLONG_MAX / vm->def->vcpus) {
+ virReportSystemError(EINVAL,
+ _("%s"),
+ "Unable to set cpu bandwidth quota");
+ goto cleanup;
+ }
+
+ if (quota > 0)
+ vm_quota = quota * vm->def->vcpus;
+ else
+ vm_quota = quota;
+ if (qemuSetupCgroupVcpuBW(cgroup, period, vm_quota) < 0)
+ goto cleanup;
+ }
+ }
+
if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
/* If we does not know VCPU<->PID mapping or all vcpu runs in the same
* thread, we cannot control each vcpu.
*/
- if (period || quota) {
- if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
- /* Ensure that we can multiply by vcpus without overflowing. */
- if (quota > LLONG_MAX / vm->def->vcpus) {
- virReportSystemError(EINVAL,
- _("%s"),
- "Unable to set cpu bandwidth quota");
- goto cleanup;
- }
-
- if (quota > 0)
- quota *= vm->def->vcpus;
- if (qemuSetupCgroupVcpuBW(cgroup, period, quota) < 0)
- goto cleanup;
- }
- }
+ virCgroupFree(&cgroup);
return 0;
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5df58b1..52e5d69 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6051,43 +6051,98 @@ qemuSetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup_vcpu = NULL;
int rc;
+ long long vm_quota = 0;
+ long long old_quota = 0;
+ unsigned long long old_period = 0;
if (period == 0 && quota == 0)
return 0;
- if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
- /* If we does not know VCPU<->PID mapping or all vcpu runs in the same
- * thread, we cannot control each vcpu.
- */
- /* Ensure that we can multiply by vcpus without overflowing. */
- if (quota > LLONG_MAX / vm->def->vcpus) {
- virReportSystemError(EINVAL,
- _("%s"),
- "Unable to set cpu bandwidth quota");
- goto cleanup;
- }
+ /* Ensure that we can multiply by vcpus without overflowing. */
+ if (quota > LLONG_MAX / vm->def->vcpus) {
+ virReportSystemError(EINVAL,
+ _("%s"),
+ "Unable to set cpu bandwidth quota");
+ goto cleanup;
+ }
+
+ if (quota > 0)
+ vm_quota = quota * vm->def->vcpus;
+ else
+ vm_quota = quota;
- if (quota > 0)
- quota *= vm->def->vcpus;
- return qemuSetupCgroupVcpuBW(cgroup, period, quota);
+ rc = virCgroupGetCpuCfsQuota(cgroup, &old_quota);
+ if (rc < 0) {
+ virReportSystemError(-rc, "%s",
+ _("unable to get cpu bandwidth tunable"));
+ goto cleanup;
}
- for (i = 0; i < priv->nvcpupids; i++) {
- rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0);
- if (rc < 0) {
- virReportSystemError(-rc,
- _("Unable to find vcpu cgroup for %s(vcpu:"
- " %d)"),
- vm->def->name, i);
- goto cleanup;
+ rc = virCgroupGetCpuCfsPeriod(cgroup, &old_period);
+ if (rc < 0) {
+ virReportSystemError(-rc, "%s",
+ _("unable to get cpu bandwidth period tunable"));
+ goto cleanup;
+ }
+
+ /*
+ * If quota will be changed to a small value, we should modify vcpu's quota
+ * first. Otherwise, we should modify vm's quota first.
+ *
+ * If period will be changed to a small value, we should modify vm's period
+ * first. Otherwise, we should modify vcpu's period first.
+ *
+ * If both quota and period will be changed to a big/small value, we cannot
+ * modify period and quota together.
+ */
+ if ((quota != 0) && (period != 0)) {
+ if (((quota > old_quota) && (period > old_period)) ||
+ ((quota < old_quota) && (period < old_period))) {
+ /* modify period */
+ if (qemuSetVcpusBWLive(vm, cgroup, period, 0) < 0)
+ goto cleanup;
+
+ /* modify quota */
+ if (qemuSetVcpusBWLive(vm, cgroup, 0, quota) < 0)
+ goto cleanup;
+ return 0;
}
+ }
- if (qemuSetupCgroupVcpuBW(cgroup_vcpu, period, quota) < 0)
+ if (((vm_quota != 0) && (vm_quota > old_quota)) ||
+ ((period != 0) && (period < old_period)))
+ /* Set cpu bandwidth for the vm */
+ if (qemuSetupCgroupVcpuBW(cgroup, period, vm_quota) < 0)
goto cleanup;
- virCgroupFree(&cgroup_vcpu);
+ /* If we does not know VCPU<->PID mapping or all vcpu runs in the same
+ * thread, we cannot control each vcpu. So we only modify cpu bandwidth
+ * when each vcpu has a separated thread.
+ */
+ if (priv->nvcpupids != 0 && priv->vcpupids[0] != vm->pid) {
+ for (i = 0; i < priv->nvcpupids; i++) {
+ rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0);
+ if (rc < 0) {
+ virReportSystemError(-rc,
+ _("Unable to find vcpu cgroup for %s(vcpu:"
+ " %d)"),
+ vm->def->name, i);
+ goto cleanup;
+ }
+
+ if (qemuSetupCgroupVcpuBW(cgroup_vcpu, period, quota) < 0)
+ goto cleanup;
+
+ virCgroupFree(&cgroup_vcpu);
+ }
}
+ if (((vm_quota != 0) && (vm_quota <= old_quota)) ||
+ ((period != 0) && (period >= old_period)))
+ /* Set cpu bandwidth for the vm */
+ if (qemuSetupCgroupVcpuBW(cgroup, period, vm_quota) < 0)
+ goto cleanup;
+
return 0;
cleanup:
--
1.7.1
5
4
From: "Daniel P. Berrange" <berrange(a)redhat.com>
* tools/virsh.pod: Fix missing > tag in docs
---
tools/virsh.pod | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 5b7fa9c..ed9eb93 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -798,7 +798,7 @@ value are kilobytes (i.e. blocks of 1024 bytes).
=back
=item B<blkiotune> I<domain-id> [I<--weight> B<weight>] [[I<--config>]
-[I<--live] | [I<--current>]]
+[I<--live>] | [I<--current>]]
Display or set the blkio parameters. QEMU/KVM supports I<--weight>.
I<--weight> is in range [100, 1000].
@@ -811,7 +811,7 @@ exclusive. If no flag is specified, behavior is different depending
on hypervisor.
=item B<setvcpus> I<domain-id> I<count> [I<--maximum>] [[I<--config>]
-[I<--live>] | [I<--current]]
+[I<--live>] | [I<--current>]]
Change the number of virtual CPUs active in a guest domain. By default,
this command works on active guest domains. To change the settings for an
--
1.7.6
3
2
From: "Daniel P. Berrange" <berrange(a)redhat.com>
---
src/rpc/virnettlscontext.c | 15 +++++++++++++++
tests/virnettlscontexttest.c | 2 +-
2 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index db03669..2a58ede 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -139,6 +139,15 @@ static int virNetTLSContextCheckCertTimes(gnutls_x509_crt_t cert,
return 0;
}
+
+#ifndef GNUTLS_1_0_COMPAT
+/*
+ * The gnutls_x509_crt_get_basic_constraints function isn't
+ * available in GNUTLS 1.0.x branches. This isn't critical
+ * though, since gnutls_certificate_verify_peers2 will do
+ * pretty much the same check at runtime, so we can just
+ * disable this code
+ */
static int virNetTLSContextCheckCertBasicConstraints(gnutls_x509_crt_t cert,
const char *certFile,
bool isServer,
@@ -180,6 +189,8 @@ static int virNetTLSContextCheckCertBasicConstraints(gnutls_x509_crt_t cert,
return 0;
}
+#endif
+
static int virNetTLSContextCheckCertKeyUsage(gnutls_x509_crt_t cert,
const char *certFile,
@@ -412,9 +423,11 @@ static int virNetTLSContextCheckCert(gnutls_x509_crt_t cert,
isServer, isCA) < 0)
return -1;
+#ifndef GNUTLS_1_0_COMPAT
if (virNetTLSContextCheckCertBasicConstraints(cert, certFile,
isServer, isCA) < 0)
return -1;
+#endif
if (virNetTLSContextCheckCertKeyUsage(cert, certFile,
isCA) < 0)
@@ -1019,11 +1032,13 @@ static int virNetTLSContextValidCertificate(virNetTLSContextPtr ctxt,
/* !sess->isServer, since on the client, we're validating the
* server's cert, and on the server, the client's cert
*/
+#ifndef GNUTLS_1_0_COMPAT
if (virNetTLSContextCheckCertBasicConstraints(cert, "[session]",
!sess->isServer, false) < 0) {
gnutls_x509_crt_deinit(cert);
goto authdeny;
}
+#endif
if (virNetTLSContextCheckCertKeyUsage(cert, "[session]",
false) < 0) {
diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c
index f2af4f0..12ecf1e 100644
--- a/tests/virnettlscontexttest.c
+++ b/tests/virnettlscontexttest.c
@@ -33,7 +33,7 @@
#include "command.h"
#include "network.h"
-#if !defined WIN32 && HAVE_LIBTASN1_H
+#if !defined WIN32 && HAVE_LIBTASN1_H && !defined GNUTLS_1_0_COMPAT
# include <libtasn1.h>
# include <gnutls/gnutls.h>
# include <gnutls/x509.h>
--
1.7.6
2
1
26 Jul '11
With older GNUTLS the gnutls_x509_privkey_import function is
unable to import our private key. Instead we must use the
alternative gnutls_x509_privkey_import_pkcs8() (as certtool
does).
* virnettlscontexttest.c: Fix import of private key with
older gnutls. Also add missing newlines to key
---
tests/virnettlscontexttest.c | 47 ++++++++++++++++++++++++-----------------
1 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c
index dfc0ac4..f2af4f0 100644
--- a/tests/virnettlscontexttest.c
+++ b/tests/virnettlscontexttest.c
@@ -57,24 +57,24 @@ extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
* here's one we prepared earlier :-)
*/
gnutls_x509_privkey_t privkey;
-# define PRIVATE_KEY \
- "-----BEGIN PRIVATE KEY-----\n" \
- "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALVcr" \
- "BL40Tm6yq88FBhJNw1aaoCjmtg0l4dWQZ/e9Fimx4ARxFpT+ji4FE" \
- "Cgl9s/SGqC+1nvlkm9ViSo0j7MKDbnDB+VRHDvMAzQhA2X7e8M0n9" \
- "rPolUY2lIVC83q0BBaOBkCj2RSmT2xTEbbC2xLukSrg2WP/ihVOxc" \
- "kXRuyFtzAgMBAAECgYB7slBexDwXrtItAMIH6m/U+LUpNe0Xx48OL" \
- "IOn4a4whNgO/o84uIwygUK27ZGFZT0kAGAk8CdF9hA6ArcbQ62s1H" \
- "myxrUbF9/mrLsQw1NEqpuUk9Ay2Tx5U/wPx35S3W/X2AvR/ZpTnCn" \
- "2q/7ym9fyiSoj86drD7BTvmKXlOnOwQJBAPOFMp4mMa9NGpGuEssO" \
- "m3Uwbp6lhcP0cA9MK+iOmeANpoKWfBdk5O34VbmeXnGYWEkrnX+9J" \
- "bM4wVhnnBWtgBMCQQC+qAEmvwcfhauERKYznMVUVksyeuhxhCe7EK" \
- "mPh+U2+g0WwdKvGDgO0PPt1gq0ILEjspMDeMHVdTwkaVBo/uMhAkA" \
- "Z5SsZyCP2aTOPFDypXRdI4eqRcjaEPOUBq27r3uYb/jeboVb2weLa" \
- "L1MmVuHiIHoa5clswPdWVI2y0em2IGoDAkBPSp/v9VKJEZabk9Frd" \
- "a+7u4fanrM9QrEjY3KhduslSilXZZSxrWjjAJPyPiqFb3M8XXA26W" \
- "nz1KYGnqYKhLcBAkB7dt57n9xfrhDpuyVEv+Uv1D3VVAhZlsaZ5Pp" \
- "dcrhrkJn2sa/+O8OKvdrPSeeu/N5WwYhJf61+CPoenMp7IFci\n" \
+# define PRIVATE_KEY \
+ "-----BEGIN PRIVATE KEY-----\n" \
+ "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALVcr\n" \
+ "BL40Tm6yq88FBhJNw1aaoCjmtg0l4dWQZ/e9Fimx4ARxFpT+ji4FE\n" \
+ "Cgl9s/SGqC+1nvlkm9ViSo0j7MKDbnDB+VRHDvMAzQhA2X7e8M0n9\n" \
+ "rPolUY2lIVC83q0BBaOBkCj2RSmT2xTEbbC2xLukSrg2WP/ihVOxc\n" \
+ "kXRuyFtzAgMBAAECgYB7slBexDwXrtItAMIH6m/U+LUpNe0Xx48OL\n" \
+ "IOn4a4whNgO/o84uIwygUK27ZGFZT0kAGAk8CdF9hA6ArcbQ62s1H\n" \
+ "myxrUbF9/mrLsQw1NEqpuUk9Ay2Tx5U/wPx35S3W/X2AvR/ZpTnCn\n" \
+ "2q/7ym9fyiSoj86drD7BTvmKXlOnOwQJBAPOFMp4mMa9NGpGuEssO\n" \
+ "m3Uwbp6lhcP0cA9MK+iOmeANpoKWfBdk5O34VbmeXnGYWEkrnX+9J\n" \
+ "bM4wVhnnBWtgBMCQQC+qAEmvwcfhauERKYznMVUVksyeuhxhCe7EK\n" \
+ "mPh+U2+g0WwdKvGDgO0PPt1gq0ILEjspMDeMHVdTwkaVBo/uMhAkA\n" \
+ "Z5SsZyCP2aTOPFDypXRdI4eqRcjaEPOUBq27r3uYb/jeboVb2weLa\n" \
+ "L1MmVuHiIHoa5clswPdWVI2y0em2IGoDAkBPSp/v9VKJEZabk9Frd\n" \
+ "a+7u4fanrM9QrEjY3KhduslSilXZZSxrWjjAJPyPiqFb3M8XXA26W\n" \
+ "nz1KYGnqYKhLcBAkB7dt57n9xfrhDpuyVEv+Uv1D3VVAhZlsaZ5Pp\n" \
+ "dcrhrkJn2sa/+O8OKvdrPSeeu/N5WwYhJf61+CPoenMp7IFci\n" \
"-----END PRIVATE KEY-----\n"
@@ -419,8 +419,15 @@ static gnutls_x509_privkey_t testTLSLoadKey(void)
if ((err = gnutls_x509_privkey_import(key, &data,
GNUTLS_X509_FMT_PEM)) < 0) {
- VIR_WARN("Failed to init key %s", gnutls_strerror(err));
- abort();
+ if (err != GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) {
+ VIR_WARN("Failed to import key %s", gnutls_strerror(err));
+ abort();
+ }
+
+ if ((err = gnutls_x509_privkey_import_pkcs8(key, &data, GNUTLS_X509_FMT_PEM, NULL, 0)) < 0) {
+ VIR_WARN("Failed to import PKCS8 key %s", gnutls_strerror(err));
+ abort();
+ }
}
return key;
--
1.7.1
4
4
[libvirt] [PATCH 1/2] Allow certificate sanity checking to be disabled
by Daniel P. Berrange 26 Jul '11
by Daniel P. Berrange 26 Jul '11
26 Jul '11
From: "Daniel P. Berrange" <berrange(a)redhat.com>
When libvirtd starts it it will sanity check its own certs,
and before libvirt clients connect to a remote server they
will sanity check their own certs. This patch allows such
sanity checking to be skipped. There is no strong reason to
need to do this, other than to bypass possible libvirt bugs
in sanity checking, or for testing purposes.
libvirt.conf gains tls_no_sanity_certificate parameter to
go along with tls_no_verify_certificate. The remote driver
client URIs gain a no_sanity URI parameter
* daemon/test_libvirtd.aug, daemon/libvirtd.conf,
daemon/libvirtd.c, daemon/libvirtd.aug: Add parameter to
allow cert sanity checks to be skipped
* src/remote/remote_driver.c: Add no_sanity parameter to
skip cert checks
* src/rpc/virnettlscontext.c, src/rpc/virnettlscontext.h:
Add new parameter for skipping sanity checks independantly
of skipping session cert validation checks
---
daemon/libvirtd.aug | 1 +
daemon/libvirtd.c | 4 ++++
daemon/libvirtd.conf | 9 +++++++++
daemon/test_libvirtd.aug | 2 ++
src/remote/remote_driver.c | 15 +++++++++------
src/rpc/virnettlscontext.c | 36 +++++++++++++++++++++++-------------
src/rpc/virnettlscontext.h | 4 ++++
7 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/daemon/libvirtd.aug b/daemon/libvirtd.aug
index 0e06142..3f47ebb 100644
--- a/daemon/libvirtd.aug
+++ b/daemon/libvirtd.aug
@@ -48,6 +48,7 @@ module Libvirtd =
| str_entry "crl_file"
let authorization_entry = bool_entry "tls_no_verify_certificate"
+ | bool_entry "tls_no_sanity_certificate"
| str_array_entry "tls_allowed_dn_list"
| str_array_entry "sasl_allowed_username_list"
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index f2f3a4e..9e044e2 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -120,6 +120,7 @@ struct daemonConfig {
char *mdns_name;
int tls_no_verify_certificate;
+ int tls_no_sanity_certificate;
char **tls_allowed_dn_list;
char **sasl_allowed_username_list;
@@ -535,12 +536,14 @@ static int daemonSetupNetworking(virNetServerPtr srv,
config->cert_file,
config->key_file,
(const char *const*)config->tls_allowed_dn_list,
+ config->tls_no_sanity_certificate ? false : true,
config->tls_no_verify_certificate ? false : true)))
goto error;
} else {
if (!(ctxt = virNetTLSContextNewServerPath(NULL,
!privileged,
(const char *const*)config->tls_allowed_dn_list,
+ config->tls_no_sanity_certificate ? false : true,
config->tls_no_verify_certificate ? false : true)))
goto error;
}
@@ -1054,6 +1057,7 @@ daemonConfigLoad(struct daemonConfig *data,
GET_CONF_INT (conf, filename, mdns_adv);
GET_CONF_STR (conf, filename, mdns_name);
+ GET_CONF_INT (conf, filename, tls_no_sanity_certificate);
GET_CONF_INT (conf, filename, tls_no_verify_certificate);
GET_CONF_STR (conf, filename, key_file);
diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf
index 3a071b0..217f2f4 100644
--- a/daemon/libvirtd.conf
+++ b/daemon/libvirtd.conf
@@ -187,6 +187,15 @@
#
+# Flag to disable verification of our own server certificates
+#
+# When libvirtd starts it performs some sanity checks against
+# its own certificates.
+#
+# Default is to always sanity. Uncommenting this will disable
+# sanity checks which is not a good idea
+#tls_no_sanity_certificate = 1
+
# Flag to disable verification of client certificates
#
# Client certificate verification is the primary authentication mechanism.
diff --git a/daemon/test_libvirtd.aug b/daemon/test_libvirtd.aug
index 5f8b644..58b7170 100644
--- a/daemon/test_libvirtd.aug
+++ b/daemon/test_libvirtd.aug
@@ -193,6 +193,7 @@ crl_file = \"/etc/pki/CA/crl.pem\"
# Default is to always verify. Uncommenting this will disable
# verification - make sure an IP whitelist is set
tls_no_verify_certificate = 1
+tls_no_sanity_certificate = 1
# A whitelist of allowed x509 Distinguished Names
@@ -468,6 +469,7 @@ audit_level = 2
{ "#comment" = "Default is to always verify. Uncommenting this will disable" }
{ "#comment" = "verification - make sure an IP whitelist is set" }
{ "tls_no_verify_certificate" = "1" }
+ { "tls_no_sanity_certificate" = "1" }
{ "#empty" }
{ "#empty" }
{ "#comment" = "A whitelist of allowed x509 Distinguished Names" }
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index ec4133b..7993d50 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -351,7 +351,7 @@ doRemoteOpen (virConnectPtr conn,
*/
char *name = NULL, *command = NULL, *sockname = NULL, *netcat = NULL;
char *port = NULL, *authtype = NULL, *username = NULL;
- int no_verify = 0, no_tty = 0;
+ bool sanity = true, verify = true, tty = true;
char *pkipath = NULL;
/* Return code from this function, and the private data. */
@@ -425,11 +425,14 @@ doRemoteOpen (virConnectPtr conn,
netcat = strdup (var->value);
if (!netcat) goto out_of_memory;
var->ignore = 1;
+ } else if (STRCASEEQ (var->name, "no_sanity")) {
+ sanity = atoi(var->value) == 0;
+ var->ignore = 1;
} else if (STRCASEEQ (var->name, "no_verify")) {
- no_verify = atoi (var->value);
+ verify = atoi (var->value) == 0;
var->ignore = 1;
} else if (STRCASEEQ (var->name, "no_tty")) {
- no_tty = atoi (var->value);
+ tty = atoi (var->value) == 0;
var->ignore = 1;
} else if (STRCASEEQ(var->name, "pkipath")) {
VIR_FREE(pkipath);
@@ -509,7 +512,7 @@ doRemoteOpen (virConnectPtr conn,
case trans_tls:
priv->tls = virNetTLSContextNewClientPath(pkipath,
geteuid() != 0 ? true : false,
- no_verify ? false : true);
+ sanity, verify);
if (!priv->tls)
goto failed;
priv->is_secure = 1;
@@ -579,8 +582,8 @@ doRemoteOpen (virConnectPtr conn,
port,
command,
username,
- no_tty,
- no_verify,
+ !tty,
+ !verify,
netcat ? netcat : "nc",
sockname)))
goto failed;
diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index 5c94df6..bde4e7a 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -382,7 +382,7 @@ virNetTLSContextCheckCertDN(gnutls_x509_crt_t cert,
certFile, gnutls_strerror(ret));
return -1;
}
-
+ VIR_DEBUG("Peer DN is %s", name);
if (whitelist &&
virNetTLSContextCheckCertDNWhitelist(name, whitelist) <= 0)
return -1;
@@ -637,6 +637,7 @@ static virNetTLSContextPtr virNetTLSContextNew(const char *cacert,
const char *cert,
const char *key,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert,
bool isServer)
{
@@ -644,8 +645,8 @@ static virNetTLSContextPtr virNetTLSContextNew(const char *cacert,
char *gnutlsdebug;
int err;
- VIR_DEBUG("cacert=%s cacrl=%s cert=%s key=%s requireValid=%d isServer=%d",
- cacert, NULLSTR(cacrl), cert, key, requireValidCert, isServer);
+ VIR_DEBUG("cacert=%s cacrl=%s cert=%s key=%s sanityCheckCert=%d requireValid=%d isServer=%d",
+ cacert, NULLSTR(cacrl), cert, key, sanityCheckCert, requireValidCert, isServer);
if (VIR_ALLOC(ctxt) < 0) {
virReportOOMError();
@@ -675,7 +676,7 @@ static virNetTLSContextPtr virNetTLSContextNew(const char *cacert,
goto error;
}
- if (requireValidCert &&
+ if (sanityCheckCert &&
virNetTLSContextSanityCheckCredentials(isServer, cacert, cert) < 0)
goto error;
@@ -851,6 +852,7 @@ out_of_memory:
static virNetTLSContextPtr virNetTLSContextNewPath(const char *pkipath,
bool tryUserPkiPath,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert,
bool isServer)
{
@@ -862,7 +864,8 @@ static virNetTLSContextPtr virNetTLSContextNewPath(const char *pkipath,
return NULL;
ctxt = virNetTLSContextNew(cacert, cacrl, cert, key,
- x509dnWhitelist, requireValidCert, isServer);
+ x509dnWhitelist, sanityCheckCert,
+ requireValidCert, isServer);
VIR_FREE(cacert);
VIR_FREE(cacrl);
@@ -875,18 +878,20 @@ static virNetTLSContextPtr virNetTLSContextNewPath(const char *pkipath,
virNetTLSContextPtr virNetTLSContextNewServerPath(const char *pkipath,
bool tryUserPkiPath,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert)
{
- return virNetTLSContextNewPath(pkipath, tryUserPkiPath,
- x509dnWhitelist, requireValidCert, true);
+ return virNetTLSContextNewPath(pkipath, tryUserPkiPath, x509dnWhitelist,
+ sanityCheckCert, requireValidCert, true);
}
virNetTLSContextPtr virNetTLSContextNewClientPath(const char *pkipath,
bool tryUserPkiPath,
+ bool sanityCheckCert,
bool requireValidCert)
{
- return virNetTLSContextNewPath(pkipath, tryUserPkiPath,
- NULL, requireValidCert, false);
+ return virNetTLSContextNewPath(pkipath, tryUserPkiPath, NULL,
+ sanityCheckCert, requireValidCert, false);
}
@@ -895,10 +900,11 @@ virNetTLSContextPtr virNetTLSContextNewServer(const char *cacert,
const char *cert,
const char *key,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert)
{
- return virNetTLSContextNew(cacert, cacrl, cert, key,
- x509dnWhitelist, requireValidCert, true);
+ return virNetTLSContextNew(cacert, cacrl, cert, key, x509dnWhitelist,
+ sanityCheckCert, requireValidCert, true);
}
@@ -906,10 +912,11 @@ virNetTLSContextPtr virNetTLSContextNewClient(const char *cacert,
const char *cacrl,
const char *cert,
const char *key,
+ bool sanityCheckCert,
bool requireValidCert)
{
- return virNetTLSContextNew(cacert, cacrl, key, cert,
- NULL, requireValidCert, false);
+ return virNetTLSContextNew(cacert, cacrl, cert, key, NULL,
+ sanityCheckCert, requireValidCert, false);
}
@@ -1047,11 +1054,14 @@ int virNetTLSContextCheckCertificate(virNetTLSContextPtr ctxt,
virNetTLSSessionPtr sess)
{
if (virNetTLSContextValidCertificate(ctxt, sess) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_WARN("Certificate check failed %s", err && err->message ? err->message : "<unknown>");
if (ctxt->requireValidCert) {
virNetError(VIR_ERR_AUTH_FAILED, "%s",
_("Failed to verify peer's certificate"));
return -1;
}
+ virResetLastError();
VIR_INFO("Ignoring bad certificate at user request");
}
return 0;
diff --git a/src/rpc/virnettlscontext.h b/src/rpc/virnettlscontext.h
index f23667f..641d67e 100644
--- a/src/rpc/virnettlscontext.h
+++ b/src/rpc/virnettlscontext.h
@@ -33,10 +33,12 @@ typedef virNetTLSSession *virNetTLSSessionPtr;
virNetTLSContextPtr virNetTLSContextNewServerPath(const char *pkipath,
bool tryUserPkiPath,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert);
virNetTLSContextPtr virNetTLSContextNewClientPath(const char *pkipath,
bool tryUserPkiPath,
+ bool sanityCheckCert,
bool requireValidCert);
virNetTLSContextPtr virNetTLSContextNewServer(const char *cacert,
@@ -44,12 +46,14 @@ virNetTLSContextPtr virNetTLSContextNewServer(const char *cacert,
const char *cert,
const char *key,
const char *const*x509dnWhitelist,
+ bool sanityCheckCert,
bool requireValidCert);
virNetTLSContextPtr virNetTLSContextNewClient(const char *cacert,
const char *cacrl,
const char *cert,
const char *key,
+ bool sanityCheckCert,
bool requireValidCert);
void virNetTLSContextRef(virNetTLSContextPtr ctxt);
--
1.7.6
2
8
From: "Daniel P. Berrange" <berrange(a)redhat.com>
* src/rpc/virnetservermdns.c: Fix leaks
---
src/rpc/virnetservermdns.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/rpc/virnetservermdns.c b/src/rpc/virnetservermdns.c
index ff2d92d..335274a 100644
--- a/src/rpc/virnetservermdns.c
+++ b/src/rpc/virnetservermdns.c
@@ -583,6 +583,7 @@ void virNetServerMDNSFree(virNetServerMDNSPtr mdns)
group = tmp;
}
+ VIR_FREE(mdns->poller);
VIR_FREE(mdns);
}
@@ -601,6 +602,7 @@ void virNetServerMDNSGroupFree(virNetServerMDNSGroupPtr grp)
entry = tmp;
}
+ VIR_FREE(grp->name);
VIR_FREE(grp);
}
@@ -610,5 +612,6 @@ void virNetServerMDNSEntryFree(virNetServerMDNSEntryPtr entry)
if (!entry)
return;
+ VIR_FREE(entry->type);
VIR_FREE(entry);
}
--
1.7.6
3
8
Hi all,
This patchset adds some missing python bindings.
The bindings for the following APIs are added:
- virDomainGetSchedulerParametersFlags
- virDomainSetSchedulerParametersFlags
- virDomainPinVcpusFlags
- virDomainGetVcpuPinInfo
*[PATCH 1/3] python: add Python binding for virDomainGetSchedulerParametersFlags API
*[PATCH 2/3] python: add Python binding for virDomainSetSchedulerParametersFlags API
*[PATCH 3/3] python: add Python binding for virDomainPinVcpusFlags API
*[PATCH 4/4] python: add Python binding for virDomainGetVcpuPinInfo API
Best regards,
Taku Izumi
--
Taku Izumi <izumi.taku(a)jp.fujitsu.com>
2
7
Now that gnulib gives us ffs, we might as well use it.
* tools/virsh.c (vshCmddefGetData): Use ffs rather than
count_one_bits.
---
tools/virsh.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index ef8dea3..0dcc66b 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -32,6 +32,7 @@
#include <inttypes.h>
#include <signal.h>
#include <poll.h>
+#include <strings.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
@@ -57,7 +58,6 @@
#include "configmake.h"
#include "threads.h"
#include "command.h"
-#include "count-one-bits.h"
static char *progname;
@@ -12280,7 +12280,7 @@ vshCmddefGetData(const vshCmdDef *cmd, uint32_t *opts_need_arg,
return NULL;
/* Grab least-significant set bit */
- i = count_one_bits(*opts_need_arg ^ (*opts_need_arg - 1)) - 1;
+ i = ffs(*opts_need_arg) - 1;
opt = &cmd->opts[i];
if (opt->type != VSH_OT_ARGV)
*opts_need_arg &= ~(1 << i);
--
1.7.1
2
2
Now that virDomainSetVcpusFlags knows about VIR_DOMAIN_AFFECT_CURRENT,
so should virDomainGetVcpusFlags.
Unfortunately, the virsh counterpart 'virsh vcpucount' has already
commandeered --current for a different meaning, so virsh does not
have a way to expose this new calling capability unless we either
break backward compatibility or consistency with other virsh commands
that take --live and --config.
* src/libvirt.c (virDomainGetVcpusFlags): Allow
VIR_DOMAIN_AFFECT_CURRENT.
* src/libxl/libxl_driver.c (libxlDomainGetVcpusFlags): Likewise.
* src/qemu/qemu_driver.c (qemudDomainGetVcpusFlags): Likewise.
* src/test/test_driver.c (testDomainGetVcpusFlags): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainGetVcpusFlags): Likewise.
---
In response to:
https://www.redhat.com/archives/libvir-list/2011-July/msg00967.html
src/libvirt.c | 4 ++--
src/libxl/libxl_driver.c | 29 +++++++++++++++++++++--------
src/qemu/qemu_driver.c | 29 +++++++++++++++++++++--------
src/test/test_driver.c | 31 +++++++++++++++++++++++--------
src/xen/xen_driver.c | 7 -------
5 files changed, 67 insertions(+), 33 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 4de718d..def3fb9 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -6951,8 +6951,8 @@ virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
return -1;
}
- /* Exactly one of these two flags should be set. */
- if (!(flags & VIR_DOMAIN_AFFECT_LIVE) == !(flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ /* At most one of these two flags should be set. */
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index cc37d05..2e0d377 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2327,18 +2327,12 @@ libxlDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
virDomainObjPtr vm;
virDomainDefPtr def;
int ret = -1;
+ bool active;
virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
VIR_DOMAIN_VCPU_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
- /* Exactly one of LIVE or CONFIG must be set. */
- if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
- libxlError(VIR_ERR_INVALID_ARG,
- _("invalid flag combination: (0x%x)"), flags);
- return -1;
- }
-
libxlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
libxlDriverUnlock(driver);
@@ -2348,14 +2342,33 @@ libxlDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
goto cleanup;
}
+ active = virDomainObjIsActive(vm);
+
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
+ if (active)
+ flags |= VIR_DOMAIN_VCPU_LIVE;
+ else
+ flags |= VIR_DOMAIN_VCPU_CONFIG;
+ }
+ if ((flags & VIR_DOMAIN_VCPU_LIVE) && (flags & VIR_DOMAIN_VCPU_CONFIG)) {
+ libxlError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+
if (flags & VIR_DOMAIN_VCPU_LIVE) {
- if (!virDomainObjIsActive(vm)) {
+ if (!active) {
libxlError(VIR_ERR_OPERATION_INVALID,
"%s", _("Domain is not running"));
goto cleanup;
}
def = vm->def;
} else {
+ if (!vm->persistent) {
+ libxlError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is transient"));
+ goto cleanup;
+ }
def = vm->newDef ? vm->newDef : vm->def;
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1a3fbfb..536cd5c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3408,18 +3408,12 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
virDomainObjPtr vm;
virDomainDefPtr def;
int ret = -1;
+ bool active;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
- /* Exactly one of LIVE or CONFIG must be set. */
- if (!(flags & VIR_DOMAIN_AFFECT_LIVE) == !(flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- qemuReportError(VIR_ERR_INVALID_ARG,
- _("invalid flag combination: (0x%x)"), flags);
- return -1;
- }
-
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
qemuDriverUnlock(driver);
@@ -3432,14 +3426,33 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
goto cleanup;
}
+ active = virDomainObjIsActive(vm);
+
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
+ if (active)
+ flags |= VIR_DOMAIN_VCPU_LIVE;
+ else
+ flags |= VIR_DOMAIN_VCPU_CONFIG;
+ }
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
- if (!virDomainObjIsActive(vm)) {
+ if (!active) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain not active"));
goto cleanup;
}
def = vm->def;
} else {
+ if (!vm->persistent) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is transient"));
+ goto cleanup;
+ }
def = vm->newDef ? vm->newDef : vm->def;
}
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 064a1cd..28da8e7 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -2067,18 +2067,12 @@ testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
virDomainObjPtr vm;
virDomainDefPtr def;
int ret = -1;
+ bool active;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
- /* Exactly one of LIVE or CONFIG must be set. */
- if (!(flags & VIR_DOMAIN_AFFECT_LIVE) == !(flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- testError(VIR_ERR_INVALID_ARG,
- _("invalid flag combination: (0x%x)"), flags);
- return -1;
- }
-
testDriverLock(privconn);
vm = virDomainFindByUUID(&privconn->domains, domain->uuid);
testDriverUnlock(privconn);
@@ -2091,14 +2085,35 @@ testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
goto cleanup;
}
+ active = virDomainObjIsActive(vm);
+
+ if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) {
+ if (active)
+ flags |= VIR_DOMAIN_VCPU_LIVE;
+ else
+ flags |= VIR_DOMAIN_VCPU_CONFIG;
+ }
+ if ((flags & VIR_DOMAIN_AFFECT_LIVE) && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
+ testError(VIR_ERR_INVALID_ARG,
+ _("invalid flag combination: (0x%x)"), flags);
+ return -1;
+ }
+
+
+
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
- if (!virDomainObjIsActive(vm)) {
+ if (!active) {
testError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain not active"));
goto cleanup;
}
def = vm->def;
} else {
+ if (!vm->persistent) {
+ testError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is transient"));
+ goto cleanup;
+ }
def = vm->newDef ? vm->newDef : vm->def;
}
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index dd1ba6c..0f8b660 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1201,13 +1201,6 @@ xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
VIR_DOMAIN_VCPU_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
- /* Exactly one of LIVE or CONFIG must be set. */
- if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
- xenUnifiedError(VIR_ERR_INVALID_ARG,
- _("invalid flag combination: (0x%x)"), flags);
- return -1;
- }
-
if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
ret = xenDaemonDomainGetVcpusFlags(dom, flags);
if (ret != -2)
--
1.7.4.4
2
6
25 Jul '11
Otherwise things like volume upload are only useful with text data.
---
python/libvirt-override.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 9d1dac2..70e0238 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -4151,11 +4151,12 @@ libvirt_virStreamSend(PyObject *self ATTRIBUTE_UNUSED,
PyObject *pyobj_stream;
virStreamPtr stream;
char *data;
+ int datalen;
int ret;
int nbytes;
- if (!PyArg_ParseTuple(args, (char *) "Ozi:virStreamRecv",
- &pyobj_stream, &data, &nbytes)) {
+ if (!PyArg_ParseTuple(args, (char *) "Oz#i:virStreamRecv",
+ &pyobj_stream, &data, &datalen, &nbytes)) {
DEBUG("%s failed to parse tuple\n", __FUNCTION__);
return VIR_PY_INT_FAIL;
}
--
1.7.4.4
2
2
[libvirt] [PATCH] util: change virFile*Pid functions to return < 0 on failure
by Laine Stump 25 Jul '11
by Laine Stump 25 Jul '11
25 Jul '11
Although most functions in libvirt return 0 on success and < 0 on
failure, there are a few functions lingering around that return errno
(a positive value) on failure, and sometimes code calling those
functions incorrectly assumes the <0 standard. I noticed one of these
the other day when auditing networkStartDhcpDaemon after Guido Gunther
found a place where success was improperly returned on failure (that
patch has been acked and is pending a push). The problem was that it
expected the return value from virFileReadPid to be < 0 on failure,
but it was actually positive (it was also neglected to set the return
code in this case, similar to the bug found by Guido).
This all led to the fact that *all* of the virFile*Pid functions in
util.c are returning errno on failure. This patch remedies that
problem by changing them all to return -errno on failure, and makes
any necessary changes to callers of the functions. (In the meantime, I
also properly set the return code on failure of virFileReadPid in
networkStartDhcpDaemon).
---
src/lxc/lxc_controller.c | 6 +++---
src/lxc/lxc_driver.c | 4 ++--
src/network/bridge_driver.c | 5 +++--
src/qemu/qemu_process.c | 2 +-
src/util/command.c | 2 +-
src/util/util.c | 30 +++++++++++++++---------------
tests/commandtest.c | 4 ++--
7 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 7eda7ef..99d9467 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -947,8 +947,8 @@ int main(int argc, char *argv[])
goto cleanup;
if (pid > 0) {
- if ((rc = virFileWritePid(LXC_STATE_DIR, name, pid)) != 0) {
- virReportSystemError(rc,
+ if ((rc = virFileWritePid(LXC_STATE_DIR, name, pid)) < 0) {
+ virReportSystemError(-rc,
_("Unable to write pid file '%s/%s.pid'"),
LXC_STATE_DIR, name);
_exit(1);
@@ -996,5 +996,5 @@ cleanup:
unlink(sockpath);
VIR_FREE(sockpath);
- return rc;
+ return -rc; /* rc is 0 or negative, but returns from main should be >=0 */
}
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 615d2c6..7d99d27 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1612,8 +1612,8 @@ static int lxcVmStart(virConnectPtr conn,
goto cleanup;
/* And get its pid */
- if ((r = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) != 0) {
- virReportSystemError(r,
+ if ((r = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) < 0) {
+ virReportSystemError(-r,
_("Failed to read pid file %s/%s.pid"),
driver->stateDir, vm->def->name);
goto cleanup;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index f242db8..b2b0b06 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -756,8 +756,9 @@ networkStartDhcpDaemon(virNetworkObjPtr network)
* pid
*/
- if (virFileReadPid(NETWORK_PID_DIR, network->def->name,
- &network->dnsmasqPid) < 0)
+ ret = virFileReadPid(NETWORK_PID_DIR, network->def->name,
+ &network->dnsmasqPid);
+ if (ret < 0)
goto cleanup;
ret = 0;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 646215e..b87c320 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2754,7 +2754,7 @@ int qemuProcessStart(virConnectPtr conn,
/* wait for qemu process to show up */
if (ret == 0) {
- if (virFileReadPidPath(priv->pidfile, &vm->pid)) {
+ if (virFileReadPidPath(priv->pidfile, &vm->pid) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("Domain %s didn't show up"), vm->def->name);
ret = -1;
diff --git a/src/util/command.c b/src/util/command.c
index 29ccaa4..475eb62 100644
--- a/src/util/command.c
+++ b/src/util/command.c
@@ -493,7 +493,7 @@ virExecWithHook(const char *const*argv,
}
if (pid > 0) {
- if (pidfile && virFileWritePidPath(pidfile,pid)) {
+ if (pidfile && (virFileWritePidPath(pidfile,pid) < 0)) {
kill(pid, SIGTERM);
usleep(500*1000);
kill(pid, SIGTERM);
diff --git a/src/util/util.c b/src/util/util.c
index d83215c..03a9e1a 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1165,17 +1165,17 @@ int virFileWritePid(const char *dir,
char *pidfile = NULL;
if (name == NULL || dir == NULL) {
- rc = EINVAL;
+ rc = -EINVAL;
goto cleanup;
}
if (virFileMakePath(dir) < 0) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
if (!(pidfile = virFilePid(dir, name))) {
- rc = ENOMEM;
+ rc = -ENOMEM;
goto cleanup;
}
@@ -1196,18 +1196,18 @@ int virFileWritePidPath(const char *pidfile,
if ((fd = open(pidfile,
O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR)) < 0) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
if (!(file = VIR_FDOPEN(fd, "w"))) {
- rc = errno;
+ rc = -errno;
VIR_FORCE_CLOSE(fd);
goto cleanup;
}
if (fprintf(file, "%d", pid) < 0) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
@@ -1215,7 +1215,7 @@ int virFileWritePidPath(const char *pidfile,
cleanup:
if (VIR_FCLOSE(file) < 0)
- rc = errno;
+ rc = -errno;
return rc;
}
@@ -1230,18 +1230,18 @@ int virFileReadPidPath(const char *path,
*pid = 0;
if (!(file = fopen(path, "r"))) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
if (fscanf(file, "%d", pid) != 1) {
- rc = EINVAL;
+ rc = -EINVAL;
VIR_FORCE_FCLOSE(file);
goto cleanup;
}
if (VIR_FCLOSE(file) < 0) {
- rc = errno;
+ rc = -errno;
goto cleanup;
}
@@ -1261,12 +1261,12 @@ int virFileReadPid(const char *dir,
*pid = 0;
if (name == NULL || dir == NULL) {
- rc = EINVAL;
+ rc = -EINVAL;
goto cleanup;
}
if (!(pidfile = virFilePid(dir, name))) {
- rc = ENOMEM;
+ rc = -ENOMEM;
goto cleanup;
}
@@ -1284,17 +1284,17 @@ int virFileDeletePid(const char *dir,
char *pidfile = NULL;
if (name == NULL || dir == NULL) {
- rc = EINVAL;
+ rc = -EINVAL;
goto cleanup;
}
if (!(pidfile = virFilePid(dir, name))) {
- rc = ENOMEM;
+ rc = -ENOMEM;
goto cleanup;
}
if (unlink(pidfile) < 0 && errno != ENOENT)
- rc = errno;
+ rc = -errno;
cleanup:
VIR_FREE(pidfile);
diff --git a/tests/commandtest.c b/tests/commandtest.c
index 9ab446c..ef2850d 100644
--- a/tests/commandtest.c
+++ b/tests/commandtest.c
@@ -230,7 +230,7 @@ static int test4(const void *unused ATTRIBUTE_UNUSED)
goto cleanup;
}
- if (virFileReadPid(abs_builddir, "commandhelper", &pid) != 0) {
+ if (virFileReadPid(abs_builddir, "commandhelper", &pid) < 0) {
printf("cannot read pidfile\n");
goto cleanup;
}
@@ -686,7 +686,7 @@ static int test18(const void *unused ATTRIBUTE_UNUSED)
}
alarm(0);
- if (virFileReadPid(abs_builddir, "commandhelper", &pid) != 0) {
+ if (virFileReadPid(abs_builddir, "commandhelper", &pid) < 0) {
printf("cannot read pidfile\n");
goto cleanup;
}
--
1.7.3.4
2
2