[libvirt] [PATCH 2/2] rpc: Fix segmentation fault when no worker pool is available

Marc Hartmayer mhartmay at linux.ibm.com
Mon Jun 18 10:38:06 UTC 2018


On Mon, Jun 18, 2018 at 09:47 AM +0200, Erik Skultety <eskultet at redhat.com> wrote:
> On Fri, Jun 15, 2018 at 03:31:34PM +0200, Marc Hartmayer wrote:
>> On Fri, Jun 15, 2018 at 01:39 PM +0200, Marc Hartmayer <mhartmay at linux.ibm.com> wrote:
>> > If srv->workers is a NULL pointer, as it is the case if there are no
>> > workers, then don't try to dereference it.
>> >
>> > Signed-off-by: Marc Hartmayer <mhartmay at linux.ibm.com>
>> > Reviewed-by: Boris Fiuczynski <fiuczy at linux.ibm.com>
>> > ---
>> >  src/rpc/virnetserver.c | 22 +++++++++++++++-------
>> >  1 file changed, 15 insertions(+), 7 deletions(-)
>> >
>> > diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
>> > index 5ae809e372..be6f610880 100644
>> > --- a/src/rpc/virnetserver.c
>> > +++ b/src/rpc/virnetserver.c
>> > @@ -933,13 +933,21 @@ virNetServerGetThreadPoolParameters(virNetServerPtr srv,
>> >                                      size_t *jobQueueDepth)
>> >  {
>> >      virObjectLock(srv);
>> > -
>> > -    *minWorkers = virThreadPoolGetMinWorkers(srv->workers);
>> > -    *maxWorkers = virThreadPoolGetMaxWorkers(srv->workers);
>> > -    *freeWorkers = virThreadPoolGetFreeWorkers(srv->workers);
>> > -    *nWorkers = virThreadPoolGetCurrentWorkers(srv->workers);
>> > -    *nPrioWorkers = virThreadPoolGetPriorityWorkers(srv->workers);
>> > -    *jobQueueDepth = virThreadPoolGetJobQueueDepth(srv->workers);
>> > +    if (srv->workers) {
>> > +        *minWorkers = virThreadPoolGetMinWorkers(srv->workers);
>> > +        *maxWorkers = virThreadPoolGetMaxWorkers(srv->workers);
>> > +        *freeWorkers = virThreadPoolGetFreeWorkers(srv->workers);
>> > +        *nWorkers = virThreadPoolGetCurrentWorkers(srv->workers);
>> > +        *nPrioWorkers = virThreadPoolGetPriorityWorkers(srv->workers);
>> > +        *jobQueueDepth = virThreadPoolGetJobQueueDepth(srv->workers);
>> > +    } else {
>> > +        *minWorkers = 0;
>> > +        *maxWorkers = 0;
>> > +        *freeWorkers = 0;
>> > +        *nWorkers = 0;
>> > +        *nPrioWorkers = 0;
>> > +        *jobQueueDepth = 0;
>> > +    }
>> >
>> >      virObjectUnlock(srv);
>> >      return 0;
>> > --
>> > 2.13.6
>>
>> After thinking again it probably makes more sense (and the code more
>> beautiful) to initialize the worker pool even for maxworker=0 (within
>
> I don't understand why should we do that.

Because right now there are several functionalities broken. Segmentation
faults in virNetServerGet/SetThreadPoolParameters, it’s not possible to
start with maxworkers=0 and then change it at runtime via
virNetServerSetThreadPoolParameters. Sure we can fix all these problems,
but then we’ve to introduce new code paths. Why can’t we just call
virThreadPoolNew(0, 0 , …)? This will only initialize the memory
structure of the pool and _no_ threads. The only change we’ve to do then
is to change the condition 'if (srv->workers)' of
'virNetServerDispatchNewMessage' to something like 'if
(virThreadPoolGetMaxWorkers(srv->workers) > 0)'.

> We don't even initialize it for
> libvirtd server - the implications are clear - you don't have workers, you
> don't get to process a job.

Yep. I don’t want to change that behavior either.

>
>> virNetServerNew) (=> we'll have to adapt virNetServerDispatchNewMessage
>> as well). BTW, there is also a segmentation fault in
>> virThreadPoolSetParameters… And currently it’s not possible to start
>> with maxworkers set to 0 and then increase it via
>
> Do I assume correctly that virNetServerDispatchNewMessage would allocate a new
> worker if there was a request to process but the threadpool was empty?

Do you mean with my proposed changes? Or without?

> If so, I
> don't see a reason to do that, why would anyone want to run with no
> workers?

Commit dff6d809fb6c851244ea07afd07f580d7320cc7a which actually
introduces this feature says:

“Allow RPC server to run single threaded

Refactor the RPC server dispatcher code so that if 'max_workers==0' the
entire server will run single threaded. This is useful for use cases
where there will only ever be 1 client connected which serializes its
requests”.

> They don't consume any resources, since they're waiting on a condition.
> However, any segfaults or deadlocks must be fixed, I'll have a look at the
> series as is, unless you've got a compelling reason why it's beneficial to run
> with no workers at all.

See the commit message above.

>
> Thanks,
> Erik
>

Thank you for looking at it.

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