ia64/xen-unstable
changeset 1661:11fc1027833b
bitkeeper revision 1.1041.5.1 (40e51d24Wg4h3PKvj5VuOULXCYhqbg)
Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
author | xenbk@gandalf.hpl.hp.com |
---|---|
date | Fri Jul 02 08:30:28 2004 +0000 (2004-07-02) |
parents | d9a96380ff94 6edc06968b87 |
children | 52c04d5d2a8e |
files | .rootkeys tools/examples/xmdefaults tools/python/xen/xend/XendClient.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/console.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/cstruct.py tools/python/xen/xend/server/domain.py tools/python/xen/xend/server/messages.py tools/python/xen/xend/server/netif.py tools/python/xen/xm/create.py tools/python/xen/xm/help.py tools/python/xen/xm/main.py tools/python/xen/xm/opts.py |
line diff
1.1 --- a/.rootkeys Thu Jul 01 23:32:40 2004 +0000 1.2 +++ b/.rootkeys Fri Jul 02 08:30:28 2004 +0000 1.3 @@ -257,7 +257,6 @@ 40c9c4692hckPol_EK0EGB16ZyDsyQ tools/pyt 1.4 40c9c469N2-b3GqpLHHHPZykJPLVvA tools/python/xen/xend/server/channel.py 1.5 40c9c469hJ_IlatRne-9QEa0-wlquw tools/python/xen/xend/server/console.py 1.6 40c9c469UcNJh_NuLU0ytorM0Lk5Ow tools/python/xen/xend/server/controller.py 1.7 -40c9c469vHh-qLiiubdbKEQbJf18Zw tools/python/xen/xend/server/cstruct.py 1.8 40d83983OXjt-y3HjSCcuoPp9rzvmw tools/python/xen/xend/server/domain.py 1.9 40c9c469yrm31i60pGKslTi2Zgpotg tools/python/xen/xend/server/messages.py 1.10 40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/python/xen/xend/server/netif.py 1.11 @@ -265,6 +264,7 @@ 40c9c469ZqILEQ8x6yWy0_51jopiCg tools/pyt 1.12 40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py 1.13 40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py 1.14 40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py 1.15 +40e41cd2w0I4En6qrJn4em8HkK_oxQ tools/python/xen/xm/help.py 1.16 40cf2937isyS250zyd0Q2GuEDoNXfQ tools/python/xen/xm/main.py 1.17 40cf2937PSslwBliN1g7ofDy2H_RhA tools/python/xen/xm/opts.py 1.18 40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/python/xen/xm/shutdown.py
2.1 --- a/tools/examples/xmdefaults Thu Jul 01 23:32:40 2004 +0000 2.2 +++ b/tools/examples/xmdefaults Fri Jul 02 08:30:28 2004 +0000 2.3 @@ -2,17 +2,24 @@ 2.4 #============================================================================ 2.5 # Python defaults setup for 'xm create'. 2.6 # Edit this file to reflect the configuration of your system. 2.7 -# This file expects the variable 'vmid' to be set. 2.8 + 2.9 #============================================================================ 2.10 2.11 -try: 2.12 - vmid = int(vmid) # convert to integer 2.13 -except: 2.14 - raise ValueError, "Variable 'vmid' must be an integer" 2.15 +# Define script variables here. 2.16 +# xm_vars is defined automatically, use xm_vars.var() to define a variable. 2.17 2.18 -if vmid <= 0: 2.19 - raise ValueError, "Variable 'vmid' must be greater than 0" 2.20 +def vmid_check(var, val): 2.21 + val = int(val) 2.22 + if val <= 0: 2.23 + raise ValueError 2.24 + return val 2.25 + 2.26 +xm_vars.var('vmid', 2.27 + use="Virtual machine id. Integer greater than 0.", 2.28 + check=vmid_check) 2.29 2.30 +# This checks the script variables. 2.31 +xm_vars.check() 2.32 2.33 #---------------------------------------------------------------------------- 2.34 # Kernel image file.
3.1 --- a/tools/python/xen/xend/XendClient.py Thu Jul 01 23:32:40 2004 +0000 3.2 +++ b/tools/python/xen/xend/XendClient.py Fri Jul 02 08:30:28 2004 +0000 3.3 @@ -1,6 +1,11 @@ 3.4 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 3.5 """Client API for the HTTP interface on xend. 3.6 Callable as a script - see main(). 3.7 + 3.8 +This API is the 'control-plane' for xend. 3.9 +The 'data-plane' is done separately. For example, consoles 3.10 +are accessed via sockets on xend, but the list of consoles 3.11 +is accessible via this API. 3.12 """ 3.13 import sys 3.14 import httplib 3.15 @@ -27,6 +32,8 @@ class Foo(httplib.HTTPResponse): 3.16 3.17 3.18 def sxprio(sxpr): 3.19 + """Convert an sxpr to a string. 3.20 + """ 3.21 io = StringIO() 3.22 sxp.show(sxpr, out=io) 3.23 print >> io 3.24 @@ -80,6 +87,12 @@ def eventurl(location, root, id=''): 3.25 return urljoin(location, root, 'event/', id) 3.26 3.27 def xend_request(url, method, data=None): 3.28 + """Make a request to xend. 3.29 + 3.30 + url xend request url 3.31 + method http method: POST or GET 3.32 + data request argument data (dict) 3.33 + """ 3.34 urlinfo = urlparse.urlparse(url) 3.35 (uproto, ulocation, upath, uparam, uquery, ufrag) = urlinfo 3.36 if DEBUG: print url, urlinfo 3.37 @@ -122,20 +135,37 @@ def xend_request(url, method, data=None) 3.38 return val 3.39 3.40 def xend_get(url, args=None): 3.41 + """Make a xend request using GET. 3.42 + Requests using GET are 'safe' and may be repeated without 3.43 + nasty side-effects. 3.44 + """ 3.45 return xend_request(url, "GET", args) 3.46 3.47 def xend_call(url, data): 3.48 + """Make xend request using POST. 3.49 + Requests using POST potentially cause side-effects and should 3.50 + not be repeated unless it really is wanted to do the side 3.51 + effect again. 3.52 + """ 3.53 return xend_request(url, "POST", data) 3.54 3.55 class Xend: 3.56 3.57 + """Default location of the xend server.""" 3.58 SRV_DEFAULT = "localhost:8000" 3.59 + 3.60 + """Default path to the xend root on the server.""" 3.61 ROOT_DEFAULT = "/xend/" 3.62 3.63 def __init__(self, srv=None, root=None): 3.64 self.bind(srv, root) 3.65 3.66 def bind(self, srv=None, root=None): 3.67 + """Bind to a given server. 3.68 + 3.69 + srv server location (host:port) 3.70 + root server xend root path 3.71 + """ 3.72 if srv is None: srv = self.SRV_DEFAULT 3.73 if root is None: root = self.ROOT_DEFAULT 3.74 if not root.endswith('/'): root += '/'
4.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py Thu Jul 01 23:32:40 2004 +0000 4.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py Fri Jul 02 08:30:28 2004 +0000 4.3 @@ -1,5 +1,6 @@ 4.4 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 4.5 4.6 +import traceback 4.7 from StringIO import StringIO 4.8 4.9 from twisted.protocols import http 4.10 @@ -24,6 +25,7 @@ class SrvDomainDir(SrvDir): 4.11 val = None 4.12 try: 4.13 dom = self.xd.domain_get(x) 4.14 + if not dom: raise KeyError('No such domain') 4.15 val = SrvDomain(dom) 4.16 except KeyError, ex: 4.17 print 'SrvDomainDir>', ex 4.18 @@ -38,6 +40,9 @@ class SrvDomainDir(SrvDir): 4.19 return v 4.20 4.21 def op_create(self, op, req): 4.22 + """Create a domain. 4.23 + Expects the domain config in request parameter 'config' in SXP format. 4.24 + """ 4.25 ok = 0 4.26 try: 4.27 configstring = req.args.get('config')[0] 4.28 @@ -48,7 +53,8 @@ class SrvDomainDir(SrvDir): 4.29 config = pin.get_val() 4.30 ok = 1 4.31 except Exception, ex: 4.32 - print 'op_create>', ex 4.33 + print 'op_create> Exception in config', ex 4.34 + traceback.print_exc() 4.35 if not ok: 4.36 req.setResponseCode(http.BAD_REQUEST, "Invalid configuration") 4.37 return "Invalid configuration" 4.38 @@ -60,10 +66,10 @@ class SrvDomainDir(SrvDir): 4.39 deferred.addCallback(self._cb_op_create, configstring, req) 4.40 return deferred 4.41 except Exception, ex: 4.42 - raise 4.43 - #return ['err', str(ex) ] 4.44 - #req.setResponseCode(http.BAD_REQUEST, "Error creating domain") 4.45 - #return str(ex) 4.46 + print 'op_create> Exception creating domain:' 4.47 + traceback.print_exc() 4.48 + req.setResponseCode(http.BAD_REQUEST, "Error creating domain") 4.49 + return str(ex) 4.50 #return error.ErrorPage(http.BAD_REQUEST, 4.51 # "Error creating domain", 4.52 # str(ex)) 4.53 @@ -90,6 +96,8 @@ class SrvDomainDir(SrvDir): 4.54 return val 4.55 4.56 def op_restore(self, op, req): 4.57 + """Restore a domain from file. 4.58 + """ 4.59 fn = FormFn(self.xd.domain_restore, 4.60 [['file', 'str']]) 4.61 val = fn(req.args) 4.62 @@ -131,6 +139,8 @@ class SrvDomainDir(SrvDir): 4.63 req.write('</ul>') 4.64 4.65 def form(self, req): 4.66 + """Generate the form(s) for domain dir operations. 4.67 + """ 4.68 req.write('<form method="post" action="%s" enctype="multipart/form-data">' 4.69 % req.prePathURL()) 4.70 req.write('<button type="submit" name="op" value="create">Create Domain</button>')
5.1 --- a/tools/python/xen/xend/server/blkif.py Thu Jul 01 23:32:40 2004 +0000 5.2 +++ b/tools/python/xen/xend/server/blkif.py Fri Jul 02 08:30:28 2004 +0000 5.3 @@ -1,3 +1,5 @@ 5.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 5.5 + 5.6 from twisted.internet import defer 5.7 5.8 from xen.xend import sxp 5.9 @@ -28,6 +30,11 @@ class BlkifControllerFactory(controller. 5.10 self.registerChannel() 5.11 5.12 def createInstance(self, dom, recreate=0): 5.13 + """Create a block device controller for a domain. 5.14 + 5.15 + dom domain 5.16 + recreate if true it's a recreate (after xend restart) 5.17 + """ 5.18 d = self.addDeferred() 5.19 blkif = self.getInstanceByDom(dom) 5.20 if blkif: 5.21 @@ -42,29 +49,50 @@ class BlkifControllerFactory(controller. 5.22 return d 5.23 5.24 def getDomainDevices(self, dom): 5.25 + """Get the block devices for a domain. 5.26 + 5.27 + dom domain 5.28 + 5.29 + returns devices 5.30 + """ 5.31 blkif = self.getInstanceByDom(dom) 5.32 return (blkif and blkif.getDevices()) or [] 5.33 5.34 def getDomainDevice(self, dom, vdev): 5.35 + """Get a block device from a domain. 5.36 + 5.37 + dom domain 5.38 + vdev device index 5.39 + 5.40 + returns device 5.41 + """ 5.42 blkif = self.getInstanceByDom(dom) 5.43 return (blkif and blkif.getDevice(vdev)) or None 5.44 5.45 def setControlDomain(self, dom, recreate=0): 5.46 + """Set the back-end block device controller domain. 5.47 + 5.48 + dom domain 5.49 + recreate if true it's a recreate (after xend restart) 5.50 + """ 5.51 if self.dom == dom: return 5.52 self.deregisterChannel() 5.53 if not recreate: 5.54 self.attached = 0 5.55 self.dom = dom 5.56 self.registerChannel() 5.57 - # 5.58 - #if xend.blkif.be_port: 5.59 - # xend.blkif.recovery = True 5.60 - #xend.blkif.be_port = xend.main.port_from_dom(dom) 5.61 5.62 def getControlDomain(self): 5.63 + """Get the back-end block device controller domain. 5.64 + """ 5.65 return self.dom 5.66 5.67 def reattachDevice(self, dom, vdev): 5.68 + """Reattach a device (on changing control domain). 5.69 + 5.70 + dom domain 5.71 + vdev device index 5.72 + """ 5.73 blkif = self.getInstanceByDom(dom) 5.74 if blkif: 5.75 blkif.reattachDevice(vdev) 5.76 @@ -83,6 +111,9 @@ class BlkifControllerFactory(controller. 5.77 return attached 5.78 5.79 def reattached(self): 5.80 + """Notify all block interface we have been reattached 5.81 + (after changing control domain). 5.82 + """ 5.83 for blkif in self.getInstances(): 5.84 blkif.reattached() 5.85 5.86 @@ -147,7 +178,6 @@ class BlkDev(controller.Dev): 5.87 return val 5.88 5.89 def destroy(self): 5.90 - print 'BlkDev>destroy>', self.vdev 5.91 PrettyPrint.prettyprint(self.sxpr()) 5.92 self.controller.send_be_vbd_destroy(self.vdev) 5.93 5.94 @@ -157,7 +187,6 @@ class BlkifController(controller.Control 5.95 """ 5.96 5.97 def __init__(self, factory, dom): 5.98 - #print 'BlkifController> dom=', dom 5.99 controller.Controller.__init__(self, factory, dom) 5.100 self.devices = {} 5.101 5.102 @@ -172,7 +201,6 @@ class BlkifController(controller.Control 5.103 self.attached = 1 5.104 self.evtchn = None 5.105 self.registerChannel() 5.106 - #print 'BlkifController<', 'dom=', self.dom, 'idx=', self.idx 5.107 5.108 def sxpr(self): 5.109 val = ['blkif', ['dom', self.dom]] 5.110 @@ -183,8 +211,6 @@ class BlkifController(controller.Control 5.111 return val 5.112 5.113 def lostChannel(self): 5.114 - print 'BlkifController>lostChannel>', 'dom=', self.dom 5.115 - #self.destroyDevices() 5.116 controller.Controller.lostChannel(self) 5.117 5.118 def getDevices(self): 5.119 @@ -201,8 +227,14 @@ class BlkifController(controller.Control 5.120 5.121 def attachDevice(self, vdev, mode, segment, recreate=0): 5.122 """Attach a device to the specified interface. 5.123 + 5.124 + vdev device index 5.125 + mode read/write mode 5.126 + segment segment 5.127 + recreate if true it's being recreated (after xend restart) 5.128 + 5.129 + returns deferred 5.130 """ 5.131 - #print 'BlkifController>attach_device>', self.dom, vdev, mode, segment 5.132 dev = self.addDevice(vdev, mode, segment) 5.133 if not dev: return -1 5.134 if recreate: 5.135 @@ -214,13 +246,11 @@ class BlkifController(controller.Control 5.136 return d 5.137 5.138 def destroy(self): 5.139 - print 'BlkifController>destroy> dom=', self.dom 5.140 def cb_destroy(val): 5.141 self.send_be_destroy() 5.142 d = self.factory.addDeferred() 5.143 d.addCallback(cb_destroy) 5.144 self.send_be_disconnect() 5.145 - #self.destroyDevices() 5.146 5.147 def destroyDevices(self): 5.148 for dev in self.getDevices(): 5.149 @@ -276,11 +306,6 @@ class BlkifController(controller.Control 5.150 self.factory.writeRequest(msg) 5.151 pass 5.152 5.153 - #def recv_fe_interface_status_changed(self, msg, req): 5.154 - # (hnd, status, chan) = unpackMsg('blkif_fe_interface_status_changed_t', msg) 5.155 - # print 'recv_fe_interface_status_changed>', hnd, status, chan 5.156 - # pass 5.157 - 5.158 def send_fe_interface_status_changed(self): 5.159 msg = packMsg('blkif_fe_interface_status_changed_t', 5.160 { 'handle' : 0,
6.1 --- a/tools/python/xen/xend/server/channel.py Thu Jul 01 23:32:40 2004 +0000 6.2 +++ b/tools/python/xen/xend/server/channel.py Fri Jul 02 08:30:28 2004 +0000 6.3 @@ -1,3 +1,5 @@ 6.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 6.5 + 6.6 import xen.lowlevel.xc; xc = xen.lowlevel.xc.new() 6.7 from xen.lowlevel import xu 6.8 from messages import msgTypeName 6.9 @@ -24,14 +26,11 @@ class ChannelFactory: 6.10 self.notifier = xu.notifier() 6.11 6.12 def addChannel(self, channel): 6.13 - """Add a channel. 6.14 + """Add a channel. Registers with the notifier. 6.15 """ 6.16 idx = channel.idx 6.17 self.channels[idx] = channel 6.18 self.notifier.bind(idx) 6.19 - # Try to wake it up 6.20 - #self.notifier.unmask(idx) 6.21 - #channel.notify() 6.22 6.23 def getChannel(self, idx): 6.24 """Get the channel with the given index (if any). 6.25 @@ -40,6 +39,7 @@ class ChannelFactory: 6.26 6.27 def delChannel(self, idx): 6.28 """Remove the channel with the given index (if any). 6.29 + Deregisters with the notifier. 6.30 """ 6.31 if idx in self.channels: 6.32 del self.channels[idx] 6.33 @@ -288,6 +288,8 @@ class Channel(BaseChannel): 6.34 self.getRemotePort())) 6.35 6.36 def handleNotification(self): 6.37 + """Process outstanding messages in repsonse to notification on the port. 6.38 + """ 6.39 if self.closed: 6.40 print 'handleNotification> Notification on closed channel', self 6.41 return 6.42 @@ -299,6 +301,8 @@ class Channel(BaseChannel): 6.43 self.notify() 6.44 6.45 def notify(self): 6.46 + """Notify the other end of the port that messages have been processed. 6.47 + """ 6.48 if self.closed: return 6.49 self.port.notify() 6.50
7.1 --- a/tools/python/xen/xend/server/console.py Thu Jul 01 23:32:40 2004 +0000 7.2 +++ b/tools/python/xen/xend/server/console.py Fri Jul 02 08:30:28 2004 +0000 7.3 @@ -1,3 +1,4 @@ 7.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 7.5 7.6 from twisted.internet import reactor 7.7 from twisted.internet import protocol 7.8 @@ -12,11 +13,6 @@ import controller 7.9 from messages import * 7.10 from params import * 7.11 7.12 -"""Telnet binary option.""" 7.13 -TRANSMIT_BINARY = '0' 7.14 -WILL = chr(251) 7.15 -IAC = chr(255) 7.16 - 7.17 class ConsoleProtocol(protocol.Protocol): 7.18 """Asynchronous handler for a console TCP socket. 7.19 """ 7.20 @@ -36,19 +32,12 @@ class ConsoleProtocol(protocol.Protocol) 7.21 self.loseConnection() 7.22 return 7.23 else: 7.24 - # KAF: A nice quiet successful connect. Don't bother with telnet 7.25 - # control sequence -- telnet is not the appropriate protocol here. 7.26 + # KAF: A nice quiet successful connect. 7.27 #self.transport.write("Connected to console %d on domain %d\n" 7.28 # % (self.idx, self.controller.dom)) 7.29 - #self.setTelnetTransmitBinary() 7.30 eserver.inject('xend.console.connect', 7.31 [self.idx, self.addr[0], self.addr[1]]) 7.32 7.33 - def setTelnetTransmitBinary(self): 7.34 - """Send the sequence to set the telnet TRANSMIT-BINARY option. 7.35 - """ 7.36 - self.write(IAC + WILL + TRANSMIT_BINARY) 7.37 - 7.38 def dataReceived(self, data): 7.39 if self.controller.handleInput(self, data): 7.40 self.loseConnection() 7.41 @@ -105,7 +94,6 @@ class ConsoleController(controller.Contr 7.42 """ 7.43 7.44 def __init__(self, factory, dom, console_port): 7.45 - #print 'ConsoleController> dom=', dom, type(dom) 7.46 controller.Controller.__init__(self, factory, dom) 7.47 self.majorTypes = [ CMSG_CONSOLE ] 7.48 self.status = "new" 7.49 @@ -118,7 +106,6 @@ class ConsoleController(controller.Contr 7.50 self.registerChannel() 7.51 self.listener = None 7.52 self.listen() 7.53 - #print 'ConsoleController<', 'dom=', self.dom, 'idx=', self.idx 7.54 7.55 def sxpr(self): 7.56 val =['console', 7.57 @@ -143,7 +130,6 @@ class ConsoleController(controller.Contr 7.58 7.59 def close(self): 7.60 try: 7.61 - #print 'ConsoleController> close dom=', self.dom 7.62 self.status = "closed" 7.63 if self.conn: 7.64 self.conn.loseConnection() 7.65 @@ -183,11 +169,11 @@ class ConsoleController(controller.Contr 7.66 self.listen() 7.67 7.68 def requestReceived(self, msg, type, subtype): 7.69 - #print '***Console', self.dom, msg.get_payload() 7.70 self.rbuf.write(msg.get_payload()) 7.71 self.handleOutput() 7.72 7.73 def responseReceived(self, msg, type, subtype): 7.74 + # Just ignore responses. 7.75 pass 7.76 7.77 def produceRequests(self): 7.78 @@ -215,18 +201,14 @@ class ConsoleController(controller.Contr 7.79 Sends it to the connected console (if any). 7.80 """ 7.81 if self.closed(): 7.82 - #print 'Console>handleOutput> closed' 7.83 return -1 7.84 if not self.conn: 7.85 - #print 'Console>handleOutput> not connected' 7.86 return 0 7.87 while not self.rbuf.empty(): 7.88 try: 7.89 - #print 'Console>handleOutput> writing...' 7.90 bytes = self.conn.write(self.rbuf.peek()) 7.91 if bytes > 0: 7.92 self.rbuf.discard(bytes) 7.93 except socket.error, error: 7.94 pass 7.95 - #print 'Console>handleOutput<' 7.96 return 0
8.1 --- a/tools/python/xen/xend/server/controller.py Thu Jul 01 23:32:40 2004 +0000 8.2 +++ b/tools/python/xen/xend/server/controller.py Fri Jul 02 08:30:28 2004 +0000 8.3 @@ -1,3 +1,5 @@ 8.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 8.5 + 8.6 from twisted.internet import defer 8.7 8.8 import channel 8.9 @@ -5,6 +7,15 @@ from messages import msgTypeName 8.10 8.11 class CtrlMsgRcvr: 8.12 """Abstract class for things that deal with a control interface to a domain. 8.13 + 8.14 + Instance variables: 8.15 + 8.16 + dom : the domain we are a control interface for 8.17 + majorTypes: list of major message types we are interested in 8.18 + subTypes : mapping of message subtypes to methods 8.19 + 8.20 + channel : channel to the domain 8.21 + idx : channel index 8.22 """ 8.23 8.24 8.25 @@ -17,6 +28,12 @@ class CtrlMsgRcvr: 8.26 self.idx = None 8.27 8.28 def requestReceived(self, msg, type, subtype): 8.29 + """Dispatch a request to handlers. 8.30 + 8.31 + msg message 8.32 + type major message type 8.33 + subtype minor message type 8.34 + """ 8.35 method = self.subTypes.get(subtype) 8.36 if method: 8.37 method(msg, 1) 8.38 @@ -25,6 +42,12 @@ class CtrlMsgRcvr: 8.39 % (msgTypeName(type, subtype), type, subtype)), self 8.40 8.41 def responseReceived(self, msg, type, subtype): 8.42 + """Dispatch a response to handlers. 8.43 + 8.44 + msg message 8.45 + type major message type 8.46 + subtype minor message type 8.47 + """ 8.48 method = self.subTypes.get(subtype) 8.49 if method: 8.50 method(msg, 0) 8.51 @@ -33,9 +56,14 @@ class CtrlMsgRcvr: 8.52 % (msgTypeName(type, subtype), type, subtype)), self 8.53 8.54 def lostChannel(self): 8.55 + """Called when the channel to the domain is lost. 8.56 + """ 8.57 pass 8.58 8.59 def registerChannel(self): 8.60 + """Register interest in our major message types with the 8.61 + channel to our domain. 8.62 + """ 8.63 #print 'CtrlMsgRcvr>registerChannel>', self 8.64 self.channel = self.channelFactory.domChannel(self.dom) 8.65 self.idx = self.channel.getIndex() 8.66 @@ -43,21 +71,32 @@ class CtrlMsgRcvr: 8.67 self.channel.registerDevice(self.majorTypes, self) 8.68 8.69 def deregisterChannel(self): 8.70 + """Deregister interest in our major message types with the 8.71 + channel to our domain. 8.72 + """ 8.73 #print 'CtrlMsgRcvr>deregisterChannel>', self 8.74 if self.channel: 8.75 self.channel.deregisterDevice(self) 8.76 del self.channel 8.77 8.78 def produceRequests(self): 8.79 + """Produce any queued requests. 8.80 + 8.81 + return number produced 8.82 + """ 8.83 return 0 8.84 8.85 def writeRequest(self, msg): 8.86 + """Write a request to the channel. 8.87 + """ 8.88 if self.channel: 8.89 self.channel.writeRequest(msg) 8.90 else: 8.91 print 'CtrlMsgRcvr>writeRequest>', 'no channel!', self 8.92 8.93 def writeResponse(self, msg): 8.94 + """Write a response to the channel. 8.95 + """ 8.96 if self.channel: 8.97 self.channel.writeResponse(msg) 8.98 else: 8.99 @@ -66,6 +105,13 @@ class CtrlMsgRcvr: 8.100 class ControllerFactory(CtrlMsgRcvr): 8.101 """Abstract class for factories creating controllers. 8.102 Maintains a table of instances. 8.103 + 8.104 + Instance variables: 8.105 + 8.106 + instances : mapping of index to controller instance 8.107 + dlist : list of deferreds 8.108 + dom : domain 8.109 + timeout : deferred timeout 8.110 """ 8.111 8.112 def __init__(self): 8.113 @@ -77,34 +123,49 @@ class ControllerFactory(CtrlMsgRcvr): 8.114 self.timeout = 10 8.115 8.116 def addInstance(self, instance): 8.117 + """Add a controller instance (under its index). 8.118 + """ 8.119 self.instances[instance.idx] = instance 8.120 8.121 def getInstance(self, idx): 8.122 + """Get a controller instance from its index. 8.123 + """ 8.124 return self.instances.get(idx) 8.125 8.126 def getInstances(self): 8.127 + """Get a list of all controller instances. 8.128 + """ 8.129 return self.instances.values() 8.130 8.131 def getInstanceByDom(self, dom): 8.132 + """Get the controller instance for the given domain. 8.133 + """ 8.134 for inst in self.instances.values(): 8.135 if inst.dom == dom: 8.136 return inst 8.137 return None 8.138 8.139 def delInstance(self, instance): 8.140 - #print 'ControllerFactory>delInstance>', instance.idx 8.141 + """Delete an instance from the table. 8.142 + """ 8.143 if instance.idx in self.instances: 8.144 - #print 'ControllerFactory>delInstance> remove', instance.idx 8.145 del self.instances[instance.idx] 8.146 8.147 def createInstance(self, dom, recreate=0): 8.148 + """Create an instance. Define in a subclass. 8.149 + """ 8.150 raise NotImplementedError() 8.151 8.152 def instanceClosed(self, instance): 8.153 - #print 'ControllerFactory>instanceClosed>', instance.idx, instance 8.154 + """Callback called when an instance is closed (usually by the instance). 8.155 + """ 8.156 self.delInstance(instance) 8.157 8.158 def addDeferred(self): 8.159 + """Add a deferred object. 8.160 + 8.161 + returns deferred 8.162 + """ 8.163 d = defer.Deferred() 8.164 if self.timeout > 0: 8.165 # The deferred will error if not called before timeout. 8.166 @@ -113,11 +174,19 @@ class ControllerFactory(CtrlMsgRcvr): 8.167 return d 8.168 8.169 def callDeferred(self, *args): 8.170 + """Call the top deferred object 8.171 + 8.172 + args arguments 8.173 + """ 8.174 if self.dlist: 8.175 d = self.dlist.pop(0) 8.176 d.callback(*args) 8.177 8.178 def errDeferred(self, *args): 8.179 + """Signal an error to the top deferred object. 8.180 + 8.181 + args arguments 8.182 + """ 8.183 if self.dlist: 8.184 d = self.dlist.pop(0) 8.185 d.errback(*args) 8.186 @@ -134,15 +203,20 @@ class Controller(CtrlMsgRcvr): 8.187 self.idx = None 8.188 8.189 def close(self): 8.190 + """Close the controller. 8.191 + """ 8.192 self.deregisterChannel() 8.193 self.lostChannel() 8.194 8.195 def lostChannel(self): 8.196 - #print 'Controller>lostChannel>', self, self.factory 8.197 + """The controller channel has been lost. 8.198 + """ 8.199 self.factory.instanceClosed(self) 8.200 8.201 class Dev: 8.202 - 8.203 + """Abstract class for a device attached to a device controller. 8.204 + """ 8.205 + 8.206 def __init__(self, controller): 8.207 self.controller = controller 8.208 self.props = {} 8.209 @@ -160,9 +234,6 @@ class Dev: 8.210 if k in self.props: 8.211 del self.props[k] 8.212 8.213 - #def __repr__(self): 8.214 - # return str(self.sxpr()) 8.215 - 8.216 def sxpr(self): 8.217 raise NotImplementedError() 8.218
9.1 --- a/tools/python/xen/xend/server/cstruct.py Thu Jul 01 23:32:40 2004 +0000 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,269 +0,0 @@ 9.4 -import struct 9.5 - 9.6 -class Struct: 9.7 - 9.8 - maxDepth = 10 9.9 - 9.10 - base = ['x', 'B', 'H', 'I', 'L', 'Q', 'c', 'h', 'i', 'l', 'q', ] 9.11 - 9.12 - sizes = {'B': 1, 9.13 - 'H': 2, 9.14 - 'I': 4, 9.15 - 'L': 4, 9.16 - 'Q': 8, 9.17 - 'c': 1, 9.18 - 'h': 2, 9.19 - 'i': 4, 9.20 - 'l': 4, 9.21 - 'q': 8, 9.22 - 'x': 1, 9.23 - } 9.24 - 9.25 - formats = { 9.26 - 'int8' : 'B', 9.27 - 'int16' : 'H', 9.28 - 'int32' : 'I', 9.29 - 'int64' : 'Q', 9.30 - 'u8' : 'B', 9.31 - 'u16' : 'H', 9.32 - 'u32' : 'I', 9.33 - 'u64' : 'Q' 9.34 - } 9.35 - 9.36 - def typedef(self, name, val): 9.37 - self.formats[name] = val 9.38 - 9.39 - def struct(self, name, *f): 9.40 - self.typedef(name, StructInfo(self, f)) 9.41 - 9.42 - def getType(self, name): 9.43 - return self.formats[name] 9.44 - 9.45 - def format(self, ty): 9.46 - d = 0 9.47 - f = ty 9.48 - while d < self.maxDepth: 9.49 - d += 1 9.50 - f = self.formats[f] 9.51 - if isinstance(f, StructInfo): 9.52 - return f.format() 9.53 - if f in self.base: 9.54 - return f 9.55 - return -1 9.56 - 9.57 - def alignedformat(self, ty): 9.58 - fmt = self.format(ty) 9.59 - #print 'alignedformat> %s |%s|' %(ty, fmt) 9.60 - afmt = self.align(fmt) 9.61 - #print 'alignedformat< %s |%s| |%s|' % (ty, fmt, afmt) 9.62 - return afmt 9.63 - 9.64 - def align(self, fmt): 9.65 - n1 = 0 9.66 - afmt = '' 9.67 - for a in fmt: 9.68 - n2 = self.getSize(a) 9.69 - m = n1 % n2 9.70 - if m: 9.71 - d = (n2 - m) 9.72 - afmt += 'x' * d 9.73 - n1 += d 9.74 - afmt += a 9.75 - n1 += n2 9.76 - return afmt 9.77 - 9.78 - def fmtsize(self, fmt): 9.79 - s = 0 9.80 - for f in fmt: 9.81 - s += self.getSize(f) 9.82 - return s 9.83 - 9.84 - def getSize(self, f): 9.85 - return self.sizes[f] 9.86 - 9.87 - def pack(self, ty, data): 9.88 - return self.getType(ty).pack(data) 9.89 - 9.90 - def unpack(self, ty, data): 9.91 - return self.getType(ty).unpack(data) 9.92 - 9.93 - def show(self): 9.94 - l = self.formats.keys() 9.95 - l.sort() 9.96 - for v in l: 9.97 - print "%-35s %-10s %s" % (v, self.format(v), self.alignedformat(v)) 9.98 - 9.99 - 9.100 -class StructInfo: 9.101 - 9.102 - def __init__(self, s, f): 9.103 - self.fmt = None 9.104 - self.structs = s 9.105 - self.fields = f 9.106 - 9.107 - def alignedformat(self): 9.108 - if self.afmt: return self.afmt 9.109 - self.afmt = self.structs.align(self.format()) 9.110 - return self.afmt 9.111 - 9.112 - def format(self): 9.113 - if self.fmt: return self.fmt 9.114 - fmt = "" 9.115 - for (ty, name) in self.fields: 9.116 - fmt += self.formatString(ty) 9.117 - self.fmt = fmt 9.118 - return fmt 9.119 - 9.120 - def formatString(self, ty): 9.121 - if ty in self.fields: 9.122 - ty = self.fields[ty] 9.123 - return self.structs.format(ty) 9.124 - 9.125 - def pack(self, *args): 9.126 - return struct.pack(self.alignedformat(), *args) 9.127 - 9.128 - def unpack(self, data): 9.129 - return struct.unpack(self.alignedformat(), data) 9.130 - 9.131 -types = Struct() 9.132 - 9.133 -types.typedef('short' , 'h') 9.134 -types.typedef('int' , 'i') 9.135 -types.typedef('long' , 'l') 9.136 -types.typedef('unsigned short', 'H') 9.137 -types.typedef('unsigned int' , 'I') 9.138 -types.typedef('unsigned long' , 'L') 9.139 -types.typedef('domid_t' , 'u64') 9.140 -types.typedef('blkif_vdev_t' , 'u16') 9.141 -types.typedef('blkif_pdev_t' , 'u16') 9.142 -types.typedef('blkif_sector_t', 'u64') 9.143 - 9.144 -types.struct('u8[6]', 9.145 - ('u8', 'a1'), 9.146 - ('u8', 'a2'), 9.147 - ('u8', 'a3'), 9.148 - ('u8', 'a4'), 9.149 - ('u8', 'a5'), 9.150 - ('u8', 'a6')) 9.151 - 9.152 -types.struct('blkif_fe_interface_status_changed_t', 9.153 - ('unsigned int', 'handle'), 9.154 - ('unsigned int', 'status'), 9.155 - ('unsigned int', 'evtchn')) 9.156 - 9.157 -types.struct('blkif_fe_driver_status_changed_t', 9.158 - ('unsigned int', 'status'), 9.159 - ('unsigned int', 'nr_interfaces')) 9.160 - 9.161 -types.struct('blkif_fe_interface_connect_t', 9.162 - ('unsigned int' , 'handle'), 9.163 - ('unsigned long', 'shmem_frame')) 9.164 - 9.165 -types.struct('blkif_fe_interface_disconnect_t', 9.166 - ('unsigned int', 'handle')) 9.167 - 9.168 -types.struct('blkif_extent_t', 9.169 - ('blkif_pdev_t' , 'device'), 9.170 - ('blkif_sector_t', 'sector_start'), 9.171 - ('blkif_sector_t', 'sector_length')) 9.172 - 9.173 -types.struct('blkif_be_create_t', 9.174 - ('domid_t' , 'domid'), 9.175 - ('unsigned int', 'blkif_handle'), 9.176 - ('unsigned int', 'status')) 9.177 - 9.178 -types.struct('blkif_be_destroy_t', 9.179 - ('domid_t' , 'domid'), 9.180 - ('unsigned int', 'blkif_handle'), 9.181 - ('unsigned int', 'status')) 9.182 - 9.183 -types.struct('blkif_be_connect_t', 9.184 - ('domid_t' , 'domid'), 9.185 - ('unsigned int' , 'blkif_handle'), 9.186 - ('unsigned int' , 'evtchn'), 9.187 - ('unsigned long', 'shmem_frame'), 9.188 - ('unsigned int' , 'status')) 9.189 - 9.190 -types.struct('blkif_be_disconnect_t', 9.191 - ('domid_t' , 'domid'), 9.192 - ('unsigned int', 'blkif_handle'), 9.193 - ('unsigned int', 'status')) 9.194 - 9.195 -types.struct('blkif_be_vbd_create_t', 9.196 - ('domid_t' , 'domid'), #Q 9.197 - ('unsigned int', 'blkif_handle'), #I 9.198 - ('blkif_vdev_t', 'vdevice'), #H 9.199 - ('int' , 'readonly'), #i 9.200 - ('unsigned int', 'status')) #I 9.201 - 9.202 -types.struct('blkif_be_vbd_destroy_t', 9.203 - ('domid_t' , 'domid'), 9.204 - ('unsigned int', 'blkif_handle'), 9.205 - ('blkif_vdev_t', 'vdevice'), 9.206 - ('unsigned int', 'status')) 9.207 - 9.208 -types.struct('blkif_be_vbd_grow_t', 9.209 - ('domid_t' , 'domid'), #Q 9.210 - ('unsigned int' , 'blkif_handle'), #I 9.211 - ('blkif_vdev_t' , 'vdevice'), #H 9.212 - ('blkif_extent_t', 'extent'), #HQQ 9.213 - ('unsigned int' , 'status')) #I 9.214 - 9.215 -types.struct('blkif_be_vbd_shrink_t', 9.216 - ('domid_t' , 'domid'), 9.217 - ('unsigned int', 'blkif_handle'), 9.218 - ('blkif_vdev_t', 'vdevice'), 9.219 - ('unsigned int', 'status')) 9.220 - 9.221 -types.struct('blkif_be_driver_status_changed_t', 9.222 - ('unsigned int', 'status'), 9.223 - ('unsigned int', 'nr_interfaces')) 9.224 - 9.225 -types.struct('netif_fe_interface_status_changed_t', 9.226 - ('unsigned int', 'handle'), 9.227 - ('unsigned int', 'status'), 9.228 - ('unsigned int', 'evtchn'), 9.229 - ('u8[6]', 'mac')) 9.230 - 9.231 -types.struct('netif_fe_driver_status_changed_t', 9.232 - ('unsigned int', 'status'), 9.233 - ('unsigned int', 'nr_interfaces')) 9.234 - 9.235 -types.struct('netif_fe_interface_connect_t', 9.236 - ('unsigned int', 'handle'), 9.237 - ('unsigned long', 'tx_shmem_frame'), 9.238 - ('unsigned long', 'rx_shmem_frame')) 9.239 - 9.240 -types.struct('netif_fe_interface_disconnect_t', 9.241 - ('unsigned int', 'handle')) 9.242 - 9.243 -types.struct('netif_be_create_t', 9.244 - ('domid_t' , 'domid'), 9.245 - ('unsigned int', 'netif_handle'), 9.246 - ('u8[6]' , 'mac'), 9.247 - ('unsigned int', 'status')) 9.248 - 9.249 -types.struct('netif_be_destroy_t', 9.250 - ('domid_t' , 'domid'), 9.251 - ('unsigned int', 'netif_handle'), 9.252 - ('unsigned int', 'status')) 9.253 - 9.254 -types.struct('netif_be_connect_t', 9.255 - ('domid_t' , 'domid'), 9.256 - ('unsigned int' , 'netif_handle'), 9.257 - ('unsigned int' , 'evtchn'), 9.258 - ('unsigned long', 'tx_shmem_frame'), 9.259 - ('unsigned long', 'rx_shmem_frame'), 9.260 - ('unsigned int' , 'status')) 9.261 - 9.262 -types.struct('netif_be_disconnect_t', 9.263 - ('domid_t' , 'domid'), 9.264 - ('unsigned int', 'netif_handle'), 9.265 - ('unsigned int', 'status')) 9.266 - 9.267 -types.struct('netif_be_driver_status_changed_t', 9.268 - ('unsigned int', 'status'), 9.269 - ('unsigned int', 'nr_interfaces')) 9.270 - 9.271 -if 1 or __name__ == "__main__": 9.272 - types.show()
10.1 --- a/tools/python/xen/xend/server/domain.py Thu Jul 01 23:32:40 2004 +0000 10.2 +++ b/tools/python/xen/xend/server/domain.py Fri Jul 02 08:30:28 2004 +0000 10.3 @@ -1,3 +1,5 @@ 10.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 10.5 + 10.6 import channel 10.7 import controller 10.8 from messages import * 10.9 @@ -7,11 +9,23 @@ class DomainControllerFactory(controller 10.10 """ 10.11 10.12 def createInstance(self, dom): 10.13 + """Create a domain controller. 10.14 + 10.15 + dom domain 10.16 + 10.17 + returns domain controller 10.18 + """ 10.19 d = DomainController(self, dom) 10.20 self.addInstance(d) 10.21 return d 10.22 10.23 def getInstanceByDom(self, dom): 10.24 + """Get a domain controller for a domain, creating if necessary. 10.25 + 10.26 + dom domain 10.27 + 10.28 + returns domain controller 10.29 + """ 10.30 for inst in self.instances.values(): 10.31 if inst.dom == dom: 10.32 return inst 10.33 @@ -21,8 +35,11 @@ class DomainControllerFactory(controller 10.34 10.35 class DomainController(controller.Controller): 10.36 """Generic controller for a domain. 10.37 + Used for domain shutdown. 10.38 """ 10.39 10.40 + """Map shutdown reasons to the message type to use. 10.41 + """ 10.42 reasons = {'poweroff' : 'shutdown_poweroff_t', 10.43 'reboot' : 'shutdown_reboot_t', 10.44 'suspend' : 'shutdown_suspend_t' } 10.45 @@ -34,6 +51,10 @@ class DomainController(controller.Contro 10.46 print 'DomainController>', self, self.channel, self.idx 10.47 10.48 def shutdown(self, reason): 10.49 + """Shutdown a domain. 10.50 + 10.51 + reason shutdown reason 10.52 + """ 10.53 msgtype = self.reasons.get(reason) 10.54 if not msgtype: 10.55 raise ValueError('invalid reason:' + reason)
11.1 --- a/tools/python/xen/xend/server/messages.py Thu Jul 01 23:32:40 2004 +0000 11.2 +++ b/tools/python/xen/xend/server/messages.py Fri Jul 02 08:30:28 2004 +0000 11.3 @@ -148,6 +148,9 @@ netif_formats = { 11.4 msg_formats.update(netif_formats) 11.5 11.6 #============================================================================ 11.7 +# Domain shutdown message types. 11.8 +#============================================================================ 11.9 + 11.10 CMSG_SHUTDOWN = 6 11.11 11.12 CMSG_SHUTDOWN_POWEROFF = 0 11.13 @@ -177,6 +180,14 @@ class Msg: 11.14 pass 11.15 11.16 def packMsg(ty, params): 11.17 + """Pack a message. 11.18 + Any 'mac' parameter is passed in as an int[6] array and converted. 11.19 + 11.20 + ty message type name 11.21 + params message parameter dict 11.22 + 11.23 + returns xu message 11.24 + """ 11.25 if DEBUG: print '>packMsg', ty, params 11.26 (major, minor) = msg_formats[ty] 11.27 args = {} 11.28 @@ -194,6 +205,15 @@ def packMsg(ty, params): 11.29 return msg 11.30 11.31 def unpackMsg(ty, msg): 11.32 + """Unpack a message. 11.33 + Any mac addresses in the message are converted to int[6] array 11.34 + in the return dict. 11.35 + 11.36 + ty message type 11.37 + msg xu message 11.38 + 11.39 + returns parameter dict 11.40 + """ 11.41 args = msg.get_payload() 11.42 mac = [0, 0, 0, 0, 0, 0] 11.43 macs = [] 11.44 @@ -212,6 +232,13 @@ def unpackMsg(ty, msg): 11.45 return args 11.46 11.47 def msgTypeName(ty, subty): 11.48 + """Convert a message type, subtype pair (ints) to a message type name (string). 11.49 + 11.50 + ty integer message type 11.51 + subty integer message subtype 11.52 + 11.53 + returns message type name (or None) 11.54 + """ 11.55 for (name, info) in msg_formats.items(): 11.56 if info[0] == ty and info[1] == subty: 11.57 return name
12.1 --- a/tools/python/xen/xend/server/netif.py Thu Jul 01 23:32:40 2004 +0000 12.2 +++ b/tools/python/xen/xend/server/netif.py Fri Jul 02 08:30:28 2004 +0000 12.3 @@ -1,3 +1,5 @@ 12.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 12.5 + 12.6 import random 12.7 12.8 from twisted.internet import defer 12.9 @@ -30,8 +32,12 @@ class NetifControllerFactory(controller. 12.10 12.11 def createInstance(self, dom, recreate=0): 12.12 """Create or find the network interface controller for a domain. 12.13 + 12.14 + dom domain 12.15 + recreate if true this is a recreate (xend restarted) 12.16 + 12.17 + returns netif controller 12.18 """ 12.19 - #print 'netif>createInstance> dom=', dom 12.20 netif = self.getInstanceByDom(dom) 12.21 if netif is None: 12.22 netif = NetifController(self, dom) 12.23 @@ -39,15 +45,31 @@ class NetifControllerFactory(controller. 12.24 return netif 12.25 12.26 def getDomainDevices(self, dom): 12.27 + """Get the network device controllers for a domain. 12.28 + 12.29 + dom domain 12.30 + 12.31 + returns netif controller 12.32 + """ 12.33 netif = self.getInstanceByDom(dom) 12.34 return (netif and netif.getDevices()) or [] 12.35 12.36 def getDomainDevice(self, dom, vif): 12.37 + """Get a virtual network interface device for a domain. 12.38 + 12.39 + dom domain 12.40 + vif virtual interface index 12.41 + 12.42 + returns NetDev 12.43 + """ 12.44 netif = self.getInstanceByDom(dom) 12.45 return (netif and netif.getDevice(vif)) or None 12.46 12.47 def setControlDomain(self, dom, recreate=0): 12.48 """Set the 'back-end' device driver domain. 12.49 + 12.50 + dom domain 12.51 + recreate if true this is a recreate (xend restarted) 12.52 """ 12.53 if self.dom == dom: return 12.54 self.deregisterChannel() 12.55 @@ -55,13 +77,10 @@ class NetifControllerFactory(controller. 12.56 self.attached = 0 12.57 self.dom = dom 12.58 self.registerChannel() 12.59 - # 12.60 - #if xend.netif.be_port.remote_dom != 0: 12.61 - # xend.netif.recovery = True 12.62 - # xend.netif.be_port = xend.main.port_from_dom(dom) 12.63 - # 12.64 12.65 def getControlDomain(self): 12.66 + """Get the domain id of the back-end control domain. 12.67 + """ 12.68 return self.dom 12.69 12.70 def recv_be_create(self, msg, req): 12.71 @@ -88,23 +107,6 @@ class NetifControllerFactory(controller. 12.72 netif.reattach_devices() 12.73 self.attached = 1 12.74 12.75 -## pl = msg.get_payload() 12.76 -## status = pl['status'] 12.77 -## if status == NETIF_DRIVER_STATUS_UP: 12.78 -## if xend.netif.recovery: 12.79 -## print "New netif backend now UP, notifying guests:" 12.80 -## for netif_key in interface.list.keys(): 12.81 -## netif = interface.list[netif_key] 12.82 -## netif.create() 12.83 -## print " Notifying %d" % netif.dom 12.84 -## msg = xu.message( 12.85 -## CMSG_NETIF_FE, 12.86 -## CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, 0, 12.87 -## { 'handle' : 0, 'status' : 1 }) 12.88 -## netif.ctrlif_tx_req(xend.main.port_from_dom(netif.dom),msg) 12.89 -## print "Done notifying guests" 12.90 -## recovery = False 12.91 - 12.92 class NetDev(controller.Dev): 12.93 """Info record for a network device. 12.94 """ 12.95 @@ -130,9 +132,13 @@ class NetDev(controller.Dev): 12.96 return val 12.97 12.98 def get_vifname(self): 12.99 + """Get the virtual interface device name. 12.100 + """ 12.101 return "vif%d.%d" % (self.controller.dom, self.vif) 12.102 12.103 def get_mac(self): 12.104 + """Get the MAC address as a string. 12.105 + """ 12.106 return ':'.join(map(lambda x: "%x" % x, self.mac)) 12.107 12.108 def vifctl_params(self): 12.109 @@ -141,23 +147,30 @@ class NetDev(controller.Dev): 12.110 'ipaddr': self.ipaddr } 12.111 12.112 def up(self, bridge=None, ipaddr=[]): 12.113 + """Bring the device up. 12.114 + 12.115 + bridge ethernet bridge to connect to 12.116 + ipaddr list of ipaddrs to filter using iptables 12.117 + """ 12.118 self.bridge = bridge 12.119 self.ipaddr = ipaddr 12.120 Vifctl.up(self.get_vifname(), **self.vifctl_params()) 12.121 12.122 def down(self): 12.123 + """Bring the device down. 12.124 + """ 12.125 Vifctl.down(self.get_vifname(), **self.vifctl_params()) 12.126 12.127 def destroy(self): 12.128 + """Destroy the device's resources and disconnect from the back-end 12.129 + device controller. 12.130 + """ 12.131 def cb_destroy(val): 12.132 self.controller.send_be_destroy(self.vif) 12.133 - print 'NetDev>destroy>', 'vif=', self.vif 12.134 - PrettyPrint.prettyprint(self.sxpr()) 12.135 self.down() 12.136 d = self.controller.factory.addDeferred() 12.137 d.addCallback(cb_destroy) 12.138 self.controller.send_be_disconnect(self.vif) 12.139 - #self.controller.send_be_destroy(self.vif) 12.140 12.141 12.142 class NetifController(controller.Controller): 12.143 @@ -165,7 +178,6 @@ class NetifController(controller.Control 12.144 """ 12.145 12.146 def __init__(self, factory, dom): 12.147 - #print 'NetifController> dom=', dom 12.148 controller.Controller.__init__(self, factory, dom) 12.149 self.devices = {} 12.150 12.151 @@ -178,21 +190,22 @@ class NetifController(controller.Control 12.152 self.recv_fe_interface_connect, 12.153 } 12.154 self.registerChannel() 12.155 - #print 'NetifController<', 'dom=', self.dom, 'idx=', self.idx 12.156 12.157 def sxpr(self): 12.158 val = ['netif', ['dom', self.dom]] 12.159 return val 12.160 12.161 def randomMAC(self): 12.162 - # VIFs get a random MAC address with a "special" vendor id. 12.163 - # 12.164 - # NB. The vendor is currently an "obsolete" one that used to belong 12.165 - # to DEC (AA-00-00). Using it is probably a bit rude :-) 12.166 - # 12.167 - # NB2. The first bit of the first random octet is set to zero for 12.168 - # all dynamic MAC addresses. This may allow us to manually specify 12.169 - # MAC addresses for some VIFs with no fear of clashes. 12.170 + """Generate a random MAC address. 12.171 + 12.172 + The OUI (Organisation Unique Identifier) used is AA:00:00, which 12.173 + is a currently unassigned one that used to belong to DEC. 12.174 + 12.175 + The remaining 3 fields are random, with the first bit of the first 12.176 + random field set 0. 12.177 + 12.178 + returns array of 6 ints 12.179 + """ 12.180 mac = [ 0xaa, 0x00, 0x00, 12.181 random.randint(0x00, 0x7f), 12.182 random.randint(0x00, 0xff), 12.183 @@ -200,29 +213,46 @@ class NetifController(controller.Control 12.184 return mac 12.185 12.186 def lostChannel(self): 12.187 - print 'NetifController>lostChannel>', 'dom=', self.dom 12.188 - #self.destroyDevices() 12.189 + """Method called when the channel has been lost. 12.190 + """ 12.191 controller.Controller.lostChannel(self) 12.192 12.193 def getDevices(self): 12.194 + """Get a list of the devices. 12.195 + """ 12.196 return self.devices.values() 12.197 12.198 def getDevice(self, vif): 12.199 + """Get a device. 12.200 + 12.201 + vif device index 12.202 + 12.203 + returns device (or None) 12.204 + """ 12.205 return self.devices.get(vif) 12.206 12.207 def addDevice(self, vif, vmac): 12.208 + """Add a network interface. If vmac is None a random MAC is 12.209 + assigned. If specified, vmac must be a string of the form 12.210 + XX:XX:XX:XX:XX where X is hex digit. 12.211 + 12.212 + vif device index 12.213 + vmac device MAC 12.214 + 12.215 + returns device 12.216 + """ 12.217 if vmac is None: 12.218 mac = self.randomMAC() 12.219 else: 12.220 mac = [ int(x, 16) for x in vmac.split(':') ] 12.221 if len(mac) != 6: raise ValueError("invalid mac") 12.222 - #print "attach_device>", "vif=", vif, "mac=", mac 12.223 dev = NetDev(self, vif, mac) 12.224 self.devices[vif] = dev 12.225 return dev 12.226 12.227 def destroy(self): 12.228 - print 'NetifController>destroy>', 'dom=', self.dom 12.229 + """Destroy the controller and all devices. 12.230 + """ 12.231 self.destroyDevices() 12.232 12.233 def destroyDevices(self): 12.234 @@ -306,7 +336,6 @@ class NetifController(controller.Control 12.235 self.factory.writeRequest(msg) 12.236 12.237 def send_be_destroy(self, vif): 12.238 - print 'NetifController>send_be_destroy>', 'dom=', self.dom, 'vif=', vif 12.239 PrettyPrint.prettyprint(self.sxpr()) 12.240 dev = self.devices[vif] 12.241 del self.devices[vif]
13.1 --- a/tools/python/xen/xm/create.py Thu Jul 01 23:32:40 2004 +0000 13.2 +++ b/tools/python/xen/xm/create.py Fri Jul 02 08:30:28 2004 +0000 13.3 @@ -1,4 +1,5 @@ 13.4 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 13.5 + 13.6 """Domain creation. 13.7 """ 13.8 import string 13.9 @@ -15,12 +16,22 @@ from xen.xm.opts import * 13.10 gopts = Opts(use="""[options] 13.11 13.12 Create a domain. 13.13 + 13.14 +Domain creation parameters can be set by command-line switches, from 13.15 +a python configuration script or an SXP config file. See documentation 13.16 +for --defaults, --config. Configuration variables can be set using 13.17 +VAR=VAL on the command line. For example vmid=3 sets vmid to 3. 13.18 + 13.19 """) 13.20 13.21 gopts.opt('help', short='h', 13.22 fn=set_true, default=0, 13.23 use="Print this help.") 13.24 13.25 +gopts.opt('help_config', 13.26 + fn=set_true, default=0, 13.27 + use="Print help for configuration file.") 13.28 + 13.29 gopts.opt('quiet', short='q', 13.30 fn=set_true, default=0, 13.31 use="Quiet.") 13.32 @@ -31,24 +42,40 @@ gopts.opt('path', val='PATH', 13.33 13.34 gopts.opt('defaults', short='f', val='FILE', 13.35 fn=set_value, default='xmdefaults', 13.36 - use="Use the given default script.") 13.37 + use="""Use the given Python defaults script. 13.38 +The defaults script is loaded after arguments have been processed. 13.39 +Each command-line option sets a configuration variable named after 13.40 +its long option name, and these variables are placed in the 13.41 +environment of the script before it is loaded. 13.42 +Variables for options that may be repeated have list values. 13.43 +Other variables can be set using VAR=VAL on the command line. 13.44 + 13.45 +After the script is loaded, option values that were not set on the 13.46 +command line are replaced by the values set in the script. 13.47 +""") 13.48 13.49 gopts.opt('config', short='F', val='FILE', 13.50 fn=set_value, default=None, 13.51 - use='Domain configuration to use (SXP).') 13.52 + use="""Domain configuration to use (SXP). 13.53 +SXP is the underlying configuration format used by Xen. 13.54 +SXP configs can be hand-written or generated from Python defaults 13.55 +scripts, using the -n (dryrun) option to print the config. 13.56 +""") 13.57 13.58 gopts.opt('load', short='L', val='FILE', 13.59 fn=set_value, default=None, 13.60 use='Domain saved state to load.') 13.61 13.62 -gopts.opt('define', short='D', val='VAR=VAL', 13.63 - fn=set_var, default=None, 13.64 - use="""Set a variable before loading defaults, e.g. '-D vmid=3' 13.65 - to set vmid. May be repeated to set more thanone variable.""") 13.66 +#gopts.opt('define', short='D', val='VAR=VAL', 13.67 +# fn=set_var, default=None, 13.68 +# use="""Set a variable before loading defaults, e.g. '-D vmid=3' 13.69 +# to set vmid. May be repeated to set more than one variable.""") 13.70 13.71 gopts.opt('dryrun', short='n', 13.72 fn=set_true, default=0, 13.73 - use="Dry run - print the config but don't create the domain.") 13.74 + use="""Dry run - print the config but don't create the domain. 13.75 +The defaults file is loaded and the SXP configuration is created and printed. 13.76 +""") 13.77 13.78 gopts.opt('name', short='N', val='NAME', 13.79 fn=set_value, default=None, 13.80 @@ -352,7 +379,15 @@ def main(argv): 13.81 args = opts.parse(argv) 13.82 if opts.vals.help: 13.83 opts.usage() 13.84 + if opts.vals.help or opts.vals.help_config: 13.85 + opts.load_defaults(help=1) 13.86 + if opts.vals.help or opts.vals.help_config: 13.87 return 13.88 + # Process remaining args as config variables. 13.89 + for arg in args: 13.90 + if '=' in arg: 13.91 + (var, val) = arg.strip().split('=') 13.92 + gopts.setvar(var.strip(), val.strip()) 13.93 if opts.vals.config: 13.94 pass 13.95 else:
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/tools/python/xen/xm/help.py Fri Jul 02 08:30:28 2004 +0000 14.3 @@ -0,0 +1,82 @@ 14.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 14.5 + 14.6 +"""Variable definition and help support for Python defaults files. 14.7 +""" 14.8 + 14.9 +import sys 14.10 + 14.11 +class Vars: 14.12 + """A set of configuration variables. 14.13 + """ 14.14 + 14.15 + def __init__(self, name, help, env): 14.16 + """Create a variable set. 14.17 + 14.18 + name name of the defaults file 14.19 + help help flag 14.20 + env local environment 14.21 + """ 14.22 + self.name = name 14.23 + self.help = help 14.24 + self.env = env 14.25 + self.vars = [] 14.26 + 14.27 + def var(self, name, use=None, check=None): 14.28 + """Define a configuration variable. 14.29 + If provided, the check function will be called as check(var, val) 14.30 + where var is the variable name and val is its value (string). 14.31 + It should return a new value for the variable, or raise ValueError if 14.32 + the value is not acceptable. 14.33 + 14.34 + name variable name 14.35 + use variable usage string 14.36 + check variable check function 14.37 + """ 14.38 + self.vars.append(Var(name, use, check)) 14.39 + 14.40 + def check(self): 14.41 + """Execute the variable checks or print help, depending on the value 14.42 + of the help flag passed to the constructor. 14.43 + """ 14.44 + if self.help: 14.45 + self.doHelp() 14.46 + else: 14.47 + for v in self.vars: 14.48 + v.doCheck(self.env) 14.49 + 14.50 + def doHelp(self, out=sys.stderr): 14.51 + """Print help for the variables. 14.52 + """ 14.53 + if self.vars: 14.54 + print >>out, "\nConfiguration variables for %s:\n" % self.name 14.55 + for v in self.vars: 14.56 + v.doHelp(out) 14.57 + print >>out 14.58 + 14.59 +class Var: 14.60 + """A single variable. 14.61 + """ 14.62 + 14.63 + def __init__(self, name, use, check): 14.64 + """Create a variable. 14.65 + 14.66 + name variable name 14.67 + use variable use string 14.68 + check variable value check function 14.69 + """ 14.70 + self.name = name 14.71 + self.use = use or '' 14.72 + self.check = check 14.73 + 14.74 + def doCheck(self, env): 14.75 + """Execute the check and set the variable to the new value. 14.76 + """ 14.77 + if not self.check: return 14.78 + env[self.name] = self.check(self.name, env.get(self.name)) 14.79 + 14.80 + def doHelp(self, out): 14.81 + """Print help for the variable. 14.82 + """ 14.83 + print >>out, "%-12s" % self.name, self.use 14.84 + 14.85 +
15.1 --- a/tools/python/xen/xm/main.py Thu Jul 01 23:32:40 2004 +0000 15.2 +++ b/tools/python/xen/xm/main.py Fri Jul 02 08:30:28 2004 +0000 15.3 @@ -5,10 +5,12 @@ import os 15.4 import os.path 15.5 import sys 15.6 from getopt import getopt 15.7 +import socket 15.8 15.9 from xen.xend import PrettyPrint 15.10 from xen.xend import sxp 15.11 from xen.xend.XendClient import server 15.12 +from xen.xend.XendClient import main as xend_client_main 15.13 from xen.xm import create, shutdown 15.14 15.15 class Prog: 15.16 @@ -65,6 +67,13 @@ class Xm: 15.17 sys.exit(1) 15.18 15.19 def main(self, args): 15.20 + try: 15.21 + self.main_call(args) 15.22 + except socket.error, ex: 15.23 + print >>sys.stderr, ex 15.24 + self.err("Error connecting to xend, is xend running?") 15.25 + 15.26 + def main_call(self, args): 15.27 """Main entry point. Dispatches to the progs. 15.28 """ 15.29 self.name = args[0] 15.30 @@ -444,5 +453,21 @@ class ProgConsole(Prog): 15.31 15.32 xm.prog(ProgConsole) 15.33 15.34 +class ProgCall(Prog): 15.35 + name = "call" 15.36 + info = "Call xend api functions." 15.37 + 15.38 + def help (self, args): 15.39 + print "call fn argss..." 15.40 + print """ 15.41 + Call a xend HTTP API function. The leading 'xend_' on the function 15.42 +can be omitted. See xen.xend.XendClient for the API functions. 15.43 +""" 15.44 + 15.45 + def main(self, args): 15.46 + xend_client_main(args) 15.47 + 15.48 +xm.prog(ProgCall) 15.49 + 15.50 def main(args): 15.51 xm.main(args)
16.1 --- a/tools/python/xen/xm/opts.py Thu Jul 01 23:32:40 2004 +0000 16.2 +++ b/tools/python/xen/xm/opts.py Fri Jul 02 08:30:28 2004 +0000 16.3 @@ -259,7 +259,7 @@ class Opts: 16.4 for opt in self.options: 16.5 opt.show() 16.6 16.7 - def load_defaults(self): 16.8 + def load_defaults(self, help=0): 16.9 """Load a defaults script. Assumes these options set: 16.10 'path' search path 16.11 'default' script name 16.12 @@ -270,12 +270,12 @@ class Opts: 16.13 else: 16.14 p = self.vals.defaults 16.15 if os.path.exists(p): 16.16 - self.load(p) 16.17 + self.load(p, help) 16.18 break 16.19 else: 16.20 self.err("Cannot open defaults file %s" % self.vals.defaults) 16.21 16.22 - def load(self, defaults, help=0): 16.23 + def load(self, defaults, help): 16.24 """Load a defaults file. Local variables in the file 16.25 are used to set options with the same names. 16.26 Variables are not used to set options that are already specified. 16.27 @@ -290,11 +290,17 @@ class Opts: 16.28 cmd = '\n'.join(["import sys", 16.29 "import os", 16.30 "import os.path", 16.31 - "import xen.util.ip", 16.32 + "from xen.xm.help import Vars", 16.33 + "from xen.util import ip", 16.34 "xm_file = '%s'" % defaults, 16.35 - "xm_help = %d" % help ]) 16.36 + "xm_help = %d" % help, 16.37 + "xm_vars = Vars(xm_file, xm_help, locals())", 16.38 + ]) 16.39 exec cmd in globals, locals 16.40 - execfile(defaults, globals, locals) 16.41 + try: 16.42 + execfile(defaults, globals, locals) 16.43 + except: 16.44 + if not help: raise 16.45 if help: return 16.46 # Extract the values set by the script and set the corresponding 16.47 # options, if not set on the command line.