Compare commits

..

2 Commits

Author SHA1 Message Date
Mark McLoughlin 6ccf4c1a0c * Wed Sep 30 2009 Mark McLoughlin <markmc@redhat.com> - 0.7.1-7
- Fix USB device passthrough (#522683)
2009-09-30 17:57:50 +00:00
Jesse Keating dbaa6786af Initialize branch F-12 for libvirt 2009-09-29 05:24:04 +00:00
15 changed files with 507 additions and 2488 deletions
+13
View File
@@ -0,0 +1,13 @@
.build*.log
*.rpm
i686
x86_64
libvirt-*.tar.gz
libvirt-0.6.0.tar.gz
libvirt-0.6.1.tar.gz
libvirt-0.6.2.tar.gz
libvirt-0.6.3.tar.gz
libvirt-0.6.4.tar.gz
libvirt-0.6.5.tar.gz
libvirt-0.7.0.tar.gz
libvirt-0.7.1.tar.gz
-5
View File
@@ -1,5 +0,0 @@
.build*.log
*.rpm
i686
x86_64
libvirt-*.tar.gz
@@ -1,27 +0,0 @@
From 37865f1dead1fac2ee34af48f96d19d686296e04 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 13 Sep 2012 14:37:22 +0100
Subject: [PATCH] Use 'qemu-system-i386' as binary instead of 'qemu'.
---
src/qemu/qemu_capabilities.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index af3b0b2..179b3d2 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -244,8 +244,8 @@ static const struct qemu_feature_flags const arch_info_x86_64_flags [] = {
/* The archicture tables for supported QEMU archs */
static const struct qemu_arch_info const arch_info_hvm[] = {
- { "i686", 32, NULL, "qemu",
- "qemu-system-x86_64", arch_info_i686_flags, 4 },
+ { "i686", 32, NULL, "qemu-system-i386",
+ NULL, arch_info_i686_flags, 4 },
{ "x86_64", 64, NULL, "qemu-system-x86_64",
NULL, arch_info_x86_64_flags, 2 },
{ "arm", 32, NULL, "qemu-system-arm", NULL, NULL, 0 },
--
1.7.11.4
+1 -1
View File
@@ -4,7 +4,7 @@ NAME := libvirt
SPECFILE = $(firstword $(wildcard *.spec))
define find-makefile-common
for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
endef
MAKEFILE_COMMON := $(shell $(find-makefile-common))
+1
View File
@@ -0,0 +1 @@
F-12
+51
View File
@@ -0,0 +1,51 @@
From 127a39777e9809053bb98a9082e27c73543ccfa2 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 17 Aug 2009 08:32:08 +0100
Subject: [PATCH] Disable sound cards when running sVirt
Temporary hack till PulseAudio autostart problems are sorted out when
SELinux enforcing (bz 486112)
Fedora-patch: libvirt-0.6.4-svirt-sound.patch
---
src/qemu_conf.c | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index f92bcef..f3b4ef0 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -1510,6 +1510,20 @@ int qemudBuildCommandLine(virConnectPtr conn,
char uuid[VIR_UUID_STRING_BUFLEN];
char domid[50];
const char *cpu = NULL;
+ int skipSound = 0;
+
+ if (driver->securityDriver &&
+ driver->securityDriver->name &&
+ STREQ(driver->securityDriver->name, "selinux") &&
+ getuid() == 0) {
+ static int soundWarned = 0;
+ skipSound = 1;
+ if (def->nsounds &&
+ !soundWarned) {
+ soundWarned = 1;
+ VIR_WARN0("Sound cards for VMs are disabled while SELinux security model is active");
+ }
+ }
uname_normalize(&ut);
@@ -2181,7 +2195,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
}
/* Add sound hardware */
- if (def->nsounds) {
+ if (def->nsounds &&
+ !skipSound) {
int size = 100;
char *modstr;
if (VIR_ALLOC_N(modstr, size+1) < 0)
--
1.6.2.5
-225
View File
@@ -1,225 +0,0 @@
Return-Path: alexl@redhat.com
Received: from zmta04.collab.prod.int.phx2.redhat.com (LHLO
zmta04.collab.prod.int.phx2.redhat.com) (10.5.81.11) by
zmail20.collab.prod.int.phx2.redhat.com with LMTP; Tue, 9 Oct 2012 11:26:38
-0400 (EDT)
Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23])
by zmta04.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id D4096D0927
for <alexl@mail.corp.redhat.com>; Tue, 9 Oct 2012 11:26:38 -0400 (EDT)
Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1])
by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q99FQV93016417;
Tue, 9 Oct 2012 11:26:33 -0400
From: Alexander Larsson <alexl@redhat.com>
To: libvir-list@redhat.com
Cc: Alexander Larsson <alexl@redhat.com>
Subject: [PATCH 1/2] virdbus: Add virDBusGetSessionBus helper
Date: Tue, 9 Oct 2012 17:26:28 +0200
Message-Id: <1349796389-6122-2-git-send-email-alexl@redhat.com>
In-Reply-To: <1349796389-6122-1-git-send-email-alexl@redhat.com>
References: <1349796389-6122-1-git-send-email-alexl@redhat.com>
X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23
This splits out some common code from virDBusGetSystemBus and
uses it to implement a new virDBusGetSessionBus helper.
---
src/libvirt_private.syms | 1 +
src/util/virdbus.c | 84 ++++++++++++++++++++++++++++++++++++------------
src/util/virdbus.h | 1 +
3 files changed, 66 insertions(+), 20 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a8c81e7..88f1b2f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1310,6 +1310,7 @@ virConsoleOpen;
# virdbus.h
virDBusGetSystemBus;
+virDBusGetSessionBus;
# virdomainlist.h
diff --git a/src/util/virdbus.c b/src/util/virdbus.c
index 4acce12..2dc7265 100644
--- a/src/util/virdbus.c
+++ b/src/util/virdbus.c
@@ -32,40 +32,49 @@
#ifdef HAVE_DBUS
static DBusConnection *systembus = NULL;
-static virOnceControl once = VIR_ONCE_CONTROL_INITIALIZER;
-static DBusError dbuserr;
+static DBusConnection *sessionbus = NULL;
+static virOnceControl systemonce = VIR_ONCE_CONTROL_INITIALIZER;
+static virOnceControl sessiononce = VIR_ONCE_CONTROL_INITIALIZER;
+static DBusError systemdbuserr;
+static DBusError sessiondbuserr;
static dbus_bool_t virDBusAddWatch(DBusWatch *watch, void *data);
static void virDBusRemoveWatch(DBusWatch *watch, void *data);
static void virDBusToggleWatch(DBusWatch *watch, void *data);
-static void virDBusSystemBusInit(void)
+static DBusConnection *virDBusBusInit(DBusBusType type, DBusError *dbuserr)
{
+ DBusConnection *bus;
+
/* Allocate and initialize a new HAL context */
dbus_connection_set_change_sigpipe(FALSE);
dbus_threads_init_default();
- dbus_error_init(&dbuserr);
- if (!(systembus = dbus_bus_get(DBUS_BUS_SYSTEM, &dbuserr)))
- return;
+ dbus_error_init(dbuserr);
+ if (!(bus = dbus_bus_get(type, dbuserr)))
+ return NULL;
- dbus_connection_set_exit_on_disconnect(systembus, FALSE);
+ dbus_connection_set_exit_on_disconnect(bus, FALSE);
/* Register dbus watch callbacks */
- if (!dbus_connection_set_watch_functions(systembus,
+ if (!dbus_connection_set_watch_functions(bus,
virDBusAddWatch,
virDBusRemoveWatch,
virDBusToggleWatch,
- NULL, NULL)) {
- systembus = NULL;
- return;
+ bus, NULL)) {
+ return NULL;
}
+ return bus;
}
+static void virDBusSystemBusInit(void)
+{
+ systembus = virDBusBusInit (DBUS_BUS_SYSTEM, &systemdbuserr);
+}
DBusConnection *virDBusGetSystemBus(void)
{
- if (virOnce(&once, virDBusSystemBusInit) < 0) {
+ if (virOnce(&systemonce, virDBusSystemBusInit) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to run one time DBus initializer"));
return NULL;
@@ -74,7 +83,7 @@ DBusConnection *virDBusGetSystemBus(void)
if (!systembus) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to get DBus system bus connection: %s"),
- dbuserr.message ? dbuserr.message : "watch setup failed");
+ systemdbuserr.message ? systemdbuserr.message : "watch setup failed");
return NULL;
}
@@ -82,13 +91,45 @@ DBusConnection *virDBusGetSystemBus(void)
}
+static void virDBusSessionBusInit(void)
+{
+ sessionbus = virDBusBusInit (DBUS_BUS_SESSION, &sessiondbuserr);
+}
+
+DBusConnection *virDBusGetSessionBus(void)
+{
+ if (virOnce(&sessiononce, virDBusSessionBusInit) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to run one time DBus initializer"));
+ return NULL;
+ }
+
+ if (!sessionbus) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to get DBus session bus connection: %s"),
+ sessiondbuserr.message ? sessiondbuserr.message : "watch setup failed");
+ return NULL;
+ }
+
+ return sessionbus;
+}
+
+struct virDBusWatch
+{
+ int watch;
+ DBusConnection *bus;
+};
+
static void virDBusWatchCallback(int fdatch ATTRIBUTE_UNUSED,
int fd ATTRIBUTE_UNUSED,
int events, void *opaque)
{
DBusWatch *watch = opaque;
+ struct virDBusWatch *info;
int dbus_flags = 0;
+ info = dbus_watch_get_data(watch);
+
if (events & VIR_EVENT_HANDLE_READABLE)
dbus_flags |= DBUS_WATCH_READABLE;
if (events & VIR_EVENT_HANDLE_WRITABLE)
@@ -100,7 +141,7 @@ static void virDBusWatchCallback(int fdatch ATTRIBUTE_UNUSED,
(void)dbus_watch_handle(watch, dbus_flags);
- while (dbus_connection_dispatch(systembus) == DBUS_DISPATCH_DATA_REMAINS)
+ while (dbus_connection_dispatch(info->bus) == DBUS_DISPATCH_DATA_REMAINS)
/* keep dispatching while data remains */;
}
@@ -120,18 +161,13 @@ static int virDBusTranslateWatchFlags(int dbus_flags)
}
-struct virDBusWatch
-{
- int watch;
-};
-
static void virDBusWatchFree(void *data) {
struct virDBusWatch *info = data;
VIR_FREE(info);
}
static dbus_bool_t virDBusAddWatch(DBusWatch *watch,
- void *data ATTRIBUTE_UNUSED)
+ void *data)
{
int flags = 0;
int fd;
@@ -148,6 +184,7 @@ static dbus_bool_t virDBusAddWatch(DBusWatch *watch,
# else
fd = dbus_watch_get_fd(watch);
# endif
+ info->bus = (DBusConnection *)data;
info->watch = virEventAddHandle(fd, flags,
virDBusWatchCallback,
watch, NULL);
@@ -194,4 +231,11 @@ DBusConnection *virDBusGetSystemBus(void)
return NULL;
}
+DBusConnection *virDBusGetSessionBus(void)
+{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("DBus support not compiled into this binary"));
+ return NULL;
+}
+
#endif /* ! HAVE_DBUS */
diff --git a/src/util/virdbus.h b/src/util/virdbus.h
index 27dca00..e443fbe 100644
--- a/src/util/virdbus.h
+++ b/src/util/virdbus.h
@@ -30,5 +30,6 @@
# include "internal.h"
DBusConnection *virDBusGetSystemBus(void);
+DBusConnection *virDBusGetSessionBus(void);
#endif /* __VIR_DBUS_H__ */
--
1.7.12.1
@@ -0,0 +1,32 @@
From 2f6e857ac7d6ed5cd417e684147dd9c98775ab3d Mon Sep 17 00:00:00 2001
From: Chris Lalancette <clalance@redhat.com>
Date: Mon, 21 Sep 2009 14:53:31 +0200
Subject: [PATCH] Don't do virSetConnError when virDrvSupportsFeature is successful.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
Fedora-patch: libvirt-fix-drv-supports-feature-bogus-error.patch
---
src/libvirt.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 4a11688..fa59dc7 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1349,8 +1349,11 @@ virDrvSupportsFeature (virConnectPtr conn, int feature)
}
ret = VIR_DRV_SUPPORTS_FEATURE (conn->driver, conn, feature);
- /* Copy to connection error object for back compatability */
- virSetConnError(conn);
+
+ if (ret < 0)
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+
return ret;
}
--
1.6.2.5
@@ -0,0 +1,46 @@
From d09ff3c35c29d14760d5ea03559042cc024e09ab Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 17 Sep 2009 15:31:08 +0100
Subject: [PATCH] Fix net/disk hot-unplug segfault
When we hot-unplug the last device, we're currently double-freeing
the device definition.
Reported by Michal Nowak here:
https://bugzilla.redhat.com/523953
* src/qemu_driver.c: fix double free
(cherry-picked from commit 8881ae1bf8783006777429403cc543c33187175d)
Fedora-patch: libvirt-fix-net-hotunplug-double-free.patch
---
src/qemu_driver.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index a65334f..de31581 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5998,7 +5998,7 @@ try_command:
/* ignore, harmless */
}
} else {
- VIR_FREE(vm->def->disks[0]);
+ VIR_FREE(vm->def->disks);
vm->def->ndisks = 0;
}
virDomainDiskDefFree(detach);
@@ -6100,7 +6100,7 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
/* ignore, harmless */
}
} else {
- VIR_FREE(vm->def->nets[0]);
+ VIR_FREE(vm->def->nets);
vm->def->nnets = 0;
}
virDomainNetDefFree(detach);
--
1.6.2.5
@@ -0,0 +1,50 @@
From d04ac8624f5fabe7587982796f2e2161220b0fcc Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 17 Sep 2009 15:32:45 +0100
Subject: [PATCH] Fix leak in PCI hostdev hot-unplug
* src/qemu_driver.c: sync the hostdev hot-unplug code with the disk/net
code.
(cherry-picked from commit a70da51ff76ed860bfc0cdee2e1d556da997c557)
Fedora-patch: libvirt-fix-pci-hostdev-hotunplug-leak.patch
---
src/qemu_driver.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index de31581..2ddcdc0 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -6206,14 +6206,20 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
pciFreeDevice(conn, pci);
}
- if (i != --vm->def->nhostdevs)
- memmove(&vm->def->hostdevs[i],
- &vm->def->hostdevs[i+1],
- sizeof(*vm->def->hostdevs) * (vm->def->nhostdevs-i));
- if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs) < 0) {
- virReportOOMError(conn);
- ret = -1;
+ if (vm->def->nhostdevs > 1) {
+ memmove(vm->def->hostdevs + i,
+ vm->def->hostdevs + i + 1,
+ sizeof(*vm->def->hostdevs) *
+ (vm->def->nhostdevs - (i + 1)));
+ vm->def->nhostdevs--;
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs) < 0) {
+ /* ignore, harmless */
+ }
+ } else {
+ VIR_FREE(vm->def->hostdevs);
+ vm->def->nhostdevs = 0;
}
+ virDomainHostdevDefFree(detach);
return ret;
}
--
1.6.2.5
+53
View File
@@ -0,0 +1,53 @@
From e50c91fdcea5d81e3eb2051c05f4e51a16c3e692 Mon Sep 17 00:00:00 2001
From: Charles Duffy <Charles_Duffy@dell.com>
Date: Fri, 18 Sep 2009 11:32:35 -0500
Subject: [PATCH] Prevent attempt to call cat -c during virDomainSave to raw
Fedora-patch: libvirt-fix-qemu-raw-format-save.patch
---
src/qemu_driver.c | 28 ++++++++++++++++++----------
1 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 2ddcdc0..7c7b985 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -3905,17 +3905,25 @@ static int qemudDomainSave(virDomainPtr dom,
goto cleanup;
}
- const char *prog = qemudSaveCompressionTypeToString(header.compressed);
- if (prog == NULL) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Invalid compress format %d"), header.compressed);
- goto cleanup;
- }
+ {
+ const char *prog = qemudSaveCompressionTypeToString(header.compressed);
+ const char *args;
- if (STREQ (prog, "raw"))
- prog = "cat";
- internalret = virAsprintf(&command, "migrate \"exec:"
- "%s -c >> '%s' 2>/dev/null\"", prog, safe_path);
+ if (prog == NULL) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Invalid compress format %d"), header.compressed);
+ goto cleanup;
+ }
+
+ if (STREQ (prog, "raw")) {
+ prog = "cat";
+ args = "";
+ } else {
+ args = "-c";
+ }
+ internalret = virAsprintf(&command, "migrate \"exec:"
+ "%s %s >> '%s' 2>/dev/null\"", prog, args, safe_path);
+ }
if (internalret < 0) {
virReportOOMError(dom->conn);
--
1.6.2.5
+41
View File
@@ -0,0 +1,41 @@
From 16f20706f8d2f113bb6a49f56e415c16d438183e Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Wed, 30 Sep 2009 18:37:03 +0100
Subject: [PATCH] Fix USB device re-labelling
A simple misplaced break out of a switch results in:
libvir: error : Failed to open file '/sys/bus/pci/devices/0000:00:54c./vendor': No such file or directory
libvir: error : Failed to open file '/sys/bus/pci/devices/0000:00:54c./device': No such file or directory
libvir: error : this function is not supported by the hypervisor: Failed to read product/vendor ID for 0000:00:54c.
when trying to passthrough a USB host device to qemu.
* src/security_selinux.c: fix a switch/break thinko
Fedora-patch: libvirt-fix-usb-device-passthrough.patch
---
src/security_selinux.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/security_selinux.c b/src/security_selinux.c
index bc295b1..b4dc153 100644
--- a/src/security_selinux.c
+++ b/src/security_selinux.c
@@ -464,12 +464,11 @@ SELinuxSetSecurityHostdevLabel(virConnectPtr conn,
ret = usbDeviceFileIterate(conn, usb, SELinuxSetSecurityUSBLabel, vm);
usbFreeDevice(conn, usb);
-
- break;
} else {
/* XXX deal with product/vendor better */
ret = 0;
}
+ break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
--
1.6.4.4
-303
View File
@@ -1,303 +0,0 @@
Return-Path: alexl@redhat.com
Received: from zmta06.collab.prod.int.phx2.redhat.com (LHLO
zmta06.collab.prod.int.phx2.redhat.com) (10.5.81.13) by
zmail20.collab.prod.int.phx2.redhat.com with LMTP; Tue, 9 Oct 2012 11:26:39
-0400 (EDT)
Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23])
by zmta06.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id D4A8516044F
for <alexl@mail.corp.redhat.com>; Tue, 9 Oct 2012 11:26:39 -0400 (EDT)
Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1])
by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q99FQV94016417;
Tue, 9 Oct 2012 11:26:34 -0400
From: Alexander Larsson <alexl@redhat.com>
To: libvir-list@redhat.com
Cc: Alexander Larsson <alexl@redhat.com>
Subject: [PATCH 2/2] Shut down session libvirtd cleanly
Date: Tue, 9 Oct 2012 17:26:29 +0200
Message-Id: <1349796389-6122-3-git-send-email-alexl@redhat.com>
In-Reply-To: <1349796389-6122-1-git-send-email-alexl@redhat.com>
References: <1349796389-6122-1-git-send-email-alexl@redhat.com>
X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23
When the session dies or when the system is going to be shut down
we save all active VMs and exit libvirtd.
Additionally whenever there is an active domain we hold a
shutdown inhibitor to avoid shutting down before all the
VMs are saved.
---
daemon/libvirtd.c | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 244 insertions(+)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index b49acc5..c3bf2ce 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -98,6 +98,11 @@
#include "configmake.h"
+#ifdef HAVE_DBUS
+# include <dbus/dbus.h>
+# include "virdbus.h"
+#endif
+
#if HAVE_SASL
virNetSASLContextPtr saslCtxt = NULL;
#endif
@@ -769,6 +774,212 @@ static int daemonSetupSignals(virNetServerPtr srv)
return 0;
}
+#ifdef HAVE_DBUS
+
+static DBusConnection *sessionBus;
+static DBusConnection *systemBus;
+static virConnectPtr sessionConnection;
+static int numActiveDomains;
+static bool hasInhibit;
+static bool callingInhibit;
+static int inhibitFd = -1;
+
+static void runSaveAllDomains(void *opaque)
+{
+ virNetServerPtr srv = opaque;
+ int numDomains, i;
+ int state;
+ virDomainPtr *domains = NULL;
+ unsigned int *flags = NULL;
+
+ numDomains = virConnectListAllDomains(sessionConnection, &domains, VIR_CONNECT_LIST_DOMAINS_ACTIVE);
+ if (numDomains < 0)
+ goto cleanup;
+
+ if (VIR_ALLOC_N(flags, numDomains) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* First we pause all VMs to make them stop dirtying
+ pages, etc. We remember if any VMs were paused so
+ we can restore that on resume. */
+ for (i = 0 ; i < numDomains ; i++) {
+ flags[i] = VIR_DOMAIN_SAVE_RUNNING;
+ if (virDomainGetState (domains[i], &state, NULL, 0) == 0) {
+ if (state == VIR_DOMAIN_PAUSED) {
+ flags[i] = VIR_DOMAIN_SAVE_PAUSED;
+ }
+ }
+ virDomainSuspend (domains[i]);
+ }
+
+ /* Then we save the VMs to disk */
+ for (i = 0 ; i < numDomains ; i++)
+ virDomainManagedSave (domains[i], flags[i]);
+
+ VIR_FREE (domains);
+ VIR_FREE (flags);
+
+ cleanup:
+ if (domains != NULL) {
+ for (i = 0 ; i < numDomains ; i++)
+ virDomainFree (domains[i]);
+ VIR_FREE (domains);
+ }
+ if (flags != NULL)
+ VIR_FREE (flags);
+
+ /* We don't need any shutdown inhibit lock anymore now */
+ if (inhibitFd != -1) {
+ if (VIR_CLOSE (inhibitFd) < 0)
+ virReportSystemError(errno, "%s", _("failed to close file"));
+ inhibitFd = -1;
+ }
+
+ /* Exit libvirtd cleanly */
+ virNetServerQuit (srv);
+}
+
+/* We do this in a thread to not block the main loop */
+static void saveAllDomains(virNetServerPtr srv)
+{
+ virThread thr;
+ virObjectRef(srv);
+ if (virThreadCreate(&thr, false, runSaveAllDomains, srv) < 0) {
+ virObjectUnref(srv);
+ }
+}
+
+static void gotInhibitReply (DBusPendingCall *pending,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ DBusMessage *reply;
+ int fd;
+
+ callingInhibit = false;
+
+ reply = dbus_pending_call_steal_reply (pending);
+ if (reply == NULL)
+ return;
+
+ if (dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_UNIX_FD, &fd,
+ DBUS_TYPE_INVALID)) {
+ if (hasInhibit)
+ inhibitFd = fd;
+ else {
+ /* We stopped the last VM since we made the inhibit call */
+ if (VIR_CLOSE (fd) < 0) {
+ virReportSystemError(errno, "%s", _("failed to close file"));
+ }
+ }
+ }
+ dbus_message_unref (reply);
+}
+
+/* As per: http://www.freedesktop.org/wiki/Software/systemd/inhibit */
+static void callInhibit(const char *what,
+ const char *who,
+ const char *why,
+ const char *mode)
+{
+ DBusMessage *message;
+ DBusPendingCall *pendingReply;
+
+ if (systemBus == NULL)
+ return;
+
+ /* Only one outstanding call at a time */
+ if (callingInhibit)
+ return;
+
+ message = dbus_message_new_method_call ("org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "Inhibit");
+ if (message == NULL)
+ return;
+
+ dbus_message_append_args (message,
+ DBUS_TYPE_STRING, &what,
+ DBUS_TYPE_STRING, &who,
+ DBUS_TYPE_STRING, &why,
+ DBUS_TYPE_STRING, &mode,
+ DBUS_TYPE_INVALID);
+
+ pendingReply = NULL;
+ if (dbus_connection_send_with_reply (systemBus, message,
+ &pendingReply,
+ 25*1000)) {
+ dbus_pending_call_set_notify (pendingReply,
+ gotInhibitReply,
+ NULL, NULL);
+ callingInhibit = true;
+ }
+ dbus_message_unref (message);
+}
+
+
+static void numActiveDomainsChanged(void)
+{
+ if (numActiveDomains > 0 && !hasInhibit) {
+ callInhibit("shutdown", _("Libvirt"), _("Virtual machines need to be saved"), "delay");
+ hasInhibit = true;
+ } else if (numActiveDomains == 0 && hasInhibit) {
+ if (inhibitFd != -1) {
+ if (VIR_CLOSE (inhibitFd) < 0) {
+ virReportSystemError(errno, "%s", _("failed to close file"));
+ }
+ inhibitFd = -1;
+ }
+ hasInhibit = false;
+ }
+}
+
+static int lifecycleEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom ATTRIBUTE_UNUSED,
+ int event,
+ int detail ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ if (event == VIR_DOMAIN_EVENT_STOPPED)
+ numActiveDomains--;
+ else if (event == VIR_DOMAIN_EVENT_STARTED)
+ numActiveDomains++;
+
+ numActiveDomainsChanged();
+
+ return 0;
+}
+
+static DBusHandlerResult handleSessionMessageFunc(DBusConnection *connection ATTRIBUTE_UNUSED,
+ DBusMessage *message,
+ void *userData)
+{
+ virNetServerPtr srv = userData;
+
+ if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
+ saveAllDomains (srv);
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult handleSystemMessageFunc(DBusConnection *connection ATTRIBUTE_UNUSED,
+ DBusMessage *message,
+ void *userData)
+{
+ virNetServerPtr srv = userData;
+
+ if (dbus_message_is_signal(message, "org.freedesktop.login1.Manager", "PrepareForShutdown")) {
+ saveAllDomains (srv);
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+#endif
+
static void daemonRunStateInit(void *opaque)
{
virNetServerPtr srv = opaque;
@@ -785,6 +996,39 @@ static void daemonRunStateInit(void *opaque)
return;
}
+#ifdef HAVE_DBUS
+ /* Tie the non-priviledged libvirtd to the session/shutdown lifecycle */
+ if (!virNetServerIsPrivileged(srv)) {
+
+ sessionBus = virDBusGetSessionBus ();
+ if (sessionBus != NULL) {
+ dbus_connection_add_filter(sessionBus,
+ handleSessionMessageFunc, srv, NULL);
+ }
+
+ systemBus = virDBusGetSystemBus ();
+ if (systemBus != NULL) {
+ dbus_connection_add_filter(systemBus,
+ handleSystemMessageFunc, srv, NULL);
+ dbus_bus_add_match(systemBus,
+ "type='signal',sender='org.freedesktop.login1', interface='org.freedesktop.login1.Manager'",
+ NULL);
+ }
+
+ sessionConnection = virConnectOpen("qemu:///session");
+ if (sessionConnection != NULL) {
+ numActiveDomains = virConnectNumOfDomains(sessionConnection);
+ virConnectDomainEventRegisterAny(sessionConnection,
+ NULL,
+ VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+ VIR_DOMAIN_EVENT_CALLBACK (lifecycleEventCallback),
+ NULL, NULL);
+ numActiveDomainsChanged();
+ }
+
+ }
+#endif
+
/* Only now accept clients from network */
virNetServerUpdateServices(srv, true);
virObjectUnref(srv);
--
1.7.12.1
+218 -1926
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1 +1 @@
56078401a10162674dbd98846d0f607d libvirt-0.10.2.8.tar.gz
f1cd360a5da38b847e166c6482141940 libvirt-0.7.1.tar.gz