direct-io.hg

view tools/python/xen/xm/main.py @ 8434:ffa8e85a9e0b

This patch fixes a bug/typo of main.py.
1. show option "-c" of help of xm dmesg
2. fix value of parameter of arg_check of xm log
3. fix aliases of vbd-create and vbd-destroy

Signed-off-by Yoshinori Katase <y_katase@soft.fujitsu.com>
author emellor@leeni.uk.xensource.com
date Thu Dec 22 15:38:10 2005 +0000 (2005-12-22)
parents 231686596796
children 09e752a1a04a
line source
1 # (C) Copyright IBM Corp. 2005
2 # Copyright (C) 2004 Mike Wray
3 # Copyright (c) 2005 XenSource Ltd
4 #
5 # Authors:
6 # Sean Dague <sean at dague dot net>
7 # Mike Wray <mike dot wray at hp dot com>
8 #
9 # This library is free software; you can redistribute it and/or
10 # modify it under the terms of version 2.1 of the GNU Lesser General Public
11 # License as published by the Free Software Foundation.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 """Grand unified management application for Xen.
23 """
24 import os
25 import os.path
26 import sys
27 import re
28 import getopt
29 import socket
30 import warnings
31 warnings.filterwarnings('ignore', category=FutureWarning)
33 import xen.xend.XendError
34 import xen.xend.XendProtocol
36 from xen.xend import PrettyPrint
37 from xen.xend import sxp
38 from xen.xm.opts import *
40 import console
43 # getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
44 # getopt.getopt if gnu_getopt is not available. This will mean that options
45 # may only be specified before positional arguments.
46 if not hasattr(getopt, 'gnu_getopt'):
47 getopt.gnu_getopt = getopt.getopt
50 # Strings for shorthelp
51 console_help = "console <DomId> Attach to domain DomId's console."
52 create_help = """create [-c] <ConfigFile>
53 [Name=Value].. Create a domain based on Config File"""
54 destroy_help = "destroy <DomId> Terminate a domain immediately"
55 help_help = "help Display this message"
56 list_help = "list [--long] [DomId, ...] List information about domains"
57 mem_max_help = "mem-max <DomId> <Mem> Set maximum memory reservation for a domain"
58 mem_set_help = "mem-set <DomId> <Mem> Adjust the current memory usage for a domain"
59 migrate_help = "migrate <DomId> <Host> Migrate a domain to another machine"
60 pause_help = "pause <DomId> Pause execution of a domain"
61 reboot_help = "reboot <DomId> [-w][-a] Reboot a domain"
62 restore_help = "restore <File> Create a domain from a saved state file"
63 save_help = "save <DomId> <File> Save domain state (and config) to file"
64 shutdown_help ="shutdown <DomId> [-w][-a][-R|-H] Shutdown a domain"
65 top_help = "top Monitor system and domains in real-time"
66 unpause_help = "unpause <DomId> Unpause a paused domain"
68 help_spacer = """
69 """
71 # Strings for longhelp
72 sysrq_help = "sysrq <DomId> <letter> Send a sysrq to a domain"
73 domid_help = "domid <DomName> Converts a domain name to a domain id"
74 domname_help = "domname <DomId> Convert a domain id to a domain name"
75 vcpu_set_help = """vcpu-set <DomId> <VCPUs> Set the number of VCPUs for a domain"""
76 vcpu_list_help = "vcpu-list <DomId> List the VCPUs for a domain (or all domains)"
77 vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs> Set which cpus a VCPU can use"
78 dmesg_help = "dmesg [-c|--clear] Read or clear Xen's message buffer"
79 info_help = "info Get information about the xen host"
80 rename_help = "rename <DomId> <New Name> Rename a domain"
81 log_help = "log Print the xend log"
82 sched_bvt_help = """sched-bvt <Parameters> Set Borrowed Virtual Time scheduler
83 parameters"""
84 sched_bvt_ctxallow_help = """sched-bvt-ctxallow <Allow> Set the BVT scheduler context switch
85 allowance"""
86 sched_sedf_help = "sched-sedf <Parameters> Set simple EDF parameters"
87 block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode>
88 [BackDomId] Create a new virtual block device"""
89 block_detach_help = """block-detach <DomId> <DevId> Destroy a domain's virtual block device,
90 where <DevId> may either be the device ID
91 or the device name as mounted in the guest"""
93 block_list_help = "block-list <DomId> List virtual block devices for a domain"
94 network_attach_help = """network-attach <DomID> [script=<script>] [ip=<ip>] [mac=<mac>]
95 [bridge=<bridge>] [backend=<backDomID>]
96 Create a new virtual network device """
97 network_detach_help = """network-detach <DomId> <DevId> Destroy a domain's virtual network
98 device, where <DevId> is the device ID."""
100 network_list_help = "network-list <DomId> List virtual network interfaces for a domain"
101 vnet_list_help = "vnet-list [-l|--long] list vnets"
102 vnet_create_help = "vnet-create <config> create a vnet from a config file"
103 vnet_delete_help = "vnet-delete <vnetid> delete a vnet"
106 short_command_list = [
107 "console",
108 "create",
109 "destroy",
110 "help",
111 "list",
112 "mem-set",
113 "migrate",
114 "pause",
115 "reboot",
116 "restore",
117 "save",
118 "shutdown",
119 "top",
120 "unpause",
121 "vcpu-set",
122 ]
124 domain_commands = [
125 "console",
126 "create",
127 "destroy",
128 "domid",
129 "domname",
130 "list",
131 "mem-max",
132 "mem-set",
133 "migrate",
134 "pause",
135 "reboot",
136 "rename",
137 "restore",
138 "save",
139 "shutdown",
140 "sysrq",
141 "top",
142 "unpause",
143 "vcpu-list",
144 "vcpu-pin",
145 "vcpu-set",
146 ]
148 host_commands = [
149 "dmesg",
150 "info",
151 "log",
152 "top",
153 ]
155 scheduler_commands = [
156 "sched-bvt",
157 "sched-bvt-ctxallow",
158 "sched-sedf",
159 ]
161 device_commands = [
162 "block-attach",
163 "block-detach",
164 "block-list",
165 "network-attach",
166 "network-detach",
167 "network-list",
168 ]
170 vnet_commands = [
171 "vnet-list",
172 "vnet-create",
173 "vnet-delete",
174 ]
176 all_commands = (domain_commands + host_commands + scheduler_commands +
177 device_commands + vnet_commands)
180 def commandToHelp(cmd):
181 return eval(cmd.replace("-", "_") + "_help")
184 shorthelp = """Usage: xm <subcommand> [args]
185 Control, list, and manipulate Xen guest instances
187 xm common subcommands:
188 """ + help_spacer.join(map(commandToHelp, short_command_list)) + """
190 <DomName> can be substituted for <DomId> in xm subcommands.
192 For a complete list of subcommands run 'xm help --long'
193 For more help on xm see the xm(1) man page
194 For more help on xm create, see the xmdomain.cfg(5) man page"""
196 longhelp = """Usage: xm <subcommand> [args]
197 Control, list, and manipulate Xen guest instances
199 xm full list of subcommands:
201 Domain Commands:
202 """ + help_spacer.join(map(commandToHelp, domain_commands)) + """
204 Xen Host Commands:
205 """ + help_spacer.join(map(commandToHelp, host_commands)) + """
207 Scheduler Commands:
208 """ + help_spacer.join(map(commandToHelp, scheduler_commands)) + """
210 Virtual Device Commands:
211 """ + help_spacer.join(map(commandToHelp, device_commands)) + """
213 Vnet commands:
214 """ + help_spacer.join(map(commandToHelp, vnet_commands)) + """
216 <DomName> can be substituted for <DomId> in xm subcommands.
218 For a short list of subcommands run 'xm help'
219 For more help on xm see the xm(1) man page
220 For more help on xm create, see the xmdomain.cfg(5) man page"""
222 # array for xm help <command>
223 help = {
224 "--long": longhelp
225 }
227 for command in all_commands:
228 # create is handled specially
229 if (command != 'create'):
230 help[command] = commandToHelp(command)
233 ####################################################################
234 #
235 # Utility functions
236 #
237 ####################################################################
239 def arg_check(args, name, lo, hi = -1):
240 n = len(args)
242 if hi == -1:
243 if n != lo:
244 err("'xm %s' requires %d argument%s.\n" % (name, lo,
245 lo > 1 and 's' or ''))
246 usage(name)
247 else:
248 if n < lo or n > hi:
249 err("'xm %s' requires between %d and %d arguments.\n" %
250 (name, lo, hi))
251 usage(name)
254 def unit(c):
255 if not c.isalpha():
256 return 0
257 base = 1
258 if c == 'G' or c == 'g': base = 1024 * 1024 * 1024
259 elif c == 'M' or c == 'm': base = 1024 * 1024
260 elif c == 'K' or c == 'k': base = 1024
261 else:
262 print 'ignoring unknown unit'
263 return base
265 def int_unit(str, dest):
266 base = unit(str[-1])
267 if not base:
268 return int(str)
270 value = int(str[:-1])
271 dst_base = unit(dest)
272 if dst_base == 0:
273 dst_base = 1
274 if dst_base > base:
275 return value / (dst_base / base)
276 else:
277 return value * (base / dst_base)
279 def err(msg):
280 print >>sys.stderr, "Error:", msg
282 def handle_xend_error(cmd, args, ex):
283 non_option = filter(lambda x: x[0] != '-', args)
284 dom = len(non_option) > 0 and non_option[0] or None
286 error = str(ex)
287 if error == "Not found" and dom != None:
288 err("Domain '%s' not found when running 'xm %s'" % (dom, cmd))
289 else:
290 err(error)
292 sys.exit(1)
295 #########################################################################
296 #
297 # Main xm functions
298 #
299 #########################################################################
301 def xm_save(args):
302 arg_check(args, "save", 2)
304 dom = args[0] # TODO: should check if this exists
305 savefile = os.path.abspath(args[1])
307 if not os.access(os.path.dirname(savefile), os.W_OK):
308 err("xm save: Unable to create file %s" % savefile)
309 sys.exit(1)
311 from xen.xend.XendClient import server
312 server.xend_domain_save(dom, savefile)
314 def xm_restore(args):
315 arg_check(args, "restore", 1)
317 savefile = os.path.abspath(args[0])
319 if not os.access(savefile, os.R_OK):
320 err("xm restore: Unable to read file %s" % savefile)
321 sys.exit(1)
323 from xen.xend.XendClient import server
324 server.xend_domain_restore(savefile)
327 def getDomains(domain_names):
328 from xen.xend.XendClient import server
329 if domain_names:
330 return map(server.xend_domain, domain_names)
331 else:
332 return server.xend_list_domains()
335 def xm_list(args):
336 use_long = 0
337 show_vcpus = 0
338 try:
339 (options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus'])
340 except getopt.GetoptError, opterr:
341 err(opterr)
342 sys.exit(1)
344 for (k, v) in options:
345 if k in ['-l', '--long']:
346 use_long = 1
347 if k in ['-v', '--vcpus']:
348 show_vcpus = 1
350 if show_vcpus:
351 print >>sys.stderr, (
352 "xm list -v is deprecated. Please use xm vcpu-list.")
353 xm_vcpu_list(params)
354 return
356 doms = getDomains(params)
358 if use_long:
359 map(PrettyPrint.prettyprint, doms)
360 else:
361 xm_brief_list(doms)
364 def parse_doms_info(info):
365 def get_info(n, t, d):
366 return t(sxp.child_value(info, n, d))
368 return {
369 'dom' : get_info('domid', int, -1),
370 'name' : get_info('name', str, '??'),
371 'mem' : get_info('memory', int, 0),
372 'vcpus' : get_info('online_vcpus', int, 0),
373 'state' : get_info('state', str, '??'),
374 'cpu_time' : get_info('cpu_time', float, 0),
375 'ssidref' : get_info('ssidref', int, 0),
376 }
379 def xm_brief_list(doms):
380 print 'Name ID Mem(MiB) VCPUs State Time(s)'
381 for dom in doms:
382 d = parse_doms_info(dom)
383 if (d['ssidref'] != 0):
384 d['ssidstr'] = (" s:%04x/p:%04x" %
385 ((d['ssidref'] >> 16) & 0xffff,
386 d['ssidref'] & 0xffff))
387 else:
388 d['ssidstr'] = ""
389 print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f%(ssidstr)s" % d)
392 def xm_vcpu_list(args):
393 print 'Name ID VCPU CPU State Time(s) CPU Affinity'
395 from xen.xend.XendClient import server
396 if args:
397 dominfo = map(server.xend_domain_vcpuinfo, args)
398 else:
399 doms = server.xend_list_domains()
400 dominfo = map(
401 lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')),
402 doms)
404 for dom in dominfo:
405 def get_info(n):
406 return sxp.child_value(dom, n)
408 #
409 # convert a list of integers into a list of pairs indicating
410 # continuous sequences in the list:
411 #
412 # [0,1,2,3] -> [(0,3)]
413 # [1,2,4,5] -> [(1,2),(4,5)]
414 # [0] -> [(0,0)]
415 # [0,1,4,6,7] -> [(0,1),(4,4),(6,7)]
416 #
417 def list_to_rangepairs(cmap):
418 cmap.sort()
419 pairs = []
420 x = y = 0
421 for i in range(0,len(cmap)):
422 try:
423 if ((cmap[y+1] - cmap[i]) > 1):
424 pairs.append((cmap[x],cmap[y]))
425 x = y = i+1
426 else:
427 y = y + 1
428 # if we go off the end, then just add x to y
429 except IndexError:
430 pairs.append((cmap[x],cmap[y]))
432 return pairs
434 #
435 # Convert pairs to range string, e.g: [(1,2),(3,3),(5,7)] -> 1-2,3,5-7
436 #
437 def format_pairs(pairs):
438 if not pairs:
439 return "no cpus"
440 out = ""
441 for f,s in pairs:
442 if (f==s):
443 out += '%d'%f
444 else:
445 out += '%d-%d'%(f,s)
446 out += ','
447 # trim trailing ','
448 return out[:-1]
450 def format_cpumap(cpumap):
451 cpumap = map(lambda x: int(x), cpumap)
452 cpumap.sort()
454 from xen.xend.XendClient import server
455 for x in server.xend_node()[1:]:
456 if len(x) > 1 and x[0] == 'nr_cpus':
457 nr_cpus = int(x[1])
458 # normalize cpumap by modulus nr_cpus, and drop duplicates
459 cpumap = dict.fromkeys(
460 map(lambda x: x % nr_cpus, cpumap)).keys()
461 if len(cpumap) == nr_cpus:
462 return "any cpu"
463 break
465 return format_pairs(list_to_rangepairs(cpumap))
467 name = get_info('name')
468 domid = int(get_info('domid'))
470 for vcpu in sxp.children(dom, 'vcpu'):
471 def vinfo(n, t):
472 return t(sxp.child_value(vcpu, n))
474 number = vinfo('number', int)
475 cpu = vinfo('cpu', int)
476 cpumap = format_cpumap(vinfo('cpumap', list))
477 online = vinfo('online', int)
478 cpu_time = vinfo('cpu_time', float)
479 running = vinfo('running', int)
480 blocked = vinfo('blocked', int)
482 if online:
483 c = str(cpu)
484 if running:
485 s = 'r'
486 else:
487 s = '-'
488 if blocked:
489 s += 'b'
490 else:
491 s += '-'
492 s += '-'
493 else:
494 c = "-"
495 s = "--p"
497 print (
498 "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f %(cpumap)s" %
499 locals())
502 def xm_reboot(args):
503 arg_check(args, "reboot", 1, 4)
504 from xen.xm import shutdown
505 shutdown.main(["shutdown", "-R"] + args)
507 def xm_pause(args):
508 arg_check(args, "pause", 1)
509 dom = args[0]
511 from xen.xend.XendClient import server
512 server.xend_domain_pause(dom)
514 def xm_unpause(args):
515 arg_check(args, "unpause", 1)
516 dom = args[0]
518 from xen.xend.XendClient import server
519 server.xend_domain_unpause(dom)
521 def xm_rename(args):
522 arg_check(args, "rename", 2)
524 from xen.xend.XendClient import server
525 server.xend_domain_rename(args[0], args[1])
527 def xm_subcommand(command, args):
528 cmd = __import__(command, globals(), locals(), 'xen.xm')
529 cmd.main([command] + args)
532 #############################################################
534 def cpu_make_map(cpulist):
535 cpus = []
536 for c in cpulist.split(','):
537 if c.find('-') != -1:
538 (x,y) = c.split('-')
539 for i in range(int(x),int(y)+1):
540 cpus.append(int(i))
541 else:
542 cpus.append(int(c))
543 cpus.sort()
544 return cpus
546 def xm_vcpu_pin(args):
547 arg_check(args, "vcpu-pin", 3)
549 dom = args[0]
550 vcpu = int(args[1])
551 cpumap = cpu_make_map(args[2])
553 from xen.xend.XendClient import server
554 server.xend_domain_pincpu(dom, vcpu, cpumap)
556 def xm_mem_max(args):
557 arg_check(args, "mem-max", 2)
559 dom = args[0]
560 mem = int_unit(args[1], 'm')
562 from xen.xend.XendClient import server
563 server.xend_domain_maxmem_set(dom, mem)
565 def xm_mem_set(args):
566 arg_check(args, "mem-set", 2)
568 dom = args[0]
569 mem_target = int_unit(args[1], 'm')
571 from xen.xend.XendClient import server
572 server.xend_domain_mem_target_set(dom, mem_target)
574 def xm_vcpu_set(args):
575 arg_check(args, "vcpu-set", 2)
577 from xen.xend.XendClient import server
578 server.xend_domain_set_vcpus(args[0], int(args[1]))
581 def xm_destroy(args):
582 arg_check(args, "destroy", 1)
583 from xen.xend.XendClient import server
584 server.xend_domain_destroy(args[0])
587 def xm_domid(args):
588 arg_check(args, "domid", 1)
590 name = args[0]
592 from xen.xend.XendClient import server
593 dom = server.xend_domain(name)
594 print sxp.child_value(dom, 'domid')
596 def xm_domname(args):
597 arg_check(args, "domname", 1)
599 name = args[0]
601 from xen.xend.XendClient import server
602 dom = server.xend_domain(name)
603 print sxp.child_value(dom, 'name')
605 def xm_sched_bvt(args):
606 arg_check(args, "sched-bvt", 6)
607 dom = args[0]
608 v = map(long, args[1:6])
609 from xen.xend.XendClient import server
610 server.xend_domain_cpu_bvt_set(dom, *v)
612 def xm_sched_bvt_ctxallow(args):
613 arg_check(args, "sched-bvt-ctxallow", 1)
615 slice = int(args[0])
616 from xen.xend.XendClient import server
617 server.xend_node_cpu_bvt_slice_set(slice)
619 def xm_sched_sedf(args):
620 arg_check(args, "sched-sedf", 6)
622 dom = args[0]
623 v = map(int, args[1:6])
624 from xen.xend.XendClient import server
625 server.xend_domain_cpu_sedf_set(dom, *v)
627 def xm_info(args):
628 from xen.xend.XendClient import server
629 info = server.xend_node()
631 for x in info[1:]:
632 if len(x) < 2:
633 print "%-23s: (none)" % x[0]
634 else:
635 print "%-23s:" % x[0], x[1]
637 def xm_console(args):
638 arg_check(args, "console", 1)
640 dom = args[0]
641 from xen.xend.XendClient import server
642 info = server.xend_domain(dom)
643 domid = int(sxp.child_value(info, 'domid', '-1'))
644 console.execConsole(domid)
647 def xm_top(args):
648 os.execvp('xentop', ['xentop'])
650 def xm_dmesg(args):
652 gopts = Opts(use="""[-c|--clear]
654 Read Xen's message buffer (boot output, warning and error messages) or clear
655 its contents if the [-c|--clear] flag is specified.
656 """)
658 gopts.opt('clear', short='c',
659 fn=set_true, default=0,
660 use="Clear the contents of the Xen message buffer.")
661 # Work around for gopts
662 myargs = args
663 myargs.insert(0, 'dmesg')
664 gopts.parse(myargs)
665 if not (1 <= len(myargs) <= 2):
666 err('Invalid arguments: ' + str(myargs))
668 from xen.xend.XendClient import server
669 if not gopts.vals.clear:
670 print server.xend_node_get_dmesg()
671 else:
672 server.xend_node_clear_dmesg()
674 def xm_log(args):
675 arg_check(args, "log", 0)
677 from xen.xend.XendClient import server
678 print server.xend_node_log()
680 def xm_network_list(args):
681 arg_check(args, "network-list", 1)
682 dom = args[0]
683 from xen.xend.XendClient import server
684 for x in server.xend_domain_devices(dom, 'vif'):
685 sxp.show(x)
686 print
688 def xm_block_list(args):
689 arg_check(args, "block-list", 1)
690 dom = args[0]
691 from xen.xend.XendClient import server
692 for x in server.xend_domain_devices(dom, 'vbd'):
693 sxp.show(x)
694 print
696 def xm_block_attach(args):
697 arg_check(args, 'block-attach', 4, 5)
699 dom = args[0]
700 vbd = ['vbd',
701 ['uname', args[1]],
702 ['dev', args[2]],
703 ['mode', args[3]]]
704 if len(args) == 5:
705 vbd.append(['backend', args[4]])
707 from xen.xend.XendClient import server
708 server.xend_domain_device_create(dom, vbd)
711 def xm_network_attach(args):
712 arg_check(args, 'network-attach', 1, 10000)
714 dom = args[0]
715 vif = ['vif']
717 for a in args[1:]:
718 vif.append(a.split("="))
720 from xen.xend.XendClient import server
721 server.xend_domain_device_create(dom, vif)
724 def detach(args, command, deviceClass):
725 arg_check(args, command, 2)
727 dom = args[0]
728 dev = args[1]
730 from xen.xend.XendClient import server
731 server.xend_domain_device_destroy(dom, deviceClass, dev)
734 def xm_block_detach(args):
735 detach(args, 'block-detach', 'vbd')
738 def xm_network_detach(args):
739 detach(args, 'network-detach', 'vif')
742 def xm_vnet_list(args):
743 from xen.xend.XendClient import server
744 try:
745 (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
746 except getopt.GetoptError, opterr:
747 err(opterr)
748 sys.exit(1)
750 use_long = 0
751 for (k, v) in options:
752 if k in ['-l', '--long']:
753 use_long = 1
755 if params:
756 use_long = 1
757 vnets = params
758 else:
759 vnets = server.xend_vnets()
761 for vnet in vnets:
762 try:
763 if use_long:
764 info = server.xend_vnet(vnet)
765 PrettyPrint.prettyprint(info)
766 else:
767 print vnet
768 except Exception, ex:
769 print vnet, ex
771 def xm_vnet_create(args):
772 arg_check(args, "vnet-create", 1)
773 conf = args[0]
774 if not os.access(conf, os.R_OK):
775 print "File not found: %s" % conf
776 sys.exit(1)
778 from xen.xend.XendClient import server
779 server.xend_vnet_create(conf)
781 def xm_vnet_delete(args):
782 arg_check(args, "vnet-delete", 1)
783 vnet = args[0]
784 from xen.xend.XendClient import server
785 server.xend_vnet_delete(vnet)
787 commands = {
788 # console commands
789 "console": xm_console,
790 # xenstat commands
791 "top": xm_top,
792 # domain commands
793 "destroy": xm_destroy,
794 "domid": xm_domid,
795 "domname": xm_domname,
796 "rename": xm_rename,
797 "restore": xm_restore,
798 "save": xm_save,
799 "reboot": xm_reboot,
800 "list": xm_list,
801 # memory commands
802 "mem-max": xm_mem_max,
803 "mem-set": xm_mem_set,
804 # cpu commands
805 "vcpu-pin": xm_vcpu_pin,
806 "vcpu-list": xm_vcpu_list,
807 "vcpu-set": xm_vcpu_set,
808 # special
809 "pause": xm_pause,
810 "unpause": xm_unpause,
811 # host commands
812 "dmesg": xm_dmesg,
813 "info": xm_info,
814 "log": xm_log,
815 # scheduler
816 "sched-bvt": xm_sched_bvt,
817 "sched-bvt-ctxallow": xm_sched_bvt_ctxallow,
818 "sched-sedf": xm_sched_sedf,
819 # block
820 "block-attach": xm_block_attach,
821 "block-detach": xm_block_detach,
822 "block-list": xm_block_list,
823 # network
824 "network-attach": xm_network_attach,
825 "network-detach": xm_network_detach,
826 "network-list": xm_network_list,
827 # vnet
828 "vnet-list": xm_vnet_list,
829 "vnet-create": xm_vnet_create,
830 "vnet-delete": xm_vnet_delete,
831 }
833 ## The commands supported by a separate argument parser in xend.xm.
834 subcommands = [
835 'create',
836 'migrate',
837 'sysrq',
838 'shutdown'
839 ]
841 for c in subcommands:
842 commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
844 aliases = {
845 "balloon": "mem-set",
846 "set-vcpus": "vcpu-set",
847 "vif-list": "network-list",
848 "vbd-create": "block-attach",
849 "vbd-destroy": "block-detach",
850 "vbd-list": "block-list",
851 }
854 def xm_lookup_cmd(cmd):
855 if commands.has_key(cmd):
856 return commands[cmd]
857 elif aliases.has_key(cmd):
858 deprecated(cmd,aliases[cmd])
859 return commands[aliases[cmd]]
860 else:
861 if len( cmd ) > 1:
862 matched_commands = filter( lambda (command, func): command[ 0:len(cmd) ] == cmd, commands.iteritems() )
863 if len( matched_commands ) == 1:
864 return matched_commands[0][1]
865 err('Sub Command %s not found!' % cmd)
866 usage()
868 def deprecated(old,new):
869 print >>sys.stderr, (
870 "Command %s is deprecated. Please use xm %s instead." % (old, new))
872 def usage(cmd=None):
873 if cmd == 'create':
874 mycmd = xm_lookup_cmd(cmd)
875 mycmd( ['--help'] )
876 sys.exit(1)
877 if help.has_key(cmd):
878 print " " + help[cmd]
879 else:
880 print shorthelp
881 sys.exit(1)
883 def main(argv=sys.argv):
884 if len(argv) < 2:
885 usage()
887 if re.compile('-*help').match(argv[1]):
888 if len(argv) > 2:
889 usage(argv[2])
890 else:
891 usage()
892 sys.exit(0)
894 cmd = xm_lookup_cmd(argv[1])
896 # strip off prog name and subcmd
897 args = argv[2:]
898 if cmd:
899 try:
900 rc = cmd(args)
901 if rc:
902 usage()
903 except socket.error, ex:
904 if os.geteuid() != 0:
905 err("Most commands need root access. Please try again as root.")
906 else:
907 err("Error connecting to xend: %s. Is xend running?" % ex[1])
908 sys.exit(1)
909 except KeyboardInterrupt:
910 print "Interrupted."
911 sys.exit(1)
912 except IOError, ex:
913 if os.geteuid() != 0:
914 err("Most commands need root access. Please try again as root.")
915 else:
916 err("Error connecting to xend: %s." % ex[1])
917 sys.exit(1)
918 except xen.xend.XendError.XendError, ex:
919 if len(args) > 0:
920 handle_xend_error(argv[1], args, ex)
921 else:
922 print "Unexpected error:", sys.exc_info()[0]
923 print
924 print "Please report to xen-devel@lists.xensource.com"
925 raise
926 except xen.xend.XendProtocol.XendError, ex:
927 if len(args) > 0:
928 handle_xend_error(argv[1], args, ex)
929 else:
930 print "Unexpected error:", sys.exc_info()[0]
931 print
932 print "Please report to xen-devel@lists.xensource.com"
933 raise
934 except SystemExit:
935 sys.exit(1)
936 except:
937 print "Unexpected error:", sys.exc_info()[0]
938 print
939 print "Please report to xen-devel@lists.xensource.com"
940 raise
942 else:
943 usage()
945 if __name__ == "__main__":
946 main()