ia64/xen-unstable

changeset 6954:308260e5868c

merge?
author cl349@firebug.cl.cam.ac.uk
date Mon Sep 19 10:51:05 2005 +0000 (2005-09-19)
parents cedb89d6b707 8f9dfc5fb51c
children 5c0ec0b171f0
files docs/Makefile tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.in tools/python/pylintrc tools/python/xen/sv/Main.py tools/python/xen/sv/Wizard.py tools/python/xen/xend/Args.py tools/python/xen/xend/EventServer.py tools/python/xen/xend/Vifctl.py tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/python/xen/xend/scheduler.py tools/python/xen/xend/server/DevController.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/SrvNode.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/netif.py tools/python/xen/xend/server/pciif.py tools/python/xen/xend/server/tpmif.py tools/python/xen/xend/server/usbif.py tools/python/xen/xend/xenstore/xsobj.py tools/python/xen/xend/xenstore/xstransact.py tools/python/xen/xend/xenstore/xswatch.py tools/python/xen/xm/create.py xen/arch/x86/shadow.c xen/arch/x86/shadow32.c xen/arch/x86/shadow_public.c xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/docs/Makefile	Mon Sep 19 09:14:41 2005 +0000
     1.2 +++ b/docs/Makefile	Mon Sep 19 10:51:05 2005 +0000
     1.3 @@ -36,11 +36,12 @@ html:
     1.4  	$(MAKE) $(DOC_HTML); fi
     1.5  
     1.6  python-dev-docs:
     1.7 -	mkdir -p api/tools/python
     1.8 +	@mkdir -v -p api/tools/python
     1.9  	@if which $(DOXYGEN) 1>/dev/null 2>/dev/null; then         \
    1.10          echo "Running doxygen to generate Python tools APIs ... "; \
    1.11  	$(DOXYGEN) Doxyfile;                                       \
    1.12 -	$(MAKE) -C api/tools/python/latex ; fi
    1.13 +	$(MAKE) -C api/tools/python/latex ; else                   \
    1.14 +        echo "Doxygen not installed; skipping python-dev-docs."; fi
    1.15  
    1.16  clean:
    1.17  	rm -rf .word_count *.aux *.dvi *.bbl *.blg *.glo *.idx *~ 
     4.1 --- a/tools/python/pylintrc	Mon Sep 19 09:14:41 2005 +0000
     4.2 +++ b/tools/python/pylintrc	Mon Sep 19 10:51:05 2005 +0000
     4.3 @@ -74,7 +74,7 @@ enable-variables=yes
     4.4  init-import=no
     4.5  
     4.6  # List of variable names used for dummy variables (i.e. not used).
     4.7 -dummy-variables=_,dummy
     4.8 +dummy-variables=_,_1,_2,_3,_4,_5,dummy
     4.9  
    4.10  
    4.11  
    4.12 @@ -131,7 +131,7 @@ good-names=i,j,k,ex,Run,_
    4.13  bad-names=foo,bar,baz,toto,tutu,tata
    4.14  
    4.15  # List of builtins function names that should not be used, separated by a comma
    4.16 -bad-functions=map,filter,apply,input
    4.17 +bad-functions=apply,input
    4.18  
    4.19  
    4.20  
     5.1 --- a/tools/python/xen/sv/Main.py	Mon Sep 19 09:14:41 2005 +0000
     5.2 +++ b/tools/python/xen/sv/Main.py	Mon Sep 19 10:51:05 2005 +0000
     5.3 @@ -1,5 +1,4 @@
     5.4  
     5.5 -from xen.sv.HTMLBase import HTMLBase
     5.6  from xen.sv.NodeInfo import NodeInfo
     5.7  from xen.sv.DomInfo  import DomInfo
     5.8  from xen.sv.CreateDomain import CreateDomain
     5.9 @@ -33,15 +32,8 @@ class Args:
    5.10              result.append( (key, self.fieldStorage.getlist( key ) ) )
    5.11          return result
    5.12                                                                                                                                                              
    5.13 -class TwistedAdapter:
    5.14 -    def __init__( self, req ):
    5.15 -        self.args = Args( req )
    5.16 -        self.uri = req.unparsed_uri
    5.17 -        self.url = req.uri
    5.18 -        self.write = req.write
    5.19 -
    5.20  # This is the Main class
    5.21 -# It peices together all the modules
    5.22 +# It pieces together all the modules
    5.23  
    5.24  class Main:
    5.25      def __init__( self ):
    5.26 @@ -61,7 +53,7 @@ class Main:
    5.27              self.init_modules( request )
    5.28              self.init_done = True
    5.29              
    5.30 -        for moduleName, module in self.modules.iteritems():
    5.31 +        for _, module in self.modules.iteritems():
    5.32              module.write_MENU( request )
    5.33              request.write( "\n" )
    5.34  
     6.1 --- a/tools/python/xen/sv/Wizard.py	Mon Sep 19 09:14:41 2005 +0000
     6.2 +++ b/tools/python/xen/sv/Wizard.py	Mon Sep 19 10:51:05 2005 +0000
     6.3 @@ -47,7 +47,7 @@ class Sheet( HTMLBase ):
     6.4      def __init__( self, urlWriter, title, location ):
     6.5          HTMLBase.__init__( self )
     6.6          self.urlWriter = urlWriter
     6.7 -        self.feilds = []
     6.8 +        self.fields = []
     6.9          self.title = title
    6.10          self.location = location
    6.11          self.passback = None
    6.12 @@ -86,9 +86,9 @@ class Sheet( HTMLBase ):
    6.13          
    6.14          request.write( "<table width='100%' cellpadding='0' cellspacing='1' border='0'>" )
    6.15          
    6.16 -    	for (feild, control) in self.feilds:
    6.17 -            control.write_Control( request, previous_values.get( feild ) )
    6.18 -            if previous_values.get( feild ) is not None and not control.validate( previous_values.get( feild ) ):
    6.19 +    	for (field, control) in self.fields:
    6.20 +            control.write_Control( request, previous_values.get( field ) )
    6.21 +            if previous_values.get( field ) is not None and not control.validate( previous_values.get( field ) ):
    6.22              	control.write_Help( request )
    6.23              
    6.24          request.write( "</table>" )
    6.25 @@ -97,7 +97,7 @@ class Sheet( HTMLBase ):
    6.26          #request.write( "<input type='hidden' name='visited-sheet%s' value='True'></p>" % self.location )
    6.27                  
    6.28      def addControl( self, control ):
    6.29 -    	self.feilds.append( [ control.getName(), control ] )
    6.30 +    	self.fields.append( [ control.getName(), control ] )
    6.31          
    6.32      def validate( self, request ):
    6.33      
    6.34 @@ -108,10 +108,10 @@ class Sheet( HTMLBase ):
    6.35          previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the map for quick reference
    6.36      	if DEBUG: print previous_values
    6.37        
    6.38 -      	for (feild, control) in self.feilds:
    6.39 -            if not control.validate( previous_values.get( feild ) ):
    6.40 +      	for (field, control) in self.fields:
    6.41 +            if not control.validate( previous_values.get( field ) ):
    6.42                  check = False
    6.43 -                if DEBUG: print "> %s = %s" % (feild, previous_values.get( feild ))
    6.44 +                if DEBUG: print "> %s = %s" % (field, previous_values.get( field ))
    6.45  
    6.46          return check
    6.47          
    6.48 @@ -143,7 +143,7 @@ class SheetControl( HTMLBase ):
    6.49          
    6.50  class InputControl( SheetControl ):
    6.51  
    6.52 -    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
    6.53 +    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this field." ):
    6.54          SheetControl.__init__( self, reg_exp )
    6.55          self.setName( name )
    6.56          
    6.57 @@ -206,7 +206,7 @@ class ListControl( SheetControl ):
    6.58          
    6.59  class FileControl( InputControl ):
    6.60  
    6.61 -    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
    6.62 +    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this field." ):
    6.63  	InputControl.__init__( self, name, defaultValue, humanText )
    6.64          
    6.65      def validate( self, persistedValue ):
     7.1 --- a/tools/python/xen/xend/Args.py	Mon Sep 19 09:14:41 2005 +0000
     7.2 +++ b/tools/python/xen/xend/Args.py	Mon Sep 19 10:51:05 2005 +0000
     7.3 @@ -32,12 +32,12 @@ class Args:
     7.4          self.arg_dict = {}
     7.5          self.key_ord = []
     7.6          self.key_dict = {}
     7.7 -        for (name, type) in paramspec:
     7.8 +        for (name, typ) in paramspec:
     7.9                  self.arg_ord.append(name)
    7.10 -                self.arg_dict[name] = type
    7.11 -        for (name, type) in keyspec:
    7.12 +                self.arg_dict[name] = typ
    7.13 +        for (name, typ) in keyspec:
    7.14                  self.key_ord.append(name)
    7.15 -                self.key_dict[name] = type
    7.16 +                self.key_dict[name] = typ
    7.17  
    7.18      def get_args(self, d, xargs=None):
    7.19          args = {}
    7.20 @@ -56,12 +56,12 @@ class Args:
    7.21      def split_args(self, d, args, keys):
    7.22          for (k, v) in d.items():
    7.23              if k in self.arg_dict:
    7.24 -                type = self.arg_dict[k]
    7.25 -                val = self.coerce(type, v)
    7.26 +                typ = self.arg_dict[k]
    7.27 +                val = self.coerce(typ, v)
    7.28                  args[k] = val
    7.29              elif k in self.key_dict:
    7.30 -                type = self.key_dict[k]
    7.31 -                val = self.coerce(type, v)
    7.32 +                typ = self.key_dict[k]
    7.33 +                val = self.coerce(typ, v)
    7.34                  keys[k] = val
    7.35              else:
    7.36                  raise ArgError('Invalid parameter: %s' % k)
    7.37 @@ -85,20 +85,20 @@ class Args:
    7.38              d[k] = val
    7.39          return self.get_args(d, xargs=xargs)
    7.40  
    7.41 -    def coerce(self, type, v):
    7.42 +    def coerce(self, typ, v):
    7.43          try:
    7.44 -            if type == 'int':
    7.45 +            if typ == 'int':
    7.46                  val = int(v)
    7.47 -            elif type == 'long':
    7.48 +            elif typ == 'long':
    7.49                  val = long(v)
    7.50 -            elif type == 'str':
    7.51 +            elif typ == 'str':
    7.52                  val = str(v)
    7.53 -            elif type == 'sxpr':
    7.54 +            elif typ == 'sxpr':
    7.55                  val = self.sxpr(v)
    7.56 -            elif type == 'bool':
    7.57 +            elif typ == 'bool':
    7.58                  val = self.bool(v)
    7.59              else:
    7.60 -                raise ArgError('invalid type:' + str(type))
    7.61 +                raise ArgError('invalid type:' + str(typ))
    7.62              return val
    7.63          except ArgError:
    7.64              raise
    7.65 @@ -142,7 +142,9 @@ class ArgFn(Args):
    7.66      Used on the client.
    7.67      """
    7.68  
    7.69 -    def __init__(self, fn, paramspec, keyspec={}):
    7.70 +    def __init__(self, fn, paramspec, keyspec = None):
    7.71 +        if keyspec == None:
    7.72 +            keyspec = {}
    7.73          Args.__init__(self, paramspec, keyspec)
    7.74          self.fn = fn
    7.75  
    7.76 @@ -154,7 +156,9 @@ class FormFn(Args):
    7.77      Used in the HTTP server.
    7.78      """
    7.79  
    7.80 -    def __init__(self, fn, paramspec, keyspec={}):
    7.81 +    def __init__(self, fn, paramspec, keyspec = None):
    7.82 +        if keyspec == None:
    7.83 +            keyspec = {}
    7.84          Args.__init__(self, paramspec, keyspec)
    7.85          self.fn = fn
    7.86  
     8.1 --- a/tools/python/xen/xend/EventServer.py	Mon Sep 19 09:14:41 2005 +0000
     8.2 +++ b/tools/python/xen/xend/EventServer.py	Mon Sep 19 10:51:05 2005 +0000
     8.3 @@ -145,7 +145,7 @@ class EventServer:
     8.4              self.lock.release()
     8.5              
     8.6          if async:
     8.7 -            scheduler.now(self.call_handlers, [event, val])
     8.8 +            scheduler.now(self.call_handlers, event, val)
     8.9          else:
    8.10              self.call_handlers(event, val)
    8.11  
     9.1 --- a/tools/python/xen/xend/Vifctl.py	Mon Sep 19 09:14:41 2005 +0000
     9.2 +++ b/tools/python/xen/xend/Vifctl.py	Mon Sep 19 10:51:05 2005 +0000
     9.3 @@ -13,13 +13,13 @@
     9.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     9.5  #============================================================================
     9.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
     9.7 +# Copyright (C) 2005 XenSource Ltd
     9.8  #============================================================================
     9.9  
    9.10  """Xend interface to networking control scripts.
    9.11  """
    9.12  import os
    9.13  import os.path
    9.14 -import sys
    9.15  import xen.util.process
    9.16  
    9.17  from xen.xend import XendRoot
    9.18 @@ -71,7 +71,7 @@ def set_vif_name(vif_old, vif_new):
    9.19          vif = vif_old
    9.20      return vif
    9.21  
    9.22 -def vifctl(op, vif=None, script=None, domain=None, mac=None, bridge=None, ipaddr=[]):
    9.23 +def vifctl(op, vif=None, script=None, domain=None, mac=None, bridge=None, ipaddr=None):
    9.24      """Call a vif control script.
    9.25      Xend calls this when bringing vifs up or down.
    9.26  
    10.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Mon Sep 19 09:14:41 2005 +0000
    10.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Mon Sep 19 10:51:05 2005 +0000
    10.3 @@ -83,7 +83,7 @@ def save(xd, fd, dominfo, live):
    10.4      if child.wait() != 0:
    10.5          raise XendError("xc_save failed: %s" % lasterr)
    10.6  
    10.7 -    dominfo.setStoreChannel(None)
    10.8 +    dominfo.closeStoreChannel()
    10.9      xd.domain_destroy(dominfo.domid)
   10.10      return None
   10.11  
    11.1 --- a/tools/python/xen/xend/XendDomain.py	Mon Sep 19 09:14:41 2005 +0000
    11.2 +++ b/tools/python/xen/xend/XendDomain.py	Mon Sep 19 10:51:05 2005 +0000
    11.3 @@ -55,7 +55,7 @@ def is_dead(dom):
    11.4  class XendDomainDict(dict):
    11.5      def get_by_name(self, name):
    11.6          try:
    11.7 -            return filter(lambda d: d.name == name, self.values())[0]
    11.8 +            return filter(lambda d: d.getName() == name, self.values())[0]
    11.9          except IndexError, err:
   11.10              return None
   11.11  
   11.12 @@ -94,7 +94,7 @@ class XendDomain:
   11.13          @return: domain objects
   11.14          """
   11.15          doms = self.list()
   11.16 -        doms.sort(lambda x, y: cmp(x.name, y.name))
   11.17 +        doms.sort(lambda x, y: cmp(x.getName(), y.getName()))
   11.18          return doms
   11.19  
   11.20      def list_names(self):
   11.21 @@ -103,7 +103,7 @@ class XendDomain:
   11.22          @return: domain names
   11.23          """
   11.24          doms = self.list_sorted()
   11.25 -        return map(lambda x: x.name, doms)
   11.26 +        return map(lambda x: x.getName(), doms)
   11.27  
   11.28      def onReleaseDomain(self):
   11.29          self.reap()
   11.30 @@ -183,12 +183,13 @@ class XendDomain:
   11.31          @param info:   domain info object
   11.32          @param notify: send a domain created event if true
   11.33          """
   11.34 -        if info.domid in self.domains:
   11.35 +        if info.getDomain() in self.domains:
   11.36              notify = False
   11.37 -        self.domains[info.domid] = info
   11.38 +        self.domains[info.getDomain()] = info
   11.39          info.exportToDB(save=True)
   11.40          if notify:
   11.41 -            eserver.inject('xend.domain.create', [info.name, info.domid])
   11.42 +            eserver.inject('xend.domain.create', [info.getName(),
   11.43 +                                                  info.getDomain()])
   11.44  
   11.45      def _delete_domain(self, id, notify=True):
   11.46          """Remove a domain from the tables.
   11.47 @@ -202,7 +203,8 @@ class XendDomain:
   11.48              info.cleanup()
   11.49              info.delete()
   11.50              if notify:
   11.51 -                eserver.inject('xend.domain.died', [info.name, info.domid])
   11.52 +                eserver.inject('xend.domain.died', [info.getName(),
   11.53 +                                                    info.getDomain()])
   11.54          # XXX this should not be needed
   11.55          for domdb in self.dbmap.values():
   11.56              if not domdb.has_key("xend"):
   11.57 @@ -227,13 +229,13 @@ class XendDomain:
   11.58              dominfo = self.domains.get(domid)
   11.59              if not dominfo or dominfo.is_terminated():
   11.60                  continue
   11.61 -            log.debug('domain died name=%s domid=%d', dominfo.name, domid)
   11.62 +            log.debug('domain died name=%s domid=%d', dominfo.getName(), domid)
   11.63              if d['crashed'] and xroot.get_enable_dump():
   11.64                  self.domain_dumpcore(domid)
   11.65              if d['shutdown']:
   11.66                  reason = shutdown_reason(d['shutdown_reason'])
   11.67 -                log.debug('shutdown name=%s id=%d reason=%s', dominfo.name,
   11.68 -                          domid, reason)
   11.69 +                log.debug('shutdown name=%s id=%d reason=%s',
   11.70 +                          dominfo.getName(), domid, reason)
   11.71                  if reason == 'suspend':
   11.72                      dominfo.state_set("suspended")
   11.73                      continue
   11.74 @@ -248,11 +250,11 @@ class XendDomain:
   11.75          # Remove entries for domains that no longer exist.
   11.76          # Update entries for existing domains.
   11.77          for d in self.domains.values():
   11.78 -            info = doms.get(d.domid)
   11.79 +            info = doms.get(d.getDomain())
   11.80              if info:
   11.81                  d.update(info)
   11.82              elif not d.restart_pending():
   11.83 -                self._delete_domain(d.domid)
   11.84 +                self._delete_domain(d.getDomain())
   11.85  
   11.86      def update_domain(self, id):
   11.87          """Update information for a single domain.
   11.88 @@ -281,20 +283,23 @@ class XendDomain:
   11.89  
   11.90          @param dominfo: domain object
   11.91          """
   11.92 -        log.info("Restarting domain: name=%s id=%s", dominfo.name, dominfo.domid)
   11.93 +        log.info("Restarting domain: name=%s id=%s", dominfo.getName(),
   11.94 +                 dominfo.getDomain())
   11.95          eserver.inject("xend.domain.restart",
   11.96 -                       [dominfo.name, dominfo.domid, "begin"])
   11.97 +                       [dominfo.getName(), dominfo.getDomain(), "begin"])
   11.98          try:
   11.99              dominfo.restart()
  11.100 -            log.info('Restarted domain name=%s id=%s', dominfo.name, dominfo.domid)
  11.101 +            log.info('Restarted domain name=%s id=%s', dominfo.getName(),
  11.102 +                     dominfo.getDomain())
  11.103              eserver.inject("xend.domain.restart",
  11.104 -                           [dominfo.name, dominfo.domid, "success"])
  11.105 -            self.domain_unpause(dominfo.domid)
  11.106 +                           [dominfo.getName(), dominfo.getDomain(),
  11.107 +                            "success"])
  11.108 +            self.domain_unpause(dominfo.getDomain())
  11.109          except Exception, ex:
  11.110              log.exception("Exception restarting domain: name=%s id=%s",
  11.111 -                          dominfo.name, dominfo.domid)
  11.112 +                          dominfo.getName(), dominfo.getDomain())
  11.113              eserver.inject("xend.domain.restart",
  11.114 -                           [dominfo.name, dominfo.domid, "fail"])
  11.115 +                           [dominfo.getName(), dominfo.getDomain(), "fail"])
  11.116          return dominfo
  11.117  
  11.118      def domain_configure(self, vmconfig):
  11.119 @@ -376,9 +381,10 @@ class XendDomain:
  11.120          @param id: domain id
  11.121          """
  11.122          dominfo = self.domain_lookup(id)
  11.123 -        eserver.inject('xend.domain.unpause', [dominfo.name, dominfo.domid])
  11.124 +        eserver.inject('xend.domain.unpause', [dominfo.getName(),
  11.125 +                                               dominfo.getDomain()])
  11.126          try:
  11.127 -            return xc.domain_unpause(dom=dominfo.domid)
  11.128 +            return xc.domain_unpause(dom=dominfo.getDomain())
  11.129          except Exception, ex:
  11.130              raise XendError(str(ex))
  11.131      
  11.132 @@ -388,9 +394,10 @@ class XendDomain:
  11.133          @param id: domain id
  11.134          """
  11.135          dominfo = self.domain_lookup(id)
  11.136 -        eserver.inject('xend.domain.pause', [dominfo.name, dominfo.domid])
  11.137 +        eserver.inject('xend.domain.pause', [dominfo.getName(),
  11.138 +                                             dominfo.getDomain()])
  11.139          try:
  11.140 -            return xc.domain_pause(dom=dominfo.domid)
  11.141 +            return xc.domain_pause(dom=dominfo.getDomain())
  11.142          except Exception, ex:
  11.143              raise XendError(str(ex))
  11.144      
  11.145 @@ -406,8 +413,9 @@ class XendDomain:
  11.146          @param reason: shutdown type: poweroff, reboot, suspend, halt
  11.147          """
  11.148          dominfo = self.domain_lookup(id)
  11.149 -        self.domain_restart_schedule(dominfo.domid, reason, force=True)
  11.150 -        eserver.inject('xend.domain.shutdown', [dominfo.name, dominfo.domid, reason])
  11.151 +        self.domain_restart_schedule(dominfo.getDomain(), reason, force=True)
  11.152 +        eserver.inject('xend.domain.shutdown', [dominfo.getName(),
  11.153 +                                                dominfo.getDomain(), reason])
  11.154          if reason == 'halt':
  11.155              reason = 'poweroff'
  11.156          val = dominfo.shutdown(reason)
  11.157 @@ -431,13 +439,13 @@ class XendDomain:
  11.158              if not dominfo.shutdown_pending:
  11.159                  # domain doesn't need shutdown
  11.160                  continue
  11.161 -            id = dominfo.domid
  11.162 +            id = dominfo.getDomain()
  11.163              left = dominfo.shutdown_time_left(SHUTDOWN_TIMEOUT)
  11.164              if left <= 0:
  11.165                  # Shutdown expired - destroy domain.
  11.166                  try:
  11.167                      log.info("Domain shutdown timeout expired: name=%s id=%s",
  11.168 -                             dominfo.name, id)
  11.169 +                             dominfo.getName(), id)
  11.170                      self.domain_destroy(id, reason=
  11.171                                          dominfo.shutdown_pending['reason'])
  11.172                  except Exception:
  11.173 @@ -462,15 +470,16 @@ class XendDomain:
  11.174          restart = (force and reason == 'reboot') or dominfo.restart_needed(reason)
  11.175          if restart:
  11.176              log.info('Scheduling restart for domain: name=%s id=%s',
  11.177 -                     dominfo.name, dominfo.domid)
  11.178 +                     dominfo.getName(), dominfo.getDomain())
  11.179              eserver.inject("xend.domain.restart",
  11.180 -                           [dominfo.name, dominfo.domid, "schedule"])
  11.181 +                           [dominfo.getName(), dominfo.getDomain(),
  11.182 +                            "schedule"])
  11.183              dominfo.restarting()
  11.184          else:
  11.185              log.info('Cancelling restart for domain: name=%s id=%s',
  11.186 -                     dominfo.name, dominfo.domid)
  11.187 +                     dominfo.getName(), dominfo.getDomain())
  11.188              eserver.inject("xend.domain.restart",
  11.189 -                           [dominfo.name, dominfo.domid, "cancel"])
  11.190 +                           [dominfo.getName(), dominfo.getDomain(), "cancel"])
  11.191              dominfo.restart_cancel()
  11.192  
  11.193      def domain_restarts(self):
  11.194 @@ -480,12 +489,12 @@ class XendDomain:
  11.195          for dominfo in self.domains.values():
  11.196              if not dominfo.restart_pending():
  11.197                  continue
  11.198 -            info = doms.get(dominfo.domid)
  11.199 +            info = doms.get(dominfo.getDomain())
  11.200              if info:
  11.201                  # Don't execute restart for domains still running.
  11.202                  continue
  11.203              # Remove it from the restarts.
  11.204 -            log.info('restarting: %s' % dominfo.name)
  11.205 +            log.info('restarting: %s' % dominfo.getName())
  11.206              self.domain_restart(dominfo)
  11.207  
  11.208      def domain_destroy(self, domid, reason='halt'):
  11.209 @@ -520,13 +529,14 @@ class XendDomain:
  11.210  
  11.211          # temporarily rename domain for localhost migration
  11.212          if dst == "localhost":
  11.213 -            dominfo.name = "tmp-" + dominfo.name
  11.214 +            dominfo.setName("tmp-" + dominfo.getName())
  11.215  
  11.216          try:
  11.217              XendCheckpoint.save(self, sock.fileno(), dominfo, live)
  11.218          except:
  11.219              if dst == "localhost":
  11.220 -                dominfo.name = string.replace(dominfo.name, "tmp-", "", 1)
  11.221 +                dominfo.setName(
  11.222 +                    string.replace(dominfo.getName(), "tmp-", "", 1))
  11.223              raise
  11.224          
  11.225          return None
  11.226 @@ -560,7 +570,7 @@ class XendDomain:
  11.227          """
  11.228          dominfo = self.domain_lookup(id)
  11.229          try:
  11.230 -            return xc.domain_pincpu(dominfo.domid, vcpu, cpumap)
  11.231 +            return xc.domain_pincpu(dominfo.getDomain(), vcpu, cpumap)
  11.232          except Exception, ex:
  11.233              raise XendError(str(ex))
  11.234  
  11.235 @@ -569,8 +579,10 @@ class XendDomain:
  11.236          """
  11.237          dominfo = self.domain_lookup(id)
  11.238          try:
  11.239 -            return xc.bvtsched_domain_set(dom=dominfo.domid, mcuadv=mcuadv,
  11.240 -                                          warpback=warpback, warpvalue=warpvalue, 
  11.241 +            return xc.bvtsched_domain_set(dom=dominfo.getDomain(),
  11.242 +                                          mcuadv=mcuadv,
  11.243 +                                          warpback=warpback,
  11.244 +                                          warpvalue=warpvalue, 
  11.245                                            warpl=warpl, warpu=warpu)
  11.246          except Exception, ex:
  11.247              raise XendError(str(ex))
  11.248 @@ -580,7 +592,7 @@ class XendDomain:
  11.249          """
  11.250          dominfo = self.domain_lookup(id)
  11.251          try:
  11.252 -            return xc.bvtsched_domain_get(dominfo.domid)
  11.253 +            return xc.bvtsched_domain_get(dominfo.getDomain())
  11.254          except Exception, ex:
  11.255              raise XendError(str(ex))
  11.256      
  11.257 @@ -590,7 +602,8 @@ class XendDomain:
  11.258          """
  11.259          dominfo = self.domain_lookup(id)
  11.260          try:
  11.261 -            return xc.sedf_domain_set(dominfo.domid, period, slice, latency, extratime, weight)
  11.262 +            return xc.sedf_domain_set(dominfo.getDomain(), period, slice,
  11.263 +                                      latency, extratime, weight)
  11.264          except Exception, ex:
  11.265              raise XendError(str(ex))
  11.266  
  11.267 @@ -599,7 +612,7 @@ class XendDomain:
  11.268          """
  11.269          dominfo = self.domain_lookup(id)
  11.270          try:
  11.271 -            return xc.sedf_domain_get(dominfo.domid)
  11.272 +            return xc.sedf_domain_get(dominfo.getDomain())
  11.273          except Exception, ex:
  11.274              raise XendError(str(ex))
  11.275  
  11.276 @@ -647,9 +660,8 @@ class XendDomain:
  11.277          @param type: device type
  11.278          """
  11.279          dominfo = self.domain_lookup(id)
  11.280 -        val = dominfo.device_delete(type, devid)
  11.281 -        dominfo.exportToDB()
  11.282 -        return val
  11.283 +        return dominfo.destroyDevice(type, devid)
  11.284 +
  11.285  
  11.286      def domain_devtype_ls(self, id, type):
  11.287          """Get list of device sxprs for a domain.
  11.288 @@ -689,7 +701,7 @@ class XendDomain:
  11.289          """
  11.290          dominfo = self.domain_lookup(id)
  11.291          try:
  11.292 -            return xc.shadow_control(dominfo.domid, op)
  11.293 +            return xc.shadow_control(dominfo.getDomain(), op)
  11.294          except Exception, ex:
  11.295              raise XendError(str(ex))
  11.296  
  11.297 @@ -703,7 +715,8 @@ class XendDomain:
  11.298          dominfo = self.domain_lookup(id)
  11.299          maxmem = int(mem) * 1024
  11.300          try:
  11.301 -            return xc.domain_setmaxmem(dominfo.domid, maxmem_kb = maxmem)
  11.302 +            return xc.domain_setmaxmem(dominfo.getDomain(),
  11.303 +                                       maxmem_kb = maxmem)
  11.304          except Exception, ex:
  11.305              raise XendError(str(ex))
  11.306  
  11.307 @@ -735,12 +748,13 @@ class XendDomain:
  11.308          @param id: domain
  11.309          """
  11.310          dominfo = self.domain_lookup(id)
  11.311 -        corefile = "/var/xen/dump/%s.%s.core"% (dominfo.name, dominfo.domid)
  11.312 +        corefile = "/var/xen/dump/%s.%s.core" % (dominfo.getName(),
  11.313 +                                                 dominfo.getDomain())
  11.314          try:
  11.315 -            xc.domain_dumpcore(dom=dominfo.domid, corefile=corefile)
  11.316 +            xc.domain_dumpcore(dom=dominfo.getDomain(), corefile=corefile)
  11.317          except Exception, ex:
  11.318              log.warning("Dumpcore failed, id=%s name=%s: %s",
  11.319 -                        dominfo.domid, dominfo.name, ex)
  11.320 +                        dominfo.getDomain(), dominfo.getName(), ex)
  11.321          
  11.322  def instance():
  11.323      """Singleton constructor. Use this instead of the class constructor.
    12.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Sep 19 09:14:41 2005 +0000
    12.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Sep 19 10:51:05 2005 +0000
    12.3 @@ -1,4 +1,4 @@
    12.4 -#============================================================================
    12.5 +#===========================================================================
    12.6  # This library is free software; you can redistribute it and/or
    12.7  # modify it under the terms of version 2.1 of the GNU Lesser General Public
    12.8  # License as published by the Free Software Foundation.
    12.9 @@ -23,23 +23,18 @@ Author: Mike Wray <mike.wray@hp.com>
   12.10  
   12.11  """
   12.12  
   12.13 -import string, re
   12.14 -import os
   12.15 +import string
   12.16  import time
   12.17  import threading
   12.18  import errno
   12.19  
   12.20 -import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
   12.21 -from xen.util.ip import check_subnet, get_current_ipgw
   12.22 +import xen.lowlevel.xc
   12.23  from xen.util.blkif import blkdev_uname_to_file
   12.24  
   12.25 -from xen.xend.server import controller
   12.26 -from xen.xend.server import SrvDaemon; xend = SrvDaemon.instance()
   12.27 +from xen.xend.server import SrvDaemon
   12.28  from xen.xend.server.channel import EventChannel
   12.29 -from xen.util.blkif import blkdev_name_to_number, expand_dev_name
   12.30  
   12.31  from xen.xend import sxp
   12.32 -from xen.xend import Blkctl
   12.33  from xen.xend.PrettyPrint import prettyprintstring
   12.34  from xen.xend.XendBootloader import bootloader
   12.35  from xen.xend.XendLogging import log
   12.36 @@ -47,7 +42,7 @@ from xen.xend.XendError import XendError
   12.37  from xen.xend.XendRoot import get_component
   12.38  
   12.39  from xen.xend.uuid import getUuid
   12.40 -from xen.xend.xenstore import DBVar, XenNode, DBMap
   12.41 +from xen.xend.xenstore import DBVar
   12.42  from xen.xend.xenstore.xstransact import xstransact
   12.43  from xen.xend.xenstore.xsutil import IntroduceDomain
   12.44  
   12.45 @@ -98,6 +93,12 @@ SIF_NET_BE_DOMAIN = (1<<5)
   12.46  SIF_TPM_BE_DOMAIN = (1<<7)
   12.47  
   12.48  
   12.49 +xc = xen.lowlevel.xc.new()
   12.50 +
   12.51 +
   12.52 +xend = SrvDaemon.instance()
   12.53 +
   12.54 +
   12.55  def domain_exists(name):
   12.56      # See comment in XendDomain constructor.
   12.57      xd = get_component('xen.xend.XendDomain')
   12.58 @@ -248,11 +249,9 @@ class XendDomainInfo:
   12.59          self.store_mfn = None
   12.60          self.console_channel = None
   12.61          self.console_mfn = None
   12.62 -        self.controllers = {}
   12.63          
   12.64          self.info = None
   12.65          self.backend_flags = 0
   12.66 -        self.netif_idx = 0
   12.67          
   12.68          #todo: state: running, suspended
   12.69          self.state = STATE_VM_OK
   12.70 @@ -334,26 +333,50 @@ class XendDomainInfo:
   12.71      def getName(self):
   12.72          return self.name
   12.73  
   12.74 +    def getPath(self):
   12.75 +        return self.path
   12.76 +
   12.77 +    def getUuid(self):
   12.78 +        return self.uuid
   12.79 +
   12.80 +    def getVCpuCount(self):
   12.81 +        return self.vcpus
   12.82 +
   12.83 +    def getSsidref(self):
   12.84 +        return self.ssidref
   12.85 +
   12.86 +    def getMemoryTarget(self):
   12.87 +        """Get this domain's target memory size, in MiB."""
   12.88 +        return self.memory
   12.89 +
   12.90      def setStoreRef(self, ref):
   12.91          self.store_mfn = ref
   12.92          self.storeDom("store/ring-ref", ref)
   12.93  
   12.94 -    def setStoreChannel(self, channel):
   12.95 -        if self.store_channel and self.store_channel != channel:
   12.96 -            self.store_channel.close()
   12.97 -        self.store_channel = channel
   12.98 -        if channel:
   12.99 -            port = channel.port1
  12.100 -        else:
  12.101 -            port = None
  12.102 -        self.storeDom("store/port", None)
  12.103 +
  12.104 +    def getBackendFlags(self):
  12.105 +        return self.backend_flags
  12.106 +
  12.107 +
  12.108 +    def closeStoreChannel(self):
  12.109 +        """Close the store channel, if any.  Nothrow guarantee."""
  12.110 +        
  12.111 +        try:
  12.112 +            if self.store_channel:
  12.113 +                try:
  12.114 +                    self.store_channel.close()
  12.115 +                    self.removeDom("store/port")
  12.116 +                finally:
  12.117 +                    self.store_channel = None
  12.118 +        except Exception, exn:
  12.119 +            log.exception(exn)
  12.120 +
  12.121  
  12.122      def setConsoleRef(self, ref):
  12.123          self.console_mfn = ref
  12.124          self.storeDom("console/ring-ref", ref)
  12.125  
  12.126      def setMemoryTarget(self, target):
  12.127 -        self.memory_target = target
  12.128          self.storeDom("memory/target", target)
  12.129  
  12.130      def update(self, info=None):
  12.131 @@ -394,150 +417,26 @@ class XendDomainInfo:
  12.132  
  12.133      __repr__ = __str__
  12.134  
  12.135 -    def getDeviceController(self, type, error=True):
  12.136 -        ctrl = self.controllers.get(type)
  12.137 -        if not ctrl and error:
  12.138 -            raise XendError("invalid device type:" + type)
  12.139 -        return ctrl
  12.140 -    
  12.141 -    def findDeviceController(self, type):
  12.142 -        return (self.getDeviceController(type, error=False)
  12.143 -                or self.createDeviceController(type))
  12.144 -
  12.145 -    def createDeviceController(self, type):
  12.146 -        ctrl = controller.createDevController(type, self, recreate=self.recreate)
  12.147 -        self.controllers[type] = ctrl
  12.148 -        return ctrl
  12.149 -
  12.150 -    def createDevice(self, type, devconfig, change=False):
  12.151 -        if self.recreate:
  12.152 -            return
  12.153 -        if type == 'vbd':
  12.154 -            typedev = sxp.child_value(devconfig, 'dev')
  12.155 -            if re.match('^ioemu:', typedev):
  12.156 -	        return;
  12.157 -
  12.158 -            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
  12.159 -
  12.160 -            devnum = blkdev_name_to_number(sxp.child_value(devconfig, 'dev'))
  12.161 -
  12.162 -            backpath = "%s/backend/%s/%s/%d" % (backdom.path, type,
  12.163 -                                                self.uuid, devnum)
  12.164 -            frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
  12.165 -
  12.166 -            front = { 'backend' : backpath,
  12.167 -                      'backend-id' : "%i" % backdom.domid,
  12.168 -                      'virtual-device' : "%i" % devnum }
  12.169 -            xstransact.Write(frontpath, front)
  12.170  
  12.171 -            (type, params) = string.split(sxp.child_value(devconfig,
  12.172 -                                                          'uname'), ':', 1)
  12.173 -            readonly = sxp.child_value(devconfig, 'mode', 'r')
  12.174 -            back = { 'type' : type,
  12.175 -                     'params' : params,
  12.176 -                     'frontend' : frontpath,
  12.177 -                     'frontend-id' : "%i" % self.domid }
  12.178 -            if readonly == 'r':
  12.179 -                back['read-only'] = ""  # existence indicates read-only
  12.180 -            xstransact.Write(backpath, back)
  12.181 -
  12.182 -            return
  12.183 -
  12.184 -        if type == 'vif':
  12.185 -            from xen.xend import XendRoot
  12.186 -            xroot = XendRoot.instance()
  12.187 +    def getDeviceController(self, name):
  12.188 +        if name not in controllerClasses:
  12.189 +            raise XendError("unknown device type: " + str(name))
  12.190  
  12.191 -            def _get_config_ipaddr(config):
  12.192 -                val = []
  12.193 -                for ipaddr in sxp.children(config, elt='ip'):
  12.194 -                    val.append(sxp.child0(ipaddr))
  12.195 -                return val
  12.196 -
  12.197 -            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
  12.198 +        return controllerClasses[name](self)
  12.199  
  12.200 -            devnum = self.netif_idx
  12.201 -            self.netif_idx += 1
  12.202 -
  12.203 -            script = sxp.child_value(devconfig, 'script',
  12.204 -                                     xroot.get_vif_script())
  12.205 -            script = os.path.join(xroot.network_script_dir, script)
  12.206 -            bridge = sxp.child_value(devconfig, 'bridge',
  12.207 -                                     xroot.get_vif_bridge())
  12.208 -            mac = sxp.child_value(devconfig, 'mac')
  12.209 -            ipaddr = _get_config_ipaddr(devconfig)
  12.210  
  12.211 -            backpath = "%s/backend/%s/%s/%d" % (backdom.path, type,
  12.212 -                                                self.uuid, devnum)
  12.213 -            frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
  12.214 -
  12.215 -            front = { 'backend' : backpath,
  12.216 -                      'backend-id' : "%i" % backdom.domid,
  12.217 -                      'handle' : "%i" % devnum,
  12.218 -                      'mac' : mac }
  12.219 -            xstransact.Write(frontpath, front)
  12.220 +    def createDevice(self, deviceClass, devconfig):
  12.221 +        return self.getDeviceController(deviceClass).createDevice(devconfig)
  12.222  
  12.223 -            back = { 'script' : script,
  12.224 -                     'domain' : self.name,
  12.225 -                     'mac' : mac,
  12.226 -                     'bridge' : bridge,
  12.227 -                     'frontend' : frontpath,
  12.228 -                     'frontend-id' : "%i" % self.domid,
  12.229 -                     'handle' : "%i" % devnum }
  12.230 -            if ipaddr:
  12.231 -                back['ip'] = ' '.join(ipaddr)
  12.232 -            xstransact.Write(backpath, back)
  12.233 -
  12.234 -            return
  12.235 -        
  12.236 -        if type == 'vtpm':
  12.237 -            backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
  12.238 -
  12.239 -            devnum = int(sxp.child_value(devconfig, 'instance', '0'))
  12.240 -            log.error("The domain has a TPM with instance %d." % devnum)
  12.241 -
  12.242 -            backpath = "%s/backend/%s/%s/%d" % (backdom.path, type,
  12.243 -                                                self.uuid, devnum)
  12.244 -            frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
  12.245  
  12.246 -            front = { 'backend' : backpath,
  12.247 -                      'backend-id' : "%i" % backdom.domid,
  12.248 -                      'handle' : "%i" % devnum }
  12.249 -            xstransact.Write(frontpath, front)
  12.250 -
  12.251 -            back = { 'instance' : "%i" % devnum,
  12.252 -                     'frontend' : frontpath,
  12.253 -                     'frontend-id' : "%i" % self.domid }
  12.254 -            xstransact.Write(backpath, back)
  12.255 -
  12.256 -            return
  12.257 -
  12.258 -        ctrl = self.findDeviceController(type)
  12.259 -        return ctrl.createDevice(devconfig, recreate=self.recreate,
  12.260 -                                 change=change)
  12.261 -
  12.262 -    def configureDevice(self, type, id, devconfig):
  12.263 -        ctrl = self.getDeviceController(type)
  12.264 -        return ctrl.configureDevice(id, devconfig)
  12.265 +    def configureDevice(self, deviceClass, devid, devconfig):
  12.266 +        return self.getDeviceController(deviceClass).configureDevice(
  12.267 +            devid, devconfig)
  12.268  
  12.269 -    def destroyDevice(self, type, id, change=False, reboot=False):
  12.270 -        ctrl = self.getDeviceController(type)
  12.271 -        return ctrl.destroyDevice(id, change=change, reboot=reboot)
  12.272 -
  12.273 -    def deleteDevice(self, type, id):
  12.274 -        ctrl = self.getDeviceController(type)
  12.275 -        return ctrl.deleteDevice(id)
  12.276  
  12.277 -    def getDevice(self, type, id, error=True):
  12.278 -        ctrl = self.getDeviceController(type)
  12.279 -        return ctrl.getDevice(id, error=error)
  12.280 -        
  12.281 -    def getDeviceIds(self, type):
  12.282 -        ctrl = self.getDeviceController(type)
  12.283 -        return ctrl.getDeviceIds()
  12.284 -    
  12.285 -    def getDeviceSxprs(self, type):
  12.286 -        ctrl = self.getDeviceController(type)
  12.287 -        return ctrl.getDeviceSxprs()
  12.288 +    def destroyDevice(self, deviceClass, devid):
  12.289 +        return self.getDeviceController(deviceClass).destroyDevice(devid)
  12.290 +
  12.291  
  12.292      def sxpr(self):
  12.293          sxpr = ['domain',
  12.294 @@ -593,25 +492,10 @@ class XendDomainInfo:
  12.295              sxpr.append(['restart_state', self.restart_state])
  12.296          if self.restart_time:
  12.297              sxpr.append(['restart_time', str(self.restart_time)])
  12.298 -
  12.299 -        devs = self.sxpr_devices()
  12.300 -        if devs:
  12.301 -            sxpr.append(devs)
  12.302          if self.config:
  12.303              sxpr.append(['config', self.config])
  12.304          return sxpr
  12.305  
  12.306 -    def sxpr_devices(self):
  12.307 -        sxpr = []
  12.308 -        for ty in self.controllers.keys():
  12.309 -            devs = self.getDeviceSxprs(ty)
  12.310 -            sxpr += devs
  12.311 -        if sxpr:
  12.312 -            sxpr.insert(0, 'devices')
  12.313 -        else:
  12.314 -            sxpr = None
  12.315 -        return sxpr
  12.316 -
  12.317      def check_name(self, name):
  12.318          """Check if a vm name is valid. Valid names contain alphabetic characters,
  12.319          digits, or characters in '_-.:/+'.
  12.320 @@ -753,8 +637,7 @@ class XendDomainInfo:
  12.321          """
  12.322          self.state = STATE_VM_TERMINATED
  12.323          self.release_devices()
  12.324 -        if self.store_channel:
  12.325 -            self.setStoreChannel(None)
  12.326 +        self.closeStoreChannel()
  12.327          if self.console_channel:
  12.328              # notify processes using this console?
  12.329              try:
  12.330 @@ -785,19 +668,21 @@ class XendDomainInfo:
  12.331      def release_devices(self):
  12.332          """Release all vm devices.
  12.333          """
  12.334 -        reboot = self.restart_pending()
  12.335 -        for ctrl in self.controllers.values():
  12.336 -            if ctrl.isDestroyed(): continue
  12.337 -            ctrl.destroyController(reboot=reboot)
  12.338 +
  12.339          t = xstransact("%s/device" % self.path)
  12.340 -        for d in t.list("vbd"):
  12.341 -            t.remove(d)
  12.342 -        for d in t.list("vif"):
  12.343 -            t.remove(d)
  12.344 -        for d in t.list("vtpm"):
  12.345 -            t.remove(d)
  12.346 +        for n in controllerClasses.keys():
  12.347 +            for d in t.list(n):
  12.348 +                try:
  12.349 +                    t.remove(d)
  12.350 +                except ex:
  12.351 +                    # Log and swallow any exceptions in removal -- there's
  12.352 +                    # nothing more we can do.
  12.353 +                    log.exception(
  12.354 +                        "Device release failed: %s; %s; %s; %s" %
  12.355 +                        (self.info['name'], n, d, str(ex)))
  12.356          t.commit()
  12.357  
  12.358 +
  12.359      def show(self):
  12.360          """Print virtual machine info.
  12.361          """
  12.362 @@ -853,9 +738,6 @@ class XendDomainInfo:
  12.363                  raise VmError('invalid device')
  12.364              dev_type = sxp.name(dev_config)
  12.365  
  12.366 -            if not controller.isDevControllerClass(dev_type):
  12.367 -                raise VmError('unknown device type: ' + dev_type)
  12.368 -            
  12.369              self.createDevice(dev_type, dev_config)
  12.370  
  12.371  
  12.372 @@ -864,10 +746,7 @@ class XendDomainInfo:
  12.373  
  12.374          @raise: VmError for invalid devices
  12.375          """
  12.376 -        if self.rebooting():
  12.377 -            for ctrl in self.controllers.values():
  12.378 -                ctrl.initController(reboot=True)
  12.379 -        else:
  12.380 +        if not self.rebooting():
  12.381              self.create_configured_devices()
  12.382          self.image.createDeviceModel()
  12.383  
  12.384 @@ -877,47 +756,19 @@ class XendDomainInfo:
  12.385          @param dev_config: device configuration
  12.386          """
  12.387          dev_type = sxp.name(dev_config)
  12.388 -        dev = self.createDevice(dev_type, dev_config, change=True)
  12.389 -        self.config.append(['device', dev.getConfig()])
  12.390 -        return dev.sxpr()
  12.391 -
  12.392 -    def device_configure(self, dev_config, id):
  12.393 -        """Configure an existing device.
  12.394 +        devid = self.createDevice(dev_type, dev_config)
  12.395 +#        self.config.append(['device', dev.getConfig()])
  12.396 +        return self.getDeviceController(dev_type).sxpr(devid)
  12.397  
  12.398 -        @param dev_config: device configuration
  12.399 -        @param id:         device id
  12.400 -        """
  12.401 -        type = sxp.name(dev_config)
  12.402 -        dev = self.getDevice(type, id)
  12.403 -        old_config = dev.getConfig()
  12.404 -        new_config = dev.configure(dev_config, change=True)
  12.405 -        # Patch new config into vm config.
  12.406 -        new_full_config = ['device', new_config]
  12.407 -        old_full_config = ['device', old_config]
  12.408 -        old_index = self.config.index(old_full_config)
  12.409 -        self.config[old_index] = new_full_config
  12.410 -        return new_config
  12.411  
  12.412 -    def device_refresh(self, type, id):
  12.413 -        """Refresh a device.
  12.414 -
  12.415 -        @param type: device type
  12.416 -        @param id:   device id
  12.417 +    def device_configure(self, dev_config, devid):
  12.418 +        """Configure an existing device.
  12.419 +        @param dev_config: device configuration
  12.420 +        @param devid:      device id
  12.421          """
  12.422 -        dev = self.getDevice(type, id)
  12.423 -        dev.refresh()
  12.424 -        
  12.425 -    def device_delete(self, type, id):
  12.426 -        """Destroy and remove a device.
  12.427 +        deviceClass = sxp.name(dev_config)
  12.428 +        self.configureDevice(deviceClass, devid, dev_config)
  12.429  
  12.430 -        @param type: device type
  12.431 -        @param id:   device id
  12.432 -        """
  12.433 -        dev = self.getDevice(type, id)
  12.434 -        dev_config = dev.getConfig()
  12.435 -        if dev_config:
  12.436 -            self.config.remove(['device', dev_config])
  12.437 -        self.deleteDevice(type, dev.getId())
  12.438  
  12.439      def configure_restart(self):
  12.440          """Configure the vm restart mode.
  12.441 @@ -1036,7 +887,7 @@ class XendDomainInfo:
  12.442          """Configure a vm.
  12.443  
  12.444          """
  12.445 -        self.configure_fields()
  12.446 +        self.configure_maxmem()
  12.447          self.create_devices()
  12.448          self.create_blkif()
  12.449  
  12.450 @@ -1047,26 +898,15 @@ class XendDomainInfo:
  12.451  
  12.452          """
  12.453          return
  12.454 -        blkif = self.getDeviceController("vbd", error=False)
  12.455 -        if not blkif:
  12.456 -            blkif = self.createDeviceController("vbd")
  12.457 -            backend = blkif.getBackend(0)
  12.458 -            backend.connect(recreate=self.recreate)
  12.459  
  12.460 -    def configure_fields(self):
  12.461 -        """Process the vm configuration fields using the registered handlers.
  12.462 -        """
  12.463 -        index = {}
  12.464 -        for field in sxp.children(self.config):
  12.465 -            field_name = sxp.name(field)
  12.466 -            field_index = index.get(field_name, 0)
  12.467 -            field_handler = config_handlers.get(field_name)
  12.468 -            # Ignore unknown fields. Warn?
  12.469 -            if field_handler:
  12.470 -                v = field_handler(self, self.config, field, field_index)
  12.471 -            else:
  12.472 -                log.warning("Unknown config field %s", field_name)
  12.473 -            index[field_name] = field_index + 1
  12.474 +    def configure_maxmem(self):
  12.475 +        try:
  12.476 +            maxmem = int(sxp.child_value(self.config, 'maxmem', self.memory))
  12.477 +            xc.domain_setmaxmem(self.domid, maxmem_kb = maxmem * 1024)
  12.478 +        except:
  12.479 +            raise VmError("invalid maxmem: " +
  12.480 +                          sxp.child_value(self.config, 'maxmem'))
  12.481 +
  12.482  
  12.483      def vcpu_hotplug(self, vcpu, state):
  12.484          """Disable or enable VCPU in domain.
  12.485 @@ -1138,26 +978,6 @@ class XendDomainInfo:
  12.486                  self.vcpu_hotplug(vcpu, 0)
  12.487  
  12.488  
  12.489 -def vm_field_ignore(_, _1, _2, _3):
  12.490 -    """Dummy config field handler used for fields with built-in handling.
  12.491 -    Matches the signature required by config_handlers.
  12.492 -    """
  12.493 -    pass
  12.494 -
  12.495 -
  12.496 -def vm_field_maxmem(vm, _1, val, _2):
  12.497 -    """Config field handler to configure vm memory limit.  Matches the
  12.498 -    signature required by config_handlers.
  12.499 -    """
  12.500 -    maxmem = sxp.child0(val)
  12.501 -    if maxmem is None:
  12.502 -        maxmem = vm.memory
  12.503 -    try:
  12.504 -        maxmem = int(maxmem)
  12.505 -    except:
  12.506 -        raise VmError("invalid maxmem: " + str(maxmem))
  12.507 -    xc.domain_setmaxmem(vm.domid, maxmem_kb = maxmem * 1024)
  12.508 -
  12.509  
  12.510  #============================================================================
  12.511  # Register image handlers.
  12.512 @@ -1172,37 +992,24 @@ addImageHandlerClass(LinuxImageHandler)
  12.513  addImageHandlerClass(VmxImageHandler)
  12.514  
  12.515  
  12.516 -"""Table of handlers for field configuration.
  12.517 -
  12.518 -field_name[String]: fn(vm, config, field, index) -> value(ignored)
  12.519 -"""
  12.520 -config_handlers = {
  12.521 -    
  12.522 -    # Ignore the fields we already handle.
  12.523 -    
  12.524 -    'name':       vm_field_ignore,
  12.525 -    'memory':     vm_field_ignore,
  12.526 -    'ssidref':    vm_field_ignore,
  12.527 -    'cpu':        vm_field_ignore,
  12.528 -    'cpu_weight': vm_field_ignore,
  12.529 -    'restart':    vm_field_ignore,
  12.530 -    'image':      vm_field_ignore,
  12.531 -    'device':     vm_field_ignore,
  12.532 -    'backend':    vm_field_ignore,
  12.533 -    'vcpus':      vm_field_ignore,
  12.534 -    'bootloader': vm_field_ignore,
  12.535 -    
  12.536 -    # Register other config handlers.
  12.537 -    'maxmem':     vm_field_maxmem
  12.538 -    }
  12.539 -
  12.540 -
  12.541  #============================================================================
  12.542  # Register device controllers and their device config types.
  12.543  
  12.544 +"""A map from device-class names to the subclass of DevController that
  12.545 +implements the device control specific to that device-class."""
  12.546 +controllerClasses = {}
  12.547 +
  12.548 +
  12.549 +def addControllerClass(device_class, cls):
  12.550 +    """Register a subclass of DevController to handle the named device-class.
  12.551 +    """
  12.552 +    cls.deviceClass = device_class
  12.553 +    controllerClasses[device_class] = cls
  12.554 +
  12.555 +
  12.556  from xen.xend.server import blkif, netif, tpmif, pciif, usbif
  12.557 -controller.addDevControllerClass("vbd",  blkif.BlkifController)
  12.558 -controller.addDevControllerClass("vif",  netif.NetifController)
  12.559 -controller.addDevControllerClass("vtpm", tpmif.TPMifController)
  12.560 -controller.addDevControllerClass("pci",  pciif.PciController)
  12.561 -controller.addDevControllerClass("usb",  usbif.UsbifController)
  12.562 +addControllerClass('vbd',  blkif.BlkifController)
  12.563 +addControllerClass('vif',  netif.NetifController)
  12.564 +addControllerClass('vtpm', tpmif.TPMifController)
  12.565 +addControllerClass('pci',  pciif.PciController)
  12.566 +addControllerClass('usb',  usbif.UsbifController)
    13.1 --- a/tools/python/xen/xend/image.py	Mon Sep 19 09:14:41 2005 +0000
    13.2 +++ b/tools/python/xen/xend/image.py	Mon Sep 19 10:51:05 2005 +0000
    13.3 @@ -18,7 +18,7 @@
    13.4  import os, string
    13.5  import re
    13.6  
    13.7 -import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    13.8 +import xen.lowlevel.xc
    13.9  from xen.xend import sxp
   13.10  from xen.xend.XendError import VmError
   13.11  from xen.xend.XendLogging import log
   13.12 @@ -27,6 +27,10 @@ from xen.xend.xenstore.xstransact import
   13.13  
   13.14  from xen.xend.server import channel
   13.15  
   13.16 +
   13.17 +xc = xen.lowlevel.xc.new()
   13.18 +
   13.19 +
   13.20  MAX_GUEST_CMDLINE = 1024
   13.21  
   13.22  class ImageHandler:
   13.23 @@ -155,7 +159,8 @@ class ImageHandler:
   13.24                  self.unlink(self.kernel)
   13.25                  self.unlink(self.ramdisk)
   13.26              if dom <= 0:
   13.27 -                raise VmError('Creating domain failed: name=%s' % self.vm.name)
   13.28 +                raise VmError('Creating domain failed: name=%s' %
   13.29 +                              self.vm.getName())
   13.30          log.debug("initDomain: cpu=%d mem_kb=%d ssidref=%d dom=%d", cpu, mem_kb, ssidref, dom)
   13.31          xc.domain_setcpuweight(dom, cpu_weight)
   13.32          xc.domain_setmaxmem(dom, mem_kb)
   13.33 @@ -183,21 +188,22 @@ class ImageHandler:
   13.34              return
   13.35  
   13.36          # Set params and call buildDomain().
   13.37 -        self.flags = self.vm.backend_flags
   13.38 +        self.flags = self.vm.getBackendFlags()
   13.39  
   13.40          if not os.path.isfile(self.kernel):
   13.41              raise VmError('Kernel image does not exist: %s' % self.kernel)
   13.42          if self.ramdisk and not os.path.isfile(self.ramdisk):
   13.43              raise VmError('Kernel ramdisk does not exist: %s' % self.ramdisk)
   13.44          if len(self.cmdline) >= MAX_GUEST_CMDLINE:
   13.45 -            log.warning('kernel cmdline too long, domain %d', self.vm.domid)
   13.46 +            log.warning('kernel cmdline too long, domain %d',
   13.47 +                        self.vm.getDomain())
   13.48          
   13.49          log.info("buildDomain os=%s dom=%d vcpus=%d", self.ostype,
   13.50 -                 self.vm.domid, self.vm.vcpus)
   13.51 +                 self.vm.getDomain(), self.vm.getVCpuCount())
   13.52          err = self.buildDomain()
   13.53          if err != 0:
   13.54              raise VmError('Building domain failed: ostype=%s dom=%d err=%d'
   13.55 -                          % (self.ostype, self.vm.domid, err))
   13.56 +                          % (self.ostype, self.vm.getDomain(), err))
   13.57  
   13.58      def getDomainMemory(self, mem_mb):
   13.59          """Memory (in KB) the domain will need for mem_mb (in MB)."""
   13.60 @@ -237,23 +243,23 @@ class LinuxImageHandler(ImageHandler):
   13.61          else:
   13.62              console_evtchn = 0
   13.63  
   13.64 -        log.debug("dom            = %d", self.vm.domid)
   13.65 +        log.debug("dom            = %d", self.vm.getDomain())
   13.66          log.debug("image          = %s", self.kernel)
   13.67          log.debug("store_evtchn   = %d", store_evtchn)
   13.68          log.debug("console_evtchn = %d", console_evtchn)
   13.69          log.debug("cmdline        = %s", self.cmdline)
   13.70          log.debug("ramdisk        = %s", self.ramdisk)
   13.71          log.debug("flags          = %d", self.flags)
   13.72 -        log.debug("vcpus          = %d", self.vm.vcpus)
   13.73 +        log.debug("vcpus          = %d", self.vm.getVCpuCount())
   13.74  
   13.75 -        ret = xc.linux_build(dom            = self.vm.domid,
   13.76 +        ret = xc.linux_build(dom            = self.vm.getDomain(),
   13.77                               image          = self.kernel,
   13.78                               store_evtchn   = store_evtchn,
   13.79                               console_evtchn = console_evtchn,
   13.80                               cmdline        = self.cmdline,
   13.81                               ramdisk        = self.ramdisk,
   13.82                               flags          = self.flags,
   13.83 -                             vcpus          = self.vm.vcpus)
   13.84 +                             vcpus          = self.vm.getVCpuCount())
   13.85          if isinstance(ret, dict):
   13.86              self.set_vminfo(ret)
   13.87              return 0
   13.88 @@ -297,22 +303,22 @@ class VmxImageHandler(ImageHandler):
   13.89  
   13.90      def buildDomain(self):
   13.91          # Create an event channel
   13.92 -        self.device_channel = channel.eventChannel(0, self.vm.domid)
   13.93 +        self.device_channel = channel.eventChannel(0, self.vm.getDomain())
   13.94          log.info("VMX device model port: %d", self.device_channel.port2)
   13.95          if self.vm.store_channel:
   13.96              store_evtchn = self.vm.store_channel.port2
   13.97          else:
   13.98              store_evtchn = 0
   13.99 -        ret = xc.vmx_build(dom            = self.vm.domid,
  13.100 +        ret = xc.vmx_build(dom            = self.vm.getDomain(),
  13.101                             image          = self.kernel,
  13.102                             control_evtchn = self.device_channel.port2,
  13.103                             store_evtchn   = store_evtchn,
  13.104 -                           memsize        = self.vm.memory,
  13.105 +                           memsize        = self.vm.getMemoryTarget(),
  13.106                             memmap         = self.memmap_value,
  13.107                             cmdline        = self.cmdline,
  13.108                             ramdisk        = self.ramdisk,
  13.109                             flags          = self.flags,
  13.110 -                           vcpus          = self.vm.vcpus)
  13.111 +                           vcpus          = self.vm.getVCpuCount())
  13.112          if isinstance(ret, dict):
  13.113              self.set_vminfo(ret)
  13.114              return 0
  13.115 @@ -391,7 +397,7 @@ class VmxImageHandler(ImageHandler):
  13.116          elif vnc:
  13.117              ret = ret + ['-vnc', '-k', 'en-us']
  13.118          if vnc:
  13.119 -            vncport = int(self.vm.domid) + 5900
  13.120 +            vncport = int(self.vm.getDomain()) + 5900
  13.121              ret = ret + ['-vncport', '%d' % vncport]
  13.122          return ret
  13.123  
  13.124 @@ -405,9 +411,9 @@ class VmxImageHandler(ImageHandler):
  13.125          vnc = self.vncParams()
  13.126          if len(vnc):
  13.127              args = args + vnc
  13.128 -        args = args + ([ "-d",  "%d" % self.vm.domid,
  13.129 +        args = args + ([ "-d",  "%d" % self.vm.getDomain(),
  13.130                    "-p", "%d" % self.device_channel.port1,
  13.131 -                  "-m", "%s" % self.vm.memory ])
  13.132 +                  "-m", "%s" % self.vm.getMemoryTarget() ])
  13.133          args = args + self.dmargs
  13.134          env = dict(os.environ)
  13.135          env['DISPLAY'] = self.display
    14.1 --- a/tools/python/xen/xend/scheduler.py	Mon Sep 19 09:14:41 2005 +0000
    14.2 +++ b/tools/python/xen/xend/scheduler.py	Mon Sep 19 10:51:05 2005 +0000
    14.3 @@ -13,11 +13,12 @@
    14.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    14.5  #============================================================================
    14.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
    14.7 +# Copyright (C) 2005 XenSource Ltd
    14.8  #============================================================================
    14.9  
   14.10  import threading
   14.11  
   14.12 -def later(delay, fn, args=(), kwargs={}):
   14.13 +def later(delay, fn, *args, **kwargs):
   14.14      """Schedule a function to be called later.
   14.15  
   14.16      @param delay:  delay in seconds
   14.17 @@ -29,7 +30,7 @@ def later(delay, fn, args=(), kwargs={})
   14.18      timer.start()
   14.19      return timer
   14.20  
   14.21 -def now(fn, args=(), kwargs={}):
   14.22 +def now(fn, *args, **kwargs):
   14.23      """Schedule a function to be called now.
   14.24  
   14.25      @param fn:     function
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/python/xen/xend/server/DevController.py	Mon Sep 19 10:51:05 2005 +0000
    15.3 @@ -0,0 +1,203 @@
    15.4 +#============================================================================
    15.5 +# This library is free software; you can redistribute it and/or
    15.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    15.7 +# License as published by the Free Software Foundation.
    15.8 +#
    15.9 +# This library is distributed in the hope that it will be useful,
   15.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15.12 +# Lesser General Public License for more details.
   15.13 +#
   15.14 +# You should have received a copy of the GNU Lesser General Public
   15.15 +# License along with this library; if not, write to the Free Software
   15.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   15.17 +#============================================================================
   15.18 +# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
   15.19 +# Copyright (C) 2005 XenSource Ltd
   15.20 +#============================================================================
   15.21 +
   15.22 +
   15.23 +from xen.xend import sxp
   15.24 +from xen.xend.XendError import VmError
   15.25 +from xen.xend.XendLogging import log
   15.26 +from xen.xend.xenstore.xstransact import xstransact
   15.27 +
   15.28 +
   15.29 +class DevController:
   15.30 +    """Abstract base class for a device controller.  Device controllers create
   15.31 +    appropriate entries in the store to trigger the creation, reconfiguration,
   15.32 +    and destruction of devices in guest domains.  Each subclass of
   15.33 +    DevController is responsible for a particular device-class, and
   15.34 +    understands the details of configuration specific to that device-class.
   15.35 +
   15.36 +    DevController itself provides the functionality common to all device
   15.37 +    creation tasks, as well as providing an interface to XendDomainInfo for
   15.38 +    triggering those events themselves.
   15.39 +    """
   15.40 +
   15.41 +    # Set when registered.
   15.42 +    deviceClass = None
   15.43 +
   15.44 +
   15.45 +    ## public:
   15.46 +
   15.47 +    def __init__(self, vm):
   15.48 +        self.vm = vm
   15.49 +
   15.50 +
   15.51 +    def createDevice(self, config):
   15.52 +        """Trigger the creation of a device with the given configuration.
   15.53 +
   15.54 +        @return The ID for the newly created device.
   15.55 +        """
   15.56 +        (devid, back, front) = self.getDeviceDetails(config)
   15.57 +
   15.58 +        self.writeDetails(config, devid, back, front)
   15.59 +
   15.60 +        return devid
   15.61 +
   15.62 +
   15.63 +    def reconfigureDevice(self, devid, config):
   15.64 +        """Reconfigure the specified device.
   15.65 +
   15.66 +        The implementation here just raises VmError.  This may be overridden
   15.67 +        by those subclasses that can reconfigure their devices.
   15.68 +        """
   15.69 +        raise VmError('%s devices may not be reconfigured' % self.deviceClass)
   15.70 +
   15.71 +
   15.72 +    def destroyDevice(self, devid):
   15.73 +        """Destroy the specified device.
   15.74 +
   15.75 +        The implementation here simply deletes the appropriate paths from
   15.76 +        the store.  This may be overridden by subclasses who need to perform
   15.77 +        other tasks on destruction.
   15.78 +        """
   15.79 +
   15.80 +        frontpath = self.frontendPath(devid)
   15.81 +        backpath = xstransact.Read("%s/backend" % frontpath)
   15.82 +
   15.83 +        xstransact.Remove(frontpath)
   15.84 +        xstransact.Remove(backpath)
   15.85 +
   15.86 +
   15.87 +    def sxpr(self, devid):
   15.88 +        """@return an s-expression describing the specified device.
   15.89 +        """
   15.90 +        return [self.deviceClass, ['dom', self.vm.getDomain(),
   15.91 +                                   'id', devid]]
   15.92 +
   15.93 +
   15.94 +    ## protected:
   15.95 +
   15.96 +    def getDeviceDetails(self, config):
   15.97 +        """Compute the details for creation of a device corresponding to the
   15.98 +        given configuration.  These details consist of a tuple of (devID,
   15.99 +        backDetails, frontDetails), where devID is the ID for the new device,
  15.100 +        and backDetails and frontDetails are the device configuration
  15.101 +        specifics for the backend and frontend respectively.
  15.102 +
  15.103 +        backDetails and frontDetails should be dictionaries, the keys and
  15.104 +        values of which will be used as paths in the store.  There is no need
  15.105 +        for these dictionaries to include the references from frontend to
  15.106 +        backend, nor vice versa, as these will be handled by DevController.
  15.107 +
  15.108 +        Abstract; must be implemented by every subclass.
  15.109 +
  15.110 +        @return (devID, backDetails, frontDetails), as specified above.
  15.111 +        """
  15.112 +
  15.113 +        raise NotImplementedError()
  15.114 +
  15.115 +
  15.116 +    def getDomain(self):
  15.117 +        """Stub to {@link XendDomainInfo.getDomain}, for use by our
  15.118 +        subclasses.
  15.119 +        """
  15.120 +        return self.vm.getDomain()
  15.121 +
  15.122 +
  15.123 +    def allocateDeviceID(self):
  15.124 +        """Allocate a device ID, allocating them consecutively on a
  15.125 +        per-domain, per-device-class basis, and using the store to record the
  15.126 +        next available ID.
  15.127 +
  15.128 +        This method is available to our subclasses, though it is not
  15.129 +        compulsory to use it; subclasses may prefer to allocate IDs based upon
  15.130 +        the device configuration instead.
  15.131 +        """
  15.132 +        path = self.frontendMiscPath()
  15.133 +        t = xstransact(path)
  15.134 +        try:
  15.135 +            result = t.read("nextDeviceID")
  15.136 +            if result:
  15.137 +                result = int(result)
  15.138 +            else:
  15.139 +                result = 1
  15.140 +            t.write("nextDeviceID", str(result + 1))
  15.141 +            t.commit()
  15.142 +            return result
  15.143 +        except:
  15.144 +            t.abort()
  15.145 +            raise
  15.146 +
  15.147 +
  15.148 +    ## private:
  15.149 +
  15.150 +    def writeDetails(self, config, devid, backDetails, frontDetails):
  15.151 +        """Write the details in the store to trigger creation of a device.
  15.152 +        The backend domain ID is taken from the given config, paths for
  15.153 +        frontend and backend are computed, and these are written to the store
  15.154 +        appropriately, including references from frontend to backend and vice
  15.155 +        versa.
  15.156 +
  15.157 +        @param config The configuration of the device, as given to
  15.158 +        {@link #createDevice}.
  15.159 +        @param devid        As returned by {@link #getDeviceDetails}.
  15.160 +        @param backDetails  As returned by {@link #getDeviceDetails}.
  15.161 +        @param frontDetails As returned by {@link #getDeviceDetails}.
  15.162 +        """
  15.163 +
  15.164 +        import xen.xend.XendDomain
  15.165 +        backdom = xen.xend.XendDomain.instance().domain_lookup_by_name(
  15.166 +            sxp.child_value(config, 'backend', '0'))
  15.167 +
  15.168 +        frontpath = self.frontendPath(devid)
  15.169 +        backpath  = self.backendPath(backdom, devid)
  15.170 +        
  15.171 +        frontDetails.update({
  15.172 +            'backend' : backpath,
  15.173 +            'backend-id' : "%i" % backdom.getDomain()
  15.174 +            })
  15.175 +
  15.176 +
  15.177 +        backDetails.update({
  15.178 +            'domain' : self.vm.getName(),
  15.179 +            'frontend' : frontpath,
  15.180 +            'frontend-id' : "%i" % self.vm.getDomain()
  15.181 +            })
  15.182 +
  15.183 +        log.debug('DevController: writing %s to %s.', str(frontDetails),
  15.184 +                  frontpath)
  15.185 +        log.debug('DevController: writing %s to %s.', str(backDetails),
  15.186 +                  backpath)
  15.187 +
  15.188 +        xstransact.Write(frontpath, frontDetails)
  15.189 +        xstransact.Write(backpath, backDetails)
  15.190 +
  15.191 +
  15.192 +    def backendPath(self, backdom, devid):
  15.193 +        """@param backdom [XendDomainInfo] The backend domain info."""
  15.194 +
  15.195 +        return "%s/backend/%s/%s/%d" % (backdom.getPath(),
  15.196 +                                        self.deviceClass,
  15.197 +                                        self.vm.getUuid(), devid)
  15.198 +
  15.199 +
  15.200 +    def frontendPath(self, devid):
  15.201 +        return "%s/device/%s/%d" % (self.vm.getPath(), self.deviceClass,
  15.202 +                                    devid)
  15.203 +
  15.204 +
  15.205 +    def frontendMiscPath(self):
  15.206 +        return "%s/device-misc/%s" % (self.vm.getPath(), self.deviceClass)
    16.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Mon Sep 19 09:14:41 2005 +0000
    16.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Mon Sep 19 10:51:05 2005 +0000
    16.3 @@ -85,7 +85,7 @@ class SrvDomainDir(SrvDir):
    16.4      def _op_create_cb(self, dominfo, configstring, req):
    16.5          """Callback to handle domain creation.
    16.6          """
    16.7 -        dom = dominfo.name
    16.8 +        dom = dominfo.getName()
    16.9          domurl = "%s/%s" % (req.prePathURL(), dom)
   16.10          req.setResponseCode(http.CREATED, "created")
   16.11          req.setHeader("Location", domurl)
   16.12 @@ -112,7 +112,7 @@ class SrvDomainDir(SrvDir):
   16.13          fn = FormFn(self.xd.domain_restore,
   16.14                      [['file', 'str']])
   16.15          dominfo = fn(req.args)
   16.16 -        dom = dominfo.name
   16.17 +        dom = dominfo.getName()
   16.18          domurl = "%s/%s" % (req.prePathURL(), dom)
   16.19          req.setResponseCode(http.CREATED)
   16.20          req.setHeader("Location", domurl)
   16.21 @@ -152,12 +152,12 @@ class SrvDomainDir(SrvDir):
   16.22              domains = self.xd.list_sorted()
   16.23              req.write('<ul>')
   16.24              for d in domains:
   16.25 -               req.write('<li><a href="%s%s"> Domain %s</a>'
   16.26 -                         % (url, d.name, d.name))
   16.27 -               req.write('id=%s' % d.domid)
   16.28 -               req.write('memory=%d'% d.memory)
   16.29 -               req.write('ssidref=%d'% d.ssidref)
   16.30 -               req.write('</li>')
   16.31 +                req.write('<li><a href="%s%s"> Domain %s</a>'
   16.32 +                          % (url, d.getName(), d.getName()))
   16.33 +                req.write('id=%s' % d.getDomain())
   16.34 +                req.write('memory=%d'% d.getMemoryTarget())
   16.35 +                req.write('ssidref=%d'% d.getSsidref())
   16.36 +                req.write('</li>')
   16.37              req.write('</ul>')
   16.38  
   16.39      def form(self, req):
    17.1 --- a/tools/python/xen/xend/server/SrvNode.py	Mon Sep 19 09:14:41 2005 +0000
    17.2 +++ b/tools/python/xen/xend/server/SrvNode.py	Mon Sep 19 10:51:05 2005 +0000
    17.3 @@ -15,7 +15,6 @@
    17.4  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
    17.5  #============================================================================
    17.6  
    17.7 -import os
    17.8  
    17.9  from xen.web.SrvDir import SrvDir
   17.10  from xen.xend import sxp
   17.11 @@ -32,15 +31,15 @@ class SrvNode(SrvDir):
   17.12          self.add('dmesg', 'SrvDmesg')
   17.13          self.add('log', 'SrvXendLog')
   17.14  
   17.15 -    def op_shutdown(self, op, req):
   17.16 +    def op_shutdown(self, _1, _2):
   17.17          val = self.xn.shutdown()
   17.18          return val
   17.19  
   17.20 -    def op_reboot(self, op, req):
   17.21 +    def op_reboot(self, _1, _2):
   17.22          val = self.xn.reboot()
   17.23          return val
   17.24  
   17.25 -    def op_cpu_bvt_slice_set(self, op, req):
   17.26 +    def op_cpu_bvt_slice_set(self, _, req):
   17.27          fn = FormFn(self.xn.cpu_bvt_slice_set,
   17.28                      [['ctx_allow', 'int']])
   17.29          val = fn(req.args, {})
    18.1 --- a/tools/python/xen/xend/server/SrvServer.py	Mon Sep 19 09:14:41 2005 +0000
    18.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Mon Sep 19 10:51:05 2005 +0000
    18.3 @@ -44,7 +44,7 @@ from threading import Thread
    18.4  
    18.5  from xen.web.httpserver import HttpServer, UnixHttpServer
    18.6  
    18.7 -from xen.xend import XendRoot; xroot = XendRoot.instance()
    18.8 +from xen.xend import XendRoot
    18.9  from xen.xend import Vifctl
   18.10  from xen.xend.XendLogging import log
   18.11  from xen.web.SrvDir import SrvDir
   18.12 @@ -52,6 +52,10 @@ import time
   18.13  
   18.14  from SrvRoot import SrvRoot
   18.15  
   18.16 +
   18.17 +xroot = XendRoot.instance()
   18.18 +
   18.19 +
   18.20  class XendServers:
   18.21  
   18.22      def __init__(self):
    19.1 --- a/tools/python/xen/xend/server/blkif.py	Mon Sep 19 09:14:41 2005 +0000
    19.2 +++ b/tools/python/xen/xend/server/blkif.py	Mon Sep 19 10:51:05 2005 +0000
    19.3 @@ -13,322 +13,47 @@
    19.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    19.5  #============================================================================
    19.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
    19.7 +# Copyright (C) 2005 XenSource Ltd
    19.8  #============================================================================
    19.9  
   19.10 -"""Support for virtual block devices.
   19.11 -"""
   19.12 +
   19.13 +import re
   19.14  import string
   19.15  
   19.16  from xen.util import blkif
   19.17 -from xen.xend.XendError import XendError, VmError
   19.18 -from xen.xend.XendRoot import get_component
   19.19 -from xen.xend.XendLogging import log
   19.20  from xen.xend import sxp
   19.21 -from xen.xend import Blkctl
   19.22 -from xen.xend.xenstore import DBVar
   19.23 -
   19.24 -from xen.xend.server.controller import Dev, DevController
   19.25 -
   19.26 -class BlkifBackend:
   19.27 -    """ Handler for the 'back-end' channel to a block device driver domain
   19.28 -    on behalf of a front-end domain.
   19.29 -    Must be connected using connect() before it can be used.
   19.30 -    """
   19.31 -
   19.32 -    def __init__(self, controller, id, dom, recreate=False):
   19.33 -        self.controller = controller
   19.34 -        self.id = id
   19.35 -        self.frontendDomain = self.controller.getDomain()
   19.36 -        self.backendDomain = dom
   19.37 -        self.destroyed = False
   19.38 -        self.connected = False
   19.39 -        self.status = None
   19.40 -
   19.41 -    def init(self, recreate=False, reboot=False):
   19.42 -        self.destroyed = False
   19.43 -        self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
   19.44 -        self.frontendDomain = self.controller.getDomain()
   19.45 -
   19.46 -    def __str__(self):
   19.47 -        return ('<BlkifBackend frontend=%d backend=%d id=%d>'
   19.48 -                % (self.frontendDomain,
   19.49 -                   self.backendDomain,
   19.50 -                   self.id))
   19.51 -
   19.52 -    def getId(self):
   19.53 -        return self.id
   19.54 -
   19.55 -    def connect(self, recreate=False):
   19.56 -        """Connect to the blkif control interface.
   19.57 -
   19.58 -        @param recreate: true if after xend restart
   19.59 -        """
   19.60 -        log.debug("Connecting blkif %s", str(self))
   19.61 -        if recreate or self.connected:
   19.62 -            self.connected = True
   19.63 -            pass
   19.64 -        
   19.65 -    def destroy(self, change=False, reboot=False):
   19.66 -        """Disconnect from the blkif control interface and destroy it.
   19.67 -        """
   19.68 -        self.destroyed = True
   19.69 -        # For change true need to notify front-end, or back-end will do it?
   19.70 -
   19.71 -    def connectInterface(self, val):
   19.72 -        self.status = BLKIF_INTERFACE_STATUS_CONNECTED
   19.73 -            
   19.74 -    def interfaceDisconnected(self):
   19.75 -        self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
   19.76 -        
   19.77 -class BlkDev(Dev):
   19.78 -    """Info record for a block device.
   19.79 -    """
   19.80 -
   19.81 -    __exports__ = Dev.__exports__ + [
   19.82 -        DBVar('dev',          ty='str'),
   19.83 -        DBVar('vdev',         ty='int'),
   19.84 -        DBVar('mode',         ty='str'),
   19.85 -        DBVar('viftype',      ty='str'),
   19.86 -        DBVar('params',       ty='str'),
   19.87 -        DBVar('node',         ty='str'),
   19.88 -        DBVar('device',       ty='long'),
   19.89 -        DBVar('dev_handle',   ty='long'),
   19.90 -        DBVar('start_sector', ty='long'),
   19.91 -        DBVar('nr_sectors',   ty='long'),
   19.92 -        ]
   19.93 -
   19.94 -    def __init__(self, controller, id, config, recreate=False):
   19.95 -        Dev.__init__(self, controller, id, config, recreate=recreate)
   19.96 -        self.dev = None
   19.97 -        self.uname = None
   19.98 -        self.vdev = None
   19.99 -        self.mode = None
  19.100 -        self.type = None
  19.101 -        self.params = None
  19.102 -        self.node = None
  19.103 -        self.device = None
  19.104 -        self.dev_handle = 0
  19.105 -        self.start_sector = None
  19.106 -        self.nr_sectors = None
  19.107 -        
  19.108 -        self.frontendDomain = self.getDomain()
  19.109 -        self.backendDomain = None
  19.110 -        self.backendId = 0
  19.111 -        self.configure(self.config, recreate=recreate)
  19.112 -
  19.113 -    def exportToDB(self, save=False):
  19.114 -        Dev.exportToDB(self, save=save)
  19.115 -        backend = self.getBackend()
  19.116 -
  19.117 -    def init(self, recreate=False, reboot=False):
  19.118 -        self.frontendDomain = self.getDomain()
  19.119 -        backend = self.getBackend()
  19.120 -        self.backendId = backend.domid
  19.121  
  19.122 -    def configure(self, config, change=False, recreate=False):
  19.123 -        if change:
  19.124 -            raise XendError("cannot reconfigure vbd")
  19.125 -        self.config = config
  19.126 -        self.uname = sxp.child_value(config, 'uname')
  19.127 -        if not self.uname:
  19.128 -            raise VmError('vbd: Missing uname')
  19.129 -        # Split into type and type-specific params (which are passed to the
  19.130 -        # type-specific control script).
  19.131 -        (self.type, self.params) = string.split(self.uname, ':', 1)
  19.132 -        self.dev = sxp.child_value(config, 'dev')
  19.133 -        if not self.dev:
  19.134 -            raise VmError('vbd: Missing dev')
  19.135 -        self.mode = sxp.child_value(config, 'mode', 'r')
  19.136 -        
  19.137 -        self.vdev = blkif.blkdev_name_to_number(self.dev)
  19.138 -        if not self.vdev:
  19.139 -            raise VmError('vbd: Device not found: %s' % self.dev)
  19.140 -        
  19.141 -        try:
  19.142 -            xd = get_component('xen.xend.XendDomain')
  19.143 -            self.backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).domid
  19.144 -        except:
  19.145 -            raise XendError('invalid backend domain')
  19.146 -
  19.147 -        return self.config
  19.148 -
  19.149 -    def attach(self, recreate=False, change=False):
  19.150 -        if recreate:
  19.151 -            pass
  19.152 -        else:
  19.153 -            node = Blkctl.block('bind', self.type, self.params)
  19.154 -            self.setNode(node)
  19.155 -            self.attachBackend()
  19.156 -        if change:
  19.157 -            self.interfaceChanged()
  19.158 -
  19.159 -    def unbind(self):
  19.160 -        if self.node is None: return
  19.161 -        log.debug("Unbinding vbd (type %s) from %s"
  19.162 -                  % (self.type, self.node))
  19.163 -        Blkctl.block('unbind', self.type, self.node)
  19.164 +from xen.xend.server.DevController import DevController
  19.165  
  19.166 -    def setNode(self, node):
  19.167 -    
  19.168 -        # NOTE: 
  19.169 -        # This clause is testing code for storage system experiments.
  19.170 -        # Add a new disk type that will just pass an opaque id in the
  19.171 -        # dev_handle and use an experimental device type.
  19.172 -        # Please contact andrew.warfield@cl.cam.ac.uk with any concerns.
  19.173 -        if self.type == 'parallax':
  19.174 -            self.node   = node
  19.175 -            self.device =  61440 # (240,0)
  19.176 -            self.dev_handle = long(self.params)
  19.177 -            self.nr_sectors = long(0)
  19.178 -            return
  19.179 -        # done.
  19.180 -            
  19.181 -        mounted_mode = self.check_mounted(node)
  19.182 -        if not '!' in self.mode and mounted_mode:
  19.183 -            if mounted_mode == "w":
  19.184 -                raise VmError("vbd: Segment %s is in writable use" %
  19.185 -                              self.uname)
  19.186 -            elif 'w' in self.mode:
  19.187 -                raise VmError("vbd: Segment %s is in read-only use" %
  19.188 -                              self.uname)
  19.189 -            
  19.190 -        segment = blkif.blkdev_segment(node)
  19.191 -        if not segment:
  19.192 -            raise VmError("vbd: Segment not found: uname=%s" % self.uname)
  19.193 -        self.node = node
  19.194 -        self.device = segment['device']
  19.195 -        self.start_sector = segment['start_sector']
  19.196 -        self.nr_sectors = segment['nr_sectors']
  19.197  
  19.198 -    def check_mounted(self, name):
  19.199 -        mode = blkif.mount_mode(name)
  19.200 -        xd = get_component('xen.xend.XendDomain')
  19.201 -        for vm in xd.list():
  19.202 -            ctrl = vm.getDeviceController(self.getType(), error=False)
  19.203 -            if (not ctrl): continue
  19.204 -            for dev in ctrl.getDevices():
  19.205 -                if dev is self: continue
  19.206 -                if dev.type == 'phy' and name == blkif.expand_dev_name(dev.params):
  19.207 -                    mode = dev.mode
  19.208 -                    if 'w' in mode:
  19.209 -                        return 'w'
  19.210 -        if mode and 'r' in mode:
  19.211 -            return 'r'
  19.212 -        return None
  19.213 -
  19.214 -    def readonly(self):
  19.215 -        return 'w' not in self.mode
  19.216 -
  19.217 -    def sxpr(self):
  19.218 -        val = ['vbd',
  19.219 -               ['id', self.id],
  19.220 -               ['vdev', self.vdev],
  19.221 -               ['device', self.device],
  19.222 -               ['mode', self.mode]]
  19.223 -        if self.dev:
  19.224 -            val.append(['dev', self.dev])
  19.225 -        if self.uname:
  19.226 -            val.append(['uname', self.uname])
  19.227 -        if self.node:
  19.228 -            val.append(['node', self.node])
  19.229 -        return val
  19.230 -
  19.231 -    def getBackend(self):
  19.232 -        return self.controller.getBackend(self.backendDomain)
  19.233 -
  19.234 -    def refresh(self):
  19.235 -        log.debug("Refreshing vbd domain=%d id=%s", self.frontendDomain,
  19.236 -                  self.id)
  19.237 -        self.interfaceChanged()
  19.238 -
  19.239 -    def destroy(self, change=False, reboot=False):
  19.240 -        """Destroy the device. If 'change' is true notify the front-end interface.
  19.241 -
  19.242 -        @param change: change flag
  19.243 -        """
  19.244 -        self.destroyed = True
  19.245 -        log.debug("Destroying vbd domain=%d id=%s", self.frontendDomain,
  19.246 -                  self.id)
  19.247 -        if change:
  19.248 -            self.interfaceChanged()
  19.249 -        self.unbind()
  19.250 -
  19.251 -    def interfaceChanged(self):
  19.252 -        """Tell the back-end to notify the front-end that a device has been
  19.253 -        added or removed.
  19.254 -        """
  19.255 -        self.getBackend().interfaceChanged()
  19.256 -
  19.257 -    def attachBackend(self):
  19.258 -        """Attach the device to its controller.
  19.259 -
  19.260 -        """
  19.261 -        self.getBackend().connect()
  19.262 -        
  19.263  class BlkifController(DevController):
  19.264      """Block device interface controller. Handles all block devices
  19.265      for a domain.
  19.266      """
  19.267      
  19.268 -    def __init__(self, vm, recreate=False):
  19.269 +    def __init__(self, vm):
  19.270          """Create a block device controller.
  19.271          """
  19.272 -        DevController.__init__(self, vm, recreate=recreate)
  19.273 -        self.backends = {}
  19.274 -        self.backendId = 0
  19.275 +        DevController.__init__(self, vm)
  19.276  
  19.277 -    def initController(self, recreate=False, reboot=False):
  19.278 -        self.destroyed = False
  19.279 -        if reboot:
  19.280 -            self.rebootBackends()
  19.281 -            self.rebootDevices()
  19.282  
  19.283 -    def sxpr(self):
  19.284 -        val = ['blkif', ['dom', self.getDomain()]]
  19.285 -        return val
  19.286 -
  19.287 -    def rebootBackends(self):
  19.288 -        for backend in self.backends.values():
  19.289 -            backend.init(reboot=True)
  19.290 +    def getDeviceDetails(self, config):
  19.291 +        """@see DevController.getDeviceDetails"""
  19.292 +        
  19.293 +        typedev = sxp.child_value(config, 'dev')
  19.294 +        if re.match('^ioemu:', typedev):
  19.295 +            return
  19.296  
  19.297 -    def getBackendById(self, id):
  19.298 -        return self.backends.get(id)
  19.299 -
  19.300 -    def getBackendByDomain(self, dom):
  19.301 -        for backend in self.backends.values():
  19.302 -            if backend.backendDomain == dom:
  19.303 -                return backend
  19.304 -        return None
  19.305 +        devid = blkif.blkdev_name_to_number(sxp.child_value(config, 'dev'))
  19.306  
  19.307 -    def getBackend(self, dom):
  19.308 -        backend = self.getBackendByDomain(dom)
  19.309 -        if backend: return backend
  19.310 -        backend = BlkifBackend(self, self.backendId, dom)
  19.311 -        self.backendId += 1
  19.312 -        self.backends[backend.getId()] = backend
  19.313 -        backend.init()
  19.314 -        return backend
  19.315 -
  19.316 -    def newDevice(self, id, config, recreate=False):
  19.317 -        """Create a device..
  19.318 +        (typ, params) = string.split(sxp.child_value(config, 'uname'), ':', 1)
  19.319 +        back = { 'type' : typ,
  19.320 +                 'params' : params
  19.321 +                 }
  19.322  
  19.323 -        @param id:      device id
  19.324 -        @param config:   device configuration
  19.325 -        @param recreate: if true it's being recreated (after xend restart)
  19.326 -        @type  recreate: bool
  19.327 -        @return: device
  19.328 -        @rtype:  BlkDev
  19.329 -        """
  19.330 -        return BlkDev(self, id, config, recreate=recreate)
  19.331 -        
  19.332 -    def destroyController(self, reboot=False):
  19.333 -        """Destroy the controller and all devices.
  19.334 -        """
  19.335 -        self.destroyed = True
  19.336 -        log.debug("Destroying blkif domain=%d", self.getDomain())
  19.337 -        self.destroyDevices(reboot=reboot)
  19.338 -        self.destroyBackends(reboot=reboot)
  19.339 +        if 'r' == sxp.child_value(config, 'mode', 'r'):
  19.340 +            back['read-only'] = ""  # existence indicates read-only
  19.341  
  19.342 -    def destroyBackends(self, reboot=False):
  19.343 -        for backend in self.backends.values():
  19.344 -            backend.destroy(reboot=reboot)
  19.345 +        front = { 'virtual-device' : "%i" % devid }
  19.346 +
  19.347 +        return (devid, back, front)
    20.1 --- a/tools/python/xen/xend/server/channel.py	Mon Sep 19 09:14:41 2005 +0000
    20.2 +++ b/tools/python/xen/xend/server/channel.py	Mon Sep 19 10:51:05 2005 +0000
    20.3 @@ -43,33 +43,6 @@ class EventChannel(dict):
    20.4  
    20.5      interdomain = classmethod(interdomain)
    20.6  
    20.7 -    def restoreFromDB(cls, db, dom1, dom2, port1=0, port2=0):
    20.8 -        """Create an event channel using db info if available.
    20.9 -        Inverse to saveToDB().
   20.10 -
   20.11 -        @param db db
   20.12 -        @param dom1
   20.13 -        @param dom2
   20.14 -        @param port1
   20.15 -        @param port2
   20.16 -        """
   20.17 -        try:
   20.18 -            dom1  = int(db['dom1'].getData())
   20.19 -        except: pass
   20.20 -        try:
   20.21 -            dom2  = int(db['dom2'].getData())
   20.22 -        except: pass
   20.23 -        try:
   20.24 -            port1 = int(db['port1'].getData())
   20.25 -        except: pass
   20.26 -        try:
   20.27 -            port2 = int(db['port2'].getData())
   20.28 -        except: pass
   20.29 -        evtchn = cls.interdomain(dom1, dom2, port1=port1, port2=port2)
   20.30 -        return evtchn
   20.31 -
   20.32 -    restoreFromDB = classmethod(restoreFromDB)
   20.33 -
   20.34      def __init__(self, dom1, dom2, d):
   20.35          d['dom1'] = dom1
   20.36          d['dom2'] = dom2
   20.37 @@ -93,18 +66,6 @@ class EventChannel(dict):
   20.38          evtchn_close(self.dom1, self.port1)
   20.39          evtchn_close(self.dom2, self.port2)
   20.40  
   20.41 -    def saveToDB(self, db, save=False):
   20.42 -        """Save the event channel to the db so it can be restored later,
   20.43 -        using restoreFromDB() on the class.
   20.44 -
   20.45 -        @param db db
   20.46 -        """
   20.47 -        db['dom1']  = str(self.dom1)
   20.48 -        db['dom2']  = str(self.dom2)
   20.49 -        db['port1'] = str(self.port1)
   20.50 -        db['port2'] = str(self.port2)
   20.51 -        db.saveDB(save=save)
   20.52 -
   20.53      def sxpr(self):
   20.54          return ['event-channel',
   20.55                  ['dom1',  self.dom1  ],
    21.1 --- a/tools/python/xen/xend/server/controller.py	Mon Sep 19 09:14:41 2005 +0000
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,423 +0,0 @@
    21.4 -#============================================================================
    21.5 -# This library is free software; you can redistribute it and/or
    21.6 -# modify it under the terms of version 2.1 of the GNU Lesser General Public
    21.7 -# License as published by the Free Software Foundation.
    21.8 -#
    21.9 -# This library is distributed in the hope that it will be useful,
   21.10 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.11 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   21.12 -# Lesser General Public License for more details.
   21.13 -#
   21.14 -# You should have received a copy of the GNU Lesser General Public
   21.15 -# License along with this library; if not, write to the Free Software
   21.16 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21.17 -#============================================================================
   21.18 -# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
   21.19 -#============================================================================
   21.20 -
   21.21 -"""General support for controllers, which handle devices
   21.22 -for a domain.
   21.23 -"""
   21.24 -
   21.25 -from xen.xend.XendError import XendError
   21.26 -from xen.xend.xenstore import DBVar
   21.27 -
   21.28 -DEBUG = 0
   21.29 -
   21.30 -class DevControllerTable:
   21.31 -    """Table of device controller classes, indexed by type name.
   21.32 -    """
   21.33 -
   21.34 -    def __init__(self):
   21.35 -        self.controllerClasses = {}
   21.36 -
   21.37 -    def getDevControllerClass(self, type):
   21.38 -        return self.controllerClasses.get(type)
   21.39 -
   21.40 -    def addDevControllerClass(self, cls):
   21.41 -        self.controllerClasses[cls.getType()] = cls
   21.42 -
   21.43 -    def delDevControllerClass(self, type):
   21.44 -        if type in self.controllerClasses:
   21.45 -            del self.controllerClasses[type]
   21.46 -
   21.47 -    def createDevController(self, type, vm, recreate=False):
   21.48 -        cls = self.getDevControllerClass(type)
   21.49 -        if not cls:
   21.50 -            raise XendError("unknown device type: " + str(type))
   21.51 -        return cls.createDevController(vm, recreate=recreate)
   21.52 -
   21.53 -def getDevControllerTable():
   21.54 -    """Singleton constructor for the controller table.
   21.55 -    """
   21.56 -    global devControllerTable
   21.57 -    try:
   21.58 -        devControllerTable
   21.59 -    except:
   21.60 -        devControllerTable = DevControllerTable()
   21.61 -    return devControllerTable
   21.62 -
   21.63 -def addDevControllerClass(name, cls):
   21.64 -    """Add a device controller class to the controller table.
   21.65 -    """
   21.66 -    cls.type = name
   21.67 -    getDevControllerTable().addDevControllerClass(cls)
   21.68 -
   21.69 -
   21.70 -def isDevControllerClass(name):
   21.71 -    """@return True if a device controller class has been registered with
   21.72 -    the controller table under the given name."""
   21.73 -    return name in getDevControllerTable().controllerClasses
   21.74 -
   21.75 -
   21.76 -def createDevController(name, vm, recreate=False):
   21.77 -    return getDevControllerTable().createDevController(name, vm, recreate=recreate)
   21.78 -
   21.79 -class DevController:
   21.80 -    """Abstract class for a device controller attached to a domain.
   21.81 -    A device controller manages all the devices of a given type for a domain.
   21.82 -    There is exactly one device controller for each device type for
   21.83 -    a domain.
   21.84 -
   21.85 -    """
   21.86 -
   21.87 -    # State:
   21.88 -    # controller/<type> : for controller
   21.89 -    # device/<type>/<id>   : for each device
   21.90 -
   21.91 -    def createDevController(cls, vm, recreate=False):
   21.92 -        """Class method to create a dev controller.
   21.93 -        """
   21.94 -        ctrl = cls(vm, recreate=recreate)
   21.95 -        ctrl.initController(recreate=recreate)
   21.96 -        ctrl.exportToDB()
   21.97 -        return ctrl
   21.98 -
   21.99 -    createDevController = classmethod(createDevController)
  21.100 -
  21.101 -    def getType(cls):
  21.102 -        return cls.type
  21.103 -
  21.104 -    getType = classmethod(getType)
  21.105 -
  21.106 -    __exports__ = [
  21.107 -        DBVar('type',      'str'),
  21.108 -        DBVar('destroyed', 'bool'),
  21.109 -        ]
  21.110 -
  21.111 -    # Set when registered.
  21.112 -    type = None
  21.113 -
  21.114 -    def __init__(self, vm, recreate=False):
  21.115 -        self.destroyed = False
  21.116 -        self.vm = vm
  21.117 -        self.db = self.getDB()
  21.118 -        self.deviceId = 0
  21.119 -        self.devices = {}
  21.120 -        self.device_order = []
  21.121 -
  21.122 -    def getDB(self):
  21.123 -        """Get the db node to use for a controller.
  21.124 -        """
  21.125 -        return self.vm.db.addChild("/controller/%s" % self.getType())
  21.126 -
  21.127 -    def getDevDB(self, id):
  21.128 -        """Get the db node to use for a device.
  21.129 -        """
  21.130 -        return self.vm.db.addChild("/device/%s/%s" % (self.getType(), id))
  21.131 -
  21.132 -    def exportToDB(self, save=False):
  21.133 -        self.db.exportToDB(self, fields=self.__exports__, save=save)
  21.134 -
  21.135 -    def importFromDB(self):
  21.136 -        self.db.importFromDB(self, fields=self.__exports__)
  21.137 -
  21.138 -    def getDevControllerType(self):
  21.139 -        return self.dctype
  21.140 -
  21.141 -    def getDomain(self):
  21.142 -        return self.vm.getDomain()
  21.143 -
  21.144 -    def getDomainName(self):
  21.145 -        return self.vm.getName()
  21.146 -
  21.147 -    def getDomainInfo(self):
  21.148 -        return self.vm
  21.149 -
  21.150 -    #----------------------------------------------------------------------------
  21.151 -    # Subclass interface.
  21.152 -    # Subclasses should define the unimplemented methods..
  21.153 -    # Redefinitions must have the same arguments.
  21.154 -
  21.155 -    def initController(self, recreate=False, reboot=False):
  21.156 -        """Initialise the controller. Called when the controller is
  21.157 -        first created, and again after the domain is rebooted (with reboot True).
  21.158 -        If called with recreate True (and reboot False) the controller is being
  21.159 -        recreated after a xend restart.
  21.160 -
  21.161 -        As this can be a re-init (after reboot) any controller state should
  21.162 -        be reset. For example the destroyed flag.
  21.163 -        """
  21.164 -        self.destroyed = False
  21.165 -        if reboot:
  21.166 -            self.rebootDevices()
  21.167 -
  21.168 -    def newDevice(self, id, config, recreate=False):
  21.169 -        """Create a device with the given config.
  21.170 -        Must be defined in subclass.
  21.171 -        Called with recreate True when the device is being recreated after a
  21.172 -        xend restart.
  21.173 -
  21.174 -        @return device
  21.175 -        """
  21.176 -        raise NotImplementedError()
  21.177 -
  21.178 -    def createDevice(self, config, recreate=False, change=False):
  21.179 -        """Create a device and attach to its front- and back-ends.
  21.180 -        If recreate is true the device is being recreated after a xend restart.
  21.181 -        If change is true the device is a change to an existing domain,
  21.182 -        i.e. it is being added at runtime rather than when the domain is created.
  21.183 -        """
  21.184 -        dev = self.newDevice(self.nextDeviceId(), config, recreate=recreate)
  21.185 -        if self.vm.recreate:
  21.186 -            dev.importFromDB()
  21.187 -        dev.init(recreate=recreate)
  21.188 -        self.addDevice(dev)
  21.189 -        if not recreate:
  21.190 -            dev.exportToDB()
  21.191 -        dev.attach(recreate=recreate, change=change)
  21.192 -        dev.exportToDB()
  21.193 -
  21.194 -        return dev
  21.195 -
  21.196 -    def configureDevice(self, id, config, change=False):
  21.197 -        """Reconfigure an existing device.
  21.198 -        May be defined in subclass."""
  21.199 -        dev = self.getDevice(id, error=True)
  21.200 -        dev.configure(config, change=change)
  21.201 -
  21.202 -    def destroyDevice(self, id, change=False, reboot=False):
  21.203 -        """Destroy a device.
  21.204 -        May be defined in subclass.
  21.205 -
  21.206 -        If reboot is true the device is being destroyed for a domain reboot.
  21.207 -
  21.208 -        The device is not deleted, since it may be recreated later.
  21.209 -        """
  21.210 -        dev = self.getDevice(id, error=True)
  21.211 -        dev.destroy(change=change, reboot=reboot)
  21.212 -        return dev
  21.213 -
  21.214 -    def deleteDevice(self, id, change=True):
  21.215 -        """Destroy a device and delete it.
  21.216 -        Normally called to remove a device from a domain at runtime.
  21.217 -        """
  21.218 -        dev = self.destroyDevice(id, change=change)
  21.219 -        self.removeDevice(dev)
  21.220 -
  21.221 -    def destroyController(self, reboot=False):
  21.222 -        """Destroy all devices and clean up.
  21.223 -        May be defined in subclass.
  21.224 -        If reboot is true the controller is being destroyed for a domain reboot.
  21.225 -        Called at domain shutdown.
  21.226 -        """
  21.227 -        self.destroyed = True
  21.228 -        self.destroyDevices(reboot=reboot)
  21.229 -
  21.230 -    #----------------------------------------------------------------------------
  21.231 -    
  21.232 -    def isDestroyed(self):
  21.233 -        return self.destroyed
  21.234 -
  21.235 -    def getDevice(self, id, error=False):
  21.236 -        dev = self.devices.get(int(id))
  21.237 -        if error and not dev:
  21.238 -            raise XendError("invalid device id: " + str(id))
  21.239 -        return dev
  21.240 -
  21.241 -    def getDeviceIds(self):
  21.242 -        return [ dev.getId() for dev in self.device_order ]
  21.243 -
  21.244 -    def getDevices(self):
  21.245 -        return self.device_order
  21.246 -
  21.247 -    def getDeviceConfig(self, id):
  21.248 -        return self.getDevice(id).getConfig()
  21.249 -
  21.250 -    def getDeviceConfigs(self):
  21.251 -        return [ dev.getConfig() for dev in self.device_order ]
  21.252 -
  21.253 -    def getDeviceSxprs(self):
  21.254 -        return [ dev.sxpr() for dev in self.device_order ]
  21.255 -
  21.256 -    def addDevice(self, dev):
  21.257 -        self.devices[dev.getId()] = dev
  21.258 -        self.device_order.append(dev)
  21.259 -        return dev
  21.260 -
  21.261 -    def removeDevice(self, dev):
  21.262 -        if dev.getId() in self.devices:
  21.263 -            del self.devices[dev.getId()]
  21.264 -        if dev in self.device_order:
  21.265 -            self.device_order.remove(dev)
  21.266 -
  21.267 -    def rebootDevices(self):
  21.268 -        for dev in self.getDevices():
  21.269 -            dev.reboot()
  21.270 -
  21.271 -    def destroyDevices(self, reboot=False):
  21.272 -        """Destroy all devices.
  21.273 -        """
  21.274 -        for dev in self.getDevices():
  21.275 -            dev.destroy(reboot=reboot)
  21.276 -
  21.277 -    def getMaxDeviceId(self):
  21.278 -        maxid = 0
  21.279 -        for id in self.devices:
  21.280 -            if id > maxid:
  21.281 -                maxid = id
  21.282 -        return maxid
  21.283 -
  21.284 -    def nextDeviceId(self):
  21.285 -        id = self.deviceId
  21.286 -        self.deviceId += 1
  21.287 -        return id
  21.288 -
  21.289 -    def getDeviceCount(self):
  21.290 -        return len(self.devices)
  21.291 -
  21.292 -class Dev:
  21.293 -    """Abstract class for a device attached to a device controller.
  21.294 -
  21.295 -    @ivar id:        identifier
  21.296 -    @type id:        int
  21.297 -    @ivar controller: device controller
  21.298 -    @type controller: DevController
  21.299 -    """
  21.300 -    
  21.301 -    # ./status       : need 2: actual and requested?
  21.302 -    # down-down: initial.
  21.303 -    # up-up: fully up.
  21.304 -    # down-up: down requested, still up. Watch front and back, when both
  21.305 -    # down go to down-down. But what if one (or both) is not connected?
  21.306 -    # Still have front/back trees with status? Watch front/status, back/status?
  21.307 -    # up-down: up requested, still down.
  21.308 -    # Back-end watches ./status, front/status
  21.309 -    # Front-end watches ./status, back/status
  21.310 -    # i.e. each watches the other 2.
  21.311 -    # Each is status/request status/actual?
  21.312 -    #
  21.313 -    # backend?
  21.314 -    # frontend?
  21.315 -
  21.316 -    __exports__ = [
  21.317 -        DBVar('id',        ty='int'),
  21.318 -        DBVar('type',      ty='str'),
  21.319 -        DBVar('config',    ty='sxpr'),
  21.320 -        DBVar('destroyed', ty='bool'),
  21.321 -        ]
  21.322 -
  21.323 -    def __init__(self, controller, id, config, recreate=False):
  21.324 -        self.controller = controller
  21.325 -        self.id = id
  21.326 -        self.config = config
  21.327 -        self.destroyed = False
  21.328 -        self.type = self.getType()
  21.329 -
  21.330 -        self.db = controller.getDevDB(id)
  21.331 -
  21.332 -    def exportToDB(self, save=False):
  21.333 -        self.db.exportToDB(self, fields=self.__exports__, save=save)
  21.334 -
  21.335 -    def importFromDB(self):
  21.336 -        self.db.importFromDB(self, fields=self.__exports__)
  21.337 -
  21.338 -    def getDomain(self):
  21.339 -        return self.controller.getDomain()
  21.340 -
  21.341 -    def getDomainName(self):
  21.342 -        return self.controller.getDomainName()
  21.343 -
  21.344 -    def getDomainInfo(self):
  21.345 -        return self.controller.getDomainInfo()
  21.346 -    
  21.347 -    def getController(self):
  21.348 -        return self.controller
  21.349 -
  21.350 -    def getType(self):
  21.351 -        return self.controller.getType()
  21.352 -
  21.353 -    def getId(self):
  21.354 -        return self.id
  21.355 -
  21.356 -    def getConfig(self):
  21.357 -        return self.config
  21.358 -
  21.359 -    def isDestroyed(self):
  21.360 -        return self.destroyed
  21.361 -
  21.362 -    #----------------------------------------------------------------------------
  21.363 -    # Subclass interface.
  21.364 -    # Define methods in subclass as needed.
  21.365 -    # Redefinitions must have the same arguments.
  21.366 -
  21.367 -    def init(self, recreate=False, reboot=False):
  21.368 -        """Initialization. Called on initial create (when reboot is False)
  21.369 -        and on reboot (when reboot is True). When xend is restarting is
  21.370 -        called with recreate True. Define in subclass if needed.
  21.371 -
  21.372 -        Device instance variables must be defined in the class constructor,
  21.373 -        but given null or default values. The real values should be initialised
  21.374 -        in this method. This allows devices to be re-initialised.
  21.375 -
  21.376 -        Since this can be called to re-initialise a device any state flags
  21.377 -        should be reset.
  21.378 -        """
  21.379 -        self.destroyed = False
  21.380 -
  21.381 -    def attach(self, recreate=False, change=False):
  21.382 -        """Attach the device to its front and back ends.
  21.383 -        Define in subclass if needed.
  21.384 -        """
  21.385 -        pass
  21.386 -
  21.387 -    def reboot(self):
  21.388 -        """Reconnect the device when the domain is rebooted.
  21.389 -        """
  21.390 -        self.init(reboot=True)
  21.391 -        self.attach()
  21.392 -
  21.393 -    def sxpr(self):
  21.394 -        """Get the s-expression for the deivice.
  21.395 -        Implement in a subclass if needed.
  21.396 -
  21.397 -        @return: sxpr
  21.398 -        """
  21.399 -        return self.getConfig()
  21.400 -
  21.401 -    def configure(self, config, change=False):
  21.402 -        """Reconfigure the device.
  21.403 -
  21.404 -        Implement in subclass.
  21.405 -        """
  21.406 -        raise NotImplementedError()
  21.407 -
  21.408 -    def refresh(self):
  21.409 -        """Refresh the device..
  21.410 -        Default no-op. Define in subclass if needed.
  21.411 -        """
  21.412 -        pass
  21.413 -
  21.414 -    def destroy(self, change=False, reboot=False):
  21.415 -        """Destroy the device.
  21.416 -        If change is True notify destruction (runtime change).
  21.417 -        If reboot is True the device is being destroyed for a reboot.
  21.418 -        Redefine in subclass if needed.
  21.419 -
  21.420 -        Called at domain shutdown and when a device is deleted from
  21.421 -        a running domain (with change True).
  21.422 -        """
  21.423 -        self.destroyed = True
  21.424 -        pass
  21.425 -    
  21.426 -    #----------------------------------------------------------------------------
    22.1 --- a/tools/python/xen/xend/server/netif.py	Mon Sep 19 09:14:41 2005 +0000
    22.2 +++ b/tools/python/xen/xend/server/netif.py	Mon Sep 19 10:51:05 2005 +0000
    22.3 @@ -13,396 +13,64 @@
    22.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    22.5  #============================================================================
    22.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
    22.7 +# Copyright (C) 2005 XenSource Ltd
    22.8  #============================================================================
    22.9  
   22.10 +
   22.11  """Support for virtual network interfaces.
   22.12  """
   22.13  
   22.14 -import random
   22.15 -
   22.16 -from xen.util.mac import macFromString, macToString
   22.17 +import os
   22.18  
   22.19  from xen.xend import sxp
   22.20 -from xen.xend import Vifctl
   22.21 -from xen.xend.XendError import XendError, VmError
   22.22 -from xen.xend.XendLogging import log
   22.23 -from xen.xend import XendVnet
   22.24 -from xen.xend.XendRoot import get_component
   22.25 -from xen.xend.xenstore import DBVar
   22.26 -
   22.27 -from xen.xend.server.controller import Dev, DevController
   22.28 -
   22.29 -class NetDev(Dev):
   22.30 -    """A network device.
   22.31 -    """
   22.32 -
   22.33 -    # State:
   22.34 -    # inherited + 
   22.35 -    # ./config
   22.36 -    # ./mac
   22.37 -    # ./be_mac
   22.38 -    # ./bridge
   22.39 -    # ./script
   22.40 -    # ./ipaddr ?
   22.41 -    #
   22.42 -    # ./credit
   22.43 -    # ./period
   22.44 -    #
   22.45 -    # ./vifctl: up/down?
   22.46 -    # ./vifname
   22.47 -    #
   22.48 -    #
   22.49 -    # Poss should have no backend state here - except for ref to backend's own tree
   22.50 -    # for the device? And a status - the one we want.
   22.51 -    # ./back/dom
   22.52 -    # ./back/devid - id for back-end (netif_handle) - same as front/devid
   22.53 -    # ./back/id    - backend id (if more than one b/e per domain)
   22.54 -    # ./back/status
   22.55 -    # ./back/tx_shmem_frame  - actually these belong in back-end state
   22.56 -    # ./back/rx_shmem_frame
   22.57 -    #
   22.58 -    # ./front/dom
   22.59 -    # ./front/devid
   22.60 -    # ./front/status - need 2: one for requested, one for actual? Or drive from dev status
   22.61 -    # and this is front status only.
   22.62 -    # ./front/tx_shmem_frame
   22.63 -    # ./front/rx_shmem_frame
   22.64 -    #
   22.65 -    # ./evtchn/front - here or in front/back?
   22.66 -    # ./evtchn/back
   22.67 -    # ./evtchn/status ?
   22.68 -    # At present created by dev: but should be created unbound by front/back
   22.69 -    # separately and then bound (by back)?
   22.70 -
   22.71 -    __exports__ = Dev.__exports__ + [
   22.72 -        DBVar('config',  ty='sxpr'),
   22.73 -        DBVar('mac',     ty='mac'),
   22.74 -        DBVar('be_mac',  ty='mac'),
   22.75 -        DBVar('bridge',  ty='str'),
   22.76 -        DBVar('script',  ty='str'),
   22.77 -        DBVar('credit',  ty='int'),
   22.78 -        DBVar('period',  ty='int'),
   22.79 -        DBVar('vifname', ty='str'),
   22.80 -        ]
   22.81 -
   22.82 -    def __init__(self, controller, id, config, recreate=False):
   22.83 -        Dev.__init__(self, controller, id, config, recreate=recreate)
   22.84 -        self.vif = int(self.id)
   22.85 -        self.status = None
   22.86 -        self.frontendDomain = self.getDomain()
   22.87 -        self.backendDomain = None
   22.88 -        self.credit = None
   22.89 -        self.period = None
   22.90 -        self.mac = None
   22.91 -        self.be_mac = None
   22.92 -        self.bridge = None
   22.93 -        self.script = None
   22.94 -        self.ipaddr = None
   22.95 -        self.mtu = None
   22.96 -        self.vifname = None
   22.97 -        self.configure(self.config, recreate=recreate)
   22.98 -
   22.99 -    def exportToDB(self, save=False):
  22.100 -        Dev.exportToDB(self, save=save)
  22.101  
  22.102 -    def init(self, recreate=False, reboot=False):
  22.103 -        self.destroyed = False
  22.104 -        self.status = NETIF_INTERFACE_STATUS_DISCONNECTED
  22.105 -        self.frontendDomain = self.getDomain()
  22.106 -
  22.107 -    def _get_config_mac(self, config):
  22.108 -        vmac = sxp.child_value(config, 'mac')
  22.109 -        if not vmac: return None
  22.110 -        try:
  22.111 -            mac = macFromString(vmac)
  22.112 -        except:
  22.113 -            raise XendError("invalid mac: %s" % vmac)
  22.114 -        return mac
  22.115 -
  22.116 -    def _get_config_be_mac(self, config):
  22.117 -        vmac = sxp.child_value(config, 'be_mac')
  22.118 -        if not vmac: return None
  22.119 -        try:
  22.120 -            mac = macFromString(vmac)
  22.121 -        except:
  22.122 -            raise XendError("invalid backend mac: %s" % vmac)
  22.123 -        return mac
  22.124 -
  22.125 -    def _get_config_ipaddr(self, config):
  22.126 -        ips = sxp.children(config, elt='ip')
  22.127 -        if ips:
  22.128 -            val = []
  22.129 -            for ipaddr in ips:
  22.130 -                val.append(sxp.child0(ipaddr))
  22.131 -        else:
  22.132 -            val = None
  22.133 -        return val
  22.134 -
  22.135 -    def _get_config_mtu(self, config):
  22.136 -        mtu = sxp.child_value(config, 'mtu')
  22.137 -        if not mtu: return None
  22.138 -        try:
  22.139 -            mtu = int(mtu)
  22.140 -        except:
  22.141 -            raise XendError("invalid mtu: %s" & mtu)
  22.142 -        return mtu
  22.143 +from xen.xend.server.DevController import DevController
  22.144  
  22.145 -    def configure(self, config, change=False, recreate=False):
  22.146 -        if change:
  22.147 -            return self.reconfigure(config)
  22.148 -        self.config = config
  22.149 -        self.mac = None
  22.150 -        self.be_mac = None
  22.151 -        self.bridge = None
  22.152 -        self.script = None
  22.153 -        self.ipaddr = []
  22.154 -        self.vifname = None
  22.155 -
  22.156 -        self.vifname = sxp.child_value(config, 'vifname')
  22.157 -        if self.vifname is None:
  22.158 -            self.vifname = self.default_vifname()
  22.159 -        if len(self.vifname) > 15:
  22.160 -            raise XendError('invalid vifname: too long: ' + self.vifname)
  22.161 -        mac = self._get_config_mac(config)
  22.162 -        if mac is None:
  22.163 -            raise XendError("invalid mac")
  22.164 -        self.mac = mac
  22.165 -        self.be_mac = self._get_config_be_mac(config)
  22.166 -        self.bridge = sxp.child_value(config, 'bridge')
  22.167 -        self.script = sxp.child_value(config, 'script')
  22.168 -        self.ipaddr = self._get_config_ipaddr(config) or []
  22.169 -        self.mtu = self._get_config_mtu(config)
  22.170 -        self._config_credit_limit(config)
  22.171 -        
  22.172 -        try:
  22.173 -            if recreate:
  22.174 -                self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
  22.175 -            else:
  22.176 -                #todo: Code below will fail on xend restart when backend is not domain 0.
  22.177 -                xd = get_component('xen.xend.XendDomain')
  22.178 -                self.backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).domid
  22.179 -        except:
  22.180 -            raise XendError('invalid backend domain')
  22.181 -        return self.config
  22.182 -
  22.183 -    def reconfigure(self, config):
  22.184 -        """Reconfigure the interface with new values.
  22.185 -        Not all configuration parameters can be changed:
  22.186 -        bridge, script and ip addresses can,
  22.187 -        backend and mac cannot.
  22.188 -
  22.189 -        To leave a parameter unchanged, omit it from the changes.
  22.190  
  22.191 -        @param config configuration changes
  22.192 -        @return updated interface configuration
  22.193 -        @raise XendError on errors
  22.194 -        """
  22.195 -        changes = {}
  22.196 -        mac = self._get_config_mac(config)
  22.197 -        be_mac = self._get_config_be_mac(config)
  22.198 -        bridge = sxp.child_value(config, 'bridge')
  22.199 -        script = sxp.child_value(config, 'script')
  22.200 -        ipaddr = self._get_config_ipaddr(config)
  22.201 -        mtu = self._get_config_mtu(config)
  22.202 -        
  22.203 -        xd = get_component('xen.xend.XendDomain')
  22.204 -        backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).domid
  22.205 -
  22.206 -        if (mac is not None) and (mac != self.mac):
  22.207 -            raise XendError("cannot change mac")
  22.208 -        if (be_mac is not None) and (be_mac != self.be_mac):
  22.209 -            raise XendError("cannot change backend mac")
  22.210 -        if (backendDomain is not None) and (backendDomain != self.backendDomain):
  22.211 -            raise XendError("cannot change backend")
  22.212 -        if (bridge is not None) and (bridge != self.bridge):
  22.213 -            changes['bridge'] = bridge
  22.214 -        if (script is not None) and (script != self.script):
  22.215 -            changes['script'] = script
  22.216 -        if (ipaddr is not None) and (ipaddr != self.ipaddr):
  22.217 -            changes['ipaddr'] = ipaddr
  22.218 -        if (mtu is not None) and (mtu != self.mtu):
  22.219 -            changes['mtu'] = mtu
  22.220 -
  22.221 -        if changes:
  22.222 -            self.vifctl("down")
  22.223 -            for (k, v) in changes.items():
  22.224 -                setattr(self, k, v)
  22.225 -            self.config = sxp.merge(config, self.config)
  22.226 -            self.vifctl("up")
  22.227 -
  22.228 -        self._config_credit_limit(config, change=True)
  22.229 -        return self.config
  22.230 -
  22.231 -    def _config_credit_limit(self, config, change=False):
  22.232 -        period = sxp.child_value(config, 'period')
  22.233 -        credit = sxp.child_value(config, 'credit')
  22.234 -        if period and credit:
  22.235 -            try:
  22.236 -                period = int(period)
  22.237 -                credit = int(credit)
  22.238 -            except ex:
  22.239 -                raise XendError('vif: invalid credit limit')
  22.240 -            if change:
  22.241 -                self.setCreditLimit(credit, period)
  22.242 -                self.config = sxp.merge([sxp.name(self.config),
  22.243 -                                         ['credit', credit],
  22.244 -                                         ['period', period]],
  22.245 -                                        self.config)
  22.246 -            else:
  22.247 -                self.period = period
  22.248 -                self.credit = credit
  22.249 -        elif period or credit:
  22.250 -            raise XendError('vif: invalid credit limit')
  22.251 -
  22.252 -    def sxpr(self):
  22.253 -        vif = str(self.vif)
  22.254 -        mac = self.get_mac()
  22.255 -        val = ['vif',
  22.256 -               ['id', self.id],
  22.257 -               ['vif', vif],
  22.258 -               ['mac', mac],
  22.259 -               ['vifname', self.vifname],
  22.260 -               ]
  22.261 -
  22.262 -        if self.be_mac:
  22.263 -            val.append(['be_mac', self.get_be_mac()])
  22.264 -        if self.bridge:
  22.265 -            val.append(['bridge', self.bridge])
  22.266 -        if self.script:
  22.267 -            val.append(['script', self.script])
  22.268 -        for ip in self.ipaddr:
  22.269 -            val.append(['ip', ip])
  22.270 -        if self.credit:
  22.271 -            val.append(['credit', self.credit])
  22.272 -        if self.period:
  22.273 -            val.append(['period', self.period])
  22.274 -        return val
  22.275 +next_devid = 1
  22.276  
  22.277 -    def get_vifname(self):
  22.278 -        """Get the virtual interface device name.
  22.279 -        """
  22.280 -        return self.vifname
  22.281  
  22.282 -    def default_vifname(self):
  22.283 -        return "vif%d.%d" % (self.frontendDomain, self.vif)
  22.284 -    
  22.285 -    def get_mac(self):
  22.286 -        """Get the MAC address as a string.
  22.287 -        """
  22.288 -        return macToString(self.mac)
  22.289 -
  22.290 -    def get_be_mac(self):
  22.291 -        """Get the backend MAC address as a string.
  22.292 -        """
  22.293 -        return macToString(self.be_mac)
  22.294 -
  22.295 -    def vifctl_params(self, vmname=None):
  22.296 -        """Get the parameters to pass to vifctl.
  22.297 -        """
  22.298 -        dom = self.frontendDomain
  22.299 -        if vmname is None:
  22.300 -            xd = get_component('xen.xend.XendDomain')
  22.301 -            try:
  22.302 -                vm = xd.domain_lookup(dom)
  22.303 -                vmname = vm.name
  22.304 -            except:
  22.305 -                vmname = 'Domain-%d' % dom
  22.306 -        return { 'domain': vmname,
  22.307 -                 'vif'   : self.get_vifname(), 
  22.308 -                 'mac'   : self.get_mac(),
  22.309 -                 'bridge': self.bridge,
  22.310 -                 'script': self.script,
  22.311 -                 'ipaddr': self.ipaddr, }
  22.312 -
  22.313 -    def vifctl(self, op, vmname=None):
  22.314 -        """Bring the device up or down.
  22.315 -        The vmname is needed when bringing a device up for a new domain because
  22.316 -        the domain is not yet in the table so we can't look its name up.
  22.317 -
  22.318 -        @param op: operation name (up, down)
  22.319 -        @param vmname: vmname
  22.320 -        """
  22.321 -        if op == 'up':
  22.322 -            Vifctl.set_vif_name(self.default_vifname(), self.vifname)
  22.323 -        Vifctl.vifctl(op, **self.vifctl_params(vmname=vmname))
  22.324 -        vnet = XendVnet.instance().vnet_of_bridge(self.bridge)
  22.325 -        if vnet:
  22.326 -            vnet.vifctl(op, self.get_vifname(), self.get_mac())
  22.327 -
  22.328 -    def attach(self, recreate=False, change=False):
  22.329 -        if recreate:
  22.330 -            pass
  22.331 -        else:
  22.332 -            if self.credit and self.period:
  22.333 -                #self.send_be_creditlimit(self.credit, self.period)
  22.334 -                pass
  22.335 -            self.vifctl('up', vmname=self.getDomainName())
  22.336 -        
  22.337 -    def destroy(self, change=False, reboot=False):
  22.338 -        """Destroy the device's resources and disconnect from the back-end
  22.339 -        device controller. If 'change' is true notify the front-end interface.
  22.340 -
  22.341 -        @param change: change flag
  22.342 -        """
  22.343 -        self.destroyed = True
  22.344 -        self.status = NETIF_INTERFACE_STATUS_CLOSED
  22.345 -        log.debug("Destroying vif domain=%d vif=%d", self.frontendDomain, self.vif)
  22.346 -        self.vifctl('down')
  22.347 -        if change:
  22.348 -            self.reportStatus()
  22.349 -
  22.350 -    def setCreditLimit(self, credit, period):
  22.351 -        #todo: these params should be in sxpr and vif config.
  22.352 -        self.credit = credit
  22.353 -        self.period = period
  22.354 -
  22.355 -    def getCredit(self):
  22.356 -        return self.credit
  22.357 -
  22.358 -    def getPeriod(self):
  22.359 -        return self.period
  22.360 -        
  22.361 -    def interfaceChanged(self):
  22.362 -        """Notify the front-end that a device has been added or removed.
  22.363 -        """
  22.364 -        pass
  22.365 -        
  22.366  class NetifController(DevController):
  22.367      """Network interface controller. Handles all network devices for a domain.
  22.368      """
  22.369      
  22.370 -    def __init__(self, vm, recreate=False):
  22.371 -        DevController.__init__(self, vm, recreate=recreate)
  22.372 +    def __init__(self, vm):
  22.373 +        DevController.__init__(self, vm)
  22.374 +
  22.375 +
  22.376 +    def getDeviceDetails(self, config):
  22.377 +        """@see DevController.getDeviceDetails"""
  22.378 +
  22.379 +        global next_devid
  22.380  
  22.381 -    def initController(self, recreate=False, reboot=False):
  22.382 -        self.destroyed = False
  22.383 -        if reboot:
  22.384 -            self.rebootDevices()
  22.385 +        from xen.xend import XendRoot
  22.386 +        xroot = XendRoot.instance()
  22.387  
  22.388 -    def destroyController(self, reboot=False):
  22.389 -        """Destroy the controller and all devices.
  22.390 -        """
  22.391 -        self.destroyed = True
  22.392 -        log.debug("Destroying netif domain=%d", self.getDomain())
  22.393 -        self.destroyDevices(reboot=reboot)
  22.394 +        def _get_config_ipaddr(config):
  22.395 +            val = []
  22.396 +            for ipaddr in sxp.children(config, elt='ip'):
  22.397 +                val.append(sxp.child0(ipaddr))
  22.398 +            return val
  22.399  
  22.400 -    def sxpr(self):
  22.401 -        val = ['netif', ['dom', self.getDomain()]]
  22.402 -        return val
  22.403 -    
  22.404 -    def newDevice(self, id, config, recreate=False):
  22.405 -        """Create a network device.
  22.406 +        devid = next_devid
  22.407 +        next_devid += 1
  22.408 +
  22.409 +        script = os.path.join(xroot.network_script_dir,
  22.410 +                              sxp.child_value(config, 'script',
  22.411 +                                              xroot.get_vif_script()))
  22.412 +        bridge = sxp.child_value(config, 'bridge',
  22.413 +                                 xroot.get_vif_bridge())
  22.414 +        mac = sxp.child_value(config, 'mac')
  22.415 +        ipaddr = _get_config_ipaddr(config)
  22.416  
  22.417 -        @param id: interface id
  22.418 -        @param config: device configuration
  22.419 -        @param recreate: recreate flag (true after xend restart)
  22.420 -        """
  22.421 -        return NetDev(self, id, config, recreate=recreate)
  22.422 +        back = { 'script' : script,
  22.423 +                 'mac' : mac,
  22.424 +                 'bridge' : bridge,
  22.425 +                 'handle' : "%i" % devid }
  22.426 +        if ipaddr:
  22.427 +            back['ip'] = ' '.join(ipaddr)
  22.428  
  22.429 -    def limitDevice(self, vif, credit, period):        
  22.430 -        if vif not in self.devices:
  22.431 -            raise XendError('device does not exist for credit limit: vif'
  22.432 -                            + str(self.getDomain()) + '.' + str(vif))
  22.433 -        
  22.434 -        dev = self.devices[vif]
  22.435 -        return dev.setCreditLimit(credit, period)
  22.436 +        front = { 'handle' : "%i" % devid,
  22.437 +                  'mac' : mac }
  22.438 +
  22.439 +        return (devid, back, front)
    23.1 --- a/tools/python/xen/xend/server/pciif.py	Mon Sep 19 09:14:41 2005 +0000
    23.2 +++ b/tools/python/xen/xend/server/pciif.py	Mon Sep 19 10:51:05 2005 +0000
    23.3 @@ -13,16 +13,22 @@
    23.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23.5  #============================================================================
    23.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
    23.7 +# Copyright (C) 2005 XenSource Ltd
    23.8  #============================================================================
    23.9  
   23.10 +
   23.11  import types
   23.12  
   23.13 -import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
   23.14 +import xen.lowlevel.xc;
   23.15  
   23.16  from xen.xend import sxp
   23.17  from xen.xend.XendError import VmError
   23.18  
   23.19 -from controller import Dev, DevController
   23.20 +from xen.xend.server.DevController import DevController
   23.21 +
   23.22 +
   23.23 +xc = xen.lowlevel.xc.new()
   23.24 +
   23.25  
   23.26  def parse_pci(val):
   23.27      """Parse a pci field.
   23.28 @@ -36,27 +42,32 @@ def parse_pci(val):
   23.29          v = val
   23.30      return v
   23.31  
   23.32 -class PciDev(Dev):
   23.33 +
   23.34 +class PciController(DevController):
   23.35 +
   23.36 +    def __init__(self, vm):
   23.37 +        DevController.__init__(self, vm)
   23.38 +
   23.39 +
   23.40 +    def getDeviceDetails(self, config):
   23.41 +        """@see DevController.getDeviceDetails"""
   23.42  
   23.43 -    def __init__(self, controller, id, config, recreate=False):
   23.44 -        Dev.__init__(self, controller, id, config, recreate=recreate)
   23.45 -        bus = sxp.child_value(self.config, 'bus')
   23.46 -        if not bus:
   23.47 -            raise VmError('pci: Missing bus')
   23.48 -        dev = sxp.child_value(self.config, 'dev')
   23.49 -        if not dev:
   23.50 -            raise VmError('pci: Missing dev')
   23.51 -        func = sxp.child_value(self.config, 'func')
   23.52 -        if not func:
   23.53 -            raise VmError('pci: Missing func')
   23.54 -        try:
   23.55 -            bus = parse_pci(bus)
   23.56 -            dev = parse_pci(dev)
   23.57 -            func = parse_pci(func)
   23.58 -        except:
   23.59 -            raise VmError('pci: invalid parameter')
   23.60 +        def get_param(field):
   23.61 +            try:
   23.62 +                val = sxp.child_value(config, field)
   23.63 +
   23.64 +                if not val:
   23.65 +                    raise VmError('pci: Missing %s config setting' % field)
   23.66  
   23.67 -    def attach(self, recreate=False, change=False):
   23.68 +                return parse_pci(val)
   23.69 +            except:
   23.70 +                raise VmError('pci: Invalid config setting %s: %s' %
   23.71 +                              (field, val))
   23.72 +        
   23.73 +        bus  = get_param('bus')
   23.74 +        dev  = get_param('dev')
   23.75 +        func = get_param('func')
   23.76 +
   23.77          rc = xc.physdev_pci_access_modify(dom    = self.getDomain(),
   23.78                                            bus    = bus,
   23.79                                            dev    = dev,
   23.80 @@ -64,13 +75,8 @@ class PciDev(Dev):
   23.81                                            enable = True)
   23.82          if rc < 0:
   23.83              #todo non-fatal
   23.84 -            raise VmError('pci: Failed to configure device: bus=%s dev=%s func=%s' %
   23.85 -                          (bus, dev, func))
   23.86 +            raise VmError(
   23.87 +                'pci: Failed to configure device: bus=%s dev=%s func=%s' %
   23.88 +                (bus, dev, func))
   23.89  
   23.90 -    def destroy(self, change=False, reboot=False):
   23.91 -        pass
   23.92 -
   23.93 -class PciController(DevController):
   23.94 -
   23.95 -    def newDevice(self, id, config, recreate=False):
   23.96 -        return PciDev(self, id, config, recreate=recreate)
   23.97 +        return (dev, {}, {})
    24.1 --- a/tools/python/xen/xend/server/tpmif.py	Mon Sep 19 09:14:41 2005 +0000
    24.2 +++ b/tools/python/xen/xend/server/tpmif.py	Mon Sep 19 10:51:05 2005 +0000
    24.3 @@ -1,45 +1,47 @@
    24.4 +#============================================================================
    24.5 +# This library is free software; you can redistribute it and/or
    24.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    24.7 +# License as published by the Free Software Foundation.
    24.8 +#
    24.9 +# This library is distributed in the hope that it will be useful,
   24.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   24.12 +# Lesser General Public License for more details.
   24.13 +#
   24.14 +# You should have received a copy of the GNU Lesser General Public
   24.15 +# License along with this library; if not, write to the Free Software
   24.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24.17 +#============================================================================
   24.18 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
   24.19  # Copyright (C) 2005 IBM Corporation
   24.20 -#   Authort: Stefan Berger, stefanb@us.ibm.com
   24.21 -# Derived from netif.py:
   24.22 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
   24.23 +#   Author: Stefan Berger, stefanb@us.ibm.com
   24.24 +# Copyright (C) 2005 XenSource Ltd
   24.25 +#============================================================================
   24.26 +
   24.27  """Support for virtual TPM interfaces.
   24.28  """
   24.29  
   24.30 -import random
   24.31 -
   24.32  from xen.xend import sxp
   24.33 -from xen.xend.XendError import XendError, VmError
   24.34  from xen.xend.XendLogging import log
   24.35 -from xen.xend.XendRoot import get_component
   24.36 -from xen.xend.xenstore import DBVar
   24.37  
   24.38 -from xen.xend.server.controller import Dev, DevController
   24.39 +from xen.xend.server.DevController import DevController
   24.40 +
   24.41  
   24.42  class TPMifController(DevController):
   24.43      """TPM interface controller. Handles all TPM devices for a domain.
   24.44      """
   24.45  
   24.46 -    def __init__(self, vm, recreate=False):
   24.47 -        DevController.__init__(self, vm, recreate=recreate)
   24.48 -
   24.49 -    def initController(self, recreate=False, reboot=False):
   24.50 -        self.destroyed = False
   24.51 +    def __init__(self, vm):
   24.52 +        DevController.__init__(self, vm)
   24.53  
   24.54 -    def destroyController(self, reboot=False):
   24.55 -        """Destroy the controller and all devices.
   24.56 -        """
   24.57 -        self.destroyed = True
   24.58 -        self.destroyDevices(reboot=reboot)
   24.59  
   24.60 -    def sxpr(self):
   24.61 -        val = ['tpmif', ['dom', self.getDomain()]]
   24.62 -        return val
   24.63 +    def getDeviceDetails(self, config):
   24.64 +        """@see DevController.getDeviceDetails"""
   24.65 +        
   24.66 +        devid = int(sxp.child_value(config, 'instance', '0'))
   24.67 +        log.error("The domain has a TPM with instance %d." % devid)
   24.68  
   24.69 -    def newDevice(self, id, config, recreate=False):
   24.70 -        """Create a TPM device.
   24.71 +        back  = { 'instance' : "%i" % devid }
   24.72 +        front = { 'handle' : "%i" % devid }
   24.73  
   24.74 -        @param id: interface id
   24.75 -        @param config: device configuration
   24.76 -        @param recreate: recreate flag (true after xend restart)
   24.77 -        """
   24.78 -        return None
   24.79 +        return (devid, back, front)
    25.1 --- a/tools/python/xen/xend/server/usbif.py	Mon Sep 19 09:14:41 2005 +0000
    25.2 +++ b/tools/python/xen/xend/server/usbif.py	Mon Sep 19 10:51:05 2005 +0000
    25.3 @@ -1,185 +1,50 @@
    25.4 +#============================================================================
    25.5 +# This library is free software; you can redistribute it and/or
    25.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public
    25.7 +# License as published by the Free Software Foundation.
    25.8 +#
    25.9 +# This library is distributed in the hope that it will be useful,
   25.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   25.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   25.12 +# Lesser General Public License for more details.
   25.13 +#
   25.14 +# You should have received a copy of the GNU Lesser General Public
   25.15 +# License along with this library; if not, write to the Free Software
   25.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   25.17 +#============================================================================
   25.18  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
   25.19  # Copyright (C) 2004 Intel Research Cambridge
   25.20  # Copyright (C) 2004 Mark Williamson <mark.williamson@cl.cam.ac.uk>
   25.21 +# Copyright (C) 2005 XenSource Ltd
   25.22 +#============================================================================
   25.23 +
   25.24 +
   25.25  """Support for virtual USB hubs.
   25.26  """
   25.27  
   25.28 -from xen.xend import sxp
   25.29 -from xen.xend.XendLogging import log
   25.30 -from xen.xend.XendError import XendError
   25.31 -from xen.xend.xenstore import DBVar
   25.32 -
   25.33 -from xen.xend.server.controller import Dev, DevController
   25.34 -
   25.35 -class UsbBackend:
   25.36 -    """Handler for the 'back-end' channel to a USB device driver domain
   25.37 -    on behalf of a front-end domain.
   25.38 -    """
   25.39 -    def __init__(self, controller, id, dom):
   25.40 -        self.controller = controller
   25.41 -        self.id = id
   25.42 -        self.destroyed = False
   25.43 -        self.connected = False
   25.44 -        self.connecting = False
   25.45 -        self.frontendDomain = self.controller.getDomain()
   25.46 -        self.backendDomain = dom
   25.47 -
   25.48 -    def init(self, recreate=False, reboot=False):
   25.49 -        pass
   25.50 -    
   25.51 -    def __str__(self):
   25.52 -        return ('<UsbifBackend frontend=%d backend=%d id=%d>'
   25.53 -                % (self.frontendDomain,
   25.54 -                   self.backendDomain,
   25.55 -                   self.id))
   25.56 -
   25.57 -    def connect(self, recreate=False):
   25.58 -        """Connect the controller to the usbif control interface.
   25.59 -
   25.60 -        @param recreate: true if after xend restart
   25.61 -        """
   25.62 -        log.debug("Connecting usbif %s", str(self))
   25.63 -        if recreate or self.connected or self.connecting:
   25.64 -            pass
   25.65 -        
   25.66 -    def destroy(self, reboot=False):
   25.67 -        """Disconnect from the usbif control interface and destroy it.
   25.68 -        """
   25.69 -        self.destroyed = True
   25.70 -        
   25.71 -    def interfaceChanged(self):
   25.72 -        pass
   25.73 +from xen.xend.server.DevController import DevController
   25.74  
   25.75  
   25.76 -class UsbDev(Dev):
   25.77 -
   25.78 -    __exports__ = Dev.__exports__ + [
   25.79 -        DBVar('port', ty='int'),
   25.80 -        DBVar('path', ty='str'),
   25.81 -        ]
   25.82 -    
   25.83 -    def __init__(self, controller, id, config, recreate=False):
   25.84 -        Dev.__init__(self, controller, id, config, recreate=recreate)
   25.85 -        self.port = id
   25.86 -        self.path = None
   25.87 -        self.frontendDomain = self.getDomain()
   25.88 -        self.backendDomain = 0
   25.89 -        self.configure(self.config, recreate=recreate)
   25.90 -
   25.91 -    def init(self, recreate=False, reboot=False):
   25.92 -        self.destroyed = False
   25.93 -        self.frontendDomain = self.getDomain()
   25.94 -        
   25.95 -    def configure(self, config, change=False, recreate=False):
   25.96 -        if change:
   25.97 -            raise XendError("cannot reconfigure usb")
   25.98 -        #todo: FIXME: Use sxp access methods to get this value.
   25.99 -        # Must not use direct indexing.
  25.100 -        self.path = config[1][1]
  25.101 -        
  25.102 -        #todo: FIXME: Support configuring the backend domain.
  25.103 -##         try:
  25.104 -##             self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
  25.105 -##         except:
  25.106 -##             raise XendError('invalid backend domain')
  25.107 +next_devid = 1
  25.108  
  25.109 -    def attach(self, recreate=False, change=False):
  25.110 -        if recreate:
  25.111 -            pass
  25.112 -        else:
  25.113 -            self.attachBackend()
  25.114 -        if change:
  25.115 -            self.interfaceChanged()
  25.116 -            
  25.117 -    def sxpr(self):
  25.118 -        val = ['usb',
  25.119 -               ['id', self.id],
  25.120 -               ['port', self.port],
  25.121 -               ['path', self.path],
  25.122 -               ]
  25.123 -        return val
  25.124 -
  25.125 -    def getBackend(self):
  25.126 -        return self.controller.getBackend(self.backendDomain)
  25.127 -
  25.128 -    def destroy(self, change=False, reboot=False):
  25.129 -        """Destroy the device. If 'change' is true notify the front-end interface.
  25.130 -
  25.131 -        @param change: change flag
  25.132 -        """
  25.133 -        self.destroyed = True
  25.134 -        log.debug("Destroying usb domain=%d id=%s", self.frontendDomain, self.id)
  25.135 -        if change:
  25.136 -            self.interfaceChanged()
  25.137 -
  25.138 -    def interfaceChanged(self):
  25.139 -        """Tell the back-end to notify the front-end that a device has been
  25.140 -        added or removed.
  25.141 -        """
  25.142 -        self.getBackend().interfaceChanged()
  25.143 -
  25.144 -    def attachBackend(self):
  25.145 -        """Attach the device to its controller.
  25.146 -
  25.147 -        """
  25.148 -        self.getBackend().connect()
  25.149  
  25.150  class UsbifController(DevController):
  25.151      """USB device interface controller. Handles all USB devices
  25.152      for a domain.
  25.153      """
  25.154      
  25.155 -    def __init__(self, vm, recreate=False):
  25.156 +    def __init__(self, vm):
  25.157          """Create a USB device controller.
  25.158          """
  25.159 -        DevController.__init__(self, vm, recreate=recreate)
  25.160 -        self.backends = {}
  25.161 -        self.backendId = 0
  25.162 +        DevController.__init__(self, vm)
  25.163  
  25.164 -    def init(self, recreate=False, reboot=False):
  25.165 -        self.destroyed = False
  25.166 -        if reboot:
  25.167 -            self.rebootBackends()
  25.168 -            self.rebootDevices()
  25.169  
  25.170 -    def sxpr(self):
  25.171 -        val = ['usbif',
  25.172 -               ['dom', self.getDomain()]]
  25.173 -        return val
  25.174 -
  25.175 -    def newDevice(self, id, config, recreate=False):
  25.176 -        return UsbDev(self, id, config, recreate=recreate)
  25.177 -
  25.178 -    def destroyController(self, reboot=False):
  25.179 -        """Destroy the controller and all devices.
  25.180 -        """
  25.181 -        self.destroyed = True
  25.182 -        log.debug("Destroying blkif domain=%d", self.getDomain())
  25.183 -        self.destroyDevices(reboot=reboot)
  25.184 -        self.destroyBackends(reboot=reboot)
  25.185 +    def getDeviceDetails(self, _):
  25.186 +        """@see DevController.getDeviceDetails"""
  25.187  
  25.188 -    def rebootBackends(self):
  25.189 -        for backend in self.backends.values():
  25.190 -            backend.init(reboot=True)
  25.191 -
  25.192 -    def getBackendById(self, id):
  25.193 -        return self.backends.get(id)
  25.194 -
  25.195 -    def getBackendByDomain(self, dom):
  25.196 -        for backend in self.backends.values():
  25.197 -            if backend.backendDomain == dom:
  25.198 -                return backend
  25.199 -        return None
  25.200 +        global next_devid
  25.201  
  25.202 -    def getBackend(self, dom):
  25.203 -        backend = self.getBackendByDomain(dom)
  25.204 -        if backend: return backend
  25.205 -        backend = UsbBackend(self, self.backendId, dom)
  25.206 -        self.backendId += 1
  25.207 -        self.backends[backend.getId()] = backend
  25.208 -        backend.init()
  25.209 -        return backend
  25.210 -    
  25.211 -    def destroyBackends(self, reboot=False):
  25.212 -        for backend in self.backends.values():
  25.213 -            backend.destroy(reboot=reboot)
  25.214 +        devid = next_devid
  25.215 +        next_devid += 1
  25.216 +
  25.217 +        return (devid, {}, {})
    26.1 --- a/tools/python/xen/xend/xenstore/xsobj.py	Mon Sep 19 09:14:41 2005 +0000
    26.2 +++ b/tools/python/xen/xend/xenstore/xsobj.py	Mon Sep 19 10:51:05 2005 +0000
    26.3 @@ -469,9 +469,6 @@ class DBMap(dict):
    26.4              n = n._addChild(x)
    26.5          return n
    26.6  
    26.7 -    def getDB(self):
    26.8 -        return self.__db__
    26.9 -
   26.10      def setDB(self, db):
   26.11          if (db is not None) and not isinstance(db, XenNode):
   26.12              raise ValueError("invalid db")
    27.1 --- a/tools/python/xen/xend/xenstore/xstransact.py	Mon Sep 19 09:14:41 2005 +0000
    27.2 +++ b/tools/python/xen/xend/xenstore/xstransact.py	Mon Sep 19 10:51:05 2005 +0000
    27.3 @@ -67,7 +67,12 @@ class xstransact:
    27.4                  if not isinstance(d, dict):
    27.5                      raise TypeError
    27.6                  for key in d.keys():
    27.7 -                    self._write(key, d[key], create, excl)
    27.8 +                    try:
    27.9 +                        self._write(key, d[key], create, excl)
   27.10 +                    except TypeError, msg:
   27.11 +                        raise TypeError('Writing %s: %s: %s' %
   27.12 +                                        (key, str(d[key]), msg))
   27.13 +                        
   27.14          elif isinstance(args[0], list):
   27.15              for l in args:
   27.16                  if not len(l) == 2:
   27.17 @@ -84,10 +89,15 @@ class xstransact:
   27.18          return xshandle().rm(path)
   27.19  
   27.20      def remove(self, *args):
   27.21 +        """If no arguments are given, remove this transaction's path.
   27.22 +        Otherwise, treat each argument as a subpath to this transaction's
   27.23 +        path, and remove each of those instead.
   27.24 +        """
   27.25          if len(args) == 0:
   27.26 -            raise TypeError
   27.27 -        for key in args:
   27.28 -            self._remove(key)
   27.29 +            xshandle().rm(self.path)
   27.30 +        else:
   27.31 +            for key in args:
   27.32 +                self._remove(key)
   27.33  
   27.34      def _list(self, key):
   27.35          path = "%s/%s" % (self.path, key)
   27.36 @@ -146,8 +156,8 @@ class xstransact:
   27.37  
   27.38      def Read(cls, path, *args):
   27.39          while True:
   27.40 +            t = cls(path)
   27.41              try:
   27.42 -                t = cls(path)
   27.43                  v = t.read(*args)
   27.44                  t.commit()
   27.45                  return v
   27.46 @@ -165,8 +175,8 @@ class xstransact:
   27.47  
   27.48      def Write(cls, path, *args, **opts):
   27.49          while True:
   27.50 +            t = cls(path)
   27.51              try:
   27.52 -                t = cls(path)
   27.53                  t.write(*args, **opts)
   27.54                  t.commit()
   27.55                  return
   27.56 @@ -183,9 +193,13 @@ class xstransact:
   27.57      Write = classmethod(Write)
   27.58  
   27.59      def Remove(cls, path, *args):
   27.60 +        """If only one argument is given (path), remove it.  Otherwise, treat
   27.61 +        each further argument as a subpath to the given path, and remove each
   27.62 +        of those instead.  This operation is performed inside a transaction.
   27.63 +        """
   27.64          while True:
   27.65 +            t = cls(path)
   27.66              try:
   27.67 -                t = cls(path)
   27.68                  t.remove(*args)
   27.69                  t.commit()
   27.70                  return
   27.71 @@ -203,8 +217,8 @@ class xstransact:
   27.72  
   27.73      def List(cls, path, *args):
   27.74          while True:
   27.75 +            t = cls(path)
   27.76              try:
   27.77 -                t = cls(path)
   27.78                  v = t.list(*args)
   27.79                  t.commit()
   27.80                  return v
   27.81 @@ -222,8 +236,8 @@ class xstransact:
   27.82  
   27.83      def Gather(cls, path, *args):
   27.84          while True:
   27.85 +            t = cls(path)
   27.86              try:
   27.87 -                t = cls(path)
   27.88                  v = t.gather(*args)
   27.89                  t.commit()
   27.90                  return v
   27.91 @@ -241,8 +255,8 @@ class xstransact:
   27.92  
   27.93      def Store(cls, path, *args):
   27.94          while True:
   27.95 +            t = cls(path)
   27.96              try:
   27.97 -                t = cls(path)
   27.98                  v = t.store(*args)
   27.99                  t.commit()
  27.100                  return v
    28.1 --- a/tools/python/xen/xend/xenstore/xswatch.py	Mon Sep 19 09:14:41 2005 +0000
    28.2 +++ b/tools/python/xen/xend/xenstore/xswatch.py	Mon Sep 19 10:51:05 2005 +0000
    28.3 @@ -1,4 +1,5 @@
    28.4  # Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
    28.5 +# Copyright (C) 2005 XenSource Ltd
    28.6  
    28.7  # This file is subject to the terms and conditions of the GNU General
    28.8  # Public License.  See the file "COPYING" in the main directory of
    28.9 @@ -15,7 +16,7 @@ class xswatch:
   28.10      xs = None
   28.11      xslock = threading.Lock()
   28.12      
   28.13 -    def __init__(self, path, fn, args=(), kwargs={}):
   28.14 +    def __init__(self, path, fn, *args, **kwargs):
   28.15          self.fn = fn
   28.16          self.args = args
   28.17          self.kwargs = kwargs
   28.18 @@ -46,11 +47,11 @@ class xswatch:
   28.19          cls.threadcond.release()
   28.20          while True:
   28.21              try:
   28.22 -                (ord, owr, oer) = select.select([ cls.xs ], [], [])
   28.23 +                (fd, _1, _2) = select.select([ cls.xs ], [], [])
   28.24                  cls.xslock.acquire()
   28.25                  # reconfirm ready to read with lock
   28.26 -                (ord, owr, oer) = select.select([ cls.xs ], [], [], 0.001)
   28.27 -                if not cls.xs in ord:
   28.28 +                (fd, _1, _2) = select.select([ cls.xs ], [], [], 0.001)
   28.29 +                if not cls.xs in fd:
   28.30                      cls.xslock.release()
   28.31                      continue
   28.32                  we = cls.xs.read_watch()
    29.1 --- a/tools/python/xen/xm/create.py	Mon Sep 19 09:14:41 2005 +0000
    29.2 +++ b/tools/python/xen/xm/create.py	Mon Sep 19 10:51:05 2005 +0000
    29.3 @@ -141,7 +141,7 @@ gopts.var('memory', val='MEMORY',
    29.4            use="Domain memory in MB.")
    29.5  
    29.6  gopts.var('ssidref', val='SSIDREF',
    29.7 -          fn=set_u32, default=-1, 
    29.8 +          fn=set_u32, default=0, 
    29.9            use="Security Identifier.")
   29.10  
   29.11  gopts.var('maxmem', val='MEMORY',