[libvirt] [PATCH] RFC: use a slirp helper process
by marcandre.lureau@redhat.com
From: Marc-André Lureau <marcandre.lureau(a)redhat.com>
I am throwing this away for discussions, and early feedback.
With the upcoming release of libslirp[1], we have an opportunity to
run SLIRP networking in a separate process. This will allow for
stricter security policies for both qemu & slirp, as slirp is
notoriously not very safe (discussed on ML, various CVEs, and even the
code says so explicitly in the comments), yet people rely on it regularly.
For network type "user", libvirt could spawn an helper process (an
experimental version is [2]). It would setup a socket pair between
qemu and the helper and use -net socket. qemu could then be built
without libslirp! (imho, qemu should deprecate built-in -net user
support, and doesn't need to grow its own sub-process handling)
This libvirt patch is a bit rough, I am not sure where things should
go. In particular, how to manage the subprocesses properly (security
aspects, and lifecycle etc), and how to deal with migration (prevent
migrating from non-helper to helper version etc).
It seems guestfwd has been non-functional for a while. This is also
something that the current experimental helper doesn't support
atm. Doing all the various "channel" types that libvirt/qemu support
would be tedious, and probably unnecessary. But the underlying
libslirp library support redirections the same way qemu does today, so
it could be added if necessary.
At this point, the slirp-helper doesn't handle migration. But is it
really worth it? From a guest POV, it would look like packet lost or
disconnection. Adding migration handling is possible, to avoid a
disconnection event. How should it be done? via a libvirt provided
socket for storage? via its own file transferred by libvirt? via qemu
somehow (qemu wouldn't really know about the external process but
would copy around the migration bits?).
Does the helper need to have a "standard" & capabilities, similar to
what is proposed for vhost-user [3]? This would allow for easier
competing implementation to emerge (I have plans in mind, not using
libslirp).
Thanks for the feedback!
[1] https://gitlab.freedesktop.org/slirp/libslirp
[2] https://github.com/elmarco/libslirp-rs
[3] https://git.qemu.org/?p=qemu.git;a=blob;f=docs/interop/vhost-user.json
Signed-off-by: Marc-André Lureau <marcandre.lureau(a)redhat.com>
---
m4/virt-driver-qemu.m4 | 5 ++
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 3 ++
src/qemu/qemu_capabilities.c | 6 +++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 38 +++++++++++---
src/qemu/qemu_command.h | 3 +-
src/qemu/qemu_conf.c | 7 ++-
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_domain.c | 11 ++++
src/qemu/qemu_domain.h | 3 ++
src/qemu/qemu_hotplug.c | 5 +-
src/qemu/qemu_interface.c | 80 ++++++++++++++++++++++++++++++
src/qemu/qemu_interface.h | 6 +++
src/qemu/test_libvirtd_qemu.aug.in | 1 +
15 files changed, 161 insertions(+), 10 deletions(-)
diff --git a/m4/virt-driver-qemu.m4 b/m4/virt-driver-qemu.m4
index a1d05bbd7f..705b1f592b 100644
--- a/m4/virt-driver-qemu.m4
+++ b/m4/virt-driver-qemu.m4
@@ -105,6 +105,11 @@ AC_DEFUN([LIBVIRT_DRIVER_CHECK_QEMU], [
[/usr/bin:/usr/libexec])
AC_DEFINE_UNQUOTED([QEMU_PR_HELPER], ["$QEMU_PR_HELPER"],
[QEMU PR helper])
+ AC_PATH_PROG([SLIRP_HELPER], [slirp-helper],
+ [/usr/bin/slirp-helper],
+ [/usr/bin:/usr/libexec])
+ AC_DEFINE_UNQUOTED([SLIRP_HELPER], ["$SLIRP_HELPER"],
+ [slirp helper])
])
AC_DEFUN([LIBVIRT_DRIVER_RESULT_QEMU], [
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index b311f02da6..15206454e0 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -88,6 +88,7 @@ module Libvirtd_qemu =
| bool_entry "clear_emulator_capabilities"
| str_entry "bridge_helper"
| str_entry "pr_helper"
+ | str_entry "slirp_helper"
| bool_entry "set_process_name"
| int_entry "max_processes"
| int_entry "max_files"
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 334b4cd4ee..725ae791c5 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -810,6 +810,9 @@
# used whenever <reservations/> are enabled for SCSI LUN devices.
#pr_helper = "/usr/bin/qemu-pr-helper"
+# Path to the SLIRP networking helper.
+#slirp_helper = "/usr/bin/slirp-helper"
+
# User for the swtpm TPM Emulator
#
# Default is 'tss'; this is the same user that tcsd (TrouSerS) installs
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f8ea66b577..86cef7b9ab 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -524,6 +524,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"scsi-disk.device_id",
"virtio-pci-non-transitional",
"overcommit",
+ "net-socket-dgram",
);
@@ -4212,6 +4213,11 @@ virQEMUCapsInitQMPVersionCaps(virQEMUCapsPtr qemuCaps)
ARCH_IS_PPC64(qemuCaps->arch)) {
virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT);
}
+
+ /* -net socket,fd= with dgram socket (for ex, with slirp helper) */
+ if (qemuCaps->version >= 3001092) {
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_NET_SOCKET_DGRAM);
+ }
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 23ecef8c63..9db4c1bf2d 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -506,6 +506,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_SCSI_DISK_DEVICE_ID, /* 'device_id' property of scsi disk */
QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL, /* virtio *-pci-{non-}transitional devices */
QEMU_CAPS_OVERCOMMIT, /* -overcommit */
+ QEMU_CAPS_NET_SOCKET_DGRAM,
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9df7b7e8ea..6a047fa8f9 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4066,7 +4066,8 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
char **tapfd,
size_t tapfdSize,
char **vhostfd,
- size_t vhostfdSize)
+ size_t vhostfdSize,
+ char *slirpfd)
{
bool is_tap = false;
virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -4137,6 +4138,12 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
break;
case VIR_DOMAIN_NET_TYPE_USER:
+ if (slirpfd) {
+ virBufferAsprintf(&buf, "socket,fd=%s,",
+ slirpfd);
+ break;
+ }
+
virBufferAddLit(&buf, "user,");
for (i = 0; i < net->guestIP.nips; i++) {
const virNetDevIPAddr *ip = net->guestIP.ips[i];
@@ -8721,10 +8728,10 @@ qemuInterfaceVhostuserConnect(virQEMUDriverPtr driver,
static int
qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
virLogManagerPtr logManager,
virSecurityManagerPtr secManager,
virCommandPtr cmd,
- virDomainDefPtr def,
virDomainNetDefPtr net,
virQEMUCapsPtr qemuCaps,
unsigned int bootindex,
@@ -8733,6 +8740,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
size_t *nnicindexes,
int **nicindexes)
{
+ virDomainDefPtr def = vm->def;
int ret = -1;
char *nic = NULL;
char *host = NULL;
@@ -8743,12 +8751,13 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
size_t vhostfdSize = 0;
char **tapfdName = NULL;
char **vhostfdName = NULL;
+ int slirpfd = -1;
+ char *slirpfdName = NULL;
virDomainNetType actualType = virDomainNetGetActualType(net);
virNetDevBandwidthPtr actualBandwidth;
bool requireNicdev = false;
size_t i;
-
if (!bootindex)
bootindex = net->info.bootIndex;
@@ -8971,6 +8980,18 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
goto cleanup;
}
+ if (actualType == VIR_DOMAIN_NET_TYPE_USER &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_NET_SOCKET_DGRAM) &&
+ !standalone) {
+ if (qemuInterfaceOpenSlirp(driver, vm, net, &slirpfd) < 0) {
+ goto cleanup;
+ }
+ virCommandPassFD(cmd, slirpfd,
+ VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+ if (virAsprintf(&slirpfdName, "%d", slirpfd) < 0)
+ goto cleanup;
+ }
+
for (i = 0; i < tapfdSize; i++) {
if (qemuSecuritySetTapFDLabel(driver->securityManager,
def, tapfd[i]) < 0)
@@ -8993,7 +9014,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
if (!(host = qemuBuildHostNetStr(net, driver,
tapfdName, tapfdSize,
- vhostfdName, vhostfdSize)))
+ vhostfdName, vhostfdSize,
+ slirpfdName)))
goto cleanup;
virCommandAddArgList(cmd, "-netdev", host, NULL);
@@ -9032,6 +9054,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
virSetError(saved_err);
virFreeError(saved_err);
}
+ VIR_FREE(slirpfdName);
for (i = 0; vhostfd && i < vhostfdSize && vhostfd[i] >= 0; i++) {
if (ret < 0)
VIR_FORCE_CLOSE(vhostfd[i]);
@@ -9061,10 +9084,10 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
*/
static int
qemuBuildNetCommandLine(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
virLogManagerPtr logManager,
virSecurityManagerPtr secManager,
virCommandPtr cmd,
- virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
virNetDevVPortProfileOp vmop,
bool standalone,
@@ -9075,6 +9098,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
size_t i;
int last_good_net = -1;
virErrorPtr originalError = NULL;
+ virDomainDefPtr def = vm->def;
if (def->nnets) {
unsigned int bootNet = 0;
@@ -9090,7 +9114,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr net = def->nets[i];
- if (qemuBuildInterfaceCommandLine(driver, logManager, secManager, cmd, def, net,
+ if (qemuBuildInterfaceCommandLine(driver, vm, logManager, secManager, cmd, net,
qemuCaps, bootNet, vmop,
standalone, nnicindexes,
nicindexes) < 0)
@@ -10818,7 +10842,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
if (qemuBuildFSDevCommandLine(cmd, def, qemuCaps) < 0)
goto error;
- if (qemuBuildNetCommandLine(driver, logManager, secManager, cmd, def,
+ if (qemuBuildNetCommandLine(driver, vm, logManager, secManager, cmd,
qemuCaps, vmop, standalone,
nnicindexes, nicindexes, &bootHostdevNet) < 0)
goto error;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 9565a7a377..93696cb8d0 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -88,7 +88,8 @@ char *qemuBuildHostNetStr(virDomainNetDefPtr net,
char **tapfd,
size_t tapfdSize,
char **vhostfd,
- size_t vhostfdSize);
+ size_t vhostfdSize,
+ char *slirpfd);
/* Current, best practice */
char *qemuBuildNicDevStr(virDomainDefPtr def,
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index daea11dacb..e3cc0921a6 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -297,7 +297,8 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
}
if (VIR_STRDUP(cfg->bridgeHelperName, QEMU_BRIDGE_HELPER) < 0 ||
- VIR_STRDUP(cfg->prHelperName, QEMU_PR_HELPER) < 0)
+ VIR_STRDUP(cfg->prHelperName, QEMU_PR_HELPER) < 0 ||
+ VIR_STRDUP(cfg->slirpHelperName, SLIRP_HELPER) < 0)
goto error;
cfg->clearEmulatorCapabilities = true;
@@ -387,6 +388,7 @@ static void virQEMUDriverConfigDispose(void *obj)
VIR_FREE(cfg->hugetlbfs);
VIR_FREE(cfg->bridgeHelperName);
VIR_FREE(cfg->prHelperName);
+ VIR_FREE(cfg->slirpHelperName);
VIR_FREE(cfg->saveImageFormat);
VIR_FREE(cfg->dumpImageFormat);
@@ -681,6 +683,9 @@ virQEMUDriverConfigLoadProcessEntry(virQEMUDriverConfigPtr cfg,
if (virConfGetValueString(conf, "pr_helper", &cfg->prHelperName) < 0)
return -1;
+ if (virConfGetValueString(conf, "slirp_helper", &cfg->slirpHelperName) < 0)
+ return -1;
+
if (virConfGetValueBool(conf, "set_process_name", &cfg->setProcessName) < 0)
return -1;
if (virConfGetValueUInt(conf, "max_processes", &cfg->maxProcesses) < 0)
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 983e74a3cf..7ae09f8f8c 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -160,6 +160,7 @@ struct _virQEMUDriverConfig {
char *bridgeHelperName;
char *prHelperName;
+ char *slirpHelperName;
bool macFilter;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index f9f5ffc22b..626702c3ed 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2345,6 +2345,15 @@ qemuDomainObjPrivateXMLFormatPR(virBufferPtr buf,
}
+static void
+qemuDomainObjPrivateXMLFormatSlirp(virBufferPtr buf,
+ qemuDomainObjPrivatePtr priv)
+{
+ if (priv->slirpPid)
+ virBufferAddLit(buf, "<Slirp/>\n");
+}
+
+
static int
qemuDomainObjPrivateXMLFormatNBDMigrationSource(virBufferPtr buf,
virStorageSourcePtr src,
@@ -2555,6 +2564,8 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
qemuDomainObjPrivateXMLFormatPR(buf, priv);
+ qemuDomainObjPrivateXMLFormatSlirp(buf, priv);
+
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV))
virBufferAsprintf(buf, "<nodename index='%llu'/>\n", priv->nodenameindex);
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 06640a9510..f7937bf436 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -365,6 +365,9 @@ struct _qemuDomainObjPrivate {
/* true if qemu-pr-helper process is running for the domain */
bool prDaemonRunning;
+ /* todo: list of running slirp processes */
+ pid_t slirpPid;
+
/* counter for generating node names for qemu disks */
unsigned long long nodenameindex;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a4f7d111b1..f6ee9815ab 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1355,6 +1355,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_NET, { .net = net } };
virErrorPtr originalError = NULL;
+ char *slirpfdName = NULL;
char **tapfdName = NULL;
int *tapfd = NULL;
size_t tapfdSize = 0;
@@ -1592,7 +1593,8 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
if (!(netstr = qemuBuildHostNetStr(net, driver,
tapfdName, tapfdSize,
- vhostfdName, vhostfdSize)))
+ vhostfdName, vhostfdSize,
+ slirpfdName)))
goto cleanup;
qemuDomainObjEnterMonitor(driver, vm);
@@ -1720,6 +1722,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
VIR_FREE(vhostfdName);
VIR_FREE(charDevAlias);
virObjectUnref(conn);
+ VIR_FREE(slirpfdName);
virDomainCCWAddressSetFree(ccwaddrs);
return ret;
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index c8effa68f4..55423d6895 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -603,6 +603,86 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def,
}
+/**
+ * qemuInterfaceOpenSlirp:
+ * @net: network definition
+ * @slirpfd: slirp connection
+ *
+ * Returns: 0 on success
+ * -1 on failure
+ */
+int
+qemuInterfaceOpenSlirp(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainNetDefPtr net,
+ int *slirpfd)
+{
+ int i, pair[2] = { -1, -1 };
+ VIR_AUTOPTR(virCommand) cmd = NULL;
+ VIR_AUTOFREE(char *) cmdstr = NULL;
+ VIR_AUTOFREE(char *) addr = NULL;
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) {
+ virReportSystemError(errno, "%s", _("failed to create socket"));
+ goto error;
+ }
+
+ cmd = virCommandNew(cfg->slirpHelperName);
+ virCommandAddArgFormat(cmd, "--fd=%d", pair[1]);
+ virCommandPassFD(cmd, pair[1],
+ VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+
+ for (i = 0; i < net->guestIP.nips; i++) {
+ const virNetDevIPAddr *ip = net->guestIP.ips[i];
+ const char *opt = "";
+
+ if (!(addr = virSocketAddrFormat(&ip->address)))
+ goto error;
+
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET))
+ opt = "--net";
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6))
+ opt = "--prefix-ipv6";
+
+ virCommandAddArgFormat(cmd, "%s=%s", opt, addr);
+ VIR_FREE(addr);
+
+ if (ip->prefix) {
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET)) {
+ virSocketAddr netmask;
+ VIR_AUTOFREE(char *) netmaskStr = NULL;
+
+ if (virSocketAddrPrefixToNetmask(ip->prefix, &netmask, AF_INET) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to translate prefix %d to netmask"),
+ ip->prefix);
+ goto error;
+ }
+ if (!(netmaskStr = virSocketAddrFormat(&netmask)))
+ goto error;
+ virCommandAddArgFormat(cmd, "--mask=%s", netmaskStr);
+ }
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6))
+ virCommandAddArgFormat(cmd, "--prefix-length-ipv6=%u", ip->prefix);
+ }
+ }
+
+ virCommandClearCaps(cmd);
+ if (virCommandRunAsync(cmd, &priv->slirpPid) < 0) {
+ goto error;
+ }
+
+ *slirpfd = pair[0];
+ return 0;
+
+error:
+ VIR_FORCE_CLOSE(pair[0]);
+ return -1;
+}
+
+
/**
* qemuInterfaceOpenVhostNet:
* @def: domain definition
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index f3ec540eda..de6195462b 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -55,4 +55,10 @@ int qemuInterfaceOpenVhostNet(virDomainDefPtr def,
virDomainNetDefPtr net,
int *vhostfd,
size_t *vhostfdSize);
+
+int qemuInterfaceOpenSlirp(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainNetDefPtr net,
+ int *slirpfd);
+
#endif /* LIBVIRT_QEMU_INTERFACE_H */
diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in
index fea1d308b7..5796e5d1eb 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -102,5 +102,6 @@ module Test_libvirtd_qemu =
}
{ "memory_backing_dir" = "/var/lib/libvirt/qemu/ram" }
{ "pr_helper" = "/usr/bin/qemu-pr-helper" }
+{ "slirp_helper" = "/usr/bin/slirp-helper" }
{ "swtpm_user" = "tss" }
{ "swtpm_group" = "tss" }
--
2.21.0.313.ge35b8cb8e2
5 years, 11 months
[libvirt] [PATCH] qemuConnectOpen: Drop unused @cfg and simplify
by Michal Privoznik
After 65a372d6e0 the @cfg variable is no longer used. This means
we can drop it and therefore drop 'cleanup' label with it.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c072bed1ce..30945d1545 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1094,44 +1094,37 @@ static virDrvOpenStatus qemuConnectOpen(virConnectPtr conn,
virConfPtr conf ATTRIBUTE_UNUSED,
unsigned int flags)
{
- virQEMUDriverConfigPtr cfg = NULL;
- virDrvOpenStatus ret = VIR_DRV_OPEN_ERROR;
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
if (qemu_driver == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("qemu state driver is not active"));
- goto cleanup;
+ return VIR_DRV_OPEN_ERROR;
}
- cfg = virQEMUDriverGetConfig(qemu_driver);
-
if (virQEMUDriverIsPrivileged(qemu_driver)) {
if (STRNEQ(conn->uri->path, "/system") &&
STRNEQ(conn->uri->path, "/session")) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected QEMU URI path '%s', try qemu:///system"),
conn->uri->path);
- goto cleanup;
+ return VIR_DRV_OPEN_ERROR;
}
} else {
if (STRNEQ(conn->uri->path, "/session")) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected QEMU URI path '%s', try qemu:///session"),
conn->uri->path);
- goto cleanup;
+ return VIR_DRV_OPEN_ERROR;
}
}
if (virConnectOpenEnsureACL(conn) < 0)
- goto cleanup;
+ return VIR_DRV_OPEN_ERROR;
conn->privateData = qemu_driver;
- ret = VIR_DRV_OPEN_SUCCESS;
- cleanup:
- virObjectUnref(cfg);
- return ret;
+ return VIR_DRV_OPEN_SUCCESS;
}
static int qemuConnectClose(virConnectPtr conn)
--
2.21.0
5 years, 11 months
[libvirt] [PATCH v2 0/8] CPU Model Baseline and Comparison for s390x
by walling@linux.ibm.com
From: Collin Walling <walling(a)linux.ibm.com>
Changelog:
v1
- introduce baseline
- split patches into small chunks
- free'd lingering qemuMonitorCPUModelInfo pointer
- when converting from virCPUDef -> virJSON, consider
feature policy FORCED for enabled
This is the second iteration of the CPU Model Comparison and
Baseline patches for s390x. The previous version only showed
comparison as a preview, and it can be found here:
https://www.redhat.com/archives/libvir-list/2019-April/msg01046.html
The first patch pull some code out of the CPU Model Expansion
JSON function so that it can be later used for the Comparison
and Baseline JSON functions.
The rest of the patches follow this sequence:
- introduce JSON monitor functions
- introduce capability and update test files
- hook up monitor functions to virsh command
Thanks
@Daniel, I added your Tested-by where I felt made most sense.
Collin Walling (8):
qemu_monitor: helper functions for CPU models
qemu_monitor: implement query-cpu-model-baseline
qemu_capabilities: introduce QEMU_CAPS_QUERY_CPU_MODEL_BASELINE
qemu_driver: hook up query-cpu-model-baseline
qemu_monitor: implement query-cpu-model-comparison
qemu_capabilities: introduce QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON
cpu_conf: xml to cpu definition parse helper
qemu_driver: hook up query-cpu-model-comparison
src/conf/cpu_conf.c | 30 +++
src/conf/cpu_conf.h | 6 +
src/cpu/cpu.c | 14 +-
src/libvirt_private.syms | 1 +
src/qemu/qemu_capabilities.c | 156 +++++++++++++
src/qemu/qemu_capabilities.h | 20 ++
src/qemu/qemu_driver.c | 38 +++
src/qemu/qemu_monitor.c | 44 ++++
src/qemu/qemu_monitor.h | 18 ++
src/qemu/qemu_monitor_json.c | 285 ++++++++++++++++++++---
src/qemu/qemu_monitor_json.h | 20 ++
tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 2 +
tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml | 2 +
tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 2 +
tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 2 +
tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 2 +
tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml | 2 +
17 files changed, 595 insertions(+), 49 deletions(-)
--
2.7.4
5 years, 11 months
[libvirt] [PATCH 1/1] util/virhostdev: consolidate duplicated KVM support code
by Daniel Henrique Barboza
tests/virhostdevtest.c implements a function called
'virHostdevHostSupportsPassthroughKVM', that is equal to
'qemuHostdevHostSupportsPassthroughLegacy' that is declared
inside qemu/qemu_hostdev.c.
This patch removes the duplicated code from both files and
and puts it inside util/virhostdev.c, under the name
virHostdev...KVM, which represents what the code does better
than using 'Legacy'.
Based-on-work-of: Shivaprasad G Bhat <sbhat(a)linux.vnet.ibm.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413(a)gmail.com>
---
src/libvirt_private.syms | 1 +
src/qemu/qemu_capabilities.c | 2 +-
src/qemu/qemu_driver.c | 6 +++---
src/qemu/qemu_hostdev.c | 34 +---------------------------------
src/qemu/qemu_hostdev.h | 1 -
src/util/virhostdev.c | 31 +++++++++++++++++++++++++++++++
src/util/virhostdev.h | 1 +
tests/virhostdevtest.c | 31 -------------------------------
8 files changed, 38 insertions(+), 69 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a03cf0b645..a6747684ea 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2044,6 +2044,7 @@ virHostCPUStatsAssign;
# util/virhostdev.h
virHostdevFindUSBDevice;
+virHostdevHostSupportsPassthroughKVM;
virHostdevIsMdevDevice;
virHostdevIsSCSIDevice;
virHostdevManagerGetDefault;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a0b2ca73fb..515db0112f 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -5152,7 +5152,7 @@ static int
virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
virDomainCapsDeviceHostdevPtr hostdev)
{
- bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();
+ bool supportsPassthroughKVM = virHostdevHostSupportsPassthroughKVM();
bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();
hostdev->supported = VIR_TRISTATE_BOOL_YES;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b2ac737d1f..c02482337a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13283,7 +13283,7 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
int ret = -1;
virNodeDeviceDefPtr def = NULL;
char *xml = NULL;
- bool legacy = qemuHostdevHostSupportsPassthroughLegacy();
+ bool kvm = virHostdevHostSupportsPassthroughKVM();
bool vfio = qemuHostdevHostSupportsPassthroughVFIO();
virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
@@ -13310,7 +13310,7 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
if (!driverName) {
if (vfio) {
driverName = "vfio";
- } else if (legacy) {
+ } else if (kvm) {
driverName = "kvm";
} else {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
@@ -13329,7 +13329,7 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
}
virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_VFIO);
} else if (STREQ(driverName, "kvm")) {
- if (!legacy) {
+ if (!kvm) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("KVM device assignment is currently not "
"supported on this system"));
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 4eb3f1d7f1..b6cb4d0980 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -132,44 +132,12 @@ qemuHostdevHostSupportsPassthroughVFIO(void)
}
-#if HAVE_LINUX_KVM_H
-# include <linux/kvm.h>
-bool
-qemuHostdevHostSupportsPassthroughLegacy(void)
-{
- int kvmfd = -1;
- bool ret = false;
-
- if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0)
- goto cleanup;
-
-# ifdef KVM_CAP_IOMMU
- if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0)
- goto cleanup;
-
- ret = true;
-# endif
-
- cleanup:
- VIR_FORCE_CLOSE(kvmfd);
-
- return ret;
-}
-#else
-bool
-qemuHostdevHostSupportsPassthroughLegacy(void)
-{
- return false;
-}
-#endif
-
-
static bool
qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDefPtr *hostdevs,
size_t nhostdevs,
virQEMUCapsPtr qemuCaps)
{
- bool supportsPassthroughKVM = qemuHostdevHostSupportsPassthroughLegacy();
+ bool supportsPassthroughKVM = virHostdevHostSupportsPassthroughKVM();
bool supportsPassthroughVFIO = qemuHostdevHostSupportsPassthroughVFIO();
size_t i;
diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h
index 41f254ab81..be6faa2c35 100644
--- a/src/qemu/qemu_hostdev.h
+++ b/src/qemu/qemu_hostdev.h
@@ -25,7 +25,6 @@
# include "qemu_conf.h"
# include "domain_conf.h"
-bool qemuHostdevHostSupportsPassthroughLegacy(void);
bool qemuHostdevHostSupportsPassthroughVFIO(void);
int qemuHostdevUpdateActiveMediatedDevices(virQEMUDriverPtr driver,
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 19ae001971..872528fdb2 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -2245,3 +2245,34 @@ virHostdevUpdateActiveDomainDevices(virHostdevManagerPtr mgr,
return 0;
}
+
+#if HAVE_LINUX_KVM_H
+# include <linux/kvm.h>
+bool
+virHostdevHostSupportsPassthroughKVM(void)
+{
+ int kvmfd = -1;
+ bool ret = false;
+
+ if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0)
+ goto cleanup;
+
+# ifdef KVM_CAP_IOMMU
+ if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0)
+ goto cleanup;
+
+ ret = true;
+# endif
+
+ cleanup:
+ VIR_FORCE_CLOSE(kvmfd);
+
+ return ret;
+}
+#else
+bool
+virHostdevHostSupportsPassthroughKVM(void)
+{
+ return false;
+}
+#endif
diff --git a/src/util/virhostdev.h b/src/util/virhostdev.h
index 7263f320a2..32fa36cdef 100644
--- a/src/util/virhostdev.h
+++ b/src/util/virhostdev.h
@@ -203,4 +203,5 @@ int virHostdevPCINodeDeviceReset(virHostdevManagerPtr mgr,
virPCIDevicePtr pci)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+bool virHostdevHostSupportsPassthroughKVM(void);
#endif /* LIBVIRT_VIRHOSTDEV_H */
diff --git a/tests/virhostdevtest.c b/tests/virhostdevtest.c
index 4e067b10d1..1258338949 100644
--- a/tests/virhostdevtest.c
+++ b/tests/virhostdevtest.c
@@ -126,37 +126,6 @@ myInit(void)
return -1;
}
-# if HAVE_LINUX_KVM_H
-# include <linux/kvm.h>
-static bool
-virHostdevHostSupportsPassthroughKVM(void)
-{
- int kvmfd = -1;
- bool ret = false;
-
- if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0)
- goto cleanup;
-
-# ifdef KVM_CAP_IOMMU
- if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0)
- goto cleanup;
-
- ret = true;
-# endif
-
- cleanup:
- VIR_FORCE_CLOSE(kvmfd);
-
- return ret;
-}
-# else
-static bool
-virHostdevHostSupportsPassthroughKVM(void)
-{
- return false;
-}
-# endif
-
static int
testVirHostdevPreparePCIHostdevs_unmanaged(void)
{
--
2.20.1
5 years, 11 months
[libvirt] [PATCH] docs: Update drivers page to link to storage.html
by John Ferlan
Rather than duplicate a list of storage pool backends on the
drivers.html page, let's just link directly to the storage driver
page similar to how the node device driver is done.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
docs/drivers.html.in | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
diff --git a/docs/drivers.html.in b/docs/drivers.html.in
index a66651df2f..4539eedbcd 100644
--- a/docs/drivers.html.in
+++ b/docs/drivers.html.in
@@ -6,7 +6,7 @@
<ul>
<li><a href="#hypervisor">Hypervisor drivers</a></li>
- <li><a href="#storage">Storage drivers</a></li>
+ <li><a href="storage.html">Storage drivers</a></li>
<li><a href="drvnodedev.html">Node device driver</a></li>
</ul>
@@ -39,19 +39,5 @@
<li><strong><a href="drvbhyve.html">Bhyve</a></strong> - The BSD Hypervisor</li>
</ul>
- <h2><a id="storage">Storage drivers</a></h2>
-
- <ul>
- <li><strong><a href="storage.html#StorageBackendDir">Directory backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendFS">Local filesystem backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendNetFS">Network filesystem backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendLogical">Logical Volume Manager (LVM) backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendDisk">Disk backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendISCSI">iSCSI backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendSCSI">SCSI backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendMultipath">Multipath backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendRBD">RBD (RADOS Block Device) backend</a></strong></li>
- <li><strong><a href="storage.html#StorageBackendSheepdog">Sheepdog backend</a></strong></li>
- </ul>
</body>
</html>
--
2.20.1
5 years, 11 months
[libvirt] [PATCH 0/2] conf: DEF_FEATURE tweaks
by Cole Robinson
After the net model enum patches, the test driver started rejecting
non-enum model strings. It should continue to accept unknown models
and generally act closer to the qemu driver. So let's add all of
qemu's DEF_FEATURE bits to match while we are at it (virt-manager will
want this for os firmware XML testing at least)
Fix an issue in the area while I'm here
Cole Robinson (2):
test: match qemu VIR_DOMAIN_DEF_FEATURE* usage
conf: Fix VIR_DOMAIN_DEF_FEATURE_FW_AUTOSELECT validation
src/conf/domain_conf.c | 6 ++----
src/test/test_driver.c | 10 +++++++++-
src/vmx/vmx.c | 3 ++-
3 files changed, 13 insertions(+), 6 deletions(-)
--
2.21.0
5 years, 11 months
[libvirt] [PATCH] spec: fix f28 rpm without firewalld zone
by Cole Robinson
Commit 3b71f2e42d added spec handling for with_firewalld_zone. We
now call %firewalld_reload if with_firewalld is set. But the matching
'BuildRequires: firewalld-filesystem' is only applied if
with_firewalld_zone is set.
Fix the former bit to use with_firewalld_zone
Reported-by: Yuval Turgeman <yturgema(a)redhat.com>
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
libvirt.spec.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 18f0a0e217..876b2f0897 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1387,12 +1387,12 @@ fi
rm -rf %{_localstatedir}/lib/rpm-state/libvirt || :
%post daemon-driver-network
-%if %{with_firewalld}
+%if %{with_firewalld_zone}
%firewalld_reload
%endif
%postun daemon-driver-network
-%if %{with_firewalld}
+%if %{with_firewalld_zone}
%firewalld_reload
%endif
--
2.21.0
5 years, 11 months
[libvirt] [PATCH] lib: Preserve error around virDomainNetReleaseActualDevice()
by Michal Privoznik
This function is calling public API virNetworkLookupByName()
which resets the error. Therefore, if
virDomainNetReleaseActualDevice() is used in cleanup path it
actually resets the original error that got us jump into
'cleanup' label.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
I've found this issue when trying to change QoS on an domain's
<interface/> and I've intentionally entered @floor bigger than
corresponding network's average. Orders bigger.
I mean, with this change the QoS is still kind of broken [1] but at
least I'm getting some sensible error instead of "An error occurred, but
the cause is unknown".
1: Thing is, when an <interface type='network'/> is being updated (virsh
update-device) then a new interface is actually created
(virDomainNetAllocateActualDevice() is called), which is then set up and
the old interface is then released. This works in theory, but for a
fraction of a second we have two interfaces. Therefore the sum of their
@floor-s might exceed the limit (which is MAX(network average, network
peak)) and thus allocating new device will fail. Unfortunately, I don't
have any bright idea around this. Maybe temporary setting
newdev->bandwidth = NULL; then allocating new device and trying to set
new bandwidth ourselves? That is still going to fail until the old
interface is not released. Ideas are welcome.
src/libxl/libxl_driver.c | 6 ++++++
src/lxc/lxc_driver.c | 3 +++
src/lxc/lxc_process.c | 3 +++
src/qemu/qemu_hotplug.c | 6 ++++++
4 files changed, 18 insertions(+)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index e7234c1479..2b9c6f1866 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3380,6 +3380,7 @@ libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
int ret = -1;
char mac[VIR_MAC_STRING_BUFLEN];
virConnectPtr conn = NULL;
+ virErrorPtr save_err = NULL;
libxl_device_nic_init(&nic);
@@ -3440,6 +3441,7 @@ libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
ret = 0;
cleanup:
+ virErrorPreserveLast(&save_err);
libxl_device_nic_dispose(&nic);
if (!ret) {
vm->def->nets[vm->def->nnets++] = net;
@@ -3450,6 +3452,7 @@ libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
}
virObjectUnref(conn);
virObjectUnref(cfg);
+ virErrorRestore(&save_err);
return ret;
}
@@ -3838,6 +3841,7 @@ libxlDomainDetachNetDevice(libxlDriverPrivatePtr driver,
libxl_device_nic nic;
char mac[VIR_MAC_STRING_BUFLEN];
int ret = -1;
+ virErrorPtr save_err = NULL;
libxl_device_nic_init(&nic);
@@ -3868,6 +3872,7 @@ libxlDomainDetachNetDevice(libxlDriverPrivatePtr driver,
ret = 0;
cleanup:
+ virErrorPreserveLast(&save_err);
libxl_device_nic_dispose(&nic);
if (!ret) {
if (detach->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
@@ -3882,6 +3887,7 @@ libxlDomainDetachNetDevice(libxlDriverPrivatePtr driver,
virDomainNetRemove(vm->def, detachidx);
}
virObjectUnref(cfg);
+ virErrorRestore(&save_err);
return ret;
}
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 1980d0804e..9db2a02dee 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -4337,6 +4337,7 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
virDomainNetType actualType;
virDomainNetDefPtr detach = NULL;
virNetDevVPortProfilePtr vport = NULL;
+ virErrorPtr save_err = NULL;
if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
goto cleanup;
@@ -4396,6 +4397,7 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
ret = 0;
cleanup:
if (!ret) {
+ virErrorPreserveLast(&save_err);
if (detach->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
virConnectPtr conn = virGetConnectNetwork();
if (conn) {
@@ -4407,6 +4409,7 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
}
virDomainNetRemove(vm->def, detachidx);
virDomainNetDefFree(detach);
+ virErrorRestore(&save_err);
}
return ret;
}
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 3a33418aca..de4d7c73fb 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -550,6 +550,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
virDomainNetDefPtr net;
virDomainNetType type;
virConnectPtr netconn = NULL;
+ virErrorPtr save_err = NULL;
if (VIR_ALLOC_N(*veths, def->nnets + 1) < 0)
return -1;
@@ -642,6 +643,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
cleanup:
if (ret < 0) {
+ virErrorPreserveLast(&save_err);
for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr iface = def->nets[i];
virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(iface);
@@ -652,6 +654,7 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK && netconn)
virDomainNetReleaseActualDevice(netconn, def, iface);
}
+ virErrorRestore(&save_err);
}
virObjectUnref(netconn);
return ret;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e199368e8a..f3c5f44a23 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1383,6 +1383,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
bool netdevPlugged = false;
char *netdev_name;
virConnectPtr conn = NULL;
+ virErrorPtr save_err = NULL;
/* preallocate new slot for device */
if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
@@ -1678,6 +1679,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
if (!ret) {
vm->def->nets[vm->def->nnets++] = net;
} else {
+ virErrorPreserveLast(&save_err);
if (releaseaddr)
qemuDomainReleaseDeviceAddress(vm, &net->info);
@@ -1706,6 +1708,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
else
VIR_WARN("Unable to release network device '%s'", NULLSTR(net->ifname));
}
+ virErrorRestore(&save_err);
}
VIR_FREE(nicstr);
@@ -3756,6 +3759,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
int ret = -1;
int changeidx = -1;
virConnectPtr conn = NULL;
+ virErrorPtr save_err = NULL;
if ((changeidx = virDomainNetFindIdx(vm->def, newdev)) < 0)
goto cleanup;
@@ -4173,6 +4177,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
ret = 0;
cleanup:
+ virErrorPreserveLast(&save_err);
/* When we get here, we will be in one of these two states:
*
* 1) newdev has been moved into the domain's list of nets and
@@ -4194,6 +4199,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
if (newdev && newdev->type == VIR_DOMAIN_NET_TYPE_NETWORK && conn)
virDomainNetReleaseActualDevice(conn, vm->def, newdev);
virObjectUnref(conn);
+ virErrorRestore(&save_err);
return ret;
}
--
2.21.0
5 years, 11 months
[libvirt] [PATCH for 5.3.0] news: Update for 5.3.0 release
by Michal Privoznik
Some basic features/bugfixes/removed features. Of course we've
done a lot more than recoded here.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
docs/news.xml | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/docs/news.xml b/docs/news.xml
index e0cab23c49..745bf64a5d 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -48,6 +48,18 @@
</description>
</change>
</section>
+ <section title="Removed features">
+ <change>
+ <summary>
+ Drop support for VirtualBox 4.x releases
+ </summary>
+ <description>
+ Support for all the 4.x releases was ended by
+ VirtualBox maintainers in December 2015. Therefore,
+ libvirt support for these releases is dropped.
+ </description>
+ </change>
+ </section>
<section title="Improvements">
<change>
<summary>
@@ -73,6 +85,27 @@
Firmware Secure Boot support is also advertised.
</description>
</change>
+ <change>
+ <summary>
+ Drop yajl-1 support in favour of yajl-2
+ </summary>
+ <description>
+ Yajl-2 is widely adapted and maintaining side by side
+ support for two versions is needless.
+ </description>
+ </change>
+ <change>
+ <summary>
+ tests: add targets for building libvirt inside Docker containers
+ </summary>
+ <description>
+ Strictly speaking this does not concern users, but it
+ is still worth mentioning. New build targets are
+ introduced to build and test libvirt under various
+ docker images, for instance make
+ <code>ci-build@fedora-28</code>
+ </description>
+ </change>
</section>
<section title="Bug fixes">
<change>
@@ -85,6 +118,35 @@
leaks may also occur.
</description>
</change>
+ <change>
+ <summary>
+ virsh: various completers fixes
+ </summary>
+ <description>
+ There were some possible crashers, memory leaks, etc.
+ which are now fixed.
+ </description>
+ </change>
+ <change>
+ <summary>
+ qemu: Make hugepages work with memfd backend
+ </summary>
+ <description>
+ Due to a bug in command line generation libvirt did not
+ honoured hugepages setting with memfd backend.
+ </description>
+ </change>
+ <change>
+ <summary>
+ Enforce ACL write permission for getting guest time & hostname
+ </summary>
+ <description>
+ Getting the guest time and hostname both require use of
+ guest agent commands. These must not be allowed for
+ read-only users, so the permissions check must validate
+ "write" permission not "read".
+ </description>
+ </change>
</section>
</release>
<release version="v5.2.0" date="2019-04-03">
--
2.21.0
5 years, 11 months