Attempt to 'fake' reboot if it isn't supported

We do this by attempting vm.shutdown(), followed by a vm.start() when
the vm actually stops. Any manual 'shutdown' or 'destroy' call will undo
the reboot command, similar to how xen acts (on RHEL5 at least).
This commit is contained in:
Cole Robinson 2010-03-17 16:41:50 -04:00
parent 249a9930e8
commit 14e1b166f6
2 changed files with 66 additions and 2 deletions

View File

@ -1178,6 +1178,8 @@ class vmmDomain(vmmDomainBase):
self.toggle_sample_network_traffic()
self.toggle_sample_disk_io()
self.reboot_listener = None
# Determine available XML flags (older libvirt versions will error
# out if passed SECURE_XML, INACTIVE_XML, etc)
(self._inactive_xml_flags,
@ -1231,7 +1233,47 @@ class vmmDomain(vmmDomainBase):
def disk_write_rate(self):
return self._get_record_helper("diskWrRate")
def _unregister_reboot_listener(self):
if self.reboot_listener == None:
return
try:
self.disconnect(self.reboot_listener)
self.reboot_listener = None
except:
pass
def manual_reboot(self):
# Attempt a manual reboot via 'shutdown' followed by startup
def reboot_listener(vm, ignore1, ignore2, self):
if vm.is_crashed():
# Abandon reboot plans
self.reboot_listener = None
return True
if not vm.is_shutoff():
# Not shutoff, continue waiting
return
try:
logging.debug("Fake reboot detected shutdown. Restarting VM")
vm.startup()
except:
logging.exception("Fake reboot startup failed")
self.reboot_listener = None
return True
self._unregister_reboot_listener()
# Request a shutdown
self.shutdown()
self.reboot_listener = util.connect_opt_out(self, "status-changed",
reboot_listener, self)
def shutdown(self):
self._unregister_reboot_listener()
self._backend.shutdown()
self._update_status()
@ -1265,7 +1307,9 @@ class vmmDomain(vmmDomainBase):
self._update_status()
def destroy(self):
self._unregister_reboot_listener()
self._backend.destroy()
self._update_status()
def interfaceStats(self, device):
return self._backend.interfaceStats(device)

View File

@ -834,10 +834,30 @@ class vmmEngine(gobject.GObject):
self.config.set_confirm_poweroff(not skip_prompt)
logging.debug("Rebooting vm '%s'." % vm.get_name())
no_support = False
reboot_err = None
try:
vm.reboot()
except Exception, e:
self.err.show_err(_("Error shutting down domain: %s" % str(e)),
except Exception, reboot_err:
no_support = virtinst.support.is_error_nosupport(reboot_err)
if not no_support:
self.err.show_err(_("Error rebooting domain: %s" %
str(reboot_err)),
"".join(traceback.format_exc()))
if not no_support:
return
# Reboot isn't supported. Let's try to emulate it
logging.debug("Hypervisor doesn't support reboot, let's fake it")
try:
vm.manual_reboot()
except:
logging.exception("Could not fake a reboot")
# Raise the original error message
self.err.show_err(_("Error rebooting domain: %s" %
str(reboot_err)),
"".join(traceback.format_exc()))
def migrate_domain(self, uri, uuid):