bitkeeper revision 1.1051 (40ed377bW0cMKaeeMSXfQOknw3iMaw)

Documentation.
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2004-07-08 12:00:59 +00:00
1 parent e7b2e4a624
commit d18cda81eb
3 files changed
+221 -76

No files matched your search

+88 -20
View File
@@ -29,8 +29,12 @@ class BlkifControllerFactory(controller.ControllerFactory):
def createInstance(self, dom, recreate=0):
"""Create a block device controller for a domain.
dom domain
recreate if true it's a recreate (after xend restart)
@param dom: domain
@type dom: int
@param recreate: if true it's a recreate (after xend restart)
@type recreate: bool
@return: deferred
@rtype: twisted.internet.defer.Deferred
"""
d = defer.Deferred()
blkif = self.getInstanceByDom(dom)
@@ -51,9 +55,10 @@ class BlkifControllerFactory(controller.ControllerFactory):
def getDomainDevices(self, dom):
"""Get the block devices for a domain.
dom domain
returns devices
@param dom: domain
@type dom: int
@return: devices
@rtype: [device]
"""
blkif = self.getInstanceByDom(dom)
return (blkif and blkif.getDevices()) or []
@@ -61,10 +66,12 @@ class BlkifControllerFactory(controller.ControllerFactory):
def getDomainDevice(self, dom, vdev):
"""Get a block device from a domain.
dom domain
vdev device index
returns device
@param dom: domain
@type dom: int
@param vdev: device index
@type vedv: int
@return: device
@rtype: device
"""
blkif = self.getInstanceByDom(dom)
return (blkif and blkif.getDevice(vdev)) or None
@@ -72,8 +79,10 @@ class BlkifControllerFactory(controller.ControllerFactory):
def setControlDomain(self, dom, recreate=0):
"""Set the back-end block device controller domain.
dom domain
recreate if true it's a recreate (after xend restart)
@param dom: domain
@type dom: int
@param recreate: if true it's a recreate (after xend restart)
@type recreate: int
"""
if self.dom == dom: return
self.deregisterChannel()
@@ -84,14 +93,19 @@ class BlkifControllerFactory(controller.ControllerFactory):
def getControlDomain(self):
"""Get the back-end block device controller domain.
@return: domain
@rtype: int
"""
return self.dom
def reattachDevice(self, dom, vdev):
"""Reattach a device (on changing control domain).
dom domain
vdev device index
@param dom: domain
@type dom: int
@param vdev: device index
@type vdev: int
"""
blkif = self.getInstanceByDom(dom)
if blkif:
@@ -102,6 +116,9 @@ class BlkifControllerFactory(controller.ControllerFactory):
def devicesAttached(self):
"""Check if all devices are attached.
@return: true if all devices attached
@rtype: bool
"""
attached = 1
for blkif in self.getInstances():
@@ -111,19 +128,32 @@ class BlkifControllerFactory(controller.ControllerFactory):
return attached
def reattached(self):
"""Notify all block interface we have been reattached
"""Notify all block interfaces we have been reattached
(after changing control domain).
"""
for blkif in self.getInstances():
blkif.reattached()
def respond_be_create(self, msg, d):
"""Response handler for a be_create message.
Calls I{d} with the block interface created.
@param msg: message
@type msg: xu message
@param d: deferred to call
@type d: Deferred
"""
print 'respond_be_create>'
val = unpackMsg('blkif_be_create_t', msg)
blkif = self.getInstanceByDom(val['domid'])
d.callback(blkif)
def respond_be_connect(self, msg):
"""Response handler for a be_connect message.
@param msg: message
@type msg: xu message
"""
print 'respond_be_connect>', self
val = unpackMsg('blkif_be_connect_t', msg)
blkif = self.getInstanceByDom(val['domid'])
@@ -133,6 +163,15 @@ class BlkifControllerFactory(controller.ControllerFactory):
pass
def respond_be_vbd_create(self, msg, d):
"""Response handler for a be_vbd_create message.
Tries to grow the vbd, and passes the deferred I{d} on for
the grow to call.
@param msg: message
@type msg: xu message
@param d: deferred to call
@type d: Deferred
"""
print 'recv_be_vbd_create>', self
val = unpackMsg('blkif_be_vbd_create_t', msg)
blkif = self.getInstanceByDom(val['domid'])
@@ -145,6 +184,13 @@ class BlkifControllerFactory(controller.ControllerFactory):
pass
def respond_be_vbd_grow(self, msg, d):
"""Response handler for a be_vbd_grow message.
@param msg: message
@type msg: xu message
@param d: deferred to call
@type d: Deferred or None
"""
print 'recv_be_vbd_grow>', self
val = unpackMsg('blkif_be_vbd_grow_t', msg)
# Check status?
@@ -155,6 +201,13 @@ class BlkifControllerFactory(controller.ControllerFactory):
self.reattachDevice(val['domid'], val['vdevice'])
def recv_be_driver_status_changed(self, msg, req):
"""Request handler for be_driver_status_changed messages.
@param msg: message
@type msg: xu message
@param req: request flag (true if the msg is a request)
@type req: bool
"""
print 'recv_be_driver_status_changed>', self, req
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
status = val['status']
@@ -222,6 +275,17 @@ class BlkifController(controller.Controller):
return self.devices.get(vdev)
def addDevice(self, vdev, mode, segment):
"""Add a device to the device table.
@param vdev: device index
@type vdev: int
@param mode: read/write mode
@type mode: string
@param segment: segment
@type segment: int
@return: device
@rtype: BlkDev
"""
if vdev in self.devices: return None
dev = BlkDev(self, vdev, mode, segment)
self.devices[vdev] = dev
@@ -230,12 +294,16 @@ class BlkifController(controller.Controller):
def attachDevice(self, vdev, mode, segment, recreate=0):
"""Attach a device to the specified interface.
vdev device index
mode read/write mode
segment segment
recreate if true it's being recreated (after xend restart)
returns deferred
@param vdev: device index
@type vdev: int
@param mode: read/write mode
@type mode: string
@param segment: segment
@type segment: int
@param recreate: if true it's being recreated (after xend restart)
@type recreate: bool
@return: deferred
@rtype: Deferred
"""
dev = self.addDevice(vdev, mode, segment)
if not dev: return -1
+20 -6
View File
@@ -2,7 +2,7 @@
import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
from xen.lowlevel import xu
from messages import msgTypeName
from messages import msgTypeName, printMsg
VIRQ_MISDIRECT = 0 # Catch-all interrupt for unbound VIRQs.
VIRQ_TIMER = 1 # Timebase update, and/or requested timeout.
@@ -222,12 +222,18 @@ class Channel(BaseChannel):
def getLocalPort(self):
"""Get the local port.
@return: local port
@rtype: int
"""
if self.closed: return -1
return self.port.local_port
def getRemotePort(self):
"""Get the remote port.
@return: remote port
@rtype: int
"""
if self.closed: return -1
return self.port.remote_port
@@ -248,8 +254,9 @@ class Channel(BaseChannel):
def registerDevice(self, types, dev):
"""Register a device controller.
@param types message types the controller handles
@param dev device controller
@param types: message types the controller handles
@type types: array of ints
@param dev: device controller
"""
if self.closed: return
self.devs.append(dev)
@@ -259,7 +266,7 @@ class Channel(BaseChannel):
def deregisterDevice(self, dev):
"""Remove the registration for a device controller.
@param dev device controller
@param dev: device controller
"""
if dev in self.devs:
self.devs.remove(dev)
@@ -270,13 +277,20 @@ class Channel(BaseChannel):
def getDevice(self, type):
"""Get the device controller handling a message type.
@param type message type
@returns controller or None
@param type: message type
@type type: int
@return: controller or None
@rtype: device controller
"""
return self.devs_by_type.get(type)
def getMessageType(self, msg):
"""Get a 2-tuple of the message type and subtype.
@param msg: message
@type msg: xu message
@return: type info
@rtype: (int, int)
"""
hdr = msg.get_header()
return (hdr['type'], hdr.get('subtype'))
+113 -50
View File
@@ -1,53 +1,80 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
"""General support for controllers, which handle devices
for a domain.
"""
from twisted.internet import defer
defer.Deferred.debug = 1
import channel
from messages import msgTypeName
from messages import msgTypeName, printMsg
DEBUG=0
DEBUG = 0
class OutOfOrderError(RuntimeError):
"""Error reported when a response arrives out of order.
"""Error reported when a response message arrives out of order.
"""
pass
class Responder:
"""Handler for a response to a message.
"""Handler for a response to a message with a specified id.
"""
def __init__(self, mid, deferred):
"""Create a responder.
mid message id of response to handle
deferred deferred object holding the callbacks
@param mid: message id of response to handle
@type mid: int
@param deferred: deferred object holding the callbacks
@type deferred: Deferred
"""
self.mid = mid
self.deferred = deferred
def responseReceived(self, msg):
"""Entry point called when a response message with the right id arrives.
Calls callback on I{self.deferred} with the message.
@param msg: response message
@type msg: xu message
"""
if self.deferred.called: return
self.deferred.callback(msg)
def error(self, err):
"""Entry point called when there has been an error.
Calls errback on I{self.deferred} with the error.
@param err: error
@type err: Exception
"""
if self.deferred.called: return
self.deferred.errback(err)
class CtrlMsgRcvr:
"""Abstract class for things that deal with a control interface to a domain.
Once I{registerChannel} has been called, our message types are registered
with the channel to the domain. The channel will call I{requestReceived}
when a request arrives, or I{responseReceived} when a response arrives,
if they have one of our message types.
Instance variables:
dom : the domain we are a control interface for
majorTypes: list of major message types we are interested in
subTypes : mapping of message subtypes to methods
@ivar dom: the domain we are a control interface for
@type dom: int
@ivar majorTypes: major message types we are interested in
@type majorTypes: [int]
@ivar subTypes: mapping of message subtypes to methods
@ivar subTypes: {int:method}
@ivar timeout: timeout (in seconds) for message handlers
@type timeout: int
channel : channel to the domain
idx : channel index
@ivar channel: channel to the domain
@type channel: Channel
@ivar idx: channel index
@ivar idx: string
@ivar responders: table of message response handlers
@type responders: {int:Responder}
"""
def __init__(self):
self.channelFactory = channel.channelFactory()
self.majorTypes = [ ]
@@ -56,22 +83,25 @@ class CtrlMsgRcvr:
self.channel = None
self.idx = None
self.responders = []
# Timeout (in seconds) for deferreds.
self.timeout = 10
def setTimeout(self, timeout):
self.timeout = timeout
def requestReceived(self, msg, type, subtype):
"""Dispatch a request to handlers.
"""Dispatch a request message to handlers.
Called by the channel for requests with one of our types.
msg message
type major message type
subtype minor message type
@param msg: message
@type msg: xu message
@param type: major message type
@type type: int
@param subtype: minor message type
@type subtype: int
"""
msgid = msg.get_header()['id']
if DEBUG:
print 'requestReceived>', self, msgid, msgTypeName(type, subtype)
print 'requestReceived>',
printMsg(msg, all=1)
method = self.subTypes.get(subtype)
if method:
method(msg, 1)
@@ -81,14 +111,23 @@ class CtrlMsgRcvr:
def responseReceived(self, msg, type, subtype):
"""Dispatch a response to handlers.
Called by the channel for responses with one of our types.
First looks for a message responder for the message's id.
See L{callResponders}, L{addResponder}.
If there is no responder, looks for a message handler for
the message type/subtype.
msg message
type major message type
subtype minor message type
@param msg: message
@type msg: xu message
@param type: major message type
@type type: int
@param subtype: minor message type
@type subtype: int
"""
msgid = msg.get_header()['id']
if DEBUG:
print 'responseReceived>', self, msgid, msgTypeName(type, subtype)
print 'responseReceived>',
printMsg(msg, all=1)
if self.callResponders(msg):
return
method = self.subTypes.get(subtype)
@@ -100,16 +139,21 @@ class CtrlMsgRcvr:
def addResponder(self, mid, deferred):
"""Add a responder for a message id.
The deferred is called with callback(msg) when a response
with the given message id arrives. Responses are expected
The I{deferred} is called with callback(msg) when a response
with message id I{mid} arrives. Responses are expected
to arrive in order of message id. When a response arrives,
waiting responders for messages with lower id have errback
called with an OutOfOrder error.
mid message id of response expected
deferred a Deferred to handle the response
Responders have a timeout set and I{deferred} will error
on expiry.
returns Responder
@param mid: message id of response expected
@type mid: int
@param deferred: handler for the response
@type deferred: Deferred
@return: responder
@rtype: Responder
"""
if self.timeout > 0:
deferred.setTimeout(self.timeout)
@@ -119,10 +163,13 @@ class CtrlMsgRcvr:
def callResponders(self, msg):
"""Call any waiting responders for a response message.
Looks for a responder registered for the message's id.
See L{addResponder}.
msg response message
returns 1 if there was a responder for the message, 0 otherwise
@param msg: response message
@type msg: xu message
@return: 1 if there was a responder for the message, 0 otherwise
@rtype : bool
"""
hdr = msg.get_header()
mid = hdr['id']
@@ -133,7 +180,7 @@ class CtrlMsgRcvr:
break
self.responders.pop()
if resp.mid < mid:
print 'handleResponse> Out of order:', resp.mid, mid
print 'callResponders> Out of order:', resp.mid, mid
resp.error(OutOfOrderError())
else:
handled = 1
@@ -148,7 +195,8 @@ class CtrlMsgRcvr:
def registerChannel(self):
"""Register interest in our major message types with the
channel to our domain.
channel to our domain. Once we have registered, the channel
will call requestReceived or responseReceived for our messages.
"""
self.channel = self.channelFactory.domChannel(self.dom)
self.idx = self.channel.getIndex()
@@ -157,7 +205,8 @@ class CtrlMsgRcvr:
def deregisterChannel(self):
"""Deregister interest in our major message types with the
channel to our domain.
channel to our domain. After this the channel won't call
us any more.
"""
if self.channel:
self.channel.deregisterDevice(self)
@@ -166,18 +215,23 @@ class CtrlMsgRcvr:
def produceRequests(self):
"""Produce any queued requests.
return number produced
@return: number produced
@rtype: int
"""
return 0
def writeRequest(self, msg, response=None):
"""Write a request to the channel.
msg message
response Deferred to handle the response (optional)
@param msg: request message
@type msg: xu message
@param response: response handler
@type response: Deferred
"""
if self.channel:
if DEBUG: print 'CtrlMsgRcvr>writeRequest>', self, msg
if DEBUG:
print 'CtrlMsgRcvr>writeRequest>',
printMsg(msg, all=1)
if response:
self.addResponder(msg.get_header()['id'], response)
self.channel.writeRequest(msg)
@@ -185,29 +239,33 @@ class CtrlMsgRcvr:
print 'CtrlMsgRcvr>writeRequest>', 'no channel!', self
def writeResponse(self, msg):
"""Write a response to the channel.
"""Write a response to the channel. This acknowledges
a request message.
@param msg: message
@type msg: xu message
"""
if self.channel:
if DEBUG: print 'CtrlMsgRcvr>writeResponse>', self, msg
if DEBUG:
print 'CtrlMsgRcvr>writeResponse>',
printMsg(msg, all=0)
self.channel.writeResponse(msg)
else:
print 'CtrlMsgRcvr>writeResponse>', 'no channel!', self
class ControllerFactory(CtrlMsgRcvr):
"""Abstract class for factories creating controllers.
"""Abstract class for factories creating controllers for a domain.
Maintains a table of instances.
Instance variables:
instances : mapping of index to controller instance
dlist : list of deferreds
dom : domain
@ivar instances: mapping of index to controller instance
@type instances: {int: Controller}
@ivar dom: domain
@type dom: int
"""
def __init__(self):
CtrlMsgRcvr.__init__(self)
self.instances = {}
self.dlist = []
self.dom = 0
def addInstance(self, instance):
@@ -241,6 +299,11 @@ class ControllerFactory(CtrlMsgRcvr):
def createInstance(self, dom, recreate=0):
"""Create an instance. Define in a subclass.
@param dom: domain
@type dom: int
@param recreate: true if the instance is being recreated (after xend restart)
@type recreate: int
"""
raise NotImplementedError()
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.