qemu: add rendernode argument

Add a new attribute 'rendernode' to <gl> spice element.

Give it to QEMU if qemu supports it (queued for 2.9).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Marc-André Lureau 2017-02-15 01:04:13 +04:00 committed by Michal Privoznik
parent 7f1bdec5fa
commit e5bda10141
11 changed files with 48 additions and 7 deletions

View File

@ -5619,7 +5619,7 @@ qemu-kvm -net nic,model=? /dev/null
&lt;clipboard copypaste='no'/&gt; &lt;clipboard copypaste='no'/&gt;
&lt;mouse mode='client'/&gt; &lt;mouse mode='client'/&gt;
&lt;filetransfer enable='no'/&gt; &lt;filetransfer enable='no'/&gt;
&lt;gl enable='yes'/&gt; &lt;gl enable='yes' rendernode='/dev/dri/by-path/pci-0000:00:02.0-render'/&gt;
&lt;/graphics&gt;</pre> &lt;/graphics&gt;</pre>
<p> <p>
Spice supports variable compression settings for audio, images and Spice supports variable compression settings for audio, images and
@ -5665,6 +5665,11 @@ qemu-kvm -net nic,model=? /dev/null
the <code>gl</code> element, by setting the <code>enable</code> the <code>gl</code> element, by setting the <code>enable</code>
property. (QEMU only, <span class="since">since 1.3.3</span>). property. (QEMU only, <span class="since">since 1.3.3</span>).
</p> </p>
<p>
By default, QEMU will pick the first available GPU DRM render node.
You may specify a DRM render node path to use instead. (QEMU only,
<span class="since">since 3.1.0</span>).
</p>
</dd> </dd>
<dt><code>rdp</code></dt> <dt><code>rdp</code></dt>
<dd> <dd>

View File

@ -3033,6 +3033,11 @@
<attribute name="enable"> <attribute name="enable">
<ref name="virYesNo"/> <ref name="virYesNo"/>
</attribute> </attribute>
<optional>
<attribute name="rendernode">
<ref name="absFilePath"/>
</attribute>
</optional>
<empty/> <empty/>
</element> </element>
</optional> </optional>

View File

@ -1300,6 +1300,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
break; break;
case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
VIR_FREE(def->data.spice.rendernode);
VIR_FREE(def->data.spice.keymap); VIR_FREE(def->data.spice.keymap);
virDomainGraphicsAuthDefClear(&def->data.spice.auth); virDomainGraphicsAuthDefClear(&def->data.spice.auth);
break; break;
@ -12141,11 +12142,13 @@ virDomainGraphicsDefParseXMLSpice(virDomainGraphicsDefPtr def,
def->data.spice.filetransfer = enableVal; def->data.spice.filetransfer = enableVal;
} else if (xmlStrEqual(cur->name, BAD_CAST "gl")) { } else if (xmlStrEqual(cur->name, BAD_CAST "gl")) {
char *enable = virXMLPropString(cur, "enable"); char *enable = virXMLPropString(cur, "enable");
char *rendernode = virXMLPropString(cur, "rendernode");
int enableVal; int enableVal;
if (!enable) { if (!enable) {
virReportError(VIR_ERR_XML_ERROR, "%s", virReportError(VIR_ERR_XML_ERROR, "%s",
_("spice gl element missing enable")); _("spice gl element missing enable"));
VIR_FREE(rendernode);
goto error; goto error;
} }
@ -12154,11 +12157,14 @@ virDomainGraphicsDefParseXMLSpice(virDomainGraphicsDefPtr def,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown enable value '%s'"), enable); _("unknown enable value '%s'"), enable);
VIR_FREE(enable); VIR_FREE(enable);
VIR_FREE(rendernode);
goto error; goto error;
} }
VIR_FREE(enable); VIR_FREE(enable);
def->data.spice.gl = enableVal; def->data.spice.gl = enableVal;
def->data.spice.rendernode = rendernode;
} else if (xmlStrEqual(cur->name, BAD_CAST "mouse")) { } else if (xmlStrEqual(cur->name, BAD_CAST "mouse")) {
char *mode = virXMLPropString(cur, "mode"); char *mode = virXMLPropString(cur, "mode");
int modeVal; int modeVal;
@ -22839,6 +22845,17 @@ virDomainGraphicsListenDefFormatAddr(virBufferPtr buf,
virBufferAsprintf(buf, " listen='%s'", glisten->address); virBufferAsprintf(buf, " listen='%s'", glisten->address);
} }
static void
virDomainSpiceGLDefFormat(virBufferPtr buf, virDomainGraphicsDefPtr def)
{
if (def->data.spice.gl == VIR_TRISTATE_BOOL_ABSENT)
return;
virBufferAsprintf(buf, "<gl enable='%s'",
virTristateBoolTypeToString(def->data.spice.gl));
virBufferEscapeString(buf, " rendernode='%s'", def->data.spice.rendernode);
virBufferAddLit(buf, "/>\n");
}
static int static int
virDomainGraphicsDefFormat(virBufferPtr buf, virDomainGraphicsDefFormat(virBufferPtr buf,
@ -23082,9 +23099,8 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
if (def->data.spice.filetransfer) if (def->data.spice.filetransfer)
virBufferAsprintf(buf, "<filetransfer enable='%s'/>\n", virBufferAsprintf(buf, "<filetransfer enable='%s'/>\n",
virTristateBoolTypeToString(def->data.spice.filetransfer)); virTristateBoolTypeToString(def->data.spice.filetransfer));
if (def->data.spice.gl)
virBufferAsprintf(buf, "<gl enable='%s'/>\n", virDomainSpiceGLDefFormat(buf, def);
virTristateBoolTypeToString(def->data.spice.gl));
} }
if (children) { if (children) {

View File

@ -1544,6 +1544,7 @@ struct _virDomainGraphicsDef {
virTristateBool copypaste; virTristateBool copypaste;
virTristateBool filetransfer; virTristateBool filetransfer;
virTristateBool gl; virTristateBool gl;
char *rendernode;
} spice; } spice;
} data; } data;
/* nListens, listens, and *port are only useful if type is vnc, /* nListens, listens, and *port are only useful if type is vnc,

View File

@ -357,6 +357,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"query-cpu-model-expansion", /* 245 */ "query-cpu-model-expansion", /* 245 */
"virtio-net.host_mtu", "virtio-net.host_mtu",
"spice-rendernode",
); );
@ -2950,6 +2951,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
{ "spice", "unix", QEMU_CAPS_SPICE_UNIX }, { "spice", "unix", QEMU_CAPS_SPICE_UNIX },
{ "drive", "throttling.bps-total-max-length", QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH }, { "drive", "throttling.bps-total-max-length", QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH },
{ "drive", "throttling.group", QEMU_CAPS_DRIVE_IOTUNE_GROUP }, { "drive", "throttling.group", QEMU_CAPS_DRIVE_IOTUNE_GROUP },
{ "spice", "rendernode", QEMU_CAPS_SPICE_RENDERNODE },
}; };
static int static int

View File

@ -393,6 +393,7 @@ typedef enum {
/* 245 */ /* 245 */
QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION, /* qmp query-cpu-model-expansion */ QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION, /* qmp query-cpu-model-expansion */
QEMU_CAPS_VIRTIO_NET_HOST_MTU, /* virtio-net-*.host_mtu */ QEMU_CAPS_VIRTIO_NET_HOST_MTU, /* virtio-net-*.host_mtu */
QEMU_CAPS_SPICE_RENDERNODE, /* -spice rendernode */
QEMU_CAPS_LAST /* this must always be the last item */ QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags; } virQEMUCapsFlags;

View File

@ -7920,6 +7920,16 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
* TristateSwitch helper */ * TristateSwitch helper */
virBufferAsprintf(&opt, "gl=%s,", virBufferAsprintf(&opt, "gl=%s,",
virTristateSwitchTypeToString(graphics->data.spice.gl)); virTristateSwitchTypeToString(graphics->data.spice.gl));
if (graphics->data.spice.rendernode) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("This QEMU doesn't support spice OpenGL rendernode"));
goto error;
}
virBufferAsprintf(&opt, "rendernode=%s,", graphics->data.spice.rendernode);
}
} }
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION)) {

View File

@ -19,6 +19,6 @@ QEMU_AUDIO_DRV=spice \
-drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,\ -drive file=/var/lib/libvirt/images/QEMUGuest1,format=qcow2,if=none,\
id=drive-ide0-0-0,cache=none \ id=drive-ide0-0-0,cache=none \
-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
-spice port=0,gl=on \ -spice port=0,gl=on,rendernode=/dev/dri/foo \
-device virtio-gpu-pci,id=video0,virgl=on,bus=pci.0,addr=0x2 \ -device virtio-gpu-pci,id=video0,virgl=on,bus=pci.0,addr=0x2 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -26,7 +26,7 @@
<input type='mouse' bus='ps2'/> <input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/> <input type='keyboard' bus='ps2'/>
<graphics type='spice' autoport='no'> <graphics type='spice' autoport='no'>
<gl enable='yes'/> <gl enable='yes' rendernode='/dev/dri/foo'/>
</graphics> </graphics>
<video> <video>
<model type='virtio' heads='1'> <model type='virtio' heads='1'>

View File

@ -1725,6 +1725,7 @@ mymain(void)
QEMU_CAPS_VIRTIO_GPU_VIRGL, QEMU_CAPS_VIRTIO_GPU_VIRGL,
QEMU_CAPS_SPICE, QEMU_CAPS_SPICE,
QEMU_CAPS_SPICE_GL, QEMU_CAPS_SPICE_GL,
QEMU_CAPS_SPICE_RENDERNODE,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY); QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
DO_TEST("video-virtio-gpu-secondary", DO_TEST("video-virtio-gpu-secondary",
QEMU_CAPS_DEVICE_VIRTIO_GPU, QEMU_CAPS_DEVICE_VIRTIO_GPU,

View File

@ -31,7 +31,7 @@
<input type='keyboard' bus='ps2'/> <input type='keyboard' bus='ps2'/>
<graphics type='spice'> <graphics type='spice'>
<listen type='none'/> <listen type='none'/>
<gl enable='yes'/> <gl enable='yes' rendernode='/dev/dri/foo'/>
</graphics> </graphics>
<video> <video>
<model type='virtio' heads='1' primary='yes'> <model type='virtio' heads='1' primary='yes'>