Allow unsafe migrations in virt-manager

Normally, setting cache=none is required in order to ensure a consistent view
of storage between the source and destination migration hosts. However, some
configurations have that quality without resorting to the use of an O_DIRECT
open (which is what cache=none does), and hence cache=none wouldn't be
necessary.

Unfortunately, libvirt is not able to determine on it's own all the
configurations which require cache=none for migration but in the interest of
safety enforces it when it isn't otherwise able to determine migration safety.

For this reason the libvirt api has an 'unsafe' option which allows the user
to override the safety migration checks.

This patch adds a checkbox to allow unsafe migration to the 'Advanced options'
portion of the migration dialog.

Signed-off-by: Charles Arnold <carnold@suse.com>
This commit is contained in:
Charles Arnold 2013-12-10 14:33:12 -07:00 committed by Cole Robinson
parent e57cd46904
commit 1124043151
3 changed files with 71 additions and 6 deletions

View File

@ -295,6 +295,53 @@
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">6</property>
<child>
<object class="GtkHBox" id="migrate-unsafe-box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label17">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Allow unsafe migration:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">migrate-unsafe</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="migrate-unsafe">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="migrate-maxdowntime-box">
<property name="visible">True</property>
@ -408,7 +455,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
<child>
@ -659,7 +706,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
</object>

View File

@ -1323,7 +1323,7 @@ class vmmDomain(vmmLibvirtObject):
self._backend.migrateSetMaxDowntime(max_downtime, flag)
def migrate(self, destconn, interface=None, rate=0,
live=False, secure=False, meter=None):
live=False, secure=False, unsafe=False, meter=None):
self._install_abort = True
newname = None
@ -1336,6 +1336,9 @@ class vmmDomain(vmmLibvirtObject):
flags |= libvirt.VIR_MIGRATE_PEER2PEER
flags |= libvirt.VIR_MIGRATE_TUNNELLED
if unsafe:
flags |= libvirt.VIR_MIGRATE_UNSAFE
destconn = destconn.get_backend().libvirtconn
logging.debug("Migrating: conn=%s flags=%s dname=%s uri=%s rate=%s",
destconn, flags, newname, interface, rate)

View File

@ -141,6 +141,7 @@ class vmmMigrateDialog(vmmGObjectUI):
self.widget("migrate-rate").set_value(0)
self.widget("migrate-secure").set_active(False)
self.widget("migrate-unsafe").set_active(False)
downtime_box = self.widget("migrate-maxdowntime-box")
support_downtime = self.vm.support_downtime()
@ -168,6 +169,16 @@ class vmmMigrateDialog(vmmGObjectUI):
secure_box.set_sensitive(support_secure)
secure_box.set_tooltip_text(secure_tooltip)
unsafe_box = self.widget("migrate-unsafe-box")
support_unsafe = hasattr(libvirt, "VIR_MIGRATE_UNSAFE")
unsafe_tooltip = ""
if not support_unsafe:
unsafe_tooltip = _("Libvirt version does not support unsafe "
"migration.")
unsafe_box.set_sensitive(support_unsafe)
unsafe_box.set_tooltip_text(unsafe_tooltip)
self.rebuild_dest_rows()
def set_state(self, vm):
@ -228,6 +239,9 @@ class vmmMigrateDialog(vmmGObjectUI):
def get_config_secure(self):
return self.widget("migrate-secure").get_active()
def get_config_unsafe(self):
return self.widget("migrate-unsafe").get_active()
def get_config_max_downtime_enabled(self):
return self.widget("migrate-max-downtime").get_sensitive()
@ -464,6 +478,7 @@ class vmmMigrateDialog(vmmGObjectUI):
max_downtime = self.get_config_max_downtime()
live = not self.get_config_offline()
secure = self.get_config_secure()
unsafe = self.get_config_unsafe()
uri = self.build_migrate_uri(destconn, srcuri)
rate = self.get_config_rate()
if rate:
@ -485,7 +500,7 @@ class vmmMigrateDialog(vmmGObjectUI):
progWin = vmmAsyncJob(
self._async_migrate,
[self.vm, destconn, uri, rate, live, secure, max_downtime],
[self.vm, destconn, uri, rate, live, secure, unsafe, max_downtime],
self._finish_cb, [destconn],
_("Migrating VM '%s'" % self.vm.get_name()),
(_("Migrating VM '%s' from %s to %s. This may take a while.") %
@ -525,7 +540,7 @@ class vmmMigrateDialog(vmmGObjectUI):
def _async_migrate(self, asyncjob,
origvm, origdconn, migrate_uri, rate, live,
secure, max_downtime):
secure, unsafe, max_downtime):
meter = asyncjob.get_meter()
srcconn = origvm.conn
@ -545,6 +560,6 @@ class vmmMigrateDialog(vmmGObjectUI):
timer = self.timeout_add(100, self._async_set_max_downtime,
vm, max_downtime, current_thread)
vm.migrate(dstconn, migrate_uri, rate, live, secure, meter=meter)
vm.migrate(dstconn, migrate_uri, rate, live, secure, unsafe, meter=meter)
if timer:
self.idle_add(GLib.source_remove, timer)