# HG changeset patch # User Wen Congyang <we...@cn.fujitsu.com> # Date 1290569680 -28800 # Node ID 519e30777e538476c18a329984b44d37d27c39c9 # Parent 076759c3ada6fbb26c32d9181fb381097ed6bd0c Add virDomainSetMigrateMaxDowntime support
diff -r 076759c3ada6 -r 519e30777e53 src/virtManager/domain.py --- a/src/virtManager/domain.py Tue Nov 23 20:13:50 2010 -0500 +++ b/src/virtManager/domain.py Wed Nov 24 11:34:40 2010 +0800 @@ -944,6 +944,12 @@ def _XMLDesc(self, flags): return self._backend.XMLDesc(flags) + def support_downtime(self): + # Note: this function has side effect + # if domain supports downtime, the downtime may be overriden to 30ms + return support.check_domain_support(self._backend, + support.SUPPORT_DOMAIN_MIGRATE_DOWNTIME) + def get_info(self): return self._backend.info() @@ -1090,6 +1096,9 @@ if self.get_autostart() != val: self._backend.setAutostart(val) + def migrate_set_max_downtime(self, max_downtime, flag=0): + self._backend.migrateSetMaxDowntime(max_downtime, flag) + def migrate(self, destconn, interface=None, rate=0, live=False, secure=False): newname = None diff -r 076759c3ada6 -r 519e30777e53 src/virtManager/migrate.py --- a/src/virtManager/migrate.py Tue Nov 23 20:13:50 2010 -0500 +++ b/src/virtManager/migrate.py Wed Nov 24 11:34:40 2010 +0800 @@ -23,6 +23,7 @@ import traceback import logging +import threading import virtinst import libvirt @@ -78,6 +79,7 @@ "on_migrate_set_rate_toggled" : self.toggle_set_rate, "on_migrate_set_interface_toggled" : self.toggle_set_interface, "on_migrate_set_port_toggled" : self.toggle_set_port, + "on_migrate_set_maxdowntime_toggled" : self.toggle_set_maxdowntime, }) util.bind_escape_key_close(self) @@ -134,6 +136,8 @@ self.window.get_widget("migrate-set-interface").set_active(False) self.window.get_widget("migrate-set-rate").set_active(False) self.window.get_widget("migrate-set-port").set_active(False) + self.window.get_widget("migrate-set-maxdowntime").set_active(False) + self.window.get_widget("migrate-max-downtime").set_value(30) running = self.vm.is_active() self.window.get_widget("migrate-offline").set_active(not running) @@ -187,6 +191,10 @@ self.window.get_widget("migrate-port").set_sensitive(enable and port_enable) + def toggle_set_maxdowntime(self, src): + enable = src.get_active() + self.window.get_widget("migrate-max-downtime").set_sensitive(enable) + def toggle_set_port(self, src): enable = src.get_active() self.window.get_widget("migrate-port").set_sensitive(enable) @@ -207,9 +215,18 @@ def get_config_offline(self): return self.window.get_widget("migrate-offline").get_active() + + def get_config_max_downtime(self): + if not self.get_config_max_downtime_enabled(): + return 0 + return int(self.window.get_widget("migrate-max-downtime").get_value()) + def get_config_secure(self): return self.window.get_widget("migrate-secure").get_active() + def get_config_max_downtime_enabled(self): + return self.window.get_widget("migrate-max-downtime").get_property("sensitive") + def get_config_rate_enabled(self): return self.window.get_widget("migrate-rate").get_property("sensitive") def get_config_rate(self): @@ -382,6 +399,10 @@ interface = self.get_config_interface() rate = self.get_config_rate() port = self.get_config_port() + max_downtime = self.get_config_max_downtime() + + if self.get_config_max_downtime_enabled() and max_downtime == 0: + return self.err.val_err(_("max downtime must be greater than 0.")) if self.get_config_interface_enabled() and interface == None: return self.err.val_err(_("An interface must be specified.")) @@ -402,6 +423,7 @@ destconn = self.get_config_destconn() srchost = self.vm.get_connection().get_hostname() dsthost = destconn.get_qualified_hostname() + max_downtime = self.get_config_max_downtime() live = not self.get_config_offline() secure = self.get_config_secure() uri = self.build_migrate_uri(destconn) @@ -418,7 +440,8 @@ self.topwin.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) progWin = vmmAsyncJob(self.config, self._async_migrate, - [self.vm, destconn, uri, rate, live, secure], + [self.vm, destconn, uri, rate, live, secure, + max_downtime], title=_("Migrating VM '%s'" % self.vm.get_name()), text=(_("Migrating VM '%s' from %s to %s. " "This may take awhile.") % @@ -437,8 +460,23 @@ destconn.tick(noStatsUpdate=True) self.close() + def _async_set_max_downtime(self, vm, max_downtime, migrate_thread): + if not migrate_thread.isAlive(): + return False + try: + vm.migrate_set_max_downtime(max_downtime, 0) + return False + except Exception, e: + if (isinstance(e, libvirt.libvirtError) and + e.get_error_code() == libvirt.VIR_ERR_OPERATION_INVALID): + # migration has not been started, wait 100 milliseconds + return True + + logging.warning("Error setting migrate downtime: %s" % e) + return False + def _async_migrate(self, origvm, origdconn, migrate_uri, rate, live, - secure, asyncjob): + secure, max_downtime, asyncjob): errinfo = None try: try: @@ -454,7 +492,22 @@ logging.debug("Migrating vm=%s from %s to %s", vm.get_name(), srcconn.get_uri(), dstconn.get_uri()) + timer = None + if max_downtime != 0 and vm.support_downtime(): + # 0 means that the spin box migrate-max-downtime does not + # be enabled. + # + # We should check whether the domain supports downtime + # early, but vm.support_downtime() has side effect, so + # we check it only when user needs to modify downtime... + current_thread = threading.currentThread() + timer = util.safe_timeout_add(100, + self._async_set_max_downtime, + vm, max_downtime, + current_thread) vm.migrate(dstconn, migrate_uri, rate, live, secure) + if timer: + gobject.source_remove(timer) except Exception, e: errinfo = (str(e), ("Unable to migrate guest:\n %s" % "".join(traceback.format_exc()))) diff -r 076759c3ada6 -r 519e30777e53 src/vmm-migrate.glade --- a/src/vmm-migrate.glade Tue Nov 23 20:13:50 2010 -0500 +++ b/src/vmm-migrate.glade Wed Nov 24 11:34:40 2010 +0800 @@ -250,6 +250,99 @@ </packing> </child> <child> + <widget class="GtkHBox" id="migrate-maxdowntime-box"> + <property name="visible">True</property> + <property name="spacing">3</property> + <child> + <widget class="GtkLabel" id="label15"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Max downtime:</property> + <property name="use_markup">True</property> + <property name="use_underline">True</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkCheckButton" id="migrate-set-maxdowntime"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="on_migrate_set_maxdowntime_toggled"/> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="hbox8"> + <property name="visible">True</property> + <property name="spacing">6</property> + <child> + <widget class="GtkHBox" id="hbox9"> + <property name="visible">True</property> + <property name="spacing">6</property> + <child> + <widget class="GtkSpinButton" id="migrate-max-downtime"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + <property name="adjustment">30 0 1000000 1 1000 0</property> + <property name="snap_to_ticks">True</property> + <property name="numeric">True</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label16"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">ms</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkAlignment" id="alignment6"> + <property name="visible">True</property> + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">2</property> + </packing> + </child> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> <widget class="GtkFrame" id="frame1"> <property name="visible">True</property> <property name="label_xalign">0</property> @@ -475,7 +568,7 @@ </widget> <packing> <property name="expand">False</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </widget> _______________________________________________ virt-tools-list mailing list virt-tools-list@redhat.com https://www.redhat.com/mailman/listinfo/virt-tools-list