debuggers.hg
changeset 6970:308260e5868c
merge?
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',