ia64/xen-unstable

view tools/python/xen/xm/main.py @ 7626:d9d88dd713ba

This is another patch that adds an arg_check() to domid and domname so
that we don't dump stack if a user runs either without an argument.

Signed-off-by: Dan Smith <danms@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Nov 04 11:05:10 2005 +0100 (2005-11-04)
parents 98515ca23ca3
children 1a5861311b04
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 commands
28 import re
29 from getopt import getopt
30 import socket
31 import warnings
32 warnings.filterwarnings('ignore', category=FutureWarning)
34 import xen.xend.XendError
35 import xen.xend.XendProtocol
37 from xen.xend import PrettyPrint
38 from xen.xend import sxp
39 from xen.xm.opts import *
41 import console
44 shorthelp = """Usage: xm <subcommand> [args]
45 Control, list, and manipulate Xen guest instances
47 xm common subcommands:
48 console <DomId> attach to console of DomId
49 create <CfgFile> create a domain based on Config File
50 destroy <DomId> terminate a domain immediately
51 help display this message
52 list [DomId, ...] list information about domains
53 mem-max <DomId> <Mem> set the maximum memory reservation for a domain
54 mem-set <DomId> <Mem> adjust the current memory usage for a domain
55 migrate <DomId> <Host> migrate a domain to another machine
56 pause <DomId> pause execution of a domain
57 reboot <DomId> reboot a domain
58 restore <File> create a domain from a saved state file
59 save <DomId> <File> save domain state (and config) to file
60 shutdown <DomId> shutdown a domain
61 top monitor system and domains in real-time
62 unpause <DomId> unpause a paused domain
64 <DomName> can be substituted for <DomId> in xm subcommands.
66 For a complete list of subcommands run 'xm help --long'
67 For more help on xm see the xm(1) man page
68 For more help on xm create, see the xmdomain.cfg(5) man page"""
70 longhelp = """Usage: xm <subcommand> [args]
71 Control, list, and manipulate Xen guest instances
73 xm full list of subcommands:
75 Domain Commands:
76 console <DomId> attach to console of DomId
77 create <ConfigFile> create a domain
78 destroy <DomId> terminate a domain immediately
79 domid <DomName> convert a domain name to a domain id
80 domname <DomId> convert a domain id to a domain name
81 list list information about domains
82 mem-max <DomId> <Mem> set domain maximum memory limit
83 mem-set <DomId> <Mem> set the domain's memory dynamically
84 migrate <DomId> <Host> migrate a domain to another machine
85 pause <DomId> pause execution of a domain
86 reboot [-w|-a] <DomId> reboot a domain
87 restore <File> create a domain from a saved state file
88 save <DomId> <File> save domain state (and config) to file
89 shutdown [-w|-a] <DomId> shutdown a domain
90 sysrq <DomId> <letter> send a sysrq to a domain
91 unpause <DomId> unpause a paused domain
92 set-vcpus <DomId> <VCPUs> enable the specified number of VCPUs in a domain
93 vcpu-list <DomId> list the VCPUs for a domain
94 vcpu-pin <DomId> <VCPU> <CPUs> set which cpus a VCPU can use.
96 Xen Host Commands:
97 dmesg [--clear] read or clear Xen's message buffer
98 info get information about the xen host
99 log print the xend log
100 top monitor system and domains in real-time
102 Scheduler Commands:
103 sched-bvt <options> set BVT scheduler parameters
104 sched-bvt-ctxallow <Allow>
105 Set the BVT scheduler context switch allowance
106 sched-sedf <options> set simple EDF parameters
108 Virtual Device Commands:
109 block-attach <DomId> <BackDev> <FrontDev> <Mode> [BackDomId]
110 Create a new virtual block device
111 block-detach <DomId> <DevId> Destroy a domain's virtual block device,
112 where <DevId> may either be the device ID
113 or the device name as mounted in the guest.
114 block-list <DomId> List virtual block devices for a domain
116 network-attach <DomID> [script=<script>] [ip=<ip>] [mac=<mac>]
117 [bridge=<bridge>] [backend=<backDomID>]
118 Create a new virtual network device
119 network-detach <DomId> <DevId> Destroy a domain's virtual network
120 device, where <DevId> is the device ID.
121 network-limit <DomId> <Vif> <Credit> <Period>
122 Limit the transmission rate of a virtual network interface
123 network-list <DomId> List virtual network interfaces for a domain
125 Vnet commands:
126 vnet-list [-l|--long] list vnets
127 vnet-create <config> create a vnet from a config file
128 vnet-delete <vnetid> delete a vnet
130 <DomName> can be substituted for <DomId> in xm subcommands.
132 For a short list of subcommands run 'xm help'
133 For more help on xm see the xm(1) man page
134 For more help on xm create, see the xmdomain.cfg(5) man page"""
136 ####################################################################
137 #
138 # Utility functions
139 #
140 ####################################################################
142 def arg_check(args,num,name):
143 if len(args) < num:
144 err("'xm %s' requires %s argument(s)!\n" % (name, num))
145 usage(name)
147 def unit(c):
148 if not c.isalpha():
149 return 0
150 base = 1
151 if c == 'G' or c == 'g': base = 1024 * 1024 * 1024
152 elif c == 'M' or c == 'm': base = 1024 * 1024
153 elif c == 'K' or c == 'k': base = 1024
154 else:
155 print 'ignoring unknown unit'
156 return base
158 def int_unit(str, dest):
159 base = unit(str[-1])
160 if not base:
161 return int(str)
163 value = int(str[:-1])
164 dst_base = unit(dest)
165 if dst_base == 0:
166 dst_base = 1
167 if dst_base > base:
168 return value / (dst_base / base)
169 else:
170 return value * (base / dst_base)
172 def err(msg):
173 print >>sys.stderr, "Error:", msg
175 def handle_xend_error(cmd, dom, ex):
176 error = str(ex)
177 if error == "Not found" and dom != None:
178 err("Domain '%s' not found when running 'xm %s'" % (dom, cmd))
179 sys.exit(1)
180 else:
181 err(error)
182 sys.exit(1)
185 #########################################################################
186 #
187 # Main xm functions
188 #
189 #########################################################################
191 def xm_save(args):
192 arg_check(args,2,"save")
194 dom = args[0] # TODO: should check if this exists
195 savefile = os.path.abspath(args[1])
197 if not os.access(os.path.dirname(savefile), os.W_OK):
198 err("xm save: Unable to create file %s" % savefile)
199 sys.exit(1)
201 from xen.xend.XendClient import server
202 server.xend_domain_save(dom, savefile)
204 def xm_restore(args):
205 arg_check(args,1,"restore")
207 savefile = os.path.abspath(args[0])
209 if not os.access(savefile, os.R_OK):
210 err("xm restore: Unable to read file %s" % savefile)
211 sys.exit(1)
213 from xen.xend.XendClient import server
214 info = server.xend_domain_restore(savefile)
215 PrettyPrint.prettyprint(info)
216 id = sxp.child_value(info, 'domid')
217 if id is not None:
218 server.xend_domain_unpause(domid)
221 def getDomains(domain_names):
222 from xen.xend.XendClient import server
223 if domain_names:
224 return map(server.xend_domain, domain_names)
225 else:
226 return server.xend_list_domains()
229 def xm_list(args):
230 use_long = 0
231 show_vcpus = 0
232 try:
233 (options, params) = getopt(args, 'lv', ['long','vcpus'])
234 except GetoptError, opterr:
235 err(opterr)
236 sys.exit(1)
238 for (k, v) in options:
239 if k in ['-l', '--long']:
240 use_long = 1
241 if k in ['-v', '--vcpus']:
242 show_vcpus = 1
244 if show_vcpus:
245 print >>sys.stderr, (
246 "xm list -v is deprecated. Please use xm vcpu-list.")
247 xm_vcpu_list(params)
248 return
250 doms = getDomains(params)
252 if use_long:
253 map(PrettyPrint.prettyprint, doms)
254 else:
255 xm_brief_list(doms)
258 def parse_doms_info(info):
259 def get_info(n, t, d):
260 return t(sxp.child_value(info, n, d))
262 return {
263 'dom' : get_info('domid', int, -1),
264 'name' : get_info('name', str, '??'),
265 'mem' : get_info('memory', int, 0),
266 'vcpus' : get_info('vcpus', int, 0),
267 'state' : get_info('state', str, '??'),
268 'cpu_time' : get_info('cpu_time', float, 0),
269 'ssidref' : get_info('ssidref', int, 0),
270 }
273 def xm_brief_list(doms):
274 print 'Name ID Mem(MiB) VCPUs State Time(s)'
275 for dom in doms:
276 d = parse_doms_info(dom)
277 if (d['ssidref'] != 0):
278 d['ssidstr'] = (" s:%04x/p:%04x" %
279 ((d['ssidref'] >> 16) & 0xffff,
280 d['ssidref'] & 0xffff))
281 else:
282 d['ssidstr'] = ""
283 print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f%(ssidstr)s" % d)
286 def xm_vcpu_list(args):
287 print 'Name ID VCPU CPU State Time(s) CPU Affinity'
289 from xen.xend.XendClient import server
290 if args:
291 dominfo = map(server.xend_domain_vcpuinfo, args)
292 else:
293 doms = server.xend_list_domains()
294 dominfo = map(
295 lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')),
296 doms)
298 for dom in dominfo:
299 def get_info(n):
300 return sxp.child_value(dom, n)
302 #
303 # convert a list of integers into a list of pairs indicating
304 # continuous sequences in the list:
305 #
306 # [0,1,2,3] -> [(0,3)]
307 # [1,2,4,5] -> [(1,2),(4,5)]
308 # [0] -> [(0,0)]
309 # [0,1,4,6,7] -> [(0,1),(4,4),(6,7)]
310 #
311 def list_to_rangepairs(cmap):
312 cmap.sort()
313 pairs = []
314 x = y = 0
315 for i in range(0,len(cmap)):
316 try:
317 if ((cmap[y+1] - cmap[i]) > 1):
318 pairs.append((cmap[x],cmap[y]))
319 x = y = i+1
320 else:
321 y = y + 1
322 # if we go off the end, then just add x to y
323 except IndexError:
324 pairs.append((cmap[x],cmap[y]))
326 return pairs
328 #
329 # Convert pairs to range string, e.g: [(1,2),(3,3),(5,7)] -> 1-2,3,5-7
330 #
331 def format_pairs(pairs):
332 if not pairs:
333 return "no cpus"
334 out = ""
335 for f,s in pairs:
336 if (f==s):
337 out += '%d'%f
338 else:
339 out += '%d-%d'%(f,s)
340 out += ','
341 # trim trailing ','
342 return out[:-1]
344 def format_cpumap(cpumap):
345 cpumap = map(lambda x: int(x), cpumap)
346 cpumap.sort()
348 from xen.xend.XendClient import server
349 for x in server.xend_node()[1:]:
350 if len(x) > 1 and x[0] == 'nr_cpus':
351 nr_cpus = int(x[1])
352 cpumap = filter(lambda x: x < nr_cpus, cpumap)
353 if len(cpumap) == nr_cpus:
354 return "any cpu"
355 break
357 return format_pairs(list_to_rangepairs(cpumap))
359 name = get_info('name')
360 domid = int(get_info('domid'))
362 for vcpu in sxp.children(dom, 'vcpu'):
363 def vinfo(n, t):
364 return t(sxp.child_value(vcpu, n))
366 number = vinfo('number', int)
367 cpu = vinfo('cpu', int)
368 cpumap = format_cpumap(vinfo('cpumap', list))
369 online = vinfo('online', int)
370 cpu_time = vinfo('cpu_time', float)
371 running = vinfo('running', int)
372 blocked = vinfo('blocked', int)
374 if online:
375 c = str(cpu)
376 if running:
377 s = 'r'
378 else:
379 s = '-'
380 if blocked:
381 s += 'b'
382 else:
383 s += '-'
384 s += '-'
385 else:
386 c = "-"
387 s = "--p"
389 print (
390 "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f %(cpumap)s" %
391 locals())
394 def xm_reboot(args):
395 arg_check(args,1,"reboot")
396 from xen.xm import shutdown
397 # ugly hack because the opt parser apparently wants
398 # the subcommand name just to throw it away!
399 shutdown.main(["bogus", "-R"] + args)
401 def xm_pause(args):
402 arg_check(args, 1, "pause")
403 dom = args[0]
405 from xen.xend.XendClient import server
406 server.xend_domain_pause(dom)
408 def xm_unpause(args):
409 arg_check(args, 1, "unpause")
410 dom = args[0]
412 from xen.xend.XendClient import server
413 server.xend_domain_unpause(dom)
415 def xm_subcommand(command, args):
416 cmd = __import__(command, globals(), locals(), 'xen.xm')
417 cmd.main(["bogus"] + args)
420 #############################################################
422 def cpu_make_map(cpulist):
423 cpus = []
424 for c in cpulist.split(','):
425 if c.find('-') != -1:
426 (x,y) = c.split('-')
427 for i in range(int(x),int(y)+1):
428 cpus.append(int(i))
429 else:
430 cpus.append(int(c))
431 cpus.sort()
432 return cpus
434 def xm_vcpu_pin(args):
435 arg_check(args, 3, "vcpu-pin")
437 dom = args[0]
438 vcpu = int(args[1])
439 cpumap = cpu_make_map(args[2])
441 from xen.xend.XendClient import server
442 server.xend_domain_pincpu(dom, vcpu, cpumap)
444 def xm_mem_max(args):
445 arg_check(args, 2, "mem-max")
447 dom = args[0]
448 mem = int_unit(args[1], 'm')
450 from xen.xend.XendClient import server
451 server.xend_domain_maxmem_set(dom, mem)
453 def xm_mem_set(args):
454 arg_check(args, 2, "mem-set")
456 dom = args[0]
457 mem_target = int_unit(args[1], 'm')
459 from xen.xend.XendClient import server
460 server.xend_domain_mem_target_set(dom, mem_target)
462 def xm_set_vcpus(args):
463 arg_check(args, 2, "set-vcpus")
465 from xen.xend.XendClient import server
466 server.xend_domain_set_vcpus(args[0], int(args[1]))
468 def xm_domid(args):
469 arg_check(args, 1, "domid")
471 name = args[0]
473 from xen.xend.XendClient import server
474 dom = server.xend_domain(name)
475 print sxp.child_value(dom, 'domid')
477 def xm_domname(args):
478 arg_check(args, 1, "domname")
480 name = args[0]
482 from xen.xend.XendClient import server
483 dom = server.xend_domain(name)
484 print sxp.child_value(dom, 'name')
486 def xm_sched_bvt(args):
487 arg_check(args, 6, "sched-bvt")
488 dom = args[0]
489 v = map(long, args[1:6])
490 from xen.xend.XendClient import server
491 server.xend_domain_cpu_bvt_set(dom, *v)
493 def xm_sched_bvt_ctxallow(args):
494 arg_check(args, 1, "sched-bvt-ctxallow")
496 slice = int(args[0])
497 from xen.xend.XendClient import server
498 server.xend_node_cpu_bvt_slice_set(slice)
500 def xm_sched_sedf(args):
501 arg_check(args, 6, "sched-sedf")
503 dom = args[0]
504 v = map(int, args[1:6])
505 from xen.xend.XendClient import server
506 server.xend_domain_cpu_sedf_set(dom, *v)
508 def xm_info(args):
509 from xen.xend.XendClient import server
510 info = server.xend_node()
512 for x in info[1:]:
513 if len(x) < 2:
514 print "%-23s: (none)" % x[0]
515 else:
516 print "%-23s:" % x[0], x[1]
518 # TODO: remove as soon as console server shows up
519 def xm_console(args):
520 arg_check(args,1,"console")
522 dom = args[0]
523 from xen.xend.XendClient import server
524 info = server.xend_domain(dom)
525 domid = int(sxp.child_value(info, 'domid', '-1'))
526 console.execConsole(domid)
529 def xm_top(args):
530 os.execvp('xentop', ['xentop'])
532 def xm_dmesg(args):
534 gopts = Opts(use="""[-c|--clear]
536 Read Xen's message buffer (boot output, warning and error messages) or clear
537 its contents if the [-c|--clear] flag is specified.
538 """)
540 gopts.opt('clear', short='c',
541 fn=set_true, default=0,
542 use="Clear the contents of the Xen message buffer.")
543 # Work around for gopts
544 myargs = args
545 myargs.insert(0, "bogus")
546 gopts.parse(myargs)
547 if not (1 <= len(myargs) <= 2):
548 err('Invalid arguments: ' + str(myargs))
550 from xen.xend.XendClient import server
551 if not gopts.vals.clear:
552 print server.xend_node_get_dmesg()
553 else:
554 server.xend_node_clear_dmesg()
556 def xm_log(args):
557 from xen.xend.XendClient import server
558 print server.xend_node_log()
560 def xm_network_limit(args):
561 arg_check(args,4,"network-limit")
562 dom = args[0]
563 v = map(int, args[1:4])
564 from xen.xend.XendClient import server
565 server.xend_domain_vif_limit(dom, *v)
567 def xm_network_list(args):
568 arg_check(args,1,"network-list")
569 dom = args[0]
570 from xen.xend.XendClient import server
571 for x in server.xend_domain_devices(dom, 'vif'):
572 sxp.show(x)
573 print
575 def xm_block_list(args):
576 arg_check(args,1,"block-list")
577 dom = args[0]
578 from xen.xend.XendClient import server
579 for x in server.xend_domain_devices(dom, 'vbd'):
580 sxp.show(x)
581 print
583 def xm_block_attach(args):
584 n = len(args)
585 if n == 0:
586 usage("block-attach")
588 if n < 4 or n > 5:
589 err("%s: Invalid argument(s)" % args[0])
590 usage("block-attach")
592 dom = args[0]
593 vbd = ['vbd',
594 ['uname', args[1]],
595 ['dev', args[2]],
596 ['mode', args[3]]]
597 if n == 5:
598 vbd.append(['backend', args[4]])
600 from xen.xend.XendClient import server
601 server.xend_domain_device_create(dom, vbd)
604 def xm_network_attach(args):
605 n = len(args)
606 if n == 0:
607 usage("network-attach")
609 dom = args[0]
610 vif = ['vif']
612 for a in args[1:]:
613 vif.append(a.split("="))
615 from xen.xend.XendClient import server
616 server.xend_domain_device_create(dom, vif)
619 def detach(args, command, deviceClass):
620 arg_check(args, 2, command)
622 dom = args[0]
623 dev = args[1]
625 from xen.xend.XendClient import server
626 server.xend_domain_device_destroy(dom, deviceClass, dev)
629 def xm_block_detach(args):
630 detach(args, 'block-detach', 'vbd')
633 def xm_network_detach(args):
634 detach(args, 'network-detach', 'vif')
637 def xm_vnet_list(args):
638 from xen.xend.XendClient import server
639 try:
640 (options, params) = getopt(args, 'l', ['long'])
641 except GetoptError, opterr:
642 err(opterr)
643 sys.exit(1)
645 use_long = 0
646 for (k, v) in options:
647 if k in ['-l', '--long']:
648 use_long = 1
650 if params:
651 use_long = 1
652 vnets = params
653 else:
654 vnets = server.xend_vnets()
656 for vnet in vnets:
657 try:
658 if use_long:
659 info = server.xend_vnet(vnet)
660 PrettyPrint.prettyprint(info)
661 else:
662 print vnet
663 except Exception, ex:
664 print vnet, ex
666 def xm_vnet_create(args):
667 arg_check(args, 1, "vnet-create")
668 conf = args[0]
669 from xen.xend.XendClient import server
670 server.xend_vnet_create(conf)
672 def xm_vnet_delete(args):
673 arg_check(args, 1, "vnet-delete")
674 vnet = args[0]
675 from xen.xend.XendClient import server
676 server.xend_vnet_delete(vnet)
678 commands = {
679 # console commands
680 "console": xm_console,
681 # xenstat commands
682 "top": xm_top,
683 # domain commands
684 "domid": xm_domid,
685 "domname": xm_domname,
686 "restore": xm_restore,
687 "save": xm_save,
688 "reboot": xm_reboot,
689 "list": xm_list,
690 # memory commands
691 "mem-max": xm_mem_max,
692 "mem-set": xm_mem_set,
693 # cpu commands
694 "vcpu-pin": xm_vcpu_pin,
695 "set-vcpus": xm_set_vcpus,
696 "vcpu-list": xm_vcpu_list,
697 # special
698 "pause": xm_pause,
699 "unpause": xm_unpause,
700 # host commands
701 "dmesg": xm_dmesg,
702 "info": xm_info,
703 "log": xm_log,
704 # scheduler
705 "sched-bvt": xm_sched_bvt,
706 "sched-bvt-ctxallow": xm_sched_bvt_ctxallow,
707 "sched-sedf": xm_sched_sedf,
708 # block
709 "block-attach": xm_block_attach,
710 "block-detach": xm_block_detach,
711 "block-list": xm_block_list,
712 # network
713 "network-attach": xm_network_attach,
714 "network-detach": xm_network_detach,
715 "network-limit": xm_network_limit,
716 "network-list": xm_network_list,
717 # vnet
718 "vnet-list": xm_vnet_list,
719 "vnet-create": xm_vnet_create,
720 "vnet-delete": xm_vnet_delete,
721 }
723 ## The commands supported by a separate argument parser in xend.xm.
724 subcommands = [
725 'create',
726 'destroy',
727 'migrate',
728 'sysrq',
729 'shutdown'
730 ]
732 for c in subcommands:
733 commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
735 aliases = {
736 "balloon": "mem-set",
737 "vif-list": "network-list",
738 "vif-limit": "network-limit",
739 "vbd-create": "block-create",
740 "vbd-destroy": "block-destroy",
741 "vbd-list": "block-list",
742 }
744 help = {
745 "--long": longhelp
746 }
749 def xm_lookup_cmd(cmd):
750 if commands.has_key(cmd):
751 return commands[cmd]
752 elif aliases.has_key(cmd):
753 deprecated(cmd,aliases[cmd])
754 return commands[aliases[cmd]]
755 else:
756 if len( cmd ) > 1:
757 matched_commands = filter( lambda (command, func): command[ 0:len(cmd) ] == cmd, commands.iteritems() )
758 if len( matched_commands ) == 1:
759 return matched_commands[0][1]
760 err('Sub Command %s not found!' % cmd)
761 usage()
763 def deprecated(old,new):
764 err('Option %s is deprecated, and will be removed in future!!!' % old)
765 err('Option %s is the new replacement, see "xm help %s" for more info' % (new, new))
767 def usage(cmd=None):
768 if help.has_key(cmd):
769 print help[cmd]
770 else:
771 print shorthelp
772 sys.exit(1)
774 def main(argv=sys.argv):
775 if len(argv) < 2:
776 usage()
778 if re.compile('-*help').match(argv[1]):
779 if len(argv) > 2:
780 usage(argv[2])
781 else:
782 usage()
783 sys.exit(0)
785 cmd = xm_lookup_cmd(argv[1])
787 # strip off prog name and subcmd
788 args = argv[2:]
789 if cmd:
790 try:
791 rc = cmd(args)
792 if rc:
793 usage()
794 except socket.error, ex:
795 if os.geteuid() != 0:
796 err("Most commands need root access. Please try again as root.")
797 else:
798 err("Error connecting to xend: %s. Is xend running?" % ex[1])
799 sys.exit(1)
800 except KeyboardInterrupt:
801 print "Interrupted."
802 sys.exit(1)
803 except IOError:
804 if os.geteuid() != 0:
805 err("Most commands need root access. Please try again as root.")
806 else:
807 err("Error connecting to xend: %s." % ex[1])
808 sys.exit(1)
809 except xen.xend.XendError.XendError, ex:
810 if len(args) > 0:
811 handle_xend_error(argv[1], args[0], ex)
812 else:
813 print "Unexpected error:", sys.exc_info()[0]
814 print
815 print "Please report to xen-devel@lists.xensource.com"
816 raise
817 except xen.xend.XendProtocol.XendError, ex:
818 if len(args) > 0:
819 handle_xend_error(argv[1], args[0], ex)
820 else:
821 print "Unexpected error:", sys.exc_info()[0]
822 print
823 print "Please report to xen-devel@lists.xensource.com"
824 raise
825 except SystemExit:
826 sys.exit(1)
827 except:
828 print "Unexpected error:", sys.exc_info()[0]
829 print
830 print "Please report to xen-devel@lists.xensource.com"
831 raise
833 else:
834 usage()
836 if __name__ == "__main__":
837 main()