[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] merge



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 1ca87f35ee4e8b85663dd64787ec730cf3fe7de9
# Parent  4a3d9fa6ba24d80fbd1d541288e4e456d4d642ee
# Parent  0e9055d69f12e230ed086bd9445aef863a16e129
merge
---
 tools/firmware/vmxassist/machine.h   |    1 
 tools/firmware/vmxassist/vm86.c      |   87 +++-
 tools/python/xen/xm/addlabel.py      |   37 +
 tools/python/xen/xm/cfgbootpolicy.py |   25 -
 tools/python/xen/xm/console.py       |    2 
 tools/python/xen/xm/create.py        |   71 +--
 tools/python/xen/xm/dry-run.py       |   20 -
 tools/python/xen/xm/dumppolicy.py    |   11 
 tools/python/xen/xm/getlabel.py      |   36 -
 tools/python/xen/xm/labels.py        |   77 +---
 tools/python/xen/xm/loadpolicy.py    |   19 -
 tools/python/xen/xm/main.py          |  658 ++++++++++++++++++++---------------
 tools/python/xen/xm/makepolicy.py    |   10 
 tools/python/xen/xm/migrate.py       |   16 
 tools/python/xen/xm/opts.py          |   90 ++++
 tools/python/xen/xm/resources.py     |   25 -
 tools/python/xen/xm/rmlabel.py       |   32 -
 tools/python/xen/xm/sysrq.py         |   14 
 xen/arch/x86/hvm/svm/svm.c           |   12 
 xen/arch/x86/hvm/vmx/vmx.c           |    1 
 xen/arch/x86/mm/shadow/common.c      |    2 
 xen/include/asm-x86/hvm/hvm.h        |    7 
 xen/include/asm-x86/hvm/vmx/vmcs.h   |    3 
 xen/include/asm-x86/hvm/vmx/vmx.h    |    6 
 24 files changed, 744 insertions(+), 518 deletions(-)

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

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.