direct-io.hg
changeset 6057:3cd4f2c38aaf
The following patch is a major restructuring of main.py to be more straight forward, and remove as much code as possible.
It does a number of things:
* It implements the standardized options proposed via my RFC for xm
* It restructures the calling of these functions to be function pointers out
of a dictionary, instead of subclasses found through inspection
* It consolidates all help info, making it easier to see that the help
screen looks consistent across commands. (Per command help isn't yet in
this patch just global help)
* It moves object importing into the functions that require them only,
allowing commands like "xm help" to be runable as non root
* It adds command aliasing to provide backwards compatibility with many
commands (i.e. xm balloon)
* It provides more useful error messages is most fail cases
* It implements a short help by default (which takes < 24 screen lines) as
requested by Mark W at OLS
* It attempts to trap more exceptions than before and provide useful errors
based on them (this requires more testing)
This patch makes no changes to any other elements of xen/xm, and works with
all other objects and libraries as is.
Signed-off-by: Sean Dague <sean@dague.net>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
It does a number of things:
* It implements the standardized options proposed via my RFC for xm
* It restructures the calling of these functions to be function pointers out
of a dictionary, instead of subclasses found through inspection
* It consolidates all help info, making it easier to see that the help
screen looks consistent across commands. (Per command help isn't yet in
this patch just global help)
* It moves object importing into the functions that require them only,
allowing commands like "xm help" to be runable as non root
* It adds command aliasing to provide backwards compatibility with many
commands (i.e. xm balloon)
* It provides more useful error messages is most fail cases
* It implements a short help by default (which takes < 24 screen lines) as
requested by Mark W at OLS
* It attempts to trap more exceptions than before and provide useful errors
based on them (this requires more testing)
This patch makes no changes to any other elements of xen/xm, and works with
all other objects and libraries as is.
Signed-off-by: Sean Dague <sean@dague.net>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Tue Aug 09 12:50:22 2005 +0000 (2005-08-09) |
parents | 663f0fb1e444 |
children | 4125b9fea242 |
files | tools/python/xen/xm/main.py |
line diff
1.1 --- a/tools/python/xen/xm/main.py Tue Aug 09 09:34:06 2005 +0000 1.2 +++ b/tools/python/xen/xm/main.py Tue Aug 09 12:50:22 2005 +0000 1.3 @@ -1,28 +1,113 @@ 1.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 1.5 +# (C) Copyright IBM Corp. 2005 1.6 +# Copyright (C) 2004 Mike Wray 1.7 +# 1.8 +# Authors: 1.9 +# Sean Dague <sean at dague dot net> 1.10 +# Mike Wray <mike dot wray at hp dot com> 1.11 +# 1.12 +# This software may be used and distributed according to the terms 1.13 +# of the GNU General Public License v2. Full details on license 1.14 +# terms and conditions are included with this distribution 1.15 + 1.16 """Grand unified management application for Xen. 1.17 """ 1.18 import os 1.19 import os.path 1.20 import sys 1.21 import commands 1.22 +import re 1.23 from getopt import getopt 1.24 import socket 1.25 import warnings 1.26 warnings.filterwarnings('ignore', category=FutureWarning) 1.27 - 1.28 from xen.xend import PrettyPrint 1.29 from xen.xend import sxp 1.30 -# this is a nasty place to stick this in, but required because 1.31 -# log file access is set up via a 5 deep import chain. This 1.32 -# ensures the user sees a useful message instead of a stack trace 1.33 -if os.getuid() != 0: 1.34 - print "xm requires root access to execute, please try again as root" 1.35 - sys.exit(1) 1.36 +from xen.xm.opts import * 1.37 +shorthelp = """Usage: xm <subcommand> [args] 1.38 + Control, list, and manipulate Xen guest instances 1.39 + 1.40 +xm common subcommands: 1.41 + console <DomId> attach to console of DomId 1.42 + create <CfgFile> create a domain based on Config File 1.43 + destroy <DomId> terminate a domain immediately 1.44 + help display this message 1.45 + list [DomId, ...] list information about domains 1.46 + mem-max <DomId> <Mem> set the maximum memory reservation for a domain 1.47 + mem-set <DomId> <Mem> adjust the current memory usage for a domain 1.48 + migrate <DomId> <Host> migrate a domain to another machine 1.49 + pause <DomId> pause execution of a domain 1.50 + reboot <DomId> reboot a domain 1.51 + restore <File> create a domain from a saved state file 1.52 + save <DomId> <File> save domain state (and config) to file 1.53 + shutdown <DomId> shutdown a domain 1.54 + unpause <DomId> unpause a paused domain 1.55 + 1.56 +For a complete list of subcommands run 'xm help --long' 1.57 +For more help on xm see the xm(1) man page 1.58 +For more help on xm create, see the xmdomain.cfg(5) man page""" 1.59 + 1.60 +longhelp = """Usage: xm <subcommand> [args] 1.61 + Control, list, and manipulate Xen guest instances 1.62 + 1.63 +xm full list of subcommands: 1.64 1.65 -from xen.xend.XendClient import XendError, server 1.66 -from xen.xend.XendClient import main as xend_client_main 1.67 -from xen.xm import create, destroy, migrate, shutdown, sysrq 1.68 -from xen.xm.opts import * 1.69 + Domain Commands: 1.70 + console <DomId> attach to console of DomId 1.71 + cpus-list <DomId> <VCpu> get the list of cpus for a VCPU 1.72 + cpus-set <DomId> <VCpu> <CPUS> set which cpus a VCPU can use. 1.73 + create <ConfigFile> create a domain 1.74 + destroy <DomId> terminate a domain immediately 1.75 + domid <DomName> convert a domain name to a domain id 1.76 + domname <DomId> convert a domain id to a domain name 1.77 + list list information about domains 1.78 + mem-max <DomId> <Mem> set domain maximum memory limit 1.79 + mem-set <DomId> <Mem> set the domain's memory dynamically 1.80 + migrate <DomId> <Host> migrate a domain to another machine 1.81 + pause <DomId> pause execution of a domain 1.82 + reboot [-w|-a] <DomId> reboot a domain 1.83 + restore <File> create a domain from a saved state file 1.84 + save <DomId> <File> save domain state (and config) to file 1.85 + shutdown [-w|-a] <DomId> shutdown a domain 1.86 + sysrq <DomId> <letter> send a sysrq to a domain 1.87 + unpause <DomId> unpause a paused domain 1.88 + vcpu-enable <DomId> <VCPU> disable VCPU in a domain 1.89 + vcpu-disable <DomId> <VCPU> enable VCPU in a domain 1.90 + vcpu-list <DomId> get the list of VCPUs for a domain 1.91 + 1.92 + Xen Host Commands: 1.93 + dmesg [--clear] read or clear Xen's message buffer 1.94 + info get information about the xen host 1.95 + log print the xend log 1.96 + 1.97 + Scheduler Commands: 1.98 + bvt <options> set BVT scheduler parameters 1.99 + bvt_ctxallow <Allow> set the BVT scheduler context switch allowance 1.100 + sedf <options> set simple EDF parameters 1.101 + 1.102 + Virtual Device Commands: 1.103 + block-create <DomId> <BackDev> <FrontDev> <Mode> [BackDomId] 1.104 + Create a new virtual block device 1.105 + block-destroy <DomId> <DevId> Destroy a domain's virtual block device 1.106 + block-list <DomId> List virtual block devices for a domain 1.107 + block-refresh <DomId> <DevId> Refresh a virtual block device for a domain 1.108 + network-limit <DomId> <Vif> <Credit> <Period> 1.109 + Limit the transmission rate of a virtual network interface 1.110 + network-list <DomId> List virtual network interfaces for a domain 1.111 + 1.112 +For a short list of subcommands run 'xm help' 1.113 +For more help on xm see the xm(1) man page 1.114 +For more help on xm create, see the xmdomain.cfg(5) man page""" 1.115 + 1.116 +#################################################################### 1.117 +# 1.118 +# Utility functions 1.119 +# 1.120 +#################################################################### 1.121 + 1.122 +def arg_check(args,num,name): 1.123 + if len(args) < num: 1.124 + err("'xm %s' requires %s argument(s)!\n" % (name, num)) 1.125 + usage(name) 1.126 1.127 def unit(c): 1.128 if not c.isalpha(): 1.129 @@ -49,692 +134,318 @@ def int_unit(str, dest): 1.130 else: 1.131 return value * (base / dst_base) 1.132 1.133 -class Group: 1.134 - 1.135 - name = "" 1.136 - info = "" 1.137 - 1.138 - def __init__(self, xm): 1.139 - self.xm = xm 1.140 - self.progs = {} 1.141 - 1.142 - def addprog(self, prog): 1.143 - self.progs[prog.name] = prog 1.144 - 1.145 - def getprog(self, name): 1.146 - return self.progs.get(name) 1.147 +def err(msg): 1.148 + print >>sys.stderr, "Error:", msg 1.149 1.150 - def proglist(self): 1.151 - kl = self.progs.keys() 1.152 - kl.sort() 1.153 - return [ self.getprog(k) for k in kl ] 1.154 - 1.155 - def help(self, args): 1.156 - if self.info: 1.157 - print 1.158 - print self.info 1.159 - print 1.160 - else: 1.161 - print 1.162 - 1.163 - def shortHelp(self, args): 1.164 - self.help(args) 1.165 - for p in self.proglist(): 1.166 - p.shortHelp(args) 1.167 - 1.168 -class Prog: 1.169 - """Base class for sub-programs. 1.170 - """ 1.171 +def handle_xend_error(cmd, dom, ex): 1.172 + error = str(ex) 1.173 + if error == "Not found" and dom != None: 1.174 + err("Domain '%s' not found when running 'xm %s'" % (dom, cmd)) 1.175 + sys.exit(1) 1.176 + else: 1.177 + raise ex 1.178 + 1.179 1.180 - """Program group it belongs to""" 1.181 - group = 'all' 1.182 - """Program name.""" 1.183 - name = '??' 1.184 - """Short program info.""" 1.185 - info = '' 1.186 - 1.187 - def __init__(self, xm): 1.188 - self.xm = xm 1.189 - 1.190 - def err(self, msg): 1.191 - self.xm.err(msg) 1.192 - 1.193 - def help(self, args): 1.194 - self.shortHelp(args) 1.195 - 1.196 - def shortHelp(self, args): 1.197 - print "%-14s %s" % (self.name, self.info) 1.198 +######################################################################### 1.199 +# 1.200 +# Main xm functions 1.201 +# 1.202 +######################################################################### 1.203 1.204 - def main(self, args): 1.205 - """Program main entry point. 1.206 - """ 1.207 - pass 1.208 - 1.209 - 1.210 -class ProgUnknown(Prog): 1.211 +def xm_create(args): 1.212 + from xen.xm import create 1.213 + # ugly hack because the opt parser apparently wants 1.214 + # the subcommand name just to throw it away! 1.215 + args.insert(0,"bogus") 1.216 + create.main(args) 1.217 1.218 - name = 'unknown' 1.219 - info = '' 1.220 - 1.221 - def help(self, args): 1.222 - self.xm.err("Unknown command: %s\nTry '%s help' for more information." 1.223 - % (args[0], self.xm.name)) 1.224 - 1.225 - main = help 1.226 - 1.227 -class Xm: 1.228 - """Main application. 1.229 - """ 1.230 - 1.231 - def __init__(self): 1.232 - self.name = 'xm' 1.233 - self.unknown = ProgUnknown(self) 1.234 - self.progs = {} 1.235 - self.groups = {} 1.236 +def xm_save(args): 1.237 + arg_check(args,2,"save") 1.238 1.239 - def err(self, msg): 1.240 - print >>sys.stderr, "Error:", msg 1.241 - sys.exit(1) 1.242 - 1.243 - def main(self, args): 1.244 - try: 1.245 - self.main_call(args) 1.246 - except socket.error, ex: 1.247 - print >>sys.stderr, ex 1.248 - self.err("Error connecting to xend, is xend running?") 1.249 - except XendError, ex: 1.250 - self.err(str(ex)) 1.251 + dom = args[0] # TODO: should check if this exists 1.252 + savefile = os.path.abspath(args[1]) 1.253 + 1.254 + from xen.xend.XendClient import server 1.255 + server.xend_domain_save(dom, savefile) 1.256 + 1.257 +def xm_restore(args): 1.258 + arg_check(args,1,"restore") 1.259 1.260 - def main_call(self, args): 1.261 - """Main entry point. Dispatches to the progs. 1.262 - """ 1.263 - self.name = args[0] 1.264 - if len(args) < 2: 1.265 - args.append('help') 1.266 - help = self.helparg(args) 1.267 - p = self.getprog(args[1], self.unknown) 1.268 - if help or len(args) < 2: 1.269 - p.help(args[1:]) 1.270 - else: 1.271 - p.main(args[1:]) 1.272 + savefile = os.path.abspath(args[0]) 1.273 1.274 - def helparg(self, args): 1.275 - for a in args: 1.276 - if a in ['-h', '--help']: 1.277 - return 1 1.278 - return 0 1.279 - 1.280 - def prog(self, pklass): 1.281 - """Add a sub-program. 1.282 - 1.283 - pklass program class (Prog subclass) 1.284 - """ 1.285 - p = pklass(self) 1.286 - self.progs[p.name] = p 1.287 - self.getgroup(p.group).addprog(p) 1.288 - return p 1.289 + from xen.xend.XendClient import server 1.290 + info = server.xend_domain_restore(savefile) 1.291 + PrettyPrint.prettyprint(info) 1.292 + id = sxp.child_value(info, 'id') 1.293 + if id is not None: 1.294 + server.xend_domain_unpause(id) 1.295 1.296 - def getprog(self, name, val=None): 1.297 - """Get a sub-program. 1.298 - name Name of the sub-program (or optionally, an unambiguous 1.299 - prefix of its name) 1.300 - val Default return value if no (unique) match is found 1.301 - """ 1.302 - 1.303 - match = None 1.304 - for progname in self.progs.keys(): 1.305 - if progname == name: 1.306 - match = progname 1.307 - break 1.308 - if progname.startswith(name): 1.309 - if not match: 1.310 - match = progname 1.311 - else: 1.312 - return val # name is ambiguous - bail out 1.313 - 1.314 - return self.progs.get(match, val) 1.315 +def xm_migrate(args): 1.316 + # TODO: arg_check 1.317 + from xen.xm import migrate 1.318 + # ugly hack because the opt parser apparently wants 1.319 + # the subcommand name just to throw it away! 1.320 + args.insert(0,"bogus") 1.321 + migrate.main(args) 1.322 1.323 - def group(self, klass): 1.324 - g = klass(self) 1.325 - self.groups[g.name] = g 1.326 - return g 1.327 - 1.328 - def getgroup(self, name): 1.329 - return self.groups[name] 1.330 - 1.331 - def grouplist(self): 1.332 - kl = self.groups.keys() 1.333 - kl.sort() 1.334 - return [ self.getgroup(k) for k in kl ] 1.335 - 1.336 -# Create the application object, then add the sub-program classes. 1.337 -xm = Xm() 1.338 - 1.339 -class GroupAll(Group): 1.340 - 1.341 - name = "all" 1.342 - info = "" 1.343 - 1.344 -xm.group(GroupAll) 1.345 - 1.346 -class GroupDomain(Group): 1.347 +def xm_list(args): 1.348 + use_long = 0 1.349 + show_vcpus = 0 1.350 + (options, params) = getopt(args, 'lv', ['long','vcpus']) 1.351 + 1.352 + n = len(params) 1.353 + for (k, v) in options: 1.354 + if k in ['-l', '--long']: 1.355 + use_long = 1 1.356 + if k in ['-v', '--vcpus']: 1.357 + show_vcpus = 1 1.358 1.359 - name = "domain" 1.360 - info = "Commands on domains:" 1.361 - 1.362 -xm.group(GroupDomain) 1.363 - 1.364 -class GroupScheduler(Group): 1.365 - 1.366 - name = "scheduler" 1.367 - info = "Comands controlling scheduling:" 1.368 - 1.369 -xm.group(GroupScheduler) 1.370 - 1.371 -class GroupHost(Group): 1.372 - 1.373 - name = "host" 1.374 - info = "Commands related to the xen host (node):" 1.375 - 1.376 -xm.group(GroupHost) 1.377 - 1.378 -class GroupConsole(Group): 1.379 - 1.380 - name = "console" 1.381 - info = "Commands related to consoles:" 1.382 - 1.383 -xm.group(GroupConsole) 1.384 - 1.385 -class GroupVbd(Group): 1.386 - 1.387 - name = "vbd" 1.388 - info = "Commands related to virtual block devices:" 1.389 - 1.390 -xm.group(GroupVbd) 1.391 - 1.392 -class GroupVif(Group): 1.393 - 1.394 - name = "vif" 1.395 - info = "Commands related to virtual network interfaces:" 1.396 - 1.397 -xm.group(GroupVif) 1.398 - 1.399 -class ProgHelp(Prog): 1.400 + domsinfo = [] 1.401 + from xen.xend.XendClient import server 1.402 + if n == 0: 1.403 + doms = server.xend_domains() 1.404 + doms.sort() 1.405 + else: 1.406 + doms = params 1.407 + for dom in doms: 1.408 + info = server.xend_domain(dom) 1.409 + domsinfo.append(parse_doms_info(info)) 1.410 + 1.411 + if use_long: 1.412 + # this actually seems like a bad idea, as it just dumps sexp out 1.413 + PrettyPrint.prettyprint(info) 1.414 + elif show_vcpus: 1.415 + xm_show_vcpus(domsinfo) 1.416 + else: 1.417 + xm_brief_list(domsinfo) 1.418 1.419 - name = "help" 1.420 - info = "Print help." 1.421 - 1.422 - def help(self, args): 1.423 - if len(args) == 2: 1.424 - name = args[1] 1.425 - p = self.xm.getprog(name) 1.426 - if p: 1.427 - p.help(args[1:]) 1.428 - else: 1.429 - print '%s: Unknown command: %s' % (self.name, name) 1.430 - else: 1.431 - for g in self.xm.grouplist(): 1.432 - g.shortHelp(args) 1.433 - print "\nTry '%s help CMD' for help on CMD" % self.xm.name 1.434 - 1.435 - main = help 1.436 - 1.437 -xm.prog(ProgHelp) 1.438 - 1.439 -class ProgCreate(Prog): 1.440 - 1.441 - group = 'domain' 1.442 - name = "create" 1.443 - info = """Create a domain.""" 1.444 - 1.445 - def help(self, args): 1.446 - create.main([args[0], '-h']) 1.447 - 1.448 - def main(self, args): 1.449 - create.main(args) 1.450 - 1.451 -xm.prog(ProgCreate) 1.452 - 1.453 -class ProgSave(Prog): 1.454 - group = 'domain' 1.455 - name = "save" 1.456 - info = """Save domain state (and config) to file.""" 1.457 - 1.458 - def help(self, args): 1.459 - print args[0], "DOM FILE" 1.460 - print """\nSave domain with id DOM to FILE.""" 1.461 +def parse_doms_info(info): 1.462 + dominfo = {} 1.463 + dominfo['dom'] = int(sxp.child_value(info, 'id', '-1')) 1.464 + dominfo['name'] = sxp.child_value(info, 'name', '??') 1.465 + dominfo['mem'] = int(sxp.child_value(info, 'memory', '0')) 1.466 + dominfo['cpu'] = str(sxp.child_value(info, 'cpu', '0')) 1.467 + dominfo['vcpus'] = int(sxp.child_value(info, 'vcpus', '0')) 1.468 + # if there is more than 1 cpu, the value doesn't mean much 1.469 + if dominfo['vcpus'] > 1: 1.470 + dominfo['cpu'] = '-' 1.471 + dominfo['state'] = sxp.child_value(info, 'state', '??') 1.472 + dominfo['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0')) 1.473 + # security identifiers 1.474 + if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0): 1.475 + dominfo['ssidref1'] = int(sxp.child_value(info, 'ssidref', '0')) & 0xffff 1.476 + dominfo['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '0')) >> 16) & 0xffff 1.477 + # get out the vcpu information 1.478 + dominfo['vcpulist'] = [] 1.479 + vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', '-1').split('|') 1.480 + cpumap = sxp.child_value(info, 'cpumap', []) 1.481 + mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1 1.482 + count = 0 1.483 + for cpu in vcpu_to_cpu: 1.484 + vcpuinfo = {} 1.485 + vcpuinfo['name'] = sxp.child_value(info, 'name', '??') 1.486 + vcpuinfo['dom'] = int(sxp.child_value(info, 'id', '-1')) 1.487 + vcpuinfo['vcpu'] = int(count) 1.488 + vcpuinfo['cpu'] = int(cpu) 1.489 + vcpuinfo['cpumap'] = int(cpumap[count])&mask 1.490 + count = count + 1 1.491 + dominfo['vcpulist'].append(vcpuinfo) 1.492 + return dominfo 1.493 1.494 - def main(self, args): 1.495 - if len(args) < 3: self.err("%s: Missing arguments" % args[0]) 1.496 - dom = args[1] 1.497 - savefile = os.path.abspath(args[2]) 1.498 - server.xend_domain_save(dom, savefile) 1.499 - 1.500 -xm.prog(ProgSave) 1.501 - 1.502 -class ProgRestore(Prog): 1.503 - group = 'domain' 1.504 - name = "restore" 1.505 - info = """Create a domain from a saved state.""" 1.506 +def xm_brief_list(domsinfo): 1.507 + print 'Name Id Mem(MB) CPU VCPU(s) State Time(s)' 1.508 + for dominfo in domsinfo: 1.509 + if dominfo.has_key("ssidref1"): 1.510 + print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f %s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo) 1.511 + else: 1.512 + print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f" % dominfo) 1.513 1.514 - def help(self, args): 1.515 - print args[0], "FILE" 1.516 - print "\nRestore a domain from FILE." 1.517 - 1.518 - def main(self, args): 1.519 - if len(args) < 2: self.err("%s: Missing arguments" % args[0]) 1.520 - savefile = os.path.abspath(args[1]) 1.521 - info = server.xend_domain_restore(savefile) 1.522 - PrettyPrint.prettyprint(info) 1.523 - id = sxp.child_value(info, 'id') 1.524 - if id is not None: 1.525 - server.xend_domain_unpause(id) 1.526 +def xm_show_vcpus(domsinfo): 1.527 + print 'Name Id VCPU CPU CPUMAP' 1.528 + for dominfo in domsinfo: 1.529 + for vcpuinfo in dominfo['vcpulist']: 1.530 + print ("%(name)-16s %(dom)3d %(vcpu)4d %(cpu)3d 0x%(cpumap)x" % 1.531 + vcpuinfo) 1.532 1.533 -xm.prog(ProgRestore) 1.534 - 1.535 -class ProgMigrate(Prog): 1.536 - group = 'domain' 1.537 - name = "migrate" 1.538 - info = """Migrate a domain to another machine.""" 1.539 - 1.540 - def help(self, args): 1.541 - migrate.help([self.name] + args) 1.542 - 1.543 - def main(self, args): 1.544 - migrate.main(args) 1.545 - 1.546 -xm.prog(ProgMigrate) 1.547 +def xm_vcpu_list(args): 1.548 + args.insert(0,"-v") 1.549 + xm_list(args) 1.550 1.551 -class ProgList(Prog): 1.552 - group = 'domain' 1.553 - name = "list" 1.554 - info = """List information about domains.""" 1.555 - 1.556 - short_options = 'lv' 1.557 - long_options = ['long','vcpus'] 1.558 - 1.559 - def help(self, args): 1.560 - if help: 1.561 - print args[0], '[options] [DOM...]' 1.562 - print """\nGet information about domains. 1.563 - Either all domains or the domains given. 1.564 +def xm_destroy(args): 1.565 + arg_check(args,1,"destroy") 1.566 1.567 - -l, --long Get more detailed information. 1.568 - -v, --vcpus Show VCPU to CPU mapping. 1.569 - """ 1.570 - return 1.571 - 1.572 - def main(self, args): 1.573 - use_long = 0 1.574 - show_vcpus = 0 1.575 - (options, params) = getopt(args[1:], 1.576 - self.short_options, 1.577 - self.long_options) 1.578 - n = len(params) 1.579 - for (k, v) in options: 1.580 - if k in ['-l', '--long']: 1.581 - use_long = 1 1.582 - if k in ['-v', '--vcpus']: 1.583 - show_vcpus = 1 1.584 - 1.585 - if n == 0: 1.586 - doms = server.xend_domains() 1.587 - doms.sort() 1.588 - else: 1.589 - doms = params 1.590 + from xen.xm import destroy 1.591 + # ugly hack because the opt parser apparently wants 1.592 + # the subcommand name just to throw it away! 1.593 + args.insert(0,"bogus") 1.594 + destroy.main(args) 1.595 1.596 - if use_long: 1.597 - self.long_list(doms) 1.598 - elif show_vcpus: 1.599 - self.show_vcpus(doms) 1.600 - else: 1.601 - self.brief_list(doms) 1.602 +# TODO: make reboot do the right thing, right now 1.603 +# reboot and shutdown are exactly the same 1.604 +def xm_reboot(args): 1.605 + arg_check(args,1,"reboot") 1.606 + # ugly hack because the opt parser apparently wants 1.607 + # the subcommand name just to throw it away! 1.608 + args.insert(0,"bogus") 1.609 + from xen.xm import shutdown 1.610 + shutdown.main(args) 1.611 1.612 - def brief_list(self, doms): 1.613 - print 'Name Id Mem(MB) CPU VCPU(s) State Time(s)' 1.614 - for dom in doms: 1.615 - info = server.xend_domain(dom) 1.616 - d = {} 1.617 - d['dom'] = int(sxp.child_value(info, 'id', '-1')) 1.618 - d['name'] = sxp.child_value(info, 'name', '??') 1.619 - d['mem'] = int(sxp.child_value(info, 'memory', '0')) 1.620 - d['cpu'] = str(sxp.child_value(info, 'cpu', '0')) 1.621 - d['vcpus'] = int(sxp.child_value(info, 'vcpus', '0')) 1.622 - d['state'] = sxp.child_value(info, 'state', '??') 1.623 - d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0')) 1.624 - if d['vcpus'] > 1: 1.625 - d['cpu'] = '-' 1.626 - if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0): 1.627 - d['ssidref1'] = int(sxp.child_value(info, 'ssidref', '0')) & 0xffff 1.628 - d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '0')) >> 16) & 0xffff 1.629 - print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f %s:%(ssidref2)02x/p:%(ssidref1)02x" % d) 1.630 - else: 1.631 - print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f" % d) 1.632 +def xm_shutdown(args): 1.633 + arg_check(args,1,"shutdown") 1.634 1.635 - def show_vcpus(self, doms): 1.636 - print 'Name Id VCPU CPU CPUMAP' 1.637 - for dom in doms: 1.638 - info = server.xend_domain(dom) 1.639 - vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', '-1').split('|') 1.640 - cpumap = sxp.child_value(info, 'cpumap', []) 1.641 - mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1 1.642 - count = 0 1.643 - for cpu in vcpu_to_cpu: 1.644 - d = {} 1.645 - d['name'] = sxp.child_value(info, 'name', '??') 1.646 - d['dom'] = int(sxp.child_value(info, 'id', '-1')) 1.647 - d['vcpu'] = int(count) 1.648 - d['cpu'] = int(cpu) 1.649 - d['cpumap'] = int(cpumap[count])&mask 1.650 - count = count + 1 1.651 - print ("%(name)-16s %(dom)3d %(vcpu)4d %(cpu)3d 0x%(cpumap)x" % d) 1.652 + # ugly hack because the opt parser apparently wants 1.653 + # the subcommand name just to throw it away! 1.654 + args.insert(0,"bogus") 1.655 + from xen.xm import shutdown 1.656 + shutdown.main(args) 1.657 + 1.658 +def xm_sysrq(args): 1.659 + from xen.xm import sysrq 1.660 + # ugly hack because the opt parser apparently wants 1.661 + # the subcommand name just to throw it away! 1.662 + args.insert(0,"bogus") 1.663 + sysrq.main(args) 1.664 1.665 - def long_list(self, doms): 1.666 - for dom in doms: 1.667 - info = server.xend_domain(dom) 1.668 - PrettyPrint.prettyprint(info) 1.669 - 1.670 -xm.prog(ProgList) 1.671 +def xm_pause(args): 1.672 + arg_check(args, 1, "pause") 1.673 + dom = args[0] 1.674 1.675 -class ProgDestroy(Prog): 1.676 - group = 'domain' 1.677 - name = "destroy" 1.678 - info = """Terminate a domain immediately.""" 1.679 - 1.680 - def help(self, args): 1.681 - destroy.main([args[0], '-h']) 1.682 - 1.683 - def main(self, args): 1.684 - destroy.main(args) 1.685 - 1.686 -xm.prog(ProgDestroy) 1.687 + from xen.xend.XendClient import server 1.688 + server.xend_domain_pause(dom) 1.689 1.690 -class ProgShutdown(Prog): 1.691 - group = 'domain' 1.692 - name = "shutdown" 1.693 - info = """Shutdown a domain.""" 1.694 - 1.695 - def help(self, args): 1.696 - shutdown.main([args[0], '-h']) 1.697 - 1.698 - def main(self, args): 1.699 - shutdown.main(args) 1.700 +def xm_unpause(args): 1.701 + arg_check(args, 1, "unpause") 1.702 + dom = args[0] 1.703 1.704 -xm.prog(ProgShutdown) 1.705 + from xen.xend.XendClient import server 1.706 + server.xend_domain_unpause(dom) 1.707 1.708 -class ProgSysrq(Prog): 1.709 - group = 'domain' 1.710 - name = "sysrq" 1.711 - info = """Send a sysrq to a domain.""" 1.712 - 1.713 - def help(self, args): 1.714 - sysrq.main([args[0], '-h']) 1.715 - 1.716 - def main(self, args): 1.717 - sysrq.main(args) 1.718 +############################################################# 1.719 1.720 -xm.prog(ProgSysrq) 1.721 - 1.722 -class ProgPause(Prog): 1.723 - group = 'domain' 1.724 - name = "pause" 1.725 - info = """Pause execution of a domain.""" 1.726 - 1.727 - def help(self, args): 1.728 - print args[0], 'DOM' 1.729 - print '\nPause execution of domain DOM.' 1.730 - 1.731 - def main(self, args): 1.732 - if len(args) < 2: self.err("%s: Missing domain" % args[0]) 1.733 - dom = args[1] 1.734 - server.xend_domain_pause(dom) 1.735 - 1.736 -xm.prog(ProgPause) 1.737 +def cpu_make_map(cpulist): 1.738 + cpus = [] 1.739 + cpumap = 0 1.740 + for c in cpulist.split(','): 1.741 + if c.find('-') != -1: 1.742 + (x,y) = c.split('-') 1.743 + for i in range(int(x),int(y)+1): 1.744 + cpus.append(int(i)) 1.745 + else: 1.746 + cpus.append(int(c)) 1.747 + cpus.sort() 1.748 + for c in cpus: 1.749 + cpumap = cpumap | 1<<c 1.750 1.751 -class ProgUnpause(Prog): 1.752 - group = 'domain' 1.753 - name = "unpause" 1.754 - info = """Unpause a paused domain.""" 1.755 - 1.756 - def help(self, args): 1.757 - print args[0], 'DOM' 1.758 - print '\nUnpause execution of domain DOM.' 1.759 - 1.760 - def main(self, args): 1.761 - if len(args) < 2: self.err("%s: Missing domain" % args[0]) 1.762 - dom = args[1] 1.763 - server.xend_domain_unpause(dom) 1.764 - 1.765 -xm.prog(ProgUnpause) 1.766 - 1.767 -class ProgPincpu(Prog): 1.768 - group = 'domain' 1.769 - name = "pincpu" 1.770 - info = """Set which cpus a VCPU can use. """ 1.771 - 1.772 - def help(self, args): 1.773 - print args[0],'DOM VCPU CPUS' 1.774 - print '\nSet which cpus VCPU in domain DOM can use.' 1.775 + return cpumap 1.776 1.777 - # convert list of cpus to bitmap integer value 1.778 - def make_map(self, cpulist): 1.779 - cpus = [] 1.780 - cpumap = 0 1.781 - for c in cpulist.split(','): 1.782 - if c.find('-') != -1: 1.783 - (x,y) = c.split('-') 1.784 - for i in range(int(x),int(y)+1): 1.785 - cpus.append(int(i)) 1.786 - else: 1.787 - cpus.append(int(c)) 1.788 - cpus.sort() 1.789 - for c in cpus: 1.790 - cpumap = cpumap | 1<<c 1.791 - 1.792 - return cpumap 1.793 +def xm_cpus_set(args): 1.794 + arg_check(args, 3, "cpus-set") 1.795 + 1.796 + dom = args[0] 1.797 + vcpu = int(args[1]) 1.798 + cpumap = cpu_make_map(args[2]) 1.799 + 1.800 + from xen.xend.XendClient import server 1.801 + server.xend_domain_pincpu(dom, vcpu, cpumap) 1.802 1.803 - def main(self, args): 1.804 - if len(args) != 4: self.err("%s: Invalid argument(s)" % args[0]) 1.805 - dom = args[1] 1.806 - vcpu = int(args[2]) 1.807 - cpumap = self.make_map(args[3]); 1.808 - server.xend_domain_pincpu(dom, vcpu, cpumap) 1.809 - 1.810 -xm.prog(ProgPincpu) 1.811 +def xm_mem_max(args): 1.812 + arg_check(args, 2, "mem-max") 1.813 + 1.814 + dom = args[0] 1.815 + mem = int_unit(args[1], 'm') 1.816 1.817 -class ProgMaxmem(Prog): 1.818 - group = 'domain' 1.819 - name = 'maxmem' 1.820 - info = """Set domain memory limit.""" 1.821 - 1.822 - def help(self, args): 1.823 - print args[0], "DOM MEMORY" 1.824 - print "\nSet the memory limit for domain DOM to MEMORY megabytes." 1.825 - 1.826 - def main(self, args): 1.827 - if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0]) 1.828 - dom = args[1] 1.829 - mem = int_unit(args[2], 'm') 1.830 - server.xend_domain_maxmem_set(dom, mem) 1.831 - 1.832 -xm.prog(ProgMaxmem) 1.833 + from xen.xend.XendClient import server 1.834 + server.xend_domain_maxmem_set(dom, mem) 1.835 + 1.836 +def xm_mem_set(args): 1.837 + arg_check(args, 2, "mem-set") 1.838 + 1.839 + dom = args[0] 1.840 + mem_target = int_unit(args[1], 'm') 1.841 1.842 -class ProgSetMem(Prog): 1.843 - group = 'domain' 1.844 - name = 'set-mem' 1.845 - info = """Set the domain's memory footprint using the balloon driver.""" 1.846 - 1.847 - def help(self, args): 1.848 - print args[0], "DOM MEMORY_TARGET" 1.849 - print """\nRequest domain DOM to adjust its memory footprint to 1.850 -MEMORY_TARGET megabytes""" 1.851 - 1.852 - def main(self, args): 1.853 - if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0]) 1.854 - dom = args[1] 1.855 - mem_target = int_unit(args[2], 'm') 1.856 - server.xend_domain_mem_target_set(dom, mem_target) 1.857 - 1.858 -xm.prog(ProgSetMem) 1.859 - 1.860 -class ProgVcpuhotplug(Prog): 1.861 - group = 'domain' 1.862 - name = 'vcpu-hotplug' 1.863 - info = """Enable or disable a VCPU in a domain.""" 1.864 - 1.865 - def help(self, args): 1.866 - print args[0], "DOM VCPU [0|1]" 1.867 - print """\nRequest virtual processor VCPU to be disabled or enabled in 1.868 -domain DOM""" 1.869 - 1.870 - def main(self, args): 1.871 - if len(args) != 4: self.err("%s: Invalid arguments(s)" % args[0]) 1.872 - name = args[1] 1.873 - vcpu = int(args[2]) 1.874 - state = int(args[3]) 1.875 - dom = server.xend_domain(name) 1.876 - id = sxp.child_value(dom, 'id') 1.877 - server.xend_domain_vcpu_hotplug(id, vcpu, state) 1.878 - 1.879 -xm.prog(ProgVcpuhotplug) 1.880 - 1.881 -class ProgDomid(Prog): 1.882 - group = 'domain' 1.883 - name = 'domid' 1.884 - info = 'Convert a domain name to a domain id.' 1.885 + from xen.xend.XendClient import server 1.886 + server.xend_domain_mem_target_set(dom, mem_target) 1.887 + 1.888 +# TODO: why does this lookup by name? and what if that fails!? 1.889 +def xm_vcpu_enable(args): 1.890 + arg_check(args, 2, "vcpu-enable") 1.891 + 1.892 + name = args[0] 1.893 + vcpu = int(args[1]) 1.894 + 1.895 + from xen.xend.XendClient import server 1.896 + dom = server.xend_domain(name) 1.897 + id = sxp.child_value(dom, 'id') 1.898 + server.xend_domain_vcpu_hotplug(id, vcpu, 1) 1.899 1.900 - def help(self, args): 1.901 - print args[0], "DOM" 1.902 - print '\nGet the domain id for the domain with name DOM.' 1.903 - 1.904 - def main (self, args): 1.905 - if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0]) 1.906 - name = args[1] 1.907 - dom = server.xend_domain(name) 1.908 - print sxp.child_value(dom, 'id') 1.909 - 1.910 -xm.prog(ProgDomid) 1.911 - 1.912 -class ProgDomname(Prog): 1.913 - group = 'domain' 1.914 - name = 'domname' 1.915 - info = 'Convert a domain id to a domain name.' 1.916 +def xm_vcpu_disable(args): 1.917 + arg_check(args, 2, "vcpu-disable") 1.918 + 1.919 + name = args[0] 1.920 + vcpu = int(args[1]) 1.921 + 1.922 + from xen.xend.XendClient import server 1.923 + dom = server.xend_domain(name) 1.924 + id = sxp.child_value(dom, 'id') 1.925 + server.xend_domain_vcpu_hotplug(id, vcpu, 0) 1.926 1.927 - def help(self, args): 1.928 - print args[0], "DOM" 1.929 - print '\nGet the name for the domain with id DOM.' 1.930 - 1.931 - def main (self, args): 1.932 - if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0]) 1.933 - name = args[1] 1.934 - dom = server.xend_domain(name) 1.935 - print sxp.child_value(dom, 'name') 1.936 - 1.937 -xm.prog(ProgDomname) 1.938 +def xm_domid(args): 1.939 + name = args[0] 1.940 1.941 -class ProgBvt(Prog): 1.942 - group = 'scheduler' 1.943 - name = "bvt" 1.944 - info = """Set BVT scheduler parameters.""" 1.945 + from xen.xend.XendClient import server 1.946 + dom = server.xend_domain(name) 1.947 + print sxp.child_value(dom, 'id') 1.948 1.949 - def help(self, args): 1.950 - print args[0], "DOM MCUADV WARPBACK WARPVALUE WARPL WARPU" 1.951 - print '\nSet Borrowed Virtual Time scheduler parameters.' 1.952 +def xm_domname(args): 1.953 + name = args[0] 1.954 1.955 - def main(self, args): 1.956 - if len(args) != 7: self.err("%s: Invalid argument(s)" % args[0]) 1.957 - dom = args[1] 1.958 - v = map(long, args[2:7]) 1.959 - server.xend_domain_cpu_bvt_set(dom, *v) 1.960 + from xen.xend.XendClient import server 1.961 + dom = server.xend_domain(name) 1.962 + print sxp.child_value(dom, 'name') 1.963 1.964 -xm.prog(ProgBvt) 1.965 - 1.966 -class ProgBvtslice(Prog): 1.967 - group = 'scheduler' 1.968 - name = "bvt_ctxallow" 1.969 - info = """Set the BVT scheduler context switch allowance.""" 1.970 +def xm_bvt(args): 1.971 + arg_check(args, 6, "bvt") 1.972 + dom = args[0] 1.973 + v = map(long, args[1:6]) 1.974 + from xen.xend.XendClient import server 1.975 + server.xend_domain_cpu_bvt_set(dom, *v) 1.976 1.977 - def help(self, args): 1.978 - print args[0], 'CTX_ALLOW' 1.979 - print '\nSet Borrowed Virtual Time scheduler context switch allowance.' 1.980 - 1.981 - def main(self, args): 1.982 - if len(args) < 2: self.err('%s: Missing context switch allowance' 1.983 - % args[0]) 1.984 - slice = int(args[1]) 1.985 - server.xend_node_cpu_bvt_slice_set(slice) 1.986 - 1.987 -xm.prog(ProgBvtslice) 1.988 +def xm_bvt_ctxallow(args): 1.989 + arg_check(args, 1, "bvt_ctxallow") 1.990 1.991 -class ProgSedf(Prog): 1.992 - group = 'scheduler' 1.993 - name= "sedf" 1.994 - info = """Set simple EDF parameters.""" 1.995 - 1.996 - def help(self, args): 1.997 - print args[0], "DOM PERIOD SLICE LATENCY EXTRATIME WEIGHT" 1.998 - print "\nSet simple EDF parameters." 1.999 + slice = int(args[0]) 1.1000 + from xen.xend.XendClient import server 1.1001 + server.xend_node_cpu_bvt_slice_set(slice) 1.1002 1.1003 - def main(self, args): 1.1004 - if len(args) != 7: self.err("%s: Invalid argument(s)" % args[0]) 1.1005 - dom = args[1] 1.1006 - v = map(int, args[2:7]) 1.1007 - server.xend_domain_cpu_sedf_set(dom, *v) 1.1008 - 1.1009 -xm.prog(ProgSedf) 1.1010 - 1.1011 -class ProgInfo(Prog): 1.1012 - group = 'host' 1.1013 - name = "info" 1.1014 - info = """Get information about the xen host.""" 1.1015 +def xm_sedf(args): 1.1016 + arg_check(args, 6, "sedf") 1.1017 + 1.1018 + dom = args[0] 1.1019 + v = map(int, args[1:5]) 1.1020 + from xen.xend.XendClient import server 1.1021 + server.xend_domain_cpu_sedf_set(dom, *v) 1.1022 1.1023 - def main(self, args): 1.1024 - info = server.xend_node() 1.1025 - for x in info[1:]: 1.1026 - print "%-23s:" % x[0], x[1] 1.1027 - 1.1028 -xm.prog(ProgInfo) 1.1029 - 1.1030 -class ProgConsole(Prog): 1.1031 - group = 'console' 1.1032 - name = "console" 1.1033 - info = """Open a console to a domain.""" 1.1034 +def xm_info(args): 1.1035 + from xen.xend.XendClient import server 1.1036 + info = server.xend_node() 1.1037 1.1038 - def help(self, args): 1.1039 - print args[0], "DOM" 1.1040 - print "\nOpen a console to domain DOM." 1.1041 + for x in info[1:]: 1.1042 + print "%-23s:" % x[0], x[1] 1.1043 1.1044 - def main(self, args): 1.1045 - if len(args) < 2: self.err("%s: Missing domain" % args[0]) 1.1046 - dom = args[1] 1.1047 - info = server.xend_domain(dom) 1.1048 - domid = int(sxp.child_value(info, 'id', '-1')) 1.1049 - cmd = "/usr/libexec/xen/xenconsole %d" % domid 1.1050 - os.execvp('/usr/libexec/xen/xenconsole', cmd.split()) 1.1051 +# TODO: remove as soon as console server shows up 1.1052 +def xm_console(args): 1.1053 + arg_check(args,1,"console") 1.1054 1.1055 -xm.prog(ProgConsole) 1.1056 - 1.1057 -class ProgCall(Prog): 1.1058 - name = "call" 1.1059 - info = "Call xend api functions." 1.1060 + dom = args[0] 1.1061 + from xen.xend.XendClient import server 1.1062 + info = server.xend_domain(dom) 1.1063 + domid = int(sxp.child_value(info, 'id', '-1')) 1.1064 + cmd = "/usr/libexec/xen/xenconsole %d" % domid 1.1065 + os.execvp('/usr/libexec/xen/xenconsole', cmd.split()) 1.1066 + console = sxp.child(info, "console") 1.1067 1.1068 - def help (self, args): 1.1069 - print args[0], "function args..." 1.1070 - print """ 1.1071 - Call a xend HTTP API function. The leading 'xend_' on the function 1.1072 -can be omitted. See xen.xend.XendClient for the API functions. 1.1073 -""" 1.1074 - 1.1075 - def main(self, args): 1.1076 - xend_client_main(args) 1.1077 - 1.1078 -xm.prog(ProgCall) 1.1079 - 1.1080 -class ProgDmesg(Prog): 1.1081 - group = 'host' 1.1082 - name = "dmesg" 1.1083 - info = """Read or clear Xen's message buffer.""" 1.1084 - 1.1085 +def xm_dmesg(args): 1.1086 + 1.1087 gopts = Opts(use="""[-c|--clear] 1.1088 1.1089 Read Xen's message buffer (boot output, warning and error messages) or clear 1.1090 @@ -744,161 +455,212 @@ its contents if the [-c|--clear] flag is 1.1091 gopts.opt('clear', short='c', 1.1092 fn=set_true, default=0, 1.1093 use="Clear the contents of the Xen message buffer.") 1.1094 - 1.1095 - short_options = ['-c'] 1.1096 - long_options = ['--clear'] 1.1097 + # Work around for gopts 1.1098 + args.insert(0,"bogus") 1.1099 + gopts.parse(args) 1.1100 + if not (1 <= len(args) <= 2): 1.1101 + err('Invalid arguments: ' + str(args)) 1.1102 1.1103 - def help(self, args): 1.1104 - self.gopts.argv = args 1.1105 - self.gopts.usage() 1.1106 - 1.1107 - def main(self, args): 1.1108 - self.gopts.parse(args) 1.1109 - if not (1 <= len(args) <=2): 1.1110 - self.gopts.err('Invalid arguments: ' + str(args)) 1.1111 + from xen.xend.XendClient import server 1.1112 + if not gopts.vals.clear: 1.1113 + print server.xend_node_get_dmesg() 1.1114 + else: 1.1115 + server.xend_node_clear_dmesg() 1.1116 1.1117 - if not self.gopts.vals.clear: 1.1118 - print server.xend_node_get_dmesg() 1.1119 - else: 1.1120 - server.xend_node_clear_dmesg() 1.1121 - 1.1122 -xm.prog(ProgDmesg) 1.1123 +def xm_log(args): 1.1124 + from xen.xend.XendClient import server 1.1125 + print server.xend_node_log() 1.1126 1.1127 -class ProgLog(Prog): 1.1128 - group = 'host' 1.1129 - name = "log" 1.1130 - info = """Print the xend log.""" 1.1131 +def xm_network_limit(args): 1.1132 + arg_check(args,4,"network-limit") 1.1133 + dom = args[0] 1.1134 + v = map(int, args[1:4]) 1.1135 + from xen.xend.XendClient import server 1.1136 + server.xend_domain_vif_limit(dom, *v) 1.1137 1.1138 - def main(self, args): 1.1139 - print server.xend_node_log() 1.1140 - 1.1141 -xm.prog(ProgLog) 1.1142 +def xm_network_list(args): 1.1143 + arg_check(args,1,"network-list") 1.1144 + dom = args[0] 1.1145 + from xen.xend.XendClient import server 1.1146 + for x in server.xend_domain_devices(dom, 'vif'): 1.1147 + sxp.show(x) 1.1148 + print 1.1149 1.1150 -class ProgVifCreditLimit(Prog): 1.1151 - group = 'vif' 1.1152 - name= "vif-limit" 1.1153 - info = """Limit the transmission rate of a virtual network interface.""" 1.1154 +def xm_block_list(args): 1.1155 + arg_check(args,1,"block-list") 1.1156 + dom = args[0] 1.1157 + from xen.xend.XendClient import server 1.1158 + for x in server.xend_domain_devices(dom, 'vbd'): 1.1159 + sxp.show(x) 1.1160 + print 1.1161 1.1162 - def help(self, args): 1.1163 - print args[0], "DOMAIN VIF CREDIT_IN_BYTES PERIOD_IN_USECS" 1.1164 - print "\nSet the credit limit of a virtual network interface." 1.1165 - 1.1166 - def main(self, args): 1.1167 - if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0]) 1.1168 - dom = args[1] 1.1169 - v = map(int, args[2:5]) 1.1170 - server.xend_domain_vif_limit(dom, *v) 1.1171 - 1.1172 -xm.prog(ProgVifCreditLimit) 1.1173 +def xm_block_create(args): 1.1174 + n = len(args) 1.1175 + if n < 4 or n > 5: 1.1176 + err("%s: Invalid argument(s)" % args[0]) 1.1177 + usage("block-create") 1.1178 1.1179 -class ProgVifList(Prog): 1.1180 - group = 'vif' 1.1181 - name = 'vif-list' 1.1182 - info = """List virtual network interfaces for a domain.""" 1.1183 + dom = args[0] 1.1184 + vbd = ['vbd', 1.1185 + ['uname', args[1]], 1.1186 + ['dev', args[2]], 1.1187 + ['mode', args[3]]] 1.1188 + if n == 5: 1.1189 + vbd.append(['backend', args[4]]) 1.1190 1.1191 - def help(self, args): 1.1192 - print args[0], "DOM" 1.1193 - print "\nList virtual network interfaces for domain DOM" 1.1194 + from xen.xend.XendClient import server 1.1195 + server.xend_domain_device_create(dom, vbd) 1.1196 + 1.1197 +def xm_block_refresh(args): 1.1198 + arg_check(args,2,"block-refresh") 1.1199 1.1200 - def main(self, args): 1.1201 - if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0]) 1.1202 - dom = args[1] 1.1203 - for x in server.xend_domain_devices(dom, 'vif'): 1.1204 - sxp.show(x) 1.1205 - print 1.1206 + dom = args[0] 1.1207 + dev = args[1] 1.1208 + 1.1209 + from xen.xend.XendClient import server 1.1210 + server.xend_domain_device_refresh(dom, 'vbd', dev) 1.1211 1.1212 -xm.prog(ProgVifList) 1.1213 +def xm_block_destroy(args): 1.1214 + arg_check(args,2,"block-destroy") 1.1215 + 1.1216 + dom = args[0] 1.1217 + dev = args[1] 1.1218 + 1.1219 + from xen.xend.XendClient import server 1.1220 + server.xend_domain_device_destroy(dom, 'vbd', dev) 1.1221 1.1222 -class ProgVbdList(Prog): 1.1223 - group = 'vbd' 1.1224 - name = 'vbd-list' 1.1225 - info = """List virtual block devices for a domain.""" 1.1226 - 1.1227 - def help(self, args): 1.1228 - print args[0], "DOM" 1.1229 - print "\nList virtual block devices for domain DOM" 1.1230 - 1.1231 - def main(self, args): 1.1232 - if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0]) 1.1233 - dom = args[1] 1.1234 - for x in server.xend_domain_devices(dom, 'vbd'): 1.1235 - sxp.show(x) 1.1236 - print 1.1237 +commands = { 1.1238 + # console commands 1.1239 + "console": xm_console, 1.1240 + # domain commands 1.1241 + "domid": xm_domid, 1.1242 + "domname": xm_domname, 1.1243 + "create": xm_create, 1.1244 + "destroy": xm_destroy, 1.1245 + "restore": xm_restore, 1.1246 + "save": xm_save, 1.1247 + "shutdown": xm_shutdown, 1.1248 + "reboot": xm_reboot, 1.1249 + "list": xm_list, 1.1250 + # memory commands 1.1251 + "mem-max": xm_mem_max, 1.1252 + "mem-set": xm_mem_set, 1.1253 + # cpu commands 1.1254 + "cpus-set": xm_cpus_set, 1.1255 +# "cpus-list": xm_cpus_list, 1.1256 + "vcpu-enable": xm_vcpu_enable, 1.1257 + "vcpu-disable": xm_vcpu_disable, 1.1258 + "vcpu-list": xm_vcpu_list, 1.1259 + # migration 1.1260 + "migrate": xm_migrate, 1.1261 + # special 1.1262 + "sysrq": xm_sysrq, 1.1263 + "pause": xm_pause, 1.1264 + "unpause": xm_unpause, 1.1265 + # host commands 1.1266 + "dmesg": xm_dmesg, 1.1267 + "info": xm_info, 1.1268 + "log": xm_log, 1.1269 + # scheduler 1.1270 + "bvt": xm_bvt, 1.1271 + "bvt_ctxallow": xm_bvt_ctxallow, 1.1272 + "sedf": xm_sedf, 1.1273 + # block 1.1274 + "block-create": xm_block_create, 1.1275 + "block-destroy": xm_block_destroy, 1.1276 + "block-list": xm_block_list, 1.1277 + "block-refresh": xm_block_refresh, 1.1278 + # network 1.1279 + "network-limit": xm_network_limit, 1.1280 + "network-list": xm_network_list 1.1281 + } 1.1282 1.1283 -xm.prog(ProgVbdList) 1.1284 - 1.1285 -class ProgVbdCreate(Prog): 1.1286 - group = 'vbd' 1.1287 - name = 'vbd-create' 1.1288 - info = """Create a new virtual block device for a domain""" 1.1289 +aliases = { 1.1290 + "balloon": "mem-set", 1.1291 + "vif-list": "network-list", 1.1292 + "vif-limit": "network-limit", 1.1293 + "vbd-create": "block-create", 1.1294 + "vbd-destroy": "block-destroy", 1.1295 + "vbd-list": "block-list", 1.1296 + "vbd-refresh": "block-refresh", 1.1297 + } 1.1298 1.1299 - def help(self, args): 1.1300 - print args[0], "DOM UNAME DEV MODE [BACKEND]" 1.1301 - print """ 1.1302 -Create a virtual block device for a domain. 1.1303 - 1.1304 - UNAME - device to export, e.g. phy:hda2 1.1305 - DEV - device name in the domain, e.g. sda1 1.1306 - MODE - access mode: r for read, w for read-write 1.1307 - BACKEND - backend driver domain 1.1308 -""" 1.1309 +help = { 1.1310 + "--long": longhelp 1.1311 + } 1.1312 1.1313 - def main(self, args): 1.1314 - n = len(args) 1.1315 - if n < 5 or n > 6: self.err("%s: Invalid argument(s)" % args[0]) 1.1316 - dom = args[1] 1.1317 - vbd = ['vbd', 1.1318 - ['uname', args[2]], 1.1319 - ['dev', args[3]], 1.1320 - ['mode', args[4]]] 1.1321 - if n == 6: 1.1322 - vbd.append(['backend', args[5]]) 1.1323 - server.xend_domain_device_create(dom, vbd) 1.1324 +def xm_lookup_cmd(cmd): 1.1325 + if commands.has_key(cmd): 1.1326 + return commands[cmd] 1.1327 + elif aliases.has_key(cmd): 1.1328 + deprecated(cmd,aliases[cmd]) 1.1329 + return commands[aliases[cmd]] 1.1330 + else: 1.1331 + err('Sub Command %s not found!' % cmd) 1.1332 + usage() 1.1333 + 1.1334 +def deprecated(old,new): 1.1335 + err('Option %s is deprecated, and will be removed in future!!!' % old) 1.1336 + err('Option %s is the new replacement, see "xm help %s" for more info' % (new, new)) 1.1337 1.1338 -xm.prog(ProgVbdCreate) 1.1339 +def usage(cmd=None): 1.1340 + if cmd == "full": 1.1341 + print fullhelp 1.1342 + elif help.has_key(cmd): 1.1343 + print help[cmd] 1.1344 + else: 1.1345 + print shorthelp 1.1346 + sys.exit(1) 1.1347 + 1.1348 +def main(argv=sys.argv): 1.1349 + if len(argv) < 2: 1.1350 + usage() 1.1351 + 1.1352 + if re.compile('-*help').match(argv[1]): 1.1353 + if len(argv) > 2 and help.has_key(argv[2]): 1.1354 + usage(argv[2]) 1.1355 + else: 1.1356 + usage() 1.1357 + sys.exit(0) 1.1358 + 1.1359 + cmd = xm_lookup_cmd(argv[1]) 1.1360 1.1361 -class ProgVbdRefresh(Prog): 1.1362 - group = 'vbd' 1.1363 - name = 'vbd-refresh' 1.1364 - info = """Refresh a virtual block device for a domain""" 1.1365 - 1.1366 - def help(self, args): 1.1367 - print args[0], "DOM DEV" 1.1368 - print """ 1.1369 -Refresh a virtual block device for a domain. 1.1370 + # strip off prog name and subcmd 1.1371 + args = argv[2:] 1.1372 + if cmd: 1.1373 + try: 1.1374 + from xen.xend.XendClient import XendError 1.1375 + rc = cmd(args) 1.1376 + if rc: 1.1377 + usage() 1.1378 + except socket.error, ex: 1.1379 + print >>sys.stderr, ex 1.1380 + err("Error connecting to xend, is xend running?") 1.1381 + sys.exit(1) 1.1382 + except IOError: 1.1383 + err("Most commands need root access. Please try again as root") 1.1384 + sys.exit(1) 1.1385 + except XendError, ex: 1.1386 + if len(args) > 0: 1.1387 + handle_xend_error(argv[1], args[0], ex) 1.1388 + else: 1.1389 + print "Unexpected error:", sys.exc_info()[0] 1.1390 + print 1.1391 + print "Please report to xen-devel@lists.xensource.com" 1.1392 + raise 1.1393 + except SystemExit: 1.1394 + sys.exit(1) 1.1395 + except: 1.1396 + print "Unexpected error:", sys.exc_info()[0] 1.1397 + print 1.1398 + print "Please report to xen-devel@lists.xensource.com" 1.1399 + raise 1.1400 + 1.1401 + else: 1.1402 + usage() 1.1403 1.1404 - DEV - idx field in the device information 1.1405 -""" 1.1406 - 1.1407 - def main(self, args): 1.1408 - if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0]) 1.1409 - dom = args[1] 1.1410 - dev = args[2] 1.1411 - server.xend_domain_device_refresh(dom, 'vbd', dev) 1.1412 - 1.1413 -xm.prog(ProgVbdRefresh) 1.1414 +if __name__ == "__main__": 1.1415 + main() 1.1416 1.1417 1.1418 -class ProgVbdDestroy(Prog): 1.1419 - group = 'vbd' 1.1420 - name = 'vbd-destroy' 1.1421 - info = """Destroy a domain's virtual block device""" 1.1422 1.1423 - def help(self, args): 1.1424 - print args[0], "DOM DEV" 1.1425 - print """ 1.1426 -Destroy vbd DEV attached to domain DOM. Detaches the device 1.1427 -from the domain, but does not destroy the device contents. 1.1428 -The device indentifier DEV is the idx field in the device 1.1429 -information. This is visible in 'xm vbd-list'.""" 1.1430 - 1.1431 - def main(self, args): 1.1432 - if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0]) 1.1433 - dom = args[1] 1.1434 - dev = args[2] 1.1435 - server.xend_domain_device_destroy(dom, 'vbd', dev) 1.1436 - 1.1437 -xm.prog(ProgVbdDestroy) 1.1438 - 1.1439 -def main(args): 1.1440 - xm.main(args)