[libvirt-users] Making the Thread-safety issues with vbox driver ?
Jean-Baptiste Rouault
jean-baptiste.rouault at diateam.net
Thu Apr 19 16:56:10 UTC 2012
On Thursday 19 April 2012 16:23:19 Matthias Bolte wrote:
> Am 19. April 2012 12:51 schrieb Jean-Baptiste Rouault
> >
> > A global mutex is needed in the vbox driver to protect access to
> > g_pVBoxGlobalData, the vboxRegister() function seems to be the best place
> > to initialize such a mutex unless there is another entry point to do
> > this ?
>
> Such a mutex doesn't help.
>
> Looking at g_pVBoxGlobalData tells me that we need to get rid of it in
> its current form for different reasons. The major reason is that it
> contains connection specific data such as the conn and domainEvents
> members. This means when you open a new connection you break all other
> open connections because connection specific data is overwritten. We
> need to redesign this.
>
> A major reason for the existence of g_pVBoxGlobalData is given in line
> 209 of vbox_tmpl.c: g_pVBoxGlobalData needs to be global because event
> callbacks won't work otherwise. Actually that's not true. Who ever did
> the original implementation of this was not aware of how COM (MS and
> XP variants) works.
>
> There is a vboxAllocCallbackObj function that creates an
> IVirtualBoxCallback COM object. The first member in a COM objects is a
> pointer to its vtbl that contains pointers to all the methods that can
> be called on it. After this vtbl the COM object contains its private
> data members, this aspect is not used in the current implementation.
>
> So we could just allocate a bigger object and put the data that
> belongs to the IVirtualBoxCallback implementation into this additional
> memory. This includes at least vboxCallBackRefCount and domainEvents
> that are currently located in g_pVBoxGlobalData.
>
> The only two members of g_pVBoxGlobalData that can stay global are
> caps and pFuncs, all other members are specific to a connection and
> cannot be global.
I'm not familiar with COM, but if all this connection-specific code can be
moved out it's nice.
> Are you referring to data->pFuncs->pfnComInitialize and
> data->pFuncs->pfnComUninitialize when you say "VirtualBox C bindings
> initialization and uninitialization functions"? As those are used to
> create connection specific objects we cannot move them out of
> vboxOpen/vboxClose. If they are not thread-safe than we need to put a
> global mutex around these calls.
Yes these two functions aren't thread-safe, it is even worse than that.
They are located in src/VBox/Main/cbinding/VBoxXPCOMC.cpp in the VirtualBox
source code. There are 4 static pointers which are replaced at each
pfnComInitialize call, and "released" (via the NS_RELEASE macro) in
pfnComUninitialize.
These accesses aren't protected at all, but what is worse is that when you
call pfnComUninitialize, the pointers to the IVirtualBox, ISession and
nsIEventQueue are released. So if you open multiple connections, then close
one of them, these objects are deleted and your last opened connection is
broken.
As you said, a global mutex is needed around these calls, but I think we
should also use the VBOX_ADDREF() macro on the IVirtualBox, ISession and
nsIEventQueue objects after pfnComInitialize, and VBOX_RELEASE() after
pfnComUninitialize.
--
Jean-Baptiste ROUAULT
Ingénieur R&D - diateam : Architectes de l'information
Phone : +33 (0)2 98 050 050 Fax : +33 (0)2 98 050 051
More information about the libvirt-users
mailing list