...
<devices>
<graphics type='sdl' display=':0.0'/>
- <graphics type='vnc' port='5904'/>
+ <graphics type='vnc' port='5904'>
+ <listen type='address' address='1.2.3.4'/>
+ </graphics>
<graphics type='rdp' autoport='yes' multiUser='yes' />
<graphics type='desktop' fullscreen='yes'/>
+ <graphics type='spice'>
+ <listen type='network' network='rednet'/>
+ </graphics>
</devices>
...</pre>
</dd>
</dl>
+ <p>
+ Rather than putting the address information used to set up the
+ listening socket for graphics types <code>vnc</code>
+ and <code>spice</code> in
+ the <code><graphics></code> <code>listen</code> attribute,
+ 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 will
+ 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>
+
<h4><a name="elementsVideo">Video devices</a></h4>
<p>
A video device.
</choice>
</attribute>
</optional>
+ <ref name="listenElements"/>
</group>
<group>
<attribute name="type">
</attribute>
</optional>
<interleave>
+ <ref name="listenElements"/>
<zeroOrMore>
<element name="channel">
<attribute name="name">
<ref name="addrIPorName"/>
</attribute>
</optional>
+ <ref name="listenElements"/>
</group>
<group>
<attribute name="type">
</choice>
</element>
</define>
+
+ <define name="listenElements">
+ <zeroOrMore>
+ <element name="listen">
+ <choice>
+ <group>
+ <attribute name="type">
+ <value>address</value>
+ </attribute>
+ <attribute name="address">
+ <ref name="addrIPorName"/>
+ </attribute>
+ </group>
+ <group>
+ <attribute name="type">
+ <value>network</value>
+ </attribute>
+ <attribute name="network">
+ <text/>
+ </attribute>
+ <optional>
+ <attribute name="address">
+ <ref name="addrIPorName"/>
+ </attribute>
+ </optional>
+ </group>
+ </choice>
+ </element>
+ </zeroOrMore>
+ </define>
<!--
A video adapter description, allowing configuration of device
model, number of virtual heads, and video ram size
"desktop",
"spice")
+VIR_ENUM_IMPL(virDomainGraphicsListen, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST,
+ "none",
+ "address",
+ "network")
+
VIR_ENUM_IMPL(virDomainGraphicsAuthConnected,
VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_LAST,
"default",
/* 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);
break;
case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
- VIR_FREE(def->data.rdp.listenAddr);
break;
case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
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);
}
return 0;
}
+static int
+virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
+ xmlNodePtr node,
+ unsigned int flags)
+{
+ int ret = -1;
+ char *type = virXMLPropString(node, "type");
+ char *address = virXMLPropString(node, "address");
+ char *network = virXMLPropString(node, "network");
+
+ if (!type) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("graphics listen type must be specified"));
+ goto error;
+ }
+
+ if ((def->type = virDomainGraphicsListenTypeFromString(type)) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("unknown graphics listen type '%s'"), type);
+ goto error;
+ }
+
+ /* address is recognized if either type='address', or if
+ * type='network' and we're looking at live XML (i.e. *not*
+ * inactive). It is otherwise ignored. */
+ if (address && address[0] &&
+ ((def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) ||
+ ((def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK) &&
+ !(flags & VIR_DOMAIN_XML_INACTIVE)))) {
+ def->address = address;
+ address = NULL;
+ }
+
+ if (network && network[0]) {
+ if (def->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK) {
+ /* network='xxx' never makes sense with anything except
+ * type='address' */
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("network attribute not allowed when listen type is not network"));
+ goto error;
+ }
+ def->network = network;
+ network = NULL;
+ }
+
+ ret = 0;
+error:
+ if (ret < 0)
+ virDomainGraphicsListenDefClear(def);
+ VIR_FREE(type);
+ VIR_FREE(address);
+ VIR_FREE(network);
+ 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 *listenAddr = NULL;
+ xmlNodePtr save = ctxt->node;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
return NULL;
}
+ ctxt->node = node;
+
type = virXMLPropString(node, "type");
if (!type) {
goto error;
}
+ if ((def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) ||
+ (def->type == VIR_DOMAIN_GRAPHICS_TYPE_RDP) ||
+ (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)) {
+
+ /* 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 = virDomainGraphicsListenDefParseXML(&def->listens[ii],
+ listenNodes[ii],
+ flags);
+ if (ret < 0)
+ goto error;
+ def->nListens++;
+ }
+ VIR_FREE(listenNodes);
+ }
+
+ /* listen attribute of <graphics> is also supported by these,
+ * but must match the 'address' attribute of the first listen
+ * that is type='address' (if present) */
+ listenAddr = virXMLPropString(node, "listen");
+ if (listenAddr && !listenAddr[0])
+ VIR_FREE(listenAddr);
+
+ if (listenAddr) {
+ if (def->nListens == 0) {
+ /* There were no <listen> elements, so we can just
+ * directly set listenAddr as listens[0]->address */
+ if (virDomainGraphicsListenSetAddress(def, 0, listenAddr,
+ -1, true) < 0)
+ goto error;
+ } else {
+ /* There is at least 1 listen element, so we look for
+ * the first listen of type='address', and make sure
+ * its address matches the listen attribute from
+ * graphics. */
+ bool matched = false;
+ const char *found = NULL;
+ int ii;
+
+ for (ii = 0; ii < nListens; ii++) {
+ if (virDomainGraphicsListenGetType(def, ii)
+ == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) {
+ found = virDomainGraphicsListenGetAddress(def, ii);
+ if (STREQ_NULLABLE(found, listenAddr)) {
+ matched = true;
+ }
+ break;
+ }
+ }
+ if (!matched) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("graphics listen attribute %s must match address "
+ "attribute of first listen element (found %s)"),
+ listenAddr, found ? found : "none");
+ goto error;
+ }
+ }
+ }
+ }
+
if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
char *port = virXMLPropString(node, "port");
char *autoport;
VIR_FREE(autoport);
}
- def->data.vnc.listenAddr = virXMLPropString(node, "listen");
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;
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");
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;
cleanup:
VIR_FREE(type);
+ VIR_FREE(listenNodes);
+ VIR_FREE(listenAddr);
+ ctxt->node = save;
return def;
error:
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,
goto no_memory;
for (i = 0 ; i < n ; i++) {
virDomainGraphicsDefPtr graphics = virDomainGraphicsDefParseXML(nodes[i],
+ ctxt,
flags);
if (!graphics)
goto error;
virDomainGraphicsAuthConnectedTypeToString(def->connected));
}
+
+static void
+virDomainGraphicsListenDefFormat(virBufferPtr buf,
+ virDomainGraphicsListenDefPtr def,
+ 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) ||
+ ((def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK) &&
+ !(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);
+ }
+
+ virBufferAddLit(buf, "/>\n");
+}
+
+
static int
virDomainGraphicsDefFormat(virBufferPtr buf,
virDomainGraphicsDefPtr def,
unsigned int flags)
{
const char *type = virDomainGraphicsTypeToString(def->type);
+ const char *listenAddr = NULL;
int children = 0;
int i;
return -1;
}
+ /* find the first listen element of type='address' and duplicate
+ * its address attribute as the listen attribute of
+ * <graphics>. This is done to improve backward compatibility. */
+ for (i = 0; i < def->nListens; i++) {
+ if (virDomainGraphicsListenGetType(def, i)
+ == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) {
+ listenAddr = virDomainGraphicsListenGetAddress(def, i);
+ break;
+ }
+ }
+
virBufferAsprintf(buf, " <graphics type='%s'", type);
switch (def->type) {
virBufferAsprintf(buf, " autoport='%s'",
def->data.vnc.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)
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;
virBufferAsprintf(buf, " autoport='%s'",
def->data.spice.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'",
}
+ for (i = 0; i < def->nListens; i++) {
+ if (virDomainGraphicsListenGetType(def, i)
+ == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE)
+ continue;
+ if (!children) {
+ virBufferAddLit(buf, ">\n");
+ children = 1;
+ }
+ virDomainGraphicsListenDefFormat(buf, &def->listens[i], 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];
}
return iface->bandwidth;
}
+
+
+/* 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. */
+
+int
+virDomainGraphicsListenGetType(virDomainGraphicsDefPtr def, size_t ii)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, false);
+
+ if (!listenInfo)
+ return VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE;
+ 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. If setType is true, set the listen's type
+ * to 'address', otherwise leave type alone. */
+int
+virDomainGraphicsListenSetAddress(virDomainGraphicsDefPtr def,
+ size_t ii, const char *address,
+ int len, bool setType)
+{
+ virDomainGraphicsListenDefPtr listenInfo
+ = virDomainGraphicsGetListen(def, ii, true);
+
+ if (!listenInfo)
+ return -1;
+
+ if (setType)
+ 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;
+}
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_LAST
};
+enum virDomainGraphicsListenType {
+ VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE = 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;
+};
+
typedef struct _virDomainGraphicsDef virDomainGraphicsDef;
typedef virDomainGraphicsDef *virDomainGraphicsDefPtr;
struct _virDomainGraphicsDef {
struct {
int port;
unsigned int autoport :1;
- char *listenAddr;
char *keymap;
char *socket;
virDomainGraphicsAuthDef auth;
} sdl;
struct {
int port;
- char *listenAddr;
unsigned int autoport :1;
unsigned int replaceUser :1;
unsigned int multiUser :1;
struct {
int port;
int tlsPort;
- char *listenAddr;
char *keymap;
virDomainGraphicsAuthDef auth;
unsigned int autoport :1;
int copypaste;
} spice;
} data;
+ /* nListens, listens, and *port 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 {
int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net);
int virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac);
+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, bool setType)
+ 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);
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)
virDomainGraphicsAuthConnectedTypeFromString;
virDomainGraphicsAuthConnectedTypeToString;
virDomainGraphicsDefFree;
+virDomainGraphicsListenGetAddress;
+virDomainGraphicsListenGetNetwork;
+virDomainGraphicsListenGetType;
+virDomainGraphicsListenSetAddress;
+virDomainGraphicsListenSetNetwork;
+virDomainGraphicsListenSetType;
virDomainGraphicsSpiceChannelModeTypeFromString;
virDomainGraphicsSpiceChannelModeTypeToString;
virDomainGraphicsSpiceChannelNameTypeFromString;
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;
+ const char *listenAddr = NULL;
+ bool escapeAddr;
+
+ listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
+ if (!listenAddr)
+ listenAddr = driver->vncListen;
+
+ escapeAddr = strchr(listenAddr, ':') != NULL;
if (escapeAddr)
- virBufferAsprintf(&opt, "[%s]", addr);
+ virBufferAsprintf(&opt, "[%s]", listenAddr);
else
- virBufferAdd(&opt, addr, -1);
+ virBufferAdd(&opt, listenAddr, -1);
virBufferAsprintf(&opt, ":%d",
def->graphics[0]->data.vnc.port - 5900);
} else if ((def->ngraphics == 1) &&
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
virBuffer opt = VIR_BUFFER_INITIALIZER;
+ const char *listenAddr = NULL;
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SPICE)) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
if (driver->spiceTLS && def->graphics[0]->data.spice.tlsPort != -1)
virBufferAsprintf(&opt, ",tls-port=%u", def->graphics[0]->data.spice.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);
+ listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
+ 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
/* -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 {
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);
+ virDomainGraphicsDefFree(vnc);
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse VNC port '%s'"), tmp+1);
goto error;
}
if (val[0] == '[')
- vnc->data.vnc.listenAddr = strndup(val+1, tmp-(val+1));
+ virDomainGraphicsListenSetAddress(vnc, 0,
+ val+1, tmp-(val+1), true);
else
- vnc->data.vnc.listenAddr = strndup(val, tmp-val);
- if (!vnc->data.vnc.listenAddr) {
- VIR_FREE(vnc);
+ virDomainGraphicsListenSetAddress(vnc, 0,
+ val, tmp-val, true);
+ if (!virDomainGraphicsListenGetAddress(vnc, 0)) {
+ virDomainGraphicsDefFree(vnc);
goto no_memory;
}
vnc->data.vnc.port += 5900;
virDomainGraphicsDefPtr dev)
{
virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
+ const char *oldListenAddr, *newListenAddr;
int ret = -1;
if (!olddev) {
return -1;
}
+ 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) ||
_("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;
_("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;
mig->type = def->type;
if (mig->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
mig->port = def->data.vnc.port;
- listenAddr = def->data.vnc.listenAddr;
+ listenAddr = virDomainGraphicsListenGetAddress(def, 0);
if (!listenAddr)
listenAddr = driver->vncListen;
mig->tlsPort = def->data.spice.tlsPort;
else
mig->tlsPort = -1;
- listenAddr = def->data.spice.listenAddr;
+ listenAddr = virDomainGraphicsListenGetAddress(def, 0);
if (!listenAddr)
listenAddr = driver->spiceListen;
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, true);
VBOX_UTF16_FREE(netAddressUtf16);
VBOX_UTF8_FREE(netAddressUtf8);
}
machine->vtbl->GetVRDEServer(machine, &VRDxServer);
#endif /* VBOX_API_VERSION >= 4000 */
if (VRDxServer) {
+ const char *listenAddr
+ = virDomainGraphicsListenGetAddress(def->graphics[i], 0);
+
VRDxServer->vtbl->SetEnabled(VRDxServer, PR_TRUE);
VIR_DEBUG("VRDP Support turned ON.");
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);
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);
}
{
bool enabled = false;
long long port = 0;
+ char *listenAddr = NULL;
if (def == NULL || *def != NULL) {
VMX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
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",
goto failure;
}
+ if (listenAddr) {
+ if (virDomainGraphicsListenSetAddress(*def, 0, listenAddr, -1, true) < 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");
return 0;
failure:
+ VIR_FREE(listenAddr);
virDomainGraphicsDefFree(*def);
*def = NULL;
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;
def->data.vnc.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) {
graphics->data.vnc.port = port;
if (listenAddr &&
- !(graphics->data.vnc.listenAddr = strdup(listenAddr)))
- goto no_memory;
+ virDomainGraphicsListenSetAddress(graphics, 0, listenAddr, -1, true))
+ goto error;
if (vncPasswd &&
!(graphics->data.vnc.auth.passwd = strdup(vncPasswd)))
no_memory:
virReportOOMError();
+error:
virDomainGraphicsDefFree(graphics);
return -1;
}
graphics->data.vnc.port = port;
if (listenAddr &&
- !(graphics->data.vnc.listenAddr = strdup(listenAddr)))
- goto no_memory;
+ virDomainGraphicsListenSetAddress(graphics, 0, listenAddr, -1, true))
+ goto error;
if (vncPasswd &&
!(graphics->data.vnc.auth.passwd = strdup(vncPasswd)))
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,
virBufferAsprintf(buf, "(vncdisplay %d)", def->data.vnc.port-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)
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,
virBufferAsprintf(buf, "(vncdisplay %d)", def->data.vnc.port-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)
int vmlocaltime = 0;
unsigned long count;
char *script = NULL;
+ char *listenAddr = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
goto cleanup;
graphics->data.vnc.port = (int)vncdisplay + 5900;
}
- if (xenXMConfigCopyStringOpt(conf, "vnclisten", &graphics->data.vnc.listenAddr) < 0)
+
+ if (xenXMConfigCopyStringOpt(conf, "vnclisten", &listenAddr) < 0)
goto cleanup;
+ if (listenAddr &&
+ virDomainGraphicsListenSetAddress(graphics, 0, listenAddr,
+ -1, true) < 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)
if (STREQ(key + 10, "1"))
graphics->data.vnc.autoport = 1;
} else if (STRPREFIX(key, "vnclisten=")) {
- if (!(graphics->data.vnc.listenAddr = strdup(key + 10)))
- goto no_memory;
+ if (virDomainGraphicsListenSetAddress(graphics, 0, key+10,
+ -1, true) < 0)
+ goto cleanup;
} else if (STRPREFIX(key, "vncpasswd=")) {
if (!(graphics->data.vnc.auth.passwd = strdup(key + 10)))
goto no_memory;
virDomainDiskDefFree(disk);
virDomainDefFree(def);
VIR_FREE(script);
+ VIR_FREE(listenAddr);
return NULL;
}
def->graphics[0]->data.sdl.xauth) < 0)
goto no_memory;
} else {
+ const char *listenAddr;
+
if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
xenXMConfigSetInt(conf, "vncdisplay",
def->graphics[0]->data.vnc.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",
virBufferAsprintf(&buf, ",xauthority=%s",
def->graphics[0]->data.sdl.xauth);
} else {
+ 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);
+ 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);
--- /dev/null
+<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'/>
+ </graphics>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
--- /dev/null
+<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='1.2.3.4' autoport='yes'>
+ <listen type='address' address='1.2.3.4'/>
+ <listen type='network' network='Bobsnetwork'/>
+ </graphics>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
<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'/>
<image compression='auto_glz'/>
<jpeg compression='auto'/>
<zlib compression='auto'/>
<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'/>
<channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/>
</graphics>
<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'/>
<channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/>
<image compression='auto_glz'/>
</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'/>
+ </graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</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'/>
+ </graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</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'/>
+ </graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
</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'/>
+ </graphics>
<video>
<model type='xen' vram='4096' heads='1'/>
</video>
--- /dev/null
+<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'/>
+ <listen type='network' network='Bobsnetwork'/>
+ </graphics>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
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");
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);
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
<sound model='sb16'/>
<sound model='es1370'/>
</devices>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
<sound model='sb16'/>
<sound model='es1370'/>
</devices>
</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'/>
+ </graphics>
</devices>
</domain>
</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'/>
+ </graphics>
</devices>
</domain>
</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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>
<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'/>
+ </graphics>
</devices>
</domain>