graphics: introduce new listen type 'socket'

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Pavel Hrdina 2016-06-08 10:35:37 +02:00
parent c5caecab7b
commit b6465e1aa4
8 changed files with 116 additions and 5 deletions

View File

@ -5360,6 +5360,14 @@ qemu-kvm -net nic,model=? /dev/null
of the first forward dev will be used.
</p>
</dd>
<dt><code>socket</code> <span class="since">since 1.3.6 (QEMU only)</span></dt>
<dd>
<p>
This listen type tells a graphics server to listen on unix socket.
Attribute <code>socket</code> contains a path to unix socket. If this
attribute is omitted libvirt will generate this path for you.
</p>
</dd>
</dl>
<h4><a name="elementsVideo">Video devices</a></h4>

View File

@ -2976,6 +2976,16 @@
</attribute>
</optional>
</group>
<group>
<attribute name="type">
<value>socket</value>
</attribute>
<optional>
<attribute name="socket">
<ref name="absFilePath"/>
</attribute>
</optional>
</group>
</choice>
</element>
</zeroOrMore>

View File

@ -561,7 +561,8 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST,
VIR_ENUM_IMPL(virDomainGraphicsListen, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST,
"none",
"address",
"network")
"network",
"socket")
VIR_ENUM_IMPL(virDomainGraphicsAuthConnected,
VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_LAST,
@ -1229,6 +1230,7 @@ virDomainGraphicsListenDefClear(virDomainGraphicsListenDefPtr def)
VIR_FREE(def->address);
VIR_FREE(def->network);
VIR_FREE(def->socket);
return;
}
@ -10895,6 +10897,7 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node,
/**
* virDomainGraphicsListenDefParseXML:
* @def: listen def pointer to be filled
* @graphics: graphics def pointer
* @node: xml node of <listen/> element
* @parent: xml node of <graphics/> element
* @flags: bit-wise or of VIR_DOMAIN_DEF_PARSE_*
@ -10906,6 +10909,7 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node,
*/
static int
virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
virDomainGraphicsDefPtr graphics,
xmlNodePtr node,
xmlNodePtr parent,
unsigned int flags)
@ -10914,8 +10918,10 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
char *type = virXMLPropString(node, "type");
char *address = virXMLPropString(node, "address");
char *network = virXMLPropString(node, "network");
char *socket = virXMLPropString(node, "socket");
char *fromConfig = virXMLPropString(node, "fromConfig");
char *addressCompat = NULL;
const char *graphicsType = virDomainGraphicsTypeToString(graphics->type);
int tmp, typeVal;
if (parent)
@ -10934,6 +10940,13 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
}
def->type = typeVal;
if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("listen type 'socket' is not available for "
"graphics type '%s'"), graphicsType);
goto error;
}
if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) {
if (address && addressCompat && STRNEQ(address, addressCompat)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@ -10968,6 +10981,17 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
network = NULL;
}
if (socket && socket[0]) {
if (def->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("'socket' attribute is valid only for listen "
"type 'socket'"));
goto error;
}
def->socket = socket;
socket = NULL;
}
if (fromConfig &&
flags & VIR_DOMAIN_DEF_PARSE_STATUS) {
if (virStrToLong_i(fromConfig, NULL, 10, &tmp) < 0) {
@ -10986,6 +11010,7 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def,
VIR_FREE(type);
VIR_FREE(address);
VIR_FREE(network);
VIR_FREE(socket);
VIR_FREE(fromConfig);
VIR_FREE(addressCompat);
return ret;
@ -11025,7 +11050,7 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def,
goto error;
for (i = 0; i < nListens; i++) {
if (virDomainGraphicsListenDefParseXML(&def->listens[i],
if (virDomainGraphicsListenDefParseXML(&def->listens[i], def,
listenNodes[i],
i == 0 ? node : NULL,
flags) < 0)
@ -21707,6 +21732,13 @@ virDomainGraphicsListenDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, " network='%s'", def->network);
}
if (def->socket &&
def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
!(def->autoGenerated &&
(flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE))) {
virBufferEscapeString(buf, " socket='%s'", def->socket);
}
if (flags & VIR_DOMAIN_DEF_FORMAT_STATUS)
virBufferAsprintf(buf, " fromConfig='%d'", def->fromConfig);
@ -24208,6 +24240,30 @@ virDomainGraphicsListenAppendAddress(virDomainGraphicsDefPtr def,
}
int
virDomainGraphicsListenAppendSocket(virDomainGraphicsDefPtr def,
const char *socket)
{
virDomainGraphicsListenDef listen;
memset(&listen, 0, sizeof(listen));
listen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET;
if (VIR_STRDUP(listen.socket, socket) < 0)
goto error;
if (VIR_APPEND_ELEMENT_COPY(def->listens, def->nListens, listen) < 0)
goto error;
return 0;
error:
VIR_FREE(listen.socket);
return -1;
}
/**
* virDomainNetFind:
* @def: domain's def

View File

@ -1418,6 +1418,7 @@ typedef enum {
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE = 0,
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS,
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK,
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET,
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST
} virDomainGraphicsListenType;
@ -1434,7 +1435,9 @@ struct _virDomainGraphicsListenDef {
virDomainGraphicsListenType type;
char *address;
char *network;
char *socket;
bool fromConfig; /* true if the @address is config file originated */
bool autoGenerated;
};
struct _virDomainGraphicsDef {
@ -2751,6 +2754,9 @@ virDomainGraphicsGetListen(virDomainGraphicsDefPtr def, size_t i);
int virDomainGraphicsListenAppendAddress(virDomainGraphicsDefPtr def,
const char *address)
ATTRIBUTE_NONNULL(1);
int virDomainGraphicsListenAppendSocket(virDomainGraphicsDefPtr def,
const char *socket)
ATTRIBUTE_NONNULL(1);
int virDomainNetGetActualType(virDomainNetDefPtr iface);
const char *virDomainNetGetActualBridgeName(virDomainNetDefPtr iface);

View File

@ -307,6 +307,7 @@ virDomainGraphicsAuthConnectedTypeToString;
virDomainGraphicsDefFree;
virDomainGraphicsGetListen;
virDomainGraphicsListenAppendAddress;
virDomainGraphicsListenAppendSocket;
virDomainGraphicsSpiceChannelModeTypeFromString;
virDomainGraphicsSpiceChannelModeTypeToString;
virDomainGraphicsSpiceChannelNameTypeFromString;

View File

@ -2624,6 +2624,15 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
break;
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
if (STRNEQ_NULLABLE(newlisten->socket, oldlisten->socket)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("cannot change listen socket setting "
"on '%s' graphics"), type);
goto cleanup;
}
break;
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
/* nada */

View File

@ -4080,6 +4080,15 @@ qemuProcessGraphicsSetupListen(virQEMUDriverConfigPtr cfg,
return -1;
break;
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
if (!glisten->socket) {
if (virAsprintf(&glisten->socket, "%s/%s.sock",
priv->libDir, type) < 0)
return -1;
glisten->autoGenerated = true;
}
break;
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
break;

View File

@ -1007,10 +1007,22 @@ get_files(vahControl * ctl)
goto cleanup;
for (i = 0; i < ctl->def->ngraphics; i++) {
if (ctl->def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
ctl->def->graphics[i]->data.vnc.socket &&
vah_add_file(&buf, ctl->def->graphics[i]->data.vnc.socket, "w"))
virDomainGraphicsDefPtr graphics = ctl->def->graphics[i];
size_t n;
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
graphics->data.vnc.socket &&
vah_add_file(&buf, graphics->data.vnc.socket, "w"))
goto cleanup;
for (n = 0; n < graphics->nListens; n++) {
virDomainGraphicsListenDef listenObj = graphics->listens[n];
if (listenObj.type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET &&
listenObj.socket &&
vah_add_file(&buf, listenObj.socket, "rw"))
goto cleanup;
}
}
if (ctl->def->ngraphics == 1 &&