ia64/xen-unstable

changeset 11581:1ca87f35ee4e

merge
author kfraser@localhost.localdomain
date Fri Sep 22 13:06:20 2006 +0100 (2006-09-22)
parents 4a3d9fa6ba24 0e9055d69f12
children a2549eb49482
files
line diff
     1.1 --- a/tools/firmware/vmxassist/machine.h	Fri Sep 22 13:06:05 2006 +0100
     1.2 +++ b/tools/firmware/vmxassist/machine.h	Fri Sep 22 13:06:20 2006 +0100
     1.3 @@ -36,6 +36,7 @@
     1.4  #define CR4_VME		(1 << 0)
     1.5  #define CR4_PVI		(1 << 1)
     1.6  #define CR4_PSE		(1 << 4)
     1.7 +#define CR4_PAE		(1 << 5)
     1.8  
     1.9  #define EFLAGS_ZF	(1 << 6)
    1.10  #define EFLAGS_TF	(1 << 8)
     2.1 --- a/tools/firmware/vmxassist/vm86.c	Fri Sep 22 13:06:05 2006 +0100
     2.2 +++ b/tools/firmware/vmxassist/vm86.c	Fri Sep 22 13:06:20 2006 +0100
     2.3 @@ -52,29 +52,74 @@ char *states[] = {
     2.4  static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
     2.5  #endif /* DEBUG */
     2.6  
     2.7 +#define PDE_PS           (1 << 7)
     2.8  #define PT_ENTRY_PRESENT 0x1
     2.9  
    2.10 +/* We only support access to <=4G physical memory due to 1:1 mapping */
    2.11  static unsigned
    2.12 -guest_linear_to_real(unsigned long base, unsigned off)
    2.13 +guest_linear_to_real(uint32_t base)
    2.14  {
    2.15 -	unsigned int gcr3 = oldctx.cr3;
    2.16 -	unsigned int l1_mfn;
    2.17 -	unsigned int l0_mfn;
    2.18 +	uint32_t gcr3 = oldctx.cr3;
    2.19 +	uint64_t l2_mfn;
    2.20 +	uint64_t l1_mfn;
    2.21 +	uint64_t l0_mfn;
    2.22  
    2.23  	if (!(oldctx.cr0 & CR0_PG))
    2.24 -		return base + off;
    2.25 +		return base;
    2.26  
    2.27 -	l1_mfn = ((unsigned int *)gcr3)[(base >> 22) & 0x3ff ];
    2.28 -	if (!(l1_mfn & PT_ENTRY_PRESENT))
    2.29 -		panic("l2 entry not present\n");
    2.30 -	l1_mfn = l1_mfn & 0xfffff000 ;
    2.31 +	if (!(oldctx.cr4 & CR4_PAE)) {
    2.32 +		l1_mfn = ((uint32_t *)gcr3)[(base >> 22) & 0x3ff];
    2.33  
    2.34 -	l0_mfn = ((unsigned int *)l1_mfn)[(base >> 12) & 0x3ff];
    2.35 -	if (!(l0_mfn & PT_ENTRY_PRESENT))
    2.36 -		panic("l1 entry not present\n");
    2.37 -	l0_mfn = l0_mfn & 0xfffff000;
    2.38 +		if (oldctx.cr4 & CR4_PSE || l1_mfn & PDE_PS) {
    2.39 +                        /* 1 level page table */
    2.40 +			l0_mfn = l1_mfn;
    2.41 +			if (!(l0_mfn & PT_ENTRY_PRESENT))
    2.42 +				panic("l1 entry not present\n");
    2.43  
    2.44 -	return l0_mfn + off + (base & 0xfff);
    2.45 +			l0_mfn &= 0xffc00000;
    2.46 +			return l0_mfn + (base & 0x3fffff);
    2.47 +		}
    2.48 +
    2.49 +		if (!(l1_mfn & PT_ENTRY_PRESENT))
    2.50 +			panic("l2 entry not present\n");
    2.51 +
    2.52 +		l1_mfn &= 0xfffff000;
    2.53 +		l0_mfn = ((uint32_t *)l1_mfn)[(base >> 12) & 0x3ff];
    2.54 +		if (!(l0_mfn & PT_ENTRY_PRESENT))
    2.55 +			panic("l1 entry not present\n");
    2.56 +		l0_mfn &= 0xfffff000;
    2.57 +
    2.58 +		return l0_mfn + (base & 0xfff);
    2.59 +	} else if (oldctx.cr4 & CR4_PAE && !(oldctx.cr4 & CR4_PSE)) {
    2.60 +		l2_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3];
    2.61 +		if (!(l2_mfn & PT_ENTRY_PRESENT))
    2.62 +			panic("l3 entry not present\n");
    2.63 +		l2_mfn &= 0x3fffff000ULL;
    2.64 +
    2.65 +		l1_mfn = ((uint64_t *)l2_mfn)[(base >> 21) & 0x1ff];
    2.66 +		if (!(l1_mfn & PT_ENTRY_PRESENT))
    2.67 +			panic("l2 entry not present\n");
    2.68 +		l1_mfn &= 0x3fffff000ULL;
    2.69 +
    2.70 +		l0_mfn = ((uint64_t *)l1_mfn)[(base >> 12) & 0x1ff];
    2.71 +		if (!(l0_mfn & PT_ENTRY_PRESENT))
    2.72 +			panic("l1 entry not present\n");
    2.73 +		l0_mfn &= 0x3fffff000ULL;
    2.74 +
    2.75 +		return l0_mfn + (base & 0xfff);
    2.76 +	} else { /* oldctx.cr4 & CR4_PAE && oldctx.cr4 & CR4_PSE */
    2.77 +		l1_mfn = ((uint64_t *)gcr3)[(base >> 30) & 0x3];
    2.78 +		if (!(l1_mfn & PT_ENTRY_PRESENT))
    2.79 +			panic("l2 entry not present\n");
    2.80 +		l1_mfn &= 0x3fffff000ULL;
    2.81 +
    2.82 +		l0_mfn = ((uint64_t *)l1_mfn)[(base >> 21) & 0x1ff];
    2.83 +		if (!(l0_mfn & PT_ENTRY_PRESENT))
    2.84 +			panic("l1 entry not present\n");
    2.85 +		l0_mfn &= 0x3ffe00000ULL;
    2.86 +
    2.87 +		return l0_mfn + (base & 0x1fffff);
    2.88 +	}
    2.89  }
    2.90  
    2.91  static unsigned
    2.92 @@ -95,7 +140,8 @@ address(struct regs *regs, unsigned seg,
    2.93  	    (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
    2.94  		return ((seg & 0xFFFF) << 4) + off;
    2.95  
    2.96 -	entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[seg >> 3];
    2.97 +	entry = ((unsigned long long *)
    2.98 +                 guest_linear_to_real(oldctx.gdtr_base))[seg >> 3];
    2.99  	entry_high = entry >> 32;
   2.100  	entry_low = entry & 0xFFFFFFFF;
   2.101  
   2.102 @@ -780,7 +826,8 @@ load_seg(unsigned long sel, uint32_t *ba
   2.103  		return 1;
   2.104  	}
   2.105  
   2.106 -	entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 0))[sel >> 3];
   2.107 +	entry = ((unsigned long long *)
   2.108 +                 guest_linear_to_real(oldctx.gdtr_base))[sel >> 3];
   2.109  
   2.110  	/* Check the P bit first */
   2.111  	if (!((entry >> (15+32)) & 0x1) && sel != 0)
     3.1 --- a/tools/python/xen/xm/addlabel.py	Fri Sep 22 13:06:05 2006 +0100
     3.2 +++ b/tools/python/xen/xm/addlabel.py	Fri Sep 22 13:06:20 2006 +0100
     3.3 @@ -19,19 +19,23 @@
     3.4  
     3.5  """Labeling a domain configuration file or a resoruce.
     3.6  """
     3.7 -import sys, os
     3.8 +import os
     3.9 +import sys
    3.10 +
    3.11  from xen.util import dictio
    3.12  from xen.util import security
    3.13 +from xen.xm.opts import OptionError
    3.14  
    3.15 -def usage():
    3.16 -    print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]"
    3.17 -    print "       xm addlabel <label> res <resource> [<policy>]\n"
    3.18 -    print "  This program adds an acm_label entry into the 'configfile'"
    3.19 -    print "  for a domain or to the global resource label file for a"
    3.20 -    print "  resource. It derives the policy from the running hypervisor"
    3.21 -    print "  if it is not given (optional parameter). If a label already"
    3.22 -    print "  exists for the given domain or resource, then addlabel fails.\n"
    3.23 -    security.err("Usage")
    3.24 +def help():
    3.25 +    return """
    3.26 +    Format: xm addlabel <label> dom <configfile> [<policy>]
    3.27 +            xm addlabel <label> res <resource> [<policy>]
    3.28 +    
    3.29 +    This program adds an acm_label entry into the 'configfile'
    3.30 +    for a domain or to the global resource label file for a
    3.31 +    resource. It derives the policy from the running hypervisor
    3.32 +    if it is not given (optional parameter). If a label already
    3.33 +    exists for the given domain or resource, then addlabel fails."""
    3.34  
    3.35  
    3.36  def validate_config_file(configfile):
    3.37 @@ -114,9 +118,8 @@ def add_domain_label(label, configfile, 
    3.38  def main (argv):
    3.39      try:
    3.40          policyref = None
    3.41 -        if len(argv) not in [4,5]:
    3.42 -            usage()
    3.43 -            return
    3.44 +        if len(argv) not in (4, 5):
    3.45 +            raise OptionError('Needs either 2 or 3 arguments')
    3.46  
    3.47          label = argv[1]
    3.48  
    3.49 @@ -135,20 +138,20 @@ def main (argv):
    3.50                      if os.path.isfile(configfile):
    3.51                          break
    3.52              if not validate_config_file(configfile):
    3.53 -                usage()
    3.54 +                raise OptionError('Invalid config file')
    3.55              else:
    3.56                  add_domain_label(label, configfile, policyref)
    3.57          elif argv[2].lower() == "res":
    3.58              resource = argv[3]
    3.59              add_resource_label(label, resource, policyref)
    3.60          else:
    3.61 -            usage()
    3.62 -
    3.63 +            raise OptionError('Need to specify either "dom" or "res" as object to add label to.')
    3.64 +            
    3.65      except security.ACMError:
    3.66          sys.exit(-1)
    3.67  
    3.68 -
    3.69  if __name__ == '__main__':
    3.70      main(sys.argv)
    3.71 +    
    3.72  
    3.73  
     4.1 --- a/tools/python/xen/xm/cfgbootpolicy.py	Fri Sep 22 13:06:05 2006 +0100
     4.2 +++ b/tools/python/xen/xm/cfgbootpolicy.py	Fri Sep 22 13:06:20 2006 +0100
     4.3 @@ -28,20 +28,17 @@ from xen.util.security import ACMError, 
     4.4  from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re
     4.5  from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re
     4.6  from xen.util.security import empty_line_re, binary_name_re, policy_name_re
     4.7 -
     4.8 +from xen.xm.opts import OptionError
     4.9  
    4.10 -def usage():
    4.11 -    print "\nUsage: xm cfgbootpolicy <policy> [<kernelversion>]\n"
    4.12 -    print "  Adds a 'module' line to the Xen grub.conf entry"
    4.13 -    print "  so that xen boots into a specific access control"
    4.14 -    print "  policy. If kernelversion is not given, then this"
    4.15 -    print "  script tries to determine it by looking for a grub"
    4.16 -    print "  entry with a line kernel xen.* If there are multiple"
    4.17 -    print "  Xen entries, then it must be called with an explicit"
    4.18 -    print "  version (it will fail otherwise).\n"
    4.19 -    err("Usage")
    4.20 -
    4.21 -
    4.22 +def help():
    4.23 +    return """
    4.24 +    Adds a 'module' line to the Xen grub.conf entry
    4.25 +    so that xen boots into a specific access control
    4.26 +    policy. If kernelversion is not given, then this
    4.27 +    script tries to determine it by looking for a grub
    4.28 +    entry with a line kernel xen.* If there are multiple
    4.29 +    Xen entries, then it must be called with an explicit
    4.30 +    version (it will fail otherwise).\n"""
    4.31  
    4.32  def determine_kernelversion(user_specified):
    4.33      within_xen_title = 0
    4.34 @@ -152,7 +149,7 @@ def main(argv):
    4.35              policy = argv[1]
    4.36              user_kver = argv[2]
    4.37          else:
    4.38 -            usage()
    4.39 +            raise OptionError('Invalid number of arguments')
    4.40  
    4.41          if not policy_name_re.match(policy):
    4.42              err("Illegal policy name \'" + policy + "\'")
     5.1 --- a/tools/python/xen/xm/console.py	Fri Sep 22 13:06:05 2006 +0100
     5.2 +++ b/tools/python/xen/xm/console.py	Fri Sep 22 13:06:20 2006 +0100
     5.3 @@ -18,9 +18,7 @@
     5.4  
     5.5  XENCONSOLE = "xenconsole"
     5.6  
     5.7 -
     5.8  import xen.util.auxbin
     5.9  
    5.10 -
    5.11  def execConsole(domid):
    5.12      xen.util.auxbin.execute(XENCONSOLE, [str(domid)])
     6.1 --- a/tools/python/xen/xm/create.py	Fri Sep 22 13:06:05 2006 +0100
     6.2 +++ b/tools/python/xen/xm/create.py	Fri Sep 22 13:06:20 2006 +0100
     6.3 @@ -25,7 +25,6 @@ import sys
     6.4  import socket
     6.5  import re
     6.6  import xmlrpclib
     6.7 -import traceback
     6.8  
     6.9  from xen.xend import sxp
    6.10  from xen.xend import PrettyPrint
    6.11 @@ -65,35 +64,36 @@ gopts.opt('quiet', short='q',
    6.12  
    6.13  gopts.opt('path', val='PATH',
    6.14            fn=set_value, default='.:/etc/xen',
    6.15 -          use="""Search path for configuration scripts.
    6.16 -         The value of PATH is a colon-separated directory list.""")
    6.17 +          use="Search path for configuration scripts. "
    6.18 +          "The value of PATH is a colon-separated directory list.")
    6.19  
    6.20  gopts.opt('defconfig', short='f', val='FILE',
    6.21            fn=set_value, default='xmdefconfig',
    6.22 -          use="""Use the given Python configuration script.
    6.23 -          The configuration script is loaded after arguments have been processed.
    6.24 -          Each command-line option sets a configuration variable named after
    6.25 -          its long option name, and these variables are placed in the
    6.26 -          environment of the script before it is loaded.
    6.27 -          Variables for options that may be repeated have list values.
    6.28 -          Other variables can be set using VAR=VAL on the command line.
    6.29 -        
    6.30 -          After the script is loaded, option values that were not set on the
    6.31 -          command line are replaced by the values set in the script.""")
    6.32 +          use="Use the given Python configuration script."
    6.33 +          "The configuration script is loaded after arguments have been "
    6.34 +          "processed. Each command-line option sets a configuration "
    6.35 +          "variable named after its long option name, and these "
    6.36 +          "variables are placed in the environment of the script before "
    6.37 +          "it is loaded. Variables for options that may be repeated have "
    6.38 +          "list values. Other variables can be set using VAR=VAL on the "
    6.39 +          "command line. "     
    6.40 +          "After the script is loaded, option values that were not set "
    6.41 +          "on the command line are replaced by the values set in the script.")
    6.42  
    6.43  gopts.default('defconfig')
    6.44  
    6.45  gopts.opt('config', short='F', val='FILE',
    6.46            fn=set_value, default=None,
    6.47 -          use="""Domain configuration to use (SXP).
    6.48 -          SXP is the underlying configuration format used by Xen.
    6.49 -          SXP configurations can be hand-written or generated from Python configuration
    6.50 -          scripts, using the -n (dryrun) option to print the configuration.""")
    6.51 +          use="Domain configuration to use (SXP).\n"
    6.52 +          "SXP is the underlying configuration format used by Xen.\n"
    6.53 +          "SXP configurations can be hand-written or generated from Python "
    6.54 +          "configuration scripts, using the -n (dryrun) option to print\n"
    6.55 +          "the configuration.")
    6.56  
    6.57  gopts.opt('dryrun', short='n',
    6.58            fn=set_true, default=0,
    6.59 -          use="""Dry run - print the configuration but don't create the domain.
    6.60 -          Loads the configuration script, creates the SXP configuration and prints it.""")
    6.61 +          use="Dry run - prints the resulting configuration in SXP but "
    6.62 +          "does not create the domain.")
    6.63  
    6.64  gopts.opt('paused', short='p',
    6.65            fn=set_true, default=0,
    6.66 @@ -105,18 +105,16 @@ gopts.opt('console_autoconnect', short='
    6.67  
    6.68  gopts.var('vncviewer', val='no|yes',
    6.69            fn=set_bool, default=None,
    6.70 -          use="""Spawn a vncviewer listening for a vnc server in the domain.
    6.71 -          The address of the vncviewer is passed to the domain on the kernel command
    6.72 -          line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY.
    6.73 -          A display value with a free port is chosen if possible.
    6.74 -          Only valid when vnc=1.
    6.75 -          """)
    6.76 +           use="Spawn a vncviewer listening for a vnc server in the domain.\n"
    6.77 +           "The address of the vncviewer is passed to the domain on the "
    6.78 +           "kernel command line using 'VNC_SERVER=<host>:<port>'. The port "
    6.79 +           "used by vnc is 5500 + DISPLAY. A display value with a free port "
    6.80 +           "is chosen if possible.\nOnly valid when vnc=1.")
    6.81  
    6.82  gopts.var('vncconsole', val='no|yes',
    6.83            fn=set_bool, default=None,
    6.84 -          use="""Spawn a vncviewer process for the domain's graphical console.
    6.85 -          Only valid when vnc=1.
    6.86 -          """)
    6.87 +          use="Spawn a vncviewer process for the domain's graphical console.\n"
    6.88 +          "Only valid when vnc=1.")
    6.89  
    6.90  gopts.var('name', val='NAME',
    6.91            fn=set_value, default=None,
    6.92 @@ -440,7 +438,6 @@ gopts.var('uuid', val='',
    6.93            addresses for virtual network interfaces.  This must be a unique 
    6.94            value across the entire cluster.""")
    6.95  
    6.96 -
    6.97  def err(msg):
    6.98      """Print an error to stderr and exit.
    6.99      """
   6.100 @@ -490,7 +487,6 @@ def configure_disks(config_devs, vals):
   6.101      """Create the config for disks (virtual block devices).
   6.102      """
   6.103      for (uname, dev, mode, backend) in vals.disk:
   6.104 -
   6.105          if uname.startswith('tap:'):
   6.106              cls = 'tap'
   6.107          else:
   6.108 @@ -851,7 +847,6 @@ def choose_vnc_display():
   6.109          if port in ports: continue
   6.110          return d
   6.111      return None
   6.112 -
   6.113  vncpid = None
   6.114  
   6.115  def daemonize(prog, args):
   6.116 @@ -885,7 +880,6 @@ def daemonize(prog, args):
   6.117              w.write(str(pid2 or 0))
   6.118              w.close()
   6.119              os._exit(0)
   6.120 -
   6.121      os.close(w)
   6.122      r = os.fdopen(r)
   6.123      daemon_pid = int(r.read())
   6.124 @@ -904,6 +898,7 @@ def spawn_vnc(display):
   6.125      vncpid = daemonize("vncviewer", vncargs)
   6.126      if vncpid == 0:
   6.127          return 0
   6.128 +
   6.129      return VNC_BASE_PORT + display
   6.130  
   6.131  def preprocess_vnc(vals):
   6.132 @@ -1091,7 +1086,6 @@ def check_domain_label(config, verbose):
   6.133  
   6.134      return answer
   6.135  
   6.136 -
   6.137  def config_security_check(config, verbose):
   6.138      """Checks each resource listed in the config to see if the active
   6.139         policy will permit creation of a new domain using the config.
   6.140 @@ -1145,7 +1139,6 @@ def config_security_check(config, verbos
   6.141  
   6.142      return answer
   6.143  
   6.144 -
   6.145  def create_security_check(config):
   6.146      passed = 0
   6.147      try:
   6.148 @@ -1158,7 +1151,9 @@ def create_security_check(config):
   6.149          sys.exit(-1)
   6.150  
   6.151      return passed
   6.152 -
   6.153 +  
   6.154 +def help():
   6.155 +    return str(gopts)
   6.156  
   6.157  def main(argv):
   6.158      try:
   6.159 @@ -1176,11 +1171,11 @@ def main(argv):
   6.160          PrettyPrint.prettyprint(config)
   6.161      else:
   6.162          if not create_security_check(config):
   6.163 -            err("Security configuration prevents domain from starting.")
   6.164 +            raise OptionError('Security Configuration prevents domain from starting')
   6.165          else:
   6.166              dom = make_domain(opts, config)
   6.167              if opts.vals.console_autoconnect:
   6.168 -                console.execConsole(dom)
   6.169 -        
   6.170 +                console.execConsole(dom)        
   6.171 +             
   6.172  if __name__ == '__main__':
   6.173      main(sys.argv)
     7.1 --- a/tools/python/xen/xm/dry-run.py	Fri Sep 22 13:06:05 2006 +0100
     7.2 +++ b/tools/python/xen/xm/dry-run.py	Fri Sep 22 13:06:20 2006 +0100
     7.3 @@ -22,20 +22,18 @@ import sys
     7.4  from xen.util import security
     7.5  from xen.xm import create
     7.6  from xen.xend import sxp
     7.7 +from xen.xm.opts import OptionError
     7.8  
     7.9 -def usage():
    7.10 -    print "\nUsage: xm dry-run <configfile>\n"
    7.11 -    print "This program checks each resource listed in the configfile"
    7.12 -    print "to see if the domain created by the configfile can access"
    7.13 -    print "the resources.  The status of each resource is listed"
    7.14 -    print "individually along with the final security decision.\n"
    7.15 -    security.err("Usage")
    7.16 -
    7.17 +def help():
    7.18 +    return """
    7.19 +    This program checks each resource listed in the configfile
    7.20 +    to see if the domain created by the configfile can access
    7.21 +    the resources.  The status of each resource is listed
    7.22 +    individually along with the final security decision."""
    7.23  
    7.24  def main (argv):
    7.25 -    try:
    7.26 -        if len(argv) != 2:
    7.27 -            usage()
    7.28 +    if len(argv) != 2:
    7.29 +        raise OptionError('Invalid number of arguments')
    7.30  
    7.31          passed = 0
    7.32          (opts, config) = create.parseCommandLine(argv)
     8.1 --- a/tools/python/xen/xm/dumppolicy.py	Fri Sep 22 13:06:05 2006 +0100
     8.2 +++ b/tools/python/xen/xm/dumppolicy.py	Fri Sep 22 13:06:20 2006 +0100
     8.3 @@ -21,12 +21,10 @@ import sys
     8.4  from xen.util.security import ACMError, err, dump_policy
     8.5  
     8.6  
     8.7 -def usage():
     8.8 -    print "\nUsage: xm dumppolicy\n"
     8.9 -    print " Retrieve and print currently enforced"
    8.10 -    print " hypervisor policy information (low-level).\n"
    8.11 -    err("Usage")
    8.12 -
    8.13 +def help():
    8.14 +    return """
    8.15 +    Retrieve and print currently enforced hypervisor policy information
    8.16 +    (low-level)."""
    8.17  
    8.18  def main(argv):
    8.19      try:
    8.20 @@ -34,7 +32,6 @@ def main(argv):
    8.21              usage()
    8.22  
    8.23          dump_policy()
    8.24 -
    8.25      except ACMError:
    8.26          sys.exit(-1)
    8.27  
     9.1 --- a/tools/python/xen/xm/getlabel.py	Fri Sep 22 13:06:05 2006 +0100
     9.2 +++ b/tools/python/xen/xm/getlabel.py	Fri Sep 22 13:06:20 2006 +0100
     9.3 @@ -21,13 +21,13 @@
     9.4  import sys, os, re
     9.5  from xen.util import dictio
     9.6  from xen.util import security
     9.7 +from xen.xm.opts import OptionError
     9.8  
     9.9 -def usage():
    9.10 -    print "\nUsage: xm getlabel dom <configfile>"
    9.11 -    print "       xm getlabel res <resource>\n"
    9.12 -    print "  This program shows the label for a domain or resource.\n"
    9.13 -    security.err("Usage")
    9.14 -
    9.15 +def help():
    9.16 +    return """
    9.17 +    Usage: xm getlabel dom <configfile>"
    9.18 +           xm getlabel res <resource>\n"
    9.19 +    This program shows the label for a domain or resource."""
    9.20  
    9.21  def get_resource_label(resource):
    9.22      """Gets the resource label
    9.23 @@ -90,21 +90,17 @@ def get_domain_label(configfile):
    9.24  
    9.25  
    9.26  def main (argv):
    9.27 -    try:
    9.28 -        if len(argv) != 3:
    9.29 -            usage()
    9.30 +    if len(argv) != 3:
    9.31 +        raise OptionError('Requires 2 arguments')
    9.32  
    9.33 -        if argv[1].lower() == "dom":
    9.34 -            configfile = argv[2]
    9.35 -            get_domain_label(configfile)
    9.36 -        elif argv[1].lower() == "res":
    9.37 -            resource = argv[2]
    9.38 -            get_resource_label(resource)
    9.39 -        else:
    9.40 -            usage()
    9.41 -
    9.42 -    except security.ACMError:
    9.43 -        sys.exit(-1)
    9.44 +    if argv[1].lower() == "dom":
    9.45 +        configfile = argv[2]
    9.46 +        get_domain_label(configfile)
    9.47 +    elif argv[1].lower() == "res":
    9.48 +        resource = argv[2]
    9.49 +        get_resource_label(resource)
    9.50 +    else:
    9.51 +        raise OptionError('First subcommand argument must be "dom" or "res"')
    9.52  
    9.53  if __name__ == '__main__':
    9.54      main(sys.argv)
    10.1 --- a/tools/python/xen/xm/labels.py	Fri Sep 22 13:06:05 2006 +0100
    10.2 +++ b/tools/python/xen/xm/labels.py	Fri Sep 22 13:06:20 2006 +0100
    10.3 @@ -23,49 +23,46 @@ import traceback
    10.4  import string
    10.5  from xen.util.security import ACMError, err, list_labels, active_policy
    10.6  from xen.util.security import vm_label_re, res_label_re, all_label_re
    10.7 +from xen.xm.opts import OptionError
    10.8  
    10.9 -def usage():
   10.10 -    print "\nUsage: xm labels [<policy>] [<type=dom|res|any>]\n"
   10.11 -    print " Prints labels of the specified type (default is dom)"
   10.12 -    print " that are defined in policy (default is current"
   10.13 -    print " hypervisor policy).\n"
   10.14 -    err("Usage")
   10.15  
   10.16 +def help():
   10.17 +    return """
   10.18 +    Prints labels of the specified type (default is dom)
   10.19 +    that are defined in policy (default is current hypervisor policy)."""
   10.20  
   10.21  def main(argv):
   10.22 +    policy = None
   10.23 +    ptype = None
   10.24 +    for arg in argv[1:]:
   10.25 +        key_val = arg.split('=')
   10.26 +        if len(key_val) == 2 and key_val[0] == 'type':
   10.27 +            if ptype:
   10.28 +                raise OptionError('type is definied twice')
   10.29 +            ptype = key_val[1].lower()
   10.30 +
   10.31 +        elif len(key_val) == 1:
   10.32 +            if policy:
   10.33 +                raise OptionError('policy is defined twice')
   10.34 +            policy = arg
   10.35 +        else:
   10.36 +            raise OptionError('Unrecognised option: %s' % arg)
   10.37 +
   10.38 +    if not policy:
   10.39 +        policy = active_policy
   10.40 +        if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
   10.41 +            raise OptionError('No policy active, you must specify a <policy>')
   10.42 +
   10.43 +    if not ptype or ptype == 'dom':
   10.44 +        condition = vm_label_re
   10.45 +    elif ptype == 'res':
   10.46 +        condition = res_label_re
   10.47 +    elif ptype == 'any':
   10.48 +        condition = all_label_re
   10.49 +    else:
   10.50 +        err("Unknown label type \'" + ptype + "\'")
   10.51 +
   10.52      try:
   10.53 -        policy = None
   10.54 -        type = None
   10.55 -        for i in argv[1:]:
   10.56 -            i_s = string.split(i, '=')
   10.57 -            if len(i_s) > 1:
   10.58 -                if (i_s[0] == 'type') and (len(i_s) == 2):
   10.59 -                    if not type:
   10.60 -                        type = i_s[1]
   10.61 -                    else:
   10.62 -                        usage()
   10.63 -                else:
   10.64 -                    usage()
   10.65 -            else:
   10.66 -                if not policy:
   10.67 -                    policy = i
   10.68 -                else:
   10.69 -                    usage()
   10.70 -
   10.71 -        if not policy:
   10.72 -            policy = active_policy
   10.73 -            if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
   10.74 -                err("No policy active. Please specify the <policy> parameter.")
   10.75 -
   10.76 -        if not type or (type in ['DOM', 'dom']):
   10.77 -            condition = vm_label_re
   10.78 -        elif type in ['RES', 'res']:
   10.79 -            condition = res_label_re
   10.80 -        elif type in ['ANY', 'any']:
   10.81 -            condition = all_label_re
   10.82 -        else:
   10.83 -            err("Unknown label type \'" + type + "\'")
   10.84 -
   10.85          labels = list_labels(policy, condition)
   10.86          labels.sort()
   10.87          for label in labels:
   10.88 @@ -74,9 +71,7 @@ def main(argv):
   10.89      except ACMError:
   10.90          sys.exit(-1)
   10.91      except:
   10.92 -        traceback.print_exc(limit=1)
   10.93 -        sys.exit(-1)
   10.94 -
   10.95 +        traceback.print_exc(limit = 1)
   10.96  
   10.97  if __name__ == '__main__':
   10.98      main(sys.argv)
    11.1 --- a/tools/python/xen/xm/loadpolicy.py	Fri Sep 22 13:06:05 2006 +0100
    11.2 +++ b/tools/python/xen/xm/loadpolicy.py	Fri Sep 22 13:06:20 2006 +0100
    11.3 @@ -21,26 +21,23 @@
    11.4  import sys
    11.5  import traceback
    11.6  from xen.util.security import ACMError, err, load_policy
    11.7 -
    11.8 +from xen.xm.opts import OptionError
    11.9  
   11.10 -def usage():
   11.11 -    print "\nUsage: xm loadpolicy <policy>\n"
   11.12 -    print " Load the compiled binary (.bin) policy"
   11.13 -    print " into the running hypervisor.\n"
   11.14 -    err("Usage")
   11.15 +def help():
   11.16 +    return """Load the compiled binary (.bin) policy into the running
   11.17 +    hypervisor."""
   11.18  
   11.19  def main(argv):
   11.20 +    if len(argv) != 2:
   11.21 +        raise OptionError('No policy defined')
   11.22 +    
   11.23      try:
   11.24 -        if len(argv) != 2:
   11.25 -            usage()
   11.26          load_policy(argv[1])
   11.27  
   11.28      except ACMError:
   11.29          sys.exit(-1)
   11.30      except:
   11.31 -        traceback.print_exc(limit=1)
   11.32 -        sys.exit(-1)
   11.33 -
   11.34 +        traceback.print_exc(limit = 1)
   11.35  
   11.36  if __name__ == '__main__':
   11.37      main(sys.argv)
    12.1 --- a/tools/python/xen/xm/main.py	Fri Sep 22 13:06:05 2006 +0100
    12.2 +++ b/tools/python/xen/xm/main.py	Fri Sep 22 13:06:20 2006 +0100
    12.3 @@ -22,28 +22,27 @@
    12.4  """Grand unified management application for Xen.
    12.5  """
    12.6  import os
    12.7 -import os.path
    12.8  import sys
    12.9  import re
   12.10  import getopt
   12.11  import socket
   12.12 -import warnings
   12.13 -warnings.filterwarnings('ignore', category=FutureWarning)
   12.14 +import traceback
   12.15  import xmlrpclib
   12.16  import traceback
   12.17  import datetime
   12.18 +from select import select
   12.19  
   12.20 -import xen.xend.XendProtocol
   12.21 +import warnings
   12.22 +warnings.filterwarnings('ignore', category=FutureWarning)
   12.23  
   12.24  from xen.xend import PrettyPrint
   12.25  from xen.xend import sxp
   12.26 -from xen.xm.opts import *
   12.27 +from xen.xend import XendClient
   12.28 +from xen.xend.XendClient import server
   12.29  
   12.30 -import console
   12.31 -import xen.xend.XendClient
   12.32 -from xen.xend.XendClient import server
   12.33 +from xen.xm.opts import OptionError, Opts, wrap, set_true
   12.34 +from xen.xm import console
   12.35  from xen.util import security
   12.36 -from select import select
   12.37  
   12.38  # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
   12.39  # getopt.getopt if gnu_getopt is not available.  This will mean that options
   12.40 @@ -51,93 +50,148 @@ from select import select
   12.41  if not hasattr(getopt, 'gnu_getopt'):
   12.42      getopt.gnu_getopt = getopt.getopt
   12.43  
   12.44 -
   12.45 -# Strings for shorthelp
   12.46 -console_help = "console <DomId>                  Attach to domain DomId's console."
   12.47 -create_help =  """create [-c] <ConfigFile>
   12.48 -               [Name=Value]..       Create a domain based on Config File"""
   12.49 -destroy_help = "destroy <DomId>                  Terminate a domain immediately"
   12.50 -dump_core_help =   """dump-core [-L|--live][-C|--crash]
   12.51 -            <DomId> [FileName]      Dump core of the specified domain"""
   12.52 -
   12.53 -help_help =    "help                             Display this message"
   12.54 -list_help =    "list [--long] [DomId, ...]       List information about domains"
   12.55 -list_label_help = "list [--label] [DomId, ...]      List information about domains including their labels"
   12.56 -
   12.57 -mem_max_help = "mem-max <DomId> <Mem>            Set maximum memory reservation for a domain"
   12.58 -mem_set_help = "mem-set <DomId> <Mem>            Adjust the current memory usage for a domain"
   12.59 -migrate_help = "migrate <DomId> <Host>           Migrate a domain to another machine"
   12.60 -pause_help =   "pause <DomId>                    Pause execution of a domain"
   12.61 -reboot_help =  "reboot <DomId> [-w][-a]          Reboot a domain"
   12.62 -restore_help = "restore <File>                   Create a domain from a saved state file"
   12.63 -save_help =    "save <DomId> <File>              Save domain state (and config) to file"
   12.64 -shutdown_help ="shutdown <DomId> [-w][-a][-R|-H] Shutdown a domain"
   12.65 -top_help =     "top                              Monitor system and domains in real-time"
   12.66 -unpause_help = "unpause <DomId>                  Unpause a paused domain"
   12.67 -uptime_help  = "uptime [-s|--short] [DomId, ...] List uptime for domains"
   12.68 -
   12.69 -help_spacer = """
   12.70 -   """
   12.71 +# General help message
   12.72  
   12.73 -# Strings for longhelp
   12.74 -sysrq_help =   "sysrq   <DomId> <letter>         Send a sysrq to a domain"
   12.75 -domid_help =   "domid <DomName>                  Converts a domain name to a domain id"
   12.76 -domname_help = "domname <DomId>                  Convert a domain id to a domain name"
   12.77 -vcpu_set_help = """vcpu-set <DomId> <VCPUs>         Set the number of active VCPUs for a domain
   12.78 -                                    within the range allowed by the domain
   12.79 -                                    configuration"""
   12.80 -vcpu_list_help = "vcpu-list <DomId>                List the VCPUs for a domain (or all domains)"
   12.81 -vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs>   Set which cpus a VCPU can use" 
   12.82 -dmesg_help =   "dmesg [-c|--clear]               Read or clear Xen's message buffer"
   12.83 -info_help =    "info                             Get information about the xen host"
   12.84 -rename_help =  "rename <DomId> <New Name>        Rename a domain"
   12.85 -log_help =     "log                              Print the xend log"
   12.86 -sched_sedf_help = "sched-sedf [DOM] [OPTIONS]       Show|Set simple EDF parameters\n" + \
   12.87 -"              -p, --period          Relative deadline(ms).\n\
   12.88 -              -s, --slice           Worst-case execution time(ms)\n\
   12.89 -                                    (slice < period).\n\
   12.90 -              -l, --latency         scaled period(ms) in case the domain\n\
   12.91 -                                    is doing heavy I/O.\n\
   12.92 -              -e, --extra           flag (0/1) which controls whether the\n\
   12.93 -                                    domain can run in extra-time\n\
   12.94 -              -w, --weight          mutually exclusive with period/slice and\n\
   12.95 -                                    specifies another way of setting a domain's\n\
   12.96 -                                    cpu period/slice."
   12.97 +USAGE_HELP = "Usage: xm <subcommand> [args]\n\n" \
   12.98 +             "Control, list, and manipulate Xen guest instances.\n"
   12.99  
  12.100 -sched_credit_help = "sched-credit                           Set or get credit scheduler parameters"
  12.101 -block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode>
  12.102 -                [BackDomId]         Create a new virtual block device"""
  12.103 -block_detach_help = """block-detach  <DomId> <DevId>    Destroy a domain's virtual block device,
  12.104 -                                    where <DevId> may either be the device ID
  12.105 -                                    or the device name as mounted in the guest"""
  12.106 -
  12.107 -block_list_help = "block-list <DomId> [--long]      List virtual block devices for a domain"
  12.108 -block_configure_help = """block-configure <DomId> <BackDev> <FrontDev> <Mode>
  12.109 -                   [BackDomId] Change block device configuration"""
  12.110 -network_attach_help = """network-attach  <DomID> [script=<script>] [ip=<ip>] [mac=<mac>]
  12.111 -                           [bridge=<bridge>] [backend=<backDomID>]
  12.112 -                                    Create a new virtual network device """
  12.113 -network_detach_help = """network-detach  <DomId> <DevId>  Destroy a domain's virtual network
  12.114 -                                    device, where <DevId> is the device ID."""
  12.115 +USAGE_FOOTER = '<Domain> can either be the Domain Name or Id.\n' \
  12.116 +               'For more help on \'xm\' see the xm(1) man page.\n' \
  12.117 +               'For more help on \'xm create\' see the xmdomain.cfg(5) '\
  12.118 +               ' man page.\n'
  12.119  
  12.120 -network_list_help = "network-list <DomId> [--long]    List virtual network interfaces for a domain"
  12.121 -vnet_list_help = "vnet-list [-l|--long]            list vnets"
  12.122 -vnet_create_help = "vnet-create <config>             create a vnet from a config file"
  12.123 -vnet_delete_help = "vnet-delete <vnetid>             delete a vnet"
  12.124 -vtpm_list_help = "vtpm-list <DomId> [--long]       list virtual TPM devices"
  12.125 -addlabel_help =  "addlabel <label> dom <configfile> Add security label to domain\n            <label> res <resource>   or resource"
  12.126 -rmlabel_help =  "rmlabel dom <configfile>         Remove security label from domain\n           res <resource>           or resource"
  12.127 -getlabel_help =  "getlabel dom <configfile>        Show security label for domain\n            res <resource>          or resource"
  12.128 -dry_run_help =  "dry-run <configfile>             Tests if domain can access its resources"
  12.129 -resources_help =  "resources                        Show info for each labeled resource"
  12.130 -cfgbootpolicy_help = "cfgbootpolicy <policy>           Add policy to boot configuration "
  12.131 -dumppolicy_help = "dumppolicy                       Print hypervisor ACM state information"
  12.132 -loadpolicy_help = "loadpolicy <policy>              Load binary policy into hypervisor"
  12.133 -makepolicy_help = "makepolicy <policy>              Build policy and create .bin/.map files"
  12.134 -labels_help     = "labels [policy] [type=DOM|..]    List <type> labels for (active) policy."
  12.135 -serve_help      = "serve                            Proxy Xend XML-RPC over stdio"
  12.136 +# Help strings are indexed by subcommand name in this way:
  12.137 +# 'subcommand': (argstring, description)
  12.138  
  12.139 -short_command_list = [
  12.140 +SUBCOMMAND_HELP = {
  12.141 +    # common commands
  12.142 +    
  12.143 +    'console'     : ('<Domain>',
  12.144 +                     'Attach to <Domain>\'s console.'),
  12.145 +    'create'      : ('<ConfigFile> [options] [vars]',
  12.146 +                     'Create a domain based on <ConfigFile>.'),
  12.147 +    'destroy'     : ('<Domain>',
  12.148 +                     'Terminate a domain immediately.'),
  12.149 +    'help'        : ('', 'Display this message.'),
  12.150 +    'list'        : ('[options] [Domain, ...]',
  12.151 +                     'List information about all/some domains.'),
  12.152 +    'mem-max'     : ('<Domain> <Mem>',
  12.153 +                     'Set the maximum amount reservation for a domain.'),
  12.154 +    'mem-set'     : ('<Domain> <Mem>',
  12.155 +                     'Set the current memory usage for a domain.'),
  12.156 +    'migrate'     : ('<Domain> <Host>',
  12.157 +                     'Migrate a domain to another machine.'),
  12.158 +    'pause'       : ('<Domain>', 'Pause execution of a domain.'),
  12.159 +    'reboot'      : ('<Domain> [-wa]', 'Reboot a domain.'),
  12.160 +    'restore'     : ('<CheckpointFile>',
  12.161 +                     'Restore a domain from a saved state.'),
  12.162 +    'save'        : ('<Domain> <CheckpointFile>',
  12.163 +                     'Save a domain state to restore later.'),
  12.164 +    'shutdown'    : ('<Domain> [-waRH]', 'Shutdown a domain.'),
  12.165 +    'top'         : ('', 'Monitor a host and the domains in real time.'),
  12.166 +    'unpause'     : ('<Domain>', 'Unpause a paused domain.'),
  12.167 +    'uptime'      : ('[-s] <Domain>', 'Print uptime for a domain.'),
  12.168 +
  12.169 +    # less used commands
  12.170 +
  12.171 +    'dmesg'       : ('[-c|--clear]',
  12.172 +                     'Read and/or clear Xend\'s message buffer.'),
  12.173 +    'domid'       : ('<DomainName>', 'Convert a domain name to domain id.'),
  12.174 +    'domname'     : ('<DomId>', 'Convert a domain id to domain name.'),
  12.175 +    'dump-core'   : ('[-L|--live] [-C|--crash] <Domain> [Filename]',
  12.176 +                     'Dump core for a specific domain.'),
  12.177 +    'info'        : ('', 'Get information about Xen host.'),
  12.178 +    'log'         : ('', 'Print Xend log'),
  12.179 +    'rename'      : ('<Domain> <NewDomainName>', 'Rename a domain.'),
  12.180 +    'sched-sedf'  : ('<Domain> [options]', 'Get/set EDF parameters.'),
  12.181 +    'sched-credit': ('-d <Domain> [-w[=WEIGHT]|-c[=CAP]]',
  12.182 +                     'Get/set credit scheduler parameters.'),
  12.183 +    'sysrq'       : ('<Domain> <letter>', 'Send a sysrq to a domain.'),
  12.184 +    'vcpu-list'   : ('[<Domain>]',
  12.185 +                     'List the VCPUs for a domain or all domains.'),
  12.186 +    'vcpu-pin'    : ('<Domain> <VCPU> <CPUs>',
  12.187 +                     'Set which CPUs a VCPU can use.'),
  12.188 +    'vcpu-set'    : ('<Domain> <vCPUs>',
  12.189 +                     'Set the number of active VCPUs for allowed for the'
  12.190 +                     ' domain.'),
  12.191 +
  12.192 +    # device commands
  12.193 +
  12.194 +    'block-attach'  :  ('<Domain> <BackDev> <FrontDev> <Mode>',
  12.195 +                        'Create a new virtual block device.'),
  12.196 +    'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomId]',
  12.197 +                        'Change block device configuration'),
  12.198 +    'block-detach'  :  ('<Domain> <DevId>',
  12.199 +                        'Destroy a domain\'s virtual block device.'),
  12.200 +    'block-list'    :  ('<Domain> [--long]',
  12.201 +                        'List virtual block devices for a domain.'),
  12.202 +    'network-attach':  ('<Domain> [--script=<script>] [--ip=<ip>] '
  12.203 +                        '[--mac=<mac>]',
  12.204 +                        'Create a new virtual network device.'),
  12.205 +    'network-detach':  ('<Domain> <DevId>',
  12.206 +                        'Destroy a domain\'s virtual network device.'),
  12.207 +    'network-list'  :  ('<Domain> [--long]',
  12.208 +                        'List virtual network interfaces for a domain.'),
  12.209 +    'vnet-create'   :  ('<ConfigFile>','Create a vnet from ConfigFile.'),
  12.210 +    'vnet-delete'   :  ('<VnetId>', 'Delete a Vnet.'),
  12.211 +    'vnet-list'     :  ('[-l|--long]', 'List Vnets.'),
  12.212 +    'vtpm-list'     :  ('<Domain> [--long]', 'List virtual TPM devices.'),
  12.213 +
  12.214 +    # security
  12.215 +
  12.216 +    'addlabel'      :  ('<label> {dom <ConfigFile>|res <resource>} [<policy>]',
  12.217 +                        'Add security label to domain.'),
  12.218 +    'rmlabel'       :  ('{dom <ConfigFile>|res <Resource>}',
  12.219 +                        'Remove a security label from domain.'),
  12.220 +    'getlabel'      :  ('{dom <ConfigFile>|res <Resource>}',
  12.221 +                        'Show security label for domain or resource.'),
  12.222 +    'dry-run'       :  ('<ConfigFile>',
  12.223 +                        'Test if a domain can access its resources.'),
  12.224 +    'resources'     :  ('', 'Show info for each labeled resource.'),
  12.225 +    'cfgbootpolicy' :  ('<policy> [kernelversion]',
  12.226 +                        'Add policy to boot configuration.'),
  12.227 +    'dumppolicy'    :  ('', 'Print hypervisor ACM state information.'),
  12.228 +    'loadpolicy'    :  ('<policy.bin>', 'Load binary policy into hypervisor.'),
  12.229 +    'makepolicy'    :  ('<policy>', 'Build policy and create .bin/.map '
  12.230 +                        'files.'),
  12.231 +    'labels'        :  ('[policy] [type=dom|res|any]',
  12.232 +                        'List <type> labels for (active) policy.'),
  12.233 +    'serve'         :  ('', 'Proxy Xend XMLRPC over stdio.'),
  12.234 +}
  12.235 +
  12.236 +SUBCOMMAND_OPTIONS = {
  12.237 +    'sched-sedf': (
  12.238 +       ('-p [MS]', '--period[=MS]', 'Relative deadline(ms)'),
  12.239 +       ('-s [MS]', '--slice[=MS]' ,
  12.240 +        'Worst-case execution time(ms). (slice < period)'),
  12.241 +       ('-l [MS]', '--latency[=MS]',
  12.242 +        'Scaled period (ms) when domain performs heavy I/O'),
  12.243 +       ('-e [FLAG]', '--extra[=FLAG]',
  12.244 +        'Flag (0 or 1) controls if domain can run in extra time.'),
  12.245 +       ('-w [FLOAT]', '--weight[=FLOAT]',
  12.246 +        'CPU Period/slice (do not set with --period/--slice)'),
  12.247 +    ),
  12.248 +    'sched-credit': (
  12.249 +       ('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'),
  12.250 +       ('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'),
  12.251 +       ('-c CAP',    '--cap=CAP',       'Cap (int)'),
  12.252 +    ),
  12.253 +    'list': (
  12.254 +       ('-l', '--long', 'Output all VM details in SXP'),
  12.255 +       ('', '--label',  'Include security labels'),
  12.256 +    ),
  12.257 +    'dmesg': (
  12.258 +       ('-c', '--clear', 'Clear dmesg buffer'),
  12.259 +    ),
  12.260 +    'vnet-list': (
  12.261 +       ('-l', '--long', 'List Vnets as SXP'),
  12.262 +    ),
  12.263 +    'network-list': (
  12.264 +       ('-l', '--long', 'List resources as SXP'),
  12.265 +    ),
  12.266 +}
  12.267 +
  12.268 +common_commands = [
  12.269      "console",
  12.270      "create",
  12.271      "destroy",
  12.272 @@ -165,7 +219,6 @@ domain_commands = [
  12.273      "domname",
  12.274      "dump-core",
  12.275      "list",
  12.276 -    "list_label",
  12.277      "mem-max",
  12.278      "mem-set",
  12.279      "migrate",
  12.280 @@ -223,67 +276,105 @@ acm_commands = [
  12.281      "makepolicy",
  12.282      "loadpolicy",
  12.283      "cfgbootpolicy",
  12.284 -    "dumppolicy"
  12.285 +    "dumppolicy",
  12.286      ]
  12.287  
  12.288  all_commands = (domain_commands + host_commands + scheduler_commands +
  12.289                  device_commands + vnet_commands + acm_commands)
  12.290  
  12.291 -
  12.292 -def commandToHelp(cmd):
  12.293 -    return eval(cmd.replace("-", "_") + "_help")
  12.294 -
  12.295 -
  12.296 -shorthelp = """Usage: xm <subcommand> [args]
  12.297 -    Control, list, and manipulate Xen guest instances
  12.298 -
  12.299 -xm common subcommands:
  12.300 -   """  + help_spacer.join(map(commandToHelp, short_command_list))  + """
  12.301 -
  12.302 -<DomName> can be substituted for <DomId> in xm subcommands.
  12.303 -
  12.304 -For a complete list of subcommands run 'xm help --long'
  12.305 -For more help on xm see the xm(1) man page
  12.306 -For more help on xm create, see the xmdomain.cfg(5) man page"""
  12.307 -
  12.308 -longhelp = """Usage: xm <subcommand> [args]
  12.309 -    Control, list, and manipulate Xen guest instances
  12.310 -
  12.311 -xm full list of subcommands:
  12.312 -
  12.313 -  Domain Commands:
  12.314 -   """ + help_spacer.join(map(commandToHelp,  domain_commands)) + """
  12.315 +####################################################################
  12.316 +#
  12.317 +#  Help/usage printing functions
  12.318 +#
  12.319 +####################################################################
  12.320  
  12.321 -  Xen Host Commands:
  12.322 -   """ + help_spacer.join(map(commandToHelp,  host_commands)) + """
  12.323 -
  12.324 -  Scheduler Commands:
  12.325 -   """ + help_spacer.join(map(commandToHelp,  scheduler_commands)) + """
  12.326 -
  12.327 -  Virtual Device Commands:
  12.328 -   """  + help_spacer.join(map(commandToHelp, device_commands)) + """
  12.329 -
  12.330 -  Vnet commands:
  12.331 -   """ + help_spacer.join(map(commandToHelp,  vnet_commands)) + """
  12.332 -
  12.333 -  Access Control commands:
  12.334 -   """ + help_spacer.join(map(commandToHelp,  acm_commands)) + """
  12.335 +def cmdHelp(cmd):
  12.336 +    """Print help for a specific subcommand."""
  12.337 +    
  12.338 +    try:
  12.339 +        args, desc = SUBCOMMAND_HELP[cmd]
  12.340 +    except KeyError:
  12.341 +        shortHelp()
  12.342 +        return
  12.343 +    
  12.344 +    print 'Usage: xm %s %s' % (cmd, args)
  12.345 +    print
  12.346 +    print desc
  12.347 +    
  12.348 +    try:
  12.349 +        # If options help message is defined, print this.
  12.350 +        for shortopt, longopt, desc in SUBCOMMAND_OPTIONS[cmd]:
  12.351 +            if shortopt and longopt:
  12.352 +                optdesc = '%s, %s' % (shortopt, longopt)
  12.353 +            elif shortopt:
  12.354 +                optdesc = shortopt
  12.355 +            elif longopt:
  12.356 +                optdesc = longopt
  12.357  
  12.358 -<DomName> can be substituted for <DomId> in xm subcommands.
  12.359 -
  12.360 -For a short list of subcommands run 'xm help'
  12.361 -For more help on xm see the xm(1) man page
  12.362 -For more help on xm create, see the xmdomain.cfg(5) man page"""
  12.363 +            wrapped_desc = wrap(desc, 43)   
  12.364 +            print '  %-30s %-43s' % (optdesc, wrapped_desc[0])
  12.365 +            for line in wrapped_desc[1:]:
  12.366 +                print ' ' * 33 + line
  12.367 +        print
  12.368 +    except KeyError:
  12.369 +        # if the command is an external module, we grab usage help
  12.370 +        # from the module itself.
  12.371 +        if cmd in IMPORTED_COMMANDS:
  12.372 +            try:
  12.373 +                cmd_module =  __import__(cmd, globals(), locals(), 'xen.xm')
  12.374 +                cmd_usage = getattr(cmd_module, "help", None)
  12.375 +                if cmd_usage:
  12.376 +                    print cmd_usage()
  12.377 +            except ImportError:
  12.378 +                pass
  12.379 +        
  12.380 +def shortHelp():
  12.381 +    """Print out generic help when xm is called without subcommand."""
  12.382 +    
  12.383 +    print USAGE_HELP
  12.384 +    print 'Common \'xm\' commands:\n'
  12.385 +    
  12.386 +    for command in common_commands:
  12.387 +        try:
  12.388 +            args, desc = SUBCOMMAND_HELP[command]
  12.389 +        except KeyError:
  12.390 +            continue
  12.391 +        wrapped_desc = wrap(desc, 50)
  12.392 +        print ' %-20s %-50s' % (command, wrapped_desc[0])
  12.393 +        for line in wrapped_desc[1:]:
  12.394 +            print ' ' * 22 + line
  12.395  
  12.396 -# array for xm help <command>
  12.397 -help = {
  12.398 -    "--long": longhelp
  12.399 -    }
  12.400 +    print
  12.401 +    print USAGE_FOOTER
  12.402 +    print 'For a complete list of subcommands run \'xm help\'.'
  12.403 +    
  12.404 +def longHelp():
  12.405 +    """Print out full help when xm is called with xm --help or xm help"""
  12.406 +    
  12.407 +    print USAGE_HELP
  12.408 +    print 'xm full list of subcommands:\n'
  12.409 +    
  12.410 +    for command in all_commands:
  12.411 +        try:
  12.412 +            args, desc = SUBCOMMAND_HELP[command]
  12.413 +        except KeyError:
  12.414 +            continue
  12.415  
  12.416 -for command in all_commands:
  12.417 -    # create is handled specially
  12.418 -    if (command != 'create'):
  12.419 -        help[command] = commandToHelp(command)
  12.420 +        wrapped_desc = wrap(desc, 50)
  12.421 +        print ' %-20s %-50s' % (command, wrapped_desc[0])
  12.422 +        for line in wrapped_desc[1:]:
  12.423 +            print ' ' * 22 + line        
  12.424 +
  12.425 +    print
  12.426 +    print USAGE_FOOTER        
  12.427 +
  12.428 +def usage(cmd = None):
  12.429 +    """ Print help usage information and exits """
  12.430 +    if cmd:
  12.431 +        cmdHelp(cmd)
  12.432 +    else:
  12.433 +        shortHelp()
  12.434 +    sys.exit(1)
  12.435  
  12.436  
  12.437  ####################################################################
  12.438 @@ -298,7 +389,7 @@ def arg_check(args, name, lo, hi = -1):
  12.439      if hi == -1:
  12.440          if n != lo:
  12.441              err("'xm %s' requires %d argument%s.\n" % (name, lo,
  12.442 -                                                       lo > 1 and 's' or ''))
  12.443 +                                                       lo == 1 and '' or 's'))
  12.444              usage(name)
  12.445      else:
  12.446          if n < lo or n > hi:
  12.447 @@ -345,14 +436,19 @@ def err(msg):
  12.448  def xm_save(args):
  12.449      arg_check(args, "save", 2)
  12.450  
  12.451 -    dom = args[0] # TODO: should check if this exists
  12.452 +    try:
  12.453 +        dominfo = parse_doms_info(server.xend.domain(args[0]))
  12.454 +    except xmlrpclib.Fault, ex:
  12.455 +        raise ex
  12.456 +    
  12.457 +    domid = dominfo['domid']
  12.458      savefile = os.path.abspath(args[1])
  12.459  
  12.460      if not os.access(os.path.dirname(savefile), os.W_OK):
  12.461          err("xm save: Unable to create file %s" % savefile)
  12.462          sys.exit(1)
  12.463      
  12.464 -    server.xend.domain.save(dom, savefile)
  12.465 +    server.xend.domain.save(domid, savefile)
  12.466      
  12.467  def xm_restore(args):
  12.468      arg_check(args, "restore", 1)
  12.469 @@ -366,9 +462,9 @@ def xm_restore(args):
  12.470      server.xend.domain.restore(savefile)
  12.471  
  12.472  
  12.473 -def getDomains(domain_names):
  12.474 +def getDomains(domain_names, full = 0):
  12.475      if domain_names:
  12.476 -        return map(server.xend.domain, domain_names)
  12.477 +        return [server.xend.domain(dom) for dom in domain_names]
  12.478      else:
  12.479          return server.xend.domains(1)
  12.480  
  12.481 @@ -378,9 +474,11 @@ def xm_list(args):
  12.482      show_vcpus = 0
  12.483      show_labels = 0
  12.484      try:
  12.485 -        (options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus','label'])
  12.486 +        (options, params) = getopt.gnu_getopt(args, 'lv',
  12.487 +                                              ['long','vcpus','label'])
  12.488      except getopt.GetoptError, opterr:
  12.489          err(opterr)
  12.490 +        usage('list')
  12.491          sys.exit(1)
  12.492      
  12.493      for (k, v) in options:
  12.494 @@ -397,7 +495,7 @@ def xm_list(args):
  12.495          xm_vcpu_list(params)
  12.496          return
  12.497  
  12.498 -    doms = getDomains(params)
  12.499 +    doms = getDomains(params, use_long)
  12.500  
  12.501      if use_long:
  12.502          map(PrettyPrint.prettyprint, doms)
  12.503 @@ -412,7 +510,7 @@ def parse_doms_info(info):
  12.504          return t(sxp.child_value(info, n, d))
  12.505      
  12.506      return {
  12.507 -        'dom'      : get_info('domid',        int,   -1),
  12.508 +        'domid'    : get_info('domid',        int,   -1),
  12.509          'name'     : get_info('name',         str,   '??'),
  12.510          'mem'      : get_info('memory',       int,   0),
  12.511          'vcpus'    : get_info('online_vcpus', int,   0),
  12.512 @@ -428,7 +526,7 @@ def parse_sedf_info(info):
  12.513          return t(sxp.child_value(info, n, d))
  12.514  
  12.515      return {
  12.516 -        'dom'      : get_info('domain',        int,   -1),
  12.517 +        'domid'    : get_info('domid',         int,   -1),
  12.518          'period'   : get_info('period',        int,   -1),
  12.519          'slice'    : get_info('slice',         int,   -1),
  12.520          'latency'  : get_info('latency',       int,   -1),
  12.521 @@ -436,34 +534,40 @@ def parse_sedf_info(info):
  12.522          'weight'   : get_info('weight',        int,   -1),
  12.523          }
  12.524  
  12.525 -
  12.526  def xm_brief_list(doms):
  12.527 -    print 'Name                              ID Mem(MiB) VCPUs State  Time(s)'
  12.528 -    for dom in doms:
  12.529 -        d = parse_doms_info(dom)
  12.530 -        print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f" % d)
  12.531 -
  12.532 -
  12.533 -def xm_label_list(doms):
  12.534 -    output = []
  12.535 -    print 'Name                              ID Mem(MiB) VCPUs State  Time(s)  Label'
  12.536 +    print '%-40s %3s %8s %5s %5s %9s' % \
  12.537 +          ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)')
  12.538 +    
  12.539 +    format = "%(name)-40s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s " \
  12.540 +             "%(cpu_time)8.1f"
  12.541 +    
  12.542      for dom in doms:
  12.543          d = parse_doms_info(dom)
  12.544 -        l = "%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f  " % d
  12.545 +        print format % d
  12.546 +
  12.547 +def xm_label_list(doms):
  12.548 +    print '%-32s %3s %8s %5s %5s %9s %-8s' % \
  12.549 +          ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)', 'Label')
  12.550 +    
  12.551 +    output = []
  12.552 +    format = '%(name)-32s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s ' \
  12.553 +             '%(cpu_time)8.1f %(seclabel)9s'
  12.554 +    
  12.555 +    for dom in doms:
  12.556 +        d = parse_doms_info(dom)
  12.557          if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
  12.558 -            if d['seclabel']:
  12.559 -                line = (l, d['seclabel'])
  12.560 -            else:
  12.561 -                line = (l, "ERROR")
  12.562 +            if not d['seclabel']:
  12.563 +                d['seclabel'] = 'ERROR'
  12.564          elif security.active_policy in ['DEFAULT']:
  12.565 -            line = (l, "DEFAULT")
  12.566 +            d['seclabel'] = 'DEFAULT'
  12.567          else:
  12.568 -            line = (l, "INACTIVE")
  12.569 -        output.append(line)
  12.570 +            d['seclabel'] = 'INACTIVE'
  12.571 +        output.append((format % d, d['seclabel']))
  12.572 +        
  12.573      #sort by labels
  12.574      output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
  12.575 -    for l in output:
  12.576 -        print l[0] + l[1]
  12.577 +    for line, label in output:
  12.578 +        print line
  12.579  
  12.580  
  12.581  def xm_vcpu_list(args):
  12.582 @@ -474,7 +578,11 @@ def xm_vcpu_list(args):
  12.583          doms = server.xend.domains(False)
  12.584          dominfo = map(server.xend.domain.getVCPUInfo, doms)
  12.585  
  12.586 -    print 'Name                              ID  VCPU  CPU  State  Time(s)  CPU Affinity'
  12.587 +    print '%-32s %3s %5s %5s %5s %9s %s' % \
  12.588 +          ('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
  12.589 +
  12.590 +    format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \
  12.591 +             ' %(cpu_time)8.1f %(cpumap)s'
  12.592  
  12.593      for dom in dominfo:
  12.594          def get_info(n):
  12.595 @@ -568,10 +676,7 @@ def xm_vcpu_list(args):
  12.596                  c = "-"
  12.597                  s = "--p"
  12.598  
  12.599 -            print (
  12.600 -                "%(name)-32s %(domid)3d  %(number)4d  %(c)3s   %(s)-3s   %(cpu_time)7.1f  %(cpumap)s" %
  12.601 -                locals())
  12.602 -
  12.603 +            print format % locals()
  12.604  
  12.605  def xm_reboot(args):
  12.606      arg_check(args, "reboot", 1, 3)
  12.607 @@ -634,31 +739,31 @@ def xm_dump_core(args):
  12.608  
  12.609  def xm_rename(args):
  12.610      arg_check(args, "rename", 2)
  12.611 -
  12.612 +        
  12.613      server.xend.domain.setName(args[0], args[1])
  12.614  
  12.615 -def xm_subcommand(command, args):
  12.616 +def xm_importcommand(command, args):
  12.617      cmd = __import__(command, globals(), locals(), 'xen.xm')
  12.618      cmd.main([command] + args)
  12.619  
  12.620  
  12.621  #############################################################
  12.622  
  12.623 -def cpu_make_map(cpulist):
  12.624 -    cpus = []
  12.625 -    for c in cpulist.split(','):
  12.626 -        if c.find('-') != -1:
  12.627 -            (x,y) = c.split('-')
  12.628 -            for i in range(int(x),int(y)+1):
  12.629 -                cpus.append(int(i))
  12.630 -        else:
  12.631 -            cpus.append(int(c))
  12.632 -    cpus.sort()
  12.633 -    return cpus
  12.634 -
  12.635  def xm_vcpu_pin(args):
  12.636      arg_check(args, "vcpu-pin", 3)
  12.637  
  12.638 +    def cpu_make_map(cpulist):
  12.639 +        cpus = []
  12.640 +        for c in cpulist.split(','):
  12.641 +            if c.find('-') != -1:
  12.642 +                (x,y) = c.split('-')
  12.643 +                for i in range(int(x),int(y)+1):
  12.644 +                    cpus.append(int(i))
  12.645 +            else:
  12.646 +                cpus.append(int(c))
  12.647 +        cpus.sort()
  12.648 +        return cpus
  12.649 +
  12.650      dom  = args[0]
  12.651      vcpu = int(args[1])
  12.652      cpumap = cpu_make_map(args[2])
  12.653 @@ -719,11 +824,12 @@ def xm_sched_sedf(args):
  12.654          info['period']  = ns_to_ms(info['period'])
  12.655          info['slice']   = ns_to_ms(info['slice'])
  12.656          info['latency'] = ns_to_ms(info['latency'])
  12.657 -        print( ("%(name)-32s %(dom)3d %(period)9.1f %(slice)9.1f" +
  12.658 +        print( ("%(name)-32s %(domid)3d %(period)9.1f %(slice)9.1f" +
  12.659                  " %(latency)7.1f %(extratime)6d %(weight)6d") % info)
  12.660  
  12.661      def domid_match(domid, info):
  12.662 -        return domid is None or domid == info['name'] or domid == str(info['dom'])
  12.663 +        return domid is None or domid == info['name'] or \
  12.664 +               domid == str(info['domid'])
  12.665  
  12.666      # we want to just display current info if no parameters are passed
  12.667      if len(args) == 0:
  12.668 @@ -757,20 +863,25 @@ def xm_sched_sedf(args):
  12.669          elif k in ['-w', '--weight']:
  12.670              opts['weight'] = v
  12.671  
  12.672 +    doms = filter(lambda x : domid_match(domid, x),
  12.673 +                        [parse_doms_info(dom) for dom in getDomains("")])
  12.674 +
  12.675      # print header if we aren't setting any parameters
  12.676      if len(opts.keys()) == 0:
  12.677 -        print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s'%('Name','ID','Period(ms)',
  12.678 -                                                     'Slice(ms)', 'Lat(ms)',
  12.679 -                                                     'Extra','Weight')
  12.680 -
  12.681 -    doms = filter(lambda x : domid_match(domid, x),
  12.682 -                        [parse_doms_info(dom) for dom in getDomains("")])
  12.683 +        print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s' % \
  12.684 +              ('Name','ID','Period(ms)', 'Slice(ms)', 'Lat(ms)',
  12.685 +               'Extra','Weight')
  12.686 +    
  12.687      for d in doms:
  12.688          # fetch current values so as not to clobber them
  12.689 -        sedf_info = \
  12.690 -            parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom']))
  12.691 +        try:
  12.692 +            sedf_raw = server.xend.domain.cpu_sedf_get(d['domid'])
  12.693 +        except xmlrpclib.Fault:
  12.694 +            # domain does not support sched-sedf?
  12.695 +            sedf_raw = {}
  12.696 +
  12.697 +        sedf_info = parse_sedf_info(sedf_raw)
  12.698          sedf_info['name'] = d['name']
  12.699 -
  12.700          # update values in case of call to set
  12.701          if len(opts.keys()) > 0:
  12.702              for k in opts.keys():
  12.703 @@ -780,7 +891,7 @@ def xm_sched_sedf(args):
  12.704              v = map(int, [sedf_info['period'], sedf_info['slice'],
  12.705                            sedf_info['latency'],sedf_info['extratime'], 
  12.706                            sedf_info['weight']])
  12.707 -            rv = server.xend.domain.cpu_sedf_set(d['dom'], *v)
  12.708 +            rv = server.xend.domain.cpu_sedf_set(d['domid'], *v)
  12.709              if int(rv) != 0:
  12.710                  err("Failed to set sedf parameters (rv=%d)."%(rv))
  12.711  
  12.712 @@ -789,17 +900,14 @@ def xm_sched_sedf(args):
  12.713              print_sedf(sedf_info)
  12.714  
  12.715  def xm_sched_credit(args):
  12.716 -    usage_msg = """sched-credit:     Set or get credit scheduler parameters
  12.717 - Usage:
  12.718 -
  12.719 -        sched-credit -d domain [-w weight] [-c cap]
  12.720 -    """
  12.721 +    """Get/Set options for Credit Scheduler."""
  12.722 +    
  12.723      try:
  12.724 -        opts, args = getopt.getopt(args[0:], "d:w:c:",
  12.725 +        opts, params = getopt.getopt(args, "d:w:c:",
  12.726              ["domain=", "weight=", "cap="])
  12.727 -    except getopt.GetoptError:
  12.728 -        # print help information and exit:
  12.729 -        print usage_msg
  12.730 +    except getopt.GetoptError, opterr:
  12.731 +        err(opterr)
  12.732 +        usage('sched-credit')
  12.733          sys.exit(1)
  12.734  
  12.735      domain = None
  12.736 @@ -816,15 +924,16 @@ def xm_sched_credit(args):
  12.737  
  12.738      if domain is None:
  12.739          # place holder for system-wide scheduler parameters
  12.740 -        print usage_msg
  12.741 +        err("No domain given.")
  12.742 +        usage('sched-credit')
  12.743          sys.exit(1)
  12.744  
  12.745      if weight is None and cap is None:
  12.746          print server.xend.domain.sched_credit_get(domain)
  12.747      else:
  12.748 -        err = server.xend.domain.sched_credit_set(domain, weight, cap)
  12.749 -        if err != 0:
  12.750 -            print err
  12.751 +        result = server.xend.domain.sched_credit_set(domain, weight, cap)
  12.752 +        if result != 0:
  12.753 +            err(str(result))
  12.754  
  12.755  def xm_info(args):
  12.756      arg_check(args, "info", 0)
  12.757 @@ -843,6 +952,8 @@ def xm_console(args):
  12.758      dom = args[0]
  12.759      info = server.xend.domain(dom)
  12.760      domid = int(sxp.child_value(info, 'domid', '-1'))
  12.761 +    if domid == -1:
  12.762 +        raise Exception("Domain is not started")
  12.763      console.execConsole(domid)
  12.764  
  12.765  def xm_uptime(args):
  12.766 @@ -920,8 +1031,11 @@ its contents if the [-c|--clear] flag is
  12.767      myargs = args
  12.768      myargs.insert(0, 'dmesg')
  12.769      gopts.parse(myargs)
  12.770 -    if not (1 <= len(myargs) <= 2):
  12.771 +    
  12.772 +    if len(myargs) not in (1, 2):
  12.773          err('Invalid arguments: ' + str(myargs))
  12.774 +        usage('dmesg')
  12.775 +        sys.exit(1)
  12.776  
  12.777      if not gopts.vals.clear:
  12.778          print server.xend.node.dmesg.info()
  12.779 @@ -939,7 +1053,7 @@ def xm_serve(args):
  12.780      from fcntl import fcntl, F_SETFL
  12.781      
  12.782      s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  12.783 -    s.connect(xen.xend.XendClient.XML_RPC_SOCKET)
  12.784 +    s.connect(XendClient.XML_RPC_SOCKET)
  12.785      fcntl(sys.stdin, F_SETFL, os.O_NONBLOCK)
  12.786  
  12.787      while True:
  12.788 @@ -1085,7 +1199,7 @@ def parse_block_configuration(args):
  12.789          cls = 'tap'
  12.790      else:
  12.791          cls = 'vbd'
  12.792 -        
  12.793 +
  12.794      vbd = [cls,
  12.795             ['uname', args[1]],
  12.796             ['dev',   args[2]],
  12.797 @@ -1094,19 +1208,12 @@ def parse_block_configuration(args):
  12.798          vbd.append(['backend', args[4]])
  12.799  
  12.800      # verify that policy permits attaching this resource
  12.801 -    try:
  12.802 -        if security.on():
  12.803 -            dominfo = server.xend.domain(dom)
  12.804 -            label = security.get_security_printlabel(dominfo)
  12.805 -        else:
  12.806 -            label = None
  12.807 +    if security.on():
  12.808 +        dominfo = server.xend.domain(dom)
  12.809 +        label = security.get_security_printlabel(dominfo)
  12.810 +    else:
  12.811 +        label = None
  12.812          security.res_security_check(args[1], label)
  12.813 -    except security.ACMError, e:
  12.814 -        print e.value
  12.815 -        sys.exit(1)
  12.816 -    except:
  12.817 -        traceback.print_exc(limit=1)
  12.818 -        sys.exit(1)
  12.819  
  12.820      return (dom, vbd)
  12.821  
  12.822 @@ -1206,10 +1313,10 @@ commands = {
  12.823      "domid": xm_domid,
  12.824      "domname": xm_domname,
  12.825      "dump-core": xm_dump_core,
  12.826 +    "reboot": xm_reboot,    
  12.827      "rename": xm_rename,
  12.828      "restore": xm_restore,
  12.829      "save": xm_save,
  12.830 -    "reboot": xm_reboot,
  12.831      "shutdown": xm_shutdown,
  12.832      "uptime": xm_uptime,
  12.833      "list": xm_list,
  12.834 @@ -1249,24 +1356,24 @@ commands = {
  12.835      }
  12.836  
  12.837  ## The commands supported by a separate argument parser in xend.xm.
  12.838 -subcommands = [
  12.839 +IMPORTED_COMMANDS = [
  12.840      'create',
  12.841      'migrate',
  12.842      'sysrq',
  12.843      'labels',
  12.844      'addlabel',
  12.845 +    'cfgbootpolicy',
  12.846 +    'makepolicy',
  12.847 +    'loadpolicy',
  12.848 +    'dumppolicy'
  12.849      'rmlabel',
  12.850      'getlabel',
  12.851      'dry-run',
  12.852      'resources',
  12.853 -    'cfgbootpolicy',
  12.854 -    'makepolicy',
  12.855 -    'loadpolicy',
  12.856 -    'dumppolicy'
  12.857      ]
  12.858  
  12.859 -for c in subcommands:
  12.860 -    commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
  12.861 +for c in IMPORTED_COMMANDS:
  12.862 +    commands[c] = eval('lambda args: xm_importcommand("%s", args)' % c)
  12.863  
  12.864  aliases = {
  12.865      "balloon": "mem-set",
  12.866 @@ -1284,11 +1391,18 @@ def xm_lookup_cmd(cmd):
  12.867      elif aliases.has_key(cmd):
  12.868          deprecated(cmd,aliases[cmd])
  12.869          return commands[aliases[cmd]]
  12.870 +    elif cmd == 'help':
  12.871 +        longHelp()
  12.872 +        sys.exit(0)
  12.873      else:
  12.874 -        if len( cmd ) > 1:
  12.875 -            matched_commands = filter( lambda (command, func): command[ 0:len(cmd) ] == cmd, commands.iteritems() )
  12.876 -            if len( matched_commands ) == 1:
  12.877 -		        return matched_commands[0][1]
  12.878 +        # simulate getopt's prefix matching behaviour
  12.879 +        if len(cmd) > 1:
  12.880 +            same_prefix_cmds = [commands[c] for c in commands.keys() \
  12.881 +                                if c[:len(cmd)] == cmd]
  12.882 +            # only execute if there is only 1 match
  12.883 +            if len(same_prefix_cmds) == 1:
  12.884 +                return same_prefix_cmds[0]
  12.885 +            
  12.886          err('Sub Command %s not found!' % cmd)
  12.887          usage()
  12.888  
  12.889 @@ -1296,27 +1410,17 @@ def deprecated(old,new):
  12.890      print >>sys.stderr, (
  12.891          "Command %s is deprecated.  Please use xm %s instead." % (old, new))
  12.892  
  12.893 -def usage(cmd=None):
  12.894 -    if cmd == 'create':
  12.895 -        mycmd = xm_lookup_cmd(cmd)
  12.896 -        mycmd( ['--help'] )
  12.897 -        sys.exit(1)
  12.898 -    if help.has_key(cmd):
  12.899 -        print "   " + help[cmd]
  12.900 -    else:
  12.901 -        print shorthelp
  12.902 -    sys.exit(1)
  12.903 -
  12.904  def main(argv=sys.argv):
  12.905      if len(argv) < 2:
  12.906          usage()
  12.907 -    
  12.908 -    if re.compile('-*help').match(argv[1]):
  12.909 -	if len(argv) > 2:
  12.910 -	    usage(argv[2])
  12.911 -	else:
  12.912 -	    usage()
  12.913 -	sys.exit(0)
  12.914 +
  12.915 +    # intercept --help and output our own help
  12.916 +    if '--help' in argv[1:]:
  12.917 +        if '--help' == argv[1]:
  12.918 +            longHelp()
  12.919 +        else:
  12.920 +            usage(argv[1])
  12.921 +        sys.exit(0)
  12.922  
  12.923      cmd = xm_lookup_cmd(argv[1])
  12.924  
  12.925 @@ -1329,9 +1433,9 @@ def main(argv=sys.argv):
  12.926                  usage()
  12.927          except socket.error, ex:
  12.928              if os.geteuid() != 0:
  12.929 -                err("Most commands need root access.  Please try again as root.")
  12.930 +                err("Most commands need root access. Please try again as root.")
  12.931              else:
  12.932 -                err("Error connecting to xend: %s.  Is xend running?" % ex[1])
  12.933 +                err("Unable to connect to xend: %s. Is xend running?" % ex[1])
  12.934              sys.exit(1)
  12.935          except KeyboardInterrupt:
  12.936              print "Interrupted."
  12.937 @@ -1340,16 +1444,16 @@ def main(argv=sys.argv):
  12.938              if os.geteuid() != 0:
  12.939                  err("Most commands need root access.  Please try again as root.")
  12.940              else:
  12.941 -                err("Error connecting to xend: %s." % ex[1])
  12.942 +                err("Unable to connect to xend: %s." % ex[1])
  12.943              sys.exit(1)
  12.944          except SystemExit:
  12.945              sys.exit(1)
  12.946          except xmlrpclib.Fault, ex:
  12.947 -            if ex.faultCode == xen.xend.XendClient.ERROR_INVALID_DOMAIN:
  12.948 -                print  >>sys.stderr, (
  12.949 -                    "Error: the domain '%s' does not exist." % ex.faultString)
  12.950 +            if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
  12.951 +                err("Domain '%s' does not exist." % ex.faultString)
  12.952              else:
  12.953 -                print  >>sys.stderr, "Error: %s" % ex.faultString
  12.954 +                err(ex.faultString)
  12.955 +            usage(argv[1])
  12.956              sys.exit(1)
  12.957          except xmlrpclib.ProtocolError, ex:
  12.958              if ex.errcode == -1:
  12.959 @@ -1364,6 +1468,10 @@ def main(argv=sys.argv):
  12.960          except (ValueError, OverflowError):
  12.961              err("Invalid argument.")
  12.962              usage(argv[1])
  12.963 +        except OptionError, e:
  12.964 +            err(str(e))
  12.965 +            usage(argv[1])
  12.966 +            print e.usage()
  12.967          except:
  12.968              print "Unexpected error:", sys.exc_info()[0]
  12.969              print
    13.1 --- a/tools/python/xen/xm/makepolicy.py	Fri Sep 22 13:06:05 2006 +0100
    13.2 +++ b/tools/python/xen/xm/makepolicy.py	Fri Sep 22 13:06:20 2006 +0100
    13.3 @@ -20,7 +20,7 @@
    13.4  import sys
    13.5  import traceback
    13.6  from xen.util.security import ACMError, err, make_policy
    13.7 -
    13.8 +from xen.xm.opts import OptionError
    13.9  
   13.10  def usage():
   13.11      print "\nUsage: xm makepolicy <policy>\n"
   13.12 @@ -29,13 +29,12 @@ def usage():
   13.13      err("Usage")
   13.14  
   13.15  
   13.16 +def main(argv):
   13.17 +    if len(argv) != 2:
   13.18 +        raise OptionError('No XML policy file specified')
   13.19  
   13.20 -def main(argv):
   13.21      try:
   13.22 -        if len(argv) != 2:
   13.23 -            usage()
   13.24          make_policy(argv[1])
   13.25 -
   13.26      except ACMError:
   13.27          sys.exit(-1)
   13.28      except:
   13.29 @@ -43,7 +42,6 @@ def main(argv):
   13.30          sys.exit(-1)
   13.31  
   13.32  
   13.33 -
   13.34  if __name__ == '__main__':
   13.35      main(sys.argv)
   13.36  
    14.1 --- a/tools/python/xen/xm/migrate.py	Fri Sep 22 13:06:05 2006 +0100
    14.2 +++ b/tools/python/xen/xm/migrate.py	Fri Sep 22 13:06:20 2006 +0100
    14.3 @@ -46,19 +46,17 @@ gopts.opt('resource', short='r', val='MB
    14.4            fn=set_int, default=0,
    14.5            use="Set level of resource usage for migration.")
    14.6  
    14.7 -def help(argv):
    14.8 -    gopts.argv = argv
    14.9 -    gopts.usage()
   14.10 +def help():
   14.11 +    return str(gopts)
   14.12      
   14.13  def main(argv):
   14.14      opts = gopts
   14.15      args = opts.parse(argv)
   14.16 -    if opts.vals.help:
   14.17 -        opts.usage()
   14.18 -        return
   14.19 +    
   14.20      if len(args) != 2:
   14.21 -        opts.usage()
   14.22 -        sys.exit(1)
   14.23 +        raise OptionError('Invalid number of arguments')
   14.24 +
   14.25      dom = args[0]
   14.26      dst = args[1]
   14.27 -    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, opts.vals.port)
   14.28 +    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource,
   14.29 +                               opts.vals.port)
    15.1 --- a/tools/python/xen/xm/opts.py	Fri Sep 22 13:06:05 2006 +0100
    15.2 +++ b/tools/python/xen/xm/opts.py	Fri Sep 22 13:06:20 2006 +0100
    15.3 @@ -24,6 +24,46 @@ import os.path
    15.4  import sys
    15.5  import types
    15.6  
    15.7 +def wrap(text, width = 70):
    15.8 +    """ Really basic textwrap. Useful because textwrap is not available
    15.9 +    for Python 2.2, and textwrap.wrap ignores newlines in Python 2.3+.
   15.10 +    """
   15.11 +    import string
   15.12 +    
   15.13 +    if len(text) < width:
   15.14 +        return [text]
   15.15 +    
   15.16 +    lines = []
   15.17 +    for line in text.split('\n'):
   15.18 +        line = line.strip()
   15.19 +        if len(line) < width:
   15.20 +            lines.append(line)
   15.21 +            continue
   15.22 +        
   15.23 +        pos = 0
   15.24 +        while pos <= len(line):
   15.25 +            wline = line[pos:pos+width].strip()
   15.26 +            if len(wline) < 2:
   15.27 +                break
   15.28 +            
   15.29 +            if wline[-1] in tuple(string.punctuation):
   15.30 +                pos += width
   15.31 +            else:
   15.32 +                lastword = wline.split()[-1]
   15.33 +                wline = wline[:-len(lastword)]
   15.34 +                pos += width - len(lastword)
   15.35 +            lines.append(wline)
   15.36 +                
   15.37 +    return lines
   15.38 +
   15.39 +class OptionError(Exception):
   15.40 +    """Denotes an error in option parsing."""
   15.41 +    def __init__(self, message, usage = ''):
   15.42 +        self.message = message
   15.43 +        self.usage = usage
   15.44 +    def __str__(self):
   15.45 +        return self.message
   15.46 +
   15.47  class Opt:
   15.48      """An individual option.
   15.49      """
   15.50 @@ -72,7 +112,21 @@ class Opt:
   15.51      def __repr__(self):
   15.52          return self.name + '=' + str(self.specified_val)
   15.53  
   15.54 -    __str__ = __repr__
   15.55 +    def __str__(self):
   15.56 +        """ Formats the option into:
   15.57 +        '-k, --key     description'
   15.58 +        """
   15.59 +        PARAM_WIDTH = 20
   15.60 +        if self.val:
   15.61 +            keys = ', '.join(['%s=%s' % (k, self.val) for k in self.optkeys])
   15.62 +        else:
   15.63 +            keys = ', '.join(self.optkeys)
   15.64 +        desc = wrap(self.use, 55)
   15.65 +        if len(keys) > PARAM_WIDTH:
   15.66 +            desc = [''] + desc
   15.67 +            
   15.68 +        wrapped = ('\n' + ' ' * (PARAM_WIDTH + 1)).join(desc)
   15.69 +        return keys.ljust(PARAM_WIDTH + 1) + wrapped
   15.70  
   15.71      def set(self, value):
   15.72          """Set the option value.
   15.73 @@ -243,7 +297,19 @@ class Opts:
   15.74      def __repr__(self):
   15.75          return '\n'.join(map(str, self.options))
   15.76  
   15.77 -    __str__ = __repr__
   15.78 +    def __str__(self):
   15.79 +        options = [s for s in self.options if s.optkeys[0][0] == '-']
   15.80 +        optvals = [s for s in self.options if s.optkeys[0][0] != '-']
   15.81 +        output = ''
   15.82 +        if options:
   15.83 +            output += '\nOptions:\n\n'
   15.84 +            output += '\n'.join([str(o) for o in options])
   15.85 +            output += '\n'
   15.86 +        if optvals:
   15.87 +            output += '\nValues:\n\n'
   15.88 +            output += '\n'.join([str(o) for o in optvals])
   15.89 +            output += '\n'
   15.90 +        return output
   15.91  
   15.92      def opt(self, name, **args):
   15.93          """Add an option.
   15.94 @@ -338,14 +404,14 @@ class Opts:
   15.95                                                self.short_opts(),
   15.96                                                self.long_opts())
   15.97              except getopt.GetoptError, err:
   15.98 -                self.err(str(err))
   15.99 +                raise OptionError(str(err), self.use)
  15.100 +            #self.err(str(err))
  15.101                  
  15.102              for (k, v) in xvals:
  15.103                  for opt in self.options:
  15.104                      if opt.specify(k, v): break
  15.105                  else:
  15.106 -                    print >>sys.stderr, "Error: Unknown option:", k
  15.107 -                    self.usage()
  15.108 +                    raise OptionError('Unknown option: %s' % k, self.use)
  15.109  
  15.110              if not args:
  15.111                  break
  15.112 @@ -390,10 +456,10 @@ class Opts:
  15.113      def usage(self):
  15.114          print 'Usage: ', self.argv[0], self.use or 'OPTIONS'
  15.115          print
  15.116 -        for opt in self.options:
  15.117 -            opt.show()
  15.118 -            print
  15.119          if self.options:
  15.120 +            for opt in self.options:
  15.121 +                opt.show()
  15.122 +                print
  15.123              print
  15.124  
  15.125      def var_usage(self):
  15.126 @@ -427,7 +493,9 @@ class Opts:
  15.127                  self.load(p, help)
  15.128                  break
  15.129          else:
  15.130 -            self.err('Cannot open config file "%s"' % self.vals.defconfig)
  15.131 +            raise OptionError('Unable to open config file: %s' % \
  15.132 +                              self.vals.defconfig,
  15.133 +                              self.use)
  15.134  
  15.135      def load(self, defconfig, help):
  15.136          """Load a defconfig file. Local variables in the file
  15.137 @@ -478,9 +546,9 @@ def set_false(opt, k, v):
  15.138  def set_bool(opt, k, v):
  15.139      """Set a boolean option.
  15.140      """
  15.141 -    if v in ['yes']:
  15.142 +    if v in ('yes', 'y'):
  15.143          opt.set(1)
  15.144 -    elif v in ['no']:
  15.145 +    elif v in ('no', 'n'):
  15.146          opt.set(0)
  15.147      else:
  15.148          opt.opts.err('Invalid value:' +v)
    16.1 --- a/tools/python/xen/xm/resources.py	Fri Sep 22 13:06:05 2006 +0100
    16.2 +++ b/tools/python/xen/xm/resources.py	Fri Sep 22 13:06:20 2006 +0100
    16.3 @@ -21,13 +21,12 @@
    16.4  import sys
    16.5  from xen.util import dictio
    16.6  from xen.util import security
    16.7 +from xen.xm.opts import OptionError
    16.8  
    16.9 -def usage():
   16.10 -    print "\nUsage: xm resource\n"
   16.11 -    print "  This program lists information for each resource in the"
   16.12 -    print "  global resource label file\n"
   16.13 -    security.err("Usage")
   16.14 -
   16.15 +def help():
   16.16 +    return """Usage: xm resource
   16.17 +    This program lists information for each resource in the
   16.18 +    global resource label file."""
   16.19  
   16.20  def print_resource_data(access_control):
   16.21      """Prints out a resource dictionary to stdout
   16.22 @@ -38,11 +37,16 @@ def print_resource_data(access_control):
   16.23          print "    policy: "+policy
   16.24          print "    label:  "+label
   16.25  
   16.26 -
   16.27  def main (argv):
   16.28 +    if len(argv) > 1:
   16.29 +        raise OptionError("No arguments required")
   16.30 +    
   16.31      try:
   16.32 -        if len(argv) != 1:
   16.33 -            usage()
   16.34 +        filename = security.res_label_filename
   16.35 +        access_control = dictio.dict_read("resources", filename)
   16.36 +    except:
   16.37 +        print "Resource file not found."
   16.38 +        return
   16.39  
   16.40          try:
   16.41              file = security.res_label_filename
   16.42 @@ -52,9 +56,6 @@ def main (argv):
   16.43  
   16.44          print_resource_data(access_control)
   16.45  
   16.46 -    except security.ACMError:
   16.47 -        sys.exit(-1)
   16.48 -
   16.49  if __name__ == '__main__':
   16.50      main(sys.argv)
   16.51  
    17.1 --- a/tools/python/xen/xm/rmlabel.py	Fri Sep 22 13:06:05 2006 +0100
    17.2 +++ b/tools/python/xen/xm/rmlabel.py	Fri Sep 22 13:06:20 2006 +0100
    17.3 @@ -21,15 +21,17 @@
    17.4  import sys, os, re
    17.5  from xen.util import dictio
    17.6  from xen.util import security
    17.7 +from xen.xm.opts import OptionError
    17.8  
    17.9 -def usage():
   17.10 -    print "\nUsage: xm rmlabel dom <configfile>"
   17.11 -    print "       xm rmlabel res <resource>\n"
   17.12 -    print "  This program removes an acm_label entry from the 'configfile'"
   17.13 -    print "  for a domain or from the global resource label file for a"
   17.14 -    print "  resource. If the label does not exist for the given domain or"
   17.15 -    print "  resource, then rmlabel fails.\n"
   17.16 -    security.err("Usage")
   17.17 +def help():
   17.18 +    return """
   17.19 +    Example: xm rmlabel dom <configfile>
   17.20 +             xm rmlabel res <resource>
   17.21 +
   17.22 +    This program removes an acm_label entry from the 'configfile'
   17.23 +    for a domain or from the global resource label file for a
   17.24 +    resource. If the label does not exist for the given domain or
   17.25 +    resource, then rmlabel fails."""
   17.26  
   17.27  
   17.28  def rm_resource_label(resource):
   17.29 @@ -93,23 +95,23 @@ def rm_domain_label(configfile):
   17.30  
   17.31  
   17.32  def main (argv):
   17.33 +
   17.34 +    if len(argv) != 3:
   17.35 +        raise OptionError('Requires 2 arguments')
   17.36 +    
   17.37 +    if argv[1].lower() not in ('dom', 'res'):
   17.38 +        raise OptionError('Unrecognised type argument: %s' % argv[1])
   17.39 +
   17.40      try:
   17.41 -        if len(argv) != 3:
   17.42 -            usage()
   17.43 -
   17.44          if argv[1].lower() == "dom":
   17.45              configfile = argv[2]
   17.46              rm_domain_label(configfile)
   17.47          elif argv[1].lower() == "res":
   17.48              resource = argv[2]
   17.49              rm_resource_label(resource)
   17.50 -        else:
   17.51 -            usage()
   17.52 -
   17.53      except security.ACMError:
   17.54          sys.exit(-1)
   17.55  
   17.56 -
   17.57  if __name__ == '__main__':
   17.58      main(sys.argv)
   17.59  
    18.1 --- a/tools/python/xen/xm/sysrq.py	Fri Sep 22 13:06:05 2006 +0100
    18.2 +++ b/tools/python/xen/xm/sysrq.py	Fri Sep 22 13:06:20 2006 +0100
    18.3 @@ -19,14 +19,12 @@ gopts.opt('help', short='h',
    18.4  def main(argv):
    18.5      opts = gopts
    18.6      args = opts.parse(argv)
    18.7 -    if opts.vals.help:
    18.8 -        opts.usage()
    18.9 -        return
   18.10 -        
   18.11 -    # no options for the moment
   18.12 -    if len(args) != 2:
   18.13 -        opts.usage()
   18.14 -        sys.exit(1)
   18.15 +
   18.16 +    if len(args) < 1:
   18.17 +        raise OptionError('Missing domain argument')
   18.18 +    if len(args) < 2:
   18.19 +        raise OptionError('Missing sysrq character')
   18.20 +
   18.21      dom = args[0]
   18.22      req = ord(args[1][0])
   18.23      server.xend.domain.send_sysrq(dom, req)
    19.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Sep 22 13:06:05 2006 +0100
    19.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Sep 22 13:06:20 2006 +0100
    19.3 @@ -259,6 +259,17 @@ static int svm_paging_enabled(struct vcp
    19.4      return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
    19.5  }
    19.6  
    19.7 +static int svm_pae_enabled(struct vcpu *v)
    19.8 +{
    19.9 +    unsigned long cr4;
   19.10 +
   19.11 +    if(!svm_paging_enabled(v))
   19.12 +        return 0;
   19.13 +
   19.14 +    cr4 = v->arch.hvm_svm.cpu_shadow_cr4;
   19.15 +
   19.16 +    return (cr4 & X86_CR4_PAE);
   19.17 +}
   19.18  
   19.19  #define IS_CANO_ADDRESS(add) 1
   19.20  
   19.21 @@ -865,6 +876,7 @@ int start_svm(void)
   19.22      hvm_funcs.realmode = svm_realmode;
   19.23      hvm_funcs.paging_enabled = svm_paging_enabled;
   19.24      hvm_funcs.long_mode_enabled = svm_long_mode_enabled;
   19.25 +    hvm_funcs.pae_enabled = svm_pae_enabled;
   19.26      hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
   19.27      hvm_funcs.instruction_length = svm_instruction_length;
   19.28      hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
    20.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Sep 22 13:06:05 2006 +0100
    20.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Sep 22 13:06:20 2006 +0100
    20.3 @@ -746,6 +746,7 @@ static void vmx_setup_hvm_funcs(void)
    20.4      hvm_funcs.realmode = vmx_realmode;
    20.5      hvm_funcs.paging_enabled = vmx_paging_enabled;
    20.6      hvm_funcs.long_mode_enabled = vmx_long_mode_enabled;
    20.7 +    hvm_funcs.pae_enabled = vmx_pae_enabled;
    20.8      hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
    20.9      hvm_funcs.instruction_length = vmx_instruction_length;
   20.10      hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
    21.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Sep 22 13:06:05 2006 +0100
    21.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Sep 22 13:06:20 2006 +0100
    21.3 @@ -2343,7 +2343,7 @@ void sh_update_paging_modes(struct vcpu 
    21.4              }
    21.5              else
    21.6  #endif
    21.7 -                if ( hvm_get_guest_ctrl_reg(v, 4) & X86_CR4_PAE )
    21.8 +                if ( hvm_pae_enabled(v) )
    21.9                  {
   21.10  #if CONFIG_PAGING_LEVELS >= 3
   21.11                      // 32-bit PAE mode guest...
    22.1 --- a/xen/include/asm-x86/hvm/hvm.h	Fri Sep 22 13:06:05 2006 +0100
    22.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Fri Sep 22 13:06:20 2006 +0100
    22.3 @@ -57,6 +57,7 @@ struct hvm_function_table {
    22.4      int (*realmode)(struct vcpu *v);
    22.5      int (*paging_enabled)(struct vcpu *v);
    22.6      int (*long_mode_enabled)(struct vcpu *v);
    22.7 +    int (*pae_enabled)(struct vcpu *v);
    22.8      int (*guest_x86_mode)(struct vcpu *v);
    22.9      int (*instruction_length)(struct vcpu *v);
   22.10      unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
   22.11 @@ -146,6 +147,12 @@ hvm_long_mode_enabled(struct vcpu *v)
   22.12      return hvm_funcs.long_mode_enabled(v);
   22.13  }
   22.14  
   22.15 + static inline int
   22.16 +hvm_pae_enabled(struct vcpu *v)
   22.17 +{
   22.18 +    return hvm_funcs.pae_enabled(v);
   22.19 +}
   22.20 +
   22.21  static inline int
   22.22  hvm_guest_x86_mode(struct vcpu *v)
   22.23  {
    23.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Sep 22 13:06:05 2006 +0100
    23.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Sep 22 13:06:20 2006 +0100
    23.3 @@ -39,6 +39,9 @@ enum {
    23.4  #define VMX_LONG_GUEST(ed)    \
    23.5    (test_bit(VMX_CPU_STATE_LMA_ENABLED, &ed->arch.hvm_vmx.cpu_state))
    23.6  
    23.7 +#define VMX_PAE_GUEST(ed)       \
    23.8 +  (test_bit(VMX_CPU_STATE_PAE_ENABLED, &ed->arch.hvm_vmx.cpu_state))
    23.9 +
   23.10  struct vmcs_struct {
   23.11      u32 vmcs_revision_id;
   23.12      unsigned char data [0]; /* vmcs size is read from MSR */
    24.1 --- a/xen/include/asm-x86/hvm/vmx/vmx.h	Fri Sep 22 13:06:05 2006 +0100
    24.2 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h	Fri Sep 22 13:06:20 2006 +0100
    24.3 @@ -418,6 +418,12 @@ static inline int vmx_long_mode_enabled(
    24.4      return VMX_LONG_GUEST(current);
    24.5  }
    24.6  
    24.7 +static inline int vmx_pae_enabled(struct vcpu *v)
    24.8 +{
    24.9 +    ASSERT(v == current);
   24.10 +    return VMX_PAE_GUEST(current);
   24.11 +}
   24.12 +
   24.13  /* Works only for vcpu == current */
   24.14  static inline int vmx_realmode(struct vcpu *v)
   24.15  {