[libvirt] [PATCH v2 06/14] conf: virDomainObjListRemoveLocked function

Jim Fehlig jfehlig at suse.com
Wed Jul 3 20:50:33 UTC 2013


On 06/20/2013 10:24 AM, Marek Marczykowski-Górecki wrote:
> On 20.06.2013 17:34, Jim Fehlig wrote:
>> Marek Marczykowski-Górecki wrote:
>>> While iterating with virDomainObjListForEach it is safe to remove
>>> current element. But while iterating, 'doms' lock is already taken, so
>>> can't use standard virDomainObjListRemove. So introduce
>>> virDomainObjListRemoveLocked for this purpose.
>>>
>>> Changes in v2:
>>>   - fix indentation
>>>
>>> Signed-off-by: Marek Marczykowski-Górecki <marmarek at invisiblethingslab.com>
>>> ---
>>>   src/conf/domain_conf.c   | 17 +++++++++++++++++
>>>   src/conf/domain_conf.h   |  2 ++
>>>   src/libvirt_private.syms |  1 +
>>>   3 files changed, 20 insertions(+)
>>>
>>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>>> index 5350c56..a4010da 100644
>>> --- a/src/conf/domain_conf.c
>>> +++ b/src/conf/domain_conf.c
>>> @@ -2336,6 +2336,23 @@ void virDomainObjListRemove(virDomainObjListPtr doms,
>>>       virObjectUnlock(doms);
>>>   }
>>>   
>>> +/* The caller must hold lock on 'doms' in addition to 'virDomainObjListRemove'
>>> + * requirements
>>> + *
>>> + * Can be used to remove current element while iterating with
>>> + * virDomainObjListForEach
>>> + */
>>> +void virDomainObjListRemoveLocked(virDomainObjListPtr doms,
>>> +                                  virDomainObjPtr dom)
>>> +{
>>> +    char uuidstr[VIR_UUID_STRING_BUFLEN];
>>> +
>>> +    virUUIDFormat(dom->def->uuid, uuidstr);
>>> +    virObjectUnlock(dom);
>>> +
>>> +    virHashRemoveEntry(doms->objs, uuidstr);
>>>    
>> Peter fixed a race in virDomainObjListRemove with commit b7c98329, and
>> although this function expects the domain obj list to be locked on
>> entry, it still seems some aspect of the race might exist here.  Is it
>> possible for another thread to lock the dom and execute some code on it
>> after the freeing function has been triggered?
> The next patch uses it only in libxlReconnectDomain (at driver
> initialization), with driver lock hold whole the time from the vm object
> creation. So in this particular case no other thread can access this vm object.
>
> In general case I think it is still safe. The other thread need to have lock
> on 'doms' list to get access to 'dom' object. Because the caller also must
> have a lock on the list before a) getting lock on a 'dom' object, b) calling
> virDomainObjListRemoveLocked, it isn't possible for the other thread to access
> 'dom' object before caller release lock on the list.

Ah, I think I got it...

>
> Hmm, this description isn't clear... So let me try to enumerate calls:
> Thread A (which removes the entry from the list):
> 1. virObjectLock(doms)
> 2. virObjectLock(dom)
> 3. virDomainObjListRemoveLocked(doms, dom)
> 4.   virObjectUnlock(dom)
> 5.   virHashRemoveEntry
> 6. virObjectUnlock(doms)
>
> Above sequence can happen during virDomainObjListForEach.
>
> If thread B tries to get lock on dom object, it should call:
> 1. virObjectLock(doms) (e.g. as part of *Lookup function)
> 1a. (lookup here)
> 2. virObjectLock(dom)
>
> At no point thread B can get lock on 'doms' while thread A is in the middle of
> above code, so it can't reach dom object to get lock on it and use it. If
> thread B have lock on 'doms' or 'dom' before thread A starts above code,
> thread A will block until B finish.

and now I do, given the clarification.  Thanks.

This has been on the list for a while with no additional comments, so ACK and 
pushed.

Regards,
Jim




More information about the libvir-list mailing list