diff --git a/9265f8ab-apparmor-lxc-rework.patch b/9265f8ab-apparmor-lxc-rework.patch
new file mode 100644
index 0000000..11c468d
--- /dev/null
+++ b/9265f8ab-apparmor-lxc-rework.patch
@@ -0,0 +1,358 @@
+From 9265f8ab67dc14fe89a26efd5c22b156d3168fd6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?=
+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 @@
+ ## .
+
+ 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
++
++profile LIBVIRT_TEMPLATE {
++ #include
++
++ # 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
+-
+-profile LIBVIRT_TEMPLATE {
+- #include
+-}
+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
++
++profile LIBVIRT_TEMPLATE {
++ #include
++}
+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
+
+- # 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 \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-\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:
diff --git a/9b1e4cd5-skip-useless-apparmor-files.patch b/9b1e4cd5-skip-useless-apparmor-files.patch
new file mode 100644
index 0000000..4c606ee
--- /dev/null
+++ b/9b1e4cd5-skip-useless-apparmor-files.patch
@@ -0,0 +1,29 @@
+commit 9b1e4cd5034225c7f750b38968b576c966c51d75
+Author: Cédric Bosdonnat
+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 */
diff --git a/dba3432b-virt-lxc-convert-fix.patch b/dba3432b-virt-lxc-convert-fix.patch
new file mode 100644
index 0000000..5dc7ad8
--- /dev/null
+++ b/dba3432b-virt-lxc-convert-fix.patch
@@ -0,0 +1,22 @@
+From 236a18572216a35f742824f4056108245fac3082 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?=
+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?
diff --git a/install-apparmor-profiles.patch b/install-apparmor-profiles.patch
index 9bb3c88..4904a53 100644
--- a/install-apparmor-profiles.patch
+++ b/install-apparmor-profiles.patch
@@ -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 \
diff --git a/libvirt.changes b/libvirt.changes
index b2c6c77..a524ba4 100644
--- a/libvirt.changes
+++ b/libvirt.changes
@@ -1,3 +1,30 @@
+-------------------------------------------------------------------
+Wed Jul 16 12:07:33 UTC 2014 - cbosdonnat@suse.com
+
+- lxc AppArmor profile now only restricting potentially dangerous
+ accesses. fdo#886460
+- Add virt-lxc-convert to libvirt-daemon-driver-lxc package
+
+- 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
diff --git a/libvirt.spec b/libvirt.spec
index 2e8ffed..a6f4984 100644
--- a/libvirt.spec
+++ b/libvirt.spec
@@ -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
@@ -1183,6 +1195,7 @@ for i in object-events dominfo domsuspend hellolibvirt openauth xml/nwfilter sys
do
(cd examples/$i ; make clean ; rm -rf .deps .libs Makefile Makefile.in)
done
+cp examples/lxcconvert/virt-lxc-convert $RPM_BUILD_ROOT%{_bindir}
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
rm -f $RPM_BUILD_ROOT%{_libdir}/*.a
rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}/lock-driver/*.la
@@ -1488,7 +1501,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
@@ -1648,6 +1662,7 @@ fi
%{_datadir}/augeas/lenses/tests/test_libvirtd_lxc.aug
%dir %{_libdir}/%{name}/connection-driver
%{_libdir}/%{name}/connection-driver/libvirt_driver_lxc.so
+%attr(0755, root, root) %{_bindir}/virt-lxc-convert
%endif
%if %{with_uml}
diff --git a/lxc-net-target-name-conversion.patch b/lxc-net-target-name-conversion.patch
new file mode 100644
index 0000000..feb7805
--- /dev/null
+++ b/lxc-net-target-name-conversion.patch
@@ -0,0 +1,130 @@
+From 27b425b5f77029bf0d322afb930eabf6ec6899e4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?=
+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 @@
+
+
+
++
+
+
+
diff --git a/lxc-net-target-name-doc.patch b/lxc-net-target-name-doc.patch
new file mode 100644
index 0000000..9c162bd
--- /dev/null
+++ b/lxc-net-target-name-doc.patch
@@ -0,0 +1,37 @@
+From c0b1a318442740b6c63630b61d0718598a9937d2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?=
+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.
+
+
++
++ Note that for LXC containers, this defines the name of the interface
++ on the host side. Since 1.2.7 , to define
++ the name of the device on the guest side, the guest
++ element should be used, as in the following snippet:
++
++
++
++ ...
++ <devices>
++ <interface type='network'>
++ <source network='default'/>
++ <guest dev='myeth'/>
++ </interface>
++ </devices>
++ ...
++
+
+
+
diff --git a/lxc-net-target-name.patch b/lxc-net-target-name.patch
new file mode 100644
index 0000000..f5c7301
--- /dev/null
+++ b/lxc-net-target-name.patch
@@ -0,0 +1,269 @@
+From 2dd011bd1451e5e6e41c0fbe98884d7594a46dc1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?=
+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:
+
+
+
+
+
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+
+
+
+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, " \n", def->ifname);
+ }
++ if (def->ifname_guest || def->ifname_guest_actual) {
++ virBufferAddLit(buf, "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, " \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 @@
+
+
+
++
+
+
+