# HG changeset patch # User Ian Jackson # Date 1277819571 -3600 # Node ID a60c604b5829db6285ff89d8163478330ac12ee2 # Parent 7b00193bd0334606b6f6779c3f14a1667a952fe4 tools/xend, xm: add a command to get the state of VMs add a command "domstate" to get the state of Vms, which may have one state of {'shutoff', 'idle','shutdown','running','crashed','paused' or 'paused by admin"}. For case of pause, I distinguish it into two conditions. One is "paused" the other is "paused by admin". "pasued by admin" means that users pause a domain voluntary by "xm paused VM" or " API" Signed-off-by James (Song Wei) Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomain.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomain.py +++ xen-4.0.1-testing/tools/python/xen/xend/XendDomain.py @@ -250,6 +250,18 @@ class XendDomain: @return: path to config file. """ return os.path.join(self._managed_path(domuuid), CACHED_CONFIG_FILE) + def domain_setpauseflag(self, dom, flag=False): + try: + dominfo = self.domain_lookup_nr(dom) + dominfo.paused_by_admin = flag + except Exception, err: + log.debug("error in in setpauseflag") + def domain_getpauseflag(self, dom): + try: + dominfo = self.domain_lookup_nr(dom) + return dominfo.paused_by_admin + except Exception, err: + log.debug("error in in getpauseflag") def _managed_check_point_path(self, domuuid): """Returns absolute path to check point file for managed domain. Index: xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py @@ -327,6 +327,8 @@ class XendDomainInfo: @type info: dictionary @ivar domid: Domain ID (if VM has started) @type domid: int or None + @ivar paused_by_admin: Is this Domain paused by command or API + @type paused_by_admin: bool @ivar guest_bitsize: the bitsize of guest @type guest_bitsize: int or None @ivar alloc_mem: the memory domain allocated when booting @@ -390,6 +392,7 @@ class XendDomainInfo: self.domid = domid self.guest_bitsize = None self.alloc_mem = None + self.paused_by_admin = False maxmem = self.info.get('memory_static_max', 0) memory = self.info.get('memory_dynamic_max', 0) Index: xen-4.0.1-testing/tools/python/xen/xend/server/SrvDomain.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xend/server/SrvDomain.py +++ xen-4.0.1-testing/tools/python/xen/xend/server/SrvDomain.py @@ -225,6 +225,20 @@ class SrvDomain(SrvDir): self.acceptCommand(req) return self.xd.domain_reset(self.dom.getName()) + def op_do_get_pauseflag(self, op, req): + self.acceptCommand(req) + return req.threadRequest(self.do_get_pauseflag, op, req) + + def do_get_pauseflag(self, _, req): + return self.xd.domain_getpauseflag(self.dom.getName(), req) + + def op_do_set_pauseflag(self, op, req): + self.acceptCommand(req) + return req.threadRequest(self.do_set_pauseflag, op, req) + + def do_set_pauseflag(self, _, req): + return self.xd.domain_setpauseflag(self.dom.getName(), req) + def op_usb_add(self, op, req): self.acceptCommand(req) return req.threadRequest(self.do_usb_add, op, req) Index: xen-4.0.1-testing/tools/python/xen/xm/main.py =================================================================== --- xen-4.0.1-testing.orig/tools/python/xen/xm/main.py +++ xen-4.0.1-testing/tools/python/xen/xm/main.py @@ -165,6 +165,8 @@ SUBCOMMAND_HELP = { #usb 'usb-add' : (' <[host:bus.addr] [host:vendor_id:product_id]>','Add the usb device to FV VM.'), 'usb-del' : (' <[host:bus.addr] [host:vendor_id:product_id]>','Delete the usb device to FV VM.'), + #domstate + 'domstate' : (' ', 'get the state of a domain'), # device commands @@ -370,6 +372,7 @@ common_commands = [ "uptime", "usb-add", "usb-del", + "domstate", "vcpu-set", ] @@ -404,6 +407,7 @@ domain_commands = [ "uptime", "usb-add", "usb-del", + "domstate", "vcpu-list", "vcpu-pin", "vcpu-set", @@ -901,7 +905,6 @@ def getDomains(domain_names, state, full return "-" state_str = "".join([state_on_off(state) for state in states]) - dom_rec.update({'name': dom_rec['name_label'], 'memory_actual': int(dom_metrics_rec['memory_actual'])/1024, 'vcpus': dom_metrics_rec['VCPUs_number'], @@ -1395,8 +1398,10 @@ def xm_pause(args): if serverType == SERVER_XEN_API: server.xenapi.VM.pause(get_single_vm(dom)) + server.xenapi.VM.set_pauseflag(get_single_vm(dom), True) else: server.xend.domain.pause(dom) + server.xend.domain.setpauseflag(dom, True) def xm_unpause(args): arg_check(args, "unpause", 1) @@ -1404,8 +1409,10 @@ def xm_unpause(args): if serverType == SERVER_XEN_API: server.xenapi.VM.unpause(get_single_vm(dom)) + server.xenapi.VM.set_pauseflag(get_single_vm(dom), False) else: server.xend.domain.unpause(dom) + server.xend.domain.setpauseflag(dom, False) def xm_dump_core(args): live = False @@ -1517,6 +1524,32 @@ def xm_usb_add(args): arg_check(args, "usb-add", 2) server.xend.domain.usb_add(args[0],args[1]) +def xm_domstate(args): + arg_check(args, "domstate", 1) + (opitons, params) = getopt.gnu_getopt(args, 's', ['domname=']) + doms = getDomains(params, 'all') + d = parse_doms_info(doms[0]) + state = d['state'] + if state: + if state.find('s') > 0: + print 'shutoff' + elif state.find('b') > 0: + print 'idle' + elif state.find('d') > 0: + print 'shutdown' + elif state.find('r') > 0: + print 'running' + elif state.find('c') > 0: + print 'crashed' + elif state.find('p') > 0: + if server.xend.domain.getpauseflag(args[0]): + print 'paused by admin' + else: + print 'paused' + else: + print 'shutoff' + return + def xm_usb_del(args): arg_check(args, "usb-del", 2) server.xend.domain.usb_del(args[0],args[1]) @@ -3542,6 +3575,8 @@ commands = { #usb "usb-add": xm_usb_add, "usb-del": xm_usb_del, + #domstate + "domstate": xm_domstate, } ## The commands supported by a separate argument parser in xend.xm.