]> xenbits.xensource.com Git - libvirt.git/commitdiff
virnetdaemon: Don't deadlock when talking to D-Bus
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 1 Sep 2017 08:33:12 +0000 (10:33 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 1 Sep 2017 11:21:33 +0000 (13:21 +0200)
https://bugzilla.redhat.com/show_bug.cgi?id=1487322

In ace45e67abbd I tried to fix a problem that we get the reply to
a D-Bus call while we were sleeping. In that case the callback
was never set. So I changed the code that the callback is called
directly in this case. However, I hadn't realized that since the
callback is called out of order it locks the virNetDaemon.
Exactly the very same virNetDaemon object that we are dealing
with right now and that we have locked already (in
virNetDaemonAddShutdownInhibition())

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/rpc/virnetdaemon.c

index 00247cfc363bcd2ac11d1b0d13ab7820d625a9e3..e3b9390af2e45d44cac22e7c6b4924fdd72ff621 100644 (file)
@@ -439,14 +439,12 @@ virNetDaemonAutoShutdown(virNetDaemonPtr dmn,
 
 #if defined(WITH_DBUS) && defined(DBUS_TYPE_UNIX_FD)
 static void
-virNetDaemonGotInhibitReply(DBusPendingCall *pending,
-                            void *opaque)
+virNetDaemonGotInhibitReplyLocked(DBusPendingCall *pending,
+                                  virNetDaemonPtr dmn)
 {
-    virNetDaemonPtr dmn = opaque;
     DBusMessage *reply;
     int fd;
 
-    virObjectLock(dmn);
     dmn->autoShutdownCallingInhibit = false;
 
     VIR_DEBUG("dmn=%p", dmn);
@@ -470,11 +468,22 @@ virNetDaemonGotInhibitReply(DBusPendingCall *pending,
     virDBusMessageUnref(reply);
 
  cleanup:
-    virObjectUnlock(dmn);
     dbus_pending_call_unref(pending);
 }
 
 
+static void
+virNetDaemonGotInhibitReply(DBusPendingCall *pending,
+                            void *opaque)
+{
+    virNetDaemonPtr dmn = opaque;
+
+    virObjectLock(dmn);
+    virNetDaemonGotInhibitReplyLocked(pending, dmn);
+    virObjectUnlock(dmn);
+}
+
+
 /* As per: http://www.freedesktop.org/wiki/Software/systemd/inhibit */
 static void
 virNetDaemonCallInhibit(virNetDaemonPtr dmn,
@@ -516,7 +525,7 @@ virNetDaemonCallInhibit(virNetDaemonPtr dmn,
                                         25 * 1000) &&
         pendingReply) {
         if (dbus_pending_call_get_completed(pendingReply)) {
-            virNetDaemonGotInhibitReply(pendingReply, dmn);
+            virNetDaemonGotInhibitReplyLocked(pendingReply, dmn);
         } else {
             dbus_pending_call_set_notify(pendingReply,
                                          virNetDaemonGotInhibitReply,