Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 31970c6c2a | |||
| 131bf1e834 | |||
| 0da9851d5d | |||
| 257e13d238 | |||
| 016a6dcd0e | |||
| b610e1c718 | |||
| caa81cd8d7 | |||
| eca45f4a3f | |||
| d475deef60 |
@@ -3,3 +3,4 @@
|
||||
i686
|
||||
x86_64
|
||||
libvirt-*.tar.gz
|
||||
libvirt-0.4.6.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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
diff -rup libvirt-0.6.0.orig/src/remote_internal.c libvirt-0.6.0.new/src/remote_internal.c
|
||||
--- libvirt-0.6.0.orig/src/remote_internal.c 2009-02-18 10:56:34.000000000 +0000
|
||||
+++ libvirt-0.6.0.new/src/remote_internal.c 2009-02-18 13:35:26.000000000 +0000
|
||||
@@ -654,12 +654,13 @@ doRemoteOpen (virConnectPtr conn,
|
||||
*/
|
||||
if (errno == ECONNREFUSED &&
|
||||
flags & VIR_DRV_OPEN_REMOTE_AUTOSTART &&
|
||||
- trials < 5) {
|
||||
+ trials < 20) {
|
||||
close(priv->sock);
|
||||
priv->sock = -1;
|
||||
- if (remoteForkDaemon(conn) == 0) {
|
||||
+ if (trials > 0 ||
|
||||
+ remoteForkDaemon(conn) == 0) {
|
||||
trials++;
|
||||
- usleep(5000 * trials * trials);
|
||||
+ usleep(1000 * 100 * trials);
|
||||
goto autostart_retry;
|
||||
}
|
||||
}
|
||||
Only in libvirt-0.6.0.new/src: remote_internal.c~
|
||||
@@ -0,0 +1,44 @@
|
||||
diff -rup libvirt-0.6.0.orig/qemud/qemud.c libvirt-0.6.0.new/qemud/qemud.c
|
||||
--- libvirt-0.6.0.orig/qemud/qemud.c 2009-02-18 10:56:34.000000000 +0000
|
||||
+++ libvirt-0.6.0.new/qemud/qemud.c 2009-02-18 12:52:18.000000000 +0000
|
||||
@@ -860,6 +860,10 @@ static struct qemud_server *qemudNetwork
|
||||
if (auth_unix_rw == REMOTE_AUTH_POLKIT ||
|
||||
auth_unix_ro == REMOTE_AUTH_POLKIT) {
|
||||
DBusError derr;
|
||||
+
|
||||
+ dbus_connection_set_change_sigpipe(FALSE);
|
||||
+ dbus_threads_init_default();
|
||||
+
|
||||
dbus_error_init(&derr);
|
||||
server->sysbus = dbus_bus_get(DBUS_BUS_SYSTEM, &derr);
|
||||
if (!(server->sysbus)) {
|
||||
@@ -868,6 +872,7 @@ static struct qemud_server *qemudNetwork
|
||||
dbus_error_free(&derr);
|
||||
goto cleanup;
|
||||
}
|
||||
+ dbus_connection_set_exit_on_disconnect(server->sysbus, FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
diff -rup libvirt-0.6.0.orig/src/node_device_hal.c libvirt-0.6.0.new/src/node_device_hal.c
|
||||
--- libvirt-0.6.0.orig/src/node_device_hal.c 2009-01-16 12:44:22.000000000 +0000
|
||||
+++ libvirt-0.6.0.new/src/node_device_hal.c 2009-02-18 12:52:48.000000000 +0000
|
||||
@@ -685,6 +685,9 @@ static int halDeviceMonitorStartup(void)
|
||||
nodeDeviceLock(driverState);
|
||||
|
||||
/* Allocate and initialize a new HAL context */
|
||||
+ dbus_connection_set_change_sigpipe(FALSE);
|
||||
+ dbus_threads_init_default();
|
||||
+
|
||||
dbus_error_init(&err);
|
||||
hal_ctx = libhal_ctx_new();
|
||||
if (hal_ctx == NULL) {
|
||||
@@ -696,6 +699,8 @@ static int halDeviceMonitorStartup(void)
|
||||
fprintf(stderr, "%s: dbus_bus_get failed\n", __FUNCTION__);
|
||||
goto failure;
|
||||
}
|
||||
+ dbus_connection_set_exit_on_disconnect(dbus_conn, FALSE);
|
||||
+
|
||||
if (!libhal_ctx_set_dbus_connection(hal_ctx, dbus_conn)) {
|
||||
fprintf(stderr, "%s: libhal_ctx_set_dbus_connection failed\n",
|
||||
__FUNCTION__);
|
||||
@@ -0,0 +1,109 @@
|
||||
diff -rup libvirt-0.6.0.orig/src/qemu_driver.c libvirt-0.6.0.new/src/qemu_driver.c
|
||||
--- libvirt-0.6.0.orig/src/qemu_driver.c 2009-01-31 09:04:18.000000000 +0000
|
||||
+++ libvirt-0.6.0.new/src/qemu_driver.c 2009-02-18 11:15:37.000000000 +0000
|
||||
@@ -633,6 +633,7 @@ qemudReadMonitorOutput(virConnectPtr con
|
||||
{
|
||||
int got = 0;
|
||||
buf[0] = '\0';
|
||||
+ timeout *= 1000; /* poll wants milli seconds */
|
||||
|
||||
/* Consume & discard the initial greeting */
|
||||
while (got < (buflen-1)) {
|
||||
@@ -694,6 +695,56 @@ qemudReadMonitorOutput(virConnectPtr con
|
||||
|
||||
}
|
||||
|
||||
+
|
||||
+/*
|
||||
+ * Returns -1 for error, 0 on success
|
||||
+ */
|
||||
+static int
|
||||
+qemudReadLogOutput(virConnectPtr conn,
|
||||
+ virDomainObjPtr vm,
|
||||
+ int fd,
|
||||
+ char *buf,
|
||||
+ int buflen,
|
||||
+ qemudHandlerMonitorOutput func,
|
||||
+ const char *what,
|
||||
+ int timeout)
|
||||
+{
|
||||
+ int got = 0;
|
||||
+ int ret;
|
||||
+ int retries = timeout*10;
|
||||
+ buf[0] = '\0';
|
||||
+
|
||||
+ while (retries) {
|
||||
+ while((ret = read(fd, buf+got, buflen-got-1)) > 0) {
|
||||
+ got += ret;
|
||||
+ buf[got] = '\0';
|
||||
+ if ((buflen-got-1) == 0) {
|
||||
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
+ _("Out of space while reading %s log output"), what);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ret < 0 && errno != EINTR) {
|
||||
+ virReportSystemError(conn, errno,
|
||||
+ _("Failure while reading %s log output"),
|
||||
+ what);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ret = func(conn, vm, buf, fd);
|
||||
+ if (ret <= 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ usleep(100*1000);
|
||||
+ retries--;
|
||||
+ }
|
||||
+ if (retries == 0)
|
||||
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
+ _("Timed out while reading %s log output"), what);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr vm,
|
||||
@@ -738,7 +789,7 @@ static int qemudOpenMonitor(virConnectPt
|
||||
vm, monfd,
|
||||
buf, sizeof(buf),
|
||||
qemudCheckMonitorPrompt,
|
||||
- "monitor", 10000) <= 0)
|
||||
+ "monitor", 10) <= 0)
|
||||
ret = -1;
|
||||
else
|
||||
ret = 0;
|
||||
@@ -770,6 +821,7 @@ static int qemudOpenMonitor(virConnectPt
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* Returns -1 for error, 0 success, 1 continue reading */
|
||||
static int qemudExtractMonitorPath(virConnectPtr conn,
|
||||
const char *haystack,
|
||||
size_t *offset,
|
||||
@@ -873,19 +925,16 @@ static int qemudWaitForMonitor(virConnec
|
||||
< 0)
|
||||
return -1;
|
||||
|
||||
- ret = qemudReadMonitorOutput(conn, vm, logfd, buf, sizeof(buf),
|
||||
- qemudFindCharDevicePTYs,
|
||||
- "console", 3000);
|
||||
+ ret = qemudReadLogOutput(conn, vm, logfd, buf, sizeof(buf),
|
||||
+ qemudFindCharDevicePTYs,
|
||||
+ "console", 3);
|
||||
if (close(logfd) < 0)
|
||||
qemudLog(QEMUD_WARN, _("Unable to close logfile: %s\n"),
|
||||
strerror(errno));
|
||||
|
||||
- if (ret == 1) /* Success */
|
||||
+ if (ret == 0) /* success */
|
||||
return 0;
|
||||
|
||||
- if (ret == -1)
|
||||
- return -1;
|
||||
-
|
||||
/* Unexpected end of file - inform user of QEMU log data */
|
||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
_("unable to start guest: %s"), buf);
|
||||
@@ -0,0 +1,124 @@
|
||||
diff -rup libvirt-0.6.0.orig/qemud/event.c libvirt-0.6.0.new/qemud/event.c
|
||||
--- libvirt-0.6.0.orig/qemud/event.c 2008-12-22 13:02:54.000000000 +0000
|
||||
+++ libvirt-0.6.0.new/qemud/event.c 2009-02-06 19:29:28.000000000 +0000
|
||||
@@ -68,6 +68,7 @@ struct virEventTimeout {
|
||||
/* State for the main event loop */
|
||||
struct virEventLoop {
|
||||
pthread_mutex_t lock;
|
||||
+ int running;
|
||||
pthread_t leader;
|
||||
int wakeupfd[2];
|
||||
int handlesCount;
|
||||
@@ -521,6 +522,7 @@ int virEventRunOnce(void) {
|
||||
int ret, timeout, nfds;
|
||||
|
||||
virEventLock();
|
||||
+ eventLoop.running = 1;
|
||||
eventLoop.leader = pthread_self();
|
||||
if ((nfds = virEventMakePollFDs(&fds)) < 0) {
|
||||
virEventUnlock();
|
||||
@@ -572,7 +574,7 @@ int virEventRunOnce(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
- eventLoop.leader = 0;
|
||||
+ eventLoop.running = 0;
|
||||
virEventUnlock();
|
||||
return 0;
|
||||
}
|
||||
@@ -611,7 +613,9 @@ int virEventInit(void)
|
||||
static int virEventInterruptLocked(void)
|
||||
{
|
||||
char c = '\0';
|
||||
- if (pthread_self() == eventLoop.leader)
|
||||
+
|
||||
+ if (!eventLoop.running ||
|
||||
+ pthread_self() == eventLoop.leader)
|
||||
return 0;
|
||||
|
||||
if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c))
|
||||
diff -rup libvirt-0.6.0.orig/qemud/qemud.c libvirt-0.6.0.new/qemud/qemud.c
|
||||
--- libvirt-0.6.0.orig/qemud/qemud.c 2009-01-31 09:04:17.000000000 +0000
|
||||
+++ libvirt-0.6.0.new/qemud/qemud.c 2009-02-06 19:29:28.000000000 +0000
|
||||
@@ -2013,11 +2013,15 @@ static int qemudOneLoop(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void qemudInactiveTimer(int timer ATTRIBUTE_UNUSED, void *data) {
|
||||
+static void qemudInactiveTimer(int timerid, void *data) {
|
||||
struct qemud_server *server = (struct qemud_server *)data;
|
||||
- DEBUG0("Got inactive timer expiry");
|
||||
- if (!virStateActive()) {
|
||||
- DEBUG0("No state active, shutting down");
|
||||
+
|
||||
+ if (virStateActive() ||
|
||||
+ server->clients) {
|
||||
+ DEBUG0("Timer expired but still active, not shutting down");
|
||||
+ virEventUpdateTimeoutImpl(timerid, -1);
|
||||
+ } else {
|
||||
+ DEBUG0("Timer expired and inactive, shutting down");
|
||||
server->shutdown = 1;
|
||||
}
|
||||
}
|
||||
@@ -2048,9 +2052,18 @@ static void qemudFreeClient(struct qemud
|
||||
static int qemudRunLoop(struct qemud_server *server) {
|
||||
int timerid = -1;
|
||||
int ret = -1, i;
|
||||
+ int timerActive = 0;
|
||||
|
||||
virMutexLock(&server->lock);
|
||||
|
||||
+ if (timeout > 0 &&
|
||||
+ (timerid = virEventAddTimeoutImpl(-1,
|
||||
+ qemudInactiveTimer,
|
||||
+ server, NULL)) < 0) {
|
||||
+ VIR_ERROR0(_("Failed to register shutdown timeout"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (min_workers > max_workers)
|
||||
max_workers = min_workers;
|
||||
|
||||
@@ -2071,11 +2084,21 @@ static int qemudRunLoop(struct qemud_ser
|
||||
* if any drivers have active state, if not
|
||||
* shutdown after timeout seconds
|
||||
*/
|
||||
- if (timeout > 0 && !virStateActive() && !server->clients) {
|
||||
- timerid = virEventAddTimeoutImpl(timeout*1000,
|
||||
- qemudInactiveTimer,
|
||||
- server, NULL);
|
||||
- DEBUG("Scheduling shutdown timer %d", timerid);
|
||||
+ if (timeout > 0) {
|
||||
+ if (timerActive) {
|
||||
+ if (server->clients) {
|
||||
+ DEBUG("Deactivating shutdown timer %d", timerid);
|
||||
+ virEventUpdateTimeoutImpl(timerid, -1);
|
||||
+ timerActive = 0;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (!virStateActive() &&
|
||||
+ !server->clients) {
|
||||
+ DEBUG("Activating shutdown timer %d", timerid);
|
||||
+ virEventUpdateTimeoutImpl(timerid, timeout * 1000);
|
||||
+ timerActive = 1;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
virMutexUnlock(&server->lock);
|
||||
@@ -2129,15 +2152,6 @@ static int qemudRunLoop(struct qemud_ser
|
||||
}
|
||||
}
|
||||
|
||||
- /* Unregister any timeout that's active, since we
|
||||
- * just had an event processed
|
||||
- */
|
||||
- if (timerid != -1) {
|
||||
- DEBUG("Removing shutdown timer %d", timerid);
|
||||
- virEventRemoveTimeoutImpl(timerid);
|
||||
- timerid = -1;
|
||||
- }
|
||||
-
|
||||
if (server->shutdown) {
|
||||
ret = 0;
|
||||
break;
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+305
-2295
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user