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@xxxxxxxx> diff --git a/ui/migrate.ui b/ui/migrate.ui index 3b81fbb..cbbbc5c 100644 --- a/ui/migrate.ui +++ b/ui/migrate.ui @@ -296,6 +296,53 @@ </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> <property name="can_focus">False</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> diff --git a/virtManager/domain.py b/virtManager/domain.py index 2fc869a..b0acd93 100644 --- a/virtManager/domain.py +++ b/virtManager/domain.py @@ -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) diff --git a/virtManager/migrate.py b/virtManager/migrate.py index 75dce35..f32dcf1 100644 --- a/virtManager/migrate.py +++ b/virtManager/migrate.py @@ -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) _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list