bitkeeper revision 1.1159.82.1 (4152d2abNRTmjgcJM5fkbYQyAoi9pA)

Change device messaging to support adding netifs at runtime,
and to support front-end polling.
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2004-09-23 13:42:03 +00:00
1 parent e9bdcef227
commit 946648e0db
12 files changed
+852 -523

No files matched your search

+46 -46
View File
@@ -324,11 +324,11 @@ static PyObject *xu_message_set_response_fields(PyObject *self, PyObject *args)
switch ( TYPE(xum->msg.type, xum->msg.subtype) )
{
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
P2C(blkif_fe_driver_status_changed_t, max_handle, u32);
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS):
P2C(blkif_fe_driver_status_t, max_handle, u32);
break;
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
P2C(netif_fe_driver_status_changed_t, max_handle, u32);
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
P2C(netif_fe_driver_status_t, max_handle, u32);
break;
}
@@ -352,13 +352,13 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
switch ( TYPE(xum->msg.type, xum->msg.subtype) )
{
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
C2P(blkif_fe_interface_status_changed_t, handle, Int, Long);
C2P(blkif_fe_interface_status_changed_t, status, Int, Long);
C2P(blkif_fe_interface_status_changed_t, evtchn, Int, Long);
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS):
C2P(blkif_fe_interface_status_t, handle, Int, Long);
C2P(blkif_fe_interface_status_t, status, Int, Long);
C2P(blkif_fe_interface_status_t, evtchn, Int, Long);
return dict;
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
C2P(blkif_fe_driver_status_changed_t, status, Int, Long);
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS):
C2P(blkif_fe_driver_status_t, status, Int, Long);
return dict;
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT):
C2P(blkif_fe_interface_connect_t, handle, Int, Long);
@@ -419,23 +419,23 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
C2P(blkif_be_vbd_shrink_t, vdevice, Int, Long);
C2P(blkif_be_vbd_shrink_t, status, Int, Long);
return dict;
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED):
C2P(blkif_be_driver_status_changed_t, status, Int, Long);
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS):
C2P(blkif_be_driver_status_t, status, Int, Long);
return dict;
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
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);
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS):
C2P(netif_fe_interface_status_t, handle, Int, Long);
C2P(netif_fe_interface_status_t, status, Int, Long);
C2P(netif_fe_interface_status_t, evtchn, Int, Long);
C2P(netif_fe_interface_status_t, mac[0], Int, Long);
C2P(netif_fe_interface_status_t, mac[1], Int, Long);
C2P(netif_fe_interface_status_t, mac[2], Int, Long);
C2P(netif_fe_interface_status_t, mac[3], Int, Long);
C2P(netif_fe_interface_status_t, mac[4], Int, Long);
C2P(netif_fe_interface_status_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);
C2P(netif_fe_driver_status_changed_t, max_handle, Int, Long);
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
C2P(netif_fe_driver_status_t, status, Int, Long);
C2P(netif_fe_driver_status_t, max_handle, Int, Long);
return dict;
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT):
C2P(netif_fe_interface_connect_t, handle, Int, Long);
@@ -468,8 +468,8 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
C2P(netif_be_disconnect_t, netif_handle, Int, Long);
C2P(netif_be_disconnect_t, status, Int, Long);
return dict;
case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED):
C2P(netif_be_driver_status_changed_t, status, Int, Long);
case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS):
C2P(netif_be_driver_status_t, status, Int, Long);
return dict;
}
@@ -543,11 +543,11 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args)
switch ( TYPE(type, subtype) )
{
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
P2C(blkif_fe_interface_status_changed_t, handle, u32);
P2C(blkif_fe_interface_status_changed_t, status, u32);
P2C(blkif_fe_interface_status_changed_t, evtchn, u16);
P2C(blkif_fe_interface_status_changed_t, domid, u16);
case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS):
P2C(blkif_fe_interface_status_t, handle, u32);
P2C(blkif_fe_interface_status_t, status, u32);
P2C(blkif_fe_interface_status_t, evtchn, u16);
P2C(blkif_fe_interface_status_t, domid, u16);
break;
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
P2C(blkif_be_create_t, domid, u32);
@@ -591,17 +591,17 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args)
P2C(blkif_be_vbd_shrink_t, blkif_handle, u32);
P2C(blkif_be_vbd_shrink_t, vdevice, blkif_vdev_t);
break;
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
P2C(netif_fe_interface_status_changed_t, handle, u32);
P2C(netif_fe_interface_status_changed_t, status, u32);
P2C(netif_fe_interface_status_changed_t, evtchn, u16);
P2C(netif_fe_interface_status_changed_t, domid, u16);
P2C(netif_fe_interface_status_changed_t, mac[0], u8);
P2C(netif_fe_interface_status_changed_t, mac[1], u8);
P2C(netif_fe_interface_status_changed_t, mac[2], u8);
P2C(netif_fe_interface_status_changed_t, mac[3], u8);
P2C(netif_fe_interface_status_changed_t, mac[4], u8);
P2C(netif_fe_interface_status_changed_t, mac[5], u8);
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS):
P2C(netif_fe_interface_status_t, handle, u32);
P2C(netif_fe_interface_status_t, status, u32);
P2C(netif_fe_interface_status_t, evtchn, u16);
P2C(netif_fe_interface_status_t, domid, u16);
P2C(netif_fe_interface_status_t, mac[0], u8);
P2C(netif_fe_interface_status_t, mac[1], u8);
P2C(netif_fe_interface_status_t, mac[2], u8);
P2C(netif_fe_interface_status_t, mac[3], u8);
P2C(netif_fe_interface_status_t, mac[4], u8);
P2C(netif_fe_interface_status_t, mac[5], u8);
break;
case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
P2C(netif_be_create_t, domid, u32);
@@ -628,9 +628,9 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args)
P2C(netif_be_disconnect_t, domid, u32);
P2C(netif_be_disconnect_t, netif_handle, u32);
break;
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
P2C(netif_fe_driver_status_changed_t, status, u32);
P2C(netif_fe_driver_status_changed_t, max_handle, u32);
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS):
P2C(netif_fe_driver_status_t, status, u32);
P2C(netif_fe_driver_status_t, max_handle, u32);
break;
}
+4 -4
View File
@@ -239,14 +239,14 @@ class XendDomain:
destroyed = 0
for d in casualties:
id = str(d['dom'])
log.debug('XendDomain>reap> domain died id=%s', id)
dominfo = self.domain_by_id.get(id)
name = (dominfo and dominfo.name) or '??'
log.debug('XendDomain>reap> domain died name=%s id=%s', name, id)
if d['shutdown']:
reason = XendDomainInfo.shutdown_reason(d['shutdown_reason'])
log.debug('XendDomain>reap> shutdown id=%s reason=%s', id, reason)
dominfo = self.domain_by_id.get(id)
name = (dominfo and dominfo.name) or '??'
if reason in ['suspend']:
if dominfo.is_terminated():
if dominfo and dominfo.is_terminated():
log.debug('XendDomain>reap> Suspended domain died id=%s', id)
else:
eserver.inject('xend.domain.suspended', [name, id])
+2 -1
View File
@@ -155,6 +155,7 @@ def make_disk(vm, config, uname, dev, mode, recreate=0):
@param recreate: recreate flag (after xend restart)
@return: deferred
"""
idx = vm.next_device_index('vbd')
segments = lookup_disk_uname(uname)
if not segments:
raise VmError("vbd: Segments not found: uname=%s" % uname)
@@ -166,7 +167,7 @@ def make_disk(vm, config, uname, dev, mode, recreate=0):
if not vdev:
raise VmError("vbd: Device not found: uname=%s dev=%s" % (uname, dev))
ctrl = xend.blkif_create(vm.dom, recreate=recreate)
return ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
return ctrl.attachDevice(idx, config, vdev, mode, segment, recreate=recreate)
def vif_up(iplist):
"""send an unsolicited ARP reply for all non link-local IP addresses.
+52 -48
View File
@@ -19,19 +19,19 @@ class BlkifBackendController(controller.BackendController):
def __init__(self, factory, dom):
controller.BackendController.__init__(self, factory, dom)
self.addMethod(CMSG_BLKIF_BE,
CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
self.recv_be_driver_status_changed)
CMSG_BLKIF_BE_DRIVER_STATUS,
self.recv_be_driver_status)
self.registerChannel()
def recv_be_driver_status_changed(self, msg, req):
"""Request handler for be_driver_status_changed messages.
def recv_be_driver_status(self, msg, req):
"""Request handler for be_driver_status messages.
@param msg: message
@type msg: xu message
@param req: request flag (true if the msg is a request)
@type req: bool
"""
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
val = unpackMsg('blkif_be_driver_status_t', msg)
status = val['status']
class BlkifBackendInterface(controller.BackendInterface):
@@ -45,10 +45,23 @@ class BlkifBackendInterface(controller.BackendInterface):
controller.BackendInterface.__init__(self, ctrl, dom, handle)
self.connected = 0
self.evtchn = None
self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
def __str__(self):
return '<BlkifBackendInterface %d %d>' % (self.controller.dom, self.dom)
def getEventChannelBackend(self):
val = 0
if self.evtchn:
val = self.evtchn['port1']
return val
def getEventChannelFrontend(self):
val = 0
if self.evtchn:
val = self.evtchn['port2']
return val
def connect(self, recreate=0):
"""Connect to the blkif control interface.
@@ -105,7 +118,7 @@ class BlkifBackendInterface(controller.BackendInterface):
msg = packMsg('blkif_be_connect_t',
{ 'domid' : self.controller.dom,
'blkif_handle' : self.handle,
'evtchn' : self.evtchn['port1'],
'evtchn' : self.getEventChannelBackend(),
'shmem_frame' : val['shmem_frame'] })
d = defer.Deferred()
d.addCallback(self.respond_be_connect)
@@ -118,31 +131,29 @@ class BlkifBackendInterface(controller.BackendInterface):
@type msg: xu message
"""
val = unpackMsg('blkif_be_connect_t', msg)
self.send_fe_interface_status_changed()
self.status = BLKIF_INTERFACE_STATUS_CONNECTED
self.send_fe_interface_status()
def send_fe_interface_status_changed(self, response=None):
msg = packMsg('blkif_fe_interface_status_changed_t',
def send_fe_interface_status(self, response=None):
msg = packMsg('blkif_fe_interface_status_t',
{ 'handle' : self.handle,
'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
'status' : self.status,
'domid' : self.dom,
'evtchn' : self.evtchn['port2'] })
'evtchn' : self.getEventChannelFrontend() })
self.controller.writeRequest(msg, response=response)
def interfaceDisconnected(self):
msg = packMsg('blkif_fe_interface_status_changed_t',
{ 'handle' : self.handle,
'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
'domid' : self.dom,
'evtchn' : 0 })
self.controller.writeRequest(msg)
self.status = BLKIF_INTERFACE_STATUS_DISCONNECTED
#todo?: Do this: self.evtchn = None
self.send_fe_interface_status()
def interfaceChanged(self):
"""Notify the front-end that devices have been added or removed.
The front-end should then probe for devices.
"""
msg = packMsg('blkif_fe_interface_status_changed_t',
msg = packMsg('blkif_fe_interface_status_t',
{ 'handle' : self.handle,
'status' : BLKIF_INTERFACE_STATUS_CHANGED,
'status' : BLKIF_INTERFACE_STATUS,
'domid' : self.dom,
'evtchn' : 0 })
self.controller.writeRequest(msg)
@@ -199,25 +210,25 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
blkif = self.getControllerByDom(dom)
return (blkif and blkif.getDevices()) or []
def getDomainDevice(self, dom, vdev):
def getDomainDevice(self, dom, idx):
"""Get a block device from a domain.
@param dom: domain
@type dom: int
@param vdev: device index
@type vdev: int
@param idx: device index
@type idx: int
@return: device
@rtype: device
"""
blkif = self.getControllerByDom(dom)
return (blkif and blkif.getDevice(vdev)) or None
return (blkif and blkif.getDevice(idx)) or None
class BlkDev(controller.SplitDev):
"""Info record for a block device.
"""
def __init__(self, ctrl, config, vdev, mode, segment):
controller.SplitDev.__init__(self, segment['device'], ctrl)
def __init__(self, idx, ctrl, config, vdev, mode, segment):
controller.SplitDev.__init__(self, idx, ctrl)
self.config = config
self.dev = None
self.uname = None
@@ -251,7 +262,7 @@ class BlkDev(controller.SplitDev):
@param change: change flag
"""
log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
log.debug("Destroying vbd domain=%d idx=%s", self.controller.dom, self.idx)
d = self.send_be_vbd_destroy()
if change:
d.addCallback(lambda val: self.interfaceChanged())
@@ -345,10 +356,9 @@ class BlkifController(controller.SplitController):
Do not call directly - use createController() on the factory instead.
"""
controller.SplitController.__init__(self, factory, dom)
self.devices = {}
self.addMethod(CMSG_BLKIF_FE,
CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED,
self.recv_fe_driver_status_changed)
CMSG_BLKIF_FE_DRIVER_STATUS,
self.recv_fe_driver_status)
self.addMethod(CMSG_BLKIF_FE,
CMSG_BLKIF_FE_INTERFACE_CONNECT,
self.recv_fe_interface_connect)
@@ -358,13 +368,7 @@ class BlkifController(controller.SplitController):
val = ['blkif', ['dom', self.dom]]
return val
def getDevices(self):
return self.devices.values()
def getDevice(self, vdev):
return self.devices.get(vdev)
def addDevice(self, config, vdev, mode, segment):
def addDevice(self, idx, config, vdev, mode, segment):
"""Add a device to the device table.
@param vdev: device index
@@ -376,20 +380,18 @@ class BlkifController(controller.SplitController):
@return: device
@rtype: BlkDev
"""
if vdev in self.devices:
raise XendError('device exists: ' + str(vdev))
dev = BlkDev(self, config, vdev, mode, segment)
self.devices[vdev] = dev
if idx in self.devices:
raise XendError('device exists: ' + str(idx))
dev = BlkDev(idx, self, config, vdev, mode, segment)
self.devices[idx] = dev
return dev
def delDevice(self, vdev):
if vdev in self.devices:
del self.devices[vdev]
def attachDevice(self, config, vdev, mode, segment, recreate=0):
def attachDevice(self, idx, config, vdev, mode, segment, recreate=0):
"""Attach a device to the specified interface.
On success the returned deferred will be called with the device.
@param idx: device id
@param config: device configuration
@param vdev: device index
@type vdev: int
@param mode: read/write mode
@@ -401,7 +403,7 @@ class BlkifController(controller.SplitController):
@return: deferred
@rtype: Deferred
"""
dev = self.addDevice(config, vdev, mode, segment)
dev = self.addDevice(idx, config, vdev, mode, segment)
if recreate:
d = defer.succeed(dev)
else:
@@ -425,8 +427,9 @@ class BlkifController(controller.SplitController):
for backend in self.getBackendInterfaces():
backend.destroy()
def recv_fe_driver_status_changed(self, msg, req):
val = unpackMsg('blkif_fe_driver_status_changed_t', msg)
def recv_fe_driver_status(self, msg, req):
val = unpackMsg('blkif_fe_driver_status_t', msg)
print 'recv_fe_driver_status>', val
for backend in self.getBackendInterfaces():
backend.interfaceDisconnected()
@@ -439,5 +442,6 @@ class BlkifController(controller.SplitController):
else:
log.error('interface connect on unknown interface: handle=%d', handle)
@@ -522,6 +522,9 @@ class BackendInterface:
def writeRequest(self, msg, response=None):
return self.backend.writeRequest(msg, response=response)
def writeResponse(self, msg):
return self.backend.writeResponse(msg)
def close(self):
self.backend.deregisterInterface(self)
self.controller.backendInterfaceClosed(self)
@@ -536,6 +539,60 @@ class SplitController(Controller):
Controller.__init__(self, factory, dom)
self.backendInterfaces = {}
self.backendHandle = 0
self.devices = {}
def getDevices(self):
"""Get a list of the devices..
"""
return self.devices.values()
def delDevice(self, idx):
"""Remove the device with the given index from the device table.
@param idx device index
"""
if idx in self.devices:
del self.devices[idx]
def getDevice(self, idx):
"""Get the device with a given index.
@param idx device index
@return device (or None)
"""
return self.devices.get(idx)
def findDevice(self, idx):
"""Find a device. If idx is non-negative,
get the device with the given index. If idx is negative,
look for the device with least index greater than -idx - 2.
For example, if idx is -2, look for devices with index
greater than 0, i.e. 1 or above.
@param idx device index
@return device (or None)
"""
if idx < 0:
idx = -idx - 2
val = None
for dev in self.devices.values():
if dev.idx <= idx: continue
if (val is None) or (dev.idx < val.idx):
val = dev
else:
val = getDevice(idx)
return val
def getMaxDeviceIdx(self):
"""Get the maximum id used by devices.
@return maximum idx
"""
maxIdx = 0
for dev in self.devices:
if dev.idx > maxIdx:
maxIdx = dev.idx
return maxIdx
def getBackendInterfaces(self):
return self.backendInterfaces.values()
+94 -55
View File
@@ -29,70 +29,106 @@ msg_formats.update(console_formats)
CMSG_BLKIF_BE = 1
CMSG_BLKIF_FE = 2
CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED = 0
CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED = 32
CMSG_BLKIF_FE_INTERFACE_CONNECT = 33
CMSG_BLKIF_FE_INTERFACE_DISCONNECT = 34
CMSG_BLKIF_FE_INTERFACE_STATUS = 0
CMSG_BLKIF_FE_DRIVER_STATUS = 32
CMSG_BLKIF_FE_INTERFACE_CONNECT = 33
CMSG_BLKIF_FE_INTERFACE_DISCONNECT = 34
CMSG_BLKIF_FE_INTERFACE_QUERY = 35
CMSG_BLKIF_BE_CREATE = 0
CMSG_BLKIF_BE_DESTROY = 1
CMSG_BLKIF_BE_CONNECT = 2
CMSG_BLKIF_BE_DISCONNECT = 3
CMSG_BLKIF_BE_VBD_CREATE = 4
CMSG_BLKIF_BE_VBD_DESTROY = 5
CMSG_BLKIF_BE_VBD_GROW = 6
CMSG_BLKIF_BE_VBD_SHRINK = 7
CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED = 32
CMSG_BLKIF_BE_CREATE = 0
CMSG_BLKIF_BE_DESTROY = 1
CMSG_BLKIF_BE_CONNECT = 2
CMSG_BLKIF_BE_DISCONNECT = 3
CMSG_BLKIF_BE_VBD_CREATE = 4
CMSG_BLKIF_BE_VBD_DESTROY = 5
CMSG_BLKIF_BE_VBD_GROW = 6
CMSG_BLKIF_BE_VBD_SHRINK = 7
CMSG_BLKIF_BE_DRIVER_STATUS = 32
BLKIF_DRIVER_STATUS_DOWN = 0
BLKIF_DRIVER_STATUS_UP = 1
BLKIF_DRIVER_STATUS_DOWN = 0
BLKIF_DRIVER_STATUS_UP = 1
BLKIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */
BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
BLKIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
BLKIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
BLKIF_INTERFACE_STATUS_CLOSED = 0 #/* Interface doesn't exist. */
BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
BLKIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
BLKIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
BLKIF_BE_STATUS_OKAY = 0
BLKIF_BE_STATUS_ERROR = 1
BLKIF_BE_STATUS_INTERFACE_EXISTS = 2
BLKIF_BE_STATUS_INTERFACE_NOT_FOUND = 3
BLKIF_BE_STATUS_INTERFACE_CONNECTED = 4
BLKIF_BE_STATUS_VBD_EXISTS = 5
BLKIF_BE_STATUS_VBD_NOT_FOUND = 6
BLKIF_BE_STATUS_OUT_OF_MEMORY = 7
BLKIF_BE_STATUS_EXTENT_NOT_FOUND = 8
BLKIF_BE_STATUS_MAPPING_ERROR = 9
BLKIF_BE_STATUS_OKAY = 0
BLKIF_BE_STATUS_ERROR = 1
BLKIF_BE_STATUS_INTERFACE_EXISTS = 2
BLKIF_BE_STATUS_INTERFACE_NOT_FOUND = 3
BLKIF_BE_STATUS_INTERFACE_CONNECTED = 4
BLKIF_BE_STATUS_VBD_EXISTS = 5
BLKIF_BE_STATUS_VBD_NOT_FOUND = 6
BLKIF_BE_STATUS_OUT_OF_MEMORY = 7
BLKIF_BE_STATUS_EXTENT_NOT_FOUND = 8
BLKIF_BE_STATUS_MAPPING_ERROR = 9
blkif_formats = {
'blkif_be_connect_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT),
# Connect be to fe (in response to blkif_fe_interface_connect_t).
'blkif_be_create_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE),
# Create be.
'blkif_be_disconnect_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT),
# Disconnect be from fe.
'blkif_be_destroy_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY),
# Destroy be (after disconnect).
# Make be do this even if no disconnect (and destroy all vbd too).
'blkif_be_vbd_create_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE),
# Create a vbd device.
'blkif_be_vbd_grow_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW),
# Change the size of a vbd device. Remove?
# Do in one go in blkif_be_vbd_create_t.
'blkif_be_vbd_destroy_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY),
# Destroy a vbd.
'blkif_fe_interface_status_changed_t':
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED),
# Add message to query be for state and vbds.
'blkif_fe_driver_status_changed_t':
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED),
'blkif_fe_interface_status_t':
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS),
# Notify device status to fe.
# Also used to notify 'any' device change with status BLKIF_INTERFACE_STATUS_CHANGED.
# Rename to blkif_fe_interface_status.
'blkif_fe_driver_status_t':
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS),
# Comes from fe, treated as notifying that fe has come up/changed.
# Xend sets be(s) to BLKIF_INTERFACE_STATUS_DISCONNECTED,
# sends blkif_fe_interface_status_t to fe (from each be).
#
# Rename to blkif_fe_driver_status.
# Reply with i/f count.
# The i/f sends probes (using -ve trick), we reply with the info.
'blkif_fe_interface_connect_t':
(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT),
# Comes from fe, passing shmem frame to use for be.
# fe sends when gets blkif_fe_interface_status_t with state NETIF_INTERFACE_STATUS_DISCONNECTED.
# Xend creates event channel and notifies be.
# Then notifies fe of event channel with blkif_fe_interface_status_t.
# Add message to kick fe to probe for devices.
# Just report new devices to fe?
#
# Add message for fe to probe a device.
# And probing with id -1 should return first.
# And probing with id -n should return first device with id > n.
# Add message to query fe for state and vbds.
}
msg_formats.update(blkif_formats)
@@ -104,24 +140,25 @@ msg_formats.update(blkif_formats)
CMSG_NETIF_BE = 3
CMSG_NETIF_FE = 4
CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED = 0
CMSG_NETIF_FE_DRIVER_STATUS_CHANGED = 32
CMSG_NETIF_FE_INTERFACE_CONNECT = 33
CMSG_NETIF_FE_INTERFACE_DISCONNECT = 34
CMSG_NETIF_FE_INTERFACE_STATUS = 0
CMSG_NETIF_FE_DRIVER_STATUS = 32
CMSG_NETIF_FE_INTERFACE_CONNECT = 33
CMSG_NETIF_FE_INTERFACE_DISCONNECT = 34
CMSG_NETIF_FE_INTERFACE_QUERY = 35
CMSG_NETIF_BE_CREATE = 0
CMSG_NETIF_BE_DESTROY = 1
CMSG_NETIF_BE_CONNECT = 2
CMSG_NETIF_BE_DISCONNECT = 3
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED = 32
CMSG_NETIF_BE_CREATE = 0
CMSG_NETIF_BE_DESTROY = 1
CMSG_NETIF_BE_CONNECT = 2
CMSG_NETIF_BE_DISCONNECT = 3
CMSG_NETIF_BE_DRIVER_STATUS = 32
NETIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */
NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
NETIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
NETIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
NETIF_INTERFACE_STATUS_CLOSED = 0 #/* Interface doesn't exist. */
NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
NETIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
NETIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
NETIF_DRIVER_STATUS_DOWN = 0
NETIF_DRIVER_STATUS_UP = 1
NETIF_DRIVER_STATUS_DOWN = 0
NETIF_DRIVER_STATUS_UP = 1
netif_formats = {
'netif_be_connect_t':
@@ -136,17 +173,17 @@ netif_formats = {
'netif_be_destroy_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY),
'netif_be_driver_status_changed_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED),
'netif_be_driver_status_t':
(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS),
'netif_fe_driver_status_changed_t':
(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED),
'netif_fe_driver_status_t':
(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS),
'netif_fe_interface_connect_t':
(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT),
'netif_fe_interface_status_changed_t':
(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED),
'netif_fe_interface_status_t':
(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS),
}
msg_formats.update(netif_formats)
@@ -241,13 +278,15 @@ def unpackMsg(ty, msg):
macs = []
for (k, v) in args.items():
if k.startswith('mac['):
macs += k
macs.append(k)
i = int(k[4:5])
mac[i] = v
else:
pass
if macs:
args['mac'] = mac
print 'macs=', macs
print 'args=', args
for k in macs:
del args[k]
if DEBUG:
+87 -55
View File
@@ -24,12 +24,12 @@ class NetifBackendController(controller.BackendController):
def __init__(self, ctrl, dom):
controller.BackendController.__init__(self, ctrl, dom)
self.addMethod(CMSG_NETIF_BE,
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
self.recv_be_driver_status_changed)
CMSG_NETIF_BE_DRIVER_STATUS,
self.recv_be_driver_status)
self.registerChannel()
def recv_be_driver_status_changed(self, msg, req):
val = unpackMsg('netif_be_driver_status_changed_t', msg)
def recv_be_driver_status(self, msg, req):
val = unpackMsg('netif_be_driver_status_t', msg)
status = val['status']
class NetifBackendInterface(controller.BackendInterface):
@@ -98,11 +98,12 @@ class NetDev(controller.SplitDev):
"""Info record for a network device.
"""
def __init__(self, ctrl, vif, config):
def __init__(self, vif, ctrl, config):
controller.SplitDev.__init__(self, vif, ctrl)
self.vif = vif
self.evtchn = None
self.configure(config)
self.status = NETIF_INTERFACE_STATUS_DISCONNECTED
def _get_config_mac(self, config):
vmac = sxp.child_value(config, 'mac')
@@ -245,6 +246,18 @@ class NetDev(controller.SplitDev):
d.addCallback(self.respond_be_create)
return d
def getEventChannelBackend(self):
val = 0
if self.evtchn:
val = self.evtchn['port1']
return val
def getEventChannelFrontend(self):
val = 0
if self.evtchn:
val = self.evtchn['port2']
return val
def send_be_create(self):
d = defer.Deferred()
msg = packMsg('netif_be_create_t',
@@ -264,11 +277,12 @@ class NetDev(controller.SplitDev):
@param change: change flag
"""
self.status = NETIF_INTERFACE_STATUS_CLOSED
def cb_destroy(val):
self.send_be_destroy()
self.getBackendInterface().close()
if change:
self.interfaceChanged()
self.reportStatus()
log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
self.vifctl('down')
d = self.send_be_disconnect()
@@ -295,7 +309,7 @@ class NetDev(controller.SplitDev):
msg = packMsg('netif_be_connect_t',
{ 'domid' : self.controller.dom,
'netif_handle' : self.vif,
'evtchn' : self.evtchn['port1'],
'evtchn' : self.getEventChannelBackend(),
'tx_shmem_frame' : val['tx_shmem_frame'],
'rx_shmem_frame' : val['rx_shmem_frame'] })
d = defer.Deferred()
@@ -306,34 +320,25 @@ class NetDev(controller.SplitDev):
val = unpackMsg('netif_be_connect_t', msg)
dom = val['domid']
vif = val['netif_handle']
msg = packMsg('netif_fe_interface_status_changed_t',
{ 'handle' : self.vif,
'status' : NETIF_INTERFACE_STATUS_CONNECTED,
'evtchn' : self.evtchn['port2'],
'domid' : self.backendDomain,
'mac' : self.mac })
self.controller.writeRequest(msg)
self.status = NETIF_INTERFACE_STATUS_CONNECTED
self.reportStatus()
def attach_fe_device(self):
msg = packMsg('netif_fe_interface_status_changed_t',
def reportStatus(self, resp=0):
msg = packMsg('netif_fe_interface_status_t',
{ 'handle' : self.vif,
'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
'evtchn' : 0,
'status' : self.status,
'evtchn' : self.getEventChannelFrontend(),
'domid' : self.backendDomain,
'mac' : self.mac })
self.controller.writeRequest(msg)
if resp:
self.controller.writeResponse(msg)
else:
self.controller.writeRequest(msg)
def interfaceChanged(self):
"""Notify the font-end that a device has been added or removed.
The front-end should then probe the devices.
"""
msg = packMsg('netif_fe_interface_status_changed_t',
{ 'handle' : self.vif,
'status' : NETIF_INTERFACE_STATUS_CHANGED,
'evtchn' : 0,
'domid' : self.backendDomain,
'mac' : self.mac })
self.controller.writeRequest(msg)
self.reportStatus()
class NetifController(controller.SplitController):
"""Network interface controller. Handles all network devices for a domain.
@@ -343,8 +348,11 @@ class NetifController(controller.SplitController):
controller.SplitController.__init__(self, factory, dom)
self.devices = {}
self.addMethod(CMSG_NETIF_FE,
CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
self.recv_fe_driver_status_changed)
CMSG_NETIF_FE_DRIVER_STATUS,
self.recv_fe_driver_status)
self.addMethod(CMSG_NETIF_FE,
CMSG_NETIF_FE_INTERFACE_STATUS,
self.recv_fe_interface_status)
self.addMethod(CMSG_NETIF_FE,
CMSG_NETIF_FE_INTERFACE_CONNECT,
self.recv_fe_interface_connect)
@@ -359,19 +367,6 @@ class NetifController(controller.SplitController):
"""
controller.Controller.lostChannel(self)
def getDevices(self):
"""Get a list of the devices.
"""
return self.devices.values()
def getDevice(self, vif):
"""Get a device.
@param vif: device index
@return: device (or None)
"""
return self.devices.get(vif)
def addDevice(self, vif, config):
"""Add a network interface.
@@ -381,14 +376,10 @@ class NetifController(controller.SplitController):
"""
if vif in self.devices:
raise XendError('device exists:' + str(vif))
dev = NetDev(self, vif, config)
dev = NetDev(vif, self, config)
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.
"""
@@ -415,23 +406,64 @@ class NetifController(controller.SplitController):
d = dev.attach()
return d
def recv_fe_driver_status_changed(self, msg, req):
def recv_fe_driver_status(self, msg, req):
if not req: return
msg = packMsg('netif_fe_driver_status_changed_t',
print
print 'recv_fe_driver_status>'
msg = packMsg('netif_fe_driver_status_t',
{ 'status' : NETIF_DRIVER_STATUS_UP,
## FIXME: max_handle should be max active interface id
'max_handle' : len(self.devices) })
self.writeRequest(msg)
for dev in self.devices.values():
dev.attach_fe_device()
'max_handle' : len(self.devices)
#'max_handle' : self.getMaxDeviceIdx()
})
# Two ways of doing it:
# 1) front-end requests driver status, we reply with the interface count,
# front-end polls the interfaces,
# front-end checks they are all up
# 2) front-end requests driver status, we reply (with anything),
# we notify the interfaces,
# we notify driver status up with the count
# front-end checks they are all up
#
# We really want to use 1), but at the moment the xenU kernel panics
# in that mode, so we're sticking to 2) for now.
resp = 0
if resp:
self.writeResponse(msg)
else:
for dev in self.devices.values():
dev.reportStatus()
self.writeRequest(msg)
return resp
def recv_fe_interface_status(self, msg, req):
if not req: return
print
val = unpackMsg('netif_fe_interface_status_t', msg)
print "recv_fe_interface_status>", val
vif = val['handle']
dev = self.findDevice(vif)
if dev:
print 'recv_fe_interface_status>', 'dev=', dev
dev.reportStatus(resp=1)
else:
msg = packMsg('netif_fe_interface_status_t',
{ 'handle' : -1,
'status' : NETIF_INTERFACE_STATUS_CLOSED,
});
print 'recv_fe_interface_status>', 'no dev, returning -1'
self.writeResponse(msg)
return 1
def recv_fe_interface_connect(self, msg, req):
val = unpackMsg('netif_fe_interface_connect_t', msg)
vif = val['handle']
dev = self.devices.get(vif)
print
print "recv_fe_interface_connect", val
dev = self.getDevice(vif)
if dev:
dev.recv_fe_interface_connect(val, req)
else:
log.error('Received netif_fe_interface_connect for unknown vif: dom=%d vif=%d',
self.dom, vif)
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.