[libvirt] [PATCH v2] security_selinux: Fix crash in virSecuritySELinuxRestoreFileLabel
by Shanzhi Yu
virSecuritySELinuxRestoreFileLabel should never be called with NULL path
add check before call this function in case of causeing libvirtd crash
https://bugzilla.redhat.com/show_bug.cgi?id=1300532
Signed-off-by: Shanzhi Yu <shyu(a)redhat.com>
---
src/security/security_selinux.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 9e98635..77e55a3 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1098,7 +1098,8 @@ virSecuritySELinuxRestoreInputLabel(virSecurityManagerPtr mgr,
switch ((virDomainInputType) input->type) {
case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
- rc = virSecuritySELinuxRestoreFileLabel(mgr, input->source.evdev);
+ if (input->source.evdev)
+ rc = virSecuritySELinuxRestoreFileLabel(mgr, input->source.evdev);
break;
case VIR_DOMAIN_INPUT_TYPE_MOUSE:
@@ -1171,7 +1172,9 @@ virSecuritySELinuxRestoreTPMFileLabelInt(virSecurityManagerPtr mgr,
switch (tpm->type) {
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
tpmdev = tpm->data.passthrough.source.data.file.path;
- rc = virSecuritySELinuxRestoreFileLabel(mgr, tpmdev);
+
+ if (tpmdev)
+ rc = virSecuritySELinuxRestoreFileLabel(mgr, tpmdev);
if ((cancel_path = virTPMCreateCancelPath(tpmdev)) != NULL) {
if (virSecuritySELinuxRestoreFileLabel(mgr, cancel_path) < 0)
@@ -1722,7 +1725,9 @@ virSecuritySELinuxRestoreHostdevCapsLabel(virSecurityManagerPtr mgr,
if (VIR_STRDUP(path, dev->source.caps.u.storage.block) < 0)
return -1;
}
- ret = virSecuritySELinuxRestoreFileLabel(mgr, path);
+ if (path)
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, path);
+
VIR_FREE(path);
break;
}
@@ -1736,7 +1741,8 @@ virSecuritySELinuxRestoreHostdevCapsLabel(virSecurityManagerPtr mgr,
if (VIR_STRDUP(path, dev->source.caps.u.misc.chardev) < 0)
return -1;
}
- ret = virSecuritySELinuxRestoreFileLabel(mgr, path);
+ if (path)
+ ret = virSecuritySELinuxRestoreFileLabel(mgr, path);
VIR_FREE(path);
break;
}
@@ -1876,13 +1882,15 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
switch (dev_source->type) {
case VIR_DOMAIN_CHR_TYPE_DEV:
case VIR_DOMAIN_CHR_TYPE_FILE:
- if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.file.path) < 0)
- goto done;
+ if (dev_source->data.file.path) {
+ if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.file.path) < 0)
+ goto done;
+ }
ret = 0;
break;
case VIR_DOMAIN_CHR_TYPE_UNIX:
- if (!dev_source->data.nix.listen) {
+ if (!dev_source->data.nix.listen && dev_source->data.file.path) {
if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.file.path) < 0)
goto done;
}
@@ -1898,7 +1906,8 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
(virSecuritySELinuxRestoreFileLabel(mgr, in) < 0)) {
goto done;
}
- } else if (virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.file.path) < 0) {
+ } else if (dev_source->data.file.path &&
+ virSecuritySELinuxRestoreFileLabel(mgr, dev_source->data.file.path) < 0) {
goto done;
}
ret = 0;
--
1.8.3.1
8 years, 9 months
[libvirt] [PATCH] qemuDomainResume: allow to resume domain with guest panicked
by Dmitry Andreev
In case of guest panicked, preserved crashed domain has stopped CPUs.
It's not possible to use tools like WinDbg for the problem investigation
until we start CPUs back.
---
src/qemu/qemu_driver.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e46404b..0930280 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1873,6 +1873,7 @@ static int qemuDomainResume(virDomainPtr dom)
int ret = -1;
virObjectEventPtr event = NULL;
int state;
+ int reason;
virQEMUDriverConfigPtr cfg = NULL;
if (!(vm = qemuDomObjFromDomain(dom)))
@@ -1892,12 +1893,14 @@ static int qemuDomainResume(virDomainPtr dom)
goto endjob;
}
- state = virDomainObjGetState(vm, NULL);
+ state = virDomainObjGetState(vm, &reason);
if (state == VIR_DOMAIN_PMSUSPENDED) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is pmsuspended"));
goto endjob;
- } else if (state == VIR_DOMAIN_PAUSED) {
+ } else if ((state == VIR_DOMAIN_CRASHED &&
+ reason == VIR_DOMAIN_CRASHED_PANICKED) ||
+ state == VIR_DOMAIN_PAUSED) {
if (qemuProcessStartCPUs(driver, vm, dom->conn,
VIR_DOMAIN_RUNNING_UNPAUSED,
QEMU_ASYNC_JOB_NONE) < 0) {
--
1.8.3.1
8 years, 9 months
[libvirt] [PATCH v3] qemu: return -1 on error paths in qemuDomainSaveImageStartVM
by Nikolay Shirokovskiy
Error paths after sending the event that domain is started written as if ret = -1
which is set at the beginning of the function. It's common idioma to keep 'ret'
equal to -1 until the end of function where it is set to 0. But here we use ret
to keep result of restore operation too and thus breaks the idioma and its users :)
Let's use different variable to hold restore result.
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
---
src/qemu/qemu_driver.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index abcdbe6..f612cf0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6732,6 +6732,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
qemuDomainAsyncJob asyncJob)
{
int ret = -1;
+ bool restored = false;
virObjectEventPtr event;
int intermediatefd = -1;
virCommandPtr cmd = NULL;
@@ -6758,13 +6759,14 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
}
/* Set the migration source and start it up. */
- ret = qemuProcessStart(conn, driver, vm, asyncJob,
- "stdio", *fd, path, NULL,
- VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
- VIR_QEMU_PROCESS_START_PAUSED);
+ if (qemuProcessStart(conn, driver, vm, asyncJob,
+ "stdio", *fd, path, NULL,
+ VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
+ VIR_QEMU_PROCESS_START_PAUSED) == 0)
+ restored = true;
if (intermediatefd != -1) {
- if (ret < 0) {
+ if (!restored) {
/* if there was an error setting up qemu, the intermediate
* process will wait forever to write to stdout, so we
* must manually kill it.
@@ -6775,7 +6777,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
if (virCommandWait(cmd, NULL) < 0) {
qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, 0);
- ret = -1;
+ restored = false;
}
VIR_DEBUG("Decompression binary stderr: %s", NULLSTR(errbuf));
}
@@ -6783,18 +6785,16 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
if (VIR_CLOSE(*fd) < 0) {
virReportSystemError(errno, _("cannot close file: %s"), path);
- ret = -1;
+ restored = false;
}
- if (ret < 0) {
- virDomainAuditStart(vm, "restored", false);
+ virDomainAuditStart(vm, "restored", restored);
+ if (!restored)
goto cleanup;
- }
event = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_RESTORED);
- virDomainAuditStart(vm, "restored", true);
qemuDomainEventQueue(driver, event);
--
1.8.3.1
8 years, 9 months
[libvirt] [PATCH 1/2] Move qemuGetDHCPInterfaces to separate file
by Guido Günther
so we can use it from the LXC driver as well.
---
I couldn't find a nice place to add this so I went for a separate file. I'm
happy to move this elsewhere.
Cheers,
-- Guido
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/libvirt_private.syms | 4 ++
src/qemu/qemu_driver.c | 104 +----------------------------------
src/util/virdhcpinterfaces.c | 127 +++++++++++++++++++++++++++++++++++++++++++
src/util/virdhcpinterfaces.h | 34 ++++++++++++
6 files changed, 169 insertions(+), 102 deletions(-)
create mode 100644 src/util/virdhcpinterfaces.c
create mode 100644 src/util/virdhcpinterfaces.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 82e8d3e..64eaa9d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -186,6 +186,7 @@ src/util/vircommand.c
src/util/virconf.c
src/util/vircrypto.c
src/util/virdbus.c
+src/util/virdhcpinterfaces.c
src/util/virdnsmasq.c
src/util/virerror.c
src/util/virerror.h
diff --git a/src/Makefile.am b/src/Makefile.am
index a4aef0f..bddfd21 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -104,6 +104,7 @@ UTIL_SOURCES = \
util/virconf.c util/virconf.h \
util/vircrypto.c util/vircrypto.h \
util/virdbus.c util/virdbus.h util/virdbuspriv.h \
+ util/virdhcpinterfaces.c util/virdhcpinterfaces.h \
util/virdnsmasq.c util/virdnsmasq.h \
util/virebtables.c util/virebtables.h \
util/virendian.h \
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3d0ec9d..ea3e83c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1377,6 +1377,10 @@ virDBusMessageRead;
virDBusSetSharedBus;
+# util/virdhcpinterfaces.h
+virGetDHCPInterfaces;
+
+
# util/virdnsmasq.h
dnsmasqAddDhcpHost;
dnsmasqAddHost;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index abcdbe6..fe1cb6d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -101,6 +101,7 @@
#include "virnuma.h"
#include "dirname.h"
#include "network/bridge_driver.h"
+#include "virdhcpinterfaces.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -173,10 +174,6 @@ static int qemuOpenFileAs(uid_t fallback_uid, gid_t fallback_gid,
const char *path, int oflags,
bool *needUnlink, bool *bypassSecurityDriver);
-static int qemuGetDHCPInterfaces(virDomainPtr dom,
- virDomainObjPtr vm,
- virDomainInterfacePtr **ifaces);
-
virQEMUDriverPtr qemu_driver = NULL;
@@ -19794,7 +19791,7 @@ qemuDomainInterfaceAddresses(virDomainPtr dom,
switch (source) {
case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE:
- ret = qemuGetDHCPInterfaces(dom, vm, ifaces);
+ ret = virGetDHCPInterfaces(dom, vm, ifaces);
break;
case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT:
@@ -19825,103 +19822,6 @@ qemuDomainInterfaceAddresses(virDomainPtr dom,
return ret;
}
-static int
-qemuGetDHCPInterfaces(virDomainPtr dom,
- virDomainObjPtr vm,
- virDomainInterfacePtr **ifaces)
-{
- int rv = -1;
- int n_leases = 0;
- size_t i, j;
- size_t ifaces_count = 0;
- virNetworkPtr network = NULL;
- char macaddr[VIR_MAC_STRING_BUFLEN];
- virDomainInterfacePtr iface = NULL;
- virNetworkDHCPLeasePtr *leases = NULL;
- virDomainInterfacePtr *ifaces_ret = NULL;
-
- if (!dom->conn->networkDriver ||
- !dom->conn->networkDriver->networkGetDHCPLeases) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Network driver does not support DHCP lease query"));
- return -1;
- }
-
- for (i = 0; i < vm->def->nnets; i++) {
- if (vm->def->nets[i]->type != VIR_DOMAIN_NET_TYPE_NETWORK)
- continue;
-
- virMacAddrFormat(&(vm->def->nets[i]->mac), macaddr);
- virObjectUnref(network);
- network = virNetworkLookupByName(dom->conn,
- vm->def->nets[i]->data.network.name);
-
- if ((n_leases = virNetworkGetDHCPLeases(network, macaddr,
- &leases, 0)) < 0)
- goto error;
-
- if (n_leases) {
- if (VIR_EXPAND_N(ifaces_ret, ifaces_count, 1) < 0)
- goto error;
-
- if (VIR_ALLOC(ifaces_ret[ifaces_count - 1]) < 0)
- goto error;
-
- iface = ifaces_ret[ifaces_count - 1];
- /* Assuming each lease corresponds to a separate IP */
- iface->naddrs = n_leases;
-
- if (VIR_ALLOC_N(iface->addrs, iface->naddrs) < 0)
- goto error;
-
- if (VIR_STRDUP(iface->name, vm->def->nets[i]->ifname) < 0)
- goto cleanup;
-
- if (VIR_STRDUP(iface->hwaddr, macaddr) < 0)
- goto cleanup;
- }
-
- for (j = 0; j < n_leases; j++) {
- virNetworkDHCPLeasePtr lease = leases[j];
- virDomainIPAddressPtr ip_addr = &iface->addrs[j];
-
- if (VIR_STRDUP(ip_addr->addr, lease->ipaddr) < 0)
- goto cleanup;
-
- ip_addr->type = lease->type;
- ip_addr->prefix = lease->prefix;
- }
-
- for (j = 0; j < n_leases; j++)
- virNetworkDHCPLeaseFree(leases[j]);
-
- VIR_FREE(leases);
- }
-
- *ifaces = ifaces_ret;
- ifaces_ret = NULL;
- rv = ifaces_count;
-
- cleanup:
- virObjectUnref(network);
- if (leases) {
- for (i = 0; i < n_leases; i++)
- virNetworkDHCPLeaseFree(leases[i]);
- }
- VIR_FREE(leases);
-
- return rv;
-
- error:
- if (ifaces_ret) {
- for (i = 0; i < ifaces_count; i++)
- virDomainInterfaceFree(ifaces_ret[i]);
- }
- VIR_FREE(ifaces_ret);
-
- goto cleanup;
-}
-
static int
qemuDomainSetUserPassword(virDomainPtr dom,
diff --git a/src/util/virdhcpinterfaces.c b/src/util/virdhcpinterfaces.c
new file mode 100644
index 0000000..80135f7
--- /dev/null
+++ b/src/util/virdhcpinterfaces.c
@@ -0,0 +1,127 @@
+/*
+ * virdhcpinterfaces.c: get a domains dhcp managed interfaces
+ *
+ * Copyright (C) 2016 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: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "virdhcpinterfaces.h"
+#include "viralloc.h"
+#include "virstring.h"
+#include "datatypes.h"
+
+#define VIR_FROM_THIS VIR_FROM_AUDIT
+
+int
+virGetDHCPInterfaces(virDomainPtr dom,
+ virDomainObjPtr vm,
+ virDomainInterfacePtr **ifaces)
+{
+ int rv = -1;
+ int n_leases = 0;
+ size_t i, j;
+ size_t ifaces_count = 0;
+ virNetworkPtr network = NULL;
+ char macaddr[VIR_MAC_STRING_BUFLEN];
+ virDomainInterfacePtr iface = NULL;
+ virNetworkDHCPLeasePtr *leases = NULL;
+ virDomainInterfacePtr *ifaces_ret = NULL;
+
+ if (!dom->conn->networkDriver ||
+ !dom->conn->networkDriver->networkGetDHCPLeases) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Network driver does not support DHCP lease query"));
+ return -1;
+ }
+
+ for (i = 0; i < vm->def->nnets; i++) {
+ if (vm->def->nets[i]->type != VIR_DOMAIN_NET_TYPE_NETWORK)
+ continue;
+
+ virMacAddrFormat(&(vm->def->nets[i]->mac), macaddr);
+ virObjectUnref(network);
+ network = virNetworkLookupByName(dom->conn,
+ vm->def->nets[i]->data.network.name);
+
+ if ((n_leases = virNetworkGetDHCPLeases(network, macaddr,
+ &leases, 0)) < 0)
+ goto error;
+
+ if (n_leases) {
+ if (VIR_EXPAND_N(ifaces_ret, ifaces_count, 1) < 0)
+ goto error;
+
+ if (VIR_ALLOC(ifaces_ret[ifaces_count - 1]) < 0)
+ goto error;
+
+ iface = ifaces_ret[ifaces_count - 1];
+ /* Assuming each lease corresponds to a separate IP */
+ iface->naddrs = n_leases;
+
+ if (VIR_ALLOC_N(iface->addrs, iface->naddrs) < 0)
+ goto error;
+
+ if (VIR_STRDUP(iface->name, vm->def->nets[i]->ifname) < 0)
+ goto cleanup;
+
+ if (VIR_STRDUP(iface->hwaddr, macaddr) < 0)
+ goto cleanup;
+ }
+
+ for (j = 0; j < n_leases; j++) {
+ virNetworkDHCPLeasePtr lease = leases[j];
+ virDomainIPAddressPtr ip_addr = &iface->addrs[j];
+
+ if (VIR_STRDUP(ip_addr->addr, lease->ipaddr) < 0)
+ goto cleanup;
+
+ ip_addr->type = lease->type;
+ ip_addr->prefix = lease->prefix;
+ }
+
+ for (j = 0; j < n_leases; j++)
+ virNetworkDHCPLeaseFree(leases[j]);
+
+ VIR_FREE(leases);
+ }
+
+ *ifaces = ifaces_ret;
+ ifaces_ret = NULL;
+ rv = ifaces_count;
+
+ cleanup:
+ virObjectUnref(network);
+ if (leases) {
+ for (i = 0; i < n_leases; i++)
+ virNetworkDHCPLeaseFree(leases[i]);
+ }
+ VIR_FREE(leases);
+
+ return rv;
+
+ error:
+ if (ifaces_ret) {
+ for (i = 0; i < ifaces_count; i++)
+ virDomainInterfaceFree(ifaces_ret[i]);
+ }
+ VIR_FREE(ifaces_ret);
+
+ goto cleanup;
+}
diff --git a/src/util/virdhcpinterfaces.h b/src/util/virdhcpinterfaces.h
new file mode 100644
index 0000000..c7acb8f
--- /dev/null
+++ b/src/util/virdhcpinterfaces.h
@@ -0,0 +1,34 @@
+/*
+ * virdhcpinterfaces.h: get a domains dhcp managed interfaces
+ *
+ * Copyright (C) 2016 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: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __VIR_DHCP_INTERFACES_H__
+# define __VIR_DHCP_INTERFACES_H__
+
+# include "internal.h"
+# include "virdomainobjlist.h"
+
+int
+virGetDHCPInterfaces(virDomainPtr dom,
+ virDomainObjPtr vm,
+ virDomainInterfacePtr **ifaces);
+
+#endif /* __VIR_DHCP_INTERFACES_H__ */
--
2.7.0.rc3
8 years, 9 months
[libvirt] [PATCH v2 00/21] vcpu info storage refactors - part 2
by Peter Krempa
Some of patches were pushed. The rest fixes most of the feedback that made
sense that was against v1.
Peter Krempa (21):
cgroup: Clean up virCgroupGetPercpuStats
conf: Add helper to retrieve bitmap of active vcpus for a definition
cgroup: Prepare for sparse vCPU topologies in virCgroupGetPercpuStats
qemu: cpu hotplug: Set vcpu state directly in the new structure
qemu: Move and rename qemuProcessDetectVcpuPIDs to
qemuDomainDetectVcpuPids
qemu: domain: Prepare qemuDomainDetectVcpuPids for reuse
qemu: Reuse qemuDomainDetectVcpuPids in cpu hot(un)plug
conf: Don't copy def->cpumask into cpu pinning info
conf: Split out logic to determine whether cpupin was provided
conf: Store cpu pinning data in def->vcpus
conf: remove unused cpu pinning helpers and data structures
conf: Extract code that formats <cputune>
util: bitmap: Introduce bitmap subtraction
conf: Add helper to return a bitmap of active iothread ids
conf: Extract code for parsing thread resource scheduler info
conf: Don't store vcpusched orthogonally to other vcpu info
conf: Fix how iothread scheduler info is stored
qemu: vcpu: Aggregate code to set vCPU tuning
qemu: vcpu: Reuse qemuProcessSetupVcpu in vcpu hotplug
qemu: iothread: Aggregate code to set IOTrhead tuning
qemu: iothread: Reuse qemuProcessSetupIOThread in iothread hotplug
src/conf/domain_conf.c | 940 +++++++++++----------
src/conf/domain_conf.h | 45 +-
src/libvirt_private.syms | 10 +-
src/libxl/libxl_domain.c | 20 +-
src/libxl/libxl_driver.c | 41 +-
src/lxc/lxc_driver.c | 2 +-
src/qemu/qemu_cgroup.c | 195 -----
src/qemu/qemu_cgroup.h | 2 -
src/qemu/qemu_domain.c | 84 ++
src/qemu/qemu_domain.h | 2 +
src/qemu/qemu_driver.c | 405 +++------
src/qemu/qemu_process.c | 478 ++++++-----
src/qemu/qemu_process.h | 6 +
src/test/test_driver.c | 45 +-
src/util/virbitmap.c | 21 +
src/util/virbitmap.h | 3 +
src/util/vircgroup.c | 74 +-
src/util/vircgroup.h | 3 +-
src/vz/vz_sdk.c | 4 +-
.../qemuxml2xmlout-cputune-iothreadsched.xml | 3 +-
tests/virbitmaptest.c | 55 ++
tests/vircgrouptest.c | 2 +-
22 files changed, 1148 insertions(+), 1292 deletions(-)
--
2.6.2
8 years, 9 months
[libvirt] [PATCH v4] qemu: Connect to guest agent iff needed
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1293351
Since we already have virtio channel events, we know when guest
agent within guest has (dis-)connected. Instead of us blindly
connecting to a socket that no one is listening to, we can just
follow what qemu-ga does. This has a nice benefit that we don't
need to 'guest-ping' the agent just to timeout and find out
nobody is listening.
The way that this commit is implemented:
- don't connect in qemuProcessStart directly, defer that to event
callback (which already follows the agent).
- after migration is settled, before we resume vCPUs, ask qemu
whether somebody is listening on the socket and if so, connect
to it.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
diff to v3:
-Move cap detection into qemuConnectAgent
src/qemu/qemu_driver.c | 13 ++++++++++++-
src/qemu/qemu_migration.c | 12 ++++++++++++
src/qemu/qemu_process.c | 24 ++++++++++++++++++++++++
3 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8ccf68b..3751ba6 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6650,12 +6650,13 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
bool start_paused,
qemuDomainAsyncJob asyncJob)
{
- int ret = -1;
+ int rc, ret = -1;
virObjectEventPtr event;
int intermediatefd = -1;
virCommandPtr cmd = NULL;
char *errbuf = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ qemuDomainObjPrivatePtr priv = vm->privateData;
if ((header->version == 2) &&
(header->compressed != QEMU_SAVE_FORMAT_RAW)) {
@@ -6710,6 +6711,16 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
goto cleanup;
}
+ if ((rc = qemuConnectAgent(driver, vm)) < 0) {
+ if (rc == -2)
+ goto cleanup;
+
+ VIR_WARN("Cannot connect to QEMU guest agent for %s",
+ vm->def->name);
+ virResetLastError();
+ priv->agentError = true;
+ }
+
event = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED,
VIR_DOMAIN_EVENT_STARTED_RESTORED);
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 51e7125..9678adf 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -5795,6 +5795,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
unsigned short port;
unsigned long long timeReceived = 0;
virObjectEventPtr event;
+ int rc;
VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, flags=%lx, retcode=%d",
@@ -5863,6 +5864,17 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
if (qemuMigrationStopNBDServer(driver, vm, mig) < 0)
goto endjob;
+ if ((rc = qemuConnectAgent(driver, vm)) < 0) {
+ if (rc == -2)
+ goto endjob;
+
+ VIR_WARN("Cannot connect to QEMU guest agent for %s",
+ vm->def->name);
+ virResetLastError();
+ priv->agentError = true;
+ }
+
+
if (flags & VIR_MIGRATE_PERSIST_DEST) {
if (qemuMigrationPersist(driver, vm, mig, !v3proto) < 0) {
/* Hmpf. Migration was successful, but making it persistent
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 05cbda2..e1a25dd 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -77,6 +77,10 @@
VIR_LOG_INIT("qemu.qemu_process");
+static int
+qemuProcessReconnectRefreshChannelVirtioState(virQEMUDriverPtr driver,
+ virDomainObjPtr vm);
+
/**
* qemuProcessRemoveDomainStatus
*
@@ -208,6 +212,26 @@ qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm)
if (!config)
return 0;
+ if (priv->agent)
+ return 0;
+
+ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VSERPORT_CHANGE) &&
+ config->state != VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED) {
+ /* So qemu is capable of sending us event whenever guest agent
+ * (dis-)connects. And we reflect its state in config->state. Well,
+ * nearly. It may happen that what we think about the guest agent state
+ * is not accurate, e.g. right after migration. Ask qemu to be sure. */
+
+ if (qemuProcessReconnectRefreshChannelVirtioState(driver, vm) < 0)
+ goto cleanup;
+
+ /* Now we are sure about the channel state. */
+ if (config->state != VIR_DOMAIN_CHR_DEVICE_STATE_CONNECTED) {
+ VIR_DEBUG("Deferring connecting to guest agent");
+ return 0;
+ }
+ }
+
if (virSecurityManagerSetDaemonSocketLabel(driver->securityManager,
vm->def) < 0) {
VIR_ERROR(_("Failed to set security context for agent for %s"),
--
2.4.10
8 years, 9 months
[libvirt] [PATCH] qemu: Don't crash when create fails early
by Martin Kletzander
Since commit 714080791778e3dfbd484ccb3953bffd820b8ba9 we are generating
socket path later than before -- when starting a domain. That makes one
particular inconsistent state of a chardev, which was not possible
before, currently valid. However, SELinux security driver forgot to
guard the main restoring function by a check for NULL-paths. So make it
no-op for NULL paths, as in the DAC driver.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1300532
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
src/security/security_selinux.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 9e986350fbb1..6a32f0a27f12 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1024,6 +1024,12 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr,
char *newpath = NULL;
char ebuf[1024];
+ /* Some paths are auto-generated, so let's be safe here and do
+ * nothing if nothing is needed.
+ */
+ if (!path)
+ return 0;
+
VIR_INFO("Restoring SELinux context on '%s'", path);
if (virFileResolveLink(path, &newpath) < 0) {
--
2.7.0
8 years, 9 months
[libvirt] oVirt considers using macTableManager='libvirt'
by Ido Barkan
Hi guys,
We, at oVirt, are considring using the automatic bridge management
feature of libvirt for our hosts
(macTableManager='libvirt').
I could find any discussion in the mailing list archives about the
motivation for this feature.
(was there?). If there wasn't I would like to start a new one, about
the possible trade offs it would
have in oVirt.
Specifically I have a few questions:
1) The obvious performance motivation is clear: considering N hosts
with M vms each connected to
the same LAN, the first packet to any unknown yet host will flood
all the vms in all N bridges.
-- was there any other motivation that I do not understand
(apart from slightly better security?
2) oVirt uses TC for port mirroring, in case this is requested by
users, to mirror traffic from a chosen
bridge to a chosen NIC in the host. I could not understand if
macTableManager will interfere
with it, or not.
3) Are there any drawbacks to enabling this feature?
4) We aim for rhel7.2. Will the feature be supported (or partially
supported) for kernels older then
3.17? And if so, in what way?
5) oVirt currently builds its own bridges and tell libvirt about them.
Does that have any affect on the
functionality of that feature?
6) are there any plans to support OVS for this feature in the future?
--
Thanks,
Ido Barkan
8 years, 9 months
[libvirt] [PATCH] conf: qemu: Add support for more HyperV Enlightenment features
by Maxim Nestratov
This patch adds support for "vpindex", "runtime", "synic" and
"stimer" features available in qemu 2.5+.
- When Hyper-V "vpindex" is on, guest can use MSR HV_X64_MSR_VP_INDEX
to get virtual processor ID.
- Hyper-V "runtime" enlightement feature allows to use MSR
HV_X64_MSR_VP_RUNTIME to get the time the virtual processor consumes
running guest code, as well as the time the hypervisor spends running
code on behalf of that guest.
- Hyper-V "synic" stands for Synthetic Interrupt Controller, which is
lapic extension controlled via MSRs.
- Hyper-V "stimer" switches on Hyper-V SynIC timers MSR's support.
Guest can setup and use fired by host events (SynIC interrupt and
appropriate timer expiration message) as guest clock events
Signed-off-by: Maxim Nestratov <mnestratov(a)virtuozzo.com>
---
docs/formatdomain.html.in | 28 ++++++++++++++++++++++
docs/schemas/domaincommon.rng | 20 ++++++++++++++++
src/conf/domain_conf.c | 18 +++++++++++++-
src/conf/domain_conf.h | 4 ++++
src/qemu/qemu_command.c | 8 +++++++
tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml | 4 ++++
tests/qemuxml2argvdata/qemuxml2argv-hyperv.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml | 4 ++++
8 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b3187bb..3edd0a2 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1460,6 +1460,10 @@
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='4096'/>
+ <vpindex state='on'/>
+ <runtime state='on'/>
+ <synic state='on'/>
+ <stimer state='on'/>
</hyperv>
<kvm>
<hidden state='on'/>
@@ -1535,6 +1539,30 @@
<td>on, off; retries - at least 4095</td>
<td><span class="since">1.1.0 (QEMU only)</span></td>
</tr>
+ <tr>
+ <td>vpindex</td>
+ <td>Virtual processor index</td>
+ <td> on, off</td>
+ <td><span class="since">2.5.0 (QEMU only)</span></td>
+ </tr>
+ <tr>
+ <td>runtime</td>
+ <td>Processor time spent on running guest code and on behalf of guest code</td>
+ <td> on, off</td>
+ <td><span class="since">2.5.0 (QEMU only)</span></td>
+ </tr>
+ <tr>
+ <td>synic</td>
+ <td>Enable Synthetic Interrupt Controller (SyNIC)</td>
+ <td> on, off</td>
+ <td><span class="since">2.5.0 (QEMU only)</span></td>
+ </tr>
+ <tr>
+ <td>stimer</td>
+ <td>Enable SyNIC timers</td>
+ <td> on, off</td>
+ <td><span class="since">2.5.0 (QEMU only)</span></td>
+ </tr>
</table>
</dd>
<dt><code>pvspinlock</code></dt>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5deb17b..e079e86 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4858,6 +4858,26 @@
</optional>
</element>
</optional>
+ <optional>
+ <element name="vpindex">
+ <ref name="featurestate"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="runtime">
+ <ref name="featurestate"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="synic">
+ <ref name="featurestate"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="stimer">
+ <ref name="featurestate"/>
+ </element>
+ </optional>
</interleave>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1ea74a6..bbc14fd 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -145,7 +145,11 @@ VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST,
VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
"relaxed",
"vapic",
- "spinlocks")
+ "spinlocks",
+ "vpindex",
+ "runtime",
+ "synic",
+ "stimer")
VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST,
"hidden")
@@ -15460,6 +15464,10 @@ virDomainDefParseXML(xmlDocPtr xml,
switch ((virDomainHyperv) feature) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
if (!(tmp = virXPathString("string(./@state)", ctxt))) {
virReportError(VIR_ERR_XML_ERROR,
_("missing 'state' attribute for "
@@ -17508,6 +17516,10 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
switch ((virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
if (src->hyperv_features[i] != dst->hyperv_features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of HyperV enlightenment "
@@ -22099,6 +22111,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
switch ((virDomainHyperv) j) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
if (def->hyperv_features[j])
virBufferAsprintf(buf, "<%s state='%s'/>\n",
virDomainHypervTypeToString(j),
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0141009..c96e0c4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1700,6 +1700,10 @@ typedef enum {
VIR_DOMAIN_HYPERV_RELAXED = 0,
VIR_DOMAIN_HYPERV_VAPIC,
VIR_DOMAIN_HYPERV_SPINLOCKS,
+ VIR_DOMAIN_HYPERV_VPINDEX,
+ VIR_DOMAIN_HYPERV_RUNTIME,
+ VIR_DOMAIN_HYPERV_SYNIC,
+ VIR_DOMAIN_HYPERV_STIMER,
VIR_DOMAIN_HYPERV_LAST
} virDomainHyperv;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5d3ab3a..fc55a82 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7739,6 +7739,10 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
switch ((virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(&buf, ",hv_%s",
virDomainHypervTypeToString(i));
@@ -12790,6 +12794,10 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
switch ((virDomainHyperv) f) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_VPINDEX:
+ case VIR_DOMAIN_HYPERV_RUNTIME:
+ case VIR_DOMAIN_HYPERV_SYNIC:
+ case VIR_DOMAIN_HYPERV_STIMER:
if (value) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("HyperV feature '%s' should not "
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml b/tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml
index 1067f64..438f4a5 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml
@@ -14,6 +14,10 @@
<relaxed state='off'/>
<vapic state='off'/>
<spinlocks state='off'/>
+ <vpindex state='off'/>
+ <runtime state='off'/>
+ <synic state='off'/>
+ <stimer state='off'/>
</hyperv>
</features>
<clock offset='utc'/>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
index a6f37e3..e4b2af5 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
@@ -8,7 +8,7 @@ QEMU_AUDIO_DRV=none \
-name QEMUGuest1 \
-S \
-M pc \
--cpu qemu32,hv_relaxed,hv_vapic,hv_spinlocks=0x2fff \
+-cpu qemu32,hv_relaxed,hv_vapic,hv_spinlocks=0x2fff,hv_vpindex,hv_runtime,hv_synic,hv_stimer \
-m 214 \
-smp 6 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
index 2b8f332..2844b24 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
@@ -14,6 +14,10 @@
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='12287'/>
+ <vpindex state='on'/>
+ <runtime state='on'/>
+ <synic state='on'/>
+ <stimer state='on'/>
</hyperv>
</features>
<clock offset='utc'/>
--
1.8.3.1
8 years, 9 months
[libvirt] [PATCH v2 0/6] Some logical pool/volume changes
by John Ferlan
v1: http://www.redhat.com/archives/libvir-list/2016-January/msg01023.html
Differences to v1:
Patch 1 is the former patch 2 with the following adjuments:
- Change helper name to be virStorageBackendLogicalParseVolExtents
- Include all 'extent' parsing needs - including fetch/parse of 'stripes'
to determine 'nextents' value, allocation of vol->source.extents,
parse of groups[6] to be 'length', parse of groups[7] to be 'size'
Patch 2 is new, but replaces some of the concepts from patch 3:
- I rototilled the virStorageBackendLogicalParseVolExtents to remove
the unnecessary trip through regex/regcomp.
- Used virStringSplitCount instread and then parse the resultant string.
- Removed the need for the 'stripes' fetch since it really wasn't doing
what it was supposed to.
- I adjusted the virstringtest to exhibit what is being parsed (it can
be removed if you think that's excessive).
Patches 3-5 are new
- These could be combined. I left them separate to show the process...
- Essentially adding a new "source" field to be used to display in
the vol-dumpxml output
Patch 6 is part of the old patch 4:
- Since the old patch 3 isn't necessary - it's essentially gone. This
just takes the patch 4 concept of changing the regex, but also applies
it to the current code.
John Ferlan (6):
logical: Create helper virStorageBackendLogicalParseVolExtents
logical: Fix parsing of the 'devices' field lvs output
logical: Search for a segtype of "thin" and mark lv as sparse
vol: Add thin_pool to _virStorageVolSource
logical: Add capability to get the thin pool name
logical: Display thin lv's found in a libvirt managed volume group
docs/formatstorage.html.in | 9 +-
src/conf/storage_conf.c | 5 +
src/conf/storage_conf.h | 1 +
src/storage/storage_backend_logical.c | 221 ++++++++++++++++------------------
tests/virstringtest.c | 11 ++
5 files changed, 127 insertions(+), 120 deletions(-)
--
2.5.0
8 years, 9 months