[libvirt] [PATCH v2 1/6] rpc: Fix deadlock if there is no worker pool available
Marc Hartmayer
mhartmay at linux.ibm.com
Fri Jul 20 07:32:38 UTC 2018
On Thu, Jul 19, 2018 at 04:51 PM +0200, John Ferlan <jferlan at redhat.com> wrote:
> On 07/03/2018 07:37 AM, Marc Hartmayer wrote:
>> @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 at linux.ibm.com>
>> Reviewed-by: Boris Fiuczynski <fiuczy at linux.ibm.com>
>> Reviewed-by: Bjoern Walk <bwalk at linux.ibm.com>
>> ---
>> src/rpc/virnetserver.c | 15 ++++++++++-----
>> 1 file changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
>> index 5c7f7dd08fe1..091e3ef23406 100644
>> --- a/src/rpc/virnetserver.c
>> +++ b/src/rpc/virnetserver.c
>> @@ -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,9 @@ static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
>> break;
>> }
>> }
>
> Should we grab an object reference then to avoid the chance that
> something disposes srv right after it's unlocked? And then Unref instead
> of Unlock later on?
>
> Following virThreadPoolSendJob finds that it'll grab the srv->workers
> pool mutex and check the quit flag before adding a job to and of course
> as you point out virNetServerProcessMsg would eventually assume that the
> server is unlocked in virNetServerProgramDispatchCall before calling
> dispatcher->func.
>
> With a Ref/Unref, I'd feel better and thus consider this,
Yep, I’m fine with that.
>
> Reviewed-by: John Ferlan <jferlan at redhat.com>
Thanks!
>
> John
>
>> + /* we can unlock @srv since @prog can only become invalid in case
>> + * of disposing @srv */
>> + virObjectUnlock(srv);
>>
>> if (srv->workers) {
>> virNetServerJobPtr job;
>> @@ -223,15 +229,14 @@ static void virNetServerDispatchNewMessage(virNetServerClientPtr client,
>> goto error;
>> }
>>
>> - virObjectUnlock(srv);
>> return;
>>
>> error:
>> virNetMessageFree(msg);
>> virNetServerClientClose(client);
>> - virObjectUnlock(srv);
>> }
>>
>> +
>> /**
>> * virNetServerCheckLimits:
>> * @srv: server to check limits on
>>
>
--
Beste Grüße / Kind regards
Marc Hartmayer
IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
More information about the libvir-list
mailing list