diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 80d9495b2e..ff50214123 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4042,6 +4042,7 @@ qemu-kvm -net nic,model=? /dev/null
<streaming mode='filter'/>
<clipboard copypaste='no'/>
<mouse mode='client'/>
+ <filetransfer enable='no'/>
</graphics>
Spice supports variable compression settings for audio,
@@ -4081,6 +4082,13 @@ qemu-kvm -net nic,model=? /dev/null
since 0.9.11 . If no mode is
specified, the qemu default will be used (client mode).
+
+ File transfer functionality (via Spice agent) is set using the
+ filetransfer
element.
+ It is enabled by default, and can be disabled by setting the
+ enable
property to no
,
+ since since 1.2.2 .
+
"rdp"
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3b20e33795..7f55f24fc0 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2496,6 +2496,17 @@
+
+
+
+
+ yes
+ no
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9e99f3018e..28e24f9555 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -604,6 +604,12 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceClipboardCopypaste,
"yes",
"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,
"subsystem",
"capabilities")
@@ -8562,6 +8568,26 @@ virDomainGraphicsDefParseXML(xmlNodePtr node,
VIR_FREE(copypaste);
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")) {
char *mode = virXMLPropString(cur, "mode");
int modeVal;
@@ -16466,7 +16492,7 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
if (!children && (def->data.spice.image || def->data.spice.jpeg ||
def->data.spice.zlib || def->data.spice.playback ||
def->data.spice.streaming || def->data.spice.copypaste ||
- def->data.spice.mousemode)) {
+ def->data.spice.mousemode || def->data.spice.filetransfer)) {
virBufferAddLit(buf, ">\n");
children = true;
}
@@ -16491,6 +16517,9 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
if (def->data.spice.copypaste)
virBufferAsprintf(buf, " \n",
virDomainGraphicsSpiceClipboardCopypasteTypeToString(def->data.spice.copypaste));
+ if (def->data.spice.filetransfer)
+ virBufferAsprintf(buf, " \n",
+ virDomainGraphicsSpiceAgentFileTransferTypeToString(def->data.spice.filetransfer));
}
if (children) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 77e508253a..d8f2e49ded 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1461,6 +1461,14 @@ enum virDomainGraphicsSpiceClipboardCopypaste {
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 {
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE = 0,
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS,
@@ -1531,6 +1539,7 @@ struct _virDomainGraphicsDef {
int playback;
int streaming;
int copypaste;
+ int filetransfer;
} spice;
} data;
/* 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(virDomainGraphicsListen)
VIR_ENUM_DECL(virDomainGraphicsAuthConnected)
+VIR_ENUM_DECL(virDomainGraphicsSpiceAgentFileTransfer)
VIR_ENUM_DECL(virDomainGraphicsSpiceChannelName)
VIR_ENUM_DECL(virDomainGraphicsSpiceChannelMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceImageCompression)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 92c7aecf72..d1a58f99be 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -235,6 +235,8 @@ virDomainGraphicsListenGetType;
virDomainGraphicsListenSetAddress;
virDomainGraphicsListenSetNetwork;
virDomainGraphicsListenSetType;
+virDomainGraphicsSpiceAgentFileTransferTypeFromString;
+virDomainGraphicsSpiceAgentFileTransferTypeToString;
virDomainGraphicsSpiceChannelModeTypeFromString;
virDomainGraphicsSpiceChannelModeTypeToString;
virDomainGraphicsSpiceChannelNameTypeFromString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 81486df80a..96b882504e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7393,6 +7393,15 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
virDomainGraphicsSpiceStreamingModeTypeToString(graphics->data.spice.streaming));
if (graphics->data.spice.copypaste == VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_NO)
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 qemu supports seamless migration turn it
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-agent-file-xfer.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-agent-file-xfer.args
new file mode 100644
index 0000000000..66f22bcbd6
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-agent-file-xfer.args
@@ -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
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-agent-file-xfer.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-agent-file-xfer.xml
new file mode 100644
index 0000000000..3a3e36619e
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-agent-file-xfer.xml
@@ -0,0 +1,40 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
index 7ddfa64045..8430d9c51b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.args
@@ -6,7 +6,8 @@ x509-dir=/etc/pki/libvirt-spice,tls-channel=default,tls-channel=main,\
plaintext-channel=inputs,\
image-compression=auto_glz,jpeg-wan-compression=auto,\
zlib-glz-wan-compression=auto,\
-playback-compression=on,streaming-video=filter,disable-copy-paste -vga \
-qxl -global qxl.ram_size=67108864 -global qxl.vram_size=18874368 \
+playback-compression=on,streaming-video=filter,disable-copy-paste,\
+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 virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
index b22fbcc762..c2b509545b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice.xml
@@ -33,6 +33,7 @@
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index b0cfa608c0..a25264e8e0 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -856,7 +856,8 @@ mymain(void)
DO_TEST("graphics-spice",
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
- QEMU_CAPS_DEVICE_QXL);
+ QEMU_CAPS_DEVICE_QXL,
+ QEMU_CAPS_SPICE_FILE_XFER_DISABLE);
driver.config->spiceSASL = 1;
ignore_value(VIR_STRDUP(driver.config->spiceSASLdir, "/root/.sasl2"));
DO_TEST("graphics-spice-sasl",
@@ -890,6 +891,12 @@ mymain(void)
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_USB_HUB,
QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_USB_REDIR,
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-usbtablet", NONE);