Accepting request 241206 from home:cbosdonnat:branches:Virtualization

- 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
This commit is contained in:
Cédric Bosdonnat 2014-07-16 13:45:18 +00:00 committed by Git OBS Bridge
parent 803ff43893
commit 43a3b335a6
9 changed files with 887 additions and 3 deletions

View File

@ -0,0 +1,358 @@
From 9265f8ab67dc14fe89a26efd5c22b156d3168fd6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
Date: Tue, 15 Jul 2014 11:02:50 +0200
Subject: [PATCH] Rework lxc apparmor profile
Rework the apparmor lxc profile abstraction to mimic ubuntu's container-default.
This profile allows quite a lot, but strives to restrict access to
dangerous resources.
Removing the explicit authorizations to bash, systemd and cron files,
forces them to keep the lxc profile for all applications inside the
container. PUx permissions where leading to running systemd (and others
tasks) unconfined.
Put the generic files, network and capabilities restrictions directly
in the TEMPLATE.lxc: this way, users can restrict them on a per
container basis.
---
examples/apparmor/Makefile.am | 6 +-
examples/apparmor/TEMPLATE.lxc | 15 ++++
examples/apparmor/{TEMPLATE => TEMPLATE.qemu} | 2 +-
examples/apparmor/libvirt-lxc | 119 +++++++++++++++++++++++---
src/security/security_apparmor.c | 21 +++--
src/security/virt-aa-helper.c | 29 +------
6 files changed, 149 insertions(+), 43 deletions(-)
create mode 100644 examples/apparmor/TEMPLATE.lxc
rename examples/apparmor/{TEMPLATE => TEMPLATE.qemu} (75%)
Index: libvirt-1.2.6/examples/apparmor/Makefile.am
===================================================================
--- libvirt-1.2.6.orig/examples/apparmor/Makefile.am
+++ libvirt-1.2.6/examples/apparmor/Makefile.am
@@ -15,7 +15,8 @@
## <http://www.gnu.org/licenses/>.
EXTRA_DIST= \
- TEMPLATE \
+ TEMPLATE.qemu \
+ TEMPLATE.lxc \
libvirt-qemu \
libvirt-lxc \
usr.lib.libvirt.virt-aa-helper \
@@ -36,6 +37,7 @@ abstractions_DATA = \
templatesdir = $(apparmordir)/libvirt
templates_DATA = \
- TEMPLATE \
+ TEMPLATE.qemu \
+ TEMPLATE.lxc \
$(NULL)
endif WITH_APPARMOR_PROFILES
Index: libvirt-1.2.6/examples/apparmor/TEMPLATE.lxc
===================================================================
--- /dev/null
+++ libvirt-1.2.6/examples/apparmor/TEMPLATE.lxc
@@ -0,0 +1,15 @@
+#
+# This profile is for the domain whose UUID matches this file.
+#
+
+#include <tunables/global>
+
+profile LIBVIRT_TEMPLATE {
+ #include <abstractions/libvirt-lxc>
+
+ # Globally allows everything to run under this profile
+ # These can be narrowed depending on the container's use.
+ file,
+ capability,
+ network,
+}
Index: libvirt-1.2.6/examples/apparmor/TEMPLATE
===================================================================
--- libvirt-1.2.6.orig/examples/apparmor/TEMPLATE
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# This profile is for the domain whose UUID matches this file.
-#
-
-#include <tunables/global>
-
-profile LIBVIRT_TEMPLATE {
- #include <abstractions/libvirt-driver>
-}
Index: libvirt-1.2.6/examples/apparmor/TEMPLATE.qemu
===================================================================
--- /dev/null
+++ libvirt-1.2.6/examples/apparmor/TEMPLATE.qemu
@@ -0,0 +1,9 @@
+#
+# This profile is for the domain whose UUID matches this file.
+#
+
+#include <tunables/global>
+
+profile LIBVIRT_TEMPLATE {
+ #include <abstractions/libvirt-qemu>
+}
Index: libvirt-1.2.6/examples/apparmor/libvirt-lxc
===================================================================
--- libvirt-1.2.6.orig/examples/apparmor/libvirt-lxc
+++ libvirt-1.2.6/examples/apparmor/libvirt-lxc
@@ -2,16 +2,115 @@
#include <abstractions/base>
- # Needed for lxc-enter-namespace
- capability sys_admin,
- capability sys_chroot,
-
- # Added for lxc-enter-namespace --cmd /bin/bash
- /bin/bash PUx,
-
- /usr/sbin/cron PUx,
- /usr/lib/systemd/systemd PUx,
-
- /usr/lib/libsystemd-*.so.* mr,
- /usr/lib/libudev-*.so.* mr,
- /etc/ld.so.cache mr,
+ umount,
+
+ # ignore DENIED message on / remount
+ deny mount options=(ro, remount) -> /,
+
+ # allow tmpfs mounts everywhere
+ mount fstype=tmpfs,
+
+ # allow mqueue mounts everywhere
+ mount fstype=mqueue,
+
+ # allow fuse mounts everywhere
+ mount fstype=fuse.*,
+
+ # deny writes in /proc/sys/fs but allow binfmt_misc to be mounted
+ mount fstype=binfmt_misc -> /proc/sys/fs/binfmt_misc/,
+ deny @{PROC}/sys/fs/** wklx,
+
+ # allow efivars to be mounted, writing to it will be blocked though
+ mount fstype=efivarfs -> /sys/firmware/efi/efivars/,
+
+ # block some other dangerous paths
+ deny @{PROC}/sysrq-trigger rwklx,
+ deny @{PROC}/mem rwklx,
+ deny @{PROC}/kmem rwklx,
+
+ # deny writes in /sys except for /sys/fs/cgroup, also allow
+ # fusectl, securityfs and debugfs to be mounted there (read-only)
+ mount fstype=fusectl -> /sys/fs/fuse/connections/,
+ mount fstype=securityfs -> /sys/kernel/security/,
+ mount fstype=debugfs -> /sys/kernel/debug/,
+ mount fstype=proc -> /proc/,
+ mount fstype=sysfs -> /sys/,
+ deny /sys/firmware/efi/efivars/** rwklx,
+ deny /sys/kernel/security/** rwklx,
+
+ # generated by: lxc-generate-aa-rules.py container-rules.base
+ deny /proc/sys/[^kn]*{,/**} wklx,
+ deny /proc/sys/k[^e]*{,/**} wklx,
+ deny /proc/sys/ke[^r]*{,/**} wklx,
+ deny /proc/sys/ker[^n]*{,/**} wklx,
+ deny /proc/sys/kern[^e]*{,/**} wklx,
+ deny /proc/sys/kerne[^l]*{,/**} wklx,
+ deny /proc/sys/kernel/[^smhd]*{,/**} wklx,
+ deny /proc/sys/kernel/d[^o]*{,/**} wklx,
+ deny /proc/sys/kernel/do[^m]*{,/**} wklx,
+ deny /proc/sys/kernel/dom[^a]*{,/**} wklx,
+ deny /proc/sys/kernel/doma[^i]*{,/**} wklx,
+ deny /proc/sys/kernel/domai[^n]*{,/**} wklx,
+ deny /proc/sys/kernel/domain[^n]*{,/**} wklx,
+ deny /proc/sys/kernel/domainn[^a]*{,/**} wklx,
+ deny /proc/sys/kernel/domainna[^m]*{,/**} wklx,
+ deny /proc/sys/kernel/domainnam[^e]*{,/**} wklx,
+ deny /proc/sys/kernel/domainname?*{,/**} wklx,
+ deny /proc/sys/kernel/h[^o]*{,/**} wklx,
+ deny /proc/sys/kernel/ho[^s]*{,/**} wklx,
+ deny /proc/sys/kernel/hos[^t]*{,/**} wklx,
+ deny /proc/sys/kernel/host[^n]*{,/**} wklx,
+ deny /proc/sys/kernel/hostn[^a]*{,/**} wklx,
+ deny /proc/sys/kernel/hostna[^m]*{,/**} wklx,
+ deny /proc/sys/kernel/hostnam[^e]*{,/**} wklx,
+ deny /proc/sys/kernel/hostname?*{,/**} wklx,
+ deny /proc/sys/kernel/m[^s]*{,/**} wklx,
+ deny /proc/sys/kernel/ms[^g]*{,/**} wklx,
+ deny /proc/sys/kernel/msg*/** wklx,
+ deny /proc/sys/kernel/s[^he]*{,/**} wklx,
+ deny /proc/sys/kernel/se[^m]*{,/**} wklx,
+ deny /proc/sys/kernel/sem*/** wklx,
+ deny /proc/sys/kernel/sh[^m]*{,/**} wklx,
+ deny /proc/sys/kernel/shm*/** wklx,
+ deny /proc/sys/kernel?*{,/**} wklx,
+ deny /proc/sys/n[^e]*{,/**} wklx,
+ deny /proc/sys/ne[^t]*{,/**} wklx,
+ deny /proc/sys/net?*{,/**} wklx,
+ deny /sys/[^fdc]*{,/**} wklx,
+ deny /sys/c[^l]*{,/**} wklx,
+ deny /sys/cl[^a]*{,/**} wklx,
+ deny /sys/cla[^s]*{,/**} wklx,
+ deny /sys/clas[^s]*{,/**} wklx,
+ deny /sys/class/[^n]*{,/**} wklx,
+ deny /sys/class/n[^e]*{,/**} wklx,
+ deny /sys/class/ne[^t]*{,/**} wklx,
+ deny /sys/class/net?*{,/**} wklx,
+ deny /sys/class?*{,/**} wklx,
+ deny /sys/d[^e]*{,/**} wklx,
+ deny /sys/de[^v]*{,/**} wklx,
+ deny /sys/dev[^i]*{,/**} wklx,
+ deny /sys/devi[^c]*{,/**} wklx,
+ deny /sys/devic[^e]*{,/**} wklx,
+ deny /sys/device[^s]*{,/**} wklx,
+ deny /sys/devices/[^v]*{,/**} wklx,
+ deny /sys/devices/v[^i]*{,/**} wklx,
+ deny /sys/devices/vi[^r]*{,/**} wklx,
+ deny /sys/devices/vir[^t]*{,/**} wklx,
+ deny /sys/devices/virt[^u]*{,/**} wklx,
+ deny /sys/devices/virtu[^a]*{,/**} wklx,
+ deny /sys/devices/virtua[^l]*{,/**} wklx,
+ deny /sys/devices/virtual/[^n]*{,/**} wklx,
+ deny /sys/devices/virtual/n[^e]*{,/**} wklx,
+ deny /sys/devices/virtual/ne[^t]*{,/**} wklx,
+ deny /sys/devices/virtual/net?*{,/**} wklx,
+ deny /sys/devices/virtual?*{,/**} wklx,
+ deny /sys/devices?*{,/**} wklx,
+ deny /sys/f[^s]*{,/**} wklx,
+ deny /sys/fs/[^c]*{,/**} wklx,
+ deny /sys/fs/c[^g]*{,/**} wklx,
+ deny /sys/fs/cg[^r]*{,/**} wklx,
+ deny /sys/fs/cgr[^o]*{,/**} wklx,
+ deny /sys/fs/cgro[^u]*{,/**} wklx,
+ deny /sys/fs/cgrou[^p]*{,/**} wklx,
+ deny /sys/fs/cgroup?*{,/**} wklx,
+ deny /sys/fs?*{,/**} wklx,
Index: libvirt-1.2.6/src/security/security_apparmor.c
===================================================================
--- libvirt-1.2.6.orig/src/security/security_apparmor.c
+++ libvirt-1.2.6/src/security/security_apparmor.c
@@ -351,26 +351,37 @@ AppArmorSetSecuritySCSILabel(virSCSIDevi
static int
AppArmorSecurityManagerProbe(const char *virtDriver ATTRIBUTE_UNUSED)
{
- char *template = NULL;
+ char *template_qemu = NULL;
+ char *template_lxc = NULL;
int rc = SECURITY_DRIVER_DISABLE;
if (use_apparmor() < 0)
return rc;
/* see if template file exists */
- if (virAsprintf(&template, "%s/TEMPLATE",
+ if (virAsprintf(&template_qemu, "%s/TEMPLATE.qemu",
APPARMOR_DIR "/libvirt") == -1)
return rc;
- if (!virFileExists(template)) {
+ if (virAsprintf(&template_lxc, "%s/TEMPLATE.lxc",
+ APPARMOR_DIR "/libvirt") == -1)
+ goto cleanup;
+
+ if (!virFileExists(template_qemu)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("template \'%s\' does not exist"), template_qemu);
+ goto cleanup;
+ }
+ if (!virFileExists(template_lxc)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("template \'%s\' does not exist"), template);
+ _("template \'%s\' does not exist"), template_lxc);
goto cleanup;
}
rc = SECURITY_DRIVER_ENABLE;
cleanup:
- VIR_FREE(template);
+ VIR_FREE(template_qemu);
+ VIR_FREE(template_lxc);
return rc;
}
Index: libvirt-1.2.6/src/security/virt-aa-helper.c
===================================================================
--- libvirt-1.2.6.orig/src/security/virt-aa-helper.c
+++ libvirt-1.2.6/src/security/virt-aa-helper.c
@@ -336,24 +336,20 @@ create_profile(const char *profile, cons
char *pcontent = NULL;
char *replace_name = NULL;
char *replace_files = NULL;
- char *replace_driver = NULL;
const char *template_name = "\nprofile LIBVIRT_TEMPLATE";
const char *template_end = "\n}";
- const char *template_driver = "libvirt-driver";
int tlen, plen;
int fd;
int rc = -1;
- const char *driver_name = "qemu";
-
- if (virtType == VIR_DOMAIN_VIRT_LXC)
- driver_name = "lxc";
if (virFileExists(profile)) {
vah_error(NULL, 0, _("profile exists"));
goto end;
}
- if (virAsprintfQuiet(&template, "%s/TEMPLATE", APPARMOR_DIR "/libvirt") < 0) {
+
+ if (virAsprintfQuiet(&template, "%s/TEMPLATE.%s", APPARMOR_DIR "/libvirt",
+ virDomainVirtTypeToString(virtType)) < 0) {
vah_error(NULL, 0, _("template name exceeds maximum length"));
goto end;
}
@@ -378,11 +374,6 @@ create_profile(const char *profile, cons
goto clean_tcontent;
}
- if (strstr(tcontent, template_driver) == NULL) {
- vah_error(NULL, 0, _("no replacement string in template"));
- goto clean_tcontent;
- }
-
/* '\nprofile <profile_name>\0' */
if (virAsprintfQuiet(&replace_name, "\nprofile %s", profile_name) == -1) {
vah_error(NULL, 0, _("could not allocate memory for profile name"));
@@ -397,15 +388,7 @@ create_profile(const char *profile, cons
goto clean_tcontent;
}
- /* 'libvirt-<driver_name>\0' */
- if (virAsprintfQuiet(&replace_driver, "libvirt-%s", driver_name) == -1) {
- vah_error(NULL, 0, _("could not allocate memory for profile driver"));
- VIR_FREE(replace_driver);
- goto clean_tcontent;
- }
-
- plen = tlen + strlen(replace_name) - strlen(template_name) +
- strlen(replace_driver) - strlen(template_driver) + 1;
+ plen = tlen + strlen(replace_name) - strlen(template_name) + 1;
if (virtType != VIR_DOMAIN_VIRT_LXC)
plen += strlen(replace_files) - strlen(template_end);
@@ -422,9 +405,6 @@ create_profile(const char *profile, cons
pcontent[0] = '\0';
strcpy(pcontent, tcontent);
- if (replace_string(pcontent, plen, template_driver, replace_driver) < 0)
- goto clean_all;
-
if (replace_string(pcontent, plen, template_name, replace_name) < 0)
goto clean_all;
@@ -455,7 +435,6 @@ create_profile(const char *profile, cons
clean_replace:
VIR_FREE(replace_name);
VIR_FREE(replace_files);
- VIR_FREE(replace_driver);
clean_tcontent:
VIR_FREE(tcontent);
end:

View File

@ -0,0 +1,29 @@
commit 9b1e4cd5034225c7f750b38968b576c966c51d75
Author: Cédric Bosdonnat <cbosdonnat@suse.com>
Date: Wed Jul 9 16:15:02 2014 +0200
Don't output libvirt-UUID.files for LXC apparmor profiles
---
src/security/virt-aa-helper.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index b5f66f3..c8f17f9 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1342,10 +1342,13 @@ main(int argc, char **argv)
vah_info(include_file);
vah_info(included_files);
rc = 0;
+ } else if (ctl->def->virtType == VIR_DOMAIN_VIRT_LXC) {
+ rc = 0;
} else if ((rc = update_include_file(include_file,
included_files,
- ctl->append)) != 0)
+ ctl->append)) != 0) {
goto cleanup;
+ }
/* create the profile from TEMPLATE */

View File

@ -0,0 +1,22 @@
From 236a18572216a35f742824f4056108245fac3082 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
Date: Fri, 4 Jul 2014 15:57:17 +0200
Subject: [PATCH] virt-lxc-convert: make free return values in bytes
---
examples/lxcconvert/virt-lxc-convert | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: libvirt-1.2.5/examples/lxcconvert/virt-lxc-convert
===================================================================
--- libvirt-1.2.5.orig/examples/lxcconvert/virt-lxc-convert
+++ libvirt-1.2.5/examples/lxcconvert/virt-lxc-convert
@@ -64,7 +64,7 @@ if test -r "$fstab"; then
sed 's/^\([^#]\)/lxc.mount.entry = \1/' "$fstab" >>"${conf_new}"
fi
-memory=$(free | sed -n '/Mem:/s/ \+/ /gp' | cut -f 2 -d ' ')
+memory=$(free -b | sed -n '/Mem:/s/ \+/ /gp' | cut -f 2 -d ' ')
default_tmpfs="size=$((memory/2))"
# Do we have tmpfs without size param?

View File

@ -2,8 +2,8 @@ Index: libvirt-1.2.6/examples/apparmor/Makefile.am
===================================================================
--- libvirt-1.2.6.orig/examples/apparmor/Makefile.am
+++ libvirt-1.2.6/examples/apparmor/Makefile.am
@@ -18,10 +18,22 @@ EXTRA_DIST= \
TEMPLATE \
@@ -19,10 +19,22 @@ EXTRA_DIST= \
TEMPLATE.lxc \
libvirt-qemu \
libvirt-lxc \
- usr.lib.libvirt.virt-aa-helper \

View File

@ -1,3 +1,29 @@
-------------------------------------------------------------------
Wed Jul 16 12:07:33 UTC 2014 - cbosdonnat@suse.com
- lxc AppArmor profile now only restricting potentially dangerous
accesses. fdo#886460
- added patches:
* 9265f8ab-apparmor-lxc-rework.patch
* 9b1e4cd5-skip-useless-apparmor-files.patch
-------------------------------------------------------------------
Wed Jul 16 11:40:35 UTC 2014 - cbosdonnat@suse.com
- virt-lxc-convert: force free to output values in bytes
- added patches:
* dba3432b-virt-lxc-convert-fix.patch
-------------------------------------------------------------------
Wed Jul 16 11:33:31 UTC 2014 - cbosdonnat@suse.com
- 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
-------------------------------------------------------------------
Wed Jul 2 12:49:36 MDT 2014 - jfehlig@suse.com

View File

@ -428,6 +428,9 @@ Source1: libvirtd.init
Source2: libvirtd-relocation-server.fw
Source99: baselibs.conf
# Upstream patches
Patch0: dba3432b-virt-lxc-convert-fix.patch
Patch1: 9b1e4cd5-skip-useless-apparmor-files.patch
Patch2: 9265f8ab-apparmor-lxc-rework.patch
# Need to go upstream
Patch100: xen-name-for-devid.patch
Patch101: xen-pv-cdrom.patch
@ -436,6 +439,9 @@ Patch102: add-nocow-to-vol-xml.patch
Patch150: lxc-keep-caps-feature.patch
Patch151: lxc-keep-caps-feature-conversion.patch
Patch152: lxc-keep-caps-feature-doc.patch
Patch153: lxc-net-target-name.patch
Patch154: lxc-net-target-name-conversion.patch
Patch155: lxc-net-target-name-doc.patch
# Our patches
Patch200: libvirtd-defaults.patch
Patch201: libvirtd-init-script.patch
@ -947,12 +953,18 @@ namespaces.
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch100 -p1
%patch101 -p1
%patch102 -p1
%patch150 -p1
%patch151 -p1
%patch152 -p1
%patch153 -p1
%patch154 -p1
%patch155 -p1
%patch200 -p1
%patch201 -p1
%patch202 -p1
@ -1488,7 +1500,8 @@ fi
%config(noreplace) %{_sysconfdir}/apparmor.d/usr.lib.libvirt.virt-aa-helper
%config(noreplace) %{_sysconfdir}/apparmor.d/abstractions/libvirt-qemu
%config(noreplace) %{_sysconfdir}/apparmor.d/abstractions/libvirt-lxc
%config(noreplace) %{_sysconfdir}/apparmor.d/libvirt/TEMPLATE
%config(noreplace) %{_sysconfdir}/apparmor.d/libvirt/TEMPLATE.lxc
%config(noreplace) %{_sysconfdir}/apparmor.d/libvirt/TEMPLATE.qemu
%{_libdir}/%{name}/virt-aa-helper
%endif
%config %{_fwdefdir}/libvirtd-relocation-server

View File

@ -0,0 +1,130 @@
From 27b425b5f77029bf0d322afb930eabf6ec6899e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
Date: Wed, 2 Jul 2014 15:13:40 +0200
Subject: [PATCH 1/2] lxc conf2xml: convert lxc.network.name for veth networks
---
src/lxc/lxc_native.c | 22 ++++++++++++++++------
.../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 1 +
tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 1 +
3 files changed, 18 insertions(+), 6 deletions(-)
Index: libvirt-1.2.5/src/lxc/lxc_native.c
===================================================================
--- libvirt-1.2.5.orig/src/lxc/lxc_native.c
+++ libvirt-1.2.5/src/lxc/lxc_native.c
@@ -338,7 +338,8 @@ lxcCreateNetDef(const char *type,
const char *linkdev,
const char *mac,
const char *flag,
- const char *macvlanmode)
+ const char *macvlanmode,
+ const char *name)
{
virDomainNetDefPtr net = NULL;
virMacAddr macAddr;
@@ -353,6 +354,8 @@ lxcCreateNetDef(const char *type,
net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN;
}
+ if (name && VIR_STRDUP(net->ifname_guest, name) < 0)
+ goto error;
if (mac && virMacAddrParse(mac, &macAddr) == 0)
net->mac = macAddr;
@@ -416,7 +419,8 @@ lxcAddNetworkDefinition(virDomainDefPtr
const char *mac,
const char *flag,
const char *macvlanmode,
- const char *vlanid)
+ const char *vlanid,
+ const char *name)
{
virDomainNetDefPtr net = NULL;
virDomainHostdevDefPtr hostdev = NULL;
@@ -452,7 +456,7 @@ lxcAddNetworkDefinition(virDomainDefPtr
goto error;
def->hostdevs[def->nhostdevs - 1] = hostdev;
} else {
- if (!(net = lxcCreateNetDef(type, linkdev, mac, flag, macvlanmode)))
+ if (!(net = lxcCreateNetDef(type, linkdev, mac, flag, macvlanmode, name)))
goto error;
if (VIR_EXPAND_N(def->nets, def->nnets, 1) < 0)
@@ -476,6 +480,7 @@ typedef struct {
char *flag;
char *macvlanmode;
char *vlanid;
+ char *name;
bool privnet;
size_t networks;
} lxcNetworkParseData;
@@ -492,7 +497,8 @@ lxcNetworkWalkCallback(const char *name,
parseData->link, parseData->mac,
parseData->flag,
parseData->macvlanmode,
- parseData->vlanid);
+ parseData->vlanid,
+ parseData->name);
if (status < 0)
return -1;
@@ -508,6 +514,7 @@ lxcNetworkWalkCallback(const char *name,
parseData->flag = NULL;
parseData->macvlanmode = NULL;
parseData->vlanid = NULL;
+ parseData->name = NULL;
/* Keep the new value */
parseData->type = value->str;
@@ -522,6 +529,8 @@ lxcNetworkWalkCallback(const char *name,
parseData->macvlanmode = value->str;
else if (STREQ(name, "lxc.network.vlan.id"))
parseData->vlanid = value->str;
+ else if (STREQ(name, "lxc.network.name"))
+ parseData->name = value->str;
else if (STRPREFIX(name, "lxc.network"))
VIR_WARN("Unhandled network property: %s = %s",
name,
@@ -535,7 +544,7 @@ lxcConvertNetworkSettings(virDomainDefPt
{
int status;
lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL,
- NULL, NULL, true, 0};
+ NULL, NULL, NULL, true, 0};
virConfWalk(properties, lxcNetworkWalkCallback, &data);
@@ -543,7 +552,8 @@ lxcConvertNetworkSettings(virDomainDefPt
status = lxcAddNetworkDefinition(def, data.type, data.link,
data.mac, data.flag,
data.macvlanmode,
- data.vlanid);
+ data.vlanid,
+ data.name);
if (status < 0)
return -1;
else if (status > 0)
Index: libvirt-1.2.5/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config
===================================================================
--- libvirt-1.2.5.orig/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config
+++ libvirt-1.2.5/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config
@@ -1,5 +1,6 @@
lxc.network.type = phys
lxc.network.link = eth0
+lxc.network.name = eth1
lxc.rootfs = /var/lib/lxc/migrate_test/rootfs
lxc.utsname = migrate_test
Index: libvirt-1.2.5/tests/lxcconf2xmldata/lxcconf2xml-simple.xml
===================================================================
--- libvirt-1.2.5.orig/tests/lxcconf2xmldata/lxcconf2xml-simple.xml
+++ libvirt-1.2.5/tests/lxcconf2xmldata/lxcconf2xml-simple.xml
@@ -37,6 +37,7 @@
<interface type='bridge'>
<mac address='02:00:15:8f:05:c1'/>
<source bridge='virbr0'/>
+ <guest dev='eth0'/>
<link state='up'/>
</interface>
<console type='pty'>

View File

@ -0,0 +1,37 @@
From c0b1a318442740b6c63630b61d0718598a9937d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
Date: Wed, 2 Jul 2014 15:24:56 +0200
Subject: [PATCH 2/2] lxc network device names change documentation
---
docs/formatdomain.html.in | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
Index: libvirt-1.2.5/docs/formatdomain.html.in
===================================================================
--- libvirt-1.2.5.orig/docs/formatdomain.html.in
+++ libvirt-1.2.5/docs/formatdomain.html.in
@@ -3757,6 +3757,23 @@ qemu-kvm -net nic,model=? /dev/null
targets using these prefixes will be ignored.
</p>
+ <p>
+ Note that for LXC containers, this defines the name of the interface
+ on the host side. <span class="since">Since 1.2.7</span>, to define
+ the name of the device on the guest side, the <code>guest</code>
+ element should be used, as in the following snippet:
+ </p>
+
+<pre>
+ ...
+ &lt;devices&gt;
+ &lt;interface type='network'&gt;
+ &lt;source network='default'/&gt;
+ <b>&lt;guest dev='myeth'/&gt;</b>
+ &lt;/interface&gt;
+ &lt;/devices&gt;
+ ...</pre>
+
<h5><a name="elementsNICSBoot">Specifying boot order</a></h5>
<pre>

269
lxc-net-target-name.patch Normal file
View File

@ -0,0 +1,269 @@
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'/>