[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 1ca87f35ee4e8b85663dd64787ec730cf3fe7de9 # Parent 4a3d9fa6ba24d80fbd1d541288e4e456d4d642ee # Parent 0e9055d69f12e230ed086bd9445aef863a16e129 merge --- tools/firmware/vmxassist/machine.h | 1 tools/firmware/vmxassist/vm86.c | 87 +++- tools/python/xen/xm/addlabel.py | 37 + tools/python/xen/xm/cfgbootpolicy.py | 25 - tools/python/xen/xm/console.py | 2 tools/python/xen/xm/create.py | 71 +-- tools/python/xen/xm/dry-run.py | 20 - tools/python/xen/xm/dumppolicy.py | 11 tools/python/xen/xm/getlabel.py | 36 - tools/python/xen/xm/labels.py | 77 +--- tools/python/xen/xm/loadpolicy.py | 19 - tools/python/xen/xm/main.py | 658 ++++++++++++++++++++--------------- tools/python/xen/xm/makepolicy.py | 10 tools/python/xen/xm/migrate.py | 16 tools/python/xen/xm/opts.py | 90 ++++ tools/python/xen/xm/resources.py | 25 - tools/python/xen/xm/rmlabel.py | 32 - tools/python/xen/xm/sysrq.py | 14 xen/arch/x86/hvm/svm/svm.c | 12 xen/arch/x86/hvm/vmx/vmx.c | 1 xen/arch/x86/mm/shadow/common.c | 2 xen/include/asm-x86/hvm/hvm.h | 7 xen/include/asm-x86/hvm/vmx/vmcs.h | 3 xen/include/asm-x86/hvm/vmx/vmx.h | 6 24 files changed, 744 insertions(+), 518 deletions(-) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/firmware/vmxassist/machine.h --- a/tools/firmware/vmxassist/machine.h Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/firmware/vmxassist/machine.h Fri Sep 22 13:06:20 2006 +0100 @@ -36,6 +36,7 @@ #define CR4_VME (1 << 0) #define CR4_PVI (1 << 1) #define CR4_PSE (1 << 4) +#define CR4_PAE (1 << 5) #define EFLAGS_ZF (1 << 6) #define EFLAGS_TF (1 << 8) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/firmware/vmxassist/vm86.c --- a/tools/firmware/vmxassist/vm86.c Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/firmware/vmxassist/vm86.c Fri Sep 22 13:06:20 2006 +0100 @@ -52,29 +52,74 @@ static char *rnames[] = { "ax", "cx", "d static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }; #endif /* DEBUG */ +#define PDE_PS (1 << 7) #define PT_ENTRY_PRESENT 0x1 +/* We only support access to <=4G physical memory due to 1:1 mapping */ static unsigned -guest_linear_to_real(unsigned long base, unsigned off) -{ - unsigned int gcr3 = oldctx.cr3; - unsigned int l1_mfn; - unsigned int l0_mfn; +guest_linear_to_real(uint32_t base) +{ + uint32_t gcr3 = oldctx.cr3; + uint64_t l2_mfn; + uint64_t l1_mfn; + uint64_t l0_mfn; if (!(oldctx.cr0 & CR0_PG)) - return base + off; - - l1_mfn = ((unsigned int *)gcr3)[(base >> 22) & 0x3ff ]; - if (!(l1_mfn & PT_ENTRY_PRESENT)) - panic("l2 entry not present\n"); - l1_mfn = l1_mfn & 0xfffff000 ; - - l0_mfn = ((unsigned int *)l1_mfn)[(base >> 12) & 0x3ff]; - if (!(l0_mfn & PT_ENTRY_PRESENT)) - panic("l1 entry not present\n"); - l0_mfn = l0_mfn & 0xfffff000; - - return l0_mfn + off + (base & 0xfff); + return base; + + if (!(oldctx.cr4 & CR4_PAE)) { + l1_mfn = ((uint32_t *)gcr3)[(base >> 22) & 0x3ff]; + + if (oldctx.cr4 & CR4_PSE || l1_mfn & PDE_PS) { + /* 1 level page table */ + l0_mfn = l1_mfn; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + + l0_mfn &= 0xffc00000; + return l0_mfn + (base & 0x3fffff); + } + + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + + l1_mfn &= 0xfffff000; + l0_mfn = ((uint32_t *)l1_mfn)[(base >> 12) & 0x3ff]; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + l0_mfn &= 0xfffff000; + + return l0_mfn + (base & 0xfff); + } else if (oldctx.cr4 & CR4_PAE && !(oldctx.cr4 & CR4_PSE)) { + l2_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3]; + if (!(l2_mfn & PT_ENTRY_PRESENT)) + panic("l3 entry not present\n"); + l2_mfn &= 0x3fffff000ULL; + + l1_mfn = ((uint64_t *)l2_mfn)[(base >> 21) & 0x1ff]; + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + l1_mfn &= 0x3fffff000ULL; + + l0_mfn = ((uint64_t *)l1_mfn)[(base >> 12) & 0x1ff]; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + l0_mfn &= 0x3fffff000ULL; + + return l0_mfn + (base & 0xfff); + } else { /* oldctx.cr4 & CR4_PAE && oldctx.cr4 & CR4_PSE */ + l1_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3]; + if (!(l1_mfn & PT_ENTRY_PRESENT)) + panic("l2 entry not present\n"); + l1_mfn &= 0x3fffff000ULL; + + l0_mfn = ((uint64_t *)l1_mfn)[(base >> 21) & 0x1ff]; + if (!(l0_mfn & PT_ENTRY_PRESENT)) + panic("l1 entry not present\n"); + l0_mfn &= 0x3ffe00000ULL; + + return l0_mfn + (base & 0x1fffff); + } } static unsigned @@ -95,7 +140,8 @@ address(struct regs *regs, unsigned seg, (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg)) return ((seg & 0xFFFF) << 4) + off; - entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[seg >> 3]; + entry = ((unsigned long long *) + guest_linear_to_real(oldctx.gdtr_base))[seg >> 3]; entry_high = entry >> 32; entry_low = entry & 0xFFFFFFFF; @@ -780,7 +826,8 @@ load_seg(unsigned long sel, uint32_t *ba return 1; } - entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[sel >> 3]; + entry = ((unsigned long long *) + guest_linear_to_real(oldctx.gdtr_base))[sel >> 3]; /* Check the P bit first */ if (!((entry >> (15+32)) & 0x1) && sel != 0) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/addlabel.py --- a/tools/python/xen/xm/addlabel.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/addlabel.py Fri Sep 22 13:06:20 2006 +0100 @@ -19,19 +19,23 @@ """Labeling a domain configuration file or a resoruce. """ -import sys, os +import os +import sys + from xen.util import dictio from xen.util import security +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]" - print " xm addlabel <label> res <resource> [<policy>]\n" - print " This program adds an acm_label entry into the 'configfile'" - print " for a domain or to the global resource label file for a" - print " resource. It derives the policy from the running hypervisor" - print " if it is not given (optional parameter). If a label already" - print " exists for the given domain or resource, then addlabel fails.\n" - security.err("Usage") +def help(): + return """ + Format: xm addlabel <label> dom <configfile> [<policy>] + xm addlabel <label> res <resource> [<policy>] + + This program adds an acm_label entry into the 'configfile' + for a domain or to the global resource label file for a + resource. It derives the policy from the running hypervisor + if it is not given (optional parameter). If a label already + exists for the given domain or resource, then addlabel fails.""" def validate_config_file(configfile): @@ -114,9 +118,8 @@ def main (argv): def main (argv): try: policyref = None - if len(argv) not in [4,5]: - usage() - return + if len(argv) not in (4, 5): + raise OptionError('Needs either 2 or 3 arguments') label = argv[1] @@ -135,20 +138,20 @@ def main (argv): if os.path.isfile(configfile): break if not validate_config_file(configfile): - usage() + raise OptionError('Invalid config file') else: add_domain_label(label, configfile, policyref) elif argv[2].lower() == "res": resource = argv[3] add_resource_label(label, resource, policyref) else: - usage() - + raise OptionError('Need to specify either "dom" or "res" as object to add label to.') + except security.ACMError: sys.exit(-1) - if __name__ == '__main__': main(sys.argv) + diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/cfgbootpolicy.py --- a/tools/python/xen/xm/cfgbootpolicy.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/cfgbootpolicy.py Fri Sep 22 13:06:20 2006 +0100 @@ -28,20 +28,17 @@ from xen.util.security import policy_dir from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re from xen.util.security import empty_line_re, binary_name_re, policy_name_re +from xen.xm.opts import OptionError - -def usage(): - print "\nUsage: xm cfgbootpolicy <policy> [<kernelversion>]\n" - print " Adds a 'module' line to the Xen grub.conf entry" - print " so that xen boots into a specific access control" - print " policy. If kernelversion is not given, then this" - print " script tries to determine it by looking for a grub" - print " entry with a line kernel xen.* If there are multiple" - print " Xen entries, then it must be called with an explicit" - print " version (it will fail otherwise).\n" - err("Usage") - - +def help(): + return """ + Adds a 'module' line to the Xen grub.conf entry + so that xen boots into a specific access control + policy. If kernelversion is not given, then this + script tries to determine it by looking for a grub + entry with a line kernel xen.* If there are multiple + Xen entries, then it must be called with an explicit + version (it will fail otherwise).\n""" def determine_kernelversion(user_specified): within_xen_title = 0 @@ -152,7 +149,7 @@ def main(argv): policy = argv[1] user_kver = argv[2] else: - usage() + raise OptionError('Invalid number of arguments') if not policy_name_re.match(policy): err("Illegal policy name \'" + policy + "\'") diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/console.py --- a/tools/python/xen/xm/console.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/console.py Fri Sep 22 13:06:20 2006 +0100 @@ -18,9 +18,7 @@ XENCONSOLE = "xenconsole" - import xen.util.auxbin - def execConsole(domid): xen.util.auxbin.execute(XENCONSOLE, [str(domid)]) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/create.py Fri Sep 22 13:06:20 2006 +0100 @@ -25,7 +25,6 @@ import socket import socket import re import xmlrpclib -import traceback from xen.xend import sxp from xen.xend import PrettyPrint @@ -65,35 +64,36 @@ gopts.opt('quiet', short='q', gopts.opt('path', val='PATH', fn=set_value, default='.:/etc/xen', - use="""Search path for configuration scripts. - The value of PATH is a colon-separated directory list.""") + use="Search path for configuration scripts. " + "The value of PATH is a colon-separated directory list.") gopts.opt('defconfig', short='f', val='FILE', fn=set_value, default='xmdefconfig', - use="""Use the given Python configuration script. - The configuration script is loaded after arguments have been processed. - Each command-line option sets a configuration variable named after - its long option name, and these variables are placed in the - environment of the script before it is loaded. - Variables for options that may be repeated have list values. - Other variables can be set using VAR=VAL on the command line. - - After the script is loaded, option values that were not set on the - command line are replaced by the values set in the script.""") + use="Use the given Python configuration script." + "The configuration script is loaded after arguments have been " + "processed. Each command-line option sets a configuration " + "variable named after its long option name, and these " + "variables are placed in the environment of the script before " + "it is loaded. Variables for options that may be repeated have " + "list values. Other variables can be set using VAR=VAL on the " + "command line. " + "After the script is loaded, option values that were not set " + "on the command line are replaced by the values set in the script.") gopts.default('defconfig') gopts.opt('config', short='F', val='FILE', fn=set_value, default=None, - use="""Domain configuration to use (SXP). - SXP is the underlying configuration format used by Xen. - SXP configurations can be hand-written or generated from Python configuration - scripts, using the -n (dryrun) option to print the configuration.""") + use="Domain configuration to use (SXP).\n" + "SXP is the underlying configuration format used by Xen.\n" + "SXP configurations can be hand-written or generated from Python " + "configuration scripts, using the -n (dryrun) option to print\n" + "the configuration.") gopts.opt('dryrun', short='n', fn=set_true, default=0, - use="""Dry run - print the configuration but don't create the domain. - Loads the configuration script, creates the SXP configuration and prints it.""") + use="Dry run - prints the resulting configuration in SXP but " + "does not create the domain.") gopts.opt('paused', short='p', fn=set_true, default=0, @@ -105,18 +105,16 @@ gopts.opt('console_autoconnect', short=' gopts.var('vncviewer', val='no|yes', fn=set_bool, default=None, - use="""Spawn a vncviewer listening for a vnc server in the domain. - The address of the vncviewer is passed to the domain on the kernel command - line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY. - A display value with a free port is chosen if possible. - Only valid when vnc=1. - """) + use="Spawn a vncviewer listening for a vnc server in the domain.\n" + "The address of the vncviewer is passed to the domain on the " + "kernel command line using 'VNC_SERVER=<host>:<port>'. The port " + "used by vnc is 5500 + DISPLAY. A display value with a free port " + "is chosen if possible.\nOnly valid when vnc=1.") gopts.var('vncconsole', val='no|yes', fn=set_bool, default=None, - use="""Spawn a vncviewer process for the domain's graphical console. - Only valid when vnc=1. - """) + use="Spawn a vncviewer process for the domain's graphical console.\n" + "Only valid when vnc=1.") gopts.var('name', val='NAME', fn=set_value, default=None, @@ -439,7 +437,6 @@ gopts.var('uuid', val='', will be randomly generated if this option is not set, just like MAC addresses for virtual network interfaces. This must be a unique value across the entire cluster.""") - def err(msg): """Print an error to stderr and exit. @@ -490,7 +487,6 @@ def configure_disks(config_devs, vals): """Create the config for disks (virtual block devices). """ for (uname, dev, mode, backend) in vals.disk: - if uname.startswith('tap:'): cls = 'tap' else: @@ -851,7 +847,6 @@ def choose_vnc_display(): if port in ports: continue return d return None - vncpid = None def daemonize(prog, args): @@ -885,7 +880,6 @@ def daemonize(prog, args): w.write(str(pid2 or 0)) w.close() os._exit(0) - os.close(w) r = os.fdopen(r) daemon_pid = int(r.read()) @@ -904,6 +898,7 @@ def spawn_vnc(display): vncpid = daemonize("vncviewer", vncargs) if vncpid == 0: return 0 + return VNC_BASE_PORT + display def preprocess_vnc(vals): @@ -1091,7 +1086,6 @@ def check_domain_label(config, verbose): return answer - def config_security_check(config, verbose): """Checks each resource listed in the config to see if the active policy will permit creation of a new domain using the config. @@ -1145,7 +1139,6 @@ def config_security_check(config, verbos return answer - def create_security_check(config): passed = 0 try: @@ -1158,7 +1151,9 @@ def create_security_check(config): sys.exit(-1) return passed - + +def help(): + return str(gopts) def main(argv): try: @@ -1176,11 +1171,11 @@ def main(argv): PrettyPrint.prettyprint(config) else: if not create_security_check(config): - err("Security configuration prevents domain from starting.") + raise OptionError('Security Configuration prevents domain from starting') else: dom = make_domain(opts, config) if opts.vals.console_autoconnect: - console.execConsole(dom) - + console.execConsole(dom) + if __name__ == '__main__': main(sys.argv) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/dry-run.py --- a/tools/python/xen/xm/dry-run.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/dry-run.py Fri Sep 22 13:06:20 2006 +0100 @@ -22,20 +22,18 @@ from xen.util import security from xen.util import security from xen.xm import create from xen.xend import sxp +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm dry-run <configfile>\n" - print "This program checks each resource listed in the configfile" - print "to see if the domain created by the configfile can access" - print "the resources. The status of each resource is listed" - print "individually along with the final security decision.\n" - security.err("Usage") - +def help(): + return """ + This program checks each resource listed in the configfile + to see if the domain created by the configfile can access + the resources. The status of each resource is listed + individually along with the final security decision.""" def main (argv): - try: - if len(argv) != 2: - usage() + if len(argv) != 2: + raise OptionError('Invalid number of arguments') passed = 0 (opts, config) = create.parseCommandLine(argv) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/dumppolicy.py --- a/tools/python/xen/xm/dumppolicy.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/dumppolicy.py Fri Sep 22 13:06:20 2006 +0100 @@ -21,12 +21,10 @@ from xen.util.security import ACMError, from xen.util.security import ACMError, err, dump_policy -def usage(): - print "\nUsage: xm dumppolicy\n" - print " Retrieve and print currently enforced" - print " hypervisor policy information (low-level).\n" - err("Usage") - +def help(): + return """ + Retrieve and print currently enforced hypervisor policy information + (low-level).""" def main(argv): try: @@ -34,7 +32,6 @@ def main(argv): usage() dump_policy() - except ACMError: sys.exit(-1) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/getlabel.py --- a/tools/python/xen/xm/getlabel.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/getlabel.py Fri Sep 22 13:06:20 2006 +0100 @@ -21,13 +21,13 @@ import sys, os, re import sys, os, re from xen.util import dictio from xen.util import security +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm getlabel dom <configfile>" - print " xm getlabel res <resource>\n" - print " This program shows the label for a domain or resource.\n" - security.err("Usage") - +def help(): + return """ + Usage: xm getlabel dom <configfile>" + xm getlabel res <resource>\n" + This program shows the label for a domain or resource.""" def get_resource_label(resource): """Gets the resource label @@ -90,21 +90,17 @@ def get_domain_label(configfile): def main (argv): - try: - if len(argv) != 3: - usage() + if len(argv) != 3: + raise OptionError('Requires 2 arguments') - if argv[1].lower() == "dom": - configfile = argv[2] - get_domain_label(configfile) - elif argv[1].lower() == "res": - resource = argv[2] - get_resource_label(resource) - else: - usage() - - except security.ACMError: - sys.exit(-1) + if argv[1].lower() == "dom": + configfile = argv[2] + get_domain_label(configfile) + elif argv[1].lower() == "res": + resource = argv[2] + get_resource_label(resource) + else: + raise OptionError('First subcommand argument must be "dom" or "res"') if __name__ == '__main__': main(sys.argv) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/labels.py --- a/tools/python/xen/xm/labels.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/labels.py Fri Sep 22 13:06:20 2006 +0100 @@ -23,49 +23,46 @@ import string import string from xen.util.security import ACMError, err, list_labels, active_policy from xen.util.security import vm_label_re, res_label_re, all_label_re +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm labels [<policy>] [<type=dom|res|any>]\n" - print " Prints labels of the specified type (default is dom)" - print " that are defined in policy (default is current" - print " hypervisor policy).\n" - err("Usage") +def help(): + return """ + Prints labels of the specified type (default is dom) + that are defined in policy (default is current hypervisor policy).""" def main(argv): + policy = None + ptype = None + for arg in argv[1:]: + key_val = arg.split('=') + if len(key_val) == 2 and key_val[0] == 'type': + if ptype: + raise OptionError('type is definied twice') + ptype = key_val[1].lower() + + elif len(key_val) == 1: + if policy: + raise OptionError('policy is defined twice') + policy = arg + else: + raise OptionError('Unrecognised option: %s' % arg) + + if not policy: + policy = active_policy + if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']: + raise OptionError('No policy active, you must specify a <policy>') + + if not ptype or ptype == 'dom': + condition = vm_label_re + elif ptype == 'res': + condition = res_label_re + elif ptype == 'any': + condition = all_label_re + else: + err("Unknown label type \'" + ptype + "\'") + try: - policy = None - type = None - for i in argv[1:]: - i_s = string.split(i, '=') - if len(i_s) > 1: - if (i_s[0] == 'type') and (len(i_s) == 2): - if not type: - type = i_s[1] - else: - usage() - else: - usage() - else: - if not policy: - policy = i - else: - usage() - - if not policy: - policy = active_policy - if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']: - err("No policy active. Please specify the <policy> parameter.") - - if not type or (type in ['DOM', 'dom']): - condition = vm_label_re - elif type in ['RES', 'res']: - condition = res_label_re - elif type in ['ANY', 'any']: - condition = all_label_re - else: - err("Unknown label type \'" + type + "\'") - labels = list_labels(policy, condition) labels.sort() for label in labels: @@ -74,9 +71,7 @@ def main(argv): except ACMError: sys.exit(-1) except: - traceback.print_exc(limit=1) - sys.exit(-1) - + traceback.print_exc(limit = 1) if __name__ == '__main__': main(sys.argv) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/loadpolicy.py --- a/tools/python/xen/xm/loadpolicy.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/loadpolicy.py Fri Sep 22 13:06:20 2006 +0100 @@ -21,26 +21,23 @@ import sys import sys import traceback from xen.util.security import ACMError, err, load_policy +from xen.xm.opts import OptionError - -def usage(): - print "\nUsage: xm loadpolicy <policy>\n" - print " Load the compiled binary (.bin) policy" - print " into the running hypervisor.\n" - err("Usage") +def help(): + return """Load the compiled binary (.bin) policy into the running + hypervisor.""" def main(argv): + if len(argv) != 2: + raise OptionError('No policy defined') + try: - if len(argv) != 2: - usage() load_policy(argv[1]) except ACMError: sys.exit(-1) except: - traceback.print_exc(limit=1) - sys.exit(-1) - + traceback.print_exc(limit = 1) if __name__ == '__main__': main(sys.argv) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/main.py Fri Sep 22 13:06:20 2006 +0100 @@ -22,28 +22,27 @@ """Grand unified management application for Xen. """ import os -import os.path import sys import re import getopt import socket -import warnings -warnings.filterwarnings('ignore', category=FutureWarning) +import traceback import xmlrpclib import traceback import datetime - -import xen.xend.XendProtocol +from select import select + +import warnings +warnings.filterwarnings('ignore', category=FutureWarning) from xen.xend import PrettyPrint from xen.xend import sxp -from xen.xm.opts import * - -import console -import xen.xend.XendClient +from xen.xend import XendClient from xen.xend.XendClient import server + +from xen.xm.opts import OptionError, Opts, wrap, set_true +from xen.xm import console from xen.util import security -from select import select # getopt.gnu_getopt is better, but only exists in Python 2.3+. Use # getopt.getopt if gnu_getopt is not available. This will mean that options @@ -51,93 +50,148 @@ if not hasattr(getopt, 'gnu_getopt'): if not hasattr(getopt, 'gnu_getopt'): getopt.gnu_getopt = getopt.getopt - -# Strings for shorthelp -console_help = "console <DomId> Attach to domain DomId's console." -create_help = """create [-c] <ConfigFile> - [Name=Value].. Create a domain based on Config File""" -destroy_help = "destroy <DomId> Terminate a domain immediately" -dump_core_help = """dump-core [-L|--live][-C|--crash] - <DomId> [FileName] Dump core of the specified domain""" - -help_help = "help Display this message" -list_help = "list [--long] [DomId, ...] List information about domains" -list_label_help = "list [--label] [DomId, ...] List information about domains including their labels" - -mem_max_help = "mem-max <DomId> <Mem> Set maximum memory reservation for a domain" -mem_set_help = "mem-set <DomId> <Mem> Adjust the current memory usage for a domain" -migrate_help = "migrate <DomId> <Host> Migrate a domain to another machine" -pause_help = "pause <DomId> Pause execution of a domain" -reboot_help = "reboot <DomId> [-w][-a] Reboot a domain" -restore_help = "restore <File> Create a domain from a saved state file" -save_help = "save <DomId> <File> Save domain state (and config) to file" -shutdown_help ="shutdown <DomId> [-w][-a][-R|-H] Shutdown a domain" -top_help = "top Monitor system and domains in real-time" -unpause_help = "unpause <DomId> Unpause a paused domain" -uptime_help = "uptime [-s|--short] [DomId, ...] List uptime for domains" - -help_spacer = """ - """ - -# Strings for longhelp -sysrq_help = "sysrq <DomId> <letter> Send a sysrq to a domain" -domid_help = "domid <DomName> Converts a domain name to a domain id" -domname_help = "domname <DomId> Convert a domain id to a domain name" -vcpu_set_help = """vcpu-set <DomId> <VCPUs> Set the number of active VCPUs for a domain - within the range allowed by the domain - configuration""" -vcpu_list_help = "vcpu-list <DomId> List the VCPUs for a domain (or all domains)" -vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs> Set which cpus a VCPU can use" -dmesg_help = "dmesg [-c|--clear] Read or clear Xen's message buffer" -info_help = "info Get information about the xen host" -rename_help = "rename <DomId> <New Name> Rename a domain" -log_help = "log Print the xend log" -sched_sedf_help = "sched-sedf [DOM] [OPTIONS] Show|Set simple EDF parameters\n" + \ -" -p, --period Relative deadline(ms).\n\ - -s, --slice Worst-case execution time(ms)\n\ - (slice < period).\n\ - -l, --latency scaled period(ms) in case the domain\n\ - is doing heavy I/O.\n\ - -e, --extra flag (0/1) which controls whether the\n\ - domain can run in extra-time\n\ - -w, --weight mutually exclusive with period/slice and\n\ - specifies another way of setting a domain's\n\ - cpu period/slice." - -sched_credit_help = "sched-credit Set or get credit scheduler parameters" -block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode> - [BackDomId] Create a new virtual block device""" -block_detach_help = """block-detach <DomId> <DevId> Destroy a domain's virtual block device, - where <DevId> may either be the device ID - or the device name as mounted in the guest""" - -block_list_help = "block-list <DomId> [--long] List virtual block devices for a domain" -block_configure_help = """block-configure <DomId> <BackDev> <FrontDev> <Mode> - [BackDomId] Change block device configuration""" -network_attach_help = """network-attach <DomID> [script=<script>] [ip=<ip>] [mac=<mac>] - [bridge=<bridge>] [backend=<backDomID>] - Create a new virtual network device """ -network_detach_help = """network-detach <DomId> <DevId> Destroy a domain's virtual network - device, where <DevId> is the device ID.""" - -network_list_help = "network-list <DomId> [--long] List virtual network interfaces for a domain" -vnet_list_help = "vnet-list [-l|--long] list vnets" -vnet_create_help = "vnet-create <config> create a vnet from a config file" -vnet_delete_help = "vnet-delete <vnetid> delete a vnet" -vtpm_list_help = "vtpm-list <DomId> [--long] list virtual TPM devices" -addlabel_help = "addlabel <label> dom <configfile> Add security label to domain\n <label> res <resource> or resource" -rmlabel_help = "rmlabel dom <configfile> Remove security label from domain\n res <resource> or resource" -getlabel_help = "getlabel dom <configfile> Show security label for domain\n res <resource> or resource" -dry_run_help = "dry-run <configfile> Tests if domain can access its resources" -resources_help = "resources Show info for each labeled resource" -cfgbootpolicy_help = "cfgbootpolicy <policy> Add policy to boot configuration " -dumppolicy_help = "dumppolicy Print hypervisor ACM state information" -loadpolicy_help = "loadpolicy <policy> Load binary policy into hypervisor" -makepolicy_help = "makepolicy <policy> Build policy and create .bin/.map files" -labels_help = "labels [policy] [type=DOM|..] List <type> labels for (active) policy." -serve_help = "serve Proxy Xend XML-RPC over stdio" - -short_command_list = [ +# General help message + +USAGE_HELP = "Usage: xm <subcommand> [args]\n\n" \ + "Control, list, and manipulate Xen guest instances.\n" + +USAGE_FOOTER = '<Domain> can either be the Domain Name or Id.\n' \ + 'For more help on \'xm\' see the xm(1) man page.\n' \ + 'For more help on \'xm create\' see the xmdomain.cfg(5) '\ + ' man page.\n' + +# Help strings are indexed by subcommand name in this way: +# 'subcommand': (argstring, description) + +SUBCOMMAND_HELP = { + # common commands + + 'console' : ('<Domain>', + 'Attach to <Domain>\'s console.'), + 'create' : ('<ConfigFile> [options] [vars]', + 'Create a domain based on <ConfigFile>.'), + 'destroy' : ('<Domain>', + 'Terminate a domain immediately.'), + 'help' : ('', 'Display this message.'), + 'list' : ('[options] [Domain, ...]', + 'List information about all/some domains.'), + 'mem-max' : ('<Domain> <Mem>', + 'Set the maximum amount reservation for a domain.'), + 'mem-set' : ('<Domain> <Mem>', + 'Set the current memory usage for a domain.'), + 'migrate' : ('<Domain> <Host>', + 'Migrate a domain to another machine.'), + 'pause' : ('<Domain>', 'Pause execution of a domain.'), + 'reboot' : ('<Domain> [-wa]', 'Reboot a domain.'), + 'restore' : ('<CheckpointFile>', + 'Restore a domain from a saved state.'), + 'save' : ('<Domain> <CheckpointFile>', + 'Save a domain state to restore later.'), + 'shutdown' : ('<Domain> [-waRH]', 'Shutdown a domain.'), + 'top' : ('', 'Monitor a host and the domains in real time.'), + 'unpause' : ('<Domain>', 'Unpause a paused domain.'), + 'uptime' : ('[-s] <Domain>', 'Print uptime for a domain.'), + + # less used commands + + 'dmesg' : ('[-c|--clear]', + 'Read and/or clear Xend\'s message buffer.'), + 'domid' : ('<DomainName>', 'Convert a domain name to domain id.'), + 'domname' : ('<DomId>', 'Convert a domain id to domain name.'), + 'dump-core' : ('[-L|--live] [-C|--crash] <Domain> [Filename]', + 'Dump core for a specific domain.'), + 'info' : ('', 'Get information about Xen host.'), + 'log' : ('', 'Print Xend log'), + 'rename' : ('<Domain> <NewDomainName>', 'Rename a domain.'), + 'sched-sedf' : ('<Domain> [options]', 'Get/set EDF parameters.'), + 'sched-credit': ('-d <Domain> [-w[=WEIGHT]|-c[=CAP]]', + 'Get/set credit scheduler parameters.'), + 'sysrq' : ('<Domain> <letter>', 'Send a sysrq to a domain.'), + 'vcpu-list' : ('[<Domain>]', + 'List the VCPUs for a domain or all domains.'), + 'vcpu-pin' : ('<Domain> <VCPU> <CPUs>', + 'Set which CPUs a VCPU can use.'), + 'vcpu-set' : ('<Domain> <vCPUs>', + 'Set the number of active VCPUs for allowed for the' + ' domain.'), + + # device commands + + 'block-attach' : ('<Domain> <BackDev> <FrontDev> <Mode>', + 'Create a new virtual block device.'), + 'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomId]', + 'Change block device configuration'), + 'block-detach' : ('<Domain> <DevId>', + 'Destroy a domain\'s virtual block device.'), + 'block-list' : ('<Domain> [--long]', + 'List virtual block devices for a domain.'), + 'network-attach': ('<Domain> [--script=<script>] [--ip=<ip>] ' + '[--mac=<mac>]', + 'Create a new virtual network device.'), + 'network-detach': ('<Domain> <DevId>', + 'Destroy a domain\'s virtual network device.'), + 'network-list' : ('<Domain> [--long]', + 'List virtual network interfaces for a domain.'), + 'vnet-create' : ('<ConfigFile>','Create a vnet from ConfigFile.'), + 'vnet-delete' : ('<VnetId>', 'Delete a Vnet.'), + 'vnet-list' : ('[-l|--long]', 'List Vnets.'), + 'vtpm-list' : ('<Domain> [--long]', 'List virtual TPM devices.'), + + # security + + 'addlabel' : ('<label> {dom <ConfigFile>|res <resource>} [<policy>]', + 'Add security label to domain.'), + 'rmlabel' : ('{dom <ConfigFile>|res <Resource>}', + 'Remove a security label from domain.'), + 'getlabel' : ('{dom <ConfigFile>|res <Resource>}', + 'Show security label for domain or resource.'), + 'dry-run' : ('<ConfigFile>', + 'Test if a domain can access its resources.'), + 'resources' : ('', 'Show info for each labeled resource.'), + 'cfgbootpolicy' : ('<policy> [kernelversion]', + 'Add policy to boot configuration.'), + 'dumppolicy' : ('', 'Print hypervisor ACM state information.'), + 'loadpolicy' : ('<policy.bin>', 'Load binary policy into hypervisor.'), + 'makepolicy' : ('<policy>', 'Build policy and create .bin/.map ' + 'files.'), + 'labels' : ('[policy] [type=dom|res|any]', + 'List <type> labels for (active) policy.'), + 'serve' : ('', 'Proxy Xend XMLRPC over stdio.'), +} + +SUBCOMMAND_OPTIONS = { + 'sched-sedf': ( + ('-p [MS]', '--period[=MS]', 'Relative deadline(ms)'), + ('-s [MS]', '--slice[=MS]' , + 'Worst-case execution time(ms). (slice < period)'), + ('-l [MS]', '--latency[=MS]', + 'Scaled period (ms) when domain performs heavy I/O'), + ('-e [FLAG]', '--extra[=FLAG]', + 'Flag (0 or 1) controls if domain can run in extra time.'), + ('-w [FLOAT]', '--weight[=FLOAT]', + 'CPU Period/slice (do not set with --period/--slice)'), + ), + 'sched-credit': ( + ('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'), + ('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'), + ('-c CAP', '--cap=CAP', 'Cap (int)'), + ), + 'list': ( + ('-l', '--long', 'Output all VM details in SXP'), + ('', '--label', 'Include security labels'), + ), + 'dmesg': ( + ('-c', '--clear', 'Clear dmesg buffer'), + ), + 'vnet-list': ( + ('-l', '--long', 'List Vnets as SXP'), + ), + 'network-list': ( + ('-l', '--long', 'List resources as SXP'), + ), +} + +common_commands = [ "console", "create", "destroy", @@ -165,7 +219,6 @@ domain_commands = [ "domname", "dump-core", "list", - "list_label", "mem-max", "mem-set", "migrate", @@ -223,67 +276,105 @@ acm_commands = [ "makepolicy", "loadpolicy", "cfgbootpolicy", - "dumppolicy" + "dumppolicy", ] all_commands = (domain_commands + host_commands + scheduler_commands + device_commands + vnet_commands + acm_commands) - -def commandToHelp(cmd): - return eval(cmd.replace("-", "_") + "_help") - - -shorthelp = """Usage: xm <subcommand> [args] - Control, list, and manipulate Xen guest instances - -xm common subcommands: - """ + help_spacer.join(map(commandToHelp, short_command_list)) + """ - -<DomName> can be substituted for <DomId> in xm subcommands. - -For a complete list of subcommands run 'xm help --long' -For more help on xm see the xm(1) man page -For more help on xm create, see the xmdomain.cfg(5) man page""" - -longhelp = """Usage: xm <subcommand> [args] - Control, list, and manipulate Xen guest instances - -xm full list of subcommands: - - Domain Commands: - """ + help_spacer.join(map(commandToHelp, domain_commands)) + """ - - Xen Host Commands: - """ + help_spacer.join(map(commandToHelp, host_commands)) + """ - - Scheduler Commands: - """ + help_spacer.join(map(commandToHelp, scheduler_commands)) + """ - - Virtual Device Commands: - """ + help_spacer.join(map(commandToHelp, device_commands)) + """ - - Vnet commands: - """ + help_spacer.join(map(commandToHelp, vnet_commands)) + """ - - Access Control commands: - """ + help_spacer.join(map(commandToHelp, acm_commands)) + """ - -<DomName> can be substituted for <DomId> in xm subcommands. - -For a short list of subcommands run 'xm help' -For more help on xm see the xm(1) man page -For more help on xm create, see the xmdomain.cfg(5) man page""" - -# array for xm help <command> -help = { - "--long": longhelp - } - -for command in all_commands: - # create is handled specially - if (command != 'create'): - help[command] = commandToHelp(command) +#################################################################### +# +# Help/usage printing functions +# +#################################################################### + +def cmdHelp(cmd): + """Print help for a specific subcommand.""" + + try: + args, desc = SUBCOMMAND_HELP[cmd] + except KeyError: + shortHelp() + return + + print 'Usage: xm %s %s' % (cmd, args) + print + print desc + + try: + # If options help message is defined, print this. + for shortopt, longopt, desc in SUBCOMMAND_OPTIONS[cmd]: + if shortopt and longopt: + optdesc = '%s, %s' % (shortopt, longopt) + elif shortopt: + optdesc = shortopt + elif longopt: + optdesc = longopt + + wrapped_desc = wrap(desc, 43) + print ' %-30s %-43s' % (optdesc, wrapped_desc[0]) + for line in wrapped_desc[1:]: + print ' ' * 33 + line + print + except KeyError: + # if the command is an external module, we grab usage help + # from the module itself. + if cmd in IMPORTED_COMMANDS: + try: + cmd_module = __import__(cmd, globals(), locals(), 'xen.xm') + cmd_usage = getattr(cmd_module, "help", None) + if cmd_usage: + print cmd_usage() + except ImportError: + pass + +def shortHelp(): + """Print out generic help when xm is called without subcommand.""" + + print USAGE_HELP + print 'Common \'xm\' commands:\n' + + for command in common_commands: + try: + args, desc = SUBCOMMAND_HELP[command] + except KeyError: + continue + wrapped_desc = wrap(desc, 50) + print ' %-20s %-50s' % (command, wrapped_desc[0]) + for line in wrapped_desc[1:]: + print ' ' * 22 + line + + print + print USAGE_FOOTER + print 'For a complete list of subcommands run \'xm help\'.' + +def longHelp(): + """Print out full help when xm is called with xm --help or xm help""" + + print USAGE_HELP + print 'xm full list of subcommands:\n' + + for command in all_commands: + try: + args, desc = SUBCOMMAND_HELP[command] + except KeyError: + continue + + wrapped_desc = wrap(desc, 50) + print ' %-20s %-50s' % (command, wrapped_desc[0]) + for line in wrapped_desc[1:]: + print ' ' * 22 + line + + print + print USAGE_FOOTER + +def usage(cmd = None): + """ Print help usage information and exits """ + if cmd: + cmdHelp(cmd) + else: + shortHelp() + sys.exit(1) #################################################################### @@ -298,7 +389,7 @@ def arg_check(args, name, lo, hi = -1): if hi == -1: if n != lo: err("'xm %s' requires %d argument%s.\n" % (name, lo, - lo > 1 and 's' or '')) + lo == 1 and '' or 's')) usage(name) else: if n < lo or n > hi: @@ -345,14 +436,19 @@ def xm_save(args): def xm_save(args): arg_check(args, "save", 2) - dom = args[0] # TODO: should check if this exists + try: + dominfo = parse_doms_info(server.xend.domain(args[0])) + except xmlrpclib.Fault, ex: + raise ex + + domid = dominfo['domid'] savefile = os.path.abspath(args[1]) if not os.access(os.path.dirname(savefile), os.W_OK): err("xm save: Unable to create file %s" % savefile) sys.exit(1) - server.xend.domain.save(dom, savefile) + server.xend.domain.save(domid, savefile) def xm_restore(args): arg_check(args, "restore", 1) @@ -366,9 +462,9 @@ def xm_restore(args): server.xend.domain.restore(savefile) -def getDomains(domain_names): +def getDomains(domain_names, full = 0): if domain_names: - return map(server.xend.domain, domain_names) + return [server.xend.domain(dom) for dom in domain_names] else: return server.xend.domains(1) @@ -378,9 +474,11 @@ def xm_list(args): show_vcpus = 0 show_labels = 0 try: - (options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus','label']) + (options, params) = getopt.gnu_getopt(args, 'lv', + ['long','vcpus','label']) except getopt.GetoptError, opterr: err(opterr) + usage('list') sys.exit(1) for (k, v) in options: @@ -397,7 +495,7 @@ def xm_list(args): xm_vcpu_list(params) return - doms = getDomains(params) + doms = getDomains(params, use_long) if use_long: map(PrettyPrint.prettyprint, doms) @@ -412,7 +510,7 @@ def parse_doms_info(info): return t(sxp.child_value(info, n, d)) return { - 'dom' : get_info('domid', int, -1), + 'domid' : get_info('domid', int, -1), 'name' : get_info('name', str, '??'), 'mem' : get_info('memory', int, 0), 'vcpus' : get_info('online_vcpus', int, 0), @@ -428,7 +526,7 @@ def parse_sedf_info(info): return t(sxp.child_value(info, n, d)) return { - 'dom' : get_info('domain', int, -1), + 'domid' : get_info('domid', int, -1), 'period' : get_info('period', int, -1), 'slice' : get_info('slice', int, -1), 'latency' : get_info('latency', int, -1), @@ -436,34 +534,40 @@ def parse_sedf_info(info): 'weight' : get_info('weight', int, -1), } - def xm_brief_list(doms): - print 'Name ID Mem(MiB) VCPUs State Time(s)' + print '%-40s %3s %8s %5s %5s %9s' % \ + ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)') + + format = "%(name)-40s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s " \ + "%(cpu_time)8.1f" + for dom in doms: d = parse_doms_info(dom) - print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f" % d) - + print format % d def xm_label_list(doms): + print '%-32s %3s %8s %5s %5s %9s %-8s' % \ + ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)', 'Label') + output = [] - print 'Name ID Mem(MiB) VCPUs State Time(s) Label' + format = '%(name)-32s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s ' \ + '%(cpu_time)8.1f %(seclabel)9s' + for dom in doms: d = parse_doms_info(dom) - l = "%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f " % d if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']: - if d['seclabel']: - line = (l, d['seclabel']) - else: - line = (l, "ERROR") + if not d['seclabel']: + d['seclabel'] = 'ERROR' elif security.active_policy in ['DEFAULT']: - line = (l, "DEFAULT") + d['seclabel'] = 'DEFAULT' else: - line = (l, "INACTIVE") - output.append(line) + d['seclabel'] = 'INACTIVE' + output.append((format % d, d['seclabel'])) + #sort by labels output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower())) - for l in output: - print l[0] + l[1] + for line, label in output: + print line def xm_vcpu_list(args): @@ -474,7 +578,11 @@ def xm_vcpu_list(args): doms = server.xend.domains(False) dominfo = map(server.xend.domain.getVCPUInfo, doms) - print 'Name ID VCPU CPU State Time(s) CPU Affinity' + print '%-32s %3s %5s %5s %5s %9s %s' % \ + ('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity') + + format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \ + ' %(cpu_time)8.1f %(cpumap)s' for dom in dominfo: def get_info(n): @@ -568,10 +676,7 @@ def xm_vcpu_list(args): c = "-" s = "--p" - print ( - "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f %(cpumap)s" % - locals()) - + print format % locals() def xm_reboot(args): arg_check(args, "reboot", 1, 3) @@ -634,30 +739,30 @@ def xm_dump_core(args): def xm_rename(args): arg_check(args, "rename", 2) - + server.xend.domain.setName(args[0], args[1]) -def xm_subcommand(command, args): +def xm_importcommand(command, args): cmd = __import__(command, globals(), locals(), 'xen.xm') cmd.main([command] + args) ############################################################# -def cpu_make_map(cpulist): - cpus = [] - for c in cpulist.split(','): - if c.find('-') != -1: - (x,y) = c.split('-') - for i in range(int(x),int(y)+1): - cpus.append(int(i)) - else: - cpus.append(int(c)) - cpus.sort() - return cpus - def xm_vcpu_pin(args): arg_check(args, "vcpu-pin", 3) + + def cpu_make_map(cpulist): + cpus = [] + for c in cpulist.split(','): + if c.find('-') != -1: + (x,y) = c.split('-') + for i in range(int(x),int(y)+1): + cpus.append(int(i)) + else: + cpus.append(int(c)) + cpus.sort() + return cpus dom = args[0] vcpu = int(args[1]) @@ -719,11 +824,12 @@ def xm_sched_sedf(args): info['period'] = ns_to_ms(info['period']) info['slice'] = ns_to_ms(info['slice']) info['latency'] = ns_to_ms(info['latency']) - print( ("%(name)-32s %(dom)3d %(period)9.1f %(slice)9.1f" + + print( ("%(name)-32s %(domid)3d %(period)9.1f %(slice)9.1f" + " %(latency)7.1f %(extratime)6d %(weight)6d") % info) def domid_match(domid, info): - return domid is None or domid == info['name'] or domid == str(info['dom']) + return domid is None or domid == info['name'] or \ + domid == str(info['domid']) # we want to just display current info if no parameters are passed if len(args) == 0: @@ -757,20 +863,25 @@ def xm_sched_sedf(args): elif k in ['-w', '--weight']: opts['weight'] = v + doms = filter(lambda x : domid_match(domid, x), + [parse_doms_info(dom) for dom in getDomains("")]) + # print header if we aren't setting any parameters if len(opts.keys()) == 0: - print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s'%('Name','ID','Period(ms)', - 'Slice(ms)', 'Lat(ms)', - 'Extra','Weight') - - doms = filter(lambda x : domid_match(domid, x), - [parse_doms_info(dom) for dom in getDomains("")]) + print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s' % \ + ('Name','ID','Period(ms)', 'Slice(ms)', 'Lat(ms)', + 'Extra','Weight') + for d in doms: # fetch current values so as not to clobber them - sedf_info = \ - parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom'])) + try: + sedf_raw = server.xend.domain.cpu_sedf_get(d['domid']) + except xmlrpclib.Fault: + # domain does not support sched-sedf? + sedf_raw = {} + + sedf_info = parse_sedf_info(sedf_raw) sedf_info['name'] = d['name'] - # update values in case of call to set if len(opts.keys()) > 0: for k in opts.keys(): @@ -780,7 +891,7 @@ def xm_sched_sedf(args): v = map(int, [sedf_info['period'], sedf_info['slice'], sedf_info['latency'],sedf_info['extratime'], sedf_info['weight']]) - rv = server.xend.domain.cpu_sedf_set(d['dom'], *v) + rv = server.xend.domain.cpu_sedf_set(d['domid'], *v) if int(rv) != 0: err("Failed to set sedf parameters (rv=%d)."%(rv)) @@ -789,17 +900,14 @@ def xm_sched_sedf(args): print_sedf(sedf_info) def xm_sched_credit(args): - usage_msg = """sched-credit: Set or get credit scheduler parameters - Usage: - - sched-credit -d domain [-w weight] [-c cap] - """ + """Get/Set options for Credit Scheduler.""" + try: - opts, args = getopt.getopt(args[0:], "d:w:c:", + opts, params = getopt.getopt(args, "d:w:c:", ["domain=", "weight=", "cap="]) - except getopt.GetoptError: - # print help information and exit: - print usage_msg + except getopt.GetoptError, opterr: + err(opterr) + usage('sched-credit') sys.exit(1) domain = None @@ -816,15 +924,16 @@ def xm_sched_credit(args): if domain is None: # place holder for system-wide scheduler parameters - print usage_msg + err("No domain given.") + usage('sched-credit') sys.exit(1) if weight is None and cap is None: print server.xend.domain.sched_credit_get(domain) else: - err = server.xend.domain.sched_credit_set(domain, weight, cap) - if err != 0: - print err + result = server.xend.domain.sched_credit_set(domain, weight, cap) + if result != 0: + err(str(result)) def xm_info(args): arg_check(args, "info", 0) @@ -843,6 +952,8 @@ def xm_console(args): dom = args[0] info = server.xend.domain(dom) domid = int(sxp.child_value(info, 'domid', '-1')) + if domid == -1: + raise Exception("Domain is not started") console.execConsole(domid) def xm_uptime(args): @@ -920,8 +1031,11 @@ its contents if the [-c|--clear] flag is myargs = args myargs.insert(0, 'dmesg') gopts.parse(myargs) - if not (1 <= len(myargs) <= 2): + + if len(myargs) not in (1, 2): err('Invalid arguments: ' + str(myargs)) + usage('dmesg') + sys.exit(1) if not gopts.vals.clear: print server.xend.node.dmesg.info() @@ -939,7 +1053,7 @@ def xm_serve(args): from fcntl import fcntl, F_SETFL s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(xen.xend.XendClient.XML_RPC_SOCKET) + s.connect(XendClient.XML_RPC_SOCKET) fcntl(sys.stdin, F_SETFL, os.O_NONBLOCK) while True: @@ -1085,7 +1199,7 @@ def parse_block_configuration(args): cls = 'tap' else: cls = 'vbd' - + vbd = [cls, ['uname', args[1]], ['dev', args[2]], @@ -1094,19 +1208,12 @@ def parse_block_configuration(args): vbd.append(['backend', args[4]]) # verify that policy permits attaching this resource - try: - if security.on(): - dominfo = server.xend.domain(dom) - label = security.get_security_printlabel(dominfo) - else: - label = None + if security.on(): + dominfo = server.xend.domain(dom) + label = security.get_security_printlabel(dominfo) + else: + label = None security.res_security_check(args[1], label) - except security.ACMError, e: - print e.value - sys.exit(1) - except: - traceback.print_exc(limit=1) - sys.exit(1) return (dom, vbd) @@ -1206,10 +1313,10 @@ commands = { "domid": xm_domid, "domname": xm_domname, "dump-core": xm_dump_core, + "reboot": xm_reboot, "rename": xm_rename, "restore": xm_restore, "save": xm_save, - "reboot": xm_reboot, "shutdown": xm_shutdown, "uptime": xm_uptime, "list": xm_list, @@ -1249,24 +1356,24 @@ commands = { } ## The commands supported by a separate argument parser in xend.xm. -subcommands = [ +IMPORTED_COMMANDS = [ 'create', 'migrate', 'sysrq', 'labels', 'addlabel', + 'cfgbootpolicy', + 'makepolicy', + 'loadpolicy', + 'dumppolicy' 'rmlabel', 'getlabel', 'dry-run', 'resources', - 'cfgbootpolicy', - 'makepolicy', - 'loadpolicy', - 'dumppolicy' ] -for c in subcommands: - commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c) +for c in IMPORTED_COMMANDS: + commands[c] = eval('lambda args: xm_importcommand("%s", args)' % c) aliases = { "balloon": "mem-set", @@ -1284,11 +1391,18 @@ def xm_lookup_cmd(cmd): elif aliases.has_key(cmd): deprecated(cmd,aliases[cmd]) return commands[aliases[cmd]] - else: - if len( cmd ) > 1: - matched_commands = filter( lambda (command, func): command[ 0:len(cmd) ] == cmd, commands.iteritems() ) - if len( matched_commands ) == 1: - return matched_commands[0][1] + elif cmd == 'help': + longHelp() + sys.exit(0) + else: + # simulate getopt's prefix matching behaviour + if len(cmd) > 1: + same_prefix_cmds = [commands[c] for c in commands.keys() \ + if c[:len(cmd)] == cmd] + # only execute if there is only 1 match + if len(same_prefix_cmds) == 1: + return same_prefix_cmds[0] + err('Sub Command %s not found!' % cmd) usage() @@ -1296,27 +1410,17 @@ def deprecated(old,new): print >>sys.stderr, ( "Command %s is deprecated. Please use xm %s instead." % (old, new)) -def usage(cmd=None): - if cmd == 'create': - mycmd = xm_lookup_cmd(cmd) - mycmd( ['--help'] ) - sys.exit(1) - if help.has_key(cmd): - print " " + help[cmd] - else: - print shorthelp - sys.exit(1) - def main(argv=sys.argv): if len(argv) < 2: usage() - - if re.compile('-*help').match(argv[1]): - if len(argv) > 2: - usage(argv[2]) - else: - usage() - sys.exit(0) + + # intercept --help and output our own help + if '--help' in argv[1:]: + if '--help' == argv[1]: + longHelp() + else: + usage(argv[1]) + sys.exit(0) cmd = xm_lookup_cmd(argv[1]) @@ -1329,9 +1433,9 @@ def main(argv=sys.argv): usage() except socket.error, ex: if os.geteuid() != 0: - err("Most commands need root access. Please try again as root.") + err("Most commands need root access. Please try again as root.") else: - err("Error connecting to xend: %s. Is xend running?" % ex[1]) + err("Unable to connect to xend: %s. Is xend running?" % ex[1]) sys.exit(1) except KeyboardInterrupt: print "Interrupted." @@ -1340,16 +1444,16 @@ def main(argv=sys.argv): if os.geteuid() != 0: err("Most commands need root access. Please try again as root.") else: - err("Error connecting to xend: %s." % ex[1]) + err("Unable to connect to xend: %s." % ex[1]) sys.exit(1) except SystemExit: sys.exit(1) except xmlrpclib.Fault, ex: - if ex.faultCode == xen.xend.XendClient.ERROR_INVALID_DOMAIN: - print >>sys.stderr, ( - "Error: the domain '%s' does not exist." % ex.faultString) + if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN: + err("Domain '%s' does not exist." % ex.faultString) else: - print >>sys.stderr, "Error: %s" % ex.faultString + err(ex.faultString) + usage(argv[1]) sys.exit(1) except xmlrpclib.ProtocolError, ex: if ex.errcode == -1: @@ -1364,6 +1468,10 @@ def main(argv=sys.argv): except (ValueError, OverflowError): err("Invalid argument.") usage(argv[1]) + except OptionError, e: + err(str(e)) + usage(argv[1]) + print e.usage() except: print "Unexpected error:", sys.exc_info()[0] print diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/makepolicy.py --- a/tools/python/xen/xm/makepolicy.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/makepolicy.py Fri Sep 22 13:06:20 2006 +0100 @@ -20,7 +20,7 @@ import sys import sys import traceback from xen.util.security import ACMError, err, make_policy - +from xen.xm.opts import OptionError def usage(): print "\nUsage: xm makepolicy <policy>\n" @@ -29,13 +29,12 @@ def usage(): err("Usage") +def main(argv): + if len(argv) != 2: + raise OptionError('No XML policy file specified') -def main(argv): try: - if len(argv) != 2: - usage() make_policy(argv[1]) - except ACMError: sys.exit(-1) except: @@ -43,7 +42,6 @@ def main(argv): sys.exit(-1) - if __name__ == '__main__': main(sys.argv) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/migrate.py --- a/tools/python/xen/xm/migrate.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/migrate.py Fri Sep 22 13:06:20 2006 +0100 @@ -46,19 +46,17 @@ gopts.opt('resource', short='r', val='MB fn=set_int, default=0, use="Set level of resource usage for migration.") -def help(argv): - gopts.argv = argv - gopts.usage() +def help(): + return str(gopts) def main(argv): opts = gopts args = opts.parse(argv) - if opts.vals.help: - opts.usage() - return + if len(args) != 2: - opts.usage() - sys.exit(1) + raise OptionError('Invalid number of arguments') + dom = args[0] dst = args[1] - server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, opts.vals.port) + server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, + opts.vals.port) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/opts.py --- a/tools/python/xen/xm/opts.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/opts.py Fri Sep 22 13:06:20 2006 +0100 @@ -23,6 +23,46 @@ import os.path import os.path import sys import types + +def wrap(text, width = 70): + """ Really basic textwrap. Useful because textwrap is not available + for Python 2.2, and textwrap.wrap ignores newlines in Python 2.3+. + """ + import string + + if len(text) < width: + return [text] + + lines = [] + for line in text.split('\n'): + line = line.strip() + if len(line) < width: + lines.append(line) + continue + + pos = 0 + while pos <= len(line): + wline = line[pos:pos+width].strip() + if len(wline) < 2: + break + + if wline[-1] in tuple(string.punctuation): + pos += width + else: + lastword = wline.split()[-1] + wline = wline[:-len(lastword)] + pos += width - len(lastword) + lines.append(wline) + + return lines + +class OptionError(Exception): + """Denotes an error in option parsing.""" + def __init__(self, message, usage = ''): + self.message = message + self.usage = usage + def __str__(self): + return self.message class Opt: """An individual option. @@ -72,7 +112,21 @@ class Opt: def __repr__(self): return self.name + '=' + str(self.specified_val) - __str__ = __repr__ + def __str__(self): + """ Formats the option into: + '-k, --key description' + """ + PARAM_WIDTH = 20 + if self.val: + keys = ', '.join(['%s=%s' % (k, self.val) for k in self.optkeys]) + else: + keys = ', '.join(self.optkeys) + desc = wrap(self.use, 55) + if len(keys) > PARAM_WIDTH: + desc = [''] + desc + + wrapped = ('\n' + ' ' * (PARAM_WIDTH + 1)).join(desc) + return keys.ljust(PARAM_WIDTH + 1) + wrapped def set(self, value): """Set the option value. @@ -243,7 +297,19 @@ class Opts: def __repr__(self): return '\n'.join(map(str, self.options)) - __str__ = __repr__ + def __str__(self): + options = [s for s in self.options if s.optkeys[0][0] == '-'] + optvals = [s for s in self.options if s.optkeys[0][0] != '-'] + output = '' + if options: + output += '\nOptions:\n\n' + output += '\n'.join([str(o) for o in options]) + output += '\n' + if optvals: + output += '\nValues:\n\n' + output += '\n'.join([str(o) for o in optvals]) + output += '\n' + return output def opt(self, name, **args): """Add an option. @@ -338,14 +404,14 @@ class Opts: self.short_opts(), self.long_opts()) except getopt.GetoptError, err: - self.err(str(err)) + raise OptionError(str(err), self.use) + #self.err(str(err)) for (k, v) in xvals: for opt in self.options: if opt.specify(k, v): break else: - print >>sys.stderr, "Error: Unknown option:", k - self.usage() + raise OptionError('Unknown option: %s' % k, self.use) if not args: break @@ -390,10 +456,10 @@ class Opts: def usage(self): print 'Usage: ', self.argv[0], self.use or 'OPTIONS' print - for opt in self.options: - opt.show() - print if self.options: + for opt in self.options: + opt.show() + print print def var_usage(self): @@ -427,7 +493,9 @@ class Opts: self.load(p, help) break else: - self.err('Cannot open config file "%s"' % self.vals.defconfig) + raise OptionError('Unable to open config file: %s' % \ + self.vals.defconfig, + self.use) def load(self, defconfig, help): """Load a defconfig file. Local variables in the file @@ -478,9 +546,9 @@ def set_bool(opt, k, v): def set_bool(opt, k, v): """Set a boolean option. """ - if v in ['yes']: + if v in ('yes', 'y'): opt.set(1) - elif v in ['no']: + elif v in ('no', 'n'): opt.set(0) else: opt.opts.err('Invalid value:' +v) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/resources.py --- a/tools/python/xen/xm/resources.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/resources.py Fri Sep 22 13:06:20 2006 +0100 @@ -21,13 +21,12 @@ import sys import sys from xen.util import dictio from xen.util import security +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm resource\n" - print " This program lists information for each resource in the" - print " global resource label file\n" - security.err("Usage") - +def help(): + return """Usage: xm resource + This program lists information for each resource in the + global resource label file.""" def print_resource_data(access_control): """Prints out a resource dictionary to stdout @@ -38,11 +37,16 @@ def print_resource_data(access_control): print " policy: "+policy print " label: "+label - def main (argv): + if len(argv) > 1: + raise OptionError("No arguments required") + try: - if len(argv) != 1: - usage() + filename = security.res_label_filename + access_control = dictio.dict_read("resources", filename) + except: + print "Resource file not found." + return try: file = security.res_label_filename @@ -52,9 +56,6 @@ def main (argv): print_resource_data(access_control) - except security.ACMError: - sys.exit(-1) - if __name__ == '__main__': main(sys.argv) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/rmlabel.py --- a/tools/python/xen/xm/rmlabel.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/rmlabel.py Fri Sep 22 13:06:20 2006 +0100 @@ -21,15 +21,17 @@ import sys, os, re import sys, os, re from xen.util import dictio from xen.util import security +from xen.xm.opts import OptionError -def usage(): - print "\nUsage: xm rmlabel dom <configfile>" - print " xm rmlabel res <resource>\n" - print " This program removes an acm_label entry from the 'configfile'" - print " for a domain or from the global resource label file for a" - print " resource. If the label does not exist for the given domain or" - print " resource, then rmlabel fails.\n" - security.err("Usage") +def help(): + return """ + Example: xm rmlabel dom <configfile> + xm rmlabel res <resource> + + This program removes an acm_label entry from the 'configfile' + for a domain or from the global resource label file for a + resource. If the label does not exist for the given domain or + resource, then rmlabel fails.""" def rm_resource_label(resource): @@ -93,22 +95,22 @@ def rm_domain_label(configfile): def main (argv): + + if len(argv) != 3: + raise OptionError('Requires 2 arguments') + + if argv[1].lower() not in ('dom', 'res'): + raise OptionError('Unrecognised type argument: %s' % argv[1]) + try: - if len(argv) != 3: - usage() - if argv[1].lower() == "dom": configfile = argv[2] rm_domain_label(configfile) elif argv[1].lower() == "res": resource = argv[2] rm_resource_label(resource) - else: - usage() - except security.ACMError: sys.exit(-1) - if __name__ == '__main__': main(sys.argv) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e tools/python/xen/xm/sysrq.py --- a/tools/python/xen/xm/sysrq.py Fri Sep 22 13:06:05 2006 +0100 +++ b/tools/python/xen/xm/sysrq.py Fri Sep 22 13:06:20 2006 +0100 @@ -19,14 +19,12 @@ def main(argv): def main(argv): opts = gopts args = opts.parse(argv) - if opts.vals.help: - opts.usage() - return - - # no options for the moment - if len(args) != 2: - opts.usage() - sys.exit(1) + + if len(args) < 1: + raise OptionError('Missing domain argument') + if len(args) < 2: + raise OptionError('Missing sysrq character') + dom = args[0] req = ord(args[1][0]) server.xend.domain.send_sysrq(dom, req) diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Fri Sep 22 13:06:05 2006 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Fri Sep 22 13:06:20 2006 +0100 @@ -259,6 +259,17 @@ static int svm_paging_enabled(struct vcp return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG); } +static int svm_pae_enabled(struct vcpu *v) +{ + unsigned long cr4; + + if(!svm_paging_enabled(v)) + return 0; + + cr4 = v->arch.hvm_svm.cpu_shadow_cr4; + + return (cr4 & X86_CR4_PAE); +} #define IS_CANO_ADDRESS(add) 1 @@ -865,6 +876,7 @@ int start_svm(void) hvm_funcs.realmode = svm_realmode; hvm_funcs.paging_enabled = svm_paging_enabled; hvm_funcs.long_mode_enabled = svm_long_mode_enabled; + hvm_funcs.pae_enabled = svm_pae_enabled; hvm_funcs.guest_x86_mode = svm_guest_x86_mode; hvm_funcs.instruction_length = svm_instruction_length; hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg; diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Sep 22 13:06:05 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Sep 22 13:06:20 2006 +0100 @@ -746,6 +746,7 @@ static void vmx_setup_hvm_funcs(void) hvm_funcs.realmode = vmx_realmode; hvm_funcs.paging_enabled = vmx_paging_enabled; hvm_funcs.long_mode_enabled = vmx_long_mode_enabled; + hvm_funcs.pae_enabled = vmx_pae_enabled; hvm_funcs.guest_x86_mode = vmx_guest_x86_mode; hvm_funcs.instruction_length = vmx_instruction_length; hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg; diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e xen/arch/x86/mm/shadow/common.c --- a/xen/arch/x86/mm/shadow/common.c Fri Sep 22 13:06:05 2006 +0100 +++ b/xen/arch/x86/mm/shadow/common.c Fri Sep 22 13:06:20 2006 +0100 @@ -2343,7 +2343,7 @@ void sh_update_paging_modes(struct vcpu } else #endif - if ( hvm_get_guest_ctrl_reg(v, 4) & X86_CR4_PAE ) + if ( hvm_pae_enabled(v) ) { #if CONFIG_PAGING_LEVELS >= 3 // 32-bit PAE mode guest... diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Fri Sep 22 13:06:05 2006 +0100 +++ b/xen/include/asm-x86/hvm/hvm.h Fri Sep 22 13:06:20 2006 +0100 @@ -57,6 +57,7 @@ struct hvm_function_table { int (*realmode)(struct vcpu *v); int (*paging_enabled)(struct vcpu *v); int (*long_mode_enabled)(struct vcpu *v); + int (*pae_enabled)(struct vcpu *v); int (*guest_x86_mode)(struct vcpu *v); int (*instruction_length)(struct vcpu *v); unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num); @@ -146,6 +147,12 @@ hvm_long_mode_enabled(struct vcpu *v) return hvm_funcs.long_mode_enabled(v); } + static inline int +hvm_pae_enabled(struct vcpu *v) +{ + return hvm_funcs.pae_enabled(v); +} + static inline int hvm_guest_x86_mode(struct vcpu *v) { diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Sep 22 13:06:05 2006 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Sep 22 13:06:20 2006 +0100 @@ -38,6 +38,9 @@ enum { #define VMX_LONG_GUEST(ed) \ (test_bit(VMX_CPU_STATE_LMA_ENABLED, &ed->arch.hvm_vmx.cpu_state)) + +#define VMX_PAE_GUEST(ed) \ + (test_bit(VMX_CPU_STATE_PAE_ENABLED, &ed->arch.hvm_vmx.cpu_state)) struct vmcs_struct { u32 vmcs_revision_id; diff -r 4a3d9fa6ba24 -r 1ca87f35ee4e xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Fri Sep 22 13:06:05 2006 +0100 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Fri Sep 22 13:06:20 2006 +0100 @@ -418,6 +418,12 @@ static inline int vmx_long_mode_enabled( return VMX_LONG_GUEST(current); } +static inline int vmx_pae_enabled(struct vcpu *v) +{ + ASSERT(v == current); + return VMX_PAE_GUEST(current); +} + /* Works only for vcpu == current */ static inline int vmx_realmode(struct vcpu *v) { _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |