rpc: Fix deadlock if there is no worker pool available

@srv must be unlocked for the call virNetServerProcessMsg otherwise a
deadlock can occur.

Since the pointer 'srv->workers' will never be changed after
initialization and the thread pool has it's own locking we can release
the lock of 'srv' earlier. This also fixes the deadlock.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Marc Hartmayer 2018-07-03 13:37:33 +02:00 committed by John Ferlan
parent 80250f70c5
commit 45e00c7f2d

View File

@ -51,6 +51,7 @@ struct _virNetServer {
char *name;
/* Immutable pointer, self-locking APIs */
virThreadPoolPtr workers;
char *mdnsGroupName;
@ -177,9 +178,11 @@ static void virNetServerHandleJob(void *jobOpaque, void *opaque)
VIR_FREE(job);
}
static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
virNetMessagePtr msg,
void *opaque)
static void
virNetServerDispatchNewMessage(virNetServerClientPtr client,
virNetMessagePtr msg,
void *opaque)
{
virNetServerPtr srv = opaque;
virNetServerProgramPtr prog = NULL;
@ -196,6 +199,11 @@ static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
break;
}
}
/* we can unlock @srv since @prog can only become invalid in case
* of disposing @srv, but let's grab a ref first to ensure nothing
* disposes of it before we use it. */
virObjectRef(srv);
virObjectUnlock(srv);
if (srv->workers) {
virNetServerJobPtr job;
@ -223,15 +231,16 @@ static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
goto error;
}
virObjectUnlock(srv);
virObjectUnref(srv);
return;
error:
virNetMessageFree(msg);
virNetServerClientClose(client);
virObjectUnlock(srv);
virObjectUnref(srv);
}
/**
* virNetServerCheckLimits:
* @srv: server to check limits on