spice: expose the QEMU disable file transfer option

spice-server offers an API to disable file transfer messages
on the agent channel between the client and the guest.
This is supported in qemu through the disable-agent-file-xfer option.

This patch exposes this option to libvirt.
Adds a new element 'filetransfer', with one property,
'enable', which accepts a boolean.
Default is enabled, for backward compatibility.

Depends on the capability exported in the first patch of the series.

Signed-off-by: Francesco Romani <fromani@redhat.com>
This commit is contained in:
Francesco Romani 2014-01-16 17:11:15 +01:00 committed by Michal Privoznik
parent 19bbc81276
commit 08d07e5fd8
11 changed files with 131 additions and 4 deletions

View File

@ -4042,6 +4042,7 @@ qemu-kvm -net nic,model=? /dev/null
&lt;streaming mode='filter'/&gt; &lt;streaming mode='filter'/&gt;
&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;/graphics&gt;</pre> &lt;/graphics&gt;</pre>
<p> <p>
Spice supports variable compression settings for audio, Spice supports variable compression settings for audio,
@ -4081,6 +4082,13 @@ qemu-kvm -net nic,model=? /dev/null
<span class="since">since 0.9.11</span>. If no mode is <span class="since">since 0.9.11</span>. If no mode is
specified, the qemu default will be used (client mode). specified, the qemu default will be used (client mode).
</p> </p>
<p>
File transfer functionality (via Spice agent) is set using the
<code>filetransfer</code> element.
It is enabled by default, and can be disabled by setting the
<code>enable</code> property to <code>no</code> ,
since <span class="since">since 1.2.2</span>.
</p>
</dd> </dd>
<dt><code>"rdp"</code></dt> <dt><code>"rdp"</code></dt>
<dd> <dd>

View File

@ -2496,6 +2496,17 @@
<empty/> <empty/>
</element> </element>
</optional> </optional>
<optional>
<element name="filetransfer">
<attribute name="enable">
<choice>
<value>yes</value>
<value>no</value>
</choice>
</attribute>
<empty/>
</element>
</optional>
</interleave> </interleave>
</group> </group>
<group> <group>

View File

@ -604,6 +604,12 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceClipboardCopypaste,
"yes", "yes",
"no"); "no");
VIR_ENUM_IMPL(virDomainGraphicsSpiceAgentFileTransfer,
VIR_DOMAIN_GRAPHICS_SPICE_AGENT_FILE_TRANSFER_LAST,
"default",
"yes",
"no");
VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST, VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST,
"subsystem", "subsystem",
"capabilities") "capabilities")
@ -8562,6 +8568,26 @@ virDomainGraphicsDefParseXML(xmlNodePtr node,
VIR_FREE(copypaste); VIR_FREE(copypaste);
def->data.spice.copypaste = copypasteVal; def->data.spice.copypaste = copypasteVal;
} else if (xmlStrEqual(cur->name, BAD_CAST "filetransfer")) {
char *enable = virXMLPropString(cur, "enable");
int enableVal;
if (!enable) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("spice filetransfer missing enable"));
goto error;
}
if ((enableVal =
virDomainGraphicsSpiceAgentFileTransferTypeFromString(enable)) <= 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown enable value '%s'"), enable);
VIR_FREE(enable);
goto error;
}
VIR_FREE(enable);
def->data.spice.filetransfer = enableVal;
} 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;
@ -16466,7 +16492,7 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
if (!children && (def->data.spice.image || def->data.spice.jpeg || if (!children && (def->data.spice.image || def->data.spice.jpeg ||
def->data.spice.zlib || def->data.spice.playback || def->data.spice.zlib || def->data.spice.playback ||
def->data.spice.streaming || def->data.spice.copypaste || def->data.spice.streaming || def->data.spice.copypaste ||
def->data.spice.mousemode)) { def->data.spice.mousemode || def->data.spice.filetransfer)) {
virBufferAddLit(buf, ">\n"); virBufferAddLit(buf, ">\n");
children = true; children = true;
} }
@ -16491,6 +16517,9 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
if (def->data.spice.copypaste) if (def->data.spice.copypaste)
virBufferAsprintf(buf, " <clipboard copypaste='%s'/>\n", virBufferAsprintf(buf, " <clipboard copypaste='%s'/>\n",
virDomainGraphicsSpiceClipboardCopypasteTypeToString(def->data.spice.copypaste)); virDomainGraphicsSpiceClipboardCopypasteTypeToString(def->data.spice.copypaste));
if (def->data.spice.filetransfer)
virBufferAsprintf(buf, " <filetransfer enable='%s'/>\n",
virDomainGraphicsSpiceAgentFileTransferTypeToString(def->data.spice.filetransfer));
} }
if (children) { if (children) {

View File

@ -1461,6 +1461,14 @@ enum virDomainGraphicsSpiceClipboardCopypaste {
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_LAST VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_LAST
}; };
enum virDomainGraphicsSpiceAgentFileTransfer {
VIR_DOMAIN_GRAPHICS_SPICE_AGENT_FILE_TRANSFER_DEFAULT = 0,
VIR_DOMAIN_GRAPHICS_SPICE_AGENT_FILE_TRANSFER_YES,
VIR_DOMAIN_GRAPHICS_SPICE_AGENT_FILE_TRANSFER_NO,
VIR_DOMAIN_GRAPHICS_SPICE_AGENT_FILE_TRANSFER_LAST
};
enum virDomainGraphicsListenType { enum virDomainGraphicsListenType {
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE = 0, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE = 0,
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS,
@ -1531,6 +1539,7 @@ struct _virDomainGraphicsDef {
int playback; int playback;
int streaming; int streaming;
int copypaste; int copypaste;
int filetransfer;
} 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,
@ -2697,6 +2706,7 @@ VIR_ENUM_DECL(virDomainInputBus)
VIR_ENUM_DECL(virDomainGraphics) VIR_ENUM_DECL(virDomainGraphics)
VIR_ENUM_DECL(virDomainGraphicsListen) VIR_ENUM_DECL(virDomainGraphicsListen)
VIR_ENUM_DECL(virDomainGraphicsAuthConnected) VIR_ENUM_DECL(virDomainGraphicsAuthConnected)
VIR_ENUM_DECL(virDomainGraphicsSpiceAgentFileTransfer)
VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName) VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName)
VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode) VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceImageCompression) VIR_ENUM_DECL(virDomainGraphicsSpiceImageCompression)

View File

@ -235,6 +235,8 @@ virDomainGraphicsListenGetType;
virDomainGraphicsListenSetAddress; virDomainGraphicsListenSetAddress;
virDomainGraphicsListenSetNetwork; virDomainGraphicsListenSetNetwork;
virDomainGraphicsListenSetType; virDomainGraphicsListenSetType;
virDomainGraphicsSpiceAgentFileTransferTypeFromString;
virDomainGraphicsSpiceAgentFileTransferTypeToString;
virDomainGraphicsSpiceChannelModeTypeFromString; virDomainGraphicsSpiceChannelModeTypeFromString;
virDomainGraphicsSpiceChannelModeTypeToString; virDomainGraphicsSpiceChannelModeTypeToString;
virDomainGraphicsSpiceChannelNameTypeFromString; virDomainGraphicsSpiceChannelNameTypeFromString;

View File

@ -7393,6 +7393,15 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
virDomainGraphicsSpiceStreamingModeTypeToString(graphics->data.spice.streaming)); virDomainGraphicsSpiceStreamingModeTypeToString(graphics->data.spice.streaming));
if (graphics->data.spice.copypaste == VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_NO) if (graphics->data.spice.copypaste == VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_NO)
virBufferAddLit(&opt, ",disable-copy-paste"); virBufferAddLit(&opt, ",disable-copy-paste");
if (graphics->data.spice.filetransfer == VIR_DOMAIN_GRAPHICS_SPICE_AGENT_FILE_TRANSFER_NO) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_FILE_XFER_DISABLE)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("This QEMU can't disable file transfers through spice"));
goto error;
} else {
virBufferAddLit(&opt, ",disable-agent-file-xfer");
}
}
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION)) {
/* If qemu supports seamless migration turn it /* If qemu supports seamless migration turn it

View File

@ -0,0 +1,9 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=spice \
/usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor \
unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb -hda \
/dev/HostVG/QEMUGuest1 -spice port=5903,tls-port=5904,addr=127.0.0.1,\
x509-dir=/etc/pki/libvirt-spice,tls-channel=main,plaintext-channel=inputs,\
disable-agent-file-xfer -vga qxl -global qxl-vga.ram_size=67108864 \
-global qxl-vga.vram_size=33554432 \
-device qxl,id=video1,ram_size=67108864,vram_size=67108864,bus=pci.0,addr=0x4 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -0,0 +1,40 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>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' target='0' unit='0'/>
</disk>
<controller type='usb' index='0'/>
<controller type='ide' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
<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'/>
<filetransfer enable='no'/>
</graphics>
<video>
<model type='qxl' ram='65536' vram='32768' heads='1'/>
</video>
<video>
<model type='qxl' ram='65536' vram='65536' heads='1'/>
</video>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -6,7 +6,8 @@ x509-dir=/etc/pki/libvirt-spice,tls-channel=default,tls-channel=main,\
plaintext-channel=inputs,\ plaintext-channel=inputs,\
image-compression=auto_glz,jpeg-wan-compression=auto,\ image-compression=auto_glz,jpeg-wan-compression=auto,\
zlib-glz-wan-compression=auto,\ zlib-glz-wan-compression=auto,\
playback-compression=on,streaming-video=filter,disable-copy-paste -vga \ playback-compression=on,streaming-video=filter,disable-copy-paste,\
qxl -global qxl.ram_size=67108864 -global qxl.vram_size=18874368 \ disable-agent-file-xfer -vga qxl -global qxl.ram_size=67108864 \
-global qxl.vram_size=18874368 \
-device qxl,id=video1,ram_size=67108864,vram_size=33554432,bus=pci.0,addr=0x4 \ -device qxl,id=video1,ram_size=67108864,vram_size=33554432,bus=pci.0,addr=0x4 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -33,6 +33,7 @@
<playback compression='on'/> <playback compression='on'/>
<streaming mode='filter'/> <streaming mode='filter'/>
<clipboard copypaste='no'/> <clipboard copypaste='no'/>
<filetransfer enable='no'/>
</graphics> </graphics>
<video> <video>
<model type='qxl' ram='65536' vram='18432' heads='1'/> <model type='qxl' ram='65536' vram='18432' heads='1'/>

View File

@ -856,7 +856,8 @@ mymain(void)
DO_TEST("graphics-spice", DO_TEST("graphics-spice",
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL, QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE, QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
QEMU_CAPS_DEVICE_QXL); QEMU_CAPS_DEVICE_QXL,
QEMU_CAPS_SPICE_FILE_XFER_DISABLE);
driver.config->spiceSASL = 1; driver.config->spiceSASL = 1;
ignore_value(VIR_STRDUP(driver.config->spiceSASLdir, "/root/.sasl2")); ignore_value(VIR_STRDUP(driver.config->spiceSASLdir, "/root/.sasl2"));
DO_TEST("graphics-spice-sasl", DO_TEST("graphics-spice-sasl",
@ -890,6 +891,12 @@ mymain(void)
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_USB_HUB, QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_USB_HUB,
QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_USB_REDIR, QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_USB_REDIR,
QEMU_CAPS_CHARDEV_SPICEVMC); QEMU_CAPS_CHARDEV_SPICEVMC);
DO_TEST("graphics-spice-agent-file-xfer",
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
QEMU_CAPS_DEVICE_QXL_VGA,
QEMU_CAPS_DEVICE_QXL,
QEMU_CAPS_SPICE_FILE_XFER_DISABLE);
DO_TEST("input-usbmouse", NONE); DO_TEST("input-usbmouse", NONE);
DO_TEST("input-usbtablet", NONE); DO_TEST("input-usbtablet", NONE);