mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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:
1 parent
9589427638
commit
7166248ac4
8 files changed
+266
-365
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||