43a3b335a6
- lxc AppArmor profile now only restricting potentially dangerous accesses. fdo#886460 - added patches: * 9265f8ab-apparmor-lxc-rework.patch * 9b1e4cd5-skip-useless-apparmor-files.patch - virt-lxc-convert: force free to output values in bytes - added patches: * dba3432b-virt-lxc-convert-fix.patch - lxc: allow setting a custom name for container NICs as LXC is is able to do it. lxc-net-target-name.patch, lxc-net-target-name-conversion.patch, lxc-net-target-name-doc.patch OBS-URL: https://build.opensuse.org/request/show/241206 OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=390
270 lines
9.4 KiB
Diff
270 lines
9.4 KiB
Diff
From 2dd011bd1451e5e6e41c0fbe98884d7594a46dc1 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
|
|
Date: Fri, 27 Jun 2014 10:41:22 +0200
|
|
Subject: [PATCH] lxc network configuration allows setting target container NIC
|
|
name
|
|
|
|
LXC network devices can now be assigned a custom NIC device name on the
|
|
container side. For example, this is configured with:
|
|
|
|
<interface type='network'>
|
|
<source network='default'/>
|
|
<guest dev="eth1"/>
|
|
</interface>
|
|
|
|
In this example the network card will appear as eth1 in the guest.
|
|
---
|
|
docs/schemas/domaincommon.rng | 17 +++++++++++++++++
|
|
src/conf/domain_conf.c | 27 +++++++++++++++++++++++++++
|
|
src/conf/domain_conf.h | 2 ++
|
|
src/lxc/lxc_container.c | 29 +++++++++++++++++++++++++----
|
|
src/lxc/lxc_process.c | 25 +++++++++++++++++++++++++
|
|
tests/lxcxml2xmldata/lxc-idmap.xml | 1 +
|
|
6 files changed, 97 insertions(+), 4 deletions(-)
|
|
|
|
Index: libvirt-1.2.5/docs/schemas/domaincommon.rng
|
|
===================================================================
|
|
--- libvirt-1.2.5.orig/docs/schemas/domaincommon.rng
|
|
+++ libvirt-1.2.5/docs/schemas/domaincommon.rng
|
|
@@ -2165,6 +2165,23 @@
|
|
</element>
|
|
</optional>
|
|
<optional>
|
|
+ <element name="guest">
|
|
+ <interleave>
|
|
+ <optional>
|
|
+ <attribute name="dev">
|
|
+ <ref name="deviceName"/>
|
|
+ </attribute>
|
|
+ </optional>
|
|
+ <optional>
|
|
+ <attribute name="actual">
|
|
+ <ref name="deviceName"/>
|
|
+ </attribute>
|
|
+ </optional>
|
|
+ </interleave>
|
|
+ <empty/>
|
|
+ </element>
|
|
+ </optional>
|
|
+ <optional>
|
|
<element name="mac">
|
|
<attribute name="address">
|
|
<ref name="uniMacAddr"/>
|
|
Index: libvirt-1.2.5/src/conf/domain_conf.c
|
|
===================================================================
|
|
--- libvirt-1.2.5.orig/src/conf/domain_conf.c
|
|
+++ libvirt-1.2.5/src/conf/domain_conf.c
|
|
@@ -1415,6 +1415,8 @@ void virDomainNetDefFree(virDomainNetDef
|
|
VIR_FREE(def->virtPortProfile);
|
|
VIR_FREE(def->script);
|
|
VIR_FREE(def->ifname);
|
|
+ VIR_FREE(def->ifname_guest);
|
|
+ VIR_FREE(def->ifname_guest_actual);
|
|
|
|
virDomainDeviceInfoClear(&def->info);
|
|
|
|
@@ -6621,6 +6623,8 @@ virDomainNetDefParseXML(virDomainXMLOpti
|
|
char *bridge = NULL;
|
|
char *dev = NULL;
|
|
char *ifname = NULL;
|
|
+ char *ifname_guest = NULL;
|
|
+ char *ifname_guest_actual = NULL;
|
|
char *script = NULL;
|
|
char *address = NULL;
|
|
char *port = NULL;
|
|
@@ -6726,6 +6730,10 @@ virDomainNetDefParseXML(virDomainXMLOpti
|
|
/* An auto-generated target name, blank it out */
|
|
VIR_FREE(ifname);
|
|
}
|
|
+ } else if ((!ifname_guest || !ifname_guest_actual) &&
|
|
+ xmlStrEqual(cur->name, BAD_CAST "guest")) {
|
|
+ ifname_guest = virXMLPropString(cur, "dev");
|
|
+ ifname_guest_actual = virXMLPropString(cur, "actual");
|
|
} else if (!linkstate &&
|
|
xmlStrEqual(cur->name, BAD_CAST "link")) {
|
|
linkstate = virXMLPropString(cur, "state");
|
|
@@ -6967,6 +6975,14 @@ virDomainNetDefParseXML(virDomainXMLOpti
|
|
def->ifname = ifname;
|
|
ifname = NULL;
|
|
}
|
|
+ if (ifname_guest != NULL) {
|
|
+ def->ifname_guest = ifname_guest;
|
|
+ ifname_guest = NULL;
|
|
+ }
|
|
+ if (ifname_guest_actual != NULL) {
|
|
+ def->ifname_guest_actual = ifname_guest_actual;
|
|
+ ifname_guest_actual = NULL;
|
|
+ }
|
|
|
|
/* NIC model (see -net nic,model=?). We only check that it looks
|
|
* reasonable, not that it is a supported NIC type. FWIW kvm
|
|
@@ -15918,6 +15934,17 @@ virDomainNetDefFormat(virBufferPtr buf,
|
|
/* Skip auto-generated target names for inactive config. */
|
|
virBufferEscapeString(buf, "<target dev='%s'/>\n", def->ifname);
|
|
}
|
|
+ if (def->ifname_guest || def->ifname_guest_actual) {
|
|
+ virBufferAddLit(buf, "<guest");
|
|
+ /* Skip auto-generated target names for inactive config. */
|
|
+ if (def->ifname_guest)
|
|
+ virBufferEscapeString(buf, " dev='%s'", def->ifname_guest);
|
|
+
|
|
+ /* Only set if the host is running, so shouldn't pollute output */
|
|
+ if (def->ifname_guest_actual)
|
|
+ virBufferEscapeString(buf, " actual='%s'", def->ifname_guest_actual);
|
|
+ virBufferAddLit(buf, "/>\n");
|
|
+ }
|
|
if (def->model) {
|
|
virBufferEscapeString(buf, "<model type='%s'/>\n",
|
|
def->model);
|
|
Index: libvirt-1.2.5/src/conf/domain_conf.h
|
|
===================================================================
|
|
--- libvirt-1.2.5.orig/src/conf/domain_conf.h
|
|
+++ libvirt-1.2.5/src/conf/domain_conf.h
|
|
@@ -916,6 +916,8 @@ struct _virDomainNetDef {
|
|
} tune;
|
|
char *script;
|
|
char *ifname;
|
|
+ char *ifname_guest;
|
|
+ char *ifname_guest_actual;
|
|
virDomainDeviceInfo info;
|
|
char *filter;
|
|
virNWFilterHashTablePtr filterparams;
|
|
Index: libvirt-1.2.5/src/lxc/lxc_container.c
|
|
===================================================================
|
|
--- libvirt-1.2.5.orig/src/lxc/lxc_container.c
|
|
+++ libvirt-1.2.5/src/lxc/lxc_container.c
|
|
@@ -464,6 +464,21 @@ static int lxcContainerSetID(virDomainDe
|
|
}
|
|
|
|
|
|
+static virDomainNetDefPtr
|
|
+lxcContainerGetNetDef(virDomainDefPtr vmDef, const char *devName)
|
|
+{
|
|
+ size_t i;
|
|
+ virDomainNetDefPtr netDef;
|
|
+
|
|
+ for (i = 0; i < vmDef->nnets; i++) {
|
|
+ netDef = vmDef->nets[i];
|
|
+ if (STREQ(netDef->ifname_guest_actual, devName))
|
|
+ return netDef;
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
/**
|
|
* lxcContainerRenameAndEnableInterfaces:
|
|
* @nveths: number of interfaces
|
|
@@ -475,16 +490,23 @@ static int lxcContainerSetID(virDomainDe
|
|
*
|
|
* Returns 0 on success or nonzero in case of error
|
|
*/
|
|
-static int lxcContainerRenameAndEnableInterfaces(bool privNet,
|
|
+static int lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef,
|
|
size_t nveths,
|
|
char **veths)
|
|
{
|
|
int rc = 0;
|
|
size_t i;
|
|
char *newname = NULL;
|
|
+ virDomainNetDefPtr netDef;
|
|
+ bool privNet = vmDef->features[VIR_DOMAIN_FEATURE_PRIVNET] ==
|
|
+ VIR_DOMAIN_FEATURE_STATE_ON;
|
|
|
|
for (i = 0; i < nveths; i++) {
|
|
- if (virAsprintf(&newname, "eth%zu", i) < 0) {
|
|
+ if (!(netDef = lxcContainerGetNetDef(vmDef, veths[i])))
|
|
+ return -1;
|
|
+
|
|
+ newname = netDef->ifname_guest;
|
|
+ if (!newname) {
|
|
rc = -1;
|
|
goto error_out;
|
|
}
|
|
@@ -2074,8 +2096,7 @@ static int lxcContainerChild(void *data)
|
|
}
|
|
|
|
/* rename and enable interfaces */
|
|
- if (lxcContainerRenameAndEnableInterfaces(vmDef->features[VIR_DOMAIN_FEATURE_PRIVNET] ==
|
|
- VIR_DOMAIN_FEATURE_STATE_ON,
|
|
+ if (lxcContainerRenameAndEnableInterfaces(vmDef,
|
|
argv->nveths,
|
|
argv->veths) < 0) {
|
|
goto cleanup;
|
|
Index: libvirt-1.2.5/src/lxc/lxc_process.c
|
|
===================================================================
|
|
--- libvirt-1.2.5.orig/src/lxc/lxc_process.c
|
|
+++ libvirt-1.2.5/src/lxc/lxc_process.c
|
|
@@ -259,6 +259,8 @@ char *virLXCProcessSetupInterfaceBridged
|
|
|
|
if (virNetDevSetMAC(containerVeth, &net->mac) < 0)
|
|
goto cleanup;
|
|
+ if (VIR_STRDUP(net->ifname_guest_actual, containerVeth) < 0)
|
|
+ goto cleanup;
|
|
|
|
if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
|
|
if (virNetDevOpenvswitchAddPort(brname, parentVeth, &net->mac,
|
|
@@ -369,6 +371,7 @@ static int virLXCProcessSetupInterfaces(
|
|
{
|
|
int ret = -1;
|
|
size_t i;
|
|
+ size_t niface = 0;
|
|
|
|
for (i = 0; i < def->nnets; i++) {
|
|
char *veth = NULL;
|
|
@@ -451,6 +454,13 @@ static int virLXCProcessSetupInterfaces(
|
|
}
|
|
|
|
(*veths)[(*nveths)-1] = veth;
|
|
+
|
|
+ /* Make sure all net definitions will have a name in the container */
|
|
+ if (!def->nets[i]->ifname_guest) {
|
|
+ if (virAsprintf(&def->nets[i]->ifname_guest, "eth%zu", niface) < 0)
|
|
+ return -1;
|
|
+ niface++;
|
|
+ }
|
|
}
|
|
|
|
ret = 0;
|
|
@@ -470,6 +480,18 @@ static int virLXCProcessSetupInterfaces(
|
|
return ret;
|
|
}
|
|
|
|
+static void
|
|
+virLXCProcessCleanInterfaces(virDomainDefPtr def)
|
|
+{
|
|
+ size_t i;
|
|
+
|
|
+ for (i = 0; i < def->nnets; i++) {
|
|
+ VIR_FREE(def->nets[i]->ifname_guest_actual);
|
|
+ def->nets[i]->ifname_guest_actual = NULL;
|
|
+ VIR_DEBUG("Cleared net names: %s", def->nets[i]->ifname_guest);
|
|
+ }
|
|
+}
|
|
+
|
|
|
|
extern virLXCDriverPtr lxc_driver;
|
|
static void virLXCProcessMonitorEOFNotify(virLXCMonitorPtr mon,
|
|
@@ -1306,6 +1328,9 @@ int virLXCProcessStart(virConnectPtr con
|
|
vm, false) < 0)
|
|
goto error;
|
|
|
|
+ /* We don't need the temporary NIC names anymore, clear them */
|
|
+ virLXCProcessCleanInterfaces(vm->def);
|
|
+
|
|
/* Write domain status to disk.
|
|
*
|
|
* XXX: Earlier we wrote the plain "live" domain XML to this
|
|
Index: libvirt-1.2.5/tests/lxcxml2xmldata/lxc-idmap.xml
|
|
===================================================================
|
|
--- libvirt-1.2.5.orig/tests/lxcxml2xmldata/lxc-idmap.xml
|
|
+++ libvirt-1.2.5/tests/lxcxml2xmldata/lxc-idmap.xml
|
|
@@ -29,6 +29,7 @@
|
|
<mac address='00:16:3e:0f:ef:8a'/>
|
|
<source bridge='bri0'/>
|
|
<target dev='veth0'/>
|
|
+ <guest dev='eth2'/>
|
|
</interface>
|
|
<console type='pty'>
|
|
<target type='lxc' port='0'/>
|