Implement vboxUniformedAPI for each vbox API version. Some common code and definitions are moved to vbox_common.c and vbox_uniformed_api.h. --- src/vbox/vbox_tmpl.c | 419 +++++++++++++++++++++++++++++--------------------- 1 file changed, 245 insertions(+), 174 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 4ba9ad7..7d01308 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -89,7 +89,7 @@ /* Include this *last* or we'll get the wrong vbox_CAPI_*.h. */ #include "vbox_glue.h" - +#include "vbox_uniformed_api.h" #define VIR_FROM_THIS VIR_FROM_VBOX @@ -189,7 +189,7 @@ if (strUtf16) {\ #define DEBUGUUID(msg, iid) \ {\ - VIR_DEBUG(msg ": {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",\ + VIR_DEBUG("%s: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", msg,\ (unsigned)(iid)->m0,\ (unsigned)(iid)->m1,\ (unsigned)(iid)->m2,\ @@ -203,42 +203,6 @@ if (strUtf16) {\ (unsigned)(iid)->m3[7]);\ }\ -typedef struct { - virMutex lock; - unsigned long version; - - virCapsPtr caps; - virDomainXMLOptionPtr xmlopt; - - IVirtualBox *vboxObj; - ISession *vboxSession; - - /** Our version specific API table pointer. */ - PCVBOXXPCOM pFuncs; - -#if VBOX_API_VERSION == 2002000 - -} vboxGlobalData; - -#else /* !(VBOX_API_VERSION == 2002000) */ - - /* Async event handling */ - virObjectEventStatePtr domainEvents; - int fdWatch; - -# if VBOX_API_VERSION <= 3002000 - /* IVirtualBoxCallback is used in VirtualBox 3.x only */ - IVirtualBoxCallback *vboxCallback; -# endif /* VBOX_API_VERSION <= 3002000 */ - - nsIEventQueue *vboxQueue; - int volatile vboxCallBackRefCount; - - /* pointer back to the connection */ - virConnectPtr conn; - -} vboxGlobalData; - /* g_pVBoxGlobalData has to be global variable, * there is no other way to make the callbacks * work other then having g_pVBoxGlobalData as @@ -249,6 +213,8 @@ typedef struct { * them that way */ +#if VBOX_API_VERSION > 2002000 + static vboxGlobalData *g_pVBoxGlobalData = NULL; #endif /* !(VBOX_API_VERSION == 2002000) */ @@ -386,13 +352,10 @@ static void nsIDFromChar(nsID *iid, const unsigned char *uuid) typedef struct _vboxIID_v2_x_WIN32 vboxIID; typedef struct _vboxIID_v2_x_WIN32 vboxIID_v2_x_WIN32; -struct _vboxIID_v2_x_WIN32 { - /* IID is represented by a GUID value. */ - GUID value; -}; - # define VBOX_IID_INITIALIZER { { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } } } +# define IIDU(name) (iidu->vboxIID_v2_x_WIN32.name) + static void vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED, vboxIID_v2_x_WIN32 *iid ATTRIBUTE_UNUSED) @@ -401,6 +364,13 @@ vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED, } static void +_vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED, + vboxIIDUnion *iid ATTRIBUTE_UNUSED) +{ + /* Nothing to free */ +} + +static void vboxIIDToUUID_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid, unsigned char *uuid) { nsIDtoChar(uuid, (nsID *)&iid->value); @@ -415,6 +385,13 @@ vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid, nsIDFromChar((nsID *)&iid->value, uuid); } +static void +_vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIIDUnion *iidu, + const unsigned char *uuid) +{ + vboxIIDFromUUID_v2_x_WIN32(data, &iidu->vboxIID_v2_x_WIN32, uuid); +} + static bool vboxIIDIsEqual_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid1, vboxIID_v2_x_WIN32 *iid2) { @@ -432,6 +409,7 @@ vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid, memcpy(&iid->value, &items[idx], sizeof(GUID)); } + # define vboxIIDUnalloc(iid) vboxIIDUnalloc_v2_x_WIN32(data, iid) # define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x_WIN32(iid, uuid) # define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v2_x_WIN32(data, iid, uuid) @@ -440,23 +418,16 @@ vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid, vboxIIDFromArrayItem_v2_x_WIN32(data, iid, array, idx) # define DEBUGIID(msg, iid) DEBUGUUID(msg, (nsID *)&(iid)) + # else /* !WIN32 */ typedef struct _vboxIID_v2_x vboxIID; typedef struct _vboxIID_v2_x vboxIID_v2_x; -struct _vboxIID_v2_x { - /* IID is represented by a pointer to a nsID. */ - nsID *value; - - /* backing is used in cases where we need to create or copy an IID. - * We cannot allocate memory that can be freed by ComUnallocMem. - * Therefore, we use this stack allocated nsID instead. */ - nsID backing; -}; - # define VBOX_IID_INITIALIZER { NULL, { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } } } +# define IIDU(name) (iidu->vboxIID_v2_x.name) + static void vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid) { @@ -472,6 +443,12 @@ vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid) } static void +_vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIIDUnion *iidu) +{ + vboxIIDUnalloc_v2_x(data, &iidu->vboxIID_v2_x); +} + +static void vboxIIDToUUID_v2_x(vboxIID_v2_x *iid, unsigned char *uuid) { nsIDtoChar(uuid, iid->value); @@ -489,6 +466,13 @@ vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid, nsIDFromChar(iid->value, uuid); } +static void +_vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIIDUnion *iidu, + const unsigned char *uuid) +{ + vboxIIDFromUUID_v2_x(data, &iidu->vboxIID_v2_x, uuid); +} + static bool vboxIIDIsEqual_v2_x(vboxIID_v2_x *iid1, vboxIID_v2_x *iid2) { @@ -506,6 +490,7 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid, memcpy(iid->value, array->items[idx], sizeof(nsID)); } + # define vboxIIDUnalloc(iid) vboxIIDUnalloc_v2_x(data, iid) # define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x(iid, uuid) # define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v2_x(data, iid, uuid) @@ -514,6 +499,7 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid, vboxIIDFromArrayItem_v2_x(data, iid, array, idx) # define DEBUGIID(msg, iid) DEBUGUUID(msg, iid) + # endif /* !WIN32 */ #else /* VBOX_API_VERSION != 2002000 */ @@ -521,16 +507,10 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid, typedef struct _vboxIID_v3_x vboxIID; typedef struct _vboxIID_v3_x vboxIID_v3_x; -struct _vboxIID_v3_x { - /* IID is represented by a UTF-16 encoded UUID in string form. */ - PRUnichar *value; - - /* owner indicates if we own the value and need to free it. */ - bool owner; -}; - # define VBOX_IID_INITIALIZER { NULL, true } +# define IIDU(name) (iidu->vboxIID_v3_x.name) + static void vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid) { @@ -543,6 +523,12 @@ vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid) } static void +_vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIIDUnion *iidu) +{ + vboxIIDUnalloc_v3_x(data, &iidu->vboxIID_v3_x); +} + +static void vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid, unsigned char *uuid) { @@ -568,6 +554,13 @@ vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid, data->pFuncs->pfnUtf8ToUtf16(utf8, &iid->value); } +static void +_vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIIDUnion *iidu, + const unsigned char *uuid) +{ + vboxIIDFromUUID_v3_x(data, &iidu->vboxIID_v3_x, uuid); +} + static bool vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1, vboxIID_v3_x *iid2) @@ -606,6 +599,7 @@ vboxIIDFromArrayItem_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid, vboxIIDFromArrayItem_v3_x(data, iid, array, idx) # define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16) + # if VBOX_API_VERSION >= 3001000 /** @@ -826,6 +820,196 @@ static PRUnichar *PRUnicharFromInt(int n) { #endif /* !(VBOX_API_VERSION == 2002000) */ +/* Begin of vboxUniformedAPI */ + +static int _pfnInitialize(vboxGlobalData *data) +{ + data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION); + if (data->pFuncs == NULL) + return -1; +#if VBOX_XPCOMC_VERSION == 0x00010000U + data->pFuncs->pfnComInitialize(&data->vboxObj, &data->vboxSession); +#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */ + data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj, ISESSION_IID_STR, &data->vboxSession); +#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */ + return 0; +} + +static int +_initializeFWatch(vboxGlobalData *data ATTRIBUTE_UNUSED) +{ +#if (VBOX_XPCOMC_VERSION == 0x00010000U) || (VBOX_API_VERSION == 2002000) + /* No event queue functionality in 2.2.* as of now */ + VIR_WARN("There is no fWatch initical in current version"); +#else /* (VBOX_XPCOMC_VERSION != 0x00010000U && VBOX_API_VERSION != 2002000) */ + /* Initialize the fWatch needed for Event Callbacks */ + data->fdWatch = -1; + data->pFuncs->pfnGetEventQueue(&data->vboxQueue); + if (data->vboxQueue == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("nsIEventQueue object is null")); + return -1; + } +#endif /* (VBOX_XPCOMC_VERSION != 0x00010000U && VBOX_API_VERSION != 2002000) */ + return 0; +} + +static nsresult +_sessionGetConsole(ISession *session, IConsole **console) +{ + return session->vtbl->GetConsole(session, console); +} + +static nsresult +_consoleSaveState(IConsole *console, IProgress **progress) +{ + return console->vtbl->SaveState(console, progress); +} + +static nsresult +_progressWaitForCompletion(IProgress *progress, PRInt32 timeout) +{ + return progress->vtbl->WaitForCompletion(progress, timeout); +} + +static nsresult _nsisupportsRelease(void *Ihandle) +{ + /* It is safety to convert a pointer from IVirtual(or structs + * like this) to nsISupports*/ + nsISupports *nsi = (nsISupports *)Ihandle; + return nsi->vtbl->Release(nsi); +} + +#if VBOX_API_VERSION == 2002000 + +static nsresult +_progressGetResultCode(IProgress *progress, resultCodeUnion *resultCode) +{ + return progress->vtbl->GetResultCode(progress, &resultCode->uResultCode); +} + +static void _initializeVboxIID(vboxIIDUnion *iidu) +{ + memset(iidu, 0, sizeof(vboxIIDUnion)); +} + +static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu) +{ +# ifdef WIN32 + DEBUGUUID(msg, (nsID *)&IIDU(value)); +# else /* !WIN32 */ + DEBUGUUID(msg, IIDU(value)); +# endif /* !WIN32 */ +} + +#else /* VBOX_API_VERSION != 2002000 */ + +static nsresult +_progressGetResultCode(IProgress *progress, resultCodeUnion *resultCode) +{ + return progress->vtbl->GetResultCode(progress, &resultCode->resultCode); +} + +static void _initializeVboxIID(vboxIIDUnion *iidu) +{ + memset(iidu, 0, sizeof(vboxIIDUnion)); + IIDU(owner) = true; +} + +static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu) +{ + DEBUGPRUnichar(msg, IIDU(value)); +} + +#endif /* VBOX_API_VERSION != 2002000 */ + +#if VBOX_API_VERSION < 4000000 + +static nsresult +_objectGetMachine(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine **machine) +{ + return data->vboxObj->vtbl->GetMachine(data->vboxObj, IIDU(value), machine); +} + +static nsresult +_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine *machine ATTRIBUTE_UNUSED) +{ + return data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, IIDU(value)); +} + +static nsresult +_sessionClose(ISession *session) +{ + return session->vtbl->Close(session); +} + +#else /* VBOX_API_VERSION >= 4000000 */ + +static nsresult +_objectGetMachine(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine **machine) +{ + return data->vboxObj->vtbl->FindMachine(data->vboxObj, IIDU(value), machine); +} + +static nsresult +_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu ATTRIBUTE_UNUSED, IMachine *machine) +{ + return machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Shared); +} + +static nsresult +_sessionClose(ISession *session) +{ + return session->vtbl->UnlockMachine(session); +} + +#endif /* VBOX_API_VERSION >= 4000000 */ + +vboxUniformedAPI NAME(UniformedAPI) = { + .APIVersion = VBOX_API_VERSION, + .XPCOMCVersion = VBOX_XPCOMC_VERSION, + .pfnInitialize = _pfnInitialize, + .initializeFWatch = _initializeFWatch, + .initializeVboxIID = _initializeVboxIID, + .objectGetMachine = _objectGetMachine, + .sessionOpenExisting = _sessionOpenExisting, + .sessionClose = _sessionClose, + .sessionGetConsole = _sessionGetConsole, + .consoleSaveState = _consoleSaveState, + .progressWaitForCompletion = _progressWaitForCompletion, + .progressGetResultCode = _progressGetResultCode, + .nsisupportsRelease = _nsisupportsRelease, +#if VBOX_API_VERSION == 2002000 +# ifdef WIN32 + .vboxIIDUnalloc = _vboxIIDUnalloc_v2_x_WIN32, + .vboxIIDFromUUID = _vboxIIDFromUUID_v2_x_WIN32, +# else /* !WIN32 */ + .vboxIIDUnalloc = _vboxIIDUnalloc_v2_x, + .vboxIIDFromUUID = _vboxIIDFromUUID_v2_x, +# endif /* !WIN32 */ +#else /* VBOX_API_VERSION != 2002000 */ + .vboxIIDUnalloc = _vboxIIDUnalloc_v3_x, + .vboxIIDFromUUID = _vboxIIDFromUUID_v3_x, +#endif /* VBOX_API_VERSION != 2002000 */ + .DEBUGIID = _DEBUGIID, + +#if (VBOX_XPCOMC_VERSION == 0x00010000U) || (VBOX_API_VERSION == 2002000) + /* No event queue functionality in 2.2.* as of now */ + .fWatchNeedInitialize = 0, +#else /* (VBOX_XPCOMC_VERSION != 0x00010000U && VBOX_API_VERSION != 2002000) */ + .fWatchNeedInitialize = 1, +#endif /* (VBOX_XPCOMC_VERSION != 0x00010000U && VBOX_API_VERSION != 2002000) */ + +#if VBOX_API_VERSION >= 4000000 + /* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */ + .getMachineForSession = 1, +#else /* VBOX_API_VERSION < 4000000 */ + .getMachineForSession = 0, +#endif /* VBOX_API_VERSION < 4000000 */ +}; + +/* End of vboxUniformedAPI and Begin of common codes */ + static PRUnichar * vboxSocketFormatAddrUtf16(vboxGlobalData *data, virSocketAddrPtr addr) { @@ -915,58 +1099,6 @@ static virCapsPtr vboxCapsInit(void) return NULL; } -static int -vboxInitialize(vboxGlobalData *data) -{ - data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION); - - if (data->pFuncs == NULL) - goto cleanup; - -#if VBOX_XPCOMC_VERSION == 0x00010000U - data->pFuncs->pfnComInitialize(&data->vboxObj, &data->vboxSession); -#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */ - data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj, - ISESSION_IID_STR, &data->vboxSession); - -# if VBOX_API_VERSION == 2002000 - - /* No event queue functionality in 2.2.* as of now */ - -# else /* !(VBOX_API_VERSION == 2002000) */ - - /* Initial the fWatch needed for Event Callbacks */ - data->fdWatch = -1; - - data->pFuncs->pfnGetEventQueue(&data->vboxQueue); - - if (data->vboxQueue == NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("nsIEventQueue object is null")); - goto cleanup; - } - -# endif /* !(VBOX_API_VERSION == 2002000) */ -#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */ - - if (data->vboxObj == NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("IVirtualBox object is null")); - goto cleanup; - } - - if (data->vboxSession == NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ISession object is null")); - goto cleanup; - } - - return 0; - - cleanup: - return -1; -} - static int vboxExtractVersion(vboxGlobalData *data) { int ret = -1; @@ -2093,67 +2225,6 @@ vboxDomainGetState(virDomainPtr dom, return ret; } -static int vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED) -{ - VBOX_OBJECT_CHECK(dom->conn, int, -1); - IConsole *console = NULL; - vboxIID iid = VBOX_IID_INITIALIZER; - IMachine *machine = NULL; - nsresult rc; - - /* VirtualBox currently doesn't support saving to a file - * at a location other then the machine folder and thus - * setting path to ATTRIBUTE_UNUSED for now, will change - * this behaviour once get the VirtualBox API in right - * shape to do this - */ - - /* Open a Session for the machine */ - vboxIIDFromUUID(&iid, dom->uuid); -#if VBOX_API_VERSION >= 4000000 - /* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */ - rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine); - if (NS_FAILED(rc)) { - virReportError(VIR_ERR_NO_DOMAIN, "%s", - _("no domain with matching uuid")); - return -1; - } -#endif - - rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine); - if (NS_SUCCEEDED(rc)) { - rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console); - if (NS_SUCCEEDED(rc) && console) { - IProgress *progress = NULL; - - console->vtbl->SaveState(console, &progress); - - if (progress) { -#if VBOX_API_VERSION == 2002000 - nsresult resultCode; -#else - PRInt32 resultCode; -#endif - - progress->vtbl->WaitForCompletion(progress, -1); - progress->vtbl->GetResultCode(progress, &resultCode); - if (NS_SUCCEEDED(resultCode)) { - ret = 0; - } - VBOX_RELEASE(progress); - } - VBOX_RELEASE(console); - } - VBOX_SESSION_CLOSE(); - } - - DEBUGIID("UUID of machine being saved:", iid.value); - - VBOX_RELEASE(machine); - vboxIIDUnalloc(&iid); - return ret; -} - static int vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, unsigned int flags) -- 1.7.9.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list