ia64/xen-unstable

view tools/python/xen/xm/main.py @ 7625:98515ca23ca3

This patch adds an arg_check into the set_vcpus code in xm, so that we
don't output a stack trace if <2 arguments are passed.

Signed-off-by: Dan Smith <danms@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Nov 04 11:03:20 2005 +0100 (2005-11-04)
parents 28face899030
children d9d88dd713ba
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 name = args[0]
471 from xen.xend.XendClient import server
472 dom = server.xend_domain(name)
473 print sxp.child_value(dom, 'domid')
475 def xm_domname(args):
476 name = args[0]
478 from xen.xend.XendClient import server
479 dom = server.xend_domain(name)
480 print sxp.child_value(dom, 'name')
482 def xm_sched_bvt(args):
483 arg_check(args, 6, "sched-bvt")
484 dom = args[0]
485 v = map(long, args[1:6])
486 from xen.xend.XendClient import server
487 server.xend_domain_cpu_bvt_set(dom, *v)
489 def xm_sched_bvt_ctxallow(args):
490 arg_check(args, 1, "sched-bvt-ctxallow")
492 slice = int(args[0])
493 from xen.xend.XendClient import server
494 server.xend_node_cpu_bvt_slice_set(slice)
496 def xm_sched_sedf(args):
497 arg_check(args, 6, "sched-sedf")
499 dom = args[0]
500 v = map(int, args[1:6])
501 from xen.xend.XendClient import server
502 server.xend_domain_cpu_sedf_set(dom, *v)
504 def xm_info(args):
505 from xen.xend.XendClient import server
506 info = server.xend_node()
508 for x in info[1:]:
509 if len(x) < 2:
510 print "%-23s: (none)" % x[0]
511 else:
512 print "%-23s:" % x[0], x[1]
514 # TODO: remove as soon as console server shows up
515 def xm_console(args):
516 arg_check(args,1,"console")
518 dom = args[0]
519 from xen.xend.XendClient import server
520 info = server.xend_domain(dom)
521 domid = int(sxp.child_value(info, 'domid', '-1'))
522 console.execConsole(domid)
525 def xm_top(args):
526 os.execvp('xentop', ['xentop'])
528 def xm_dmesg(args):
530 gopts = Opts(use="""[-c|--clear]
532 Read Xen's message buffer (boot output, warning and error messages) or clear
533 its contents if the [-c|--clear] flag is specified.
534 """)
536 gopts.opt('clear', short='c',
537 fn=set_true, default=0,
538 use="Clear the contents of the Xen message buffer.")
539 # Work around for gopts
540 myargs = args
541 myargs.insert(0, "bogus")
542 gopts.parse(myargs)
543 if not (1 <= len(myargs) <= 2):
544 err('Invalid arguments: ' + str(myargs))
546 from xen.xend.XendClient import server
547 if not gopts.vals.clear:
548 print server.xend_node_get_dmesg()
549 else:
550 server.xend_node_clear_dmesg()
552 def xm_log(args):
553 from xen.xend.XendClient import server
554 print server.xend_node_log()
556 def xm_network_limit(args):
557 arg_check(args,4,"network-limit")
558 dom = args[0]
559 v = map(int, args[1:4])
560 from xen.xend.XendClient import server
561 server.xend_domain_vif_limit(dom, *v)
563 def xm_network_list(args):
564 arg_check(args,1,"network-list")
565 dom = args[0]
566 from xen.xend.XendClient import server
567 for x in server.xend_domain_devices(dom, 'vif'):
568 sxp.show(x)
569 print
571 def xm_block_list(args):
572 arg_check(args,1,"block-list")
573 dom = args[0]
574 from xen.xend.XendClient import server
575 for x in server.xend_domain_devices(dom, 'vbd'):
576 sxp.show(x)
577 print
579 def xm_block_attach(args):
580 n = len(args)
581 if n == 0:
582 usage("block-attach")
584 if n < 4 or n > 5:
585 err("%s: Invalid argument(s)" % args[0])
586 usage("block-attach")
588 dom = args[0]
589 vbd = ['vbd',
590 ['uname', args[1]],
591 ['dev', args[2]],
592 ['mode', args[3]]]
593 if n == 5:
594 vbd.append(['backend', args[4]])
596 from xen.xend.XendClient import server
597 server.xend_domain_device_create(dom, vbd)
600 def xm_network_attach(args):
601 n = len(args)
602 if n == 0:
603 usage("network-attach")
605 dom = args[0]
606 vif = ['vif']
608 for a in args[1:]:
609 vif.append(a.split("="))
611 from xen.xend.XendClient import server
612 server.xend_domain_device_create(dom, vif)
615 def detach(args, command, deviceClass):
616 arg_check(args, 2, command)
618 dom = args[0]
619 dev = args[1]
621 from xen.xend.XendClient import server
622 server.xend_domain_device_destroy(dom, deviceClass, dev)
625 def xm_block_detach(args):
626 detach(args, 'block-detach', 'vbd')
629 def xm_network_detach(args):
630 detach(args, 'network-detach', 'vif')
633 def xm_vnet_list(args):
634 from xen.xend.XendClient import server
635 try:
636 (options, params) = getopt(args, 'l', ['long'])
637 except GetoptError, opterr:
638 err(opterr)
639 sys.exit(1)
641 use_long = 0
642 for (k, v) in options:
643 if k in ['-l', '--long']:
644 use_long = 1
646 if params:
647 use_long = 1
648 vnets = params
649 else:
650 vnets = server.xend_vnets()
652 for vnet in vnets:
653 try:
654 if use_long:
655 info = server.xend_vnet(vnet)
656 PrettyPrint.prettyprint(info)
657 else:
658 print vnet
659 except Exception, ex:
660 print vnet, ex
662 def xm_vnet_create(args):
663 arg_check(args, 1, "vnet-create")
664 conf = args[0]
665 from xen.xend.XendClient import server
666 server.xend_vnet_create(conf)
668 def xm_vnet_delete(args):
669 arg_check(args, 1, "vnet-delete")
670 vnet = args[0]
671 from xen.xend.XendClient import server
672 server.xend_vnet_delete(vnet)
674 commands = {
675 # console commands
676 "console": xm_console,
677 # xenstat commands
678 "top": xm_top,
679 # domain commands
680 "domid": xm_domid,
681 "domname": xm_domname,
682 "restore": xm_restore,
683 "save": xm_save,
684 "reboot": xm_reboot,
685 "list": xm_list,
686 # memory commands
687 "mem-max": xm_mem_max,
688 "mem-set": xm_mem_set,
689 # cpu commands
690 "vcpu-pin": xm_vcpu_pin,
691 "set-vcpus": xm_set_vcpus,
692 "vcpu-list": xm_vcpu_list,
693 # special
694 "pause": xm_pause,
695 "unpause": xm_unpause,
696 # host commands
697 "dmesg": xm_dmesg,
698 "info": xm_info,
699 "log": xm_log,
700 # scheduler
701 "sched-bvt": xm_sched_bvt,
702 "sched-bvt-ctxallow": xm_sched_bvt_ctxallow,
703 "sched-sedf": xm_sched_sedf,
704 # block
705 "block-attach": xm_block_attach,
706 "block-detach": xm_block_detach,
707 "block-list": xm_block_list,
708 # network
709 "network-attach": xm_network_attach,
710 "network-detach": xm_network_detach,
711 "network-limit": xm_network_limit,
712 "network-list": xm_network_list,
713 # vnet
714 "vnet-list": xm_vnet_list,
715 "vnet-create": xm_vnet_create,
716 "vnet-delete": xm_vnet_delete,
717 }
719 ## The commands supported by a separate argument parser in xend.xm.
720 subcommands = [
721 'create',
722 'destroy',
723 'migrate',
724 'sysrq',
725 'shutdown'
726 ]
728 for c in subcommands:
729 commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
731 aliases = {
732 "balloon": "mem-set",
733 "vif-list": "network-list",
734 "vif-limit": "network-limit",
735 "vbd-create": "block-create",
736 "vbd-destroy": "block-destroy",
737 "vbd-list": "block-list",
738 }
740 help = {
741 "--long": longhelp
742 }
745 def xm_lookup_cmd(cmd):
746 if commands.has_key(cmd):
747 return commands[cmd]
748 elif aliases.has_key(cmd):
749 deprecated(cmd,aliases[cmd])
750 return commands[aliases[cmd]]
751 else:
752 if len( cmd ) > 1:
753 matched_commands = filter( lambda (command, func): command[ 0:len(cmd) ] == cmd, commands.iteritems() )
754 if len( matched_commands ) == 1:
755 return matched_commands[0][1]
756 err('Sub Command %s not found!' % cmd)
757 usage()
759 def deprecated(old,new):
760 err('Option %s is deprecated, and will be removed in future!!!' % old)
761 err('Option %s is the new replacement, see "xm help %s" for more info' % (new, new))
763 def usage(cmd=None):
764 if help.has_key(cmd):
765 print help[cmd]
766 else:
767 print shorthelp
768 sys.exit(1)
770 def main(argv=sys.argv):
771 if len(argv) < 2:
772 usage()
774 if re.compile('-*help').match(argv[1]):
775 if len(argv) > 2:
776 usage(argv[2])
777 else:
778 usage()
779 sys.exit(0)
781 cmd = xm_lookup_cmd(argv[1])
783 # strip off prog name and subcmd
784 args = argv[2:]
785 if cmd:
786 try:
787 rc = cmd(args)
788 if rc:
789 usage()
790 except socket.error, ex:
791 if os.geteuid() != 0:
792 err("Most commands need root access. Please try again as root.")
793 else:
794 err("Error connecting to xend: %s. Is xend running?" % ex[1])
795 sys.exit(1)
796 except KeyboardInterrupt:
797 print "Interrupted."
798 sys.exit(1)
799 except IOError:
800 if os.geteuid() != 0:
801 err("Most commands need root access. Please try again as root.")
802 else:
803 err("Error connecting to xend: %s." % ex[1])
804 sys.exit(1)
805 except xen.xend.XendError.XendError, ex:
806 if len(args) > 0:
807 handle_xend_error(argv[1], args[0], ex)
808 else:
809 print "Unexpected error:", sys.exc_info()[0]
810 print
811 print "Please report to xen-devel@lists.xensource.com"
812 raise
813 except xen.xend.XendProtocol.XendError, ex:
814 if len(args) > 0:
815 handle_xend_error(argv[1], args[0], ex)
816 else:
817 print "Unexpected error:", sys.exc_info()[0]
818 print
819 print "Please report to xen-devel@lists.xensource.com"
820 raise
821 except SystemExit:
822 sys.exit(1)
823 except:
824 print "Unexpected error:", sys.exc_info()[0]
825 print
826 print "Please report to xen-devel@lists.xensource.com"
827 raise
829 else:
830 usage()
832 if __name__ == "__main__":
833 main()