From b8aa82790b0a81c1e46fb170777b81db7bd0f607 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Sat, 6 Jun 2015 11:17:32 -0400 Subject: [PATCH] Add patches --- ...vide-virNetDevSysfsFile-on-non-Linux.patch | 40 +++ 0002-Introduce-virnetdevtest.patch | 310 ++++++++++++++++++ 0003-Cleanup-sys-class-net-usage.patch | 265 +++++++++++++++ ...wireless-PHYs-to-a-network-namespace.patch | 77 +++++ ...-Add-virnetdevtestdata-to-EXTRA_DIST.patch | 27 ++ ...-veth-interfaces-unless-explicitly-a.patch | 55 ++++ ...error-out-if-a-bond-has-no-interface.patch | 80 +++++ ...-virnetdev-fix-moving-of-802.11-phys.patch | 88 +++++ ...ssword-less-access-for-libvirt-group.patch | 126 +++++++ 9 files changed, 1068 insertions(+) create mode 100644 0001-build-provide-virNetDevSysfsFile-on-non-Linux.patch create mode 100644 0002-Introduce-virnetdevtest.patch create mode 100644 0003-Cleanup-sys-class-net-usage.patch create mode 100644 0004-lxc-move-wireless-PHYs-to-a-network-namespace.patch create mode 100644 0005-tests-Add-virnetdevtestdata-to-EXTRA_DIST.patch create mode 100644 0006-lxc-don-t-up-the-veth-interfaces-unless-explicitly-a.patch create mode 100644 0007-interface-don-t-error-out-if-a-bond-has-no-interface.patch create mode 100644 0008-virnetdev-fix-moving-of-802.11-phys.patch create mode 100644 0101-polkit-Allow-password-less-access-for-libvirt-group.patch diff --git a/0001-build-provide-virNetDevSysfsFile-on-non-Linux.patch b/0001-build-provide-virNetDevSysfsFile-on-non-Linux.patch new file mode 100644 index 0000000..22f141f --- /dev/null +++ b/0001-build-provide-virNetDevSysfsFile-on-non-Linux.patch @@ -0,0 +1,40 @@ +From: Eric Blake +Date: Tue, 14 Apr 2015 13:53:04 -0600 +Subject: [PATCH] build: provide virNetDevSysfsFile on non-Linux + +Commit 49ed6cff is broken on mingw and other non-linux platforms: + + CCLD libvirt.la + Cannot export virNetDevSysfsFile: symbol not defined + collect2: error: ld returned 1 exit status + +* src/util/virnetdev.c: Provide virNetDevSysfsFile fallback. + +Signed-off-by: Eric Blake +(cherry picked from commit 58dfc5341432e5b510c441457a524b9d818ad63c) +--- + src/util/virnetdev.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index 309fbb8..ebb4c5c 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -1777,6 +1777,17 @@ virNetDevGetVirtualFunctionInfo(const char *vfname ATTRIBUTE_UNUSED, + _("Unable to get virtual function info on this platform")); + return -1; + } ++ ++int ++virNetDevSysfsFile(char **pf_sysfs_device_link ATTRIBUTE_UNUSED, ++ const char *ifname ATTRIBUTE_UNUSED, ++ const char *file ATTRIBUTE_UNUSED) ++{ ++ virReportSystemError(ENOSYS, "%s", ++ _("Unable to get sysfs info on this platform")); ++ return -1; ++} ++ + #endif /* !__linux__ */ + #if defined(__linux__) && defined(HAVE_LIBNL) && defined(IFLA_VF_MAX) + diff --git a/0002-Introduce-virnetdevtest.patch b/0002-Introduce-virnetdevtest.patch new file mode 100644 index 0000000..4ada906 --- /dev/null +++ b/0002-Introduce-virnetdevtest.patch @@ -0,0 +1,310 @@ +From: Michal Privoznik +Date: Wed, 11 Jun 2014 15:05:00 +0200 +Subject: [PATCH] Introduce virnetdevtest + +This is yet another test for check of basic functionality of our +NIC state handling code. + +Signed-off-by: Michal Privoznik +(cherry picked from commit 49ed6cff997bb893dafc805c868c9e772a04696d) +--- + src/libvirt_private.syms | 1 + + src/util/virnetdev.c | 4 +- + src/util/virnetdev.h | 5 ++ + tests/Makefile.am | 15 ++++ + tests/virnetdevmock.c | 48 +++++++++++ + tests/virnetdevtest.c | 94 ++++++++++++++++++++++ + .../sys/class/net/eth0-broken/operstate | 1 + + .../sys/class/net/eth0-broken/speed | 1 + + .../virnetdevtestdata/sys/class/net/eth0/operstate | 1 + + tests/virnetdevtestdata/sys/class/net/eth0/speed | 1 + + tests/virnetdevtestdata/sys/class/net/lo/operstate | 1 + + tests/virnetdevtestdata/sys/class/net/lo/speed | 1 + + 12 files changed, 171 insertions(+), 2 deletions(-) + create mode 100644 tests/virnetdevmock.c + create mode 100644 tests/virnetdevtest.c + create mode 100644 tests/virnetdevtestdata/sys/class/net/eth0-broken/operstate + create mode 100644 tests/virnetdevtestdata/sys/class/net/eth0-broken/speed + create mode 100644 tests/virnetdevtestdata/sys/class/net/eth0/operstate + create mode 100644 tests/virnetdevtestdata/sys/class/net/eth0/speed + create mode 100644 tests/virnetdevtestdata/sys/class/net/lo/operstate + create mode 100644 tests/virnetdevtestdata/sys/class/net/lo/speed + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 8653727..9cda39c 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1702,6 +1702,7 @@ virNetDevSetPromiscuous; + virNetDevSetRcvAllMulti; + virNetDevSetRcvMulti; + virNetDevSetupControl; ++virNetDevSysfsFile; + virNetDevValidateConfig; + + +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index ebb4c5c..c196d98 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -1514,9 +1514,9 @@ int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED, + #ifdef __linux__ + # define NET_SYSFS "/sys/class/net/" + +-static int ++int + virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, +- const char *file) ++ const char *file) + { + + if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/%s", ifname, file) < 0) +diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h +index 0c0f666..d692f94 100644 +--- a/src/util/virnetdev.h ++++ b/src/util/virnetdev.h +@@ -203,4 +203,9 @@ int virNetDevSetRcvAllMulti(const char *ifname, bool receive) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + int virNetDevGetRcvAllMulti(const char *ifname, bool *receive) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; ++int virNetDevSysfsFile(char **pf_sysfs_device_link, ++ const char *ifname, ++ const char *file) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ++ ATTRIBUTE_RETURN_CHECK; + #endif /* __VIR_NETDEV_H__ */ +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 938270c..2dd0088 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -175,6 +175,7 @@ test_programs = virshtest sockettest \ + domainconftest \ + virhostdevtest \ + vircaps2xmltest \ ++ virnetdevtest \ + $(NULL) + + if WITH_REMOTE +@@ -401,6 +402,7 @@ test_libraries = libshunload.la \ + virnetserverclientmock.la \ + vircgroupmock.la \ + virpcimock.la \ ++ virnetdevmock.la \ + $(NULL) + if WITH_QEMU + test_libraries += libqemumonitortestutils.la \ +@@ -1017,6 +1019,19 @@ virpcimock_la_LIBADD = $(GNULIB_LIBS) \ + virpcimock_la_LDFLAGS = -module -avoid-version \ + -rpath /evil/libtool/hack/to/force/shared/lib/creation + ++virnetdevtest_SOURCES = \ ++ virnetdevtest.c testutils.h testutils.c ++virnetdevtest_CFLAGS = $(AM_CFLAGS) $(LIBNL_CFLAGS) ++virnetdevtest_LDADD = $(LDADDS) ++ ++virnetdevmock_la_SOURCES = \ ++ virnetdevmock.c ++virnetdevmock_la_CFLAGS = $(AM_CFLAGS) $(LIBNL_CFLAGS) ++virnetdevmock_la_LIBADD = $(GNULIB_LIBS) \ ++ ../src/libvirt.la ++virnetdevmock_la_LDFLAGS = -module -avoid-version \ ++ -rpath /evil/libtool/hack/to/force/shared/lib/creation ++ + if WITH_LINUX + virusbtest_SOURCES = \ + virusbtest.c testutils.h testutils.c +diff --git a/tests/virnetdevmock.c b/tests/virnetdevmock.c +new file mode 100644 +index 0000000..a9967b7 +--- /dev/null ++++ b/tests/virnetdevmock.c +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (C) 2015 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ * ++ * Author: Michal Privoznik ++ */ ++ ++#include ++ ++#ifdef __linux__ ++# include "internal.h" ++# include ++# include ++# include "virstring.h" ++# include "virnetdev.h" ++ ++# define NET_DEV_TEST_DATA_PREFIX abs_srcdir "/virnetdevtestdata/sys/class/net" ++ ++int ++virNetDevSysfsFile(char **pf_sysfs_device_link, ++ const char *ifname, ++ const char *file) ++{ ++ ++ if (virAsprintfQuiet(pf_sysfs_device_link, "%s/%s/%s", ++ NET_DEV_TEST_DATA_PREFIX, ifname, file) < 0) { ++ fprintf(stderr, "Out of memory\n"); ++ abort(); ++ } ++ ++ return 0; ++} ++#else ++/* Nothing to override on non-__linux__ platforms */ ++#endif +diff --git a/tests/virnetdevtest.c b/tests/virnetdevtest.c +new file mode 100644 +index 0000000..c31543e +--- /dev/null ++++ b/tests/virnetdevtest.c +@@ -0,0 +1,94 @@ ++/* ++ * Copyright (C) 2015 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ * ++ * Author: Michal Privoznik ++ */ ++ ++#include ++ ++#include "testutils.h" ++ ++#ifdef __linux__ ++ ++# include "virnetdev.h" ++ ++# define VIR_FROM_THIS VIR_FROM_NONE ++ ++struct testVirNetDevGetLinkInfoData { ++ const char *ifname; /* ifname to get info on */ ++ virInterfaceState state; /* expected state */ ++ unsigned int speed; /* expected speed */ ++}; ++ ++static int ++testVirNetDevGetLinkInfo(const void *opaque) ++{ ++ int ret = -1; ++ const struct testVirNetDevGetLinkInfoData *data = opaque; ++ virInterfaceLink lnk; ++ ++ if (virNetDevGetLinkInfo(data->ifname, &lnk) < 0) ++ goto cleanup; ++ ++ if (lnk.state != data->state) { ++ fprintf(stderr, ++ "Fetched link state (%s) doesn't match the expected one (%s)", ++ virInterfaceStateTypeToString(lnk.state), ++ virInterfaceStateTypeToString(data->state)); ++ goto cleanup; ++ } ++ ++ if (lnk.speed != data->speed) { ++ fprintf(stderr, ++ "Fetched link speed (%u) doesn't match the expected one (%u)", ++ lnk.speed, data->speed); ++ goto cleanup; ++ } ++ ++ ret = 0; ++ cleanup: ++ return ret; ++} ++ ++static int ++mymain(void) ++{ ++ int ret = 0; ++ ++# define DO_TEST_LINK(ifname, state, speed) \ ++ do { \ ++ struct testVirNetDevGetLinkInfoData data = {ifname, state, speed}; \ ++ if (virtTestRun("Link info: " # ifname, \ ++ testVirNetDevGetLinkInfo, &data) < 0) \ ++ ret = -1; \ ++ } while (0) ++ ++ DO_TEST_LINK("eth0", VIR_INTERFACE_STATE_UP, 1000); ++ DO_TEST_LINK("lo", VIR_INTERFACE_STATE_UNKNOWN, 0); ++ DO_TEST_LINK("eth0-broken", VIR_INTERFACE_STATE_DOWN, 0); ++ ++ return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; ++} ++ ++VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virnetdevmock.so") ++#else ++int ++main(void) ++{ ++ return EXIT_AM_SKIP; ++} ++#endif +diff --git a/tests/virnetdevtestdata/sys/class/net/eth0-broken/operstate b/tests/virnetdevtestdata/sys/class/net/eth0-broken/operstate +new file mode 100644 +index 0000000..eb0e904 +--- /dev/null ++++ b/tests/virnetdevtestdata/sys/class/net/eth0-broken/operstate +@@ -0,0 +1 @@ ++down +diff --git a/tests/virnetdevtestdata/sys/class/net/eth0-broken/speed b/tests/virnetdevtestdata/sys/class/net/eth0-broken/speed +new file mode 100644 +index 0000000..4f6ff86 +--- /dev/null ++++ b/tests/virnetdevtestdata/sys/class/net/eth0-broken/speed +@@ -0,0 +1 @@ ++4294967295 +diff --git a/tests/virnetdevtestdata/sys/class/net/eth0/operstate b/tests/virnetdevtestdata/sys/class/net/eth0/operstate +new file mode 100644 +index 0000000..e31ee94 +--- /dev/null ++++ b/tests/virnetdevtestdata/sys/class/net/eth0/operstate +@@ -0,0 +1 @@ ++up +diff --git a/tests/virnetdevtestdata/sys/class/net/eth0/speed b/tests/virnetdevtestdata/sys/class/net/eth0/speed +new file mode 100644 +index 0000000..83b33d2 +--- /dev/null ++++ b/tests/virnetdevtestdata/sys/class/net/eth0/speed +@@ -0,0 +1 @@ ++1000 +diff --git a/tests/virnetdevtestdata/sys/class/net/lo/operstate b/tests/virnetdevtestdata/sys/class/net/lo/operstate +new file mode 100644 +index 0000000..3546645 +--- /dev/null ++++ b/tests/virnetdevtestdata/sys/class/net/lo/operstate +@@ -0,0 +1 @@ ++unknown +diff --git a/tests/virnetdevtestdata/sys/class/net/lo/speed b/tests/virnetdevtestdata/sys/class/net/lo/speed +new file mode 100644 +index 0000000..573541a +--- /dev/null ++++ b/tests/virnetdevtestdata/sys/class/net/lo/speed +@@ -0,0 +1 @@ ++0 diff --git a/0003-Cleanup-sys-class-net-usage.patch b/0003-Cleanup-sys-class-net-usage.patch new file mode 100644 index 0000000..c136b95 --- /dev/null +++ b/0003-Cleanup-sys-class-net-usage.patch @@ -0,0 +1,265 @@ +From: Michal Privoznik +Date: Wed, 15 Apr 2015 11:45:47 +0200 +Subject: [PATCH] Cleanup "/sys/class/net" usage + +Throughout the code, we have several places need to construct a path +somewhere in /sys/class/net/... They are not consistent and nearly +each code piece invents its own way how to do it. So unify this by: + +1) use virNetDevSysfsFile() wherever possible + +2) At least use common macro SYSFS_NET_DIR declared in virnetdev.h at + the rest of places which can't go with 1) + +Signed-off-by: Michal Privoznik +(cherry picked from commit 96a21e975f4b9d2f66a6aee1a16188837c98f82c) +--- + src/Makefile.am | 4 ++-- + src/parallels/parallels_network.c | 10 ++++------ + src/util/virnetdev.c | 5 ++--- + src/util/virnetdev.h | 2 ++ + src/util/virnetdevbridge.c | 13 ++++++------- + src/util/virnetdevmacvlan.c | 30 +++++++++++++++--------------- + src/util/virnetdevveth.c | 2 +- + 7 files changed, 32 insertions(+), 34 deletions(-) + +diff --git a/src/Makefile.am b/src/Makefile.am +index c2e1947..a900303 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1381,8 +1381,8 @@ noinst_LTLIBRARIES += libvirt_driver_parallels.la + libvirt_la_BUILT_LIBADD += libvirt_driver_parallels.la + libvirt_driver_parallels_la_CFLAGS = \ + -I$(srcdir)/conf $(AM_CFLAGS) \ +- $(PARALLELS_SDK_CFLAGS) +-libvirt_driver_parallels_la_LIBADD = $(PARALLELS_SDK_LIBS) ++ $(PARALLELS_SDK_CFLAGS) $(LIBNL_CFLAGS) ++libvirt_driver_parallels_la_LIBADD = $(PARALLELS_SDK_LIBS) $(LIBNL_LIBS) + libvirt_driver_parallels_la_SOURCES = $(PARALLELS_DRIVER_SOURCES) + endif WITH_PARALLELS + +diff --git a/src/parallels/parallels_network.c b/src/parallels/parallels_network.c +index 3e7087d..b4ae737 100644 +--- a/src/parallels/parallels_network.c ++++ b/src/parallels/parallels_network.c +@@ -28,6 +28,7 @@ + #include "viralloc.h" + #include "virerror.h" + #include "virfile.h" ++#include "virnetdev.h" + #include "md5.h" + #include "parallels_utils.h" + #include "virstring.h" +@@ -39,8 +40,6 @@ + virReportErrorHelper(VIR_FROM_TEST, VIR_ERR_OPERATION_FAILED, __FILE__, \ + __FUNCTION__, __LINE__, _("Can't parse prlctl output")) + +-#define SYSFS_NET_DIR "/sys/class/net" +- + static int parallelsGetBridgedNetInfo(virNetworkDefPtr def, virJSONValuePtr jobj) + { + const char *ifname; +@@ -56,8 +55,7 @@ static int parallelsGetBridgedNetInfo(virNetworkDefPtr def, virJSONValuePtr jobj + goto cleanup; + } + +- if (virAsprintf(&bridgeLink, "%s/%s/brport/bridge", +- SYSFS_NET_DIR, ifname) < 0) ++ if (virAsprintf(&bridgeLink, SYSFS_NET_DIR "%s/brport/bridge", ifname) < 0) + goto cleanup; + + if (virFileResolveLink(bridgeLink, &bridgePath) < 0) { +@@ -68,8 +66,8 @@ static int parallelsGetBridgedNetInfo(virNetworkDefPtr def, virJSONValuePtr jobj + if (VIR_STRDUP(def->bridge, last_component(bridgePath)) < 0) + goto cleanup; + +- if (virAsprintf(&bridgeAddressPath, "%s/%s/brport/bridge/address", +- SYSFS_NET_DIR, ifname) < 0) ++ if (virAsprintf(&bridgeAddressPath, SYSFS_NET_DIR "%s/brport/bridge/address", ++ ifname) < 0) + goto cleanup; + + if ((len = virFileReadAll(bridgeAddressPath, 18, &bridgeAddress)) < 0) { +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index c196d98..93f6715 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -1512,14 +1512,13 @@ int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED, + + + #ifdef __linux__ +-# define NET_SYSFS "/sys/class/net/" + + int + virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, + const char *file) + { + +- if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/%s", ifname, file) < 0) ++ if (virAsprintf(pf_sysfs_device_link, SYSFS_NET_DIR "%s/%s", ifname, file) < 0) + return -1; + return 0; + } +@@ -1529,7 +1528,7 @@ virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, + const char *file) + { + +- if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/device/%s", ifname, ++ if (virAsprintf(pf_sysfs_device_link, SYSFS_NET_DIR "%s/device/%s", ifname, + file) < 0) + return -1; + return 0; +diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h +index d692f94..83868d4 100644 +--- a/src/util/virnetdev.h ++++ b/src/util/virnetdev.h +@@ -203,6 +203,8 @@ int virNetDevSetRcvAllMulti(const char *ifname, bool receive) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + int virNetDevGetRcvAllMulti(const char *ifname, bool *receive) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; ++ ++# define SYSFS_NET_DIR "/sys/class/net/" + int virNetDevSysfsFile(char **pf_sysfs_device_link, + const char *ifname, + const char *file) +diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c +index d9dcc39..282746b 100644 +--- a/src/util/virnetdevbridge.c ++++ b/src/util/virnetdevbridge.c +@@ -114,7 +114,6 @@ static int virNetDevBridgeCmd(const char *brname, + #endif + + #if defined(HAVE_STRUCT_IFREQ) && defined(__linux__) +-# define SYSFS_NET_DIR "/sys/class/net" + /* + * Bridge parameters can be set via sysfs on newish kernels, + * or by ioctl on older kernels. Perhaps we could just use +@@ -130,7 +129,7 @@ static int virNetDevBridgeSet(const char *brname, + char *path = NULL; + int ret = -1; + +- if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) ++ if (virAsprintf(&path, SYSFS_NET_DIR "%s/bridge/%s", brname, paramname) < 0) + return -1; + + if (virFileExists(path)) { +@@ -177,7 +176,7 @@ static int virNetDevBridgeGet(const char *brname, + char *path = NULL; + int ret = -1; + +- if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) ++ if (virAsprintf(&path, SYSFS_NET_DIR "%s/bridge/%s", brname, paramname) < 0) + return -1; + + if (virFileExists(path)) { +@@ -235,8 +234,8 @@ virNetDevBridgePortSet(const char *brname, + + snprintf(valuestr, sizeof(valuestr), "%lu", value); + +- if (virAsprintf(&path, "%s/%s/brif/%s/%s", +- SYSFS_NET_DIR, brname, ifname, paramname) < 0) ++ if (virAsprintf(&path, SYSFS_NET_DIR "%s/brif/%s/%s", ++ brname, ifname, paramname) < 0) + return -1; + + if (!virFileExists(path)) +@@ -265,8 +264,8 @@ virNetDevBridgePortGet(const char *brname, + char *valuestr = NULL; + int ret = -1; + +- if (virAsprintf(&path, "%s/%s/brif/%s/%s", +- SYSFS_NET_DIR, brname, ifname, paramname) < 0) ++ if (virAsprintf(&path, SYSFS_NET_DIR "%s/brif/%s/%s", ++ brname, ifname, paramname) < 0) + return -1; + + if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long), &valuestr) < 0) +diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c +index b5ee2f1..955d90d 100644 +--- a/src/util/virnetdevmacvlan.c ++++ b/src/util/virnetdevmacvlan.c +@@ -299,19 +299,15 @@ static + int virNetDevMacVLanTapOpen(const char *ifname, + int retries) + { +- FILE *file; +- char path[64]; ++ int ret = -1; ++ FILE *file = NULL; ++ char *path; + int ifindex; + char tapname[50]; + int tapfd; + +- if (snprintf(path, sizeof(path), +- "/sys/class/net/%s/ifindex", ifname) >= sizeof(path)) { +- virReportSystemError(errno, +- "%s", +- _("buffer for ifindex path is too small")); ++ if (virNetDevSysfsFile(&path, ifname, "ifindex") < 0) + return -1; +- } + + file = fopen(path, "r"); + +@@ -319,15 +315,14 @@ int virNetDevMacVLanTapOpen(const char *ifname, + virReportSystemError(errno, + _("cannot open macvtap file %s to determine " + "interface index"), path); +- return -1; ++ goto cleanup; + } + + if (fscanf(file, "%d", &ifindex) != 1) { + virReportSystemError(errno, + "%s", _("cannot determine macvtap's tap device " + "interface index")); +- VIR_FORCE_FCLOSE(file); +- return -1; ++ goto cleanup; + } + + VIR_FORCE_FCLOSE(file); +@@ -337,7 +332,7 @@ int virNetDevMacVLanTapOpen(const char *ifname, + virReportSystemError(errno, + "%s", + _("internal buffer for tap device is too small")); +- return -1; ++ goto cleanup; + } + + while (1) { +@@ -351,12 +346,17 @@ int virNetDevMacVLanTapOpen(const char *ifname, + break; + } + +- if (tapfd < 0) ++ if (tapfd < 0) { + virReportSystemError(errno, + _("cannot open macvtap tap device %s"), + tapname); +- +- return tapfd; ++ goto cleanup; ++ } ++ ret = tapfd; ++ cleanup: ++ VIR_FREE(path); ++ VIR_FORCE_FCLOSE(file); ++ return ret; + } + + +diff --git a/src/util/virnetdevveth.c b/src/util/virnetdevveth.c +index e9d6f9c..6905168 100644 +--- a/src/util/virnetdevveth.c ++++ b/src/util/virnetdevveth.c +@@ -47,7 +47,7 @@ static int virNetDevVethExists(int devNum) + { + int ret; + char *path = NULL; +- if (virAsprintf(&path, "/sys/class/net/vnet%d/", devNum) < 0) ++ if (virAsprintf(&path, SYSFS_NET_DIR "vnet%d/", devNum) < 0) + return -1; + ret = virFileExists(path) ? 1 : 0; + VIR_DEBUG("Checked dev vnet%d usage: %d", devNum, ret); diff --git a/0004-lxc-move-wireless-PHYs-to-a-network-namespace.patch b/0004-lxc-move-wireless-PHYs-to-a-network-namespace.patch new file mode 100644 index 0000000..0ba53ed --- /dev/null +++ b/0004-lxc-move-wireless-PHYs-to-a-network-namespace.patch @@ -0,0 +1,77 @@ +From: Lubomir Rintel +Date: Tue, 14 Apr 2015 18:21:44 +0200 +Subject: [PATCH] lxc: move wireless PHYs to a network namespace + +The 802.11 interfaces can not be moved by themselves, their Phy has to move too. + +If there are other interfaces, they have to move too -- hopefully it's not too +confusing. This is a less-invasive alternative to defining a new hostdev type +for PHYs. + +Signed-off-by: Michal Privoznik +(cherry picked from commit 3a495948b97770b026afab1ccaac560a9669a36e) +--- + src/util/virnetdev.c | 39 ++++++++++++++++++++++++++++++++++++--- + 1 file changed, 36 insertions(+), 3 deletions(-) + +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index 93f6715..e111a07 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -551,20 +551,53 @@ int virNetDevSetMTUFromDevice(const char *ifname, + */ + int virNetDevSetNamespace(const char *ifname, pid_t pidInNs) + { +- int rc; ++ int ret = -1; + char *pid = NULL; ++ char *phy = NULL; ++ char *phy_path = NULL; ++ int len; ++ + const char *argv[] = { + "ip", "link", "set", ifname, "netns", NULL, NULL + }; + ++ const char *iwargv[] = { ++ "iw", "phy", NULL, "set", "netns", NULL, NULL ++ }; ++ + if (virAsprintf(&pid, "%lld", (long long) pidInNs) == -1) + return -1; + + argv[5] = pid; +- rc = virRun(argv, NULL); ++ if (virRun(argv, NULL) < 0) ++ goto cleanup; ++ ++ /* The 802.11 wireless devices only move together with their PHY. */ ++ if (virNetDevSysfsFile(&phy_path, ifname, "phy80211/name") < 0) ++ goto cleanup; ++ ++ if ((len = virFileReadAllQuiet(phy_path, 1024, &phy) < 0)) { ++ if (errno == ENOENT) { ++ /* Okay, this is not a wireless card. Claim success. */ ++ ret = 0; ++ } ++ goto cleanup; ++ } ++ ++ /* Remove a line break. */ ++ phy[len - 1] = '\0'; ++ ++ iwargv[2] = phy; ++ iwargv[5] = pid; ++ if (virRun(iwargv, NULL) < 0) ++ goto cleanup; + ++ ret = 0; ++ cleanup: ++ VIR_FREE(phy_path); ++ VIR_FREE(phy); + VIR_FREE(pid); +- return rc; ++ return ret; + } + + #if defined(SIOCSIFNAME) && defined(HAVE_STRUCT_IFREQ) diff --git a/0005-tests-Add-virnetdevtestdata-to-EXTRA_DIST.patch b/0005-tests-Add-virnetdevtestdata-to-EXTRA_DIST.patch new file mode 100644 index 0000000..8acd8f3 --- /dev/null +++ b/0005-tests-Add-virnetdevtestdata-to-EXTRA_DIST.patch @@ -0,0 +1,27 @@ +From: Michal Privoznik +Date: Wed, 15 Apr 2015 10:09:52 +0200 +Subject: [PATCH] tests: Add virnetdevtestdata to EXTRA_DIST + +In one of my previous commits (49ed6cff9) I've introduced a test +among with some files stored under virnetdevtestdata folder. +While this works perfectly within a git tree, the folder was not +getting into .tar.gz and therefore the dist-check would fail. + +Signed-off-by: Michal Privoznik +(cherry picked from commit 598f3fddbc0a9e9c16bb0554ff1481d3250c7d00) +--- + tests/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 2dd0088..3af12b6 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -132,6 +132,7 @@ EXTRA_DIST = \ + vboxsnapshotxmldata \ + virsh-uriprecedence \ + virfiledata \ ++ virnetdevtestdata \ + virpcitestdata \ + virscsidata \ + virusbtestdata \ diff --git a/0006-lxc-don-t-up-the-veth-interfaces-unless-explicitly-a.patch b/0006-lxc-don-t-up-the-veth-interfaces-unless-explicitly-a.patch new file mode 100644 index 0000000..b63bb93 --- /dev/null +++ b/0006-lxc-don-t-up-the-veth-interfaces-unless-explicitly-a.patch @@ -0,0 +1,55 @@ +From: Lubomir Rintel +Date: Fri, 24 Apr 2015 15:52:56 +0200 +Subject: [PATCH] lxc: don't up the veth interfaces unless explicitly asked to + +Upping an interface for no reason and not configuring it is a cardinal sin. + +With the default addrgenmode if eui64 it sticks a link-local address to the +interface. That is not good, as NetworkManager would see an address configured, +assume the interface is already configured and won't touch it iself and the +interface might stay unconfigured until the end of the days. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1124721 + +Signed-off-by: Michal Privoznik +(cherry picked from commit c3cf3c43a0bb2e0e4909c32821e20f607635ec85) +--- + src/lxc/lxc_container.c | 3 ++- + src/lxc/lxc_native.c | 10 ++++------ + 2 files changed, 6 insertions(+), 7 deletions(-) + +diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c +index cc20b6d..9a9ae5c 100644 +--- a/src/lxc/lxc_container.c ++++ b/src/lxc/lxc_container.c +@@ -541,7 +541,8 @@ static int lxcContainerRenameAndEnableInterfaces(virDomainDefPtr vmDef, + VIR_FREE(ipStr); + } + +- if (netDef->linkstate != VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) { ++ if (netDef->nips || ++ netDef->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP) { + VIR_DEBUG("Enabling %s", newname); + rc = virNetDevSetOnline(newname, true); + if (rc < 0) +diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c +index abf07ce..434523a 100644 +--- a/src/lxc/lxc_native.c ++++ b/src/lxc/lxc_native.c +@@ -348,12 +348,10 @@ lxcCreateNetDef(const char *type, + if (VIR_ALLOC(net) < 0) + goto error; + +- if (flag) { +- if (STREQ(flag, "up")) +- net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP; +- else +- net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; +- } ++ if (STREQ_NULLABLE(flag, "up")) ++ net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP; ++ else ++ net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; + + if (VIR_STRDUP(net->ifname_guest, name) < 0) + goto error; diff --git a/0007-interface-don-t-error-out-if-a-bond-has-no-interface.patch b/0007-interface-don-t-error-out-if-a-bond-has-no-interface.patch new file mode 100644 index 0000000..cdd318d --- /dev/null +++ b/0007-interface-don-t-error-out-if-a-bond-has-no-interface.patch @@ -0,0 +1,80 @@ +From: Lubomir Rintel +Date: Wed, 27 May 2015 19:30:50 +0200 +Subject: [PATCH] interface: don't error out if a bond has no interfaces + +It's not a problem at all and causes virt-manager to break down. + +Note: netcf 0.2.8 and earlier generates invalid XML for a bond with no +interfaces anyway, so in that case this error in libvirt is never +reached since we fail earlier. + +Signed-off-by: Lubomir Rintel +(cherry picked from commit efc68de5cd70d62b1941a707d22299422f1962f9) +--- + src/conf/interface_conf.c | 29 ++++++++++++----------------- + 1 file changed, 12 insertions(+), 17 deletions(-) + +diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c +index c2eb945..26e55cc 100644 +--- a/src/conf/interface_conf.c ++++ b/src/conf/interface_conf.c +@@ -1,7 +1,7 @@ + /* + * interface_conf.c: interfaces XML handling + * +- * Copyright (C) 2006-2010, 2013, 2014 Red Hat, Inc. ++ * Copyright (C) 2006-2010, 2013-2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -548,39 +548,34 @@ virInterfaceDefParseBondItfs(virInterfaceDefPtr def, + virInterfaceDefPtr itf; + int nbItf; + size_t i; +- int ret = 0; ++ int ret = -1; + + nbItf = virXPathNodeSet("./interface", ctxt, &interfaces); +- if (nbItf < 0) { +- ret = -1; +- goto error; +- } ++ if (nbItf < 0) ++ goto cleanup; + + if (nbItf == 0) { +- virReportError(VIR_ERR_XML_ERROR, +- "%s", _("bond has no interfaces")); +- ret = -1; +- goto error; ++ ret = 0; ++ goto cleanup; + } + +- if (VIR_ALLOC_N(def->data.bond.itf, nbItf) < 0) { +- ret = -1; +- goto error; +- } ++ if (VIR_ALLOC_N(def->data.bond.itf, nbItf) < 0) ++ goto cleanup; ++ + def->data.bond.nbItf = nbItf; + + for (i = 0; i < nbItf; i++) { + ctxt->node = interfaces[i]; + itf = virInterfaceDefParseXML(ctxt, VIR_INTERFACE_TYPE_BOND); + if (itf == NULL) { +- ret = -1; + def->data.bond.nbItf = i; +- goto error; ++ goto cleanup; + } + def->data.bond.itf[i] = itf; + } + +- error: ++ ret = 0; ++ cleanup: + VIR_FREE(interfaces); + ctxt->node = bond; + return ret; diff --git a/0008-virnetdev-fix-moving-of-802.11-phys.patch b/0008-virnetdev-fix-moving-of-802.11-phys.patch new file mode 100644 index 0000000..a6acc8c --- /dev/null +++ b/0008-virnetdev-fix-moving-of-802.11-phys.patch @@ -0,0 +1,88 @@ +From: Lubomir Rintel +Date: Mon, 1 Jun 2015 20:40:23 +0200 +Subject: [PATCH] virnetdev: fix moving of 802.11 phys + +There was a couple of problems with the style fixes applied to the original +patch: + +1.) virFileReadAllQuiet comparison was incorrectly parenthesized when moved +into a condition, causing the len to be set to the result of comparison. This, +together with the removed underflow check would underflow the phy buffer. + +2.) The logic was broken. Failure to call "ip" would abort the function, thus +the "iw" branch would never be reached. + +This aims to fix the issues and work around possible style complains :) + +Signed-off-by: Lubomir Rintel +(cherry picked from commit 81b19ce46a9a65a00481403b8c0b15a8ac1367f2) +--- + src/util/virnetdev.c | 46 +++++++++++++++++++++------------------------- + 1 file changed, 21 insertions(+), 25 deletions(-) + +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index e111a07..e2c9f9d 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -557,40 +557,36 @@ int virNetDevSetNamespace(const char *ifname, pid_t pidInNs) + char *phy_path = NULL; + int len; + +- const char *argv[] = { +- "ip", "link", "set", ifname, "netns", NULL, NULL +- }; +- +- const char *iwargv[] = { +- "iw", "phy", NULL, "set", "netns", NULL, NULL +- }; +- + if (virAsprintf(&pid, "%lld", (long long) pidInNs) == -1) + return -1; + +- argv[5] = pid; +- if (virRun(argv, NULL) < 0) +- goto cleanup; +- + /* The 802.11 wireless devices only move together with their PHY. */ + if (virNetDevSysfsFile(&phy_path, ifname, "phy80211/name") < 0) + goto cleanup; + +- if ((len = virFileReadAllQuiet(phy_path, 1024, &phy) < 0)) { +- if (errno == ENOENT) { +- /* Okay, this is not a wireless card. Claim success. */ +- ret = 0; +- } +- goto cleanup; +- } ++ if ((len = virFileReadAllQuiet(phy_path, 1024, &phy)) <= 0) { ++ /* Not a wireless device. */ ++ const char *argv[] = { ++ "ip", "link", "set", ifname, "netns", NULL, NULL ++ }; + +- /* Remove a line break. */ +- phy[len - 1] = '\0'; ++ argv[5] = pid; ++ if (virRun(argv, NULL) < 0) ++ goto cleanup; + +- iwargv[2] = phy; +- iwargv[5] = pid; +- if (virRun(iwargv, NULL) < 0) +- goto cleanup; ++ } else { ++ const char *argv[] = { ++ "iw", "phy", NULL, "set", "netns", NULL, NULL ++ }; ++ ++ /* Remove a line break. */ ++ phy[len - 1] = '\0'; ++ ++ argv[2] = phy; ++ argv[5] = pid; ++ if (virRun(argv, NULL) < 0) ++ goto cleanup; ++ } + + ret = 0; + cleanup: diff --git a/0101-polkit-Allow-password-less-access-for-libvirt-group.patch b/0101-polkit-Allow-password-less-access-for-libvirt-group.patch new file mode 100644 index 0000000..9597b17 --- /dev/null +++ b/0101-polkit-Allow-password-less-access-for-libvirt-group.patch @@ -0,0 +1,126 @@ +From: Cole Robinson +Date: Tue, 28 Apr 2015 17:38:00 -0400 +Subject: [PATCH] polkit: Allow password-less access for 'libvirt' group + +Many users, who admin their own machines, want to be able to access +system libvirtd via tools like virt-manager without having to enter +a root password. Just google 'virt-manager without password' and +you'll find many hits. I've read at least 5 blog posts over the years +describing slightly different ways of achieving this goal. + +Let's finally add official support for this. + +Install a polkit-1 rules file granting password-less auth for any user +in the new 'libvirt' group. Create the group on RPM install + +https://bugzilla.redhat.com/show_bug.cgi?id=957300 +(cherry picked from commit e94979e901517af9fdde358d7b7c92cc055dd50c) +--- + daemon/Makefile.am | 13 +++++++++++++ + daemon/libvirt.rules | 9 +++++++++ + libvirt.spec.in | 15 +++++++++++++-- + 3 files changed, 35 insertions(+), 2 deletions(-) + create mode 100644 daemon/libvirt.rules + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index b95a79d..9c5ea37 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -53,6 +53,7 @@ EXTRA_DIST = \ + libvirtd.init.in \ + libvirtd.upstart \ + libvirtd.policy.in \ ++ libvirt.rules \ + libvirtd.sasl \ + libvirtd.service.in \ + libvirtd.socket.in \ +@@ -233,6 +234,8 @@ policyauth = auth_admin_keep_session + else ! WITH_POLKIT0 + policydir = $(datadir)/polkit-1/actions + policyauth = auth_admin_keep ++rulesdir = $(datadir)/polkit-1/rules.d ++rulesfile = libvirt.rules + endif ! WITH_POLKIT0 + endif WITH_POLKIT + +@@ -263,9 +266,19 @@ if WITH_POLKIT + install-data-polkit:: + $(MKDIR_P) $(DESTDIR)$(policydir) + $(INSTALL_DATA) libvirtd.policy $(DESTDIR)$(policydir)/org.libvirt.unix.policy ++if ! WITH_POLKIT0 ++ $(MKDIR_P) $(DESTDIR)$(rulesdir) ++ $(INSTALL_DATA) $(srcdir)/$(rulesfile) $(DESTDIR)$(rulesdir)/50-libvirt.rules ++endif ! WITH_POLKIT0 ++ + uninstall-data-polkit:: + rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy + rmdir $(DESTDIR)$(policydir) || : ++if ! WITH_POLKIT0 ++ rm -f $(DESTDIR)$(rulesdir)/50-libvirt.rules ++ rmdir $(DESTDIR)$(rulesdir) || : ++endif ! WITH_POLKIT0 ++ + else ! WITH_POLKIT + install-data-polkit:: + uninstall-data-polkit:: +diff --git a/daemon/libvirt.rules b/daemon/libvirt.rules +new file mode 100644 +index 0000000..01a15fa +--- /dev/null ++++ b/daemon/libvirt.rules +@@ -0,0 +1,9 @@ ++// Allow any user in the 'libvirt' group to connect to system libvirtd ++// without entering a password. ++ ++polkit.addRule(function(action, subject) { ++ if (action.id == "org.libvirt.unix.manage" && ++ subject.isInGroup("libvirt")) { ++ return polkit.Result.YES; ++ } ++}); +diff --git a/libvirt.spec.in b/libvirt.spec.in +index f25b710..766bd08 100644 +--- a/libvirt.spec.in ++++ b/libvirt.spec.in +@@ -1628,9 +1628,9 @@ then + fi + + %if %{with_libvirtd} ++%pre daemon + %if ! %{with_driver_modules} + %if %{with_qemu} +-%pre daemon + %if 0%{?fedora} || 0%{?rhel} >= 6 + # We want soft static allocation of well-known ids, as disk images + # are commonly shared across NFS mounts by id rather than name; see +@@ -1644,11 +1644,21 @@ if ! getent passwd qemu >/dev/null; then + useradd -r -g qemu -G kvm -d / -s /sbin/nologin -c "qemu user" qemu + fi + fi +-exit 0 + %endif + %endif + %endif + ++ %if %{with_polkit} ++ %if 0%{?fedora} || 0%{?rhel} >= 6 ++# 'libvirt' group is just to allow password-less polkit access to ++# libvirtd. The uid number is irrelevant, so we use dynamic allocation ++# described at the above link. ++getent group libvirt >/dev/null || groupadd -r libvirt ++ %endif ++ %endif ++ ++exit 0 ++ + %post daemon + + %if %{with_systemd} +@@ -1922,6 +1932,7 @@ exit 0 + %if 0%{?fedora} || 0%{?rhel} >= 6 + %{_datadir}/polkit-1/actions/org.libvirt.unix.policy + %{_datadir}/polkit-1/actions/org.libvirt.api.policy ++%{_datadir}/polkit-1/rules.d/50-libvirt.rules + %else + %{_datadir}/PolicyKit/policy/org.libvirt.unix.policy + %endif