This patch series solves vbox driver thread-safety issues where
libvird process would segfault when there was more than one concurrent
vbox connection. The reason for the segfault was because the original
implementation called pfnComInitialize/Unintialize on each
virConnectOpen/Close calls which were setting pointers to ISession and
IVirtualBox instances that were held by the global g_pVBoxGlobalData.
This caused new connection to overwrite the pointer created by the
prior connection.
Changes since v2 to address feedback in [1]:
* call uninitialize when vboxSdkInitialize or vboxExtractVersion fails.
* make sure to set the global vbox_driver pointer to NULL after
virObjectUnref releases last reference, to avoid segfaults when
VBOX_RELEASE is called in unintialize call.
* tested all possible failure paths to make sure libvirtd does not
crash, that is, vboxSdkInitialize has 4 code paths that can possibly
return -1 and made sure all of them are safely handled.
* fixed "unintilalize" typos in code comments and commit messages.
In other words, the change boils down to:
if (vboxSdkInitialize() < 0 || vboxExtractVersion() < 0) {
gVBoxAPI.UPFN.Uninitialize(vbox_driver); // call uninit on failure
/* make sure to clear the pointer when last reference was released */
if (!virObjectUnref(vbox_driver))
vbox_driver = NULL; // make sure this is NULL
virMutexUnlock(&vbox_driver_lock);
return NULL;
}
[1]
https://www.redhat.com/archives/libvir-list/2016-November/msg01132.html
Dawid Zamirski (2):
vbox: change how vbox API is initialized.
vbox: get rid of g_pVBoxGlobalData
src/vbox/vbox_common.c | 565 +++++++++++++++++++++++-------------------
src/vbox/vbox_common.h | 2 +-
src/vbox/vbox_driver.c | 1 +
src/vbox/vbox_network.c | 24 +-
src/vbox/vbox_storage.c | 20 +-
src/vbox/vbox_tmpl.c | 434 ++++++++++++++++----------------
src/vbox/vbox_uniformed_api.h | 110 ++++----
7 files changed, 616 insertions(+), 540 deletions(-)
--
2.9.3