diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 141942f3b9..81dae6cd30 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -1622,7 +1622,31 @@ class XendDomain: vcpu) except Exception, ex: raise XendError(str(ex)) - + + def domain_reset(self, domid): + """Terminate domain immediately, and then create domain. + + @param domid: Domain ID or Name + @type domid: int or string. + @rtype: None + @raise XendError: Failed to destroy or create + @raise XendInvalidDomain: Domain is not valid + """ + + dominfo = self.domain_lookup_nr(domid) + if not dominfo: + raise XendInvalidDomain(str(domid)) + if dominfo and dominfo.getDomid() == DOM0_ID: + raise XendError("Cannot reset privileged domain %s" % domid) + if dominfo._stateGet() not in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): + raise VMBadState("Domain '%s' is not started" % domid, + POWER_STATE_NAMES[DOM_STATE_RUNNING], + POWER_STATE_NAMES[dominfo._stateGet()]) + try: + dominfo.resetDomain() + except Exception, ex: + raise XendError(str(ex)) + def instance(): """Singleton constructor. Use this instead of the class constructor. diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index a88dfb4a3f..5fa15fd2fa 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -2323,6 +2323,34 @@ class XendDomainInfo: self._cleanup_phantom_devs(paths) + def resetDomain(self): + log.debug("XendDomainInfo.resetDomain(%s)", str(self.domid)) + + old_domid = self.domid + prev_vm_xend = self._listRecursiveVm('xend') + new_dom_info = self.info + try: + self._unwatchVm() + self.destroy() + + new_dom = None + try: + from xen.xend import XendDomain + new_dom_info['domid'] = None + new_dom = XendDomain.instance().domain_create_from_dict( + new_dom_info) + for x in prev_vm_xend[0][1]: + new_dom._writeVm('xend/%s' % x[0], x[1]) + new_dom.waitForDevices() + new_dom.unpause() + except: + if new_dom: + new_dom.destroy() + raise + except: + log.exception('Failed to reset domain %s.', str(old_domid)) + + def resumeDomain(self): log.debug("XendDomainInfo.resumeDomain(%s)", str(self.domid)) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index f5ad85d381..e27393c505 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -107,6 +107,7 @@ SUBCOMMAND_HELP = { 'Migrate a domain to another machine.'), 'pause' : ('', 'Pause execution of a domain.'), 'reboot' : (' [-wa]', 'Reboot a domain.'), + 'reset' : ('', 'Reset a domain.'), 'restore' : (' [-p]', 'Restore a domain from a saved state.'), 'save' : ('[-c] ', @@ -274,6 +275,7 @@ common_commands = [ "migrate", "pause", "reboot", + "reset", "restore", "resume", "save", @@ -303,6 +305,7 @@ domain_commands = [ "pause", "reboot", "rename", + "reset", "restore", "resume", "save", @@ -1248,6 +1251,13 @@ def xm_shutdown(args): from xen.xm import shutdown shutdown.main(["shutdown"] + args) +def xm_reset(args): + arg_check(args, "reset", 1) + dom = args[0] + + # TODO: XenAPI + server.xend.domain.reset(dom) + def xm_pause(args): arg_check(args, "pause", 1) dom = args[0] @@ -2474,6 +2484,7 @@ commands = { "dump-core": xm_dump_core, "reboot": xm_reboot, "rename": xm_rename, + "reset": xm_reset, "restore": xm_restore, "resume": xm_resume, "save": xm_save,