diff --git a/docs/xen_config.html b/docs/xen_config.html
index 45499667ac..81258c5189 100644
--- a/docs/xen_config.html
+++ b/docs/xen_config.html
@@ -62,7 +62,7 @@ The top-level element, a virtual machine configuration.
memory: int, required. Domain memory in MB.
cpu: int, optional. Cpu to run on.
image: linux | netbsd | ..., required. Domain image (OS-specific element).
- controller: any device controller type, optional, default none.
+ backend: any backend device type, optional, default none.
device: any device type, optional, repeats. Device.
restart: string, optional, default onreboot. Restart mode, one of
- onreboot: restart the domain when it exits with code reboot.
@@ -99,7 +99,21 @@ block devices.
(backend (netif)) element
The vm is a net device backend.
-The domain may not have virtual network interfaces (vifs) configured.
+The vm may not have virtual network interfaces (vifs) configured.
+
+(backend (vbd) element
+Defines the domain to use as the backend for virtual block devices.
+The domain must exist.
+
+ - domain: string, required. Domain name or id.
+
+
+(backend (vif) element
+Defines the domain to use as the backend for virtual network interfaces.
+The domain must exist.
+
+ - dom: string, required. Domain name or id.
+
(device (vif)) element
Defines a virtual network interface.
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index ce01d28b0a..0f17c10b4e 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -69,6 +69,12 @@ STATE_RESTART_BOOTING = 'booting'
STATE_VM_OK = "ok"
STATE_VM_TERMINATED = "terminated"
+
+def domain_exists(name):
+ # See comment in XendDomain constructor.
+ xd = get_component('xen.xend.XendDomain')
+ return xd.domain_exists(name)
+
def shutdown_reason(code):
"""Get a shutdown reason from a code.
@@ -131,10 +137,10 @@ def lookup_disk_uname(uname):
segments = None
return segments
-def make_disk(dom, uname, dev, mode, recreate=0):
+def make_disk(vm, uname, dev, mode, recreate=0):
"""Create a virtual disk device for a domain.
- @param dom: domain id
+ @param vm: vm
@param uname: device to export
@param dev: device name in domain
@param mode: read/write mode
@@ -148,10 +154,11 @@ def make_disk(dom, uname, dev, mode, recreate=0):
raise VmError("vbd: Multi-segment vdisk: uname=%s" % uname)
segment = segments[0]
vdev = blkdev_name_to_number(dev)
- ctrl = xend.blkif_create(dom, recreate=recreate)
+ backend = vm.get_device_backend('vbd')
+ ctrl = xend.blkif_create(vm.dom, recreate=recreate, backend=backend)
def fn(ctrl):
- return xend.blkif_dev_create(dom, vdev, mode, segment, recreate=recreate)
+ return xend.blkif_dev_create(vm.dom, vdev, mode, segment, recreate=recreate)
ctrl.addCallback(fn)
return ctrl
@@ -371,6 +378,7 @@ class XendDomainInfo:
self.console = None
self.devices = {}
self.device_index = {}
+ self.device_backends = {}
self.configs = []
self.info = None
self.ipaddrs = []
@@ -466,9 +474,7 @@ class XendDomainInfo:
if c in '_-.': continue
if c in string.ascii_letters: continue
raise VmError('invalid vm name')
- # See comment in XendDomain constructor.
- xd = get_component('xen.xend.XendDomain')
- dominfo = xd.domain_exists(name)
+ dominfo = domain_exists(name)
# When creating or rebooting, a domain with my name should not exist.
# When restoring, a domain with my name will exist, but it should have
# my domain id.
@@ -663,6 +669,7 @@ class XendDomainInfo:
self.devices = {}
self.device_index = {}
+ self.device_backends = {}
self.configs = []
self.ipaddrs = []
@@ -901,15 +908,40 @@ 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 of blkif.
+ """Set configuration flags if the vm is a backend for netif or blkif.
+ Configure the backends to use for vbd and vif if specified.
"""
for c in sxp.children(self.config, 'backend'):
- name = sxp.name(sxp.child0(c))
+ v = sxp.child0(c)
+ name = sxp.name(v)
if name == 'blkif':
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))
@@ -1039,7 +1071,8 @@ 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")
- xend.netif_create(vm.dom, recreate=vm.recreate)
+ backend = vm.get_device_backend('vif')
+ xend.netif_create(vm.dom, recreate=vm.recreate, backend=backend)
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):
@@ -1068,7 +1101,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.dom, uname, dev, mode, vm.recreate)
+ defer = make_disk(vm, uname, dev, mode, vm.recreate)
def fn(vbd):
vbd.dev = dev
vbd.uname = uname
diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py
index aaeef6d54c..e6a1f30900 100644
--- a/tools/python/xen/xend/server/SrvDaemon.py
+++ b/tools/python/xen/xend/server/SrvDaemon.py
@@ -661,12 +661,12 @@ class Daemon:
"""
return self.blkifCF.getControlDomain()
- def blkif_create(self, dom, recreate=0):
+ def blkif_create(self, dom, recreate=0, backend=0):
"""Create a block device interface controller.
Returns Deferred
"""
- d = self.blkifCF.createInstance(dom, recreate=recreate)
+ d = self.blkifCF.createInstance(dom, recreate=recreate, backend=backend)
return d
def blkifs(self):
@@ -699,11 +699,11 @@ class Daemon:
"""
return self.netifCF.getControlDomain()
- def netif_create(self, dom, recreate=0):
+ def netif_create(self, dom, recreate=0, backend=0):
"""Create a network interface controller.
"""
- return self.netifCF.createInstance(dom, recreate=recreate)
+ return self.netifCF.createInstance(dom, recreate=recreate, backend=backend)
def netifs(self):
return [ x.sxpr() for x in self.netifCF.getInstances() ]
diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py
index 69d6fb0b1f..e9f45e9713 100644
--- a/tools/python/xen/xm/create.py
+++ b/tools/python/xen/xm/create.py
@@ -121,6 +121,14 @@ 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',
fn=append_value, default=[],
use="""Add a disk device to a domain. The physical device is DEV,
@@ -306,6 +314,10 @@ 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: