With this element users will control how SPICE
server behaves upon migration. For now, there's
just one attribute 'seamless' turning seamless
migration on/off/default.
---
docs/formatdomain.html.in | 10 ++++++++++
docs/schemas/domaincommon.rng | 11 +++++++++++
src/conf/domain_conf.c | 31 ++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 10 ++++++++++
src/libvirt_private.syms | 2 ++
5 files changed, 63 insertions(+), 1 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c05f3df..8b87055 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3216,6 +3216,7 @@ qemu-kvm -net nic,model=? /dev/null
<streaming mode='filter'/>
<clipboard copypaste='no'/>
<mouse mode='client'/>
+ <migration seamless='on'/>
</graphics></pre>
<p>
Spice supports variable compression settings for audio,
@@ -3255,6 +3256,15 @@ qemu-kvm -net nic,model=? /dev/null
<span class="since">since 0.9.11</span>. If no mode
is
specified, the qemu default will be used (client mode).
</p>
+ <p>
+ SPICE migration behaviour can be controlled via
+ <code>migration</code> element (<span
class="since">since
+ 0.9.11</span>). Notably, <code>seamless</code>
+ attribute turns on or off seamless migration. Accepted
+ values are <code>on</code> or <code>off</code>. If
you
+ don't specify anything libvirt turns on this feature for
+ old enough qemu.
+ </p>
</dd>
<dt><code>"rdp"</code></dt>
<dd>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index d70f0c2..09e31eb 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2061,6 +2061,17 @@
<empty/>
</element>
</optional>
+ <optional>
+ <element name="migration">
+ <attribute name="seamless">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </attribute>
+ <empty/>
+ </element>
+ </optional>
</interleave>
</group>
<group>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 75756c4..35a3ee8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -500,6 +500,11 @@ VIR_ENUM_IMPL(virDomainGraphicsSpiceClipboardCopypaste,
"default",
"yes",
"no");
+VIR_ENUM_IMPL(virDomainGraphicsSpiceMigrationSeamless,
+ VIR_DOMAIN_GRAPHICS_SPICE_MIGRATION_SEAMLESS_LAST,
+ "default",
+ "on",
+ "off");
VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST,
"subsystem",
@@ -6652,6 +6657,27 @@ virDomainGraphicsDefParseXML(xmlNodePtr node,
VIR_FREE(mode);
def->data.spice.mousemode = modeVal;
+ } else if (xmlStrEqual(cur->name, BAD_CAST "migration")) {
+ char *seamless = virXMLPropString(cur, "seamless");
+ int seamlessVal;
+
+ if (!seamless) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("spice migration missing seamless"));
+ goto error;
+ }
+
+ seamlessVal =
virDomainGraphicsSpiceMigrationSeamlessTypeFromString(seamless);
+ if (seamlessVal <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unknown seamless migration value
'%s'"),
+ seamless);
+ VIR_FREE(seamless);
+ goto error;
+ }
+ VIR_FREE(seamless);
+
+ def->data.spice.seamless = seamlessVal;
}
}
cur = cur->next;
@@ -13249,7 +13275,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.seamless))
{
virBufferAddLit(buf, ">\n");
children = 1;
}
@@ -13274,6 +13300,9 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
if (def->data.spice.copypaste)
virBufferAsprintf(buf, " <clipboard
copypaste='%s'/>\n",
virDomainGraphicsSpiceClipboardCopypasteTypeToString(def->data.spice.copypaste));
+ if (def->data.spice.seamless)
+ virBufferAsprintf(buf, " <migration
seamless='%s'/>\n",
+
virDomainGraphicsSpiceMigrationSeamlessTypeToString(def->data.spice.seamless));
}
if (children) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index b6fb0db..8e61378 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1213,6 +1213,14 @@ enum virDomainGraphicsSpiceClipboardCopypaste {
VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_LAST
};
+enum virDomainGraphicsSpiceMigrationSeamless {
+ VIR_DOMAIN_GRAPHICS_SPICE_MIGRATION_SEAMLESS_DEFAULT = 0,
+ VIR_DOMAIN_GRAPHICS_SPICE_MIGRATION_SEAMLESS_ON,
+ VIR_DOMAIN_GRAPHICS_SPICE_MIGRATION_SEAMLESS_OFF,
+
+ VIR_DOMAIN_GRAPHICS_SPICE_MIGRATION_SEAMLESS_LAST
+};
+
enum virDomainGraphicsListenType {
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE = 0,
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS,
@@ -1280,6 +1288,7 @@ struct _virDomainGraphicsDef {
int playback;
int streaming;
int copypaste;
+ int seamless;
} spice;
} data;
/* nListens, listens, and *port are only useful if type is vnc,
@@ -2198,6 +2207,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
+VIR_ENUM_DECL(virDomainGraphicsSpiceMigrationSeamless)
VIR_ENUM_DECL(virDomainNumatuneMemMode)
VIR_ENUM_DECL(virDomainNumatuneMemPlacementMode)
/* from libvirt.h */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 064e2a6..b2ff153 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -377,6 +377,8 @@ virDomainGraphicsSpiceImageCompressionTypeFromString;
virDomainGraphicsSpiceImageCompressionTypeToString;
virDomainGraphicsSpiceJpegCompressionTypeFromString;
virDomainGraphicsSpiceJpegCompressionTypeToString;
+virDomainGraphicsSpiceMigrationSeamlessTypeFromString;
+virDomainGraphicsSpiceMigrationSeamlessTypeToString;
virDomainGraphicsSpiceMouseModeTypeFromString;
virDomainGraphicsSpiceMouseModeTypeToString;
virDomainGraphicsSpicePlaybackCompressionTypeFromString;
--
1.7.8.6