mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.1159.38.3 (4123550cLBAC07otAj8ftsT6MzujHQ)
Make backend domain a per-device parameter. Restructure device controllers and adjust config handling.
This commit is contained in:
1 parent
b450daf7d3
commit
d82470e9a7
6 files changed
+321
-369
No files matched your search
@@ -137,7 +137,7 @@ def lookup_disk_uname(uname):
|
||||
segments = None
|
||||
return segments
|
||||
|
||||
def make_disk(vm, uname, dev, mode, recreate=0):
|
||||
def make_disk(vm, config, uname, dev, mode, recreate=0):
|
||||
"""Create a virtual disk device for a domain.
|
||||
|
||||
@param vm: vm
|
||||
@@ -154,13 +154,8 @@ def make_disk(vm, uname, dev, mode, recreate=0):
|
||||
raise VmError("vbd: Multi-segment vdisk: uname=%s" % uname)
|
||||
segment = segments[0]
|
||||
vdev = blkdev_name_to_number(dev)
|
||||
backend = vm.get_device_backend('vbd')
|
||||
ctrl = xend.blkif_create(vm.dom, recreate=recreate, backend=backend)
|
||||
|
||||
def fn(ctrl):
|
||||
return xend.blkif_dev_create(vm.dom, vdev, mode, segment, recreate=recreate)
|
||||
ctrl.addCallback(fn)
|
||||
return ctrl
|
||||
ctrl = xend.blkif_create(vm.dom, recreate=recreate)
|
||||
return ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
|
||||
|
||||
def vif_up(iplist):
|
||||
"""send an unsolicited ARP reply for all non link-local IP addresses.
|
||||
@@ -340,22 +335,6 @@ def append_deferred(dlist, v):
|
||||
if isinstance(v, defer.Deferred):
|
||||
dlist.append(v)
|
||||
|
||||
def _vm_configure1(val, vm):
|
||||
d = vm.create_devices()
|
||||
d.addCallback(_vm_configure2, vm)
|
||||
return d
|
||||
|
||||
def _vm_configure2(val, vm):
|
||||
d = vm.configure_fields()
|
||||
def cbok(results):
|
||||
return vm
|
||||
def cberr(err):
|
||||
vm.destroy()
|
||||
return err
|
||||
d.addCallback(cbok)
|
||||
d.addErrback(cberr)
|
||||
return d
|
||||
|
||||
class XendDomainInfo:
|
||||
"""Virtual machine object."""
|
||||
|
||||
@@ -379,7 +358,6 @@ class XendDomainInfo:
|
||||
self.console = None
|
||||
self.devices = {}
|
||||
self.device_index = {}
|
||||
self.device_backends = {}
|
||||
self.configs = []
|
||||
self.info = None
|
||||
self.ipaddrs = []
|
||||
@@ -675,7 +653,6 @@ class XendDomainInfo:
|
||||
|
||||
self.devices = {}
|
||||
self.device_index = {}
|
||||
self.device_backends = {}
|
||||
self.configs = []
|
||||
self.ipaddrs = []
|
||||
|
||||
@@ -915,25 +892,6 @@ class XendDomainInfo:
|
||||
self.restart_state = None
|
||||
return d
|
||||
|
||||
def configure_device_backend(self, type, sxpr):
|
||||
"""Configure the backend domain to use for devices of a given type.
|
||||
|
||||
@param type: device type
|
||||
@param sxpr: config
|
||||
@raise: VmError if the domain id is missing
|
||||
@raise: VmError if the domain does not exist
|
||||
"""
|
||||
dom = sxp.child_value(sxpr, 'domain')
|
||||
if dom is None:
|
||||
raise VmError('missing backend domain')
|
||||
dominfo = domain_exists(dom)
|
||||
if dominfo is None:
|
||||
raise VmError('invalid backend domain:' + dom)
|
||||
self.device_backends[type] = dominfo.dom
|
||||
|
||||
def get_device_backend(self, type):
|
||||
return self.device_backends.get(type, 0)
|
||||
|
||||
def configure_backends(self):
|
||||
"""Set configuration flags if the vm is a backend for netif or blkif.
|
||||
Configure the backends to use for vbd and vif if specified.
|
||||
@@ -945,21 +903,9 @@ class XendDomainInfo:
|
||||
self.blkif_backend = 1
|
||||
elif name == 'netif':
|
||||
self.netif_backend = 1
|
||||
elif name == 'vbd':
|
||||
self.configure_device_backend('vbd', v)
|
||||
elif name == 'vif':
|
||||
self.configure_device_backend('vif', v)
|
||||
else:
|
||||
raise VmError('invalid backend type:' + str(name))
|
||||
|
||||
def create_backends(self):
|
||||
"""Setup the netif and blkif backends.
|
||||
"""
|
||||
if self.blkif_backend:
|
||||
xend.blkif_set_control_domain(self.dom, recreate=self.recreate)
|
||||
if self.netif_backend:
|
||||
xend.netif_set_control_domain(self.dom, recreate=self.recreate)
|
||||
|
||||
def configure(self):
|
||||
"""Configure a vm.
|
||||
|
||||
@@ -968,12 +914,19 @@ class XendDomainInfo:
|
||||
|
||||
returns Deferred - calls callback with vm
|
||||
"""
|
||||
if self.blkif_backend:
|
||||
d = defer.Deferred()
|
||||
d.callback(self)
|
||||
else:
|
||||
d = xend.blkif_create(self.dom, recreate=self.recreate)
|
||||
d.addCallback(_vm_configure1, self)
|
||||
d = self.create_devices()
|
||||
d.addCallback(self._configure)
|
||||
return d
|
||||
|
||||
def _configure(self, val):
|
||||
d = self.configure_fields()
|
||||
def cbok(results):
|
||||
return self
|
||||
def cberr(err):
|
||||
self.destroy()
|
||||
return err
|
||||
d.addCallback(cbok)
|
||||
d.addErrback(cberr)
|
||||
return d
|
||||
|
||||
def dom_construct(self, dom, config):
|
||||
@@ -1078,16 +1031,14 @@ def vm_dev_vif(vm, val, index):
|
||||
# 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')
|
||||
xend.netif_create(vm.dom, recreate=vm.recreate, backend=backend)
|
||||
ctrl = xend.netif_create(vm.dom, recreate=vm.recreate)
|
||||
log.debug("Creating vif dom=%d vif=%d mac=%s", vm.dom, vif, str(vmac))
|
||||
defer = xend.netif_dev_create(vm.dom, vif, val, recreate=vm.recreate)
|
||||
def fn(id):
|
||||
dev = xend.netif_dev(vm.dom, vif)
|
||||
defer = ctrl.attachDevice(vif, val, recreate=vm.recreate)
|
||||
def cbok(dev):
|
||||
dev.vifctl('up', vmname=vm.name)
|
||||
vm.add_device('vif', dev)
|
||||
return id
|
||||
defer.addCallback(fn)
|
||||
return dev
|
||||
defer.addCallback(cbok)
|
||||
return defer
|
||||
|
||||
def vm_dev_vbd(vm, val, index):
|
||||
@@ -1108,7 +1059,7 @@ def vm_dev_vbd(vm, val, index):
|
||||
raise VmError('vbd: Missing dev')
|
||||
mode = sxp.child_value(val, 'mode', 'r')
|
||||
log.debug("Creating vbd dom=%d uname=%s dev=%s", vm.dom, uname, dev)
|
||||
defer = make_disk(vm, uname, dev, mode, vm.recreate)
|
||||
defer = make_disk(vm, val, uname, dev, mode, vm.recreate)
|
||||
def fn(vbd):
|
||||
vbd.dev = dev
|
||||
vbd.uname = uname
|
||||
|
||||
@@ -651,23 +651,12 @@ class Daemon:
|
||||
"""
|
||||
return self.channelF.getDomChannel(dom)
|
||||
|
||||
def blkif_set_control_domain(self, dom, recreate=0):
|
||||
"""Set the block device backend control domain.
|
||||
"""
|
||||
return self.blkifCF.setControlDomain(dom, recreate=recreate)
|
||||
|
||||
def blkif_get_control_domain(self, dom):
|
||||
"""Get the block device backend control domain.
|
||||
"""
|
||||
return self.blkifCF.getControlDomain()
|
||||
|
||||
def blkif_create(self, dom, recreate=0, backend=0):
|
||||
def blkif_create(self, dom, recreate=0):
|
||||
"""Create a block device interface controller.
|
||||
|
||||
Returns Deferred
|
||||
Returns controller
|
||||
"""
|
||||
d = self.blkifCF.createInstance(dom, recreate=recreate, backend=backend)
|
||||
return d
|
||||
return self.blkifCF.createInstance(dom, recreate=recreate)
|
||||
|
||||
def blkifs(self):
|
||||
return [ x.sxpr() for x in self.blkifCF.getInstances() ]
|
||||
@@ -678,7 +667,7 @@ class Daemon:
|
||||
def blkif_dev(self, dom, vdev):
|
||||
return self.blkifCF.getDomainDevice(dom, vdev)
|
||||
|
||||
def blkif_dev_create(self, dom, vdev, mode, segment, recreate=0):
|
||||
def blkif_dev_create(self, dom, config, vdev, mode, segment, recreate=0):
|
||||
"""Create a block device.
|
||||
|
||||
Returns Deferred
|
||||
@@ -686,24 +675,14 @@ class Daemon:
|
||||
ctrl = self.blkifCF.getInstanceByDom(dom)
|
||||
if not ctrl:
|
||||
raise XendError('No blkif controller: %d' % dom)
|
||||
d = ctrl.attachDevice(vdev, mode, segment, recreate=recreate)
|
||||
d = ctrl.attachDevice(config, vdev, mode, segment, recreate=recreate)
|
||||
return d
|
||||
|
||||
def netif_set_control_domain(self, dom, recreate=0):
|
||||
"""Set the network interface backend control domain.
|
||||
"""
|
||||
return self.netifCF.setControlDomain(dom, recreate=recreate)
|
||||
|
||||
def netif_get_control_domain(self, dom):
|
||||
"""Get the network interface backend control domain.
|
||||
"""
|
||||
return self.netifCF.getControlDomain()
|
||||
|
||||
def netif_create(self, dom, recreate=0, backend=0):
|
||||
def netif_create(self, dom, recreate=0):
|
||||
"""Create a network interface controller.
|
||||
|
||||
"""
|
||||
return self.netifCF.createInstance(dom, recreate=recreate, backend=backend)
|
||||
return self.netifCF.createInstance(dom, recreate=recreate)
|
||||
|
||||
def netifs(self):
|
||||
return [ x.sxpr() for x in self.netifCF.getInstances() ]
|
||||
|
||||
@@ -17,13 +17,19 @@ class BlkifBackendController(controller.BackendController):
|
||||
""" Handler for the 'back-end' channel to a device driver domain.
|
||||
"""
|
||||
|
||||
def __init__(self, factory, dom):
|
||||
controller.BackendController.__init__(self, factory, dom)
|
||||
def __init__(self, ctrl, dom, handle):
|
||||
controller.BackendController.__init__(self, ctrl, dom, handle)
|
||||
self.connected = 0
|
||||
self.evtchn = None
|
||||
self.handle = handle
|
||||
self.addMethod(CMSG_BLKIF_BE,
|
||||
CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
|
||||
self.recv_be_driver_status_changed)
|
||||
self.registerChannel()
|
||||
|
||||
def __str__(self):
|
||||
return '<BlkifBackendController %d %d>' % (self.controller.dom, self.dom)
|
||||
|
||||
def recv_be_driver_status_changed(self, msg, req):
|
||||
"""Request handler for be_driver_status_changed messages.
|
||||
|
||||
@@ -35,32 +41,109 @@ class BlkifBackendController(controller.BackendController):
|
||||
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
|
||||
status = val['status']
|
||||
|
||||
class BlkifControllerFactory(controller.SplitControllerFactory):
|
||||
def connect(self, recreate=0):
|
||||
"""Connect the controller to the blkif control interface.
|
||||
|
||||
@param recreate: true if after xend restart
|
||||
@return: deferred
|
||||
"""
|
||||
log.debug("Connecting blkif %s", str(self))
|
||||
if recreate or self.connected:
|
||||
d = defer.succeed(self)
|
||||
else:
|
||||
d = self.send_be_create()
|
||||
d.addCallback(self.respond_be_create)
|
||||
return d
|
||||
|
||||
def send_be_create(self):
|
||||
d = defer.Deferred()
|
||||
msg = packMsg('blkif_be_create_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.handle })
|
||||
self.writeRequest(msg, response=d)
|
||||
return d
|
||||
|
||||
def respond_be_create(self, msg):
|
||||
val = unpackMsg('blkif_be_create_t', msg)
|
||||
print 'respond_be_create>', val
|
||||
self.connected = 1
|
||||
return self
|
||||
|
||||
def destroy(self):
|
||||
"""Disconnect from the blkif control interface and destroy it.
|
||||
"""
|
||||
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('>BlkifBackendController>send_be_disconnect> %s', str(self))
|
||||
msg = packMsg('blkif_be_disconnect_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.handle })
|
||||
self.writeRequest(msg, response=response)
|
||||
|
||||
def send_be_destroy(self, response=None):
|
||||
log.debug('>BlkifBackendController>send_be_destroy> %s', str(self))
|
||||
msg = packMsg('blkif_be_destroy_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.handle })
|
||||
self.writeRequest(msg, response=response)
|
||||
|
||||
def connectInterface(self, val):
|
||||
self.evtchn = channel.eventChannel(0, self.controller.dom)
|
||||
log.debug("Connecting blkif to event channel %s ports=%d:%d",
|
||||
str(self), self.evtchn['port1'], self.evtchn['port2'])
|
||||
msg = packMsg('blkif_be_connect_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.handle,
|
||||
'evtchn' : self.evtchn['port1'],
|
||||
'shmem_frame' : val['shmem_frame'] })
|
||||
d = defer.Deferred()
|
||||
d.addCallback(self.respond_be_connect)
|
||||
self.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)
|
||||
print 'respond_be_connect>', str(self), val
|
||||
self.send_fe_interface_status_changed()
|
||||
|
||||
def send_fe_interface_status_changed(self, response=None):
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.handle,
|
||||
'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
|
||||
'evtchn' : self.evtchn['port2'] })
|
||||
self.controller.writeRequest(msg, response=response)
|
||||
|
||||
class BlkifControllerFactory(controller.ControllerFactory):
|
||||
"""Factory for creating block device interface controllers.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
controller.SplitControllerFactory.__init__(self)
|
||||
controller.ControllerFactory.__init__(self)
|
||||
|
||||
def createInstance(self, dom, recreate=0, backend=0):
|
||||
def createInstance(self, dom, recreate=0):
|
||||
"""Create a block device controller for a domain.
|
||||
|
||||
@param dom: domain
|
||||
@type dom: int
|
||||
@param recreate: if true it's a recreate (after xend restart)
|
||||
@type recreate: bool
|
||||
@return: deferred
|
||||
@rtype: twisted.internet.defer.Deferred
|
||||
@return: block device controller
|
||||
@rtype: BlkifController
|
||||
"""
|
||||
blkif = self.getInstanceByDom(dom)
|
||||
if blkif:
|
||||
d = defer.Deferred()
|
||||
d.callback(blkif)
|
||||
else:
|
||||
blkif = BlkifController(self, dom, backend)
|
||||
if blkif is None:
|
||||
blkif = BlkifController(self, dom)
|
||||
self.addInstance(blkif)
|
||||
d = blkif.connect(recreate=recreate)
|
||||
return d
|
||||
return blkif
|
||||
|
||||
def getDomainDevices(self, dom):
|
||||
"""Get the block devices for a domain.
|
||||
@@ -86,15 +169,13 @@ class BlkifControllerFactory(controller.SplitControllerFactory):
|
||||
blkif = self.getInstanceByDom(dom)
|
||||
return (blkif and blkif.getDevice(vdev)) or None
|
||||
|
||||
def createBackendController(self, dom):
|
||||
return BlkifBackendController(self, dom)
|
||||
|
||||
class BlkDev(controller.Dev):
|
||||
class BlkDev(controller.SplitDev):
|
||||
"""Info record for a block device.
|
||||
"""
|
||||
|
||||
def __init__(self, ctrl, vdev, mode, segment):
|
||||
controller.Dev.__init__(self, segment['device'], ctrl)
|
||||
def __init__(self, ctrl, config, vdev, mode, segment):
|
||||
controller.SplitDev.__init__(self, segment['device'], ctrl)
|
||||
self.config = config
|
||||
self.dev = None
|
||||
self.uname = None
|
||||
self.vdev = vdev
|
||||
@@ -102,9 +183,10 @@ class BlkDev(controller.Dev):
|
||||
self.device = segment['device']
|
||||
self.start_sector = segment['start_sector']
|
||||
self.nr_sectors = segment['nr_sectors']
|
||||
|
||||
def getBackendController(self):
|
||||
return self.controller.backendController
|
||||
try:
|
||||
self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
|
||||
except:
|
||||
raise XendError('invalid backend domain')
|
||||
|
||||
def readonly(self):
|
||||
return 'w' not in self.mode
|
||||
@@ -125,77 +207,77 @@ class BlkDev(controller.Dev):
|
||||
log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
|
||||
self.send_be_vbd_destroy()
|
||||
|
||||
def attach(self, d):
|
||||
def attach(self):
|
||||
"""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)
|
||||
backend = self.getBackend()
|
||||
d1 = backend.connect()
|
||||
d2 = defer.Deferred()
|
||||
d2.addCallback(self.send_be_vbd_create)
|
||||
d1.chainDeferred(d2)
|
||||
return d2
|
||||
|
||||
def send_be_vbd_create(self, response=None):
|
||||
def send_be_vbd_create(self, val):
|
||||
d = defer.Deferred()
|
||||
d.addCallback(self.respond_be_vbd_create)
|
||||
backend = self.getBackend()
|
||||
msg = packMsg('blkif_be_vbd_create_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.controller.handle,
|
||||
'blkif_handle' : backend.handle,
|
||||
'vdevice' : self.vdev,
|
||||
'readonly' : self.readonly() })
|
||||
self.getBackendController().writeRequest(msg, response=response)
|
||||
backend.writeRequest(msg, response=d)
|
||||
return d
|
||||
|
||||
def respond_be_vbd_create(self, msg, d):
|
||||
def respond_be_vbd_create(self, msg):
|
||||
"""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)
|
||||
d = self.send_be_vbd_grow()
|
||||
d.addCallback(self.respond_be_vbd_grow)
|
||||
return d
|
||||
|
||||
def send_be_vbd_grow(self, response=None):
|
||||
def send_be_vbd_grow(self):
|
||||
d = defer.Deferred()
|
||||
backend = self.getBackend()
|
||||
msg = packMsg('blkif_be_vbd_grow_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.controller.handle,
|
||||
'blkif_handle' : backend.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)
|
||||
backend.writeRequest(msg, response=d)
|
||||
return d
|
||||
|
||||
def respond_be_vbd_grow(self, msg, d):
|
||||
def respond_be_vbd_grow(self, msg):
|
||||
"""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"
|
||||
raise 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)
|
||||
return 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)
|
||||
backend = self.getBackend()
|
||||
msg = packMsg('blkif_be_vbd_destroy_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.controller.handle,
|
||||
'blkif_handle' : backend.handle,
|
||||
'vdevice' : self.vdev })
|
||||
self.controller.delDevice(self.vdev)
|
||||
self.getBackendController().writeRequest(msg, response=response)
|
||||
backend.writeRequest(msg, response=response)
|
||||
|
||||
|
||||
class BlkifController(controller.SplitController):
|
||||
@@ -203,12 +285,12 @@ class BlkifController(controller.SplitController):
|
||||
for a domain.
|
||||
"""
|
||||
|
||||
def __init__(self, factory, dom, backend):
|
||||
def __init__(self, factory, dom):
|
||||
"""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)
|
||||
controller.SplitController.__init__(self, factory, dom)
|
||||
self.devices = {}
|
||||
self.addMethod(CMSG_BLKIF_FE,
|
||||
CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED,
|
||||
@@ -216,25 +298,22 @@ class BlkifController(controller.SplitController):
|
||||
self.addMethod(CMSG_BLKIF_FE,
|
||||
CMSG_BLKIF_FE_INTERFACE_CONNECT,
|
||||
self.recv_fe_interface_connect)
|
||||
self.handle = 0
|
||||
self.evtchn = None
|
||||
self.registerChannel()
|
||||
|
||||
def sxpr(self):
|
||||
val = ['blkif', ['dom', self.dom]]
|
||||
if self.evtchn:
|
||||
val.append(['evtchn',
|
||||
self.evtchn['port1'],
|
||||
self.evtchn['port2']])
|
||||
return val
|
||||
|
||||
def createBackend(self, dom, handle):
|
||||
return BlkifBackendController(self, dom, handle)
|
||||
|
||||
def getDevices(self):
|
||||
return self.devices.values()
|
||||
|
||||
def getDevice(self, vdev):
|
||||
return self.devices.get(vdev)
|
||||
|
||||
def addDevice(self, vdev, mode, segment):
|
||||
def addDevice(self, config, vdev, mode, segment):
|
||||
"""Add a device to the device table.
|
||||
|
||||
@param vdev: device index
|
||||
@@ -246,8 +325,9 @@ class BlkifController(controller.SplitController):
|
||||
@return: device
|
||||
@rtype: BlkDev
|
||||
"""
|
||||
if vdev in self.devices: return None
|
||||
dev = BlkDev(self, vdev, mode, segment)
|
||||
if vdev in self.devices:
|
||||
raise XendError('device exists: ' + str(vdev))
|
||||
dev = BlkDev(self, config, vdev, mode, segment)
|
||||
self.devices[vdev] = dev
|
||||
return dev
|
||||
|
||||
@@ -255,7 +335,7 @@ class BlkifController(controller.SplitController):
|
||||
if vdev in self.devices:
|
||||
del self.devices[vdev]
|
||||
|
||||
def attachDevice(self, vdev, mode, segment, recreate=0):
|
||||
def attachDevice(self, config, vdev, mode, segment, recreate=0):
|
||||
"""Attach a device to the specified interface.
|
||||
On success the returned deferred will be called with the device.
|
||||
|
||||
@@ -270,13 +350,11 @@ class BlkifController(controller.SplitController):
|
||||
@return: deferred
|
||||
@rtype: Deferred
|
||||
"""
|
||||
dev = self.addDevice(vdev, mode, segment)
|
||||
if not dev: return -1
|
||||
d = defer.Deferred()
|
||||
dev = self.addDevice(config, vdev, mode, segment)
|
||||
if recreate:
|
||||
d.callback(dev)
|
||||
d = defer.succeed(dev)
|
||||
else:
|
||||
dev.attach(d)
|
||||
d = dev.attach()
|
||||
return d
|
||||
|
||||
def destroy(self):
|
||||
@@ -284,7 +362,7 @@ class BlkifController(controller.SplitController):
|
||||
"""
|
||||
log.debug("Destroying blkif domain=%d", self.dom)
|
||||
self.destroyDevices()
|
||||
self.disconnect()
|
||||
self.destroyBackends()
|
||||
|
||||
def destroyDevices(self):
|
||||
"""Destroy all devices.
|
||||
@@ -292,87 +370,28 @@ class BlkifController(controller.SplitController):
|
||||
for dev in self.getDevices():
|
||||
dev.destroy()
|
||||
|
||||
def connect(self, recreate=0):
|
||||
"""Connect the controller to the blkif control interface.
|
||||
def destroyBackends(self):
|
||||
for backend in self.getBackends():
|
||||
backend.destroy()
|
||||
|
||||
@param recreate: true if after xend restart
|
||||
@return: deferred
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
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):
|
||||
val = unpackMsg('blkif_fe_driver_status_changed_t', msg)
|
||||
print 'recv_fe_driver_status_changed>', val
|
||||
# For each backend?
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.handle,
|
||||
{ 'handle' : 0,
|
||||
'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)
|
||||
log.debug("Connecting blkif to event channel dom=%d ports=%d:%d",
|
||||
self.dom, self.evtchn['port1'], self.evtchn['port2'])
|
||||
msg = packMsg('blkif_be_connect_t',
|
||||
{ 'domid' : self.dom,
|
||||
'blkif_handle' : val['handle'],
|
||||
'evtchn' : self.evtchn['port1'],
|
||||
'shmem_frame' : val['shmem_frame'] })
|
||||
d = defer.Deferred()
|
||||
d.addCallback(self.respond_be_connect)
|
||||
self.backendController.writeRequest(msg, response=d)
|
||||
handle = val['handle']
|
||||
backend = self.getBackendByHandle(handle)
|
||||
if backend:
|
||||
backend.connectInterface(val)
|
||||
else:
|
||||
log.error('interface connect on unknown interface: handle=%d', handle)
|
||||
|
||||
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' : self.handle,
|
||||
'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
|
||||
'evtchn' : self.evtchn['port2'] })
|
||||
self.writeRequest(msg, response=response)
|
||||
|
||||
|
||||
@@ -372,68 +372,11 @@ class Controller(CtrlMsgRcvr):
|
||||
self.deregisterChannel()
|
||||
self.factory.instanceClosed(self)
|
||||
|
||||
class SplitControllerFactory(ControllerFactory):
|
||||
"""Factory for SplitControllers.
|
||||
|
||||
@ivar backends: mapping of domain id to backend
|
||||
@type backends: {int: BackendController}
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
ControllerFactory.__init__(self)
|
||||
self.backends = {}
|
||||
|
||||
def createInstance(self, dom, recreate=0, backend=0):
|
||||
"""Create an instance. Define in a subclass.
|
||||
|
||||
@param dom: domain
|
||||
@type dom: int
|
||||
@param recreate: true if the instance is being recreated (after xend restart)
|
||||
@type recreate: int
|
||||
@param backend: backend domain
|
||||
@type backend: int
|
||||
@return: controller instance
|
||||
@rtype: SplitController (or subclass)
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def getBackendController(self, dom):
|
||||
"""Get the backend controller for a domain.
|
||||
|
||||
@param dom: domain
|
||||
@return: backend controller
|
||||
"""
|
||||
ctrlr = self.backends.get(dom)
|
||||
if ctrlr is None:
|
||||
ctrlr = self.createBackendController(dom)
|
||||
self.backends[dom] = ctrlr
|
||||
return ctrlr
|
||||
|
||||
def createBackendController(self, dom):
|
||||
"""Create a backend controller. Define in a subclass.
|
||||
|
||||
@param dom: domain
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def delBackendController(self, ctrlr):
|
||||
"""Remove a backend controller.
|
||||
|
||||
@param ctrlr: backend controller
|
||||
"""
|
||||
if ctrlr.dom in self.backends:
|
||||
del self.backends[ctrlr.dom]
|
||||
|
||||
def backendControllerClosed(self, ctrlr):
|
||||
"""Callback called when a backend is closed.
|
||||
"""
|
||||
self.delBackendController(ctrlr)
|
||||
|
||||
class BackendController(CtrlMsgRcvr):
|
||||
"""Abstract class for a backend device controller attached to a domain.
|
||||
|
||||
@ivar factory: controller factory
|
||||
@type factory: ControllerFactory
|
||||
@ivar controller: frontend controller
|
||||
@type controller: Controller
|
||||
@ivar dom: domain
|
||||
@type dom: int
|
||||
@ivar channel: channel to the domain
|
||||
@@ -441,10 +384,11 @@ class BackendController(CtrlMsgRcvr):
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, factory, dom):
|
||||
def __init__(self, controller, dom, handle):
|
||||
CtrlMsgRcvr.__init__(self)
|
||||
self.factory = factory
|
||||
self.controller = controller
|
||||
self.dom = int(dom)
|
||||
self.handle = handle
|
||||
self.channel = None
|
||||
|
||||
def close(self):
|
||||
@@ -452,31 +396,66 @@ class BackendController(CtrlMsgRcvr):
|
||||
|
||||
def lostChannel(self):
|
||||
self.deregisterChannel()
|
||||
self.factory.instanceClosed(self)
|
||||
|
||||
|
||||
self.controller.backendClosed(self)
|
||||
|
||||
class SplitController(Controller):
|
||||
"""Abstract class for a device controller attached to a domain.
|
||||
A SplitController has a BackendContoller.
|
||||
A SplitController manages a BackendController for each backend domain
|
||||
it has at least one device for.
|
||||
"""
|
||||
|
||||
def __init__(self, factory, dom, backend):
|
||||
def __init__(self, factory, dom):
|
||||
Controller.__init__(self, factory, dom)
|
||||
self.backendDomain = None
|
||||
self.backendController = None
|
||||
self.setBackendDomain(backend)
|
||||
self.backends = {}
|
||||
self.backendHandle = 0
|
||||
|
||||
def setBackendDomain(self, dom):
|
||||
ctrlr = self.factory.getBackendController(dom)
|
||||
self.backendDomain = ctrlr.dom
|
||||
self.backendController = ctrlr
|
||||
def getBackends(self):
|
||||
return self.backends.values()
|
||||
|
||||
def getBackendDomain(self):
|
||||
return self.backendDomain
|
||||
def getBackendByHandle(self, handle):
|
||||
for b in self.getBackends():
|
||||
if b.handle == handle:
|
||||
return b
|
||||
return None
|
||||
|
||||
def getBackendController(self):
|
||||
return self.backendController
|
||||
def getBackendByDomain(self, dom):
|
||||
return self.backends.get(dom)
|
||||
|
||||
def getBackend(self, dom):
|
||||
"""Get the backend controller for a domain.
|
||||
|
||||
@param dom: domain
|
||||
@return: backend controller
|
||||
"""
|
||||
b = self.getBackendByDomain(dom)
|
||||
if b is None:
|
||||
handle = self.backendHandle
|
||||
self.backendHandle += 1
|
||||
b = self.createBackend(dom, handle)
|
||||
self.backends[b.dom] = b
|
||||
return b
|
||||
|
||||
def createBackend(self, dom, handle):
|
||||
"""Create a backend controller. Define in a subclass.
|
||||
|
||||
@param dom: domain
|
||||
@param handle: controller handle
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def delBackend(self, ctrlr):
|
||||
"""Remove a backend controller.
|
||||
|
||||
@param ctrlr: backend controller
|
||||
"""
|
||||
if ctrlr.dom in self.backends:
|
||||
del self.backends[ctrlr.dom]
|
||||
|
||||
def backendClosed(self, ctrlr):
|
||||
"""Callback called when a backend is closed.
|
||||
"""
|
||||
self.delBackend(ctrlr)
|
||||
|
||||
class Dev:
|
||||
"""Abstract class for a device attached to a device controller.
|
||||
|
||||
@@ -517,4 +496,15 @@ class Dev:
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
class SplitDev(Dev):
|
||||
|
||||
def __init__(self, idx, controller):
|
||||
Dev.__init__(self, idx, controller)
|
||||
self.backendDomain = 0
|
||||
|
||||
def getBackend(self):
|
||||
return self.controller.getBackend(self.backendDomain)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ class NetifBackendController(controller.BackendController):
|
||||
"""Handler for the 'back-end' channel to a device driver domain.
|
||||
"""
|
||||
|
||||
def __init__(self, factory, dom):
|
||||
controller.BackendController.__init__(self, factory, dom)
|
||||
def __init__(self, ctrl, dom, handle):
|
||||
controller.BackendController.__init__(self, ctrl, dom, handle)
|
||||
self.addMethod(CMSG_NETIF_BE,
|
||||
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
|
||||
self.recv_be_driver_status_changed)
|
||||
@@ -33,14 +33,14 @@ class NetifBackendController(controller.BackendController):
|
||||
val = unpackMsg('netif_be_driver_status_changed_t', msg)
|
||||
status = val['status']
|
||||
|
||||
class NetifControllerFactory(controller.SplitControllerFactory):
|
||||
class NetifControllerFactory(controller.ControllerFactory):
|
||||
"""Factory for creating network interface controllers.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
controller.ControllerFactory.__init__(self)
|
||||
|
||||
def createInstance(self, dom, recreate=0, backend=0):
|
||||
def createInstance(self, dom, recreate=0):
|
||||
"""Create or find the network interface controller for a domain.
|
||||
|
||||
@param dom: domain
|
||||
@@ -49,7 +49,7 @@ class NetifControllerFactory(controller.SplitControllerFactory):
|
||||
"""
|
||||
netif = self.getInstanceByDom(dom)
|
||||
if netif is None:
|
||||
netif = NetifController(self, dom, backend=backend)
|
||||
netif = NetifController(self, dom)
|
||||
self.addInstance(netif)
|
||||
return netif
|
||||
|
||||
@@ -72,22 +72,16 @@ class NetifControllerFactory(controller.SplitControllerFactory):
|
||||
netif = self.getInstanceByDom(dom)
|
||||
return (netif and netif.getDevice(vif)) or None
|
||||
|
||||
def createBackendController(self, dom):
|
||||
return NetifBackendController(self, dom)
|
||||
|
||||
class NetDev(controller.Dev):
|
||||
class NetDev(controller.SplitDev):
|
||||
"""Info record for a network device.
|
||||
"""
|
||||
|
||||
def __init__(self, ctrl, vif, config):
|
||||
controller.Dev.__init__(self, vif, ctrl)
|
||||
controller.SplitDev.__init__(self, vif, ctrl)
|
||||
self.vif = vif
|
||||
self.evtchn = None
|
||||
self.configure(config)
|
||||
|
||||
def getBackendController(self):
|
||||
return self.controller.backendController
|
||||
|
||||
def configure(self, config):
|
||||
self.config = config
|
||||
self.mac = None
|
||||
@@ -108,6 +102,11 @@ class NetDev(controller.Dev):
|
||||
for ipaddr in ipaddrs:
|
||||
self.ipaddr.append(sxp.child0(ipaddr))
|
||||
|
||||
try:
|
||||
self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
|
||||
except:
|
||||
raise XendError('invalid backend domain')
|
||||
|
||||
def sxpr(self):
|
||||
vif = str(self.vif)
|
||||
mac = self.get_mac()
|
||||
@@ -168,16 +167,25 @@ 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 attach(self):
|
||||
print 'attach>'
|
||||
d = self.send_be_create()
|
||||
d.addCallback(self.respond_be_create)
|
||||
return d
|
||||
|
||||
def send_be_create(self, response=None):
|
||||
def send_be_create(self):
|
||||
d = defer.Deferred()
|
||||
msg = packMsg('netif_be_create_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'netif_handle' : self.vif,
|
||||
'mac' : self.mac })
|
||||
self.getBackendController().writeRequest(msg, response=response)
|
||||
self.getBackend().writeRequest(msg, response=d)
|
||||
return d
|
||||
|
||||
def respond_be_create(self, msg):
|
||||
val = unpackMsg('netif_be_create_t', msg)
|
||||
print 'respond_be_create>', val
|
||||
return self
|
||||
|
||||
def destroy(self):
|
||||
"""Destroy the device's resources and disconnect from the back-end
|
||||
@@ -187,22 +195,23 @@ class NetDev(controller.Dev):
|
||||
self.send_be_destroy()
|
||||
log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
|
||||
self.vifctl('down')
|
||||
d = defer.Deferred()
|
||||
d = self.send_be_disconnect()
|
||||
d.addCallback(cb_destroy)
|
||||
self.send_be_disconnect(response=d)
|
||||
|
||||
def send_be_disconnect(self, response=None):
|
||||
def send_be_disconnect(self):
|
||||
d = defer.Deferred()
|
||||
msg = packMsg('netif_be_disconnect_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'netif_handle' : self.vif })
|
||||
self.getBackendController().writeRequest(msg, response=response)
|
||||
self.getBackend().writeRequest(msg, response=d)
|
||||
return d
|
||||
|
||||
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)
|
||||
self.getBackend().writeRequest(msg, response=response)
|
||||
|
||||
def recv_fe_interface_connect(self, val, req):
|
||||
if not req: return
|
||||
@@ -215,14 +224,12 @@ class NetDev(controller.Dev):
|
||||
'rx_shmem_frame' : val['rx_shmem_frame'] })
|
||||
d = defer.Deferred()
|
||||
d.addCallback(self.respond_be_connect)
|
||||
self.getBackendController().writeRequest(msg, response=d)
|
||||
self.getBackend().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,
|
||||
@@ -242,8 +249,8 @@ class NetifController(controller.SplitController):
|
||||
"""Network interface controller. Handles all network devices for a domain.
|
||||
"""
|
||||
|
||||
def __init__(self, factory, dom, backend):
|
||||
controller.SplitController.__init__(self, factory, dom, backend)
|
||||
def __init__(self, factory, dom):
|
||||
controller.SplitController.__init__(self, factory, dom)
|
||||
self.devices = {}
|
||||
self.addMethod(CMSG_NETIF_FE,
|
||||
CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
|
||||
@@ -253,6 +260,9 @@ class NetifController(controller.SplitController):
|
||||
self.recv_fe_interface_connect)
|
||||
self.registerChannel()
|
||||
|
||||
def createBackend(self, dom, handle):
|
||||
return NetifBackendController(self, dom, handle)
|
||||
|
||||
def sxpr(self):
|
||||
val = ['netif', ['dom', self.dom]]
|
||||
return val
|
||||
@@ -282,6 +292,8 @@ class NetifController(controller.SplitController):
|
||||
@param config: device configuration
|
||||
@return: device
|
||||
"""
|
||||
if vif in self.devices:
|
||||
raise XendError('device exists:' + str(vif))
|
||||
dev = NetDev(self, vif, config)
|
||||
self.devices[vif] = dev
|
||||
return dev
|
||||
@@ -310,11 +322,10 @@ class NetifController(controller.SplitController):
|
||||
@return: deferred
|
||||
"""
|
||||
dev = self.addDevice(vif, config)
|
||||
d = defer.Deferred()
|
||||
if recreate:
|
||||
d.callback(self)
|
||||
d = defer.succeed(dev)
|
||||
else:
|
||||
dev.attach(d)
|
||||
d = dev.attach()
|
||||
return d
|
||||
|
||||
def recv_fe_driver_status_changed(self, msg, req):
|
||||
@@ -333,5 +344,6 @@ class NetifController(controller.SplitController):
|
||||
if dev:
|
||||
dev.recv_fe_interface_connect(val, req)
|
||||
else:
|
||||
log.error('Received netif_fe_interface_connect for unknown vif: '+vif)
|
||||
log.error('Received netif_fe_interface_connect for unknown vif: dom=%d vif=%d',
|
||||
self.dom, vif)
|
||||
|
||||
@@ -126,19 +126,12 @@ gopts.var('netif', val='no|yes',
|
||||
fn=set_bool, default=0,
|
||||
use="Make the domain a network interface backend.")
|
||||
|
||||
gopts.var('vbd_backend', val='DOM',
|
||||
fn=set_value, default=None,
|
||||
use='Set the domain to use for the vbd backend.')
|
||||
|
||||
gopts.var('vif_backend', val='DOM',
|
||||
fn=set_value, default=None,
|
||||
use='Set the domain to use for the vif backend.')
|
||||
|
||||
gopts.var('disk', val='phy:DEV,VDEV,MODE',
|
||||
gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
|
||||
fn=append_value, default=[],
|
||||
use="""Add a disk device to a domain. The physical device is DEV,
|
||||
which is exported to the domain as VDEV. The disk is read-only if MODE
|
||||
is 'r', read-write if MODE is 'w'.
|
||||
is 'r', read-write if MODE is 'w'. If DOM is specified it defines the
|
||||
backend driver domain to use for the disk.
|
||||
The option may be repeated to add more than one disk.
|
||||
""")
|
||||
|
||||
@@ -153,13 +146,14 @@ gopts.var('ipaddr', val="IPADDR",
|
||||
fn=append_value, default=[],
|
||||
use="Add an IP address to the domain.")
|
||||
|
||||
gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT",
|
||||
gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM",
|
||||
fn=append_value, default=[],
|
||||
use="""Add a network interface with the given MAC address and bridge.
|
||||
The vif is configured by calling the given configuration script.
|
||||
If mac is not specified a random MAC address is used.
|
||||
If bridge is not specified the default bridge is used.
|
||||
If script is not specified the default script is used.
|
||||
If backend is not specified the default backend driver domain is used.
|
||||
This option may be repeated to add more than one vif.
|
||||
Specifying vifs will increase the number of interfaces as needed.
|
||||
""")
|
||||
@@ -241,11 +235,13 @@ def configure_image(config, vals):
|
||||
def configure_disks(config_devs, vals):
|
||||
"""Create the config for disks (virtual block devices).
|
||||
"""
|
||||
for (uname, dev, mode) in vals.disk:
|
||||
for (uname, dev, mode, backend) in vals.disk:
|
||||
config_vbd = ['vbd',
|
||||
['uname', uname],
|
||||
['dev', dev ],
|
||||
['mode', mode ] ]
|
||||
if backend:
|
||||
config_vbd.append(['backend', backend])
|
||||
config_devs.append(['device', config_vbd])
|
||||
|
||||
def configure_pci(config_devs, vals):
|
||||
@@ -285,16 +281,20 @@ def configure_vifs(config_devs, vals):
|
||||
mac = d.get('mac')
|
||||
bridge = d.get('bridge')
|
||||
script = d.get('script')
|
||||
backend = d.get('backend')
|
||||
else:
|
||||
mac = randomMAC()
|
||||
bridge = None
|
||||
script = None
|
||||
backend = None
|
||||
config_vif = ['vif']
|
||||
config_vif.append(['mac', mac])
|
||||
if bridge:
|
||||
config_vif.append(['bridge', bridge])
|
||||
if script:
|
||||
config_vif.append(['script', script])
|
||||
if backend:
|
||||
config_vif.append(['backend', backend])
|
||||
config_devs.append(['device', config_vif])
|
||||
|
||||
def configure_vfr(config, vals):
|
||||
@@ -320,10 +320,6 @@ def make_config(vals):
|
||||
config.append(['backend', ['blkif']])
|
||||
if vals.netif:
|
||||
config.append(['backend', ['netif']])
|
||||
if vals.vbd_backend:
|
||||
config.append(['backend', ['vbd', ['dom', vals.vbd_backend]]])
|
||||
if vals.vif_backend:
|
||||
config.append(['backend', ['vif', ['dom', vals.vif_backend]]])
|
||||
if vals.restart:
|
||||
config.append(['restart', vals.restart])
|
||||
if vals.console:
|
||||
@@ -342,7 +338,12 @@ def preprocess_disk(opts, vals):
|
||||
disk = []
|
||||
for v in vals.disk:
|
||||
d = v.split(',')
|
||||
if len(d) != 3:
|
||||
n = len(d)
|
||||
if n == 3:
|
||||
d.append(none)
|
||||
elif n == 4:
|
||||
pass
|
||||
else:
|
||||
opts.err('Invalid disk specifier: ' + v)
|
||||
disk.append(d)
|
||||
vals.disk = disk
|
||||
@@ -369,7 +370,7 @@ def preprocess_vifs(opts, vals):
|
||||
(k, v) = b.strip().split('=', 1)
|
||||
k = k.strip()
|
||||
v = v.strip()
|
||||
if k not in ['mac', 'bridge']:
|
||||
if k not in ['mac', 'bridge', 'script', 'backend']:
|
||||
opts.err('Invalid vif specifier: ' + vif)
|
||||
d[k] = v
|
||||
vifs.append(d)
|
||||
|
||||