At least Xen supports backend drivers in another domain (aka "driver
domain"). This patch introduces XML config option for such setting as
'domain' element with 'name' attribute. Verification its content is left
for the driver.
In the future some option will be needed for USB devices (hostdev
objects), but for now libxl doesn't have support for PVUSB.
Signed-off-by: Marek Marczykowski-Górecki <marmarek(a)invisiblethingslab.com>
---
Changes in v2:
- describe in docs/formatdomain.html.in
- enforce empty domain tag (only 'name' attribute allowed)
Changes in v3:
- fix grammar of the documentation
docs/formatdomain.html.in | 29 +++++++++++++++++++++++++++++
docs/schemas/domaincommon.rng | 16 ++++++++++++++++
src/conf/domain_conf.c | 28 ++++++++++++++++++++++++++++
src/conf/domain_conf.h | 2 ++
4 files changed, 75 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 755d084..9c67b5b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1751,6 +1751,13 @@
</li>
</ul>
</dd>
+ <dt><code>domain</code></dt>
+ <dd>The optional <code>domain</code> element allows to specify a
+ backend domain (aka driver domain) for the device. If actual device/file
+ resides in some other domain on the same host, use the
<code>name</code>
+ attribute to specify its name.
+ <span class="since">Since 1.0.7 (Xen only)</span>
+ </dd>
<dt><code>boot</code></dt>
<dd>Specifies that the disk is bootable. The <code>order</code>
attribute determines the order in which devices will be tried during
@@ -3554,6 +3561,28 @@ qemu-kvm -net nic,model=? /dev/null
element is unspecified is to have the link state <code>up</code>.
<span class="since">Since 0.9.5</span>
</p>
+ <h5><a name="elementDomain">Setting up a network backend in a
driver domain</a></h5>
+<pre>
+ ...
+ <devices>
+ ...
+ <interface type='bridge'>
+ <source bridge='br0'/>
+ <b><domain name='netvm'/></b>
+ </interface>
+ ...
+ </devices>
+ ...</pre>
+
+ <p>
+ The optional <code>domain</code> element allows to specify a backend
+ domain (aka driver domain) for the device. Use the <code>name</code>
+ attribute to specify its name. You can use it to create a direct network
+ link between domains (so data will not go through the host system). Use
+ with type 'ethernet' to create a plain network link, or with
'bridge' to
+ connect to some bridge inside the driver domain.
+ <span class="since">Since 1.0.7 (Xen only)</span>
+ </p>
<h4><a name="elementsInput">Input devices</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 1eb2f68..6fe4d90 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -908,6 +908,14 @@
</optional>
<ref name="target"/>
<optional>
+ <element name="domain">
+ <attribute name="name">
+ <ref name="domainName"/>
+ </attribute>
+ <empty/>
+ </element>
+ </optional>
+ <optional>
<ref name="deviceBoot"/>
</optional>
<optional>
@@ -1981,6 +1989,14 @@
</element>
</optional>
<optional>
+ <element name="domain">
+ <attribute name="name">
+ <ref name="domainName"/>
+ </attribute>
+ <empty/>
+ </element>
+ </optional>
+ <optional>
<element name="model">
<attribute name="type">
<data type="string">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2373397..5350c56 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1183,6 +1183,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
VIR_FREE(def->wwn);
VIR_FREE(def->vendor);
VIR_FREE(def->product);
+ VIR_FREE(def->domain_name);
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE)
VIR_FREE(def->auth.secret.usage);
virStorageEncryptionFree(def->encryption);
@@ -1308,6 +1309,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
VIR_FREE(def->virtPortProfile);
VIR_FREE(def->script);
+ VIR_FREE(def->domain_name);
VIR_FREE(def->ifname);
virDomainDeviceInfoClear(&def->info);
@@ -4693,6 +4695,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
char *vendor = NULL;
char *product = NULL;
char *discard = NULL;
+ char *domain_name = NULL;
int expected_secret_usage = -1;
int auth_secret_usage = -1;
@@ -4853,6 +4856,9 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
if (target &&
STRPREFIX(target, "ioemu:"))
memmove(target, target+6, strlen(target)-5);
+ } else if (!domain_name &&
+ xmlStrEqual(cur->name, BAD_CAST "domain")) {
+ domain_name = virXMLPropString(cur, "name");
} else if (xmlStrEqual(cur->name, BAD_CAST "geometry")) {
if (virXPathUInt("string(./geometry/@cyls)",
ctxt, &def->geometry.cylinders) < 0) {
@@ -5148,6 +5154,11 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
ctxt->node = saved_node;
}
+ if (domain_name != NULL) {
+ def->domain_name = domain_name;
+ domain_name = NULL;
+ }
+
if (target == NULL) {
if (def->srcpool) {
char *tmp;
@@ -5504,6 +5515,7 @@ cleanup:
VIR_FREE(wwn);
VIR_FREE(vendor);
VIR_FREE(product);
+ VIR_FREE(domain_name);
ctxt->node = save_ctxt;
return def;
@@ -6109,6 +6121,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
char *mode = NULL;
char *linkstate = NULL;
char *addrtype = NULL;
+ char *domain_name = NULL;
virNWFilterHashTablePtr filterparams = NULL;
virDomainActualNetDefPtr actual = NULL;
xmlNodePtr oldnode = ctxt->node;
@@ -6207,6 +6220,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
} else if (!script &&
xmlStrEqual(cur->name, BAD_CAST "script")) {
script = virXMLPropString(cur, "path");
+ } else if (!domain_name &&
+ xmlStrEqual(cur->name, BAD_CAST "domain")) {
+ domain_name = virXMLPropString(cur, "name");
} else if (xmlStrEqual(cur->name, BAD_CAST "model")) {
model = virXMLPropString(cur, "type");
} else if (xmlStrEqual(cur->name, BAD_CAST "driver")) {
@@ -6437,6 +6453,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
def->script = script;
script = NULL;
}
+ if (domain_name != NULL) {
+ def->domain_name = domain_name;
+ domain_name = NULL;
+ }
if (ifname != NULL) {
def->ifname = ifname;
ifname = NULL;
@@ -6574,6 +6594,7 @@ cleanup:
VIR_FREE(mode);
VIR_FREE(linkstate);
VIR_FREE(addrtype);
+ VIR_FREE(domain_name);
virNWFilterHashTableFree(filterparams);
return def;
@@ -14018,6 +14039,11 @@ virDomainDiskDefFormat(virBufferPtr buf,
if (virDomainDiskSourceDefFormat(buf, def) < 0)
return -1;
+
+ if (def->domain_name) {
+ virBufferEscapeString(buf, " <domain name='%s'/>\n",
def->domain_name);
+ }
+
virDomainDiskGeometryDefFormat(buf, def);
virDomainDiskBlockIoDefFormat(buf, def);
@@ -14601,6 +14627,8 @@ virDomainNetDefFormat(virBufferPtr buf,
return -1;
virBufferEscapeString(buf, "<script path='%s'/>\n",
def->script);
+ if (def->domain_name)
+ virBufferEscapeString(buf, "<domain name='%s'/>\n",
def->domain_name);
if (def->ifname &&
!((flags & VIR_DOMAIN_XML_INACTIVE) &&
(STRPREFIX(def->ifname, VIR_NET_GENERATED_PREFIX)))) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5b159ac..24d3809 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -718,6 +718,7 @@ struct _virDomainDiskDef {
int rawio; /* no = 0, yes = 1 */
int sgio; /* enum virDomainDeviceSGIO */
int discard; /* enum virDomainDiskDiscard */
+ char *domain_name; /* backend domain name */
size_t nseclabels;
virSecurityDeviceLabelDefPtr *seclabels;
@@ -981,6 +982,7 @@ struct _virDomainNetDef {
unsigned long sndbuf;
} tune;
char *script;
+ char *domain_name; /* backend domain name */
char *ifname;
virDomainDeviceInfo info;
char *filter;
--
1.8.1.4