direct-io.hg

changeset 1530:396e842f2f14

bitkeeper revision 1.995 (40d7059ek3ICHR5Iebek8AzkIdzn7Q)

Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
author xenbk@gandalf.hpl.hp.com
date Mon Jun 21 15:58:22 2004 +0000 (2004-06-21)
parents a815a43920c0 2c0b02513019
children 793f5eb5d149
files .rootkeys BitKeeper/etc/logging_ok docs/xen_config.html tools/xc/py/Xc.c tools/xenmgr/lib/EventServer.py tools/xenmgr/lib/XendClient.py tools/xenmgr/lib/XendConsole.py tools/xenmgr/lib/XendDomain.py tools/xenmgr/lib/XendDomainInfo.py tools/xenmgr/lib/server/SrvConsoleServer.py tools/xenmgr/lib/server/blkif.py tools/xenmgr/lib/server/controller.py tools/xenmgr/lib/server/messages.py tools/xenmgr/lib/server/netif.py tools/xenmgr/lib/xm/create.py tools/xenmgr/lib/xm/main.py tools/xenmgr/lib/xm/opts.py tools/xenmgr/lib/xm/shutdown.py tools/xenmgr/netfix
line diff
     1.1 --- a/.rootkeys	Mon Jun 21 14:15:58 2004 +0000
     1.2 +++ b/.rootkeys	Mon Jun 21 15:58:22 2004 +0000
     1.3 @@ -16,6 +16,7 @@ 3f9e7d60PWZJeVh5xdnk0nLUdxlqEA docs/eps/
     1.4  3f9e7d63lTwQbp2fnx7yY93epWS-eQ docs/figs/dummy
     1.5  3f9e7d564bWFB-Czjv1qdmE6o0GqNg docs/interface.tex
     1.6  3f9e7d58t7N6hjjBMxSn-NMxBphchA docs/style.tex
     1.7 +40d6ccbfKKBq8jE0ula4eHEzBiQuDA docs/xen_config.html
     1.8  3f9e7d5bz8BwYkNuwyiPVu7JJG441A docs/xenstyle.cls
     1.9  3f815144d1vI2777JI-dO4wk49Iw7g extras/mini-os/Makefile
    1.10  3f815144zTnCV5591ulIJQrpe5b-5Q extras/mini-os/README
     2.1 --- a/BitKeeper/etc/logging_ok	Mon Jun 21 14:15:58 2004 +0000
     2.2 +++ b/BitKeeper/etc/logging_ok	Mon Jun 21 15:58:22 2004 +0000
     2.3 @@ -38,3 +38,4 @@ smh22@uridium.cl.cam.ac.uk
     2.4  sos22@labyrinth.cl.cam.ac.uk
     2.5  tlh20@elite.cl.cam.ac.uk
     2.6  tlh20@labyrinth.cl.cam.ac.uk
     2.7 +xenbk@gandalf.hpl.hp.com
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/docs/xen_config.html	Mon Jun 21 15:58:22 2004 +0000
     3.3 @@ -0,0 +1,192 @@
     3.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     3.5 +<html>
     3.6 +<head>
     3.7 +  <meta http-equiv="content-type"
     3.8 + content="text/html; charset=ISO-8859-1">
     3.9 +  <title>Xen Configuration Syntax</title>
    3.10 +</head>
    3.11 +<body>
    3.12 +<center>
    3.13 +<h1>Xen Configuration Syntax</h1>
    3.14 +<br>
    3.15 +Version 0.1<br>2004 June 21<br>
    3.16 +</center>
    3.17 +
    3.18 +<h1>Xen Configuration</h1>
    3.19 +The Xen virtual machine creation tools provide command-line interfaces and
    3.20 +HTTP interfaces to creating virtual machines. Underneath all these interfaces
    3.21 +virtual machine configuration data is represented in a common configuration syntax
    3.22 +called SXP.
    3.23 +
    3.24 +The SXP syntax is s-expressions (sxprs), a simple bracketed abstract syntax.
    3.25 +Python lists are used to represent its parsed form, with a support
    3.26 +api providing  access to fields and values (class xenmgr.sxp).
    3.27 +
    3.28 +<h1>SXP syntax</h1>
    3.29 +<p>A general s-expression has the syntax:
    3.30 +<code><pre>
    3.31 +s-exp = '(' s-exp* ')' | atom | string
    3.32 +</pre></code>
    3.33 +Where an <code>atom</code> is an unquoted string, such as fred or /domain/0.
    3.34 +A <code>string</code> is a quoted string, supporting the usual escape sequences.
    3.35 +Strings support single or double quotes: 'fred 1' or "fred 2" are both accepted.
    3.36 +The characters ()[]&lt;&gt{} are separators.
    3.37 +
    3.38 +<p>An <code>element</code> is an s-expression representing data similar to XML.
    3.39 +It has the form:
    3.40 +<code><pre>
    3.41 +element    = '(' name attributes? value* ')'
    3.42 +name       = atom
    3.43 +attributes = '(' '@' attribute* ')'
    3.44 +attribute  = '(' attrname attrval ')'
    3.45 +attrname   = atom
    3.46 +attrval    = atom | string
    3.47 +value      = element | atom | string
    3.48 +</pre></code>
    3.49 +The <code>name</code> is the element name (roughly indentifying its type).
    3.50 +The <code>attributes</code> is a list of attribute-values.
    3.51 +We usually prefer to avoid using attributes, and use sub-elements instead.
    3.52 +As in XML, any element may have the attribute <code>id</code> to give it an identifier
    3.53 +for later reference.
    3.54 +
    3.55 +<h1>VM configuration</h1>
    3.56 +A vm configuration is a single SXP vm element, with subelements for
    3.57 +vm parameters and devices. The supported elements and their fields
    3.58 +are listed below.
    3.59 +
    3.60 +<h2>(vm) element</h2>
    3.61 +The top-level element, a virtual machine configuration.
    3.62 +<ul>
    3.63 +    <li>name: string, required. Domain name.
    3.64 +    <li>id: int, optional, default generated. Domain unique id.
    3.65 +    <li>memory: int, optional, default 128. Domain memory in MB.
    3.66 +    <li>image: linux | netbsd | ..., required. Domain image (OS-specific element).
    3.67 +    <li>controller: any device controller type, optional, default none.
    3.68 +    <li>device: any device type, optional, repeats. Device.
    3.69 +    <li>auto-restart: bool, optional, default false. Auto-restart flag.
    3.70 +</ul>
    3.71 +
    3.72 +<h2>(image (linux)) element</h2>
    3.73 +Defines a linux kernel image and its command-line parameters.
    3.74 +<ul>
    3.75 +    <li>kernel: string, required. Kernel image file (absolute path).
    3.76 +    <li>root: string, optional. Root device.
    3.77 +    <li>ip: string, optional. IP address specifier.
    3.78 +    <li>ramdisk: string, optional, default none. Ramdisk file (absolute path).
    3.79 +    <li>args: string, optional. Extra kernel args.
    3.80 +</ul>
    3.81 +
    3.82 +<h2>(image (netbsd)) element</h2>
    3.83 +Defines a netbsd kernel image and its command-line parameters.
    3.84 +<ul>
    3.85 +    <li>kernel: string, required. Kernel image file.
    3.86 +    <li>root: string, optional. Root device.
    3.87 +    <li>ip: string, optional. IP address specifier.
    3.88 +    <li>ramdisk: string, optional, default none. Ramdisk file.
    3.89 +    <li>args: string, optional. Extra kernel args.
    3.90 +</ul>
    3.91 +
    3.92 +<h2>(controller (block)) element</h2>
    3.93 +Define that the vm is a block device controller backend.
    3.94 +The vm can have pci devices configured, but no virtual
    3.95 +block devices.
    3.96 +
    3.97 +<h2>(controller (net)) element</h2>
    3.98 +Define that the vm is a net device controller backend.
    3.99 +The domain may not have virtual network interfaces (vifs) configured.
   3.100 +
   3.101 +<h2>(device (vif)) element</h2>
   3.102 +Defines a virtual network interface.
   3.103 +<ul>
   3.104 +    <li>mac: string, optional, default generated. Interface MAC address.
   3.105 +    <li>quota info: optional. Subelements bytes and usecs.
   3.106 +    <li>bridge: string, optional, default system-dependent. Bridge to connect to.
   3.107 +</ul>
   3.108 +A random MAC is assined is not specified.
   3.109 +The interface is connected to the system default bridge if no bridge
   3.110 +is specified.
   3.111 +
   3.112 +<h2>(device (vbd)) element</h2>
   3.113 +Defines a virtual block device.
   3.114 +<ul>
   3.115 +    <li>uname: string, required. Virtual block device id, e.g phys:hda1.
   3.116 +    <li>dev: string, required. Device file name in domain, e.g. xda1.
   3.117 +    <li>mode: string, optional, default r. Read-write mode: r | rw | w.
   3.118 +</ul>
   3.119 +The uname field defines the device being exported from the block device
   3.120 +controller. The dev field defines the device name the vm will see.
   3.121 +The device is read-only unless the mode contains w.
   3.122 +
   3.123 +<h2>(device (pci)) element</h2>
   3.124 +Defines a pci device. 
   3.125 +<ul>
   3.126 +    <li>bus: int, required. PCI bus id.
   3.127 +    <li>dev: int, required. PCI dev id.
   3.128 +    <li>func: int, required. PCI func id.
   3.129 +</ul>
   3.130 +The bus, dev or func may be given in hex,
   3.131 +e.g. 0xff. With no leading 0x they are interpreted as decimal.
   3.132 +
   3.133 +<h2>(vnet) element</h2>
   3.134 +Defines the virtual networks associated with vifs (may go away soon).
   3.135 +Contains a list of vif elements:
   3.136 +<ul>
   3.137 +  <li>id: id of the vif being configured.
   3.138 +  <li>vnet: id of vnet the vif is assigned to.
   3.139 +</ul>
   3.140 +
   3.141 +<h2>(vfr) element</h2>
   3.142 +Defines the ip addresses for vifs (may go away soon).
   3.143 +Contains a list of vif elements:
   3.144 +<ul>
   3.145 +  <li>id: vif index
   3.146 +  <li>ip: vif ip address
   3.147 +</ul>
   3.148 +
   3.149 +<h1>Examples</h1>
   3.150 +<p> A vm  with 64 MB memory, root on /dev/xda1 (mapped from /dev/hda1),
   3.151 +one vif with default MAC.
   3.152 +<code><pre>
   3.153 +(vm
   3.154 +    (name xendom1)
   3.155 +    (memory 64)
   3.156 +    (image
   3.157 +        (linux
   3.158 +            (kernel /boot/vmlinuz-2.4.26-xen)
   3.159 +            (ip ::::xendom1:eth0:dhcp)
   3.160 +            (root /dev/xda1)
   3.161 +            (args 'rw fastboot 4')
   3.162 +        )
   3.163 +    )
   3.164 +    (device (vif))
   3.165 +    (device (vbd (uname phy:hda1) (dev xda1) (mode w)))
   3.166 +)
   3.167 +</pre></code>
   3.168 +
   3.169 +<p>A vm with 64 MB memory, NFS root, and 2 vifs on separate vnets.
   3.170 +<code><pre>
   3.171 +(vm 
   3.172 +   (name xendom2)
   3.173 +   (memory 64)
   3.174 +    # Define a linux image.
   3.175 +    (image
   3.176 +        (linux 
   3.177 +            (kernel "/boot/vmlinuz-2.4.26-xen")
   3.178 +            (ip     "::::xendom2:eth0:dhcp")
   3.179 +            (root   "/dev/nfs")
   3.180 +            (args   "rw fastboot nfsroot=15.144.25.79:/opt/xen/xendom2 4")
   3.181 +         )
   3.182 +    )
   3.183 +    # Define some vifs, with ids for use later.
   3.184 +    (device (vif (@ (id vif1)) (mac aa:00:00:00:00:12)))
   3.185 +    (device (vif (@ (id vif2)) (mac aa:00:00:00:10:12)))
   3.186 +
   3.187 +     # Configure vnets. Refer to vifs by id.
   3.188 +     (vnet (vif (id vif1) (vnet 1))
   3.189 +           (vif (id vif2) (vnet 2)))
   3.190 +
   3.191 +)
   3.192 +</pre></code>
   3.193 +
   3.194 +</body>
   3.195 +</html>
     5.1 --- a/tools/xenmgr/lib/EventServer.py	Mon Jun 21 14:15:58 2004 +0000
     5.2 +++ b/tools/xenmgr/lib/EventServer.py	Mon Jun 21 15:58:22 2004 +0000
     5.3 @@ -85,7 +85,8 @@ class EventServer:
     5.4          hl = self.handlers.get(event)
     5.5          if hl is None:
     5.6              return
     5.7 -        hl.remove(handler)
     5.8 +        if handler in hl:
     5.9 +            hl.remove(handler)
    5.10  
    5.11      def inject(self, event, val):
    5.12          """Inject an event. Handlers for it are called if runing, otherwise
     6.1 --- a/tools/xenmgr/lib/XendClient.py	Mon Jun 21 14:15:58 2004 +0000
     6.2 +++ b/tools/xenmgr/lib/XendClient.py	Mon Jun 21 15:58:22 2004 +0000
     6.3 @@ -244,29 +244,12 @@ class Xend:
     6.4          return xend_get(self.domainurl(id),
     6.5                          { 'op'      : 'vifs' })
     6.6      
     6.7 -    def xend_domain_vif_stats(self, id, vif):
     6.8 -        return xend_get(self.domainurl(id),
     6.9 -                        { 'op'      : 'vif_stats',
    6.10 -                          'vif'     : vif})
    6.11 -
    6.12      def xend_domain_vif_ip_add(self, id, vif, ipaddr):
    6.13          return xend_call(self.domainurl(id),
    6.14                           {'op'      : 'vif_ip_add',
    6.15                            'vif'     : vif,
    6.16                            'ip'      : ipaddr })
    6.17          
    6.18 -    def xend_domain_vif_scheduler_set(id, vif, bytes, usecs):
    6.19 -        return xend_call(self.domainurl(id),
    6.20 -                         {'op'      : 'vif_scheduler_set',
    6.21 -                          'vif'     : vif,
    6.22 -                          'bytes'   : bytes,
    6.23 -                          'usecs'   : usecs })
    6.24 -
    6.25 -    def xend_domain_vif_scheduler_get(id, vif):
    6.26 -        return xend_get(self.domainurl(id),
    6.27 -                         {'op'      : 'vif_scheduler_get',
    6.28 -                          'vif'     : vif})
    6.29 -
    6.30      def xend_domain_vbds(self, id):
    6.31          return xend_get(self.domainurl(id),
    6.32                          {'op'       : 'vbds'})
    6.33 @@ -276,18 +259,6 @@ class Xend:
    6.34                          {'op'       : 'vbd',
    6.35                           'vbd'      : vbd})
    6.36  
    6.37 -##     def xend_domain_vbd_add(self, id, uname, dev, mode):
    6.38 -##         return xend_call(self.domainurl(id),
    6.39 -##                          {'op'      : 'vbd_add',
    6.40 -##                           'uname'   : uname,
    6.41 -##                           'dev'     : dev,
    6.42 -##                           'mode'    : mode})
    6.43 -
    6.44 -##     def xend_domain_vbd_remove(self, id, dev):
    6.45 -##         return xend_call(self.domainurl(id),
    6.46 -##                          {'op'      : 'vbd_remove',
    6.47 -##                           'dev'     : dev})
    6.48 -
    6.49      def xend_consoles(self):
    6.50          return xend_get(self.consoleurl())
    6.51  
     7.1 --- a/tools/xenmgr/lib/XendConsole.py	Mon Jun 21 14:15:58 2004 +0000
     7.2 +++ b/tools/xenmgr/lib/XendConsole.py	Mon Jun 21 15:58:22 2004 +0000
     7.3 @@ -104,8 +104,10 @@ class XendConsole:
     7.4                  self._delete_console(c.id)
     7.5  
     7.6      def onDomainDied(self, event, val):
     7.7 +        print 'onDomainDied', "dom=", dom,
     7.8          dom = int(val)
     7.9          for c in self.consoles():
    7.10 +            print 'onDomainDied', "dom=", dom, "dom1=", c.dom1, "dom2=", c.dom2
    7.11              if (c.dom1 == dom) or (c.dom2 == dom):
    7.12                  self._delete_console(c.id)
    7.13  
     8.1 --- a/tools/xenmgr/lib/XendDomain.py	Mon Jun 21 14:15:58 2004 +0000
     8.2 +++ b/tools/xenmgr/lib/XendDomain.py	Mon Jun 21 15:58:22 2004 +0000
     8.3 @@ -18,6 +18,9 @@ import XendDomainInfo
     8.4  import XendConsole
     8.5  import EventServer
     8.6  
     8.7 +from xenmgr.server import SrvConsoleServer
     8.8 +xend = SrvConsoleServer.instance()
     8.9 +
    8.10  eserver = EventServer.instance()
    8.11  
    8.12  __all__ = [ "XendDomain" ]
    8.13 @@ -49,15 +52,16 @@ class XendDomain:
    8.14      def initial_refresh(self):
    8.15          """Refresh initial domain info from domain_db.
    8.16          """
    8.17 -        print "initial_refresh> db=", self.domain_db.values()
    8.18 +        print "initial_refresh>"
    8.19 +        for d in self.domain_db.values(): print 'db dom=', d
    8.20          domlist = xc.domain_getinfo()
    8.21 -        print "doms=", domlist
    8.22 +        for d in domlist: print 'xc dom=', d
    8.23          doms = {}
    8.24          for d in domlist:
    8.25              domid = str(d['dom'])
    8.26              doms[domid] = d
    8.27          for config in self.domain_db.values():
    8.28 -            domid = int(sxp.child_value(config, 'id'))
    8.29 +            domid = str(sxp.child_value(config, 'id'))
    8.30              print "dom=", domid, "config=", config
    8.31              if domid in doms:
    8.32                  print "dom=", domid, "new"
    8.33 @@ -141,7 +145,7 @@ class XendDomain:
    8.34                  config = None
    8.35                  image = None
    8.36                  newinfo = XendDomainInfo.XendDomainInfo(
    8.37 -                    config, d['dom'], d['name'], d['mem_kb']/1024, image)
    8.38 +                    config, d['dom'], d['name'], d['mem_kb']/1024, image=image, info=d)
    8.39                  self._add_domain(newinfo.id, newinfo)
    8.40          # Remove entries for domains that no longer exist.
    8.41          for d in self.domain.values():
    8.42 @@ -193,13 +197,13 @@ class XendDomain:
    8.43          """
    8.44          dom = int(id)
    8.45          eserver.inject('xend.domain.start', id)
    8.46 -        return xc.domain_start(dom=dom)
    8.47 +        return xend.domain_start(dom)
    8.48      
    8.49      def domain_stop(self, id):
    8.50          """Stop domain running.
    8.51          """
    8.52          dom = int(id)
    8.53 -        return xc.domain_stop(dom=dom)
    8.54 +        return xend.domain_stop(dom)
    8.55      
    8.56      def domain_shutdown(self, id):
    8.57          """Shutdown domain (nicely).
    8.58 @@ -208,7 +212,7 @@ class XendDomain:
    8.59          if dom <= 0:
    8.60              return 0
    8.61          eserver.inject('xend.domain.shutdown', id)
    8.62 -        val = xc.domain_destroy(dom=dom, force=0)
    8.63 +        val = xend.domain_destroy(dom, force=0)
    8.64          self.refresh()
    8.65          return val
    8.66      
    8.67 @@ -219,7 +223,7 @@ class XendDomain:
    8.68          if dom <= 0:
    8.69              return 0
    8.70          eserver.inject('xend.domain.halt', id)
    8.71 -        val = xc.domain_destroy(dom=dom, force=1)
    8.72 +        val = xend.domain_destroy(dom, force=1)
    8.73          self.refresh()
    8.74          return val       
    8.75  
    8.76 @@ -247,21 +251,6 @@ class XendDomain:
    8.77          self._add_domain(dominfo.id, dominfo)
    8.78          return dominfo
    8.79      
    8.80 -    def domain_device_add(self, id, info):
    8.81 -        """Add a device to a domain.
    8.82 -        """
    8.83 -        pass
    8.84 -    
    8.85 -    def domain_device_remove(self, id, dev):
    8.86 -        """Delete a device from a domain.
    8.87 -        """
    8.88 -        pass
    8.89 -    
    8.90 -    def domain_device_configure(self, id, dev, info):
    8.91 -        """Configure a domain device.
    8.92 -        """
    8.93 -        pass
    8.94 -
    8.95      #============================================================================
    8.96      # Backward compatibility stuff from here on.
    8.97  
    8.98 @@ -297,23 +286,10 @@ class XendDomain:
    8.99          if not dominfo: return None
   8.100          return dominfo.get_device_by_index(vif)
   8.101  
   8.102 -    def domain_vif_stats(self, dom, vif):
   8.103 -        dom = int(dom)
   8.104 -        return xc.vif_stats_get(dom=dom, vif=vif)
   8.105 -
   8.106      def domain_vif_ip_add(self, dom, vif, ip):
   8.107          dom = int(dom)
   8.108          return xenctl.ip.setup_vfr_rules_for_vif(dom, vif, ip)
   8.109  
   8.110 -    def domain_vif_scheduler_set(self, dom, vif, bytes, usecs):
   8.111 -        dom = int(dom)
   8.112 -        return xc.xc_vif_scheduler_set(dom=dom, vif=vif,
   8.113 -                                       credit_bytes=bytes, credit_usecs=usecs)
   8.114 -
   8.115 -    def domain_vif_scheduler_get(self, dom, vif):
   8.116 -        dom = int(dom)
   8.117 -        return xc.vif_scheduler_get(dom=dom, vif=vif)
   8.118 -
   8.119      def domain_vbd_ls(self, dom):
   8.120          dominfo = self.domain_get(dom)
   8.121          if not dominfo: return []
   8.122 @@ -329,19 +305,6 @@ class XendDomain:
   8.123                  return v
   8.124          return None
   8.125  
   8.126 -##     def domain_vbd_add(self, dom, uname, dev, mode):
   8.127 -##         dom = int(dom)
   8.128 -##         vbd = vm.make_disk(dom, uname, dev, mode)
   8.129 -##         return vbd
   8.130 -
   8.131 -##     def domain_vbd_remove(self, dom, dev):
   8.132 -##         dom = int(dom)
   8.133 -##         vbd = xenctl.vdisk.blkdev_name_to_number(dev)
   8.134 -##         if vbd < 0: return vbd
   8.135 -##         err = xc.vbd_destroy(dom, vbd)
   8.136 -##         if err < 0: return err
   8.137 -##         return vbd
   8.138 -
   8.139      def domain_shadow_control(self, dom, op):
   8.140          dom = int(dom)
   8.141          return xc.shadow_control(dom, op)
     9.1 --- a/tools/xenmgr/lib/XendDomainInfo.py	Mon Jun 21 14:15:58 2004 +0000
     9.2 +++ b/tools/xenmgr/lib/XendDomainInfo.py	Mon Jun 21 15:58:22 2004 +0000
     9.3 @@ -28,6 +28,9 @@ xendConsole = XendConsole.instance()
     9.4  import server.SrvConsoleServer
     9.5  xend = server.SrvConsoleServer.instance()
     9.6  
     9.7 +SIF_BLK_BE_DOMAIN = (1<<4)
     9.8 +SIF_NET_BE_DOMAIN = (1<<5)
     9.9 +
    9.10  def readlines(fd):
    9.11      """Version of readlines safe against EINTR.
    9.12      """
    9.13 @@ -59,7 +62,7 @@ class VmError(ValueError):
    9.14  class XendDomainInfo:
    9.15      """Virtual machine object."""
    9.16  
    9.17 -    def __init__(self, config, dom, name, memory, image=None, console=None):
    9.18 +    def __init__(self, config, dom, name, memory, image=None, console=None, info=None):
    9.19          """Construct a virtual machine object.
    9.20  
    9.21          config   configuration
    9.22 @@ -78,8 +81,10 @@ class XendDomainInfo:
    9.23          self.console = console
    9.24          self.devices = {}
    9.25          self.configs = []
    9.26 -        self.info = None
    9.27 +        self.info = info
    9.28          self.ipaddrs = []
    9.29 +        self.block_controller = 0
    9.30 +        self.net_controller = 0
    9.31  
    9.32          #todo: state: running, suspended
    9.33          self.state = 'running'
    9.34 @@ -329,23 +334,28 @@ def xen_domain_create(config, ostype, na
    9.35      vifs_n  number of network interfaces
    9.36      returns vm
    9.37      """
    9.38 +    flags = 0
    9.39      if not os.path.isfile(kernel):
    9.40          raise VmError('Kernel image does not exist: %s' % kernel)
    9.41      if ramdisk and not os.path.isfile(ramdisk):
    9.42          raise VMError('Kernel ramdisk does not exist: %s' % ramdisk)
    9.43  
    9.44      cpu = int(sxp.child_value(config, 'cpu', '-1'))
    9.45 +    print 'xen_domain_create> create ', memory, name, cpu
    9.46      dom = xc.domain_create(mem_kb= memory * 1024, name= name, cpu= cpu)
    9.47      if dom <= 0:
    9.48          raise VmError('Creating domain failed: name=%s memory=%d kernel=%s'
    9.49                        % (name, memory, kernel))
    9.50      console = xendConsole.console_create(dom)
    9.51      buildfn = getattr(xc, '%s_build' % ostype)
    9.52 +    
    9.53 +    print 'xen_domain_create> build ', ostype, dom, kernel, cmdline, ramdisk
    9.54      err = buildfn(dom            = dom,
    9.55                    image          = kernel,
    9.56                    control_evtchn = console.port2,
    9.57                    cmdline        = cmdline,
    9.58 -                  ramdisk        = ramdisk)
    9.59 +                  ramdisk        = ramdisk,
    9.60 +                  flags          = flags)
    9.61      if err != 0:
    9.62          raise VmError('Building domain failed: type=%s dom=%d err=%d'
    9.63                        % (ostype, dom, err))
    9.64 @@ -528,6 +538,18 @@ def vm_create_devices(vm, config):
    9.65      print '<vm_create_devices'
    9.66      return deferred
    9.67  
    9.68 +def config_controllers(vm, config):
    9.69 +    for c in sxp.children(config, 'controller'):
    9.70 +        name = sxp.name(c)
    9.71 +        if name == 'block':
    9.72 +            vm.block_controller = 1
    9.73 +            xend.blkif_set_control_domain(vm.dom)
    9.74 +        elif name == 'net':
    9.75 +            vm.net_controller = 1
    9.76 +            xend.netif_set_control_domain(vm.dom)
    9.77 +        else:
    9.78 +            raise VmError('invalid controller type:' + str(name))
    9.79 +    
    9.80  def vm_configure(vm, config):
    9.81      """Configure a vm.
    9.82  
    9.83 @@ -536,7 +558,12 @@ def vm_configure(vm, config):
    9.84  
    9.85      returns Deferred - calls callback with vm
    9.86      """
    9.87 -    d = xend.blkif_create(vm.dom)
    9.88 +    config_controllers(vm, config)
    9.89 +    if vm.block_controller:
    9.90 +        d = defer.Deferred()
    9.91 +        d.callback(1)
    9.92 +    else:
    9.93 +        d = xend.blkif_create(vm.dom)
    9.94      d.addCallback(_vm_configure1, vm, config)
    9.95      return d
    9.96  
    9.97 @@ -653,8 +680,11 @@ def vm_dev_vif(vm, val, index):
    9.98      val       vif config
    9.99      index     vif index
   9.100      """
   9.101 +    if vm.net_controller:
   9.102 +        raise VmError('vif: vif in control domain')
   9.103      vif = index #todo
   9.104      vmac = sxp.child_value(val, "mac")
   9.105 +    bridge = sxp.child_value(val, "bridge") # todo
   9.106      defer = make_vif(vm.dom, vif, vmac)
   9.107      def fn(id):
   9.108          dev = val + ['vif', vif]
   9.109 @@ -671,6 +701,8 @@ def vm_dev_vbd(vm, val, index):
   9.110      val       vbd config
   9.111      index     vbd index
   9.112      """
   9.113 +    if vm.block_controller:
   9.114 +        raise VmError('vbd: vbd in control domain')
   9.115      uname = sxp.child_value(val, 'uname')
   9.116      if not uname:
   9.117          raise VMError('vbd: Missing uname')
   9.118 @@ -686,6 +718,16 @@ def vm_dev_vbd(vm, val, index):
   9.119      defer.addCallback(fn)
   9.120      return defer
   9.121  
   9.122 +def parse_pci(val):
   9.123 +    if isinstance(val, StringType):
   9.124 +        radix = 10
   9.125 +        if val.startswith('0x') or val.startswith('0X'):
   9.126 +            radix = 16
   9.127 +        v = int(val, radix)
   9.128 +    else:
   9.129 +        v = val
   9.130 +    return v
   9.131 +
   9.132  def vm_dev_pci(vm, val, index):
   9.133      bus = sxp.child_value(val, 'bus')
   9.134      if not bus:
   9.135 @@ -697,9 +739,9 @@ def vm_dev_pci(vm, val, index):
   9.136      if not func:
   9.137          raise VMError('pci: Missing func')
   9.138      try:
   9.139 -        bus = int(bus, 16)
   9.140 -        dev = int(dev, 16)
   9.141 -        func = int(func, 16)
   9.142 +        bus = parse_pci(bus)
   9.143 +        dev = parse_pci(dev)
   9.144 +        func = parse_pci(func)
   9.145      except:
   9.146          raise VMError('pci: invalid parameter')
   9.147      rc = xc.physdev_pci_access_modify(dom=vm.dom, bus=bus, dev=dev, func=func, enable=1)
    10.1 --- a/tools/xenmgr/lib/server/SrvConsoleServer.py	Mon Jun 21 14:15:58 2004 +0000
    10.2 +++ b/tools/xenmgr/lib/server/SrvConsoleServer.py	Mon Jun 21 15:58:22 2004 +0000
    10.3 @@ -21,6 +21,8 @@ from twisted.internet import protocol
    10.4  from twisted.internet import abstract
    10.5  from twisted.internet import defer
    10.6  
    10.7 +import Xc; xc = Xc.new()
    10.8 +
    10.9  import xend.utils
   10.10  
   10.11  from xenmgr import sxp
   10.12 @@ -289,6 +291,12 @@ class EventProtocol(protocol.Protocol):
   10.13              else:
   10.14                  self.send_error()
   10.15  
   10.16 +    def loseConnection(self):
   10.17 +        if self.transport:
   10.18 +            self.transport.loseConnection()
   10.19 +        if self.connected:
   10.20 +            reactor.callLater(0, self.connectionLost)
   10.21 +
   10.22      def connectionLost(self, reason=None):
   10.23          self.unsubscribe()
   10.24  
   10.25 @@ -559,6 +567,16 @@ class Daemon:
   10.26          reactor.diconnectAll()
   10.27          sys.exit(0)
   10.28  
   10.29 +    def blkif_set_control_domain(self, dom):
   10.30 +        """Set the block device backend control domain.
   10.31 +        """
   10.32 +        return self.blkifCF.setControlDomain(dom)
   10.33 +    
   10.34 +    def blkif_get_control_domain(self, dom):
   10.35 +        """Get the block device backend control domain.
   10.36 +        """
   10.37 +        return self.blkifCF.getControlDomain()
   10.38 +    
   10.39      def blkif_create(self, dom):
   10.40          """Create a block device interface controller.
   10.41          
   10.42 @@ -579,6 +597,16 @@ class Daemon:
   10.43          d = ctrl.attach_device(vdev, mode, segment)
   10.44          return d
   10.45  
   10.46 +    def netif_set_control_domain(self, dom):
   10.47 +        """Set the network interface backend control domain.
   10.48 +        """
   10.49 +        return self.netifCF.setControlDomain(dom)
   10.50 +
   10.51 +    def netif_get_control_domain(self, dom):
   10.52 +        """Get the network interface backend control domain.
   10.53 +        """
   10.54 +        return self.netifCF.getControlDomain()
   10.55 +    
   10.56      def netif_create(self, dom):
   10.57          """Create a network interface controller.
   10.58          
   10.59 @@ -622,6 +650,28 @@ class Daemon:
   10.60          if console.conn:
   10.61              console.conn.loseConnection()
   10.62  
   10.63 +    def domain_start(self, id):
   10.64 +        """Start domain running.
   10.65 +        """
   10.66 +        dom = int(id)
   10.67 +        if dom <= 0: return 0
   10.68 +        return xc.domain_start(dom=dom)
   10.69 +        
   10.70 +    def domain_stop(self, id):
   10.71 +        """Stop domain running.
   10.72 +        """
   10.73 +        dom = int(id)
   10.74 +        if dom <= 0: return 0 
   10.75 +        xc.domain_stop(dom=dom)
   10.76 +
   10.77 +    def domain_destroy(self, id, force=0):
   10.78 +        """Destroy a domain. Shutdown if force=0, terminate immediately if force=1.
   10.79 +        """
   10.80 +        dom = int(id)
   10.81 +        if dom <= 0: return 0 
   10.82 +        return xc.domain_destroy(dom=dom, force=force)
   10.83 +    
   10.84 +
   10.85  def instance():
   10.86      global inst
   10.87      try:
    11.1 --- a/tools/xenmgr/lib/server/blkif.py	Mon Jun 21 14:15:58 2004 +0000
    11.2 +++ b/tools/xenmgr/lib/server/blkif.py	Mon Jun 21 15:58:22 2004 +0000
    11.3 @@ -34,9 +34,9 @@ class BlkifControllerFactory(controller.
    11.4          return d
    11.5  
    11.6      def setControlDomain(self, dom):
    11.7 -        if self.channel:
    11.8 -            self.deregisterChannel()
    11.9 -            self.attached = 0
   11.10 +        if self.dom == dom: return
   11.11 +        self.deregisterChannel()
   11.12 +        self.attached = 0
   11.13          self.dom = dom
   11.14          self.registerChannel()
   11.15          #
   11.16 @@ -44,6 +44,9 @@ class BlkifControllerFactory(controller.
   11.17          #    xend.blkif.recovery = True
   11.18          #xend.blkif.be_port = xend.main.port_from_dom(dom)
   11.19  
   11.20 +    def getControlDomain(self):
   11.21 +        return self.dom
   11.22 +
   11.23      def recv_be_create(self, msg, req):
   11.24          #print 'recv_be_create>'
   11.25          val = unpackMsg('blkif_be_create_t', msg)
   11.26 @@ -81,15 +84,20 @@ class BlkifControllerFactory(controller.
   11.27          blkif = self.getInstanceByDom(dom)
   11.28          if blkif:
   11.29              blkif.reattach_device(vdev)
   11.30 +        self.attached = self.devices_attached()
   11.31 +        if self.attached:
   11.32 +            self.reattached()
   11.33 +
   11.34 +    def devices_attached(self):
   11.35 +        """Check if all devices are attached.
   11.36 +        """
   11.37          attached = 1
   11.38          for blkif in self.getInstances():
   11.39              if not blkif.attached:
   11.40                  attached = 0
   11.41                  break
   11.42 -        self.attached = attached
   11.43 -        if self.attached:
   11.44 -            self.reattached()
   11.45 -
   11.46 +        return attached
   11.47 +                         
   11.48      def reattached(self):
   11.49          for blkif in self.getInstances():
   11.50              blkif.reattached()
   11.51 @@ -149,12 +157,16 @@ class BlkifController(controller.Control
   11.52          return self.factory.addDeferred()
   11.53  
   11.54      def detach(self):
   11.55 +        """Detach all devices, when the back-end control domain has changed.
   11.56 +        """
   11.57          self.attached = 0
   11.58          for dev in self.devices.values():
   11.59              dev.attached = 0
   11.60              self.send_be_vbd_create(vdev)
   11.61  
   11.62      def reattach_device(self, vdev):
   11.63 +        """Reattach a device, when the back-end control domain has changed.
   11.64 +        """
   11.65          dev = self.devices[vdev]
   11.66          dev.attached = 1
   11.67          attached = 1
   11.68 @@ -166,6 +178,8 @@ class BlkifController(controller.Control
   11.69          return self.attached
   11.70  
   11.71      def reattached(self):
   11.72 +        """All devices have been reattached after the back-end control domain has changed.
   11.73 +        """
   11.74          msg = packMsg('blkif_fe_interface_status_changed_t',
   11.75                        { 'handle' : 0,
   11.76                          'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED})
    12.1 --- a/tools/xenmgr/lib/server/controller.py	Mon Jun 21 14:15:58 2004 +0000
    12.2 +++ b/tools/xenmgr/lib/server/controller.py	Mon Jun 21 15:58:22 2004 +0000
    12.3 @@ -37,9 +37,7 @@ class CtrlMsgRcvr:
    12.4      
    12.5      def registerChannel(self):
    12.6          self.channel = self.channelFactory.domChannel(self.dom)
    12.7 -        #print 'registerChannel> channel=', self.channel, self
    12.8          self.idx = self.channel.getIndex()
    12.9 -        #print 'registerChannel> idx=', self.idx
   12.10          if self.majorTypes:
   12.11              self.channel.registerDevice(self.majorTypes, self)
   12.12          
   12.13 @@ -90,7 +88,7 @@ class ControllerFactory(CtrlMsgRcvr):
   12.14          return None
   12.15  
   12.16      def delInstance(self, instance):
   12.17 -        if instance in self.instances:
   12.18 +        if instance.idx in self.instances:
   12.19              del self.instances[instance.idx]
   12.20  
   12.21      def createInstance(self, dom):
    13.1 --- a/tools/xenmgr/lib/server/messages.py	Mon Jun 21 14:15:58 2004 +0000
    13.2 +++ b/tools/xenmgr/lib/server/messages.py	Mon Jun 21 15:58:22 2004 +0000
    13.3 @@ -142,6 +142,34 @@ netif_formats = {
    13.4  msg_formats.update(netif_formats)
    13.5  
    13.6  #============================================================================
    13.7 +CMSG_SUSPEND  = 5
    13.8 +CMSG_SHUTDOWN = 6
    13.9 +
   13.10 +CMSG_SHUTDOWN_HALT      = 0
   13.11 +CMSG_SHUTDOWN_POWEROFF  = 1
   13.12 +CMSG_SHUTDOWN_REBOOT    = 2
   13.13 +
   13.14 +STOPCODE_shutdown       = 0
   13.15 +STOPCODE_reboot         = 1
   13.16 +STOPCODE_suspend        = 2
   13.17 +
   13.18 +ctrlif_formats = {
   13.19 +    'ctrlif_suspend_t':
   13.20 +    (CMSG_SUSPEND, 0, "??"),
   13.21 +
   13.22 +    'ctrlif_shutdown_halt_t':
   13.23 +    (CMSG_SHUTDOWN, CMSG_SHUTDOWN_HALT, "??"),
   13.24 +    
   13.25 +    'ctrlif_shutdown_poweroff_t':
   13.26 +    (CMSG_SHUTDOWN, CMSG_SHUTDOWN_POWEROFF, "??"),
   13.27 +    
   13.28 +    'ctrlif_shutdown_reboot_t':
   13.29 +    (CMSG_SHUTDOWN, CMSG_SHUTDOWN_REBOOT, "??"),
   13.30 +    }
   13.31 +
   13.32 +msg_formats.update(ctrlif_formats)
   13.33 +
   13.34 +#============================================================================
   13.35  
   13.36  class Msg:
   13.37      pass
    14.1 --- a/tools/xenmgr/lib/server/netif.py	Mon Jun 21 14:15:58 2004 +0000
    14.2 +++ b/tools/xenmgr/lib/server/netif.py	Mon Jun 21 15:58:22 2004 +0000
    14.3 @@ -35,6 +35,7 @@ class NetifControllerFactory(controller.
    14.4      def setControlDomain(self, dom):
    14.5          """Set the 'back-end' device driver domain.
    14.6          """
    14.7 +        if self.dom == dom: return
    14.8          self.deregisterChannel()
    14.9          self.attached = 0
   14.10          self.dom = dom
   14.11 @@ -44,7 +45,9 @@ class NetifControllerFactory(controller.
   14.12          #    xend.netif.recovery = True
   14.13          #    xend.netif.be_port = xend.main.port_from_dom(dom)
   14.14          #
   14.15 -        pass
   14.16 +
   14.17 +    def getControlDomain(self):
   14.18 +        return self.dom
   14.19  
   14.20      def recv_be_create(self, msg, req):
   14.21          self.callDeferred(0)
   14.22 @@ -64,6 +67,8 @@ class NetifControllerFactory(controller.
   14.23          val = unpackMsg('netif_be_driver_status_changed_t', msg)
   14.24          status = val['status']
   14.25          if status == NETIF_DRIVER_STATUS_UP and not self.attached:
   14.26 +            # If we are not attached the driver domain was changed, and
   14.27 +            # this signals the new driver domain is ready.
   14.28              for netif in self.getInstances():
   14.29                  netif.reattach_devices()
   14.30              self.attached = 1
   14.31 @@ -149,6 +154,8 @@ class NetifController(controller.Control
   14.32          return d
   14.33  
   14.34      def reattach_devices(self):
   14.35 +        """Reattach all devices when the back-end control domain has changed.
   14.36 +        """
   14.37          d = self.factory.addDeferred()
   14.38          self.send_be_create(vif)
   14.39          self.attach_fe_devices(0)
   14.40 @@ -182,10 +189,6 @@ class NetifController(controller.Control
   14.41                          'rx_shmem_frame' : val['rx_shmem_frame'] })
   14.42          self.factory.writeRequest(msg)
   14.43  
   14.44 -    #def recv_fe_interface_status_changed(self):
   14.45 -    #    print 'recv_fe_interface_status_changed>'
   14.46 -    #    pass
   14.47 -    
   14.48      def send_interface_connected(self, vif):
   14.49          dev = self.devices[vif]
   14.50          msg = packMsg('netif_fe_interface_status_changed_t',
    15.1 --- a/tools/xenmgr/lib/xm/create.py	Mon Jun 21 14:15:58 2004 +0000
    15.2 +++ b/tools/xenmgr/lib/xm/create.py	Mon Jun 21 15:58:22 2004 +0000
    15.3 @@ -7,28 +7,28 @@ from xenmgr.XendClient import server
    15.4  
    15.5  from xenmgr.xm.opts import *
    15.6  
    15.7 -opts = Opts(use="""[options]
    15.8 +gopts = Opts(use="""[options]
    15.9  
   15.10  Create a domain.
   15.11  """)
   15.12  
   15.13 -opts.opt('help', short='h',
   15.14 +gopts.opt('help', short='h',
   15.15           fn=set_value, default=0,
   15.16           use="Print this help.")
   15.17  
   15.18 -opts.opt('quiet', short='q',
   15.19 +gopts.opt('quiet', short='q',
   15.20           fn=set_true, default=0,
   15.21           use="Quiet.")
   15.22  
   15.23 -opts.opt('path', val='PATH',
   15.24 +gopts.opt('path', val='PATH',
   15.25           fn=set_value, default='.:/etc/xc',
   15.26           use="Search path for default scripts.")
   15.27  
   15.28 -opts.opt('defaults', short='f', val='FILE',
   15.29 +gopts.opt('defaults', short='f', val='FILE',
   15.30           fn=set_value, default='xmdefaults',
   15.31           use="Use the given default script.")
   15.32  
   15.33 -opts.opt('config', short='F', val='FILE',
   15.34 +gopts.opt('config', short='F', val='FILE',
   15.35           fn=set_value, default=None,
   15.36           use='Domain configuration to use.')
   15.37  
   15.38 @@ -38,102 +38,103 @@ def set_var(opt, k, v):
   15.39          (k, v) = string.split(d, '=')
   15.40          opt.opts.setvar(k, v)
   15.41  
   15.42 -opts.opt('define', short='D', val='VAR=VAL',
   15.43 +gopts.opt('define', short='D', val='VAR=VAL',
   15.44           fn=set_var, default=None,
   15.45           use="""Set variables before loading defaults, e.g. '-D vmid=3;ip=1.2.3.4'
   15.46           to set vmid and ip.""")
   15.47  
   15.48 -opts.opt('dryrun', short='n',
   15.49 +gopts.opt('dryrun', short='n',
   15.50           fn=set_true, default=0,
   15.51           use="Dry run - print the config but don't create the domain.")
   15.52  
   15.53 -opts.opt('console', short='c',
   15.54 +gopts.opt('console', short='c',
   15.55           fn=set_true, default=0,
   15.56           use="Connect to console after domain is created.")
   15.57  
   15.58 -opts.opt('kernel', short='k', val='FILE',
   15.59 +gopts.opt('kernel', short='k', val='FILE',
   15.60 +         fn=set_value, default=None,
   15.61           use="Path to kernel image.")
   15.62  
   15.63 -opts.opt('ramdisk', short='r', val='FILE',
   15.64 +gopts.opt('ramdisk', short='r', val='FILE',
   15.65           fn=set_value, default='',
   15.66           use="Path to ramdisk.")
   15.67  
   15.68 -opts.opt('builder', short='b', val='FUNCTION',
   15.69 +gopts.opt('builder', short='b', val='FUNCTION',
   15.70           fn=set_value, default='linux',
   15.71           use="Function to use to build the domain.")
   15.72  
   15.73 -opts.opt('memory', short='m', val='MEMORY',
   15.74 +gopts.opt('memory', short='m', val='MEMORY',
   15.75           fn=set_value, default=128,
   15.76           use="Domain memory in MB.")
   15.77  
   15.78 -opts.opt('disk', short='d', val='phy:DEV,VDEV,MODE',
   15.79 +gopts.opt('disk', short='d', val='phy:DEV,VDEV,MODE',
   15.80           fn=append_value, default=[],
   15.81           use="""Add a disk device to a domain. The physical device is DEV, which
   15.82           is exported to the domain as VDEV. The disk is read-only if MODE is r,
   15.83           read-write if mode is 'w'.""")
   15.84  
   15.85 -opts.opt('pci', val='BUS,DEV,FUNC',
   15.86 +gopts.opt('pci', val='BUS,DEV,FUNC',
   15.87           fn=append_value, default=[],
   15.88 -         use="""Add a PCI device to a domain.""")
   15.89 +         use="""Add a PCI device to a domain, using given params (in hex).""")
   15.90  
   15.91 -opts.opt('ipaddr', short='i', val="IPADDR",
   15.92 +gopts.opt('ipaddr', short='i', val="IPADDR",
   15.93           fn=append_value, default=[],
   15.94           use="Add an IP address to the domain.")
   15.95  
   15.96 -opts.opt('mac', short='M', val="MAC",
   15.97 +gopts.opt('mac', short='M', val="MAC",
   15.98           fn=append_value, default=[],
   15.99           use="""Add a network interface with the given mac address to the domain.
  15.100           More than one interface may be specified. Interfaces with unspecified MAC addresses
  15.101           are allocated a random address.""")
  15.102  
  15.103 -opts.opt('nics', val="N",
  15.104 +gopts.opt('nics', val="N",
  15.105           fn=set_int, default=1,
  15.106           use="Set the number of network interfaces.")
  15.107  
  15.108 -opts.opt('vnet', val='VNET',
  15.109 +gopts.opt('vnet', val='VNET',
  15.110           fn=append_value, default=[],
  15.111           use="""Define the vnets for the network interfaces.
  15.112           More than one vnet may be given, they are used in order.
  15.113           """)
  15.114  
  15.115 -opts.opt('root', short='R', val='DEVICE',
  15.116 +gopts.opt('root', short='R', val='DEVICE',
  15.117           fn=set_value, default='',
  15.118           use="""Set the root= parameter on the kernel command line.
  15.119           Use a device, e.g. /dev/sda1, or /dev/nfs for NFS root.""")
  15.120  
  15.121 -opts.opt('extra', short='E', val="ARGS",
  15.122 +gopts.opt('extra', short='E', val="ARGS",
  15.123           fn=set_value, default='',
  15.124           use="Set extra arguments to append to the kernel command line.")
  15.125  
  15.126 -opts.opt('ip', short='I', val='IPADDR',
  15.127 +gopts.opt('ip', short='I', val='IPADDR',
  15.128           fn=set_value, default='',
  15.129           use="Set the kernel IP interface address.")
  15.130  
  15.131 -opts.opt('gateway', val="IPADDR",
  15.132 +gopts.opt('gateway', val="IPADDR",
  15.133           fn=set_value, default='',
  15.134           use="Set kernel IP gateway.")
  15.135  
  15.136 -opts.opt('netmask', val="MASK",
  15.137 +gopts.opt('netmask', val="MASK",
  15.138           fn=set_value, default = '',
  15.139           use="Set kernel IP netmask.")
  15.140  
  15.141 -opts.opt('hostname', val="NAME",
  15.142 +gopts.opt('hostname', val="NAME",
  15.143           fn=set_value, default='',
  15.144           use="Set kernel IP hostname.")
  15.145  
  15.146 -opts.opt('interface', val="INTF",
  15.147 +gopts.opt('interface', val="INTF",
  15.148           fn=set_value, default="eth0",
  15.149           use="Set the kernel IP interface name.")
  15.150  
  15.151 -opts.opt('dhcp', val="off|dhcp",
  15.152 +gopts.opt('dhcp', val="off|dhcp",
  15.153           fn=set_value, default='off',
  15.154           use="Set kernel dhcp option.")
  15.155  
  15.156 -opts.opt('nfs_server', val="IPADDR",
  15.157 +gopts.opt('nfs_server', val="IPADDR",
  15.158           fn=set_value, default=None,
  15.159           use="Set the address of the NFS server for NFS root.")
  15.160  
  15.161 -opts.opt('nfs_root', val="PATH",
  15.162 +gopts.opt('nfs_root', val="PATH",
  15.163           fn=set_value, default=None,
  15.164           use="Set the path of the root NFS directory.")
  15.165  
  15.166 @@ -160,7 +161,7 @@ def make_config(opts):
  15.167          config_image.append(['ip', cmdline_ip])
  15.168      if opts.root:
  15.169          cmdline_root = strip('root=', opts.root)
  15.170 -        config_image.append(['root', opts.root])
  15.171 +        config_image.append(['root', cmdline_root])
  15.172      if opts.extra:
  15.173          config_image.append(['args', opts.extra])
  15.174      config.append(['image', config_image ])
  15.175 @@ -221,7 +222,9 @@ def preprocess_pci(opts):
  15.176          d = v.split(',')
  15.177          if len(d) != 3:
  15.178              opts.err('Invalid pci specifier: ' + v)
  15.179 -        pci.append(d)
  15.180 +        # Components are in hex: add hex specifier.
  15.181 +        hexd = map(lambda v: '0x'+v, d)
  15.182 +        pci.append(hexd)
  15.183      opts.pci = pci
  15.184  
  15.185  def preprocess_ip(opts):
  15.186 @@ -247,6 +250,8 @@ def preprocess_nfs(opts):
  15.187      opts.extra = nfs + ' ' + opts.extra
  15.188      
  15.189  def preprocess(opts):
  15.190 +    if not opts.kernel:
  15.191 +        opts.err("No kernel specified")
  15.192      preprocess_disk(opts)
  15.193      preprocess_pci(opts)
  15.194      preprocess_ip(opts)
  15.195 @@ -278,6 +283,7 @@ def make_domain(opts, config):
  15.196      return (dom, console_port)
  15.197  
  15.198  def main(argv):
  15.199 +    opts = gopts
  15.200      args = opts.parse(argv)
  15.201      if opts.config:
  15.202          pass
  15.203 @@ -285,6 +291,7 @@ def main(argv):
  15.204          opts.load_defaults()
  15.205      if opts.help:
  15.206          opts.usage()
  15.207 +        return
  15.208      preprocess(opts)
  15.209      config = make_config(opts)
  15.210      if opts.dryrun:
    16.1 --- a/tools/xenmgr/lib/xm/main.py	Mon Jun 21 14:15:58 2004 +0000
    16.2 +++ b/tools/xenmgr/lib/xm/main.py	Mon Jun 21 15:58:22 2004 +0000
    16.3 @@ -1,7 +1,7 @@
    16.4  #!/usr/bin/python
    16.5 -import string
    16.6  import sys
    16.7  
    16.8 +from xenmgr import PrettyPrint
    16.9  from xenmgr import sxp
   16.10  from xenmgr.XendClient import server
   16.11  from xenmgr.xm import create, shutdown
   16.12 @@ -39,7 +39,7 @@ class Xm:
   16.13      def help(self, meth, args):
   16.14          name = meth[3:]
   16.15          f = getattr(self, meth)
   16.16 -        print "%s\t%s" % (name, f.__doc__ or '')
   16.17 +        print "%-14s %s" % (name, f.__doc__ or '')
   16.18  
   16.19      def xm_help(self, help, args):
   16.20          """Print help."""
   16.21 @@ -69,12 +69,14 @@ class Xm:
   16.22              print args[0], "FILE"
   16.23              print "\nRestore a domain from FILE."
   16.24          if len(args) < 2: self.err("%s: Missing file" % args[0])
   16.25 -        server.xend_domain_restore(dom, None, filename)
   16.26 +        filename = args[1]
   16.27 +        server.xend_domain_restore(None, filename)
   16.28  
   16.29 -    def xm_ls(self, help, args):
   16.30 +    def xm_domains(self, help, args):
   16.31          """List domains."""
   16.32 -        if help: self.help('xm_' + args[0]); return
   16.33 +        if help: self.help('xm_' + args[0], args); return
   16.34          doms = server.xend_domains()
   16.35 +        doms.sort()
   16.36          print 'Dom  Name             Mem(MB)  CPU  State  Time(s)'
   16.37          for dom in doms:
   16.38              info = server.xend_domain(dom)
   16.39 @@ -85,7 +87,19 @@ class Xm:
   16.40              d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
   16.41              d['state'] = sxp.child_value(info, 'state', '??')
   16.42              d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
   16.43 -            print ("%(dom)-4d %(name)-16s %(mem)4d     %(cpu)3d %(state)5s %(cpu_time)10.2f" % d)
   16.44 +            print ("%(dom)-4d %(name)-16s %(mem)7d  %(cpu)3d  %(state)5s  %(cpu_time)7.1f" % d)
   16.45 +
   16.46 +    def xm_domain(self, help, args):
   16.47 +        """Get information about a domain."""
   16.48 +        if help:
   16.49 +            print args[0], 'DOM'
   16.50 +            print '\nGet information about domain DOM.'
   16.51 +            return
   16.52 +        if len(args) < 2: self.err("%s: Missing domain" % args[0])
   16.53 +        dom = args[1]
   16.54 +        info = server.xend_domain(dom)
   16.55 +        PrettyPrint.prettyprint(info)
   16.56 +        print
   16.57  
   16.58      def xm_halt(self, help, args):
   16.59          """Terminate a domain immediately."""
   16.60 @@ -101,8 +115,8 @@ class Xm:
   16.61          """Shutdown a domain."""
   16.62          shutdown.main(args)
   16.63  
   16.64 -    def xm_stop(self, help, args):
   16.65 -        """Stop execution of a domain."""
   16.66 +    def xm_pause(self, help, args):
   16.67 +        """Pause execution of a domain."""
   16.68          if help:
   16.69              print args[0], 'DOM'
   16.70              print '\nStop execution of domain DOM.'
   16.71 @@ -111,11 +125,11 @@ class Xm:
   16.72          dom = args[1]
   16.73          server.xend_domain_stop(dom)
   16.74  
   16.75 -    def xm_start(self, help, args):
   16.76 -        """Start execution of a domain."""
   16.77 +    def xm_unpause(self, help, args):
   16.78 +        """Unpause a paused domain."""
   16.79          if help:
   16.80              print args[0], 'DOM'
   16.81 -            print '\nStart execution of domain DOM.'
   16.82 +            print '\nUnpause execution of domain DOM.'
   16.83              return
   16.84          if len(args) < 2: self.err("%s: Missing domain" % args[0])
   16.85          dom = args[1]
   16.86 @@ -131,32 +145,6 @@ class Xm:
   16.87          v = map(int, args[1:3])
   16.88          server.xend_domain_pincpu(*v)
   16.89  
   16.90 -    def xm_vif_stats(self, help, args):
   16.91 -        """Get stats for a virtual interface."""
   16.92 -        if help:
   16.93 -            print args[0], 'DOM VIF'
   16.94 -            print '\nGet stats for interface VIF on domain DOM.'
   16.95 -            return
   16.96 -        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
   16.97 -        v = map(int, args[1:3])
   16.98 -        print server.xend_domain_vif_stats(*v)
   16.99 -
  16.100 -    def xm_vif_rate(self, help, args):
  16.101 -        """Set or get vif rate params."""
  16.102 -        if help:
  16.103 -            print args[0], "DOM VIF [BYTES USECS]"
  16.104 -            print '\nSet or get rate controls for interface VIF on domain DOM.'
  16.105 -            return
  16.106 -        n = len(args)
  16.107 -        if n == 3:
  16.108 -            v = map(int, args[1:n])
  16.109 -            print server.xend_domain_vif_scheduler_get(*v)
  16.110 -        elif n == 5:
  16.111 -            v = map(int, args[1:n])
  16.112 -            server.xend_domain_vif_scheduler_set(*v)
  16.113 -        else:
  16.114 -            self.err("%s: Invalid argument(s)" % args[0])
  16.115 -
  16.116      def xm_bvt(self, help, args):
  16.117          """Set BVT scheduler parameters."""
  16.118          if help:
  16.119 @@ -193,16 +181,29 @@ class Xm:
  16.120              print "\nSet round robin scheduler slice."
  16.121              return
  16.122          if len(args) != 2: self.err("%s: Invalid argument(s)" % args[0])
  16.123 -        slice = int(args[1])
  16.124 -        server.xend_node_rrobin_set(slice)
  16.125 +        rrslice = int(args[1])
  16.126 +        server.xend_node_rrobin_set(rrslice)
  16.127  
  16.128      def xm_info(self, help, args):
  16.129          """Get information about the xen host."""
  16.130 -        if help: self.help('xm_info'); return
  16.131 +        if help: self.help('xm_' + args[0], args); return
  16.132          info = server.xend_node()
  16.133          for x in info[1:]:
  16.134              print "%-23s:" % x[0], x[1]
  16.135  
  16.136 +    def xm_consoles(self, help, args):
  16.137 +        """Get information about domain consoles."""
  16.138 +        if help: self.help('xm_' + args[0], args); return
  16.139 +        l = server.xend_consoles()
  16.140 +        print "Dom Port  Id"
  16.141 +        for x in l:
  16.142 +            info = server.xend_console(x)
  16.143 +            d = {}
  16.144 +            d['dom'] = sxp.child(info, 'dst', ['dst', '?', '?'])[1]
  16.145 +            d['port'] = sxp.child_value(info, 'port', '?')
  16.146 +            d['id'] = sxp.child_value(info, 'id', '?')
  16.147 +            print "%(dom)3s %(port)4s %(id)3s" % d
  16.148 +
  16.149      def xm_console(self, help, args):
  16.150          """Open a console to a domain."""
  16.151          if help:
    17.1 --- a/tools/xenmgr/lib/xm/opts.py	Mon Jun 21 14:15:58 2004 +0000
    17.2 +++ b/tools/xenmgr/lib/xm/opts.py	Mon Jun 21 15:58:22 2004 +0000
    17.3 @@ -91,6 +91,7 @@ class Opts:
    17.4          self._vals = {}
    17.5          self._globals = {}
    17.6          self._locals = {}
    17.7 +        self.quiet = 0
    17.8  
    17.9      def opt(self, name, **args):
   17.10          x = Opt(self, name, **args)
    18.1 --- a/tools/xenmgr/lib/xm/shutdown.py	Mon Jun 21 14:15:58 2004 +0000
    18.2 +++ b/tools/xenmgr/lib/xm/shutdown.py	Mon Jun 21 15:58:22 2004 +0000
    18.3 @@ -5,19 +5,19 @@ import time
    18.4  from xenmgr.XendClient import server
    18.5  from xenmgr.xm.opts import *
    18.6  
    18.7 -opts = Opts(use="""[options] [DOM]
    18.8 +gopts = Opts(use="""[options] [DOM]
    18.9  
   18.10  Shutdown one or more domains gracefully.""")
   18.11  
   18.12 -opts.opt('help', short='h',
   18.13 +gopts.opt('help', short='h',
   18.14           fn=set_value, default=0,
   18.15           use="Print this help.")
   18.16  
   18.17 -opts.opt('all', short='a',
   18.18 +gopts.opt('all', short='a',
   18.19           fn=set_true, default=0,
   18.20           use="Shutdown all domains.")
   18.21  
   18.22 -opts.opt('wait', short='w',
   18.23 +gopts.opt('wait', short='w',
   18.24           fn=set_true, default=0,
   18.25           use='Wait for shutdown to complete.')
   18.26  
   18.27 @@ -28,7 +28,7 @@ def shutdown(opts, doms, wait):
   18.28      if 0 in doms:
   18.29          doms.remove(0)
   18.30      for d in doms:
   18.31 -        server.xend_domain_shutdown(dom)
   18.32 +        server.xend_domain_shutdown(d)
   18.33      if wait:
   18.34          while doms:
   18.35              alive = domains()
   18.36 @@ -55,6 +55,7 @@ def main_dom(opts, args):
   18.37      shutdown(opts, [ domid ], opts.wait)
   18.38      
   18.39  def main(argv):
   18.40 +    opts = gopts
   18.41      args = opts.parse(argv)
   18.42      if opts.help:
   18.43          opts.usage()
    19.1 --- a/tools/xenmgr/netfix	Mon Jun 21 14:15:58 2004 +0000
    19.2 +++ b/tools/xenmgr/netfix	Mon Jun 21 15:58:22 2004 +0000
    19.3 @@ -85,11 +85,10 @@ def reconfigure(interface, bridge):
    19.4      if not intf_info['gateway']:
    19.5          print 'Gateway not found: ', interface
    19.6          return
    19.7 -    cmd(CMD_IFCONFIG, '%(interface)s 0.0.0.0' % intf_info)
    19.8      cmd(CMD_IFCONFIG, '%(bridge)s %(address)s netmask %(mask)s broadcast %(broadcast)s up' % intf_info)
    19.9      cmd(CMD_ROUTE, 'add default gateway %(gateway)s dev %(bridge)s' % intf_info)
   19.10 -    if os.path.exists(CMD_BRCTL):
   19.11 -        cmd(CMD_BRCTL, 'addif %(bridge)s %(interface)s' % intf_info)
   19.12 +    cmd(CMD_BRCTL, 'addif %(bridge)s %(interface)s' % intf_info)
   19.13 +    cmd(CMD_IFCONFIG, '%(interface)s 0.0.0.0' % intf_info)
   19.14  
   19.15  defaults = {
   19.16      'interface': 'eth0',