Rebased to version 1.2.13.2

disk backend is not removed properly when disk frontent hotplug fails (bz #1265968)
Fix TPM cancel path on newer kernels (bz #1244895)
Remove timeout for libvirt-guests.service (bz #1195544)
CVE-2015-5313 libvirt: filesystem storage volume names path traversal flaw (bz #1291433)
Fix VM names with non-ascii (bz #1062943)
Fix backwards migration with graphics listen address (bz #1276883)
remotes/origin/f22
Cole Robinson 2015-12-23 19:09:14 -05:00
parent 1b23098699
commit 43c932192d
15 changed files with 20 additions and 1554 deletions

View File

@ -1,40 +0,0 @@
From: Eric Blake <eblake@redhat.com>
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 <eblake@redhat.com>
(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)

View File

@ -79,10 +79,10 @@ index 0000000..01a15fa
+ }
+});
diff --git a/libvirt.spec.in b/libvirt.spec.in
index f25b710..766bd08 100644
index dc327a2..a23629d 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1628,9 +1628,9 @@ then
@@ -1631,9 +1631,9 @@ then
fi
%if %{with_libvirtd}
@ -93,7 +93,7 @@ index f25b710..766bd08 100644
%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
@@ -1647,11 +1647,21 @@ if ! getent passwd qemu >/dev/null; then
useradd -r -g qemu -G kvm -d / -s /sbin/nologin -c "qemu user" qemu
fi
fi
@ -116,7 +116,7 @@ index f25b710..766bd08 100644
%post daemon
%if %{with_systemd}
@@ -1922,6 +1932,7 @@ exit 0
@@ -1925,6 +1935,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

View File

@ -1,310 +0,0 @@
From: Michal Privoznik <mprivozn@redhat.com>
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 <mprivozn@redhat.com>
(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
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Michal Privoznik <mprivozn@redhat.com>
+ */
+
+#include <config.h>
+
+#ifdef __linux__
+# include "internal.h"
+# include <stdlib.h>
+# include <stdio.h>
+# 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
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Michal Privoznik <mprivozn@redhat.com>
+ */
+
+#include <config.h>
+
+#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

View File

@ -1,265 +0,0 @@
From: Michal Privoznik <mprivozn@redhat.com>
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 <mprivozn@redhat.com>
(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);

View File

@ -1,77 +0,0 @@
From: Lubomir Rintel <lkundrak@v3.sk>
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 <mprivozn@redhat.com>
(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)

View File

@ -1,27 +0,0 @@
From: Michal Privoznik <mprivozn@redhat.com>
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 <mprivozn@redhat.com>
(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 \

View File

@ -1,55 +0,0 @@
From: Lubomir Rintel <lkundrak@v3.sk>
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 <mprivozn@redhat.com>
(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;

View File

@ -1,80 +0,0 @@
From: Lubomir Rintel <lkundrak@v3.sk>
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 <lkundrak@v3.sk>
(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;

View File

@ -1,88 +0,0 @@
From: Lubomir Rintel <lkundrak@v3.sk>
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 <lkundrak@v3.sk>
(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:

View File

@ -1,35 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 13 Mar 2015 16:59:26 +0100
Subject: [PATCH] qemu: process: Export qemuProcessFindDomainDiskByAlias
(cherry picked from commit 5c634730b99b53afd6e2cea4b7d2fc2dfc2ee630)
---
src/qemu/qemu_process.c | 2 +-
src/qemu/qemu_process.h | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 46f02b5..1994027 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -390,7 +390,7 @@ qemuProcessFindDomainDiskByPath(virDomainObjPtr vm,
return NULL;
}
-static virDomainDiskDefPtr
+virDomainDiskDefPtr
qemuProcessFindDomainDiskByAlias(virDomainObjPtr vm,
const char *alias)
{
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 2e1d393..fffc926 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -107,4 +107,7 @@ int qemuProcessReadLog(int fd, char *buf, int buflen, int off, bool skipchar);
int qemuProcessSetSchedParams(int id, pid_t pid, size_t nsp,
virDomainThreadSchedParamPtr sp);
+virDomainDiskDefPtr qemuProcessFindDomainDiskByAlias(virDomainObjPtr vm,
+ const char *alias);
+
#endif /* __QEMU_PROCESS_H__ */

View File

@ -1,351 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 13 Mar 2015 17:00:03 +0100
Subject: [PATCH] qemu: event: Don't fiddle with disk backing trees without a
job
Surprisingly we did not grab a VM job when a block job finished and we'd
happily rewrite the backing chain data. This made it possible to crash
libvirt when queueing two backing chains tightly and other badness.
To fix it, add yet another handler to the helper thread that handles
monitor events that require a job.
(cherry picked from commit 1a92c719101e5bfa6fe2b78006ad04c7f075ea28)
---
src/qemu/qemu_domain.h | 2 +
src/qemu/qemu_driver.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_process.c | 129 ++++++++-----------------------------------
3 files changed, 168 insertions(+), 105 deletions(-)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index fe3e2b1..a7ebb47 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -196,6 +196,7 @@ typedef enum {
QEMU_PROCESS_EVENT_DEVICE_DELETED,
QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED,
QEMU_PROCESS_EVENT_SERIAL_CHANGED,
+ QEMU_PROCESS_EVENT_BLOCK_JOB,
QEMU_PROCESS_EVENT_LAST
} qemuProcessEventType;
@@ -204,6 +205,7 @@ struct qemuProcessEvent {
virDomainObjPtr vm;
qemuProcessEventType eventType;
int action;
+ int status;
void *data;
};
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1009497..2e8c9d8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4480,6 +4480,141 @@ processSerialChangedEvent(virQEMUDriverPtr driver,
}
+static void
+processBlockJobEvent(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ char *diskAlias,
+ int type,
+ int status)
+{
+ virObjectEventPtr event = NULL;
+ virObjectEventPtr event2 = NULL;
+ const char *path;
+ virDomainDiskDefPtr disk;
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainDiskDefPtr persistDisk = NULL;
+ bool save = false;
+
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Domain is not running");
+ goto endjob;
+ }
+
+ disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
+
+ if (disk) {
+ /* Have to generate two variants of the event for old vs. new
+ * client callbacks */
+ if (type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT &&
+ disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)
+ type = disk->mirrorJob;
+ path = virDomainDiskGetSource(disk);
+ event = virDomainEventBlockJobNewFromObj(vm, path, type, status);
+ event2 = virDomainEventBlockJob2NewFromObj(vm, disk->dst, type,
+ status);
+
+ /* If we completed a block pull or commit, then update the XML
+ * to match. */
+ switch ((virConnectDomainEventBlockJobStatus) status) {
+ case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
+ if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
+ if (vm->newDef) {
+ int indx = virDomainDiskIndexByName(vm->newDef, disk->dst,
+ false);
+ virStorageSourcePtr copy = NULL;
+
+ if (indx >= 0) {
+ persistDisk = vm->newDef->disks[indx];
+ copy = virStorageSourceCopy(disk->mirror, false);
+ if (virStorageSourceInitChainElement(copy,
+ persistDisk->src,
+ true) < 0) {
+ VIR_WARN("Unable to update persistent definition "
+ "on vm %s after block job",
+ vm->def->name);
+ virStorageSourceFree(copy);
+ copy = NULL;
+ persistDisk = NULL;
+ }
+ }
+ if (copy) {
+ virStorageSourceFree(persistDisk->src);
+ persistDisk->src = copy;
+ }
+ }
+
+ /* XXX We want to revoke security labels and disk
+ * lease, as well as audit that revocation, before
+ * dropping the original source. But it gets tricky
+ * if both source and mirror share common backing
+ * files (we want to only revoke the non-shared
+ * portion of the chain); so for now, we leak the
+ * access to the original. */
+ virStorageSourceFree(disk->src);
+ disk->src = disk->mirror;
+ } else {
+ virStorageSourceFree(disk->mirror);
+ }
+
+ /* Recompute the cached backing chain to match our
+ * updates. Better would be storing the chain ourselves
+ * rather than reprobing, but we haven't quite completed
+ * that conversion to use our XML tracking. */
+ disk->mirror = NULL;
+ save = disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
+ disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
+ disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
+ ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk,
+ true, true));
+ break;
+
+ case VIR_DOMAIN_BLOCK_JOB_READY:
+ disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY;
+ save = true;
+ break;
+
+ case VIR_DOMAIN_BLOCK_JOB_FAILED:
+ case VIR_DOMAIN_BLOCK_JOB_CANCELED:
+ virStorageSourceFree(disk->mirror);
+ disk->mirror = NULL;
+ disk->mirrorState = status == VIR_DOMAIN_BLOCK_JOB_FAILED ?
+ VIR_DOMAIN_DISK_MIRROR_STATE_ABORT : VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
+ disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
+ save = true;
+ break;
+
+ case VIR_DOMAIN_BLOCK_JOB_LAST:
+ break;
+ }
+ }
+
+ if (save) {
+ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
+ VIR_WARN("Unable to save status on vm %s after block job",
+ vm->def->name);
+ if (persistDisk && virDomainSaveConfig(cfg->configDir,
+ vm->newDef) < 0)
+ VIR_WARN("Unable to update persistent definition on vm %s "
+ "after block job", vm->def->name);
+ }
+ virObjectUnlock(vm);
+ virObjectUnref(cfg);
+
+ if (event)
+ qemuDomainEventQueue(driver, event);
+ if (event2)
+ qemuDomainEventQueue(driver, event2);
+
+ endjob:
+ qemuDomainObjEndJob(driver, vm);
+ cleanup:
+ VIR_FREE(diskAlias);
+}
+
+
static void qemuProcessEventHandler(void *data, void *opaque)
{
struct qemuProcessEvent *processEvent = data;
@@ -4506,6 +4641,13 @@ static void qemuProcessEventHandler(void *data, void *opaque)
case QEMU_PROCESS_EVENT_SERIAL_CHANGED:
processSerialChangedEvent(driver, vm, processEvent->data,
processEvent->action);
+ break;
+ case QEMU_PROCESS_EVENT_BLOCK_JOB:
+ processBlockJobEvent(driver, vm,
+ processEvent->data,
+ processEvent->action,
+ processEvent->status);
+ break;
case QEMU_PROCESS_EVENT_LAST:
break;
}
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1994027..685cec6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1017,123 +1017,42 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
- virObjectEventPtr event = NULL;
- virObjectEventPtr event2 = NULL;
- const char *path;
- virDomainDiskDefPtr disk;
- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- virDomainDiskDefPtr persistDisk = NULL;
- bool save = false;
+ struct qemuProcessEvent *processEvent = NULL;
+ char *data;
virObjectLock(vm);
- disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias);
- if (disk) {
- /* Have to generate two variants of the event for old vs. new
- * client callbacks */
- if (type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT &&
- disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT)
- type = disk->mirrorJob;
- path = virDomainDiskGetSource(disk);
- event = virDomainEventBlockJobNewFromObj(vm, path, type, status);
- event2 = virDomainEventBlockJob2NewFromObj(vm, disk->dst, type,
- status);
-
- /* If we completed a block pull or commit, then update the XML
- * to match. */
- switch ((virConnectDomainEventBlockJobStatus) status) {
- case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
- if (disk->mirrorState == VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT) {
- if (vm->newDef) {
- int indx = virDomainDiskIndexByName(vm->newDef, disk->dst,
- false);
- virStorageSourcePtr copy = NULL;
-
- if (indx >= 0) {
- persistDisk = vm->newDef->disks[indx];
- copy = virStorageSourceCopy(disk->mirror, false);
- if (virStorageSourceInitChainElement(copy,
- persistDisk->src,
- true) < 0) {
- VIR_WARN("Unable to update persistent definition "
- "on vm %s after block job",
- vm->def->name);
- virStorageSourceFree(copy);
- copy = NULL;
- persistDisk = NULL;
- }
- }
- if (copy) {
- virStorageSourceFree(persistDisk->src);
- persistDisk->src = copy;
- }
- }
-
- /* XXX We want to revoke security labels and disk
- * lease, as well as audit that revocation, before
- * dropping the original source. But it gets tricky
- * if both source and mirror share common backing
- * files (we want to only revoke the non-shared
- * portion of the chain); so for now, we leak the
- * access to the original. */
- virStorageSourceFree(disk->src);
- disk->src = disk->mirror;
- } else {
- virStorageSourceFree(disk->mirror);
- }
+ VIR_DEBUG("Block job for device %s (domain: %p,%s) type %d status %d",
+ diskAlias, vm, vm->def->name, type, status);
- /* Recompute the cached backing chain to match our
- * updates. Better would be storing the chain ourselves
- * rather than reprobing, but we haven't quite completed
- * that conversion to use our XML tracking. */
- disk->mirror = NULL;
- save = disk->mirrorState != VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
- disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
- disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
- ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk,
- true, true));
- break;
-
- case VIR_DOMAIN_BLOCK_JOB_READY:
- disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_READY;
- save = true;
- break;
+ if (VIR_ALLOC(processEvent) < 0)
+ goto error;
- case VIR_DOMAIN_BLOCK_JOB_FAILED:
- case VIR_DOMAIN_BLOCK_JOB_CANCELED:
- virStorageSourceFree(disk->mirror);
- disk->mirror = NULL;
- disk->mirrorState = status == VIR_DOMAIN_BLOCK_JOB_FAILED ?
- VIR_DOMAIN_DISK_MIRROR_STATE_ABORT : VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
- disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
- save = true;
- break;
+ processEvent->eventType = QEMU_PROCESS_EVENT_BLOCK_JOB;
+ if (VIR_STRDUP(data, diskAlias) < 0)
+ goto error;
+ processEvent->data = data;
+ processEvent->vm = vm;
+ processEvent->action = type;
+ processEvent->status = status;
- case VIR_DOMAIN_BLOCK_JOB_LAST:
- break;
- }
+ virObjectRef(vm);
+ if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
+ ignore_value(virObjectUnref(vm));
+ goto error;
}
- if (save) {
- if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
- VIR_WARN("Unable to save status on vm %s after block job",
- vm->def->name);
- if (persistDisk && virDomainSaveConfig(cfg->configDir,
- vm->newDef) < 0)
- VIR_WARN("Unable to update persistent definition on vm %s "
- "after block job", vm->def->name);
- }
+ cleanup:
virObjectUnlock(vm);
- virObjectUnref(cfg);
-
- if (event)
- qemuDomainEventQueue(driver, event);
- if (event2)
- qemuDomainEventQueue(driver, event2);
-
return 0;
+ error:
+ if (processEvent)
+ VIR_FREE(processEvent->data);
+ VIR_FREE(processEvent);
+ goto cleanup;
}
+
static int
qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,

View File

@ -1,175 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 13 Mar 2015 17:22:04 +0100
Subject: [PATCH] qemu: Disallow concurrent block jobs on a single disk
While qemu may be prepared to do this libvirt is not. Forbid the block
ops until we fix our code.
(cherry picked from commit 51f9f03a4ca50b070c0fbfb29748d49f583e15e1)
---
src/conf/domain_conf.h | 4 ++++
src/qemu/qemu_domain.c | 23 +++++++++++++++++++++++
src/qemu/qemu_domain.h | 2 ++
src/qemu/qemu_driver.c | 28 +++++++++++++---------------
4 files changed, 42 insertions(+), 15 deletions(-)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bca1b94..47bdb61 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -664,6 +664,10 @@ struct _virDomainDiskDef {
int tray_status; /* enum virDomainDiskTray */
int removable; /* enum virTristateSwitch */
+ /* ideally we want a smarter way to interlock block jobs on single qemu disk
+ * in the future, but for now we just disallow any concurrent job on a
+ * single disk */
+ bool blockjob;
virStorageSourcePtr mirror;
int mirrorState; /* enum virDomainDiskMirrorState */
int mirrorJob; /* virDomainBlockJobType */
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index bd7d8a4..7c2d046 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2757,6 +2757,29 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
return ret;
}
+
+bool
+qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk)
+{
+ if (disk->mirror) {
+ virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
+ _("disk '%s' already in active block job"),
+ disk->dst);
+
+ return true;
+ }
+
+ if (disk->blockjob) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("disk '%s' already in active block job"),
+ disk->dst);
+ return true;
+ }
+
+ return false;
+}
+
+
int
qemuDomainUpdateDeviceList(virQEMUDriverPtr driver,
virDomainObjPtr vm,
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index a7ebb47..41e075b 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -414,6 +414,8 @@ int qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+bool qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk);
+
void qemuDomObjEndAPI(virDomainObjPtr *vm);
#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2e8c9d8..3ec057b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4569,6 +4569,7 @@ processBlockJobEvent(virQEMUDriverPtr driver,
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk,
true, true));
+ disk->blockjob = false;
break;
case VIR_DOMAIN_BLOCK_JOB_READY:
@@ -4584,6 +4585,7 @@ processBlockJobEvent(virQEMUDriverPtr driver,
VIR_DOMAIN_DISK_MIRROR_STATE_ABORT : VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
save = true;
+ disk->blockjob = false;
break;
case VIR_DOMAIN_BLOCK_JOB_LAST:
@@ -15827,6 +15829,7 @@ qemuDomainBlockPivot(virConnectPtr conn,
disk->mirror = NULL;
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
+ disk->blockjob = false;
}
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
ret = -1;
@@ -15927,12 +15930,9 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
goto endjob;
disk = vm->def->disks[idx];
- if (mode == BLOCK_JOB_PULL && disk->mirror) {
- virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
- _("disk '%s' already in active block job"),
- disk->dst);
+ if (mode == BLOCK_JOB_PULL && qemuDomainDiskBlockJobIsActive(disk))
goto endjob;
- }
+
if (mode == BLOCK_JOB_ABORT) {
if ((flags & VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT) &&
!(async && disk->mirror)) {
@@ -16017,6 +16017,8 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
if (mode == BLOCK_JOB_ABORT && disk->mirror)
disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
goto endjob;
+ } else if (mode == BLOCK_JOB_PULL) {
+ disk->blockjob = true;
}
waitjob:
@@ -16269,12 +16271,8 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
if (!device)
goto endjob;
disk = vm->def->disks[idx];
- if (disk->mirror) {
- virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
- _("disk '%s' already in active block job"),
- disk->dst);
+ if (qemuDomainDiskBlockJobIsActive(disk))
goto endjob;
- }
if (!(virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_MIRROR) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC))) {
@@ -16396,6 +16394,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
disk->mirror = mirror;
mirror = NULL;
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
+ disk->blockjob = true;
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
VIR_WARN("Unable to save status on vm %s after state change",
@@ -16657,12 +16656,9 @@ qemuDomainBlockCommit(virDomainPtr dom,
disk->dst);
goto endjob;
}
- if (disk->mirror) {
- virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
- _("disk '%s' already in active block job"),
- disk->dst);
+
+ if (qemuDomainDiskBlockJobIsActive(disk))
goto endjob;
- }
if (qemuDomainDetermineDiskChain(driver, vm, disk, false, true) < 0)
goto endjob;
@@ -16785,6 +16781,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
goto endjob;
}
+ disk->blockjob = true;
+
if (mirror) {
if (ret == 0) {
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);

View File

@ -1,28 +0,0 @@
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 16 Mar 2015 16:52:44 +0100
Subject: [PATCH] qemu: block-commit: Mark disk in block jobs only on
successful command
Patch 51f9f03a4ca50b070c0fbfb29748d49f583e15e1 introduces a regression
where if a blockCommit operation fails the disk is still marked as being
part of a block job but can't be unmarked later.
(cherry picked from commit ee744b5b387b5123ee40683c52ab40783ffc3020)
---
src/qemu/qemu_driver.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3ec057b..4817e06 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16781,7 +16781,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
goto endjob;
}
- disk->blockjob = true;
+ if (ret == 0)
+ disk->blockjob = true;
if (mirror) {
if (ret == 0) {

View File

@ -370,8 +370,8 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 1.2.13.1
Release: 3%{?dist}%{?extra_release}
Version: 1.2.13.2
Release: 1%{?dist}%{?extra_release}
License: LGPLv2+
Group: Development/Libraries
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@ -382,23 +382,8 @@ URL: http://libvirt.org/
%endif
Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz
# lxc network fixes (bz #1225591, bz #1225593, bz #1225594)
Patch0001: 0001-build-provide-virNetDevSysfsFile-on-non-Linux.patch
Patch0002: 0002-Introduce-virnetdevtest.patch
Patch0003: 0003-Cleanup-sys-class-net-usage.patch
Patch0004: 0004-lxc-move-wireless-PHYs-to-a-network-namespace.patch
Patch0005: 0005-tests-Add-virnetdevtestdata-to-EXTRA_DIST.patch
Patch0006: 0006-lxc-don-t-up-the-veth-interfaces-unless-explicitly-a.patch
Patch0007: 0007-interface-don-t-error-out-if-a-bond-has-no-interface.patch
Patch0008: 0008-virnetdev-fix-moving-of-802.11-phys.patch
# polkit: Allow password-less access for 'libvirt' group (bz #957300)
Patch0101: 0101-polkit-Allow-password-less-access-for-libvirt-group.patch
# Add sanity checks for drive mirroring (bz #1263438)
Patch0102: 0102-qemu-process-Export-qemuProcessFindDomainDiskByAlias.patch
Patch0103: 0103-qemu-event-Don-t-fiddle-with-disk-backing-trees-with.patch
Patch0104: 0104-qemu-Disallow-concurrent-block-jobs-on-a-single-disk.patch
Patch0105: 0105-qemu-block-commit-Mark-disk-in-block-jobs-only-on-su.patch
Patch0001: 0001-polkit-Allow-password-less-access-for-libvirt-group.patch
%if %{with_libvirtd}
Requires: libvirt-daemon = %{version}-%{release}
@ -1261,6 +1246,7 @@ if [ $COUNT -gt 0 ]; then
fi
echo "Applied $COUNT patches"
rm -f $PATCHLIST
rm -rf .git
%build
%if ! %{with_xen}
@ -2311,6 +2297,17 @@ exit 0
%doc examples/systemtap
%changelog
* Wed Dec 23 2015 Cole Robinson <crobinso@redhat.com> - 1.2.13.2-1
- Rebased to version 1.2.13.2
- disk backend is not removed properly when disk frontent hotplug fails (bz
#1265968)
- Fix TPM cancel path on newer kernels (bz #1244895)
- Remove timeout for libvirt-guests.service (bz #1195544)
- CVE-2015-5313 libvirt: filesystem storage volume names path traversal flaw
(bz #1291433)
- Fix VM names with non-ascii (bz #1062943)
- Fix backwards migration with graphics listen address (bz #1276883)
* Mon Sep 21 2015 Cole Robinson <crobinso@redhat.com> - 1.2.13.1-3
- Add sanity checks for drive mirroring (bz #1263438)

View File

@ -1 +1 @@
ed36872b34ad3b2e01744b189c039d5c libvirt-1.2.13.1.tar.gz
05f461cd499c628ef07822dd607c340a libvirt-1.2.13.2.tar.gz