conf: add <listen> subelement to domain <graphics> element

Once it's plugged in, the <listen> element will be an optional
replacement for the "listen" attribute that graphics elements already
have. If the <listen> element is 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" listen attribute is also still
     accepted, and will be stored internally just as if it were a
     separate <listen> element. On output (i.e. format), the address
     attribute of the first <listen> element of type 'address' will be
     duplicated in the legacy "listen" attribute of the <graphic>
     element.

  2) The "listenAddr" attribute has been removed from the unions in
     virDomainGRaphicsDef for graphics types vnc, rdp, and spice.
     This attribute is now in the <listen> subelement (aka
     virDomainGraphicsListenDef)

  3) Helper functions were written to provide simple access
     (both Get and Set) to the listen elements and their attributes.

* src/libvirt_private.syms: export the listen helper functions

* src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c,
  src/qemu/qemu_migration.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) listenAddr
  attribute. 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 "listen" 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.
This commit is contained in:
Laine Stump 2011-07-07 00:20:28 -04:00
parent 3f39a0bf27
commit ef79fb5b5f
57 changed files with 823 additions and 118 deletions

View File

@ -2043,9 +2043,14 @@ qemu-kvm -net nic,model=? /dev/null
...
&lt;devices&gt;
&lt;graphics type='sdl' display=':0.0'/&gt;
&lt;graphics type='vnc' port='5904'/&gt;
&lt;graphics type='vnc' port='5904'&gt;
&lt;listen type='address' address='1.2.3.4'/&gt;
&lt;/graphics&gt;
&lt;graphics type='rdp' autoport='yes' multiUser='yes' /&gt;
&lt;graphics type='desktop' fullscreen='yes'/&gt;
&lt;graphics type='spice'&gt;
&lt;listen type='network' network='rednet'/&gt;
&lt;/graphics&gt;
&lt;/devices&gt;
...</pre>
@ -2191,6 +2196,54 @@ qemu-kvm -net nic,model=? /dev/null
</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>&lt;graphics&gt;</code> <code>listen</code> attribute,
a separate subelement of <code>&lt;graphics&gt;</code>,
called <code>&lt;listen&gt;</code> can be specified (see the
examples above)<span class="since">since
0.9.4</span>. <code>&lt;listen&gt;</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.

View File

@ -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,36 @@
</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

View File

@ -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,
"none",
"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);
}
@ -4018,19 +4037,82 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node,
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) {
@ -4045,6 +4127,78 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
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;
@ -4077,14 +4231,9 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
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;
@ -4149,11 +4298,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");
@ -4215,13 +4359,8 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
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;
@ -4395,7 +4534,10 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, unsigned int flags)
cleanup:
VIR_FREE(type);
VIR_FREE(listenNodes);
VIR_FREE(listenAddr);
ctxt->node = save;
return def;
error:
@ -5264,7 +5406,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,
@ -6513,6 +6655,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;
@ -9423,12 +9566,44 @@ virDomainGraphicsAuthDefFormatAttr(virBufferPtr buf,
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;
@ -9438,6 +9613,17 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
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) {
@ -9457,9 +9643,8 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
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)
@ -9498,8 +9683,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;
@ -9525,9 +9710,8 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
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'",
@ -9538,6 +9722,17 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
}
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];
@ -11405,3 +11600,160 @@ virDomainNetGetActualBandwidth(virDomainNetDefPtr iface)
}
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;
}

View File

@ -761,6 +761,22 @@ enum virDomainGraphicsSpiceClipboardCopypaste {
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 {
@ -769,7 +785,6 @@ struct _virDomainGraphicsDef {
struct {
int port;
unsigned int autoport :1;
char *listenAddr;
char *keymap;
char *socket;
virDomainGraphicsAuthDef auth;
@ -781,7 +796,6 @@ struct _virDomainGraphicsDef {
} sdl;
struct {
int port;
char *listenAddr;
unsigned int autoport :1;
unsigned int replaceUser :1;
unsigned int multiUser :1;
@ -793,7 +807,6 @@ struct _virDomainGraphicsDef {
struct {
int port;
int tlsPort;
char *listenAddr;
char *keymap;
virDomainGraphicsAuthDef auth;
unsigned int autoport :1;
@ -806,6 +819,11 @@ struct _virDomainGraphicsDef {
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 {
@ -1485,6 +1503,24 @@ int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac);
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);
@ -1647,6 +1683,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)

View File

@ -299,6 +299,12 @@ virDomainGetRootFilesystem;
virDomainGraphicsAuthConnectedTypeFromString;
virDomainGraphicsAuthConnectedTypeToString;
virDomainGraphicsDefFree;
virDomainGraphicsListenGetAddress;
virDomainGraphicsListenGetNetwork;
virDomainGraphicsListenGetType;
virDomainGraphicsListenSetAddress;
virDomainGraphicsListenSetNetwork;
virDomainGraphicsListenSetType;
virDomainGraphicsSpiceChannelModeTypeFromString;
virDomainGraphicsSpiceChannelModeTypeToString;
virDomainGraphicsSpiceChannelNameTypeFromString;

View File

@ -4127,14 +4127,18 @@ 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;
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);
@ -4221,6 +4225,7 @@ qemuBuildCommandLine(virConnectPtr conn,
} 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",
@ -4233,10 +4238,11 @@ qemuBuildCommandLine(virConnectPtr conn,
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
@ -5978,7 +5984,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 {
@ -5993,24 +5999,26 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
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;

View File

@ -1052,6 +1052,7 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
virDomainGraphicsDefPtr dev)
{
virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
const char *oldListenAddr, *newListenAddr;
int ret = -1;
if (!olddev) {
@ -1060,6 +1061,9 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
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) ||
@ -1069,8 +1073,7 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
_("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;
@ -1118,8 +1121,7 @@ qemuDomainChangeGraphics(struct qemud_driver *driver,
_("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;

View File

@ -210,7 +210,7 @@ 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;
listenAddr = virDomainGraphicsListenGetAddress(def, 0);
if (!listenAddr)
listenAddr = driver->vncListen;
@ -223,7 +223,7 @@ qemuMigrationCookieGraphicsAlloc(struct qemud_driver *driver,
mig->tlsPort = def->data.spice.tlsPort;
else
mig->tlsPort = -1;
listenAddr = def->data.spice.listenAddr;
listenAddr = virDomainGraphicsListenGetAddress(def, 0);
if (!listenAddr)
listenAddr = driver->spiceListen;

View File

@ -2501,7 +2501,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, true);
VBOX_UTF16_FREE(netAddressUtf16);
VBOX_UTF8_FREE(netAddressUtf8);
}
@ -4532,6 +4533,9 @@ vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
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.");
@ -4576,14 +4580,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 +4597,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);
}

View File

@ -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,6 +1789,12 @@ virVMXParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def)
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");
@ -1806,6 +1813,7 @@ virVMXParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def)
return 0;
failure:
VIR_FREE(listenAddr);
virDomainGraphicsDefFree(*def);
*def = NULL;
@ -3196,6 +3204,8 @@ 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;
@ -3216,9 +3226,9 @@ virVMXFormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer)
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) {

View File

@ -750,8 +750,8 @@ xenParseSxprGraphicsOld(virDomainDefPtr def,
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)))
@ -794,6 +794,7 @@ xenParseSxprGraphicsOld(virDomainDefPtr def,
no_memory:
virReportOOMError();
error:
virDomainGraphicsDefFree(graphics);
return -1;
}
@ -866,8 +867,8 @@ xenParseSxprGraphicsNew(virDomainDefPtr def,
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)))
@ -1437,6 +1438,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,
@ -1463,8 +1466,9 @@ xenFormatSxprGraphicsNew(virDomainGraphicsDefPtr def,
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)
@ -1482,6 +1486,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,
@ -1506,8 +1512,9 @@ xenFormatSxprGraphicsOld(virDomainGraphicsDefPtr def,
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)

View File

@ -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();
@ -860,8 +861,16 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
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)
@ -931,8 +940,9 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
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;
@ -1067,6 +1077,7 @@ cleanup:
virDomainDiskDefFree(disk);
virDomainDefFree(def);
VIR_FREE(script);
VIR_FREE(listenAddr);
return NULL;
}
@ -1646,6 +1657,8 @@ virConfPtr xenFormatXM(virConnectPtr conn,
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)
@ -1657,9 +1670,9 @@ virConfPtr xenFormatXM(virConnectPtr conn,
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",
@ -1683,15 +1696,17 @@ virConfPtr xenFormatXM(virConnectPtr conn,
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);

View File

@ -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'/>
</graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -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='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>

View File

@ -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'/>
<image compression='auto_glz'/>
<jpeg compression='auto'/>
<zlib compression='auto'/>

View File

@ -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'/>
<channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/>
</graphics>

View File

@ -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'/>
<channel name='main' mode='secure'/>
<channel name='inputs' mode='insecure'/>
<image compression='auto_glz'/>

View File

@ -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'/>
</graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>

View File

@ -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'/>
</graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>

View File

@ -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'/>
</graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>

View File

@ -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'/>
</graphics>
<video>
<model type='xen' vram='4096' heads='1'/>
</video>

View File

@ -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'/>
<listen type='network' network='Bobsnetwork'/>
</graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -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);

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
<sound model='sb16'/>
<sound model='es1370'/>
</devices>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
<sound model='sb16'/>
<sound model='es1370'/>
</devices>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>

View File

@ -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'/>
</graphics>
</devices>
</domain>