ia64/xen-unstable

changeset 11591:cdd03c7ec8d3

Merge.
author Steven Smith <ssmith@xensource.com>
date Fri Sep 22 17:22:18 2006 +0100 (2006-09-22)
parents 08a582a98471 92bfc59726a4
children bdace8da6319
files tools/python/xen/xm/sysrq.py
line diff
     1.1 --- a/tools/firmware/vmxassist/machine.h	Fri Sep 22 17:21:52 2006 +0100
     1.2 +++ b/tools/firmware/vmxassist/machine.h	Fri Sep 22 17:22:18 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 17:21:52 2006 +0100
     2.2 +++ b/tools/firmware/vmxassist/vm86.c	Fri Sep 22 17:22:18 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/xend/XendDomainInfo.py	Fri Sep 22 17:21:52 2006 +0100
     3.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Sep 22 17:22:18 2006 +0100
     3.3 @@ -596,6 +596,8 @@ class XendDomainInfo:
     3.4              if self.info['memory'] == 0:
     3.5                  if self.infoIsSet('mem_kb'):
     3.6                      self.info['memory'] = (self.info['mem_kb'] + 1023) / 1024
     3.7 +            if self.info['memory'] <= 0:
     3.8 +                raise VmError('Invalid memory size')
     3.9  
    3.10              if self.info['maxmem'] < self.info['memory']:
    3.11                  self.info['maxmem'] = self.info['memory']
    3.12 @@ -986,14 +988,18 @@ class XendDomainInfo:
    3.13                  this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
    3.14                  corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
    3.15                                    self.info['name'], self.domid)
    3.16 +                
    3.17 +            if os.path.isdir(corefile):
    3.18 +                raise XendError("Cannot dump core in a directory: %s" %
    3.19 +                                corefile)
    3.20 +            
    3.21              xc.domain_dumpcore(self.domid, corefile)
    3.22 -
    3.23 -        except:
    3.24 +        except RuntimeError, ex:
    3.25              corefile_incomp = corefile+'-incomplete'
    3.26              os.rename(corefile, corefile_incomp)
    3.27              log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
    3.28                            self.domid, self.info['name'])
    3.29 -
    3.30 +            raise XendError("Failed to dump core: %s" %  str(ex))
    3.31  
    3.32      ## public:
    3.33  
    3.34 @@ -1001,6 +1007,9 @@ class XendDomainInfo:
    3.35          """Set the memory target of this domain.
    3.36          @param target In MiB.
    3.37          """
    3.38 +        if target <= 0:
    3.39 +            raise XendError('Invalid memory size')
    3.40 +        
    3.41          log.debug("Setting memory target of domain %s (%d) to %d MiB.",
    3.42                    self.info['name'], self.domid, target)
    3.43          
    3.44 @@ -1093,15 +1102,16 @@ class XendDomainInfo:
    3.45      ## public:
    3.46  
    3.47      def destroyDevice(self, deviceClass, devid):
    3.48 -	if type(devid) is str:
    3.49 -	    devicePath = '%s/device/%s' % (self.dompath, deviceClass)
    3.50 -	    for entry in xstransact.List(devicePath):
    3.51 -		backend = xstransact.Read('%s/%s' % (devicePath, entry), "backend")
    3.52 -		devName = xstransact.Read(backend, "dev")
    3.53 -		if devName == devid:
    3.54 -		    # We found the integer matching our devid, use it instead
    3.55 -		    devid = entry
    3.56 -        	    break
    3.57 +        if type(devid) is str:
    3.58 +            devicePath = '%s/device/%s' % (self.dompath, deviceClass)
    3.59 +            for entry in xstransact.List(devicePath):
    3.60 +                backend = xstransact.Read('%s/%s' % (devicePath, entry),
    3.61 +                                          "backend")
    3.62 +                devName = xstransact.Read(backend, "dev")
    3.63 +                if devName == devid:
    3.64 +                    # We found the integer matching our devid, use it instead
    3.65 +                    devid = entry
    3.66 +                    break
    3.67          return self.getDeviceController(deviceClass).destroyDevice(devid)
    3.68  
    3.69  
     4.1 --- a/tools/python/xen/xm/addlabel.py	Fri Sep 22 17:21:52 2006 +0100
     4.2 +++ b/tools/python/xen/xm/addlabel.py	Fri Sep 22 17:22:18 2006 +0100
     4.3 @@ -19,19 +19,23 @@
     4.4  
     4.5  """Labeling a domain configuration file or a resoruce.
     4.6  """
     4.7 -import sys, os
     4.8 +import os
     4.9 +import sys
    4.10 +
    4.11  from xen.util import dictio
    4.12  from xen.util import security
    4.13 +from xen.xm.opts import OptionError
    4.14  
    4.15 -def usage():
    4.16 -    print "\nUsage: xm addlabel <label> dom <configfile> [<policy>]"
    4.17 -    print "       xm addlabel <label> res <resource> [<policy>]\n"
    4.18 -    print "  This program adds an acm_label entry into the 'configfile'"
    4.19 -    print "  for a domain or to the global resource label file for a"
    4.20 -    print "  resource. It derives the policy from the running hypervisor"
    4.21 -    print "  if it is not given (optional parameter). If a label already"
    4.22 -    print "  exists for the given domain or resource, then addlabel fails.\n"
    4.23 -    security.err("Usage")
    4.24 +def help():
    4.25 +    return """
    4.26 +    Format: xm addlabel <label> dom <configfile> [<policy>]
    4.27 +            xm addlabel <label> res <resource> [<policy>]
    4.28 +    
    4.29 +    This program adds an acm_label entry into the 'configfile'
    4.30 +    for a domain or to the global resource label file for a
    4.31 +    resource. It derives the policy from the running hypervisor
    4.32 +    if it is not given (optional parameter). If a label already
    4.33 +    exists for the given domain or resource, then addlabel fails."""
    4.34  
    4.35  
    4.36  def validate_config_file(configfile):
    4.37 @@ -114,9 +118,8 @@ def add_domain_label(label, configfile, 
    4.38  def main (argv):
    4.39      try:
    4.40          policyref = None
    4.41 -        if len(argv) not in [4,5]:
    4.42 -            usage()
    4.43 -            return
    4.44 +        if len(argv) not in (4, 5):
    4.45 +            raise OptionError('Needs either 2 or 3 arguments')
    4.46  
    4.47          label = argv[1]
    4.48  
    4.49 @@ -135,20 +138,20 @@ def main (argv):
    4.50                      if os.path.isfile(configfile):
    4.51                          break
    4.52              if not validate_config_file(configfile):
    4.53 -                usage()
    4.54 +                raise OptionError('Invalid config file')
    4.55              else:
    4.56                  add_domain_label(label, configfile, policyref)
    4.57          elif argv[2].lower() == "res":
    4.58              resource = argv[3]
    4.59              add_resource_label(label, resource, policyref)
    4.60          else:
    4.61 -            usage()
    4.62 -
    4.63 +            raise OptionError('Need to specify either "dom" or "res" as object to add label to.')
    4.64 +            
    4.65      except security.ACMError:
    4.66          sys.exit(-1)
    4.67  
    4.68 -
    4.69  if __name__ == '__main__':
    4.70      main(sys.argv)
    4.71 +    
    4.72  
    4.73  
     5.1 --- a/tools/python/xen/xm/cfgbootpolicy.py	Fri Sep 22 17:21:52 2006 +0100
     5.2 +++ b/tools/python/xen/xm/cfgbootpolicy.py	Fri Sep 22 17:22:18 2006 +0100
     5.3 @@ -28,20 +28,17 @@ from xen.util.security import ACMError, 
     5.4  from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re
     5.5  from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re
     5.6  from xen.util.security import empty_line_re, binary_name_re, policy_name_re
     5.7 -
     5.8 +from xen.xm.opts import OptionError
     5.9  
    5.10 -def usage():
    5.11 -    print "\nUsage: xm cfgbootpolicy <policy> [<kernelversion>]\n"
    5.12 -    print "  Adds a 'module' line to the Xen grub.conf entry"
    5.13 -    print "  so that xen boots into a specific access control"
    5.14 -    print "  policy. If kernelversion is not given, then this"
    5.15 -    print "  script tries to determine it by looking for a grub"
    5.16 -    print "  entry with a line kernel xen.* If there are multiple"
    5.17 -    print "  Xen entries, then it must be called with an explicit"
    5.18 -    print "  version (it will fail otherwise).\n"
    5.19 -    err("Usage")
    5.20 -
    5.21 -
    5.22 +def help():
    5.23 +    return """
    5.24 +    Adds a 'module' line to the Xen grub.conf entry
    5.25 +    so that xen boots into a specific access control
    5.26 +    policy. If kernelversion is not given, then this
    5.27 +    script tries to determine it by looking for a grub
    5.28 +    entry with a line kernel xen.* If there are multiple
    5.29 +    Xen entries, then it must be called with an explicit
    5.30 +    version (it will fail otherwise).\n"""
    5.31  
    5.32  def determine_kernelversion(user_specified):
    5.33      within_xen_title = 0
    5.34 @@ -152,7 +149,7 @@ def main(argv):
    5.35              policy = argv[1]
    5.36              user_kver = argv[2]
    5.37          else:
    5.38 -            usage()
    5.39 +            raise OptionError('Invalid number of arguments')
    5.40  
    5.41          if not policy_name_re.match(policy):
    5.42              err("Illegal policy name \'" + policy + "\'")
     6.1 --- a/tools/python/xen/xm/console.py	Fri Sep 22 17:21:52 2006 +0100
     6.2 +++ b/tools/python/xen/xm/console.py	Fri Sep 22 17:22:18 2006 +0100
     6.3 @@ -18,9 +18,7 @@
     6.4  
     6.5  XENCONSOLE = "xenconsole"
     6.6  
     6.7 -
     6.8  import xen.util.auxbin
     6.9  
    6.10 -
    6.11  def execConsole(domid):
    6.12      xen.util.auxbin.execute(XENCONSOLE, [str(domid)])
     7.1 --- a/tools/python/xen/xm/create.py	Fri Sep 22 17:21:52 2006 +0100
     7.2 +++ b/tools/python/xen/xm/create.py	Fri Sep 22 17:22:18 2006 +0100
     7.3 @@ -25,7 +25,6 @@ import sys
     7.4  import socket
     7.5  import re
     7.6  import xmlrpclib
     7.7 -import traceback
     7.8  
     7.9  from xen.xend import sxp
    7.10  from xen.xend import PrettyPrint
    7.11 @@ -57,7 +56,8 @@ gopts.opt('help', short='h',
    7.12  
    7.13  gopts.opt('help_config',
    7.14            fn=set_true, default=0,
    7.15 -          use="Print help for the configuration script.")
    7.16 +          use="Print the available configuration variables (vars) for the "
    7.17 +          "configuration script.")
    7.18  
    7.19  gopts.opt('quiet', short='q',
    7.20            fn=set_true, default=0,
    7.21 @@ -65,35 +65,36 @@ gopts.opt('quiet', short='q',
    7.22  
    7.23  gopts.opt('path', val='PATH',
    7.24            fn=set_value, default='.:/etc/xen',
    7.25 -          use="""Search path for configuration scripts.
    7.26 -         The value of PATH is a colon-separated directory list.""")
    7.27 +          use="Search path for configuration scripts. "
    7.28 +          "The value of PATH is a colon-separated directory list.")
    7.29  
    7.30  gopts.opt('defconfig', short='f', val='FILE',
    7.31            fn=set_value, default='xmdefconfig',
    7.32 -          use="""Use the given Python configuration script.
    7.33 -          The configuration script is loaded after arguments have been processed.
    7.34 -          Each command-line option sets a configuration variable named after
    7.35 -          its long option name, and these variables are placed in the
    7.36 -          environment of the script before it is loaded.
    7.37 -          Variables for options that may be repeated have list values.
    7.38 -          Other variables can be set using VAR=VAL on the command line.
    7.39 -        
    7.40 -          After the script is loaded, option values that were not set on the
    7.41 -          command line are replaced by the values set in the script.""")
    7.42 +          use="Use the given Python configuration script."
    7.43 +          "The configuration script is loaded after arguments have been "
    7.44 +          "processed. Each command-line option sets a configuration "
    7.45 +          "variable named after its long option name, and these "
    7.46 +          "variables are placed in the environment of the script before "
    7.47 +          "it is loaded. Variables for options that may be repeated have "
    7.48 +          "list values. Other variables can be set using VAR=VAL on the "
    7.49 +          "command line. "     
    7.50 +          "After the script is loaded, option values that were not set "
    7.51 +          "on the command line are replaced by the values set in the script.")
    7.52  
    7.53  gopts.default('defconfig')
    7.54  
    7.55  gopts.opt('config', short='F', val='FILE',
    7.56            fn=set_value, default=None,
    7.57 -          use="""Domain configuration to use (SXP).
    7.58 -          SXP is the underlying configuration format used by Xen.
    7.59 -          SXP configurations can be hand-written or generated from Python configuration
    7.60 -          scripts, using the -n (dryrun) option to print the configuration.""")
    7.61 +          use="Domain configuration to use (SXP).\n"
    7.62 +          "SXP is the underlying configuration format used by Xen.\n"
    7.63 +          "SXP configurations can be hand-written or generated from Python "
    7.64 +          "configuration scripts, using the -n (dryrun) option to print "
    7.65 +          "the configuration.")
    7.66  
    7.67  gopts.opt('dryrun', short='n',
    7.68            fn=set_true, default=0,
    7.69 -          use="""Dry run - print the configuration but don't create the domain.
    7.70 -          Loads the configuration script, creates the SXP configuration and prints it.""")
    7.71 +          use="Dry run - prints the resulting configuration in SXP but "
    7.72 +          "does not create the domain.")
    7.73  
    7.74  gopts.opt('paused', short='p',
    7.75            fn=set_true, default=0,
    7.76 @@ -105,18 +106,16 @@ gopts.opt('console_autoconnect', short='
    7.77  
    7.78  gopts.var('vncviewer', val='no|yes',
    7.79            fn=set_bool, default=None,
    7.80 -          use="""Spawn a vncviewer listening for a vnc server in the domain.
    7.81 -          The address of the vncviewer is passed to the domain on the kernel command
    7.82 -          line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY.
    7.83 -          A display value with a free port is chosen if possible.
    7.84 -          Only valid when vnc=1.
    7.85 -          """)
    7.86 +           use="Spawn a vncviewer listening for a vnc server in the domain.\n"
    7.87 +           "The address of the vncviewer is passed to the domain on the "
    7.88 +           "kernel command line using 'VNC_SERVER=<host>:<port>'. The port "
    7.89 +           "used by vnc is 5500 + DISPLAY. A display value with a free port "
    7.90 +           "is chosen if possible.\nOnly valid when vnc=1.")
    7.91  
    7.92  gopts.var('vncconsole', val='no|yes',
    7.93            fn=set_bool, default=None,
    7.94 -          use="""Spawn a vncviewer process for the domain's graphical console.
    7.95 -          Only valid when vnc=1.
    7.96 -          """)
    7.97 +          use="Spawn a vncviewer process for the domain's graphical console.\n"
    7.98 +          "Only valid when vnc=1.")
    7.99  
   7.100  gopts.var('name', val='NAME',
   7.101            fn=set_value, default=None,
   7.102 @@ -440,7 +439,6 @@ gopts.var('uuid', val='',
   7.103            addresses for virtual network interfaces.  This must be a unique 
   7.104            value across the entire cluster.""")
   7.105  
   7.106 -
   7.107  def err(msg):
   7.108      """Print an error to stderr and exit.
   7.109      """
   7.110 @@ -490,7 +488,6 @@ def configure_disks(config_devs, vals):
   7.111      """Create the config for disks (virtual block devices).
   7.112      """
   7.113      for (uname, dev, mode, backend) in vals.disk:
   7.114 -
   7.115          if uname.startswith('tap:'):
   7.116              cls = 'tap'
   7.117          else:
   7.118 @@ -851,7 +848,6 @@ def choose_vnc_display():
   7.119          if port in ports: continue
   7.120          return d
   7.121      return None
   7.122 -
   7.123  vncpid = None
   7.124  
   7.125  def daemonize(prog, args):
   7.126 @@ -885,7 +881,6 @@ def daemonize(prog, args):
   7.127              w.write(str(pid2 or 0))
   7.128              w.close()
   7.129              os._exit(0)
   7.130 -
   7.131      os.close(w)
   7.132      r = os.fdopen(r)
   7.133      daemon_pid = int(r.read())
   7.134 @@ -904,6 +899,7 @@ def spawn_vnc(display):
   7.135      vncpid = daemonize("vncviewer", vncargs)
   7.136      if vncpid == 0:
   7.137          return 0
   7.138 +
   7.139      return VNC_BASE_PORT + display
   7.140  
   7.141  def preprocess_vnc(vals):
   7.142 @@ -1019,11 +1015,10 @@ def get_xauthority():
   7.143  def parseCommandLine(argv):
   7.144      gopts.reset()
   7.145      args = gopts.parse(argv)
   7.146 -    if gopts.vals.help:
   7.147 -        gopts.usage()
   7.148 +
   7.149      if gopts.vals.help or gopts.vals.help_config:
   7.150 -        gopts.load_defconfig(help=1)
   7.151 -    if gopts.vals.help or gopts.vals.help_config:
   7.152 +        if gopts.vals.help_config:
   7.153 +            print gopts.val_usage()
   7.154          return (None, None)
   7.155  
   7.156      if not gopts.vals.display:
   7.157 @@ -1091,7 +1086,6 @@ def check_domain_label(config, verbose):
   7.158  
   7.159      return answer
   7.160  
   7.161 -
   7.162  def config_security_check(config, verbose):
   7.163      """Checks each resource listed in the config to see if the active
   7.164         policy will permit creation of a new domain using the config.
   7.165 @@ -1145,7 +1139,6 @@ def config_security_check(config, verbos
   7.166  
   7.167      return answer
   7.168  
   7.169 -
   7.170  def create_security_check(config):
   7.171      passed = 0
   7.172      try:
   7.173 @@ -1158,7 +1151,9 @@ def create_security_check(config):
   7.174          sys.exit(-1)
   7.175  
   7.176      return passed
   7.177 -
   7.178 +  
   7.179 +def help():
   7.180 +    return str(gopts)
   7.181  
   7.182  def main(argv):
   7.183      try:
   7.184 @@ -1176,11 +1171,11 @@ def main(argv):
   7.185          PrettyPrint.prettyprint(config)
   7.186      else:
   7.187          if not create_security_check(config):
   7.188 -            err("Security configuration prevents domain from starting.")
   7.189 +            raise OptionError('Security Configuration prevents domain from starting')
   7.190          else:
   7.191              dom = make_domain(opts, config)
   7.192              if opts.vals.console_autoconnect:
   7.193 -                console.execConsole(dom)
   7.194 -        
   7.195 +                console.execConsole(dom)        
   7.196 +             
   7.197  if __name__ == '__main__':
   7.198      main(sys.argv)
     8.1 --- a/tools/python/xen/xm/dry-run.py	Fri Sep 22 17:21:52 2006 +0100
     8.2 +++ b/tools/python/xen/xm/dry-run.py	Fri Sep 22 17:22:18 2006 +0100
     8.3 @@ -22,20 +22,18 @@ import sys
     8.4  from xen.util import security
     8.5  from xen.xm import create
     8.6  from xen.xend import sxp
     8.7 +from xen.xm.opts import OptionError
     8.8  
     8.9 -def usage():
    8.10 -    print "\nUsage: xm dry-run <configfile>\n"
    8.11 -    print "This program checks each resource listed in the configfile"
    8.12 -    print "to see if the domain created by the configfile can access"
    8.13 -    print "the resources.  The status of each resource is listed"
    8.14 -    print "individually along with the final security decision.\n"
    8.15 -    security.err("Usage")
    8.16 -
    8.17 +def help():
    8.18 +    return """
    8.19 +    This program checks each resource listed in the configfile
    8.20 +    to see if the domain created by the configfile can access
    8.21 +    the resources.  The status of each resource is listed
    8.22 +    individually along with the final security decision."""
    8.23  
    8.24  def main (argv):
    8.25 -    try:
    8.26 -        if len(argv) != 2:
    8.27 -            usage()
    8.28 +    if len(argv) != 2:
    8.29 +        raise OptionError('Invalid number of arguments')
    8.30  
    8.31          passed = 0
    8.32          (opts, config) = create.parseCommandLine(argv)
     9.1 --- a/tools/python/xen/xm/dumppolicy.py	Fri Sep 22 17:21:52 2006 +0100
     9.2 +++ b/tools/python/xen/xm/dumppolicy.py	Fri Sep 22 17:22:18 2006 +0100
     9.3 @@ -21,12 +21,10 @@ import sys
     9.4  from xen.util.security import ACMError, err, dump_policy
     9.5  
     9.6  
     9.7 -def usage():
     9.8 -    print "\nUsage: xm dumppolicy\n"
     9.9 -    print " Retrieve and print currently enforced"
    9.10 -    print " hypervisor policy information (low-level).\n"
    9.11 -    err("Usage")
    9.12 -
    9.13 +def help():
    9.14 +    return """
    9.15 +    Retrieve and print currently enforced hypervisor policy information
    9.16 +    (low-level)."""
    9.17  
    9.18  def main(argv):
    9.19      try:
    9.20 @@ -34,7 +32,6 @@ def main(argv):
    9.21              usage()
    9.22  
    9.23          dump_policy()
    9.24 -
    9.25      except ACMError:
    9.26          sys.exit(-1)
    9.27  
    10.1 --- a/tools/python/xen/xm/getlabel.py	Fri Sep 22 17:21:52 2006 +0100
    10.2 +++ b/tools/python/xen/xm/getlabel.py	Fri Sep 22 17:22:18 2006 +0100
    10.3 @@ -21,13 +21,13 @@
    10.4  import sys, os, re
    10.5  from xen.util import dictio
    10.6  from xen.util import security
    10.7 +from xen.xm.opts import OptionError
    10.8  
    10.9 -def usage():
   10.10 -    print "\nUsage: xm getlabel dom <configfile>"
   10.11 -    print "       xm getlabel res <resource>\n"
   10.12 -    print "  This program shows the label for a domain or resource.\n"
   10.13 -    security.err("Usage")
   10.14 -
   10.15 +def help():
   10.16 +    return """
   10.17 +    Usage: xm getlabel dom <configfile>"
   10.18 +           xm getlabel res <resource>\n"
   10.19 +    This program shows the label for a domain or resource."""
   10.20  
   10.21  def get_resource_label(resource):
   10.22      """Gets the resource label
   10.23 @@ -90,21 +90,17 @@ def get_domain_label(configfile):
   10.24  
   10.25  
   10.26  def main (argv):
   10.27 -    try:
   10.28 -        if len(argv) != 3:
   10.29 -            usage()
   10.30 +    if len(argv) != 3:
   10.31 +        raise OptionError('Requires 2 arguments')
   10.32  
   10.33 -        if argv[1].lower() == "dom":
   10.34 -            configfile = argv[2]
   10.35 -            get_domain_label(configfile)
   10.36 -        elif argv[1].lower() == "res":
   10.37 -            resource = argv[2]
   10.38 -            get_resource_label(resource)
   10.39 -        else:
   10.40 -            usage()
   10.41 -
   10.42 -    except security.ACMError:
   10.43 -        sys.exit(-1)
   10.44 +    if argv[1].lower() == "dom":
   10.45 +        configfile = argv[2]
   10.46 +        get_domain_label(configfile)
   10.47 +    elif argv[1].lower() == "res":
   10.48 +        resource = argv[2]
   10.49 +        get_resource_label(resource)
   10.50 +    else:
   10.51 +        raise OptionError('First subcommand argument must be "dom" or "res"')
   10.52  
   10.53  if __name__ == '__main__':
   10.54      main(sys.argv)
    11.1 --- a/tools/python/xen/xm/labels.py	Fri Sep 22 17:21:52 2006 +0100
    11.2 +++ b/tools/python/xen/xm/labels.py	Fri Sep 22 17:22:18 2006 +0100
    11.3 @@ -23,49 +23,46 @@ import traceback
    11.4  import string
    11.5  from xen.util.security import ACMError, err, list_labels, active_policy
    11.6  from xen.util.security import vm_label_re, res_label_re, all_label_re
    11.7 +from xen.xm.opts import OptionError
    11.8  
    11.9 -def usage():
   11.10 -    print "\nUsage: xm labels [<policy>] [<type=dom|res|any>]\n"
   11.11 -    print " Prints labels of the specified type (default is dom)"
   11.12 -    print " that are defined in policy (default is current"
   11.13 -    print " hypervisor policy).\n"
   11.14 -    err("Usage")
   11.15  
   11.16 +def help():
   11.17 +    return """
   11.18 +    Prints labels of the specified type (default is dom)
   11.19 +    that are defined in policy (default is current hypervisor policy)."""
   11.20  
   11.21  def main(argv):
   11.22 +    policy = None
   11.23 +    ptype = None
   11.24 +    for arg in argv[1:]:
   11.25 +        key_val = arg.split('=')
   11.26 +        if len(key_val) == 2 and key_val[0] == 'type':
   11.27 +            if ptype:
   11.28 +                raise OptionError('type is definied twice')
   11.29 +            ptype = key_val[1].lower()
   11.30 +
   11.31 +        elif len(key_val) == 1:
   11.32 +            if policy:
   11.33 +                raise OptionError('policy is defined twice')
   11.34 +            policy = arg
   11.35 +        else:
   11.36 +            raise OptionError('Unrecognised option: %s' % arg)
   11.37 +
   11.38 +    if not policy:
   11.39 +        policy = active_policy
   11.40 +        if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
   11.41 +            raise OptionError('No policy active, you must specify a <policy>')
   11.42 +
   11.43 +    if not ptype or ptype == 'dom':
   11.44 +        condition = vm_label_re
   11.45 +    elif ptype == 'res':
   11.46 +        condition = res_label_re
   11.47 +    elif ptype == 'any':
   11.48 +        condition = all_label_re
   11.49 +    else:
   11.50 +        err("Unknown label type \'" + ptype + "\'")
   11.51 +
   11.52      try:
   11.53 -        policy = None
   11.54 -        type = None
   11.55 -        for i in argv[1:]:
   11.56 -            i_s = string.split(i, '=')
   11.57 -            if len(i_s) > 1:
   11.58 -                if (i_s[0] == 'type') and (len(i_s) == 2):
   11.59 -                    if not type:
   11.60 -                        type = i_s[1]
   11.61 -                    else:
   11.62 -                        usage()
   11.63 -                else:
   11.64 -                    usage()
   11.65 -            else:
   11.66 -                if not policy:
   11.67 -                    policy = i
   11.68 -                else:
   11.69 -                    usage()
   11.70 -
   11.71 -        if not policy:
   11.72 -            policy = active_policy
   11.73 -            if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
   11.74 -                err("No policy active. Please specify the <policy> parameter.")
   11.75 -
   11.76 -        if not type or (type in ['DOM', 'dom']):
   11.77 -            condition = vm_label_re
   11.78 -        elif type in ['RES', 'res']:
   11.79 -            condition = res_label_re
   11.80 -        elif type in ['ANY', 'any']:
   11.81 -            condition = all_label_re
   11.82 -        else:
   11.83 -            err("Unknown label type \'" + type + "\'")
   11.84 -
   11.85          labels = list_labels(policy, condition)
   11.86          labels.sort()
   11.87          for label in labels:
   11.88 @@ -74,9 +71,7 @@ def main(argv):
   11.89      except ACMError:
   11.90          sys.exit(-1)
   11.91      except:
   11.92 -        traceback.print_exc(limit=1)
   11.93 -        sys.exit(-1)
   11.94 -
   11.95 +        traceback.print_exc(limit = 1)
   11.96  
   11.97  if __name__ == '__main__':
   11.98      main(sys.argv)
    12.1 --- a/tools/python/xen/xm/loadpolicy.py	Fri Sep 22 17:21:52 2006 +0100
    12.2 +++ b/tools/python/xen/xm/loadpolicy.py	Fri Sep 22 17:22:18 2006 +0100
    12.3 @@ -21,26 +21,23 @@
    12.4  import sys
    12.5  import traceback
    12.6  from xen.util.security import ACMError, err, load_policy
    12.7 -
    12.8 +from xen.xm.opts import OptionError
    12.9  
   12.10 -def usage():
   12.11 -    print "\nUsage: xm loadpolicy <policy>\n"
   12.12 -    print " Load the compiled binary (.bin) policy"
   12.13 -    print " into the running hypervisor.\n"
   12.14 -    err("Usage")
   12.15 +def help():
   12.16 +    return """Load the compiled binary (.bin) policy into the running
   12.17 +    hypervisor."""
   12.18  
   12.19  def main(argv):
   12.20 +    if len(argv) != 2:
   12.21 +        raise OptionError('No policy defined')
   12.22 +    
   12.23      try:
   12.24 -        if len(argv) != 2:
   12.25 -            usage()
   12.26          load_policy(argv[1])
   12.27  
   12.28      except ACMError:
   12.29          sys.exit(-1)
   12.30      except:
   12.31 -        traceback.print_exc(limit=1)
   12.32 -        sys.exit(-1)
   12.33 -
   12.34 +        traceback.print_exc(limit = 1)
   12.35  
   12.36  if __name__ == '__main__':
   12.37      main(sys.argv)
    13.1 --- a/tools/python/xen/xm/main.py	Fri Sep 22 17:21:52 2006 +0100
    13.2 +++ b/tools/python/xen/xm/main.py	Fri Sep 22 17:22:18 2006 +0100
    13.3 @@ -22,28 +22,27 @@
    13.4  """Grand unified management application for Xen.
    13.5  """
    13.6  import os
    13.7 -import os.path
    13.8  import sys
    13.9  import re
   13.10  import getopt
   13.11  import socket
   13.12 -import warnings
   13.13 -warnings.filterwarnings('ignore', category=FutureWarning)
   13.14 +import traceback
   13.15  import xmlrpclib
   13.16  import traceback
   13.17  import datetime
   13.18 +from select import select
   13.19  
   13.20 -import xen.xend.XendProtocol
   13.21 +import warnings
   13.22 +warnings.filterwarnings('ignore', category=FutureWarning)
   13.23  
   13.24  from xen.xend import PrettyPrint
   13.25  from xen.xend import sxp
   13.26 -from xen.xm.opts import *
   13.27 +from xen.xend import XendClient
   13.28 +from xen.xend.XendClient import server
   13.29  
   13.30 -import console
   13.31 -import xen.xend.XendClient
   13.32 -from xen.xend.XendClient import server
   13.33 +from xen.xm.opts import OptionError, Opts, wrap, set_true
   13.34 +from xen.xm import console
   13.35  from xen.util import security
   13.36 -from select import select
   13.37  
   13.38  # getopt.gnu_getopt is better, but only exists in Python 2.3+.  Use
   13.39  # getopt.getopt if gnu_getopt is not available.  This will mean that options
   13.40 @@ -51,93 +50,148 @@ from select import select
   13.41  if not hasattr(getopt, 'gnu_getopt'):
   13.42      getopt.gnu_getopt = getopt.getopt
   13.43  
   13.44 -
   13.45 -# Strings for shorthelp
   13.46 -console_help = "console <DomId>                  Attach to domain DomId's console."
   13.47 -create_help =  """create [-c] <ConfigFile>
   13.48 -               [Name=Value]..       Create a domain based on Config File"""
   13.49 -destroy_help = "destroy <DomId>                  Terminate a domain immediately"
   13.50 -dump_core_help =   """dump-core [-L|--live][-C|--crash]
   13.51 -            <DomId> [FileName]      Dump core of the specified domain"""
   13.52 -
   13.53 -help_help =    "help                             Display this message"
   13.54 -list_help =    "list [--long] [DomId, ...]       List information about domains"
   13.55 -list_label_help = "list [--label] [DomId, ...]      List information about domains including their labels"
   13.56 -
   13.57 -mem_max_help = "mem-max <DomId> <Mem>            Set maximum memory reservation for a domain"
   13.58 -mem_set_help = "mem-set <DomId> <Mem>            Adjust the current memory usage for a domain"
   13.59 -migrate_help = "migrate <DomId> <Host>           Migrate a domain to another machine"
   13.60 -pause_help =   "pause <DomId>                    Pause execution of a domain"
   13.61 -reboot_help =  "reboot <DomId> [-w][-a]          Reboot a domain"
   13.62 -restore_help = "restore <File>                   Create a domain from a saved state file"
   13.63 -save_help =    "save <DomId> <File>              Save domain state (and config) to file"
   13.64 -shutdown_help ="shutdown <DomId> [-w][-a][-R|-H] Shutdown a domain"
   13.65 -top_help =     "top                              Monitor system and domains in real-time"
   13.66 -unpause_help = "unpause <DomId>                  Unpause a paused domain"
   13.67 -uptime_help  = "uptime [-s|--short] [DomId, ...] List uptime for domains"
   13.68 -
   13.69 -help_spacer = """
   13.70 -   """
   13.71 +# General help message
   13.72  
   13.73 -# Strings for longhelp
   13.74 -sysrq_help =   "sysrq   <DomId> <letter>         Send a sysrq to a domain"
   13.75 -domid_help =   "domid <DomName>                  Converts a domain name to a domain id"
   13.76 -domname_help = "domname <DomId>                  Convert a domain id to a domain name"
   13.77 -vcpu_set_help = """vcpu-set <DomId> <VCPUs>         Set the number of active VCPUs for a domain
   13.78 -                                    within the range allowed by the domain
   13.79 -                                    configuration"""
   13.80 -vcpu_list_help = "vcpu-list <DomId>                List the VCPUs for a domain (or all domains)"
   13.81 -vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs>   Set which cpus a VCPU can use" 
   13.82 -dmesg_help =   "dmesg [-c|--clear]               Read or clear Xen's message buffer"
   13.83 -info_help =    "info                             Get information about the xen host"
   13.84 -rename_help =  "rename <DomId> <New Name>        Rename a domain"
   13.85 -log_help =     "log                              Print the xend log"
   13.86 -sched_sedf_help = "sched-sedf [DOM] [OPTIONS]       Show|Set simple EDF parameters\n" + \
   13.87 -"              -p, --period          Relative deadline(ms).\n\
   13.88 -              -s, --slice           Worst-case execution time(ms)\n\
   13.89 -                                    (slice < period).\n\
   13.90 -              -l, --latency         scaled period(ms) in case the domain\n\
   13.91 -                                    is doing heavy I/O.\n\
   13.92 -              -e, --extra           flag (0/1) which controls whether the\n\
   13.93 -                                    domain can run in extra-time\n\
   13.94 -              -w, --weight          mutually exclusive with period/slice and\n\
   13.95 -                                    specifies another way of setting a domain's\n\
   13.96 -                                    cpu period/slice."
   13.97 +USAGE_HELP = "Usage: xm <subcommand> [args]\n\n" \
   13.98 +             "Control, list, and manipulate Xen guest instances.\n"
   13.99  
  13.100 -sched_credit_help = "sched-credit                           Set or get credit scheduler parameters"
  13.101 -block_attach_help = """block-attach <DomId> <BackDev> <FrontDev> <Mode>
  13.102 -                [BackDomId]         Create a new virtual block device"""
  13.103 -block_detach_help = """block-detach  <DomId> <DevId>    Destroy a domain's virtual block device,
  13.104 -                                    where <DevId> may either be the device ID
  13.105 -                                    or the device name as mounted in the guest"""
  13.106 -
  13.107 -block_list_help = "block-list <DomId> [--long]      List virtual block devices for a domain"
  13.108 -block_configure_help = """block-configure <DomId> <BackDev> <FrontDev> <Mode>
  13.109 -                   [BackDomId] Change block device configuration"""
  13.110 -network_attach_help = """network-attach  <DomID> [script=<script>] [ip=<ip>] [mac=<mac>]
  13.111 -                           [bridge=<bridge>] [backend=<backDomID>]
  13.112 -                                    Create a new virtual network device """
  13.113 -network_detach_help = """network-detach  <DomId> <DevId>  Destroy a domain's virtual network
  13.114 -                                    device, where <DevId> is the device ID."""
  13.115 +USAGE_FOOTER = '<Domain> can either be the Domain Name or Id.\n' \
  13.116 +               'For more help on \'xm\' see the xm(1) man page.\n' \
  13.117 +               'For more help on \'xm create\' see the xmdomain.cfg(5) '\
  13.118 +               ' man page.\n'
  13.119  
  13.120 -network_list_help = "network-list <DomId> [--long]    List virtual network interfaces for a domain"
  13.121 -vnet_list_help = "vnet-list [-l|--long]            list vnets"
  13.122 -vnet_create_help = "vnet-create <config>             create a vnet from a config file"
  13.123 -vnet_delete_help = "vnet-delete <vnetid>             delete a vnet"
  13.124 -vtpm_list_help = "vtpm-list <DomId> [--long]       list virtual TPM devices"
  13.125 -addlabel_help =  "addlabel <label> dom <configfile> Add security label to domain\n            <label> res <resource>   or resource"
  13.126 -rmlabel_help =  "rmlabel dom <configfile>         Remove security label from domain\n           res <resource>           or resource"
  13.127 -getlabel_help =  "getlabel dom <configfile>        Show security label for domain\n            res <resource>          or resource"
  13.128 -dry_run_help =  "dry-run <configfile>             Tests if domain can access its resources"
  13.129 -resources_help =  "resources                        Show info for each labeled resource"
  13.130 -cfgbootpolicy_help = "cfgbootpolicy <policy>           Add policy to boot configuration "
  13.131 -dumppolicy_help = "dumppolicy                       Print hypervisor ACM state information"
  13.132 -loadpolicy_help = "loadpolicy <policy>              Load binary policy into hypervisor"
  13.133 -makepolicy_help = "makepolicy <policy>              Build policy and create .bin/.map files"
  13.134 -labels_help     = "labels [policy] [type=DOM|..]    List <type> labels for (active) policy."
  13.135 -serve_help      = "serve                            Proxy Xend XML-RPC over stdio"
  13.136 +# Help strings are indexed by subcommand name in this way:
  13.137 +# 'subcommand': (argstring, description)
  13.138  
  13.139 -short_command_list = [
  13.140 +SUBCOMMAND_HELP = {
  13.141 +    # common commands
  13.142 +    
  13.143 +    'console'     : ('<Domain>',
  13.144 +                     'Attach to <Domain>\'s console.'),
  13.145 +    'create'      : ('<ConfigFile> [options] [vars]',
  13.146 +                     'Create a domain based on <ConfigFile>.'),
  13.147 +    'destroy'     : ('<Domain>',
  13.148 +                     'Terminate a domain immediately.'),
  13.149 +    'help'        : ('', 'Display this message.'),
  13.150 +    'list'        : ('[options] [Domain, ...]',
  13.151 +                     'List information about all/some domains.'),
  13.152 +    'mem-max'     : ('<Domain> <Mem>',
  13.153 +                     'Set the maximum amount reservation for a domain.'),
  13.154 +    'mem-set'     : ('<Domain> <Mem>',
  13.155 +                     'Set the current memory usage for a domain.'),
  13.156 +    'migrate'     : ('<Domain> <Host>',
  13.157 +                     'Migrate a domain to another machine.'),
  13.158 +    'pause'       : ('<Domain>', 'Pause execution of a domain.'),
  13.159 +    'reboot'      : ('<Domain> [-wa]', 'Reboot a domain.'),
  13.160 +    'restore'     : ('<CheckpointFile>',
  13.161 +                     'Restore a domain from a saved state.'),
  13.162 +    'save'        : ('<Domain> <CheckpointFile>',
  13.163 +                     'Save a domain state to restore later.'),
  13.164 +    'shutdown'    : ('<Domain> [-waRH]', 'Shutdown a domain.'),
  13.165 +    'top'         : ('', 'Monitor a host and the domains in real time.'),
  13.166 +    'unpause'     : ('<Domain>', 'Unpause a paused domain.'),
  13.167 +    'uptime'      : ('[-s] <Domain>', 'Print uptime for a domain.'),
  13.168 +
  13.169 +    # less used commands
  13.170 +
  13.171 +    'dmesg'       : ('[-c|--clear]',
  13.172 +                     'Read and/or clear Xend\'s message buffer.'),
  13.173 +    'domid'       : ('<DomainName>', 'Convert a domain name to domain id.'),
  13.174 +    'domname'     : ('<DomId>', 'Convert a domain id to domain name.'),
  13.175 +    'dump-core'   : ('[-L|--live] [-C|--crash] <Domain> [Filename]',
  13.176 +                     'Dump core for a specific domain.'),
  13.177 +    'info'        : ('', 'Get information about Xen host.'),
  13.178 +    'log'         : ('', 'Print Xend log'),
  13.179 +    'rename'      : ('<Domain> <NewDomainName>', 'Rename a domain.'),
  13.180 +    'sched-sedf'  : ('<Domain> [options]', 'Get/set EDF parameters.'),
  13.181 +    'sched-credit': ('-d <Domain> [-w[=WEIGHT]|-c[=CAP]]',
  13.182 +                     'Get/set credit scheduler parameters.'),
  13.183 +    'sysrq'       : ('<Domain> <letter>', 'Send a sysrq to a domain.'),
  13.184 +    'vcpu-list'   : ('[<Domain>]',
  13.185 +                     'List the VCPUs for a domain or all domains.'),
  13.186 +    'vcpu-pin'    : ('<Domain> <VCPU> <CPUs>',
  13.187 +                     'Set which CPUs a VCPU can use.'),
  13.188 +    'vcpu-set'    : ('<Domain> <vCPUs>',
  13.189 +                     'Set the number of active VCPUs for allowed for the'
  13.190 +                     ' domain.'),
  13.191 +
  13.192 +    # device commands
  13.193 +
  13.194 +    'block-attach'  :  ('<Domain> <BackDev> <FrontDev> <Mode>',
  13.195 +                        'Create a new virtual block device.'),
  13.196 +    'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomId]',
  13.197 +                        'Change block device configuration'),
  13.198 +    'block-detach'  :  ('<Domain> <DevId>',
  13.199 +                        'Destroy a domain\'s virtual block device.'),
  13.200 +    'block-list'    :  ('<Domain> [--long]',
  13.201 +                        'List virtual block devices for a domain.'),
  13.202 +    'network-attach':  ('<Domain> [--script=<script>] [--ip=<ip>] '
  13.203 +                        '[--mac=<mac>]',
  13.204 +                        'Create a new virtual network device.'),
  13.205 +    'network-detach':  ('<Domain> <DevId>',
  13.206 +                        'Destroy a domain\'s virtual network device.'),
  13.207 +    'network-list'  :  ('<Domain> [--long]',
  13.208 +                        'List virtual network interfaces for a domain.'),
  13.209 +    'vnet-create'   :  ('<ConfigFile>','Create a vnet from ConfigFile.'),
  13.210 +    'vnet-delete'   :  ('<VnetId>', 'Delete a Vnet.'),
  13.211 +    'vnet-list'     :  ('[-l|--long]', 'List Vnets.'),
  13.212 +    'vtpm-list'     :  ('<Domain> [--long]', 'List virtual TPM devices.'),
  13.213 +
  13.214 +    # security
  13.215 +
  13.216 +    'addlabel'      :  ('<label> {dom <ConfigFile>|res <resource>} [<policy>]',
  13.217 +                        'Add security label to domain.'),
  13.218 +    'rmlabel'       :  ('{dom <ConfigFile>|res <Resource>}',
  13.219 +                        'Remove a security label from domain.'),
  13.220 +    'getlabel'      :  ('{dom <ConfigFile>|res <Resource>}',
  13.221 +                        'Show security label for domain or resource.'),
  13.222 +    'dry-run'       :  ('<ConfigFile>',
  13.223 +                        'Test if a domain can access its resources.'),
  13.224 +    'resources'     :  ('', 'Show info for each labeled resource.'),
  13.225 +    'cfgbootpolicy' :  ('<policy> [kernelversion]',
  13.226 +                        'Add policy to boot configuration.'),
  13.227 +    'dumppolicy'    :  ('', 'Print hypervisor ACM state information.'),
  13.228 +    'loadpolicy'    :  ('<policy.bin>', 'Load binary policy into hypervisor.'),
  13.229 +    'makepolicy'    :  ('<policy>', 'Build policy and create .bin/.map '
  13.230 +                        'files.'),
  13.231 +    'labels'        :  ('[policy] [type=dom|res|any]',
  13.232 +                        'List <type> labels for (active) policy.'),
  13.233 +    'serve'         :  ('', 'Proxy Xend XMLRPC over stdio.'),
  13.234 +}
  13.235 +
  13.236 +SUBCOMMAND_OPTIONS = {
  13.237 +    'sched-sedf': (
  13.238 +       ('-p [MS]', '--period[=MS]', 'Relative deadline(ms)'),
  13.239 +       ('-s [MS]', '--slice[=MS]' ,
  13.240 +        'Worst-case execution time(ms). (slice < period)'),
  13.241 +       ('-l [MS]', '--latency[=MS]',
  13.242 +        'Scaled period (ms) when domain performs heavy I/O'),
  13.243 +       ('-e [FLAG]', '--extra[=FLAG]',
  13.244 +        'Flag (0 or 1) controls if domain can run in extra time.'),
  13.245 +       ('-w [FLOAT]', '--weight[=FLOAT]',
  13.246 +        'CPU Period/slice (do not set with --period/--slice)'),
  13.247 +    ),
  13.248 +    'sched-credit': (
  13.249 +       ('-d DOMAIN', '--domain=DOMAIN', 'Domain to modify'),
  13.250 +       ('-w WEIGHT', '--weight=WEIGHT', 'Weight (int)'),
  13.251 +       ('-c CAP',    '--cap=CAP',       'Cap (int)'),
  13.252 +    ),
  13.253 +    'list': (
  13.254 +       ('-l', '--long', 'Output all VM details in SXP'),
  13.255 +       ('', '--label',  'Include security labels'),
  13.256 +    ),
  13.257 +    'dmesg': (
  13.258 +       ('-c', '--clear', 'Clear dmesg buffer'),
  13.259 +    ),
  13.260 +    'vnet-list': (
  13.261 +       ('-l', '--long', 'List Vnets as SXP'),
  13.262 +    ),
  13.263 +    'network-list': (
  13.264 +       ('-l', '--long', 'List resources as SXP'),
  13.265 +    ),
  13.266 +}
  13.267 +
  13.268 +common_commands = [
  13.269      "console",
  13.270      "create",
  13.271      "destroy",
  13.272 @@ -165,7 +219,6 @@ domain_commands = [
  13.273      "domname",
  13.274      "dump-core",
  13.275      "list",
  13.276 -    "list_label",
  13.277      "mem-max",
  13.278      "mem-set",
  13.279      "migrate",
  13.280 @@ -223,67 +276,105 @@ acm_commands = [
  13.281      "makepolicy",
  13.282      "loadpolicy",
  13.283      "cfgbootpolicy",
  13.284 -    "dumppolicy"
  13.285 +    "dumppolicy",
  13.286      ]
  13.287  
  13.288  all_commands = (domain_commands + host_commands + scheduler_commands +
  13.289                  device_commands + vnet_commands + acm_commands)
  13.290  
  13.291 -
  13.292 -def commandToHelp(cmd):
  13.293 -    return eval(cmd.replace("-", "_") + "_help")
  13.294 -
  13.295 -
  13.296 -shorthelp = """Usage: xm <subcommand> [args]
  13.297 -    Control, list, and manipulate Xen guest instances
  13.298 -
  13.299 -xm common subcommands:
  13.300 -   """  + help_spacer.join(map(commandToHelp, short_command_list))  + """
  13.301 -
  13.302 -<DomName> can be substituted for <DomId> in xm subcommands.
  13.303 -
  13.304 -For a complete list of subcommands run 'xm help --long'
  13.305 -For more help on xm see the xm(1) man page
  13.306 -For more help on xm create, see the xmdomain.cfg(5) man page"""
  13.307 -
  13.308 -longhelp = """Usage: xm <subcommand> [args]
  13.309 -    Control, list, and manipulate Xen guest instances
  13.310 -
  13.311 -xm full list of subcommands:
  13.312 -
  13.313 -  Domain Commands:
  13.314 -   """ + help_spacer.join(map(commandToHelp,  domain_commands)) + """
  13.315 +####################################################################
  13.316 +#
  13.317 +#  Help/usage printing functions
  13.318 +#
  13.319 +####################################################################
  13.320  
  13.321 -  Xen Host Commands:
  13.322 -   """ + help_spacer.join(map(commandToHelp,  host_commands)) + """
  13.323 -
  13.324 -  Scheduler Commands:
  13.325 -   """ + help_spacer.join(map(commandToHelp,  scheduler_commands)) + """
  13.326 -
  13.327 -  Virtual Device Commands:
  13.328 -   """  + help_spacer.join(map(commandToHelp, device_commands)) + """
  13.329 -
  13.330 -  Vnet commands:
  13.331 -   """ + help_spacer.join(map(commandToHelp,  vnet_commands)) + """
  13.332 -
  13.333 -  Access Control commands:
  13.334 -   """ + help_spacer.join(map(commandToHelp,  acm_commands)) + """
  13.335 +def cmdHelp(cmd):
  13.336 +    """Print help for a specific subcommand."""
  13.337 +    
  13.338 +    try:
  13.339 +        args, desc = SUBCOMMAND_HELP[cmd]
  13.340 +    except KeyError:
  13.341 +        shortHelp()
  13.342 +        return
  13.343 +    
  13.344 +    print 'Usage: xm %s %s' % (cmd, args)
  13.345 +    print
  13.346 +    print desc
  13.347 +    
  13.348 +    try:
  13.349 +        # If options help message is defined, print this.
  13.350 +        for shortopt, longopt, desc in SUBCOMMAND_OPTIONS[cmd]:
  13.351 +            if shortopt and longopt:
  13.352 +                optdesc = '%s, %s' % (shortopt, longopt)
  13.353 +            elif shortopt:
  13.354 +                optdesc = shortopt
  13.355 +            elif longopt:
  13.356 +                optdesc = longopt
  13.357  
  13.358 -<DomName> can be substituted for <DomId> in xm subcommands.
  13.359 -
  13.360 -For a short list of subcommands run 'xm help'
  13.361 -For more help on xm see the xm(1) man page
  13.362 -For more help on xm create, see the xmdomain.cfg(5) man page"""
  13.363 +            wrapped_desc = wrap(desc, 43)   
  13.364 +            print '  %-30s %-43s' % (optdesc, wrapped_desc[0])
  13.365 +            for line in wrapped_desc[1:]:
  13.366 +                print ' ' * 33 + line
  13.367 +        print
  13.368 +    except KeyError:
  13.369 +        # if the command is an external module, we grab usage help
  13.370 +        # from the module itself.
  13.371 +        if cmd in IMPORTED_COMMANDS:
  13.372 +            try:
  13.373 +                cmd_module =  __import__(cmd, globals(), locals(), 'xen.xm')
  13.374 +                cmd_usage = getattr(cmd_module, "help", None)
  13.375 +                if cmd_usage:
  13.376 +                    print cmd_usage()
  13.377 +            except ImportError:
  13.378 +                pass
  13.379 +        
  13.380 +def shortHelp():
  13.381 +    """Print out generic help when xm is called without subcommand."""
  13.382 +    
  13.383 +    print USAGE_HELP
  13.384 +    print 'Common \'xm\' commands:\n'
  13.385 +    
  13.386 +    for command in common_commands:
  13.387 +        try:
  13.388 +            args, desc = SUBCOMMAND_HELP[command]
  13.389 +        except KeyError:
  13.390 +            continue
  13.391 +        wrapped_desc = wrap(desc, 50)
  13.392 +        print ' %-20s %-50s' % (command, wrapped_desc[0])
  13.393 +        for line in wrapped_desc[1:]:
  13.394 +            print ' ' * 22 + line
  13.395  
  13.396 -# array for xm help <command>
  13.397 -help = {
  13.398 -    "--long": longhelp
  13.399 -    }
  13.400 +    print
  13.401 +    print USAGE_FOOTER
  13.402 +    print 'For a complete list of subcommands run \'xm help\'.'
  13.403 +    
  13.404 +def longHelp():
  13.405 +    """Print out full help when xm is called with xm --help or xm help"""
  13.406 +    
  13.407 +    print USAGE_HELP
  13.408 +    print 'xm full list of subcommands:\n'
  13.409 +    
  13.410 +    for command in all_commands:
  13.411 +        try:
  13.412 +            args, desc = SUBCOMMAND_HELP[command]
  13.413 +        except KeyError:
  13.414 +            continue
  13.415  
  13.416 -for command in all_commands:
  13.417 -    # create is handled specially
  13.418 -    if (command != 'create'):
  13.419 -        help[command] = commandToHelp(command)
  13.420 +        wrapped_desc = wrap(desc, 50)
  13.421 +        print ' %-20s %-50s' % (command, wrapped_desc[0])
  13.422 +        for line in wrapped_desc[1:]:
  13.423 +            print ' ' * 22 + line        
  13.424 +
  13.425 +    print
  13.426 +    print USAGE_FOOTER        
  13.427 +
  13.428 +def usage(cmd = None):
  13.429 +    """ Print help usage information and exits """
  13.430 +    if cmd:
  13.431 +        cmdHelp(cmd)
  13.432 +    else:
  13.433 +        shortHelp()
  13.434 +    sys.exit(1)
  13.435  
  13.436  
  13.437  ####################################################################
  13.438 @@ -298,7 +389,7 @@ def arg_check(args, name, lo, hi = -1):
  13.439      if hi == -1:
  13.440          if n != lo:
  13.441              err("'xm %s' requires %d argument%s.\n" % (name, lo,
  13.442 -                                                       lo > 1 and 's' or ''))
  13.443 +                                                       lo == 1 and '' or 's'))
  13.444              usage(name)
  13.445      else:
  13.446          if n < lo or n > hi:
  13.447 @@ -345,14 +436,19 @@ def err(msg):
  13.448  def xm_save(args):
  13.449      arg_check(args, "save", 2)
  13.450  
  13.451 -    dom = args[0] # TODO: should check if this exists
  13.452 +    try:
  13.453 +        dominfo = parse_doms_info(server.xend.domain(args[0]))
  13.454 +    except xmlrpclib.Fault, ex:
  13.455 +        raise ex
  13.456 +    
  13.457 +    domid = dominfo['domid']
  13.458      savefile = os.path.abspath(args[1])
  13.459  
  13.460      if not os.access(os.path.dirname(savefile), os.W_OK):
  13.461          err("xm save: Unable to create file %s" % savefile)
  13.462          sys.exit(1)
  13.463      
  13.464 -    server.xend.domain.save(dom, savefile)
  13.465 +    server.xend.domain.save(domid, savefile)
  13.466      
  13.467  def xm_restore(args):
  13.468      arg_check(args, "restore", 1)
  13.469 @@ -366,9 +462,9 @@ def xm_restore(args):
  13.470      server.xend.domain.restore(savefile)
  13.471  
  13.472  
  13.473 -def getDomains(domain_names):
  13.474 +def getDomains(domain_names, full = 0):
  13.475      if domain_names:
  13.476 -        return map(server.xend.domain, domain_names)
  13.477 +        return [server.xend.domain(dom) for dom in domain_names]
  13.478      else:
  13.479          return server.xend.domains(1)
  13.480  
  13.481 @@ -378,9 +474,11 @@ def xm_list(args):
  13.482      show_vcpus = 0
  13.483      show_labels = 0
  13.484      try:
  13.485 -        (options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus','label'])
  13.486 +        (options, params) = getopt.gnu_getopt(args, 'lv',
  13.487 +                                              ['long','vcpus','label'])
  13.488      except getopt.GetoptError, opterr:
  13.489          err(opterr)
  13.490 +        usage('list')
  13.491          sys.exit(1)
  13.492      
  13.493      for (k, v) in options:
  13.494 @@ -397,7 +495,7 @@ def xm_list(args):
  13.495          xm_vcpu_list(params)
  13.496          return
  13.497  
  13.498 -    doms = getDomains(params)
  13.499 +    doms = getDomains(params, use_long)
  13.500  
  13.501      if use_long:
  13.502          map(PrettyPrint.prettyprint, doms)
  13.503 @@ -412,7 +510,7 @@ def parse_doms_info(info):
  13.504          return t(sxp.child_value(info, n, d))
  13.505      
  13.506      return {
  13.507 -        'dom'      : get_info('domid',        int,   -1),
  13.508 +        'domid'    : get_info('domid',        int,   -1),
  13.509          'name'     : get_info('name',         str,   '??'),
  13.510          'mem'      : get_info('memory',       int,   0),
  13.511          'vcpus'    : get_info('online_vcpus', int,   0),
  13.512 @@ -428,7 +526,7 @@ def parse_sedf_info(info):
  13.513          return t(sxp.child_value(info, n, d))
  13.514  
  13.515      return {
  13.516 -        'dom'      : get_info('domain',        int,   -1),
  13.517 +        'domid'    : get_info('domid',         int,   -1),
  13.518          'period'   : get_info('period',        int,   -1),
  13.519          'slice'    : get_info('slice',         int,   -1),
  13.520          'latency'  : get_info('latency',       int,   -1),
  13.521 @@ -436,34 +534,40 @@ def parse_sedf_info(info):
  13.522          'weight'   : get_info('weight',        int,   -1),
  13.523          }
  13.524  
  13.525 -
  13.526  def xm_brief_list(doms):
  13.527 -    print 'Name                              ID Mem(MiB) VCPUs State  Time(s)'
  13.528 -    for dom in doms:
  13.529 -        d = parse_doms_info(dom)
  13.530 -        print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f" % d)
  13.531 -
  13.532 -
  13.533 -def xm_label_list(doms):
  13.534 -    output = []
  13.535 -    print 'Name                              ID Mem(MiB) VCPUs State  Time(s)  Label'
  13.536 +    print '%-40s %3s %8s %5s %5s %9s' % \
  13.537 +          ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)')
  13.538 +    
  13.539 +    format = "%(name)-40s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s " \
  13.540 +             "%(cpu_time)8.1f"
  13.541 +    
  13.542      for dom in doms:
  13.543          d = parse_doms_info(dom)
  13.544 -        l = "%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f  " % d
  13.545 +        print format % d
  13.546 +
  13.547 +def xm_label_list(doms):
  13.548 +    print '%-32s %3s %8s %5s %5s %9s %-8s' % \
  13.549 +          ('Name', 'ID', 'Mem(MiB)', 'VCPUs', 'State', 'Time(s)', 'Label')
  13.550 +    
  13.551 +    output = []
  13.552 +    format = '%(name)-32s %(domid)3d %(mem)8d %(vcpus)5d %(state)5s ' \
  13.553 +             '%(cpu_time)8.1f %(seclabel)9s'
  13.554 +    
  13.555 +    for dom in doms:
  13.556 +        d = parse_doms_info(dom)
  13.557          if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
  13.558 -            if d['seclabel']:
  13.559 -                line = (l, d['seclabel'])
  13.560 -            else:
  13.561 -                line = (l, "ERROR")
  13.562 +            if not d['seclabel']:
  13.563 +                d['seclabel'] = 'ERROR'
  13.564          elif security.active_policy in ['DEFAULT']:
  13.565 -            line = (l, "DEFAULT")
  13.566 +            d['seclabel'] = 'DEFAULT'
  13.567          else:
  13.568 -            line = (l, "INACTIVE")
  13.569 -        output.append(line)
  13.570 +            d['seclabel'] = 'INACTIVE'
  13.571 +        output.append((format % d, d['seclabel']))
  13.572 +        
  13.573      #sort by labels
  13.574      output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
  13.575 -    for l in output:
  13.576 -        print l[0] + l[1]
  13.577 +    for line, label in output:
  13.578 +        print line
  13.579  
  13.580  
  13.581  def xm_vcpu_list(args):
  13.582 @@ -474,7 +578,11 @@ def xm_vcpu_list(args):
  13.583          doms = server.xend.domains(False)
  13.584          dominfo = map(server.xend.domain.getVCPUInfo, doms)
  13.585  
  13.586 -    print 'Name                              ID  VCPU  CPU  State  Time(s)  CPU Affinity'
  13.587 +    print '%-32s %3s %5s %5s %5s %9s %s' % \
  13.588 +          ('Name', 'ID', 'VCPUs', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
  13.589 +
  13.590 +    format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \
  13.591 +             ' %(cpu_time)8.1f %(cpumap)s'
  13.592  
  13.593      for dom in dominfo:
  13.594          def get_info(n):
  13.595 @@ -568,10 +676,7 @@ def xm_vcpu_list(args):
  13.596                  c = "-"
  13.597                  s = "--p"
  13.598  
  13.599 -            print (
  13.600 -                "%(name)-32s %(domid)3d  %(number)4d  %(c)3s   %(s)-3s   %(cpu_time)7.1f  %(cpumap)s" %
  13.601 -                locals())
  13.602 -
  13.603 +            print format % locals()
  13.604  
  13.605  def xm_reboot(args):
  13.606      arg_check(args, "reboot", 1, 3)
  13.607 @@ -634,31 +739,31 @@ def xm_dump_core(args):
  13.608  
  13.609  def xm_rename(args):
  13.610      arg_check(args, "rename", 2)
  13.611 -
  13.612 +        
  13.613      server.xend.domain.setName(args[0], args[1])
  13.614  
  13.615 -def xm_subcommand(command, args):
  13.616 +def xm_importcommand(command, args):
  13.617      cmd = __import__(command, globals(), locals(), 'xen.xm')
  13.618      cmd.main([command] + args)
  13.619  
  13.620  
  13.621  #############################################################
  13.622  
  13.623 -def cpu_make_map(cpulist):
  13.624 -    cpus = []
  13.625 -    for c in cpulist.split(','):
  13.626 -        if c.find('-') != -1:
  13.627 -            (x,y) = c.split('-')
  13.628 -            for i in range(int(x),int(y)+1):
  13.629 -                cpus.append(int(i))
  13.630 -        else:
  13.631 -            cpus.append(int(c))
  13.632 -    cpus.sort()
  13.633 -    return cpus
  13.634 -
  13.635  def xm_vcpu_pin(args):
  13.636      arg_check(args, "vcpu-pin", 3)
  13.637  
  13.638 +    def cpu_make_map(cpulist):
  13.639 +        cpus = []
  13.640 +        for c in cpulist.split(','):
  13.641 +            if c.find('-') != -1:
  13.642 +                (x,y) = c.split('-')
  13.643 +                for i in range(int(x),int(y)+1):
  13.644 +                    cpus.append(int(i))
  13.645 +            else:
  13.646 +                cpus.append(int(c))
  13.647 +        cpus.sort()
  13.648 +        return cpus
  13.649 +
  13.650      dom  = args[0]
  13.651      vcpu = int(args[1])
  13.652      cpumap = cpu_make_map(args[2])
  13.653 @@ -719,11 +824,12 @@ def xm_sched_sedf(args):
  13.654          info['period']  = ns_to_ms(info['period'])
  13.655          info['slice']   = ns_to_ms(info['slice'])
  13.656          info['latency'] = ns_to_ms(info['latency'])
  13.657 -        print( ("%(name)-32s %(dom)3d %(period)9.1f %(slice)9.1f" +
  13.658 +        print( ("%(name)-32s %(domid)3d %(period)9.1f %(slice)9.1f" +
  13.659                  " %(latency)7.1f %(extratime)6d %(weight)6d") % info)
  13.660  
  13.661      def domid_match(domid, info):
  13.662 -        return domid is None or domid == info['name'] or domid == str(info['dom'])
  13.663 +        return domid is None or domid == info['name'] or \
  13.664 +               domid == str(info['domid'])
  13.665  
  13.666      # we want to just display current info if no parameters are passed
  13.667      if len(args) == 0:
  13.668 @@ -757,20 +863,25 @@ def xm_sched_sedf(args):
  13.669          elif k in ['-w', '--weight']:
  13.670              opts['weight'] = v
  13.671  
  13.672 +    doms = filter(lambda x : domid_match(domid, x),
  13.673 +                        [parse_doms_info(dom) for dom in getDomains("")])
  13.674 +
  13.675      # print header if we aren't setting any parameters
  13.676      if len(opts.keys()) == 0:
  13.677 -        print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s'%('Name','ID','Period(ms)',
  13.678 -                                                     'Slice(ms)', 'Lat(ms)',
  13.679 -                                                     'Extra','Weight')
  13.680 -
  13.681 -    doms = filter(lambda x : domid_match(domid, x),
  13.682 -                        [parse_doms_info(dom) for dom in getDomains("")])
  13.683 +        print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s' % \
  13.684 +              ('Name','ID','Period(ms)', 'Slice(ms)', 'Lat(ms)',
  13.685 +               'Extra','Weight')
  13.686 +    
  13.687      for d in doms:
  13.688          # fetch current values so as not to clobber them
  13.689 -        sedf_info = \
  13.690 -            parse_sedf_info(server.xend.domain.cpu_sedf_get(d['dom']))
  13.691 +        try:
  13.692 +            sedf_raw = server.xend.domain.cpu_sedf_get(d['domid'])
  13.693 +        except xmlrpclib.Fault:
  13.694 +            # domain does not support sched-sedf?
  13.695 +            sedf_raw = {}
  13.696 +
  13.697 +        sedf_info = parse_sedf_info(sedf_raw)
  13.698          sedf_info['name'] = d['name']
  13.699 -
  13.700          # update values in case of call to set
  13.701          if len(opts.keys()) > 0:
  13.702              for k in opts.keys():
  13.703 @@ -780,7 +891,7 @@ def xm_sched_sedf(args):
  13.704              v = map(int, [sedf_info['period'], sedf_info['slice'],
  13.705                            sedf_info['latency'],sedf_info['extratime'], 
  13.706                            sedf_info['weight']])
  13.707 -            rv = server.xend.domain.cpu_sedf_set(d['dom'], *v)
  13.708 +            rv = server.xend.domain.cpu_sedf_set(d['domid'], *v)
  13.709              if int(rv) != 0:
  13.710                  err("Failed to set sedf parameters (rv=%d)."%(rv))
  13.711  
  13.712 @@ -789,17 +900,14 @@ def xm_sched_sedf(args):
  13.713              print_sedf(sedf_info)
  13.714  
  13.715  def xm_sched_credit(args):
  13.716 -    usage_msg = """sched-credit:     Set or get credit scheduler parameters
  13.717 - Usage:
  13.718 -
  13.719 -        sched-credit -d domain [-w weight] [-c cap]
  13.720 -    """
  13.721 +    """Get/Set options for Credit Scheduler."""
  13.722 +    
  13.723      try:
  13.724 -        opts, args = getopt.getopt(args[0:], "d:w:c:",
  13.725 +        opts, params = getopt.getopt(args, "d:w:c:",
  13.726              ["domain=", "weight=", "cap="])
  13.727 -    except getopt.GetoptError:
  13.728 -        # print help information and exit:
  13.729 -        print usage_msg
  13.730 +    except getopt.GetoptError, opterr:
  13.731 +        err(opterr)
  13.732 +        usage('sched-credit')
  13.733          sys.exit(1)
  13.734  
  13.735      domain = None
  13.736 @@ -816,15 +924,16 @@ def xm_sched_credit(args):
  13.737  
  13.738      if domain is None:
  13.739          # place holder for system-wide scheduler parameters
  13.740 -        print usage_msg
  13.741 +        err("No domain given.")
  13.742 +        usage('sched-credit')
  13.743          sys.exit(1)
  13.744  
  13.745      if weight is None and cap is None:
  13.746          print server.xend.domain.sched_credit_get(domain)
  13.747      else:
  13.748 -        err = server.xend.domain.sched_credit_set(domain, weight, cap)
  13.749 -        if err != 0:
  13.750 -            print err
  13.751 +        result = server.xend.domain.sched_credit_set(domain, weight, cap)
  13.752 +        if result != 0:
  13.753 +            err(str(result))
  13.754  
  13.755  def xm_info(args):
  13.756      arg_check(args, "info", 0)
  13.757 @@ -843,6 +952,8 @@ def xm_console(args):
  13.758      dom = args[0]
  13.759      info = server.xend.domain(dom)
  13.760      domid = int(sxp.child_value(info, 'domid', '-1'))
  13.761 +    if domid == -1:
  13.762 +        raise Exception("Domain is not started")
  13.763      console.execConsole(domid)
  13.764  
  13.765  def xm_uptime(args):
  13.766 @@ -899,6 +1010,12 @@ def xm_uptime(args):
  13.767  
  13.768          print upstring
  13.769  
  13.770 +def xm_sysrq(args):
  13.771 +    arg_check(args, "sysrq", 2)
  13.772 +    dom = args[0]
  13.773 +    req = args[1]
  13.774 +    server.xend.domain.send_sysrq(dom, req)    
  13.775 +
  13.776  def xm_top(args):
  13.777      arg_check(args, "top", 0)
  13.778  
  13.779 @@ -920,8 +1037,11 @@ its contents if the [-c|--clear] flag is
  13.780      myargs = args
  13.781      myargs.insert(0, 'dmesg')
  13.782      gopts.parse(myargs)
  13.783 -    if not (1 <= len(myargs) <= 2):
  13.784 +    
  13.785 +    if len(myargs) not in (1, 2):
  13.786          err('Invalid arguments: ' + str(myargs))
  13.787 +        usage('dmesg')
  13.788 +        sys.exit(1)
  13.789  
  13.790      if not gopts.vals.clear:
  13.791          print server.xend.node.dmesg.info()
  13.792 @@ -939,7 +1059,7 @@ def xm_serve(args):
  13.793      from fcntl import fcntl, F_SETFL
  13.794      
  13.795      s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  13.796 -    s.connect(xen.xend.XendClient.XML_RPC_SOCKET)
  13.797 +    s.connect(XendClient.XML_RPC_SOCKET)
  13.798      fcntl(sys.stdin, F_SETFL, os.O_NONBLOCK)
  13.799  
  13.800      while True:
  13.801 @@ -1085,7 +1205,7 @@ def parse_block_configuration(args):
  13.802          cls = 'tap'
  13.803      else:
  13.804          cls = 'vbd'
  13.805 -        
  13.806 +
  13.807      vbd = [cls,
  13.808             ['uname', args[1]],
  13.809             ['dev',   args[2]],
  13.810 @@ -1094,19 +1214,12 @@ def parse_block_configuration(args):
  13.811          vbd.append(['backend', args[4]])
  13.812  
  13.813      # verify that policy permits attaching this resource
  13.814 -    try:
  13.815 -        if security.on():
  13.816 -            dominfo = server.xend.domain(dom)
  13.817 -            label = security.get_security_printlabel(dominfo)
  13.818 -        else:
  13.819 -            label = None
  13.820 +    if security.on():
  13.821 +        dominfo = server.xend.domain(dom)
  13.822 +        label = security.get_security_printlabel(dominfo)
  13.823 +    else:
  13.824 +        label = None
  13.825          security.res_security_check(args[1], label)
  13.826 -    except security.ACMError, e:
  13.827 -        print e.value
  13.828 -        sys.exit(1)
  13.829 -    except:
  13.830 -        traceback.print_exc(limit=1)
  13.831 -        sys.exit(1)
  13.832  
  13.833      return (dom, vbd)
  13.834  
  13.835 @@ -1206,11 +1319,12 @@ commands = {
  13.836      "domid": xm_domid,
  13.837      "domname": xm_domname,
  13.838      "dump-core": xm_dump_core,
  13.839 +    "reboot": xm_reboot,    
  13.840      "rename": xm_rename,
  13.841      "restore": xm_restore,
  13.842      "save": xm_save,
  13.843 -    "reboot": xm_reboot,
  13.844      "shutdown": xm_shutdown,
  13.845 +    "sysrq": xm_sysrq,
  13.846      "uptime": xm_uptime,
  13.847      "list": xm_list,
  13.848      # memory commands
  13.849 @@ -1249,24 +1363,23 @@ commands = {
  13.850      }
  13.851  
  13.852  ## The commands supported by a separate argument parser in xend.xm.
  13.853 -subcommands = [
  13.854 +IMPORTED_COMMANDS = [
  13.855      'create',
  13.856      'migrate',
  13.857 -    'sysrq',
  13.858      'labels',
  13.859      'addlabel',
  13.860 +    'cfgbootpolicy',
  13.861 +    'makepolicy',
  13.862 +    'loadpolicy',
  13.863 +    'dumppolicy'
  13.864      'rmlabel',
  13.865      'getlabel',
  13.866      'dry-run',
  13.867      'resources',
  13.868 -    'cfgbootpolicy',
  13.869 -    'makepolicy',
  13.870 -    'loadpolicy',
  13.871 -    'dumppolicy'
  13.872      ]
  13.873  
  13.874 -for c in subcommands:
  13.875 -    commands[c] = eval('lambda args: xm_subcommand("%s", args)' % c)
  13.876 +for c in IMPORTED_COMMANDS:
  13.877 +    commands[c] = eval('lambda args: xm_importcommand("%s", args)' % c)
  13.878  
  13.879  aliases = {
  13.880      "balloon": "mem-set",
  13.881 @@ -1284,11 +1397,18 @@ def xm_lookup_cmd(cmd):
  13.882      elif aliases.has_key(cmd):
  13.883          deprecated(cmd,aliases[cmd])
  13.884          return commands[aliases[cmd]]
  13.885 +    elif cmd == 'help':
  13.886 +        longHelp()
  13.887 +        sys.exit(0)
  13.888      else:
  13.889 -        if len( cmd ) > 1:
  13.890 -            matched_commands = filter( lambda (command, func): command[ 0:len(cmd) ] == cmd, commands.iteritems() )
  13.891 -            if len( matched_commands ) == 1:
  13.892 -		        return matched_commands[0][1]
  13.893 +        # simulate getopt's prefix matching behaviour
  13.894 +        if len(cmd) > 1:
  13.895 +            same_prefix_cmds = [commands[c] for c in commands.keys() \
  13.896 +                                if c[:len(cmd)] == cmd]
  13.897 +            # only execute if there is only 1 match
  13.898 +            if len(same_prefix_cmds) == 1:
  13.899 +                return same_prefix_cmds[0]
  13.900 +            
  13.901          err('Sub Command %s not found!' % cmd)
  13.902          usage()
  13.903  
  13.904 @@ -1296,27 +1416,17 @@ def deprecated(old,new):
  13.905      print >>sys.stderr, (
  13.906          "Command %s is deprecated.  Please use xm %s instead." % (old, new))
  13.907  
  13.908 -def usage(cmd=None):
  13.909 -    if cmd == 'create':
  13.910 -        mycmd = xm_lookup_cmd(cmd)
  13.911 -        mycmd( ['--help'] )
  13.912 -        sys.exit(1)
  13.913 -    if help.has_key(cmd):
  13.914 -        print "   " + help[cmd]
  13.915 -    else:
  13.916 -        print shorthelp
  13.917 -    sys.exit(1)
  13.918 -
  13.919  def main(argv=sys.argv):
  13.920      if len(argv) < 2:
  13.921          usage()
  13.922 -    
  13.923 -    if re.compile('-*help').match(argv[1]):
  13.924 -	if len(argv) > 2:
  13.925 -	    usage(argv[2])
  13.926 -	else:
  13.927 -	    usage()
  13.928 -	sys.exit(0)
  13.929 +
  13.930 +    # intercept --help and output our own help
  13.931 +    if '--help' in argv[1:]:
  13.932 +        if '--help' == argv[1]:
  13.933 +            longHelp()
  13.934 +        else:
  13.935 +            usage(argv[1])
  13.936 +        sys.exit(0)
  13.937  
  13.938      cmd = xm_lookup_cmd(argv[1])
  13.939  
  13.940 @@ -1329,9 +1439,9 @@ def main(argv=sys.argv):
  13.941                  usage()
  13.942          except socket.error, ex:
  13.943              if os.geteuid() != 0:
  13.944 -                err("Most commands need root access.  Please try again as root.")
  13.945 +                err("Most commands need root access. Please try again as root.")
  13.946              else:
  13.947 -                err("Error connecting to xend: %s.  Is xend running?" % ex[1])
  13.948 +                err("Unable to connect to xend: %s. Is xend running?" % ex[1])
  13.949              sys.exit(1)
  13.950          except KeyboardInterrupt:
  13.951              print "Interrupted."
  13.952 @@ -1340,16 +1450,16 @@ def main(argv=sys.argv):
  13.953              if os.geteuid() != 0:
  13.954                  err("Most commands need root access.  Please try again as root.")
  13.955              else:
  13.956 -                err("Error connecting to xend: %s." % ex[1])
  13.957 +                err("Unable to connect to xend: %s." % ex[1])
  13.958              sys.exit(1)
  13.959          except SystemExit:
  13.960              sys.exit(1)
  13.961          except xmlrpclib.Fault, ex:
  13.962 -            if ex.faultCode == xen.xend.XendClient.ERROR_INVALID_DOMAIN:
  13.963 -                print  >>sys.stderr, (
  13.964 -                    "Error: the domain '%s' does not exist." % ex.faultString)
  13.965 +            if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
  13.966 +                err("Domain '%s' does not exist." % ex.faultString)
  13.967              else:
  13.968 -                print  >>sys.stderr, "Error: %s" % ex.faultString
  13.969 +                err(ex.faultString)
  13.970 +            usage(argv[1])
  13.971              sys.exit(1)
  13.972          except xmlrpclib.ProtocolError, ex:
  13.973              if ex.errcode == -1:
  13.974 @@ -1364,6 +1474,10 @@ def main(argv=sys.argv):
  13.975          except (ValueError, OverflowError):
  13.976              err("Invalid argument.")
  13.977              usage(argv[1])
  13.978 +        except OptionError, e:
  13.979 +            err(str(e))
  13.980 +            usage(argv[1])
  13.981 +            print e.usage()
  13.982          except:
  13.983              print "Unexpected error:", sys.exc_info()[0]
  13.984              print
    14.1 --- a/tools/python/xen/xm/makepolicy.py	Fri Sep 22 17:21:52 2006 +0100
    14.2 +++ b/tools/python/xen/xm/makepolicy.py	Fri Sep 22 17:22:18 2006 +0100
    14.3 @@ -20,7 +20,7 @@
    14.4  import sys
    14.5  import traceback
    14.6  from xen.util.security import ACMError, err, make_policy
    14.7 -
    14.8 +from xen.xm.opts import OptionError
    14.9  
   14.10  def usage():
   14.11      print "\nUsage: xm makepolicy <policy>\n"
   14.12 @@ -29,13 +29,12 @@ def usage():
   14.13      err("Usage")
   14.14  
   14.15  
   14.16 +def main(argv):
   14.17 +    if len(argv) != 2:
   14.18 +        raise OptionError('No XML policy file specified')
   14.19  
   14.20 -def main(argv):
   14.21      try:
   14.22 -        if len(argv) != 2:
   14.23 -            usage()
   14.24          make_policy(argv[1])
   14.25 -
   14.26      except ACMError:
   14.27          sys.exit(-1)
   14.28      except:
   14.29 @@ -43,7 +42,6 @@ def main(argv):
   14.30          sys.exit(-1)
   14.31  
   14.32  
   14.33 -
   14.34  if __name__ == '__main__':
   14.35      main(sys.argv)
   14.36  
    15.1 --- a/tools/python/xen/xm/migrate.py	Fri Sep 22 17:21:52 2006 +0100
    15.2 +++ b/tools/python/xen/xm/migrate.py	Fri Sep 22 17:22:18 2006 +0100
    15.3 @@ -46,19 +46,17 @@ gopts.opt('resource', short='r', val='MB
    15.4            fn=set_int, default=0,
    15.5            use="Set level of resource usage for migration.")
    15.6  
    15.7 -def help(argv):
    15.8 -    gopts.argv = argv
    15.9 -    gopts.usage()
   15.10 +def help():
   15.11 +    return str(gopts)
   15.12      
   15.13  def main(argv):
   15.14      opts = gopts
   15.15      args = opts.parse(argv)
   15.16 -    if opts.vals.help:
   15.17 -        opts.usage()
   15.18 -        return
   15.19 +    
   15.20      if len(args) != 2:
   15.21 -        opts.usage()
   15.22 -        sys.exit(1)
   15.23 +        raise OptionError('Invalid number of arguments')
   15.24 +
   15.25      dom = args[0]
   15.26      dst = args[1]
   15.27 -    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource, opts.vals.port)
   15.28 +    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource,
   15.29 +                               opts.vals.port)
    16.1 --- a/tools/python/xen/xm/opts.py	Fri Sep 22 17:21:52 2006 +0100
    16.2 +++ b/tools/python/xen/xm/opts.py	Fri Sep 22 17:22:18 2006 +0100
    16.3 @@ -24,6 +24,42 @@ import os.path
    16.4  import sys
    16.5  import types
    16.6  
    16.7 +def _line_wrap(text, width = 70):
    16.8 +    lines = []
    16.9 +    current_line = ''
   16.10 +    words = text.strip().split()
   16.11 +    while words:
   16.12 +        word = words.pop(0)
   16.13 +        if len(current_line) + len(word) + 1 < width:
   16.14 +            current_line += word + ' '
   16.15 +        else:
   16.16 +            lines.append(current_line.strip())
   16.17 +            current_line = word + ' '
   16.18 +            
   16.19 +    if current_line:
   16.20 +        lines.append(current_line.strip())
   16.21 +    return lines
   16.22 +
   16.23 +def wrap(text, width = 70):
   16.24 +    """ Really basic textwrap. Useful because textwrap is not available
   16.25 +    for Python 2.2, and textwrap.wrap ignores newlines in Python 2.3+.
   16.26 +    """
   16.27 +    if len(text) < width:
   16.28 +        return [text]
   16.29 +    
   16.30 +    lines = []
   16.31 +    for line in text.split('\n'):
   16.32 +        lines += _line_wrap(line, width)
   16.33 +    return lines
   16.34 +
   16.35 +class OptionError(Exception):
   16.36 +    """Denotes an error in option parsing."""
   16.37 +    def __init__(self, message, usage = ''):
   16.38 +        self.message = message
   16.39 +        self.usage = usage
   16.40 +    def __str__(self):
   16.41 +        return self.message
   16.42 +
   16.43  class Opt:
   16.44      """An individual option.
   16.45      """
   16.46 @@ -72,7 +108,21 @@ class Opt:
   16.47      def __repr__(self):
   16.48          return self.name + '=' + str(self.specified_val)
   16.49  
   16.50 -    __str__ = __repr__
   16.51 +    def __str__(self):
   16.52 +        """ Formats the option into:
   16.53 +        '-k, --key     description'
   16.54 +        """
   16.55 +        PARAM_WIDTH = 20
   16.56 +        if self.val:
   16.57 +            keys = ', '.join(['%s=%s' % (k, self.val) for k in self.optkeys])
   16.58 +        else:
   16.59 +            keys = ', '.join(self.optkeys)
   16.60 +        desc = wrap(self.use, 55)
   16.61 +        if len(keys) > PARAM_WIDTH:
   16.62 +            desc = [''] + desc
   16.63 +            
   16.64 +        wrapped = ('\n' + ' ' * (PARAM_WIDTH + 1)).join(desc)
   16.65 +        return keys.ljust(PARAM_WIDTH + 1) + wrapped
   16.66  
   16.67      def set(self, value):
   16.68          """Set the option value.
   16.69 @@ -243,8 +293,24 @@ class Opts:
   16.70      def __repr__(self):
   16.71          return '\n'.join(map(str, self.options))
   16.72  
   16.73 -    __str__ = __repr__
   16.74 +    def __str__(self):
   16.75 +        options = [s for s in self.options if s.optkeys[0][0] == '-']
   16.76 +        output = ''
   16.77 +        if options:
   16.78 +            output += '\nOptions:\n\n'
   16.79 +            output += '\n'.join([str(o) for o in options])
   16.80 +            output += '\n'
   16.81 +        return output
   16.82  
   16.83 +    def val_usage(self):
   16.84 +        optvals = [s for s in self.options if s.optkeys[0][0] != '-']
   16.85 +        output = ''
   16.86 +        if optvals:
   16.87 +            output += '\nValues:\n\n'
   16.88 +            output += '\n'.join([str(o) for o in optvals])
   16.89 +            output += '\n'
   16.90 +        return output
   16.91 +    
   16.92      def opt(self, name, **args):
   16.93          """Add an option.
   16.94  
   16.95 @@ -338,14 +404,14 @@ class Opts:
   16.96                                                self.short_opts(),
   16.97                                                self.long_opts())
   16.98              except getopt.GetoptError, err:
   16.99 -                self.err(str(err))
  16.100 +                raise OptionError(str(err), self.use)
  16.101 +            #self.err(str(err))
  16.102                  
  16.103              for (k, v) in xvals:
  16.104                  for opt in self.options:
  16.105                      if opt.specify(k, v): break
  16.106                  else:
  16.107 -                    print >>sys.stderr, "Error: Unknown option:", k
  16.108 -                    self.usage()
  16.109 +                    raise OptionError('Unknown option: %s' % k, self.use)
  16.110  
  16.111              if not args:
  16.112                  break
  16.113 @@ -390,10 +456,10 @@ class Opts:
  16.114      def usage(self):
  16.115          print 'Usage: ', self.argv[0], self.use or 'OPTIONS'
  16.116          print
  16.117 -        for opt in self.options:
  16.118 -            opt.show()
  16.119 -            print
  16.120          if self.options:
  16.121 +            for opt in self.options:
  16.122 +                opt.show()
  16.123 +                print
  16.124              print
  16.125  
  16.126      def var_usage(self):
  16.127 @@ -427,7 +493,9 @@ class Opts:
  16.128                  self.load(p, help)
  16.129                  break
  16.130          else:
  16.131 -            self.err('Cannot open config file "%s"' % self.vals.defconfig)
  16.132 +            raise OptionError('Unable to open config file: %s' % \
  16.133 +                              self.vals.defconfig,
  16.134 +                              self.use)
  16.135  
  16.136      def load(self, defconfig, help):
  16.137          """Load a defconfig file. Local variables in the file
  16.138 @@ -478,9 +546,9 @@ def set_false(opt, k, v):
  16.139  def set_bool(opt, k, v):
  16.140      """Set a boolean option.
  16.141      """
  16.142 -    if v in ['yes']:
  16.143 +    if v in ('yes', 'y'):
  16.144          opt.set(1)
  16.145 -    elif v in ['no']:
  16.146 +    elif v in ('no', 'n'):
  16.147          opt.set(0)
  16.148      else:
  16.149          opt.opts.err('Invalid value:' +v)
    17.1 --- a/tools/python/xen/xm/resources.py	Fri Sep 22 17:21:52 2006 +0100
    17.2 +++ b/tools/python/xen/xm/resources.py	Fri Sep 22 17:22:18 2006 +0100
    17.3 @@ -21,13 +21,12 @@
    17.4  import sys
    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 resource\n"
   17.11 -    print "  This program lists information for each resource in the"
   17.12 -    print "  global resource label file\n"
   17.13 -    security.err("Usage")
   17.14 -
   17.15 +def help():
   17.16 +    return """Usage: xm resource
   17.17 +    This program lists information for each resource in the
   17.18 +    global resource label file."""
   17.19  
   17.20  def print_resource_data(access_control):
   17.21      """Prints out a resource dictionary to stdout
   17.22 @@ -38,11 +37,16 @@ def print_resource_data(access_control):
   17.23          print "    policy: "+policy
   17.24          print "    label:  "+label
   17.25  
   17.26 -
   17.27  def main (argv):
   17.28 +    if len(argv) > 1:
   17.29 +        raise OptionError("No arguments required")
   17.30 +    
   17.31      try:
   17.32 -        if len(argv) != 1:
   17.33 -            usage()
   17.34 +        filename = security.res_label_filename
   17.35 +        access_control = dictio.dict_read("resources", filename)
   17.36 +    except:
   17.37 +        print "Resource file not found."
   17.38 +        return
   17.39  
   17.40          try:
   17.41              file = security.res_label_filename
   17.42 @@ -52,9 +56,6 @@ def main (argv):
   17.43  
   17.44          print_resource_data(access_control)
   17.45  
   17.46 -    except security.ACMError:
   17.47 -        sys.exit(-1)
   17.48 -
   17.49  if __name__ == '__main__':
   17.50      main(sys.argv)
   17.51  
    18.1 --- a/tools/python/xen/xm/rmlabel.py	Fri Sep 22 17:21:52 2006 +0100
    18.2 +++ b/tools/python/xen/xm/rmlabel.py	Fri Sep 22 17:22:18 2006 +0100
    18.3 @@ -21,15 +21,17 @@
    18.4  import sys, os, re
    18.5  from xen.util import dictio
    18.6  from xen.util import security
    18.7 +from xen.xm.opts import OptionError
    18.8  
    18.9 -def usage():
   18.10 -    print "\nUsage: xm rmlabel dom <configfile>"
   18.11 -    print "       xm rmlabel res <resource>\n"
   18.12 -    print "  This program removes an acm_label entry from the 'configfile'"
   18.13 -    print "  for a domain or from the global resource label file for a"
   18.14 -    print "  resource. If the label does not exist for the given domain or"
   18.15 -    print "  resource, then rmlabel fails.\n"
   18.16 -    security.err("Usage")
   18.17 +def help():
   18.18 +    return """
   18.19 +    Example: xm rmlabel dom <configfile>
   18.20 +             xm rmlabel res <resource>
   18.21 +
   18.22 +    This program removes an acm_label entry from the 'configfile'
   18.23 +    for a domain or from the global resource label file for a
   18.24 +    resource. If the label does not exist for the given domain or
   18.25 +    resource, then rmlabel fails."""
   18.26  
   18.27  
   18.28  def rm_resource_label(resource):
   18.29 @@ -93,23 +95,23 @@ def rm_domain_label(configfile):
   18.30  
   18.31  
   18.32  def main (argv):
   18.33 +
   18.34 +    if len(argv) != 3:
   18.35 +        raise OptionError('Requires 2 arguments')
   18.36 +    
   18.37 +    if argv[1].lower() not in ('dom', 'res'):
   18.38 +        raise OptionError('Unrecognised type argument: %s' % argv[1])
   18.39 +
   18.40      try:
   18.41 -        if len(argv) != 3:
   18.42 -            usage()
   18.43 -
   18.44          if argv[1].lower() == "dom":
   18.45              configfile = argv[2]
   18.46              rm_domain_label(configfile)
   18.47          elif argv[1].lower() == "res":
   18.48              resource = argv[2]
   18.49              rm_resource_label(resource)
   18.50 -        else:
   18.51 -            usage()
   18.52 -
   18.53      except security.ACMError:
   18.54          sys.exit(-1)
   18.55  
   18.56 -
   18.57  if __name__ == '__main__':
   18.58      main(sys.argv)
   18.59  
    19.1 --- a/tools/python/xen/xm/shutdown.py	Fri Sep 22 17:21:52 2006 +0100
    19.2 +++ b/tools/python/xen/xm/shutdown.py	Fri Sep 22 17:22:18 2006 +0100
    19.3 @@ -120,7 +120,6 @@ def main(argv):
    19.4      opts = gopts
    19.5      args = opts.parse(argv)
    19.6      if opts.vals.help:
    19.7 -        opts.usage()
    19.8          return
    19.9      if opts.vals.all:
   19.10          main_all(opts, args)
    20.1 --- a/tools/python/xen/xm/sysrq.py	Fri Sep 22 17:21:52 2006 +0100
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,32 +0,0 @@
    20.4 -# (C) Matthew Bloch <matthew@bytemark.co.uk> 2004
    20.5 -# Copyright (C) 2005 XenSource Ltd
    20.6 -
    20.7 -"""Domain sysrq.
    20.8 -"""
    20.9 -
   20.10 -from xen.xend.XendClient import server
   20.11 -from xen.xm.opts import *
   20.12 -
   20.13 -gopts = Opts(use="""[DOM] [letter]
   20.14 -
   20.15 -Sends a Linux sysrq to a domain.
   20.16 -""")
   20.17 -
   20.18 -gopts.opt('help', short='h',
   20.19 -         fn=set_true, default=0,
   20.20 -         use="Print this help.")
   20.21 -
   20.22 -def main(argv):
   20.23 -    opts = gopts
   20.24 -    args = opts.parse(argv)
   20.25 -    if opts.vals.help:
   20.26 -        opts.usage()
   20.27 -        return
   20.28 -        
   20.29 -    # no options for the moment
   20.30 -    if len(args) != 2:
   20.31 -        opts.usage()
   20.32 -        sys.exit(1)
   20.33 -    dom = args[0]
   20.34 -    req = ord(args[1][0])
   20.35 -    server.xend.domain.send_sysrq(dom, req)
    21.1 --- a/xen/arch/x86/hvm/platform.c	Fri Sep 22 17:21:52 2006 +0100
    21.2 +++ b/xen/arch/x86/hvm/platform.c	Fri Sep 22 17:22:18 2006 +0100
    21.3 @@ -416,6 +416,11 @@ static int hvm_decode(int realmode, unsi
    21.4          GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
    21.5          return reg_mem(instr->op_size, opcode, instr, rex);
    21.6  
    21.7 +    case 0x3A: /* cmp r8, r8/m8 */
    21.8 +        instr->instr = INSTR_CMP;
    21.9 +        GET_OP_SIZE_FOR_BYTE(instr->op_size);
   21.10 +        return reg_mem(instr->op_size, opcode, instr, rex);
   21.11 +
   21.12      case 0x3B: /* cmp m32/16, r32/16 */
   21.13          instr->instr = INSTR_CMP;
   21.14          GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
   21.15 @@ -471,6 +476,11 @@ static int hvm_decode(int realmode, unsi
   21.16          GET_OP_SIZE_FOR_BYTE(size_reg);
   21.17          return mem_reg(size_reg, opcode, instr, rex);
   21.18  
   21.19 +    case 0x85: /* text m16/32, r16/32 */
   21.20 +        instr->instr = INSTR_TEST;
   21.21 +        GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
   21.22 +        return mem_reg(instr->op_size, opcode, instr, rex);
   21.23 +
   21.24      case 0x87:  /* xchg {r/m16|r/m32}, {m/r16|m/r32} */
   21.25          instr->instr = INSTR_XCHG;
   21.26          GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
    22.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Sep 22 17:21:52 2006 +0100
    22.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Sep 22 17:22:18 2006 +0100
    22.3 @@ -259,6 +259,17 @@ static int svm_paging_enabled(struct vcp
    22.4      return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
    22.5  }
    22.6  
    22.7 +static int svm_pae_enabled(struct vcpu *v)
    22.8 +{
    22.9 +    unsigned long cr4;
   22.10 +
   22.11 +    if(!svm_paging_enabled(v))
   22.12 +        return 0;
   22.13 +
   22.14 +    cr4 = v->arch.hvm_svm.cpu_shadow_cr4;
   22.15 +
   22.16 +    return (cr4 & X86_CR4_PAE);
   22.17 +}
   22.18  
   22.19  #define IS_CANO_ADDRESS(add) 1
   22.20  
   22.21 @@ -865,6 +876,7 @@ int start_svm(void)
   22.22      hvm_funcs.realmode = svm_realmode;
   22.23      hvm_funcs.paging_enabled = svm_paging_enabled;
   22.24      hvm_funcs.long_mode_enabled = svm_long_mode_enabled;
   22.25 +    hvm_funcs.pae_enabled = svm_pae_enabled;
   22.26      hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
   22.27      hvm_funcs.instruction_length = svm_instruction_length;
   22.28      hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
   22.29 @@ -1847,12 +1859,12 @@ static int svm_cr_access(struct vcpu *v,
   22.30         where the prefix lives later on */
   22.31      index = skip_prefix_bytes(buffer, sizeof(buffer));
   22.32      
   22.33 -    if (type == TYPE_MOV_TO_CR) 
   22.34 +    if ( type == TYPE_MOV_TO_CR )
   22.35      {
   22.36          inst_len = __get_instruction_length_from_list(
   22.37              vmcb, list_a, ARR_SIZE(list_a), &buffer[index], &match);
   22.38      }
   22.39 -    else
   22.40 +    else /* type == TYPE_MOV_FROM_CR */
   22.41      {
   22.42          inst_len = __get_instruction_length_from_list(
   22.43              vmcb, list_b, ARR_SIZE(list_b), &buffer[index], &match);
    23.1 --- a/xen/arch/x86/hvm/vmx/io.c	Fri Sep 22 17:21:52 2006 +0100
    23.2 +++ b/xen/arch/x86/hvm/vmx/io.c	Fri Sep 22 17:22:18 2006 +0100
    23.3 @@ -108,11 +108,17 @@ asmlinkage void vmx_intr_assist(void)
    23.4          return;
    23.5      }
    23.6  
    23.7 +    /* This could be moved earlier in the VMX resume sequence. */
    23.8      __vmread(IDT_VECTORING_INFO_FIELD, &idtv_info_field);
    23.9      if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) {
   23.10          __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
   23.11  
   23.12 -        __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
   23.13 +        /*
   23.14 +         * Safe: the length will only be interpreted for software exceptions
   23.15 +         * and interrupts. If we get here then delivery of some event caused a
   23.16 +         * fault, and this always results in defined VM_EXIT_INSTRUCTION_LEN.
   23.17 +         */
   23.18 +        __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len); /* Safe */
   23.19          __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
   23.20  
   23.21          if (unlikely(idtv_info_field & 0x800)) { /* valid error code */
    24.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Sep 22 17:21:52 2006 +0100
    24.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Sep 22 17:22:18 2006 +0100
    24.3 @@ -597,7 +597,7 @@ static int vmx_instruction_length(struct
    24.4  {
    24.5      unsigned long inst_len;
    24.6  
    24.7 -    if (__vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len))
    24.8 +    if ( __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len) ) /* XXX Unsafe XXX */
    24.9          return 0;
   24.10      return inst_len;
   24.11  }
   24.12 @@ -746,6 +746,7 @@ static void vmx_setup_hvm_funcs(void)
   24.13      hvm_funcs.realmode = vmx_realmode;
   24.14      hvm_funcs.paging_enabled = vmx_paging_enabled;
   24.15      hvm_funcs.long_mode_enabled = vmx_long_mode_enabled;
   24.16 +    hvm_funcs.pae_enabled = vmx_pae_enabled;
   24.17      hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
   24.18      hvm_funcs.instruction_length = vmx_instruction_length;
   24.19      hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
   24.20 @@ -836,11 +837,16 @@ int start_vmx(void)
   24.21  
   24.22  /*
   24.23   * Not all cases receive valid value in the VM-exit instruction length field.
   24.24 + * Callers must know what they're doing!
   24.25   */
   24.26 -#define __get_instruction_length(len) \
   24.27 -    __vmread(VM_EXIT_INSTRUCTION_LEN, &(len)); \
   24.28 -     if ((len) < 1 || (len) > 15) \
   24.29 -        __hvm_bug(&regs);
   24.30 +static int __get_instruction_length(void)
   24.31 +{
   24.32 +    int len;
   24.33 +    __vmread(VM_EXIT_INSTRUCTION_LEN, &len); /* Safe: callers audited */
   24.34 +    if ( (len < 1) || (len > 15) )
   24.35 +        __hvm_bug(guest_cpu_user_regs());
   24.36 +    return len;
   24.37 +}
   24.38  
   24.39  static void inline __update_guest_eip(unsigned long inst_len)
   24.40  {
   24.41 @@ -1051,15 +1057,18 @@ static int check_for_null_selector(unsig
   24.42      int i, inst_len;
   24.43      int inst_copy_from_guest(unsigned char *, unsigned long, int);
   24.44  
   24.45 -    __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
   24.46 +    inst_len = __get_instruction_length(); /* Safe: INS/OUTS */
   24.47      memset(inst, 0, MAX_INST_LEN);
   24.48 -    if (inst_copy_from_guest(inst, eip, inst_len) != inst_len) {
   24.49 +    if ( inst_copy_from_guest(inst, eip, inst_len) != inst_len )
   24.50 +    {
   24.51          printf("check_for_null_selector: get guest instruction failed\n");
   24.52          domain_crash_synchronous();
   24.53      }
   24.54  
   24.55 -    for (i = 0; i < inst_len; i++) {
   24.56 -        switch (inst[i]) {
   24.57 +    for ( i = 0; i < inst_len; i++ )
   24.58 +    {
   24.59 +        switch ( inst[i] )
   24.60 +        {
   24.61          case 0xf3: /* REPZ */
   24.62          case 0xf2: /* REPNZ */
   24.63          case 0xf0: /* LOCK */
   24.64 @@ -1184,15 +1193,14 @@ static void vmx_io_instruction(unsigned 
   24.65      }
   24.66  }
   24.67  
   24.68 -int
   24.69 -vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
   24.70 +static int vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
   24.71  {
   24.72 -    unsigned long inst_len;
   24.73      int error = 0;
   24.74  
   24.75 -    error |= __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
   24.76 +    /* NB. Skip transition instruction. */
   24.77      error |= __vmread(GUEST_RIP, &c->eip);
   24.78 -    c->eip += inst_len; /* skip transition instruction */
   24.79 +    c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
   24.80 +
   24.81      error |= __vmread(GUEST_RSP, &c->esp);
   24.82      error |= __vmread(GUEST_RFLAGS, &c->eflags);
   24.83  
   24.84 @@ -1249,8 +1257,7 @@ vmx_world_save(struct vcpu *v, struct vm
   24.85      return !error;
   24.86  }
   24.87  
   24.88 -int
   24.89 -vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
   24.90 +static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
   24.91  {
   24.92      unsigned long mfn, old_cr4, old_base_mfn;
   24.93      int error = 0;
   24.94 @@ -1364,8 +1371,7 @@ vmx_world_restore(struct vcpu *v, struct
   24.95  
   24.96  enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST_RESTORE };
   24.97  
   24.98 -int
   24.99 -vmx_assist(struct vcpu *v, int mode)
  24.100 +static int vmx_assist(struct vcpu *v, int mode)
  24.101  {
  24.102      struct vmx_assist_context c;
  24.103      u32 magic;
  24.104 @@ -1408,8 +1414,8 @@ vmx_assist(struct vcpu *v, int mode)
  24.105          break;
  24.106  
  24.107          /*
  24.108 -         * Restore the VMXASSIST_OLD_CONTEXT that was saved by VMX_ASSIST_INVOKE
  24.109 -         * above.
  24.110 +         * Restore the VMXASSIST_OLD_CONTEXT that was saved by
  24.111 +         * VMX_ASSIST_INVOKE above.
  24.112           */
  24.113      case VMX_ASSIST_RESTORE:
  24.114          /* save the old context */
  24.115 @@ -1552,7 +1558,8 @@ static int vmx_set_cr0(unsigned long val
  24.116              }
  24.117          }
  24.118  
  24.119 -        if ( vmx_assist(v, VMX_ASSIST_INVOKE) ) {
  24.120 +        if ( vmx_assist(v, VMX_ASSIST_INVOKE) )
  24.121 +        {
  24.122              set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &v->arch.hvm_vmx.cpu_state);
  24.123              __vmread(GUEST_RIP, &eip);
  24.124              HVM_DBG_LOG(DBG_LEVEL_1,
  24.125 @@ -1815,7 +1822,8 @@ static void mov_from_cr(int cr, int gp, 
  24.126      HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR%d, value = %lx", cr, value);
  24.127  }
  24.128  
  24.129 -static int vmx_cr_access(unsigned long exit_qualification, struct cpu_user_regs *regs)
  24.130 +static int vmx_cr_access(unsigned long exit_qualification,
  24.131 +                         struct cpu_user_regs *regs)
  24.132  {
  24.133      unsigned int gp, cr;
  24.134      unsigned long value;
  24.135 @@ -2069,6 +2077,47 @@ void restore_cpu_user_regs(struct cpu_us
  24.136  }
  24.137  #endif
  24.138  
  24.139 +static void vmx_reflect_exception(struct vcpu *v)
  24.140 +{
  24.141 +    int error_code, intr_info, vector;
  24.142 +
  24.143 +    __vmread(VM_EXIT_INTR_INFO, &intr_info);
  24.144 +    vector = intr_info & 0xff;
  24.145 +    if ( intr_info & INTR_INFO_DELIVER_CODE_MASK )
  24.146 +        __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
  24.147 +    else
  24.148 +        error_code = VMX_DELIVER_NO_ERROR_CODE;
  24.149 +
  24.150 +#ifndef NDEBUG
  24.151 +    {
  24.152 +        unsigned long rip;
  24.153 +
  24.154 +        __vmread(GUEST_RIP, &rip);
  24.155 +        HVM_DBG_LOG(DBG_LEVEL_1, "rip = %lx, error_code = %x",
  24.156 +                    rip, error_code);
  24.157 +    }
  24.158 +#endif /* NDEBUG */
  24.159 +
  24.160 +    /*
  24.161 +     * According to Intel Virtualization Technology Specification for
  24.162 +     * the IA-32 Intel Architecture (C97063-002 April 2005), section
  24.163 +     * 2.8.3, SW_EXCEPTION should be used for #BP and #OV, and
  24.164 +     * HW_EXCEPTION used for everything else.  The main difference
  24.165 +     * appears to be that for SW_EXCEPTION, the EIP/RIP is incremented
  24.166 +     * by VM_ENTER_INSTRUCTION_LEN bytes, whereas for HW_EXCEPTION,
  24.167 +     * it is not.
  24.168 +     */
  24.169 +    if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_SW_EXCEPTION )
  24.170 +    {
  24.171 +        int ilen = __get_instruction_length(); /* Safe: software exception */
  24.172 +        vmx_inject_sw_exception(v, vector, ilen);
  24.173 +    }
  24.174 +    else
  24.175 +    {
  24.176 +        vmx_inject_hw_exception(v, vector, error_code);
  24.177 +    }
  24.178 +}
  24.179 +
  24.180  asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
  24.181  {
  24.182      unsigned int exit_reason;
  24.183 @@ -2116,7 +2165,8 @@ asmlinkage void vmx_vmexit_handler(struc
  24.184  
  24.185      TRACE_VMEXIT(0,exit_reason);
  24.186  
  24.187 -    switch ( exit_reason ) {
  24.188 +    switch ( exit_reason )
  24.189 +    {
  24.190      case EXIT_REASON_EXCEPTION_NMI:
  24.191      {
  24.192          /*
  24.193 @@ -2242,43 +2292,38 @@ asmlinkage void vmx_vmexit_handler(struc
  24.194          domain_crash_synchronous();
  24.195          break;
  24.196      case EXIT_REASON_CPUID:
  24.197 +        inst_len = __get_instruction_length(); /* Safe: CPUID */
  24.198 +        __update_guest_eip(inst_len);
  24.199          vmx_vmexit_do_cpuid(&regs);
  24.200 -        __get_instruction_length(inst_len);
  24.201 -        __update_guest_eip(inst_len);
  24.202          break;
  24.203      case EXIT_REASON_HLT:
  24.204 -        __get_instruction_length(inst_len);
  24.205 +        inst_len = __get_instruction_length(); /* Safe: HLT */
  24.206          __update_guest_eip(inst_len);
  24.207          vmx_vmexit_do_hlt();
  24.208          break;
  24.209      case EXIT_REASON_INVLPG:
  24.210      {
  24.211 -        unsigned long   va;
  24.212 -
  24.213 +        unsigned long va;
  24.214 +        inst_len = __get_instruction_length(); /* Safe: INVLPG */
  24.215 +        __update_guest_eip(inst_len);
  24.216          __vmread(EXIT_QUALIFICATION, &va);
  24.217          vmx_vmexit_do_invlpg(va);
  24.218 -        __get_instruction_length(inst_len);
  24.219 -        __update_guest_eip(inst_len);
  24.220          break;
  24.221      }
  24.222      case EXIT_REASON_VMCALL:
  24.223      {
  24.224 -        __get_instruction_length(inst_len);
  24.225 +        inst_len = __get_instruction_length(); /* Safe: VMCALL */
  24.226 +        __update_guest_eip(inst_len);
  24.227          __vmread(GUEST_RIP, &rip);
  24.228          __vmread(EXIT_QUALIFICATION, &exit_qualification);
  24.229 -
  24.230          hvm_do_hypercall(&regs);
  24.231 -        __update_guest_eip(inst_len);
  24.232          break;
  24.233      }
  24.234      case EXIT_REASON_CR_ACCESS:
  24.235      {
  24.236          __vmread(GUEST_RIP, &rip);
  24.237 -        __get_instruction_length(inst_len);
  24.238          __vmread(EXIT_QUALIFICATION, &exit_qualification);
  24.239 -
  24.240 -        HVM_DBG_LOG(DBG_LEVEL_1, "rip = %lx, inst_len =%lx, exit_qualification = %lx",
  24.241 -                    rip, inst_len, exit_qualification);
  24.242 +        inst_len = __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
  24.243          if ( vmx_cr_access(exit_qualification, &regs) )
  24.244              __update_guest_eip(inst_len);
  24.245          TRACE_VMEXIT(3,regs.error_code);
  24.246 @@ -2291,19 +2336,19 @@ asmlinkage void vmx_vmexit_handler(struc
  24.247          break;
  24.248      case EXIT_REASON_IO_INSTRUCTION:
  24.249          __vmread(EXIT_QUALIFICATION, &exit_qualification);
  24.250 -        __get_instruction_length(inst_len);
  24.251 +        inst_len = __get_instruction_length(); /* Safe: IN, INS, OUT, OUTS */
  24.252          vmx_io_instruction(exit_qualification, inst_len);
  24.253          TRACE_VMEXIT(4,exit_qualification);
  24.254          break;
  24.255      case EXIT_REASON_MSR_READ:
  24.256 -        __get_instruction_length(inst_len);
  24.257 +        inst_len = __get_instruction_length(); /* Safe: RDMSR */
  24.258 +        __update_guest_eip(inst_len);
  24.259          vmx_do_msr_read(&regs);
  24.260 -        __update_guest_eip(inst_len);
  24.261          break;
  24.262      case EXIT_REASON_MSR_WRITE:
  24.263 +        inst_len = __get_instruction_length(); /* Safe: WRMSR */
  24.264 +        __update_guest_eip(inst_len);
  24.265          vmx_do_msr_write(&regs);
  24.266 -        __get_instruction_length(inst_len);
  24.267 -        __update_guest_eip(inst_len);
  24.268          break;
  24.269      case EXIT_REASON_MWAIT_INSTRUCTION:
  24.270      case EXIT_REASON_MONITOR_INSTRUCTION:
    25.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Sep 22 17:21:52 2006 +0100
    25.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Sep 22 17:22:18 2006 +0100
    25.3 @@ -2343,7 +2343,7 @@ void sh_update_paging_modes(struct vcpu 
    25.4              }
    25.5              else
    25.6  #endif
    25.7 -                if ( hvm_get_guest_ctrl_reg(v, 4) & X86_CR4_PAE )
    25.8 +                if ( hvm_pae_enabled(v) )
    25.9                  {
   25.10  #if CONFIG_PAGING_LEVELS >= 3
   25.11                      // 32-bit PAE mode guest...
    26.1 --- a/xen/include/asm-x86/hvm/hvm.h	Fri Sep 22 17:21:52 2006 +0100
    26.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Fri Sep 22 17:22:18 2006 +0100
    26.3 @@ -57,6 +57,7 @@ struct hvm_function_table {
    26.4      int (*realmode)(struct vcpu *v);
    26.5      int (*paging_enabled)(struct vcpu *v);
    26.6      int (*long_mode_enabled)(struct vcpu *v);
    26.7 +    int (*pae_enabled)(struct vcpu *v);
    26.8      int (*guest_x86_mode)(struct vcpu *v);
    26.9      int (*instruction_length)(struct vcpu *v);
   26.10      unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
   26.11 @@ -146,6 +147,12 @@ hvm_long_mode_enabled(struct vcpu *v)
   26.12      return hvm_funcs.long_mode_enabled(v);
   26.13  }
   26.14  
   26.15 + static inline int
   26.16 +hvm_pae_enabled(struct vcpu *v)
   26.17 +{
   26.18 +    return hvm_funcs.pae_enabled(v);
   26.19 +}
   26.20 +
   26.21  static inline int
   26.22  hvm_guest_x86_mode(struct vcpu *v)
   26.23  {
    27.1 --- a/xen/include/asm-x86/hvm/svm/emulate.h	Fri Sep 22 17:21:52 2006 +0100
    27.2 +++ b/xen/include/asm-x86/hvm/svm/emulate.h	Fri Sep 22 17:22:18 2006 +0100
    27.3 @@ -94,15 +94,14 @@ extern int __get_instruction_length_from
    27.4  static inline int __get_instruction_length(struct vmcb_struct *vmcb, 
    27.5          enum instruction_index instr, u8 *guest_eip_buf)
    27.6  {
    27.7 -    return __get_instruction_length_from_list(vmcb, &instr, 1, guest_eip_buf, 
    27.8 -            NULL);
    27.9 +    return __get_instruction_length_from_list(
   27.10 +        vmcb, &instr, 1, guest_eip_buf, NULL);
   27.11  }
   27.12  
   27.13  
   27.14  static inline unsigned int is_prefix(u8 opc)
   27.15  {
   27.16 -    switch(opc)
   27.17 -    {
   27.18 +    switch ( opc ) {
   27.19      case 0x66:
   27.20      case 0x67:
   27.21      case 0x2E:
   27.22 @@ -115,22 +114,7 @@ static inline unsigned int is_prefix(u8 
   27.23      case 0xF3:
   27.24      case 0xF2:
   27.25  #if __x86_64__
   27.26 -    case 0x40:
   27.27 -    case 0x41:
   27.28 -    case 0x42:
   27.29 -    case 0x43:
   27.30 -    case 0x44:
   27.31 -    case 0x45:
   27.32 -    case 0x46:
   27.33 -    case 0x47:
   27.34 -    case 0x48:
   27.35 -    case 0x49:
   27.36 -    case 0x4a:
   27.37 -    case 0x4b:
   27.38 -    case 0x4c:
   27.39 -    case 0x4d:
   27.40 -    case 0x4e:
   27.41 -    case 0x4f:
   27.42 +    case 0x40 ... 0x4f:
   27.43  #endif /* __x86_64__ */
   27.44          return 1;
   27.45      }
   27.46 @@ -141,15 +125,15 @@ static inline unsigned int is_prefix(u8 
   27.47  static inline int skip_prefix_bytes(u8 *buf, size_t size)
   27.48  {
   27.49      int index;
   27.50 -    for (index = 0; index < size && is_prefix(buf[index]); index ++)  
   27.51 -        /* do nothing */ ;
   27.52 +    for ( index = 0; index < size && is_prefix(buf[index]); index++ )
   27.53 +        continue;
   27.54      return index;
   27.55  }
   27.56  
   27.57  
   27.58  
   27.59 -static void inline __update_guest_eip(struct vmcb_struct *vmcb, 
   27.60 -        int inst_len) 
   27.61 +static void inline __update_guest_eip(
   27.62 +    struct vmcb_struct *vmcb, int inst_len) 
   27.63  {
   27.64      ASSERT(inst_len > 0);
   27.65      vmcb->rip += inst_len;
    28.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Sep 22 17:21:52 2006 +0100
    28.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Sep 22 17:22:18 2006 +0100
    28.3 @@ -39,6 +39,9 @@ enum {
    28.4  #define VMX_LONG_GUEST(ed)    \
    28.5    (test_bit(VMX_CPU_STATE_LMA_ENABLED, &ed->arch.hvm_vmx.cpu_state))
    28.6  
    28.7 +#define VMX_PAE_GUEST(ed)       \
    28.8 +  (test_bit(VMX_CPU_STATE_PAE_ENABLED, &ed->arch.hvm_vmx.cpu_state))
    28.9 +
   28.10  struct vmcs_struct {
   28.11      u32 vmcs_revision_id;
   28.12      unsigned char data [0]; /* vmcs size is read from MSR */
    29.1 --- a/xen/include/asm-x86/hvm/vmx/vmx.h	Fri Sep 22 17:21:52 2006 +0100
    29.2 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h	Fri Sep 22 17:22:18 2006 +0100
    29.3 @@ -418,6 +418,12 @@ static inline int vmx_long_mode_enabled(
    29.4      return VMX_LONG_GUEST(current);
    29.5  }
    29.6  
    29.7 +static inline int vmx_pae_enabled(struct vcpu *v)
    29.8 +{
    29.9 +    ASSERT(v == current);
   29.10 +    return VMX_PAE_GUEST(current);
   29.11 +}
   29.12 +
   29.13  /* Works only for vcpu == current */
   29.14  static inline int vmx_realmode(struct vcpu *v)
   29.15  {
   29.16 @@ -469,7 +475,7 @@ static inline void __vmx_inject_exceptio
   29.17      if ( error_code != VMX_DELIVER_NO_ERROR_CODE ) {
   29.18          __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
   29.19          intr_fields |= INTR_INFO_DELIVER_CODE_MASK;
   29.20 -     }
   29.21 +    }
   29.22  
   29.23      if ( ilen )
   29.24        __vmwrite(VM_ENTRY_INSTRUCTION_LEN, ilen);
   29.25 @@ -499,40 +505,4 @@ static inline void vmx_inject_extint(str
   29.26      __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
   29.27  }
   29.28  
   29.29 -static inline void vmx_reflect_exception(struct vcpu *v)
   29.30 -{
   29.31 -    int error_code, intr_info, vector;
   29.32 -
   29.33 -    __vmread(VM_EXIT_INTR_INFO, &intr_info);
   29.34 -    vector = intr_info & 0xff;
   29.35 -    if ( intr_info & INTR_INFO_DELIVER_CODE_MASK )
   29.36 -        __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
   29.37 -    else
   29.38 -        error_code = VMX_DELIVER_NO_ERROR_CODE;
   29.39 -
   29.40 -#ifndef NDEBUG
   29.41 -    {
   29.42 -        unsigned long rip;
   29.43 -
   29.44 -        __vmread(GUEST_RIP, &rip);
   29.45 -        HVM_DBG_LOG(DBG_LEVEL_1, "rip = %lx, error_code = %x",
   29.46 -                    rip, error_code);
   29.47 -    }
   29.48 -#endif /* NDEBUG */
   29.49 -
   29.50 -    /* According to Intel Virtualization Technology Specification for
   29.51 -       the IA-32 Intel Architecture (C97063-002 April 2005), section
   29.52 -       2.8.3, SW_EXCEPTION should be used for #BP and #OV, and
   29.53 -       HW_EXCPEPTION used for everything else.  The main difference
   29.54 -       appears to be that for SW_EXCEPTION, the EIP/RIP is incremented
   29.55 -       by VM_ENTER_INSTRUCTION_LEN bytes, whereas for HW_EXCEPTION,
   29.56 -       it is not.  */
   29.57 -    if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_SW_EXCEPTION ) {
   29.58 -        int ilen;
   29.59 -        __vmread(VM_EXIT_INSTRUCTION_LEN, &ilen);
   29.60 -        vmx_inject_sw_exception(v, vector, ilen);
   29.61 -    } else
   29.62 -        vmx_inject_hw_exception(v, vector, error_code);
   29.63 -}
   29.64 -
   29.65  #endif /* __ASM_X86_HVM_VMX_VMX_H__ */
    30.1 --- a/xen/include/asm-x86/mm.h	Fri Sep 22 17:21:52 2006 +0100
    30.2 +++ b/xen/include/asm-x86/mm.h	Fri Sep 22 17:22:18 2006 +0100
    30.3 @@ -181,9 +181,6 @@ void init_frametable(void);
    30.4  int alloc_page_type(struct page_info *page, unsigned long type);
    30.5  void free_page_type(struct page_info *page, unsigned long type);
    30.6  extern void invalidate_shadow_ldt(struct vcpu *d);
    30.7 -extern int shadow_remove_all_write_access(
    30.8 -    struct domain *d, unsigned long gmfn, unsigned long mfn);
    30.9 -extern u32 shadow_remove_all_access( struct domain *d, unsigned long gmfn);
   30.10  extern int _shadow_mode_refcounts(struct domain *d);
   30.11  
   30.12  static inline void put_page(struct page_info *page)