virnetdaemon: Don't deadlock when talking to D-Bus

https://bugzilla.redhat.com/show_bug.cgi?id=1487322

In ace45e67ab 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>
This commit is contained in:
Michal Privoznik 2017-09-01 10:33:12 +02:00
parent 9820756cd3
commit 054c6d2721

View 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,