From: Alexander Larsson <alexl@xxxxxxxxxx> When the session dies or when the system is going to be shut down we issue a virStateStop() call to instruct drivers to prepare to be stopped. This will remove any previously acquire inhibitions. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- daemon/libvirtd.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index b1b3ef7..40c411c 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 @@ -774,6 +779,65 @@ static void daemonInhibitCallback(bool inhibit, void *opaque) } +#ifdef HAVE_DBUS +static DBusConnection *sessionBus; +static DBusConnection *systemBus; + +static void daemonStopWorker(void *opaque) +{ + virNetServerPtr srv = opaque; + + VIR_DEBUG("Begin stop srv=%p", srv); + + ignore_value(virStateStop()); + + VIR_DEBUG("Completed stop srv=%p", srv); + + /* Exit libvirtd cleanly */ + virNetServerQuit(srv); +} + + +/* We do this in a thread to not block the main loop */ +static void daemonStop(virNetServerPtr srv) +{ + virThread thr; + virObjectRef(srv); + if (virThreadCreate(&thr, false, daemonStopWorker, srv) < 0) + virObjectUnref(srv); +} + + +static DBusHandlerResult handleSessionMessageFunc(DBusConnection *connection ATTRIBUTE_UNUSED, + DBusMessage *message, + void *opaque) +{ + virNetServerPtr srv = opaque; + + VIR_DEBUG("srv=%p", srv); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) + daemonStop(srv); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult handleSystemMessageFunc(DBusConnection *connection ATTRIBUTE_UNUSED, + DBusMessage *message, + void *opaque) +{ + virNetServerPtr srv = opaque; + + VIR_DEBUG("srv=%p", srv); + + if (dbus_message_is_signal(message, "org.freedesktop.login1.Manager", "PrepareForShutdown")) + daemonStop(srv); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} +#endif + + static void daemonRunStateInit(void *opaque) { virNetServerPtr srv = opaque; @@ -792,6 +856,26 @@ 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); + } + } +#endif + /* Only now accept clients from network */ virNetServerUpdateServices(srv, true); virObjectUnref(srv); -- 1.7.12.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list