bitkeeper revision 1.1159.38.1 (41231e93omwWBjFZGIgG3ek6UMbDYA)

Refactor device setup code so that the devices do more of
the messaging.
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2004-08-18 09:17:07 +00:00
1 parent 9589427638
commit 7166248ac4
8 files changed
+266 -365

No files matched your search

+6
View File
@@ -426,6 +426,12 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
C2P(netif_fe_interface_status_changed_t, status, Int, Long);
C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
C2P(netif_fe_interface_status_changed_t, mac[0], Int, Long);
C2P(netif_fe_interface_status_changed_t, mac[1], Int, Long);
C2P(netif_fe_interface_status_changed_t, mac[2], Int, Long);
C2P(netif_fe_interface_status_changed_t, mac[3], Int, Long);
C2P(netif_fe_interface_status_changed_t, mac[4], Int, Long);
C2P(netif_fe_interface_status_changed_t, mac[5], Int, Long);
return dict;
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
C2P(netif_fe_driver_status_changed_t, status, Int, Long);
+4 -4
View File
@@ -1074,8 +1074,8 @@ def vm_dev_vif(vm, val, index):
@param index: vif index
@return: deferred
"""
if vm.netif_backend:
raise VmError('vif: vif in netif backend domain')
#if vm.netif_backend:
# raise VmError('vif: vif in netif backend domain')
vif = vm.next_device_index('vif')
vmac = sxp.child_value(val, "mac")
backend = vm.get_device_backend('vif')
@@ -1098,8 +1098,8 @@ def vm_dev_vbd(vm, val, index):
@param index: vbd index
@return: deferred
"""
if vm.blkif_backend:
raise VmError('vbd: vbd in blkif backend domain')
#if vm.blkif_backend:
# raise VmError('vbd: vbd in blkif backend domain')
uname = sxp.child_value(val, 'uname')
if not uname:
raise VmError('vbd: Missing uname')
+15 -15
View File
@@ -48,7 +48,7 @@ class SrvDomain(SrvDir):
fn = FormFn(self.xd.domain_shutdown,
[['dom', 'str'],
['reason', 'str']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
req.setResponseCode(http.ACCEPTED)
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
@@ -57,7 +57,7 @@ class SrvDomain(SrvDir):
fn = FormFn(self.xd.domain_destroy,
[['dom', 'str'],
['reason', 'str']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
@@ -65,7 +65,7 @@ class SrvDomain(SrvDir):
fn = FormFn(self.xd.domain_save,
[['dom', 'str'],
['file', 'str']])
deferred = fn(req.args, {'dom': self.dom.name})
deferred = fn(req.args, {'dom': self.dom.id})
deferred.addCallback(self._op_save_cb, req)
deferred.addErrback(self._op_save_err, req)
return deferred
@@ -81,7 +81,7 @@ class SrvDomain(SrvDir):
fn = FormFn(self.xd.domain_migrate,
[['dom', 'str'],
['destination', 'str']])
deferred = fn(req.args, {'dom': self.dom.name})
deferred = fn(req.args, {'dom': self.dom.id})
print 'op_migrate>', deferred
deferred.addCallback(self._op_migrate_cb, req)
deferred.addErrback(self._op_migrate_err, req)
@@ -107,7 +107,7 @@ class SrvDomain(SrvDir):
fn = FormFn(self.xd.domain_pincpu,
[['dom', 'str'],
['cpu', 'int']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
return val
def op_cpu_bvt_set(self, op, req):
@@ -118,7 +118,7 @@ class SrvDomain(SrvDir):
['warpvalue', 'int'],
['warpl', 'long'],
['warpu', 'long']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
return val
def op_cpu_fbvt_set(self, op, req):
@@ -128,7 +128,7 @@ class SrvDomain(SrvDir):
['warp', 'int'],
['warpl', 'int'],
['warpu', 'int']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
return val
def op_cpu_atropos_set(self, op, req):
@@ -138,21 +138,21 @@ class SrvDomain(SrvDir):
['slice', 'int'],
['latency', 'int'],
['xtratime', 'int']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
return val
def op_maxmem_set(self, op, req):
fn = FormFn(self.xd.domain_maxmem_set,
[['dom', 'str'],
['memory', 'int']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
return val
def op_device_create(self, op, req):
fn = FormFn(self.xd.domain_device_create,
[['dom', 'str'],
['config', 'sxpr']])
d = fn(req.args, {'dom': self.dom.name})
d = fn(req.args, {'dom': self.dom.id})
return d
def op_device_destroy(self, op, req):
@@ -160,29 +160,29 @@ class SrvDomain(SrvDir):
[['dom', 'str'],
['type', 'str'],
['idx', 'str']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
return val
def op_vifs(self, op, req):
devs = self.xd.domain_vif_ls(self.dom.name)
devs = self.xd.domain_vif_ls(self.dom.id)
return [ dev.sxpr() for dev in devs ]
def op_vif(self, op, req):
fn = FormFn(self.xd.domain_vif_get,
[['dom', 'str'],
['vif', 'str']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
return val
def op_vbds(self, op, req):
devs = self.xd.domain_vbd_ls(self.dom.name)
devs = self.xd.domain_vbd_ls(self.dom.id)
return [ dev.sxpr() for dev in devs ]
def op_vbd(self, op, req):
fn = FormFn(self.xd.domain_vbd_get,
[['dom', 'str'],
['vbd', 'str']])
val = fn(req.args, {'dom': self.dom.name})
val = fn(req.args, {'dom': self.dom.id})
return val
def render_POST(self, req):
+152 -236
View File
@@ -22,74 +22,7 @@ class BlkifBackendController(controller.BackendController):
self.addMethod(CMSG_BLKIF_BE,
CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
self.recv_be_driver_status_changed)
self.attached = 1
self.registerChannel()
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
"""
val = unpackMsg('blkif_be_create_t', msg)
blkif = self.factory.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
"""
val = unpackMsg('blkif_be_connect_t', msg)
blkif = self.factory.getInstanceByDom(val['domid'])
if blkif:
blkif.send_fe_interface_status_changed()
else:
pass
def respond_be_vbd_create(self, msg, dev, 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 dev: device
@type dev: BlkDev
@param d: deferred to call
@type d: Deferred
"""
val = unpackMsg('blkif_be_vbd_create_t', msg)
blkif = self.factory.getInstanceByDom(val['domid'])
if blkif:
d1 = defer.Deferred()
d1.addCallback(self.respond_be_vbd_grow, dev, d)
if d: d1.addErrback(d.errback)
blkif.send_be_vbd_grow(val['vdevice'], response=d1)
else:
pass
def respond_be_vbd_grow(self, msg, dev, d):
"""Response handler for a be_vbd_grow message.
@param msg: message
@type msg: xu message
@param dev: device
@type dev: BlkDev
@param d: deferred to call
@type d: Deferred or None
"""
val = unpackMsg('blkif_be_vbd_grow_t', msg)
status = val['status']
if status != BLKIF_BE_STATUS_OKAY:
raise XendError("Adding extent to vbd failed: device %x, error %d"
% (val['extent.device'], status))
if d:
d.callback(dev)
def recv_be_driver_status_changed(self, msg, req):
"""Request handler for be_driver_status_changed messages.
@@ -101,11 +34,6 @@ class BlkifBackendController(controller.BackendController):
"""
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
status = val['status']
if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
for blkif in self.factory.getInstances():
if blkif.backendController == self:
blkif.detach()
class BlkifControllerFactory(controller.SplitControllerFactory):
"""Factory for creating block device interface controllers.
@@ -113,7 +41,6 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
def __init__(self):
controller.SplitControllerFactory.__init__(self)
self.attached = 1
def createInstance(self, dom, recreate=0, backend=0):
"""Create a block device controller for a domain.
@@ -125,20 +52,14 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
@return: deferred
@rtype: twisted.internet.defer.Deferred
"""
d = defer.Deferred()
blkif = self.getInstanceByDom(dom)
if blkif:
d = defer.Deferred()
d.callback(blkif)
else:
blkif = BlkifController(self, dom, backend)
self.addInstance(blkif)
if recreate:
d.callback(blkif)
else:
d1 = defer.Deferred()
d1.addCallback(blkif.backendController.respond_be_create, d)
d1.addErrback(d.errback)
blkif.send_be_create(response=d1)
d = blkif.connect(recreate=recreate)
return d
def getDomainDevices(self, dom):
@@ -158,7 +79,7 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
@param dom: domain
@type dom: int
@param vdev: device index
@type vedv: int
@type vdev: int
@return: device
@rtype: device
"""
@@ -168,66 +89,6 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
def createBackendController(self, dom):
return BlkifBackendController(self, dom)
def setControlDomain(self, dom, recreate=0):
"""Set the back-end block device controller domain.
@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()
if not recreate:
self.attached = 0
self.dom = dom
self.registerChannel()
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).
@param dom: domain
@type dom: int
@param vdev: device index
@type vdev: int
"""
blkif = self.getInstanceByDom(dom)
if blkif:
blkif.reattachDevice(vdev)
self.attached = self.devicesAttached()
if self.attached:
self.reattached()
def devicesAttached(self):
"""Check if all devices are attached.
@return: true if all devices attached
@rtype: bool
"""
attached = 1
for blkif in self.getInstances():
if not blkif.attached:
attached = 0
break
return attached
def reattached(self):
"""Notify all block interfaces we have been reattached
(after changing control domain).
"""
for blkif in self.getInstances():
blkif.reattached()
class BlkDev(controller.Dev):
"""Info record for a block device.
"""
@@ -241,7 +102,9 @@ class BlkDev(controller.Dev):
self.device = segment['device']
self.start_sector = segment['start_sector']
self.nr_sectors = segment['nr_sectors']
self.attached = 1
def getBackendController(self):
return self.controller.backendController
def readonly(self):
return 'w' not in self.mode
@@ -260,7 +123,80 @@ class BlkDev(controller.Dev):
def destroy(self):
log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
self.controller.send_be_vbd_destroy(self.vdev)
self.send_be_vbd_destroy()
def attach(self, d):
"""Attach the device to its controller.
@param d: deferred to call with the device on success
"""
d1 = defer.Deferred()
d1.addCallback(self.respond_be_vbd_create, d)
d1.addErrback(d.errback)
self.send_be_vbd_create(response=d1)
def send_be_vbd_create(self, response=None):
msg = packMsg('blkif_be_vbd_create_t',
{ 'domid' : self.controller.dom,
'blkif_handle' : self.controller.handle,
'vdevice' : self.vdev,
'readonly' : self.readonly() })
self.getBackendController().writeRequest(msg, response=response)
def respond_be_vbd_create(self, msg, d):
"""Response handler for a be_vbd_create message.
Tries to grow the vbd.
@param msg: message
@type msg: xu message
@param d: deferred to call
@type d: Deferred
"""
val = unpackMsg('blkif_be_vbd_create_t', msg)
d1 = defer.Deferred()
d1.addCallback(self.respond_be_vbd_grow, d)
if d: d1.addErrback(d.errback)
self.send_be_vbd_grow(response=d1)
def send_be_vbd_grow(self, response=None):
msg = packMsg('blkif_be_vbd_grow_t',
{ 'domid' : self.controller.dom,
'blkif_handle' : self.controller.handle,
'vdevice' : self.vdev,
'extent.device' : self.device,
'extent.sector_start' : self.start_sector,
'extent.sector_length' : self.nr_sectors })
self.getBackendController().writeRequest(msg, response=response)
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
"""
val = unpackMsg('blkif_be_vbd_grow_t', msg)
status = val['status']
if status != BLKIF_BE_STATUS_OKAY:
err = XendError("Adding extent to vbd failed: device %d, error %d"
% (self.vdev, status))
#if(d):
# d.errback(err)
raise err
if d:
d.callback(self)
def send_be_vbd_destroy(self, response=None):
log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d',
self.controller.dom, self.vdev)
msg = packMsg('blkif_be_vbd_destroy_t',
{ 'domid' : self.controller.dom,
'blkif_handle' : self.controller.handle,
'vdevice' : self.vdev })
self.controller.delDevice(self.vdev)
self.getBackendController().writeRequest(msg, response=response)
class BlkifController(controller.SplitController):
"""Block device interface controller. Handles all block devices
@@ -268,6 +204,10 @@ class BlkifController(controller.SplitController):
"""
def __init__(self, factory, dom, backend):
"""Create a block device controller.
The controller must be connected using connect() before it can be used.
Do not call directly - use createInstance() on the factory instead.
"""
controller.SplitController.__init__(self, factory, dom, backend)
self.devices = {}
self.addMethod(CMSG_BLKIF_FE,
@@ -276,7 +216,7 @@ class BlkifController(controller.SplitController):
self.addMethod(CMSG_BLKIF_FE,
CMSG_BLKIF_FE_INTERFACE_CONNECT,
self.recv_fe_interface_connect)
self.attached = 1
self.handle = 0
self.evtchn = None
self.registerChannel()
@@ -311,6 +251,10 @@ class BlkifController(controller.SplitController):
self.devices[vdev] = dev
return dev
def delDevice(self, vdev):
if vdev in self.devices:
del self.devices[vdev]
def attachDevice(self, vdev, mode, segment, recreate=0):
"""Attach a device to the specified interface.
On success the returned deferred will be called with the device.
@@ -332,63 +276,75 @@ class BlkifController(controller.SplitController):
if recreate:
d.callback(dev)
else:
d1 = defer.Deferred()
d1.addCallback(self.backendController.respond_be_vbd_create, dev, d)
d1.addErrback(d.errback)
self.send_be_vbd_create(vdev, response=d1)
dev.attach(d)
return d
def destroy(self):
def cb_destroy(val):
self.send_be_destroy()
"""Destroy the controller and all devices.
"""
log.debug("Destroying blkif domain=%d", self.dom)
d = defer.Deferred()
d.addCallback(cb_destroy)
self.send_be_disconnect(response=d)
self.destroyDevices()
self.disconnect()
def destroyDevices(self):
"""Destroy all devices.
"""
for dev in self.getDevices():
dev.destroy()
def detach(self):
"""Detach all devices, when the back-end control domain has changed.
"""
self.attached = 0
for dev in self.devices.values():
dev.attached = 0
d1 = defer.Deferred()
d1.addCallback(self.backendController.respond_be_vbd_create, None, None)
self.send_be_vbd_create(vdev, response=d1)
def connect(self, recreate=0):
"""Connect the controller to the blkif control interface.
def reattachDevice(self, vdev):
"""Reattach a device, when the back-end control domain has changed.
@param recreate: true if after xend restart
@return: deferred
"""
dev = self.devices[vdev]
dev.attached = 1
attached = 1
for dev in self.devices.values():
if not dev.attached:
attached = 0
break
self.attached = attached
return self.attached
def reattached(self):
"""All devices have been reattached after the back-end control
domain has changed.
log.debug("Connecting blkif domain=%d", self.dom)
d = defer.Deferred()
if recreate:
d.callback(self)
else:
def cbresp(msg):
return self
d.addCallback(cbresp)
self.send_be_create(response=d)
return d
def send_be_create(self, response=None):
msg = packMsg('blkif_be_create_t',
{ 'domid' : self.dom,
'blkif_handle' : self.handle })
self.backendController.writeRequest(msg, response=response)
def disconnect(self):
"""Disconnect from the blkif control interface and destroy it.
"""
msg = packMsg('blkif_fe_interface_status_changed_t',
{ 'handle' : 0,
'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED})
self.writeRequest(msg)
def cb_destroy(val):
self.send_be_destroy()
d = defer.Deferred()
d.addCallback(cb_destroy)
self.send_be_disconnect(response=d)
def send_be_disconnect(self, response=None):
log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
msg = packMsg('blkif_be_disconnect_t',
{ 'domid' : self.dom,
'blkif_handle' : self.handle })
self.backendController.writeRequest(msg, response=response)
def send_be_destroy(self, response=None):
log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
msg = packMsg('blkif_be_destroy_t',
{ 'domid' : self.dom,
'blkif_handle' : self.handle })
self.backendController.writeRequest(msg, response=response)
def recv_fe_driver_status_changed(self, msg, req):
msg = packMsg('blkif_fe_interface_status_changed_t',
{ 'handle' : 0,
{ 'handle' : self.handle,
'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
'evtchn' : 0 })
self.writeRequest(msg)
def recv_fe_interface_connect(self, msg, req):
val = unpackMsg('blkif_fe_interface_connect_t', msg)
self.evtchn = channel.eventChannel(0, self.dom)
@@ -400,63 +356,23 @@ class BlkifController(controller.SplitController):
'evtchn' : self.evtchn['port1'],
'shmem_frame' : val['shmem_frame'] })
d = defer.Deferred()
d.addCallback(self.backendController.respond_be_connect)
d.addCallback(self.respond_be_connect)
self.backendController.writeRequest(msg, response=d)
def respond_be_connect(self, msg):
"""Response handler for a be_connect message.
@param msg: message
@type msg: xu message
"""
val = unpackMsg('blkif_be_connect_t', msg)
self.send_fe_interface_status_changed()
def send_fe_interface_status_changed(self, response=None):
msg = packMsg('blkif_fe_interface_status_changed_t',
{ 'handle' : 0,
{ 'handle' : self.handle,
'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
'evtchn' : self.evtchn['port2'] })
self.writeRequest(msg, response=response)
def send_be_create(self, response=None):
msg = packMsg('blkif_be_create_t',
{ 'domid' : self.dom,
'blkif_handle' : 0 })
self.backendController.writeRequest(msg, response=response)
def send_be_disconnect(self, response=None):
log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
msg = packMsg('blkif_be_disconnect_t',
{ 'domid' : self.dom,
'blkif_handle' : 0 })
self.backendController.writeRequest(msg, response=response)
def send_be_destroy(self, response=None):
log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
msg = packMsg('blkif_be_destroy_t',
{ 'domid' : self.dom,
'blkif_handle' : 0 })
self.backendController.writeRequest(msg, response=response)
def send_be_vbd_create(self, vdev, response=None):
dev = self.devices[vdev]
msg = packMsg('blkif_be_vbd_create_t',
{ 'domid' : self.dom,
'blkif_handle' : 0,
'vdevice' : dev.vdev,
'readonly' : dev.readonly() })
self.backendController.writeRequest(msg, response=response)
def send_be_vbd_grow(self, vdev, response=None):
dev = self.devices[vdev]
msg = packMsg('blkif_be_vbd_grow_t',
{ 'domid' : self.dom,
'blkif_handle' : 0,
'vdevice' : dev.vdev,
'extent.device' : dev.device,
'extent.sector_start' : dev.start_sector,
'extent.sector_length' : dev.nr_sectors })
self.backendController.writeRequest(msg, response=response)
def send_be_vbd_destroy(self, vdev, response=None):
log.debug('>BlkifController>send_be_vbd_destroy> dom=%d vdev=%d', self.dom, vdev)
dev = self.devices[vdev]
msg = packMsg('blkif_be_vbd_destroy_t',
{ 'domid' : self.dom,
'blkif_handle' : 0,
'vdevice' : dev.vdev })
del self.devices[vdev]
self.backendController.writeRequest(msg, response=response)
+4 -2
View File
@@ -333,13 +333,15 @@ class Channel(BaseChannel):
(ty, subty) = self.getMessageType(msg)
#todo: Must respond before writing any more messages.
#todo: Should automate this (respond on write)
self.port.write_response(msg)
responded = 0
dev = self.getDevice(ty)
if dev:
dev.requestReceived(msg, ty, subty)
responded = dev.requestReceived(msg, ty, subty)
else:
print ("requestReceived> No device: Message type %s %d:%d"
% (msgTypeName(ty, subty), ty, subty)), self
if not responded:
self.port.write_response(msg)
def handleResponses(self):
work = 0
+3 -1
View File
@@ -125,12 +125,14 @@ class CtrlMsgRcvr:
if DEBUG:
print 'requestReceived>',
printMsg(msg, all=1)
responded = 0
method = self.getMethod(type, subtype)
if method:
method(msg, 1)
responded = method(msg, 1)
elif DEBUG:
print ('requestReceived> No handler: Message type %s %d:%d'
% (msgTypeName(type, subtype), type, subtype)), self
return responded
def responseReceived(self, msg, type, subtype):
"""Dispatch a response to handlers.
+4 -3
View File
@@ -215,7 +215,7 @@ def packMsg(ty, params):
else:
args[k] = v
msg = xu.message(major, minor, msgid, args)
if DEBUG: print '<packMsg', msg.get_header()['id'], ty, params
if DEBUG: print '<packMsg', msg.get_header()['id'], ty, args
return msg
def unpackMsg(ty, msg):
@@ -231,8 +231,9 @@ def unpackMsg(ty, msg):
@rtype: dict
"""
args = msg.get_payload()
if DEBUG: print '>unpackMsg', args
if isinstance(args, types.StringType):
args = { 'value': args }
args = {'value': args}
else:
mac = [0, 0, 0, 0, 0, 0]
macs = []
@@ -284,5 +285,5 @@ def printMsg(msg, out=sys.stdout, all=0):
ty = msgTypeName(major, minor)
print >>out, 'message:', 'type=', ty, '%d:%d' % (major, minor), 'id=%d' % msgid
if all:
print >>out, 'payload=', unpackMsg(ty, msg)
print >>out, 'payload=', msg.get_payload()
+78 -104
View File
@@ -27,30 +27,11 @@ class NetifBackendController(controller.BackendController):
self.addMethod(CMSG_NETIF_BE,
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
self.recv_be_driver_status_changed)
self.attached = 1
self.registerChannel()
def respond_be_connect(self, msg):
val = unpackMsg('netif_be_connect_t', msg)
dom = val['domid']
vif = val['netif_handle']
netif = self.factory.getInstanceByDom(dom)
if netif:
netif.send_interface_connected(vif)
else:
log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif)
pass
def recv_be_driver_status_changed(self, msg, req):
val = unpackMsg('netif_be_driver_status_changed_t', msg)
status = val['status']
if status == NETIF_DRIVER_STATUS_UP and not self.attached:
# If we are not attached the driver domain was changed, and
# this signals the new driver domain is ready.
for netif in self.factory.getInstances():
if netif.backendController == self:
netif.reattach_devices()
self.attached = 1
class NetifControllerFactory(controller.SplitControllerFactory):
"""Factory for creating network interface controllers.
@@ -58,7 +39,6 @@ class NetifControllerFactory(controller.SplitControllerFactory):
def __init__(self):
controller.ControllerFactory.__init__(self)
self.attached = 1
def createInstance(self, dom, recreate=0, backend=0):
"""Create or find the network interface controller for a domain.
@@ -95,26 +75,6 @@ class NetifControllerFactory(controller.SplitControllerFactory):
def createBackendController(self, dom):
return NetifBackendController(self, dom)
def setControlDomain(self, dom, recreate=0):
"""Set the 'back-end' device driver domain.
@param dom: domain
@param recreate: if true this is a recreate (xend restarted)
"""
if self.dom == dom: return
self.deregisterChannel()
if not recreate:
self.attached = 0
self.dom = dom
self.registerChannel()
def getControlDomain(self):
"""Get the domain id of the back-end control domain.
@return domain id
"""
return self.dom
class NetDev(controller.Dev):
"""Info record for a network device.
"""
@@ -125,6 +85,9 @@ class NetDev(controller.Dev):
self.evtchn = None
self.configure(config)
def getBackendController(self):
return self.controller.backendController
def configure(self, config):
self.config = config
self.mac = None
@@ -205,19 +168,76 @@ class NetDev(controller.Dev):
if vnet:
vnet.vifctl(op, self.get_vifname(), self.get_mac())
def attach(self, d):
print 'attach>', d
self.send_be_create(response=d)
def send_be_create(self, response=None):
msg = packMsg('netif_be_create_t',
{ 'domid' : self.controller.dom,
'netif_handle' : self.vif,
'mac' : self.mac })
self.getBackendController().writeRequest(msg, response=response)
def destroy(self):
"""Destroy the device's resources and disconnect from the back-end
device controller.
"""
def cb_destroy(val):
self.controller.send_be_destroy(self.vif)
self.send_be_destroy()
log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
self.vifctl('down')
d = defer.Deferred()
d.addCallback(cb_destroy)
self.controller.send_be_disconnect(self.vif, response=d)
self.send_be_disconnect(response=d)
def send_be_disconnect(self, response=None):
msg = packMsg('netif_be_disconnect_t',
{ 'domid' : self.controller.dom,
'netif_handle' : self.vif })
self.getBackendController().writeRequest(msg, response=response)
def send_be_destroy(self, response=None):
msg = packMsg('netif_be_destroy_t',
{ 'domid' : self.controller.dom,
'netif_handle' : self.vif })
self.controller.delDevice(self.vif)
self.getBackendController().writeRequest(msg, response=response)
def recv_fe_interface_connect(self, val, req):
if not req: return
self.evtchn = channel.eventChannel(0, self.controller.dom)
msg = packMsg('netif_be_connect_t',
{ 'domid' : self.controller.dom,
'netif_handle' : self.vif,
'evtchn' : self.evtchn['port1'],
'tx_shmem_frame' : val['tx_shmem_frame'],
'rx_shmem_frame' : val['rx_shmem_frame'] })
d = defer.Deferred()
d.addCallback(self.respond_be_connect)
self.getBackendController().writeRequest(msg, response=d)
def respond_be_connect(self, msg):
val = unpackMsg('netif_be_connect_t', msg)
dom = val['domid']
vif = val['netif_handle']
print 'respond_be_connect>', ' dom=', dom, ' vif=', vif
print 'respond_be_connect>', 'self.dom=', self.controller.dom, 'self.vif=', self.vif
msg = packMsg('netif_fe_interface_status_changed_t',
{ 'handle' : self.vif,
'status' : NETIF_INTERFACE_STATUS_CONNECTED,
'evtchn' : self.evtchn['port2'],
'mac' : self.mac })
self.controller.writeRequest(msg)
def attach_fe_device(self):
msg = packMsg('netif_fe_interface_status_changed_t',
{ 'handle' : self.vif,
'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
'evtchn' : 0,
'mac' : self.mac })
self.controller.writeRequest(msg)
class NetifController(controller.SplitController):
"""Network interface controller. Handles all network devices for a domain.
"""
@@ -266,6 +286,10 @@ class NetifController(controller.SplitController):
self.devices[vif] = dev
return dev
def delDevice(self, vif):
if vif in self.devices:
del self.devices[vif]
def destroy(self):
"""Destroy the controller and all devices.
"""
@@ -285,79 +309,29 @@ class NetifController(controller.SplitController):
@param recreate: recreate flag (true after xend restart)
@return: deferred
"""
self.addDevice(vif, config)
dev = self.addDevice(vif, config)
d = defer.Deferred()
if recreate:
d.callback(self)
else:
self.send_be_create(vif, response=d)
dev.attach(d)
return d
def reattach_devices(self):
"""Reattach all devices when the back-end control domain has changed.
"""
self.send_be_create(vif)
self.attach_fe_devices()
def attach_fe_devices(self):
for dev in self.devices.values():
msg = packMsg('netif_fe_interface_status_changed_t',
{ 'handle' : dev.vif,
'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
'evtchn' : 0,
'mac' : dev.mac })
self.writeRequest(msg)
def recv_fe_driver_status_changed(self, msg, req):
if not req: return
msg = packMsg('netif_fe_driver_status_changed_t',
{ 'status' : NETIF_DRIVER_STATUS_UP,
'nr_interfaces' : len(self.devices) })
self.writeRequest(msg)
self.attach_fe_devices()
for dev in self.devices.values():
dev.attach_fe_device()
def recv_fe_interface_connect(self, msg, req):
val = unpackMsg('netif_fe_interface_connect_t', msg)
dev = self.devices[val['handle']]
dev.evtchn = channel.eventChannel(0, self.dom)
msg = packMsg('netif_be_connect_t',
{ 'domid' : self.dom,
'netif_handle' : dev.vif,
'evtchn' : dev.evtchn['port1'],
'tx_shmem_frame' : val['tx_shmem_frame'],
'rx_shmem_frame' : val['rx_shmem_frame'] })
d = defer.Deferred()
d.addCallback(self.backendController.respond_be_connect)
self.backendController.writeRequest(msg, response=d)
vif = val['handle']
dev = self.devices.get(vif)
if dev:
dev.recv_fe_interface_connect(val, req)
else:
log.error('Received netif_fe_interface_connect for unknown vif: '+vif)
def send_interface_connected(self, vif, response=None):
dev = self.devices[vif]
msg = packMsg('netif_fe_interface_status_changed_t',
{ 'handle' : dev.vif,
'status' : NETIF_INTERFACE_STATUS_CONNECTED,
'evtchn' : dev.evtchn['port2'],
'mac' : dev.mac })
self.writeRequest(msg, response=response)
def send_be_create(self, vif, response=None):
dev = self.devices[vif]
msg = packMsg('netif_be_create_t',
{ 'domid' : self.dom,
'netif_handle' : dev.vif,
'mac' : dev.mac })
self.backendController.writeRequest(msg, response=response)
def send_be_disconnect(self, vif, response=None):
dev = self.devices[vif]
msg = packMsg('netif_be_disconnect_t',
{ 'domid' : self.dom,
'netif_handle' : dev.vif })
self.backendController.writeRequest(msg, response=response)
def send_be_destroy(self, vif, response=None):
dev = self.devices[vif]
del self.devices[vif]
msg = packMsg('netif_be_destroy_t',
{ 'domid' : self.dom,
'netif_handle' : vif })
self.backendController.writeRequest(msg, response=response)
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.