mirror of https://gitee.com/openkylin/libvirt.git
VBox add Storage Volume support
* src/vbox/vbox_driver.c src/vbox/vbox_tmpl.c: adds the driver for storage volumes
This commit is contained in:
parent
0cf672fa91
commit
6b50bbea00
|
@ -41,8 +41,10 @@
|
||||||
|
|
||||||
extern virDriver vbox22Driver;
|
extern virDriver vbox22Driver;
|
||||||
extern virNetworkDriver vbox22NetworkDriver;
|
extern virNetworkDriver vbox22NetworkDriver;
|
||||||
|
extern virStorageDriver vbox22StorageDriver;
|
||||||
extern virDriver vbox30Driver;
|
extern virDriver vbox30Driver;
|
||||||
extern virNetworkDriver vbox30NetworkDriver;
|
extern virNetworkDriver vbox30NetworkDriver;
|
||||||
|
extern virStorageDriver vbox30StorageDriver;
|
||||||
|
|
||||||
static virDriver vboxDriverDummy;
|
static virDriver vboxDriverDummy;
|
||||||
|
|
||||||
|
@ -55,6 +57,7 @@ static virDriver vboxDriverDummy;
|
||||||
int vboxRegister(void) {
|
int vboxRegister(void) {
|
||||||
virDriverPtr driver;
|
virDriverPtr driver;
|
||||||
virNetworkDriverPtr networkDriver;
|
virNetworkDriverPtr networkDriver;
|
||||||
|
virStorageDriverPtr storageDriver;
|
||||||
uint32_t uVersion;
|
uint32_t uVersion;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -65,6 +68,7 @@ int vboxRegister(void) {
|
||||||
*/
|
*/
|
||||||
driver = &vboxDriverDummy;
|
driver = &vboxDriverDummy;
|
||||||
networkDriver = &vbox22NetworkDriver;
|
networkDriver = &vbox22NetworkDriver;
|
||||||
|
storageDriver = &vbox22StorageDriver;
|
||||||
|
|
||||||
/* Init the glue and get the API version. */
|
/* Init the glue and get the API version. */
|
||||||
if (VBoxCGlueInit() == 0) {
|
if (VBoxCGlueInit() == 0) {
|
||||||
|
@ -83,10 +87,12 @@ int vboxRegister(void) {
|
||||||
DEBUG0("VirtualBox API version: 2.2");
|
DEBUG0("VirtualBox API version: 2.2");
|
||||||
driver = &vbox22Driver;
|
driver = &vbox22Driver;
|
||||||
networkDriver = &vbox22NetworkDriver;
|
networkDriver = &vbox22NetworkDriver;
|
||||||
|
storageDriver = &vbox22StorageDriver;
|
||||||
} else if (uVersion >= 2002051 && uVersion < 3000051) {
|
} else if (uVersion >= 2002051 && uVersion < 3000051) {
|
||||||
DEBUG0("VirtualBox API version: 3.0");
|
DEBUG0("VirtualBox API version: 3.0");
|
||||||
driver = &vbox30Driver;
|
driver = &vbox30Driver;
|
||||||
networkDriver = &vbox30NetworkDriver;
|
networkDriver = &vbox30NetworkDriver;
|
||||||
|
storageDriver = &vbox30StorageDriver;
|
||||||
} else {
|
} else {
|
||||||
DEBUG0("Unsupport VirtualBox API version");
|
DEBUG0("Unsupport VirtualBox API version");
|
||||||
}
|
}
|
||||||
|
@ -99,6 +105,8 @@ int vboxRegister(void) {
|
||||||
return -1;
|
return -1;
|
||||||
if (virRegisterNetworkDriver(networkDriver) < 0)
|
if (virRegisterNetworkDriver(networkDriver) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (virRegisterStorageDriver(storageDriver) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "network_conf.h"
|
#include "network_conf.h"
|
||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
#include "domain_event.h"
|
#include "domain_event.h"
|
||||||
|
#include "storage_conf.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
@ -159,6 +160,15 @@ static void vboxDriverUnlock(vboxGlobalData *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if VBOX_API_VERSION == 2002
|
#if VBOX_API_VERSION == 2002
|
||||||
|
|
||||||
|
#define vboxIIDFromUUID(uuid, iid) nsIDFromChar((iid), (uuid))
|
||||||
|
#define vboxIIDToUUID(uuid, iid) nsIDtoChar((uuid), (iid))
|
||||||
|
#define vboxIIDUnalloc(iid) data->pFuncs->pfnComUnallocMem(iid)
|
||||||
|
#define vboxIIDFree(iid) VIR_FREE(iid)
|
||||||
|
#define vboxIIDUtf8Free(iid) VIR_FREE(iid)
|
||||||
|
#define vboxIIDUtf16Free(iid) VIR_FREE(iid)
|
||||||
|
#define DEBUGIID(msg, iid) DEBUGUUID(msg, iid)
|
||||||
|
|
||||||
static void nsIDtoChar(unsigned char *uuid, const nsID *iid) {
|
static void nsIDtoChar(unsigned char *uuid, const nsID *iid) {
|
||||||
char uuidstrsrc[VIR_UUID_STRING_BUFLEN];
|
char uuidstrsrc[VIR_UUID_STRING_BUFLEN];
|
||||||
char uuidstrdst[VIR_UUID_STRING_BUFLEN];
|
char uuidstrdst[VIR_UUID_STRING_BUFLEN];
|
||||||
|
@ -241,16 +251,39 @@ static void nsIDFromChar(nsID *iid, const unsigned char *uuid) {
|
||||||
|
|
||||||
typedef nsID vboxIID;
|
typedef nsID vboxIID;
|
||||||
|
|
||||||
#define vboxIIDFromUUID(uuid, iid) nsIDFromChar((iid), (uuid))
|
static bool vboxIIDEqual(vboxIID *firstIID, vboxIID *secondIID) {
|
||||||
#define vboxIIDToUUID(uuid, iid) nsIDtoChar((uuid), (iid))
|
if (memcmp(firstIID, secondIID, sizeof(firstIID)) == 0)
|
||||||
#define vboxIIDUnalloc(iid) data->pFuncs->pfnComUnallocMem(iid)
|
return true;
|
||||||
#define vboxIIDFree(iid) VIR_FREE(iid)
|
else
|
||||||
#define DEBUGIID(msg, iid) DEBUGUUID(msg, iid)
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vboxIIDtoUtf8(virConnectPtr conn, vboxIID *iid, char **uuidstr) {
|
||||||
|
unsigned char hddUUID[VIR_UUID_BUFLEN];
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(*uuidstr, VIR_UUID_STRING_BUFLEN) < 0) {
|
||||||
|
virReportOOMError(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vboxIIDToUUID(hddUUID, iid);
|
||||||
|
virUUIDFormat(hddUUID, *uuidstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vboxUtf8toIID(virConnectPtr conn, char *uuidstr, vboxIID **iid) {
|
||||||
|
unsigned char hddUUID[VIR_UUID_BUFLEN];
|
||||||
|
|
||||||
|
if (VIR_ALLOC(*iid) < 0) {
|
||||||
|
virReportOOMError(conn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
virUUIDParse(uuidstr, hddUUID);
|
||||||
|
vboxIIDFromUUID(hddUUID, *iid);
|
||||||
|
}
|
||||||
|
|
||||||
#else /* !(VBOX_API_VERSION == 2002) */
|
#else /* !(VBOX_API_VERSION == 2002) */
|
||||||
|
|
||||||
typedef PRUnichar vboxIID;
|
|
||||||
|
|
||||||
#define vboxIIDFromUUID(uuid, iid)\
|
#define vboxIIDFromUUID(uuid, iid)\
|
||||||
{\
|
{\
|
||||||
char vboxIIDUtf8[VIR_UUID_STRING_BUFLEN];\
|
char vboxIIDUtf8[VIR_UUID_STRING_BUFLEN];\
|
||||||
|
@ -268,9 +301,56 @@ typedef PRUnichar vboxIID;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define vboxIIDFree(iid) data->pFuncs->pfnUtf16Free(iid)
|
#define vboxIIDFree(iid) data->pFuncs->pfnUtf16Free(iid)
|
||||||
|
#define vboxIIDUtf8Free(iid) data->pFuncs->pfnUtf8Free(iid)
|
||||||
|
#define vboxIIDUtf16Free(iid) data->pFuncs->pfnUtf16Free(iid)
|
||||||
#define vboxIIDUnalloc(iid) data->pFuncs->pfnUtf16Free(iid)
|
#define vboxIIDUnalloc(iid) data->pFuncs->pfnUtf16Free(iid)
|
||||||
#define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16)
|
#define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16)
|
||||||
|
|
||||||
|
typedef PRUnichar vboxIID;
|
||||||
|
|
||||||
|
static bool vboxIIDEqual(vboxIID *firstIID, vboxIID *secondIID) {
|
||||||
|
unsigned char firstUUID[VIR_UUID_BUFLEN];
|
||||||
|
unsigned char secondUUID[VIR_UUID_BUFLEN];
|
||||||
|
char *firstIIDUtf8 = NULL;
|
||||||
|
char *secondIIDUtf8 = NULL;
|
||||||
|
|
||||||
|
if (!g_pVBoxGlobalData)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(firstIID, &firstIIDUtf8);
|
||||||
|
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(secondIID, &secondIIDUtf8);
|
||||||
|
|
||||||
|
/* Note: we can't directly compare the utf8 strings here
|
||||||
|
* cause the two UUID's may have seperators as space or '-'
|
||||||
|
* or mixture of both and we don't want to fail here by
|
||||||
|
* using direct string comparison. Here virUUIDParse() takes
|
||||||
|
* care of these cases.
|
||||||
|
*/
|
||||||
|
|
||||||
|
virUUIDParse(firstIIDUtf8, firstUUID);
|
||||||
|
virUUIDParse(secondIIDUtf8, secondUUID);
|
||||||
|
|
||||||
|
g_pVBoxGlobalData->pFuncs->pfnUtf8Free(firstIIDUtf8);
|
||||||
|
g_pVBoxGlobalData->pFuncs->pfnUtf8Free(secondIIDUtf8);
|
||||||
|
|
||||||
|
if (memcmp(firstUUID, secondUUID, sizeof(firstIID)) == 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vboxIIDtoUtf8(virConnectPtr conn, vboxIID *iid, char **uuidstr) {
|
||||||
|
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(iid, uuidstr);
|
||||||
|
if (!(*uuidstr))
|
||||||
|
virReportOOMError(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vboxUtf8toIID(virConnectPtr conn, char *uuidstr, vboxIID **iid) {
|
||||||
|
g_pVBoxGlobalData->pFuncs->pfnUtf8ToUtf16(uuidstr, iid);
|
||||||
|
if (!(*iid))
|
||||||
|
virReportOOMError(conn);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !(VBOX_API_VERSION == 2002) */
|
#endif /* !(VBOX_API_VERSION == 2002) */
|
||||||
|
|
||||||
static virCapsPtr vboxCapsInit(void) {
|
static virCapsPtr vboxCapsInit(void) {
|
||||||
|
@ -5475,6 +5555,806 @@ cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Storage Functions here on
|
||||||
|
*/
|
||||||
|
|
||||||
|
static virDrvOpenStatus vboxStorageOpen (virConnectPtr conn,
|
||||||
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||||
|
int flags ATTRIBUTE_UNUSED) {
|
||||||
|
vboxGlobalData *data = conn->privateData;
|
||||||
|
|
||||||
|
if (STRNEQ(conn->driver->name, "VBOX"))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((data->pFuncs == NULL) ||
|
||||||
|
(data->vboxObj == NULL) ||
|
||||||
|
(data->vboxSession == NULL))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
DEBUG0("vbox storage intialized");
|
||||||
|
/* conn->storagePrivateData = some storage specific data */
|
||||||
|
return VIR_DRV_OPEN_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return VIR_DRV_OPEN_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vboxStorageClose (virConnectPtr conn) {
|
||||||
|
DEBUG0("vbox storage unintialized");
|
||||||
|
conn->storagePrivateData = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vboxStorageNumOfPools(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
||||||
|
|
||||||
|
/** Currently only one pool supported, the default one
|
||||||
|
* given by ISystemProperties::defaultHardDiskFolder()
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vboxStorageListPools(virConnectPtr conn, char **const names, int nnames) {
|
||||||
|
int numActive = 0;
|
||||||
|
|
||||||
|
if (nnames == 1) {
|
||||||
|
names[numActive] = strdup("default-pool");
|
||||||
|
if (names[numActive] == NULL) {
|
||||||
|
virReportOOMError(conn);
|
||||||
|
} else {
|
||||||
|
numActive++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virStoragePoolPtr vboxStoragePoolLookupByName(virConnectPtr conn, const char *name) {
|
||||||
|
virStoragePoolPtr ret = NULL;
|
||||||
|
|
||||||
|
/** Current limitation of the function: since
|
||||||
|
* the default pool doesn't have UUID just assign
|
||||||
|
* one till vbox can handle pools
|
||||||
|
*/
|
||||||
|
if (STREQ("default-pool", name)) {
|
||||||
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
|
const char *uuidstr = "1deff1ff-1481-464f-967f-a50fe8936cc4";
|
||||||
|
|
||||||
|
virUUIDParse(uuidstr, uuid);
|
||||||
|
|
||||||
|
ret = virGetStoragePool(conn, name, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vboxStoragePoolNumOfVolumes(virStoragePoolPtr pool) {
|
||||||
|
vboxGlobalData *data = pool->conn->privateData;
|
||||||
|
IHardDisk **hardDisks = NULL;
|
||||||
|
PRUint32 hardDiskCount = 0;
|
||||||
|
PRUint32 hardDiskAccessible = 0;
|
||||||
|
nsresult rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(data->vboxObj) {
|
||||||
|
rc = data->vboxObj->vtbl->GetHardDisks(data->vboxObj, &hardDiskCount, &hardDisks);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
for (i = 0; i < hardDiskCount; ++i) {
|
||||||
|
IHardDisk *hardDisk = hardDisks[i];
|
||||||
|
if (hardDisk) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (hddstate != MediaState_Inaccessible)
|
||||||
|
hardDiskAccessible++;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hardDiskCount = 0;
|
||||||
|
} else {
|
||||||
|
hardDiskCount = -1;
|
||||||
|
vboxError(pool->conn, VIR_ERR_INTERNAL_ERROR,"%s:%s, rc=%08x",
|
||||||
|
"could not get number of volumes in the pool",
|
||||||
|
pool->name, (unsigned)rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hardDiskAccessible)
|
||||||
|
return hardDiskAccessible;
|
||||||
|
else
|
||||||
|
return hardDiskCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vboxStoragePoolListVolumes(virStoragePoolPtr pool, char **const names, int nnames) {
|
||||||
|
vboxGlobalData *data = pool->conn->privateData;
|
||||||
|
IHardDisk **hardDisks = NULL;
|
||||||
|
PRUint32 hardDiskCount = 0;
|
||||||
|
PRUint32 numActive = 0;
|
||||||
|
nsresult rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(data->vboxObj) {
|
||||||
|
rc = data->vboxObj->vtbl->GetHardDisks(data->vboxObj, &hardDiskCount, &hardDisks);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
for (i = 0; i < hardDiskCount && numActive < nnames; ++i) {
|
||||||
|
IHardDisk *hardDisk = hardDisks[i];
|
||||||
|
|
||||||
|
if (hardDisk) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (hddstate != MediaState_Inaccessible) {
|
||||||
|
char *nameUtf8 = NULL;
|
||||||
|
PRUnichar *nameUtf16 = NULL;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetName((IMedium *)hardDisk, &nameUtf16);
|
||||||
|
data->pFuncs->pfnUtf16ToUtf8(nameUtf16, &nameUtf8);
|
||||||
|
|
||||||
|
if (nameUtf8) {
|
||||||
|
DEBUG("nnames[%d]: %s", numActive, nameUtf8);
|
||||||
|
names[numActive] = strdup(nameUtf8);
|
||||||
|
if (names[numActive] == NULL) {
|
||||||
|
virReportOOMError(pool->conn);
|
||||||
|
} else {
|
||||||
|
numActive++;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf8Free(nameUtf8);
|
||||||
|
}
|
||||||
|
data->pFuncs->pfnUtf16Free(nameUtf16);
|
||||||
|
}
|
||||||
|
hardDisk->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hardDiskCount = 0;
|
||||||
|
} else {
|
||||||
|
hardDiskCount = -1;
|
||||||
|
vboxError(pool->conn, VIR_ERR_INTERNAL_ERROR,"%s:%s, rc=%08x",
|
||||||
|
"could not get the volume list in the pool",
|
||||||
|
pool->name, (unsigned)rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numActive)
|
||||||
|
return numActive;
|
||||||
|
else
|
||||||
|
return hardDiskCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virStorageVolPtr vboxStorageVolLookupByName(virStoragePoolPtr pool, const char *name) {
|
||||||
|
vboxGlobalData *data = pool->conn->privateData;
|
||||||
|
IHardDisk **hardDisks = NULL;
|
||||||
|
virStorageVolPtr ret = NULL;
|
||||||
|
PRUint32 hardDiskCount = 0;
|
||||||
|
nsresult rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(data->vboxObj && name) {
|
||||||
|
rc = data->vboxObj->vtbl->GetHardDisks(data->vboxObj, &hardDiskCount, &hardDisks);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
for (i = 0; i < hardDiskCount; ++i) {
|
||||||
|
IHardDisk *hardDisk = hardDisks[i];
|
||||||
|
|
||||||
|
if (hardDisk) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (hddstate != MediaState_Inaccessible) {
|
||||||
|
char *nameUtf8 = NULL;
|
||||||
|
PRUnichar *nameUtf16 = NULL;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetName((IMedium *)hardDisk, &nameUtf16);
|
||||||
|
|
||||||
|
if (nameUtf16) {
|
||||||
|
data->pFuncs->pfnUtf16ToUtf8(nameUtf16, &nameUtf8);
|
||||||
|
data->pFuncs->pfnUtf16Free(nameUtf16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameUtf8 && STREQ(nameUtf8, name)) {
|
||||||
|
vboxIID *hddIID = NULL;
|
||||||
|
char *hddIIDUtf8 = NULL;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetId((IMedium *)hardDisk, &hddIID);
|
||||||
|
|
||||||
|
if (hddIID) {
|
||||||
|
vboxIIDtoUtf8(pool->conn, hddIID, &hddIIDUtf8);
|
||||||
|
vboxIIDUnalloc(hddIID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hddIIDUtf8) {
|
||||||
|
|
||||||
|
ret = virGetStorageVol(pool->conn, pool->name, name, hddIIDUtf8);
|
||||||
|
|
||||||
|
DEBUG("virStorageVolPtr: %p", ret);
|
||||||
|
DEBUG("Storage Volume Name: %s", name);
|
||||||
|
DEBUG("Storage Volume key : %s", hddIIDUtf8);
|
||||||
|
DEBUG("Storage Volume Pool: %s", pool->name);
|
||||||
|
|
||||||
|
vboxIIDUtf8Free(hddIIDUtf8);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf8Free(nameUtf8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameUtf8)
|
||||||
|
data->pFuncs->pfnUtf8Free(nameUtf8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < hardDiskCount; ++i)
|
||||||
|
if (hardDisks[i])
|
||||||
|
hardDisks[i]->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virStorageVolPtr vboxStorageVolLookupByKey(virConnectPtr conn, const char *key) {
|
||||||
|
vboxGlobalData *data = conn->privateData;
|
||||||
|
vboxIID *hddIID = NULL;
|
||||||
|
IHardDisk *hardDisk = NULL;
|
||||||
|
virStorageVolPtr ret = NULL;
|
||||||
|
nsresult rc;
|
||||||
|
|
||||||
|
#if VBOX_API_VERSION == 2002
|
||||||
|
if (VIR_ALLOC(hddIID) < 0) {
|
||||||
|
virReportOOMError(conn);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data->vboxObj && key) {
|
||||||
|
unsigned char hddUUID[VIR_UUID_BUFLEN];
|
||||||
|
|
||||||
|
virUUIDParse(key, hddUUID);
|
||||||
|
vboxIIDFromUUID(hddUUID, hddIID);
|
||||||
|
{
|
||||||
|
#else /* VBOX_API_VERSION != 2002 */
|
||||||
|
if(data->vboxObj && key) {
|
||||||
|
data->pFuncs->pfnUtf8ToUtf16(key, &hddIID);
|
||||||
|
if (hddIID) {
|
||||||
|
#endif /* VBOX_API_VERSION != 2002 */
|
||||||
|
|
||||||
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID, &hardDisk);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (hddstate != MediaState_Inaccessible) {
|
||||||
|
PRUnichar *hddNameUtf16 = NULL;
|
||||||
|
char *hddNameUtf8 = NULL;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetName((IMedium *)hardDisk, &hddNameUtf16);
|
||||||
|
data->pFuncs->pfnUtf16ToUtf8(hddNameUtf16, &hddNameUtf8);
|
||||||
|
|
||||||
|
if (hddNameUtf8) {
|
||||||
|
if (vboxStorageNumOfPools(conn) == 1) {
|
||||||
|
ret = virGetStorageVol(conn, "default-pool", hddNameUtf8, key);
|
||||||
|
DEBUG("Storage Volume Pool: %s", "default-pool");
|
||||||
|
} else {
|
||||||
|
/* TODO: currently only one default pool and thus
|
||||||
|
* nothing here, change it when pools are supported
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("Storage Volume Name: %s", key);
|
||||||
|
DEBUG("Storage Volume key : %s", hddNameUtf8);
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf8Free(hddNameUtf8);
|
||||||
|
data->pFuncs->pfnUtf16Free(hddNameUtf16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if VBOX_API_VERSION == 2002
|
||||||
|
cleanup:
|
||||||
|
#endif
|
||||||
|
vboxIIDFree(hddIID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virStorageVolPtr vboxStorageVolLookupByPath(virConnectPtr conn, const char *path) {
|
||||||
|
vboxGlobalData *data = conn->privateData;
|
||||||
|
PRUnichar *hddPathUtf16 = NULL;
|
||||||
|
IHardDisk *hardDisk = NULL;
|
||||||
|
virStorageVolPtr ret = NULL;
|
||||||
|
nsresult rc;
|
||||||
|
|
||||||
|
if(data->vboxObj && path) {
|
||||||
|
data->pFuncs->pfnUtf8ToUtf16(path, &hddPathUtf16);
|
||||||
|
|
||||||
|
if (hddPathUtf16) {
|
||||||
|
rc = data->vboxObj->vtbl->FindHardDisk(data->vboxObj, hddPathUtf16, &hardDisk);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (hddstate != MediaState_Inaccessible) {
|
||||||
|
PRUnichar *hddNameUtf16 = NULL;
|
||||||
|
char *hddNameUtf8 = NULL;
|
||||||
|
vboxIID *hddIID = NULL;
|
||||||
|
char *hddIIDUtf8 = NULL;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetName((IMedium *)hardDisk, &hddNameUtf16);
|
||||||
|
hardDisk->vtbl->imedium.GetId((IMedium *)hardDisk, &hddIID);
|
||||||
|
|
||||||
|
if (hddNameUtf16) {
|
||||||
|
data->pFuncs->pfnUtf16ToUtf8(hddNameUtf16, &hddNameUtf8);
|
||||||
|
data->pFuncs->pfnUtf16Free(hddNameUtf16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hddIID) {
|
||||||
|
vboxIIDtoUtf8(conn, hddIID, &hddIIDUtf8);
|
||||||
|
vboxIIDUnalloc(hddIID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hddIIDUtf8 && hddNameUtf8) {
|
||||||
|
|
||||||
|
/* TODO: currently only one default pool and thus
|
||||||
|
* the check below, change it when pools are supported
|
||||||
|
*/
|
||||||
|
if (vboxStorageNumOfPools(conn) == 1)
|
||||||
|
ret = virGetStorageVol(conn, "default-pool", hddNameUtf8, hddIIDUtf8);
|
||||||
|
|
||||||
|
DEBUG("Storage Volume Pool: %s", "default-pool");
|
||||||
|
DEBUG("Storage Volume Name: %s", hddNameUtf8);
|
||||||
|
DEBUG("Storage Volume key : %s", hddIIDUtf8);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hddNameUtf8)
|
||||||
|
data->pFuncs->pfnUtf8Free(hddNameUtf8);
|
||||||
|
|
||||||
|
if (hddIIDUtf8)
|
||||||
|
vboxIIDUtf8Free(hddIIDUtf8);
|
||||||
|
}
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisk);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf16Free(hddPathUtf16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virStorageVolPtr vboxStorageVolCreateXML(virStoragePoolPtr pool,
|
||||||
|
const char *xml,
|
||||||
|
unsigned int flags ATTRIBUTE_UNUSED) {
|
||||||
|
vboxGlobalData *data = pool->conn->privateData;
|
||||||
|
virStorageVolPtr ret = NULL;
|
||||||
|
virStorageVolDefPtr def = NULL;
|
||||||
|
virStoragePoolDef poolDef;
|
||||||
|
nsresult rc;
|
||||||
|
|
||||||
|
/* since there is currently one default pool now
|
||||||
|
* and virStorageVolDefFormat() just checks it type
|
||||||
|
* so just assign it for now, change the behaviour
|
||||||
|
* when vbox supports pools.
|
||||||
|
*/
|
||||||
|
memset(&poolDef, 0, sizeof(poolDef));
|
||||||
|
poolDef.type = VIR_STORAGE_POOL_DIR;
|
||||||
|
|
||||||
|
if ((def = virStorageVolDefParseString(pool->conn, &poolDef, xml)) == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((data->vboxObj) && def->name && def->type == VIR_STORAGE_VOL_FILE) {
|
||||||
|
PRUnichar *hddFormatUtf16 = NULL;
|
||||||
|
PRUnichar *hddNameUtf16 = NULL;
|
||||||
|
|
||||||
|
/* TODO: for now only the vmdk, vpc and vdi type harddisk
|
||||||
|
* variants can be created, also since there is no vdi
|
||||||
|
* type in enum virStorageVolFormatFileSystem {} the default
|
||||||
|
* will be to create vdi if nothing is specified in
|
||||||
|
* def->target.format
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (def->target.format == VIR_STORAGE_VOL_FILE_VMDK) {
|
||||||
|
data->pFuncs->pfnUtf8ToUtf16("VMDK", &hddFormatUtf16);
|
||||||
|
} else if (def->target.format == VIR_STORAGE_VOL_FILE_VPC) {
|
||||||
|
data->pFuncs->pfnUtf8ToUtf16("VHD", &hddFormatUtf16);
|
||||||
|
} else {
|
||||||
|
data->pFuncs->pfnUtf8ToUtf16("VDI", &hddFormatUtf16);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf8ToUtf16(def->name, &hddNameUtf16);
|
||||||
|
|
||||||
|
if (hddFormatUtf16 && hddNameUtf16) {
|
||||||
|
IHardDisk *hardDisk = NULL;
|
||||||
|
|
||||||
|
rc = data->vboxObj->vtbl->CreateHardDisk(data->vboxObj, hddFormatUtf16, hddNameUtf16, &hardDisk);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
IProgress *progress = NULL;
|
||||||
|
PRUint64 logicalSize = def->capacity / 1024 / 1024;
|
||||||
|
PRUint32 variant = HardDiskVariant_Standard;
|
||||||
|
|
||||||
|
if (def->capacity == def->allocation)
|
||||||
|
variant = HardDiskVariant_Fixed;
|
||||||
|
|
||||||
|
rc = hardDisk->vtbl->CreateBaseStorage(hardDisk, logicalSize, variant, &progress);
|
||||||
|
if (NS_SUCCEEDED(rc) && progress) {
|
||||||
|
vboxIID *hddIID = NULL;
|
||||||
|
#if VBOX_API_VERSION == 2002
|
||||||
|
nsresult resultCode;
|
||||||
|
#else
|
||||||
|
PRInt32 resultCode;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
progress->vtbl->WaitForCompletion(progress, -1);
|
||||||
|
progress->vtbl->GetResultCode(progress, &resultCode);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(resultCode)) {
|
||||||
|
|
||||||
|
rc = hardDisk->vtbl->imedium.GetId((IMedium *)hardDisk, &hddIID);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
char *hddKey = NULL;
|
||||||
|
|
||||||
|
vboxIIDtoUtf8(pool->conn, hddIID, &hddKey);
|
||||||
|
|
||||||
|
if (hddKey)
|
||||||
|
ret = virGetStorageVol(pool->conn, pool->name, def->name, hddKey);
|
||||||
|
|
||||||
|
vboxIIDUtf8Free(hddKey);
|
||||||
|
vboxIIDUnalloc(hddIID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
progress->vtbl->nsisupports.Release((nsISupports *)progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hddFormatUtf16)
|
||||||
|
data->pFuncs->pfnUtf16Free(hddFormatUtf16);
|
||||||
|
if (hddNameUtf16)
|
||||||
|
data->pFuncs->pfnUtf16Free(hddNameUtf16);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virStorageVolDefFree(def);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int vboxStorageVolDelete(virStorageVolPtr vol,
|
||||||
|
unsigned int flags ATTRIBUTE_UNUSED) {
|
||||||
|
vboxGlobalData *data = vol->conn->privateData;
|
||||||
|
vboxIID *hddIID = NULL;
|
||||||
|
IHardDisk *hardDisk = NULL;
|
||||||
|
int ret = -1, i = 0, j = 0;
|
||||||
|
int deregister = 0;
|
||||||
|
nsresult rc;
|
||||||
|
|
||||||
|
if(data->vboxObj && vol->key) {
|
||||||
|
|
||||||
|
vboxUtf8toIID(vol->conn, vol->key, &hddIID);
|
||||||
|
if (hddIID) {
|
||||||
|
|
||||||
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID, &hardDisk);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (hddstate != MediaState_Inaccessible) {
|
||||||
|
PRUint32 machineIdsSize = 0;
|
||||||
|
vboxIID **machineIds = NULL;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetMachineIds((IMedium *)hardDisk, &machineIdsSize, &machineIds);
|
||||||
|
|
||||||
|
for (i = 0; i < machineIdsSize; i++) {
|
||||||
|
IMachine *machine = NULL;
|
||||||
|
|
||||||
|
rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, machineIds[i]);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
|
||||||
|
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
PRUint32 hddAttachSize = 0;
|
||||||
|
IHardDiskAttachment **hddAttachments = NULL;
|
||||||
|
|
||||||
|
machine->vtbl->GetHardDiskAttachments(machine, &hddAttachSize, &hddAttachments);
|
||||||
|
for (j = 0; j < hddAttachSize; j++) {
|
||||||
|
IHardDiskAttachment *hddAttachment = hddAttachments[j];
|
||||||
|
|
||||||
|
if (hddAttachment) {
|
||||||
|
IHardDisk *hdd = NULL;
|
||||||
|
|
||||||
|
rc = hddAttachment->vtbl->GetHardDisk(hddAttachment, &hdd);
|
||||||
|
if (NS_SUCCEEDED(rc) && hdd) {
|
||||||
|
vboxIID *iid = NULL;
|
||||||
|
|
||||||
|
hdd->vtbl->imedium.GetId((IMedium *)hdd, &iid);
|
||||||
|
if (iid) {
|
||||||
|
|
||||||
|
DEBUGIID("HardDisk (to delete) UUID", hddIID);
|
||||||
|
DEBUGIID("HardDisk (currently processing) UUID", iid);
|
||||||
|
|
||||||
|
if (vboxIIDEqual(hddIID, iid)) {
|
||||||
|
PRUnichar *controller = NULL;
|
||||||
|
PRInt32 port = 0;
|
||||||
|
PRInt32 device = 0;
|
||||||
|
|
||||||
|
DEBUGIID("Found HardDisk to delete, UUID", hddIID);
|
||||||
|
|
||||||
|
hddAttachment->vtbl->GetController(hddAttachment, &controller);
|
||||||
|
hddAttachment->vtbl->GetPort(hddAttachment, &port);
|
||||||
|
hddAttachment->vtbl->GetDevice(hddAttachment, &device);
|
||||||
|
|
||||||
|
rc = machine->vtbl->DetachHardDisk(machine, controller, port, device);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
rc = machine->vtbl->SaveSettings(machine);
|
||||||
|
DEBUG0("saving machine settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
deregister++;
|
||||||
|
DEBUG("deregistering hdd:%d", deregister);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controller)
|
||||||
|
data->pFuncs->pfnUtf16Free(controller);
|
||||||
|
}
|
||||||
|
vboxIIDUnalloc(iid);
|
||||||
|
}
|
||||||
|
hdd->vtbl->imedium.nsisupports.Release((nsISupports *)hdd);
|
||||||
|
}
|
||||||
|
hddAttachment->vtbl->nsisupports.Release((nsISupports *)hddAttachment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
machine->vtbl->nsisupports.Release((nsISupports *)machine);
|
||||||
|
}
|
||||||
|
data->vboxSession->vtbl->Close(data->vboxSession);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < machineIdsSize; i++)
|
||||||
|
if (machineIds[i])
|
||||||
|
vboxIIDUnalloc(machineIds[i]);
|
||||||
|
|
||||||
|
if (machineIdsSize == 0 || machineIdsSize == deregister) {
|
||||||
|
IProgress *progress = NULL;
|
||||||
|
|
||||||
|
rc = hardDisk->vtbl->DeleteStorage(hardDisk, &progress);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rc) && progress) {
|
||||||
|
progress->vtbl->WaitForCompletion(progress, -1);
|
||||||
|
progress->vtbl->nsisupports.Release((nsISupports *)progress);
|
||||||
|
DEBUGIID("HardDisk deleted, UUID", hddIID);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisk);
|
||||||
|
}
|
||||||
|
|
||||||
|
vboxIIDUtf16Free(hddIID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vboxStorageVolGetInfo(virStorageVolPtr vol, virStorageVolInfoPtr info) {
|
||||||
|
vboxGlobalData *data = vol->conn->privateData;
|
||||||
|
IHardDisk *hardDisk = NULL;
|
||||||
|
vboxIID *hddIID = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
nsresult rc;
|
||||||
|
|
||||||
|
if(data->vboxObj && vol->key && info) {
|
||||||
|
|
||||||
|
vboxUtf8toIID(vol->conn, vol->key, &hddIID);
|
||||||
|
if (hddIID) {
|
||||||
|
|
||||||
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID, &hardDisk);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (hddstate != MediaState_Inaccessible) {
|
||||||
|
PRUint32 hddType;
|
||||||
|
PRUint64 hddLogicalSize;
|
||||||
|
PRUint64 hddActualSize;
|
||||||
|
|
||||||
|
hardDisk->vtbl->GetType(hardDisk, &hddType);
|
||||||
|
if (hddType == HardDiskType_Writethrough)
|
||||||
|
info->type = VIR_STORAGE_VOL_BLOCK;
|
||||||
|
else
|
||||||
|
info->type = VIR_STORAGE_VOL_FILE;
|
||||||
|
|
||||||
|
hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
|
||||||
|
info->capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetSize((IMedium *)hardDisk, &hddActualSize);
|
||||||
|
info->allocation = hddActualSize;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
DEBUG("Storage Volume Name: %s", vol->name);
|
||||||
|
DEBUG("Storage Volume Type: %s", info->type == VIR_STORAGE_VOL_BLOCK ? "Block" : "File");
|
||||||
|
DEBUG("Storage Volume Capacity: %llu", info->capacity);
|
||||||
|
DEBUG("Storage Volume Allocation: %llu", info->allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisk);
|
||||||
|
}
|
||||||
|
|
||||||
|
vboxIIDUtf16Free(hddIID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags ATTRIBUTE_UNUSED) {
|
||||||
|
vboxGlobalData *data = vol->conn->privateData;
|
||||||
|
IHardDisk *hardDisk = NULL;
|
||||||
|
vboxIID *hddIID = NULL;
|
||||||
|
char *ret = NULL;
|
||||||
|
virStoragePoolDef pool;
|
||||||
|
virStorageVolDef def;
|
||||||
|
int defOk = 0;
|
||||||
|
nsresult rc;
|
||||||
|
|
||||||
|
memset(&pool, 0, sizeof(pool));
|
||||||
|
memset(&def, 0, sizeof(def));
|
||||||
|
|
||||||
|
if(data->vboxObj && vol->key) {
|
||||||
|
|
||||||
|
vboxUtf8toIID(vol->conn, vol->key, &hddIID);
|
||||||
|
if (hddIID) {
|
||||||
|
|
||||||
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID, &hardDisk);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
rc = hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (NS_SUCCEEDED(rc) && hddstate != MediaState_Inaccessible) {
|
||||||
|
PRUnichar *hddFormatUtf16 = NULL;
|
||||||
|
PRUint64 hddLogicalSize;
|
||||||
|
PRUint64 hddActualSize;
|
||||||
|
PRUint32 hddType;
|
||||||
|
|
||||||
|
/* since there is currently one default pool now
|
||||||
|
* and virStorageVolDefFormat() just checks it type
|
||||||
|
* so just assign it for now, change the behaviour
|
||||||
|
* when vbox supports pools.
|
||||||
|
*/
|
||||||
|
pool.type = VIR_STORAGE_POOL_DIR;
|
||||||
|
|
||||||
|
rc = hardDisk->vtbl->GetType(hardDisk, &hddType);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
if (hddType == HardDiskType_Writethrough)
|
||||||
|
def.type = VIR_STORAGE_VOL_BLOCK;
|
||||||
|
else
|
||||||
|
def.type = VIR_STORAGE_VOL_FILE;
|
||||||
|
defOk = 1;
|
||||||
|
} else {
|
||||||
|
defOk = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
|
||||||
|
if (NS_SUCCEEDED(rc) && defOk)
|
||||||
|
def.capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
|
||||||
|
else
|
||||||
|
defOk = 0;
|
||||||
|
|
||||||
|
rc = hardDisk->vtbl->imedium.GetSize((IMedium *)hardDisk, &hddActualSize);
|
||||||
|
if (NS_SUCCEEDED(rc) && defOk)
|
||||||
|
def.allocation = hddActualSize;
|
||||||
|
else
|
||||||
|
defOk = 0;
|
||||||
|
|
||||||
|
def.name = strdup(vol->name);
|
||||||
|
if (!(def.name && defOk))
|
||||||
|
defOk = 0;
|
||||||
|
|
||||||
|
def.key = strdup(vol->key);
|
||||||
|
if (!(def.key && defOk))
|
||||||
|
defOk = 0;
|
||||||
|
|
||||||
|
rc = hardDisk->vtbl->GetFormat(hardDisk, &hddFormatUtf16);
|
||||||
|
if (NS_SUCCEEDED(rc) && defOk) {
|
||||||
|
char *hddFormatUtf8 = NULL;
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf16ToUtf8(hddFormatUtf16, &hddFormatUtf8);
|
||||||
|
if (hddFormatUtf8) {
|
||||||
|
|
||||||
|
DEBUG("Storage Volume Format: %s", hddFormatUtf8);
|
||||||
|
|
||||||
|
if (STRCASEEQ("vmdk", hddFormatUtf8))
|
||||||
|
def.target.format = VIR_STORAGE_VOL_FILE_VMDK;
|
||||||
|
else if (STRCASEEQ("vhd", hddFormatUtf8))
|
||||||
|
def.target.format = VIR_STORAGE_VOL_FILE_VPC;
|
||||||
|
else
|
||||||
|
def.target.format = VIR_STORAGE_VOL_FILE_RAW;
|
||||||
|
|
||||||
|
/* TODO: need to add vdi to enum virStorageVolFormatFileSystem {}
|
||||||
|
* and then add it here
|
||||||
|
*/
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf8Free(hddFormatUtf8);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf16Free(hddFormatUtf16);
|
||||||
|
} else {
|
||||||
|
defOk = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisk);
|
||||||
|
}
|
||||||
|
|
||||||
|
vboxIIDUtf16Free(hddIID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defOk)
|
||||||
|
ret = virStorageVolDefFormat(vol->conn, &pool, &def);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *vboxStorageVolGetPath(virStorageVolPtr vol) {
|
||||||
|
vboxGlobalData *data = vol->conn->privateData;
|
||||||
|
IHardDisk *hardDisk = NULL;
|
||||||
|
vboxIID *hddIID = NULL;
|
||||||
|
char *ret = NULL;
|
||||||
|
nsresult rc;
|
||||||
|
|
||||||
|
if(data->vboxObj && vol->key) {
|
||||||
|
|
||||||
|
vboxUtf8toIID(vol->conn, vol->key, &hddIID);
|
||||||
|
if (hddIID) {
|
||||||
|
|
||||||
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID, &hardDisk);
|
||||||
|
if (NS_SUCCEEDED(rc)) {
|
||||||
|
PRUint32 hddstate;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetState((IMedium *)hardDisk, &hddstate);
|
||||||
|
if (hddstate != MediaState_Inaccessible) {
|
||||||
|
PRUnichar *hddLocationUtf16 = NULL;
|
||||||
|
char *hddLocationUtf8 = NULL;
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.GetLocation((IMedium *)hardDisk, &hddLocationUtf16);
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf16ToUtf8(hddLocationUtf16, &hddLocationUtf8);
|
||||||
|
if (hddLocationUtf8) {
|
||||||
|
|
||||||
|
ret = strdup(hddLocationUtf8);
|
||||||
|
if (!ret)
|
||||||
|
virReportOOMError(vol->conn);
|
||||||
|
|
||||||
|
DEBUG("Storage Volume Name: %s", vol->name);
|
||||||
|
DEBUG("Storage Volume Path: %s", hddLocationUtf8);
|
||||||
|
DEBUG("Storage Volume Pool: %s", vol->pool);
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf8Free(hddLocationUtf8);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pFuncs->pfnUtf16Free(hddLocationUtf16);
|
||||||
|
}
|
||||||
|
|
||||||
|
hardDisk->vtbl->imedium.nsisupports.Release((nsISupports *)hardDisk);
|
||||||
|
}
|
||||||
|
|
||||||
|
vboxIIDUtf16Free(hddIID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Tables
|
* Function Tables
|
||||||
|
@ -5576,3 +6456,41 @@ virNetworkDriver NAME(NetworkDriver) = {
|
||||||
.networkGetAutostart = NULL,
|
.networkGetAutostart = NULL,
|
||||||
.networkSetAutostart = NULL
|
.networkSetAutostart = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virStorageDriver NAME(StorageDriver) = {
|
||||||
|
.name = "VBOX",
|
||||||
|
.open = vboxStorageOpen,
|
||||||
|
.close = vboxStorageClose,
|
||||||
|
.numOfPools = vboxStorageNumOfPools,
|
||||||
|
.listPools = vboxStorageListPools,
|
||||||
|
.numOfDefinedPools = NULL,
|
||||||
|
.listDefinedPools = NULL,
|
||||||
|
.findPoolSources = NULL,
|
||||||
|
.poolLookupByName = vboxStoragePoolLookupByName,
|
||||||
|
.poolLookupByUUID = NULL,
|
||||||
|
.poolLookupByVolume = NULL,
|
||||||
|
.poolCreateXML = NULL,
|
||||||
|
.poolDefineXML = NULL,
|
||||||
|
.poolBuild = NULL,
|
||||||
|
.poolUndefine = NULL,
|
||||||
|
.poolCreate = NULL,
|
||||||
|
.poolDestroy = NULL,
|
||||||
|
.poolDelete = NULL,
|
||||||
|
.poolRefresh = NULL,
|
||||||
|
.poolGetInfo = NULL,
|
||||||
|
.poolGetXMLDesc = NULL,
|
||||||
|
.poolGetAutostart = NULL,
|
||||||
|
.poolSetAutostart = NULL,
|
||||||
|
.poolNumOfVolumes = vboxStoragePoolNumOfVolumes,
|
||||||
|
.poolListVolumes = vboxStoragePoolListVolumes,
|
||||||
|
|
||||||
|
.volLookupByName = vboxStorageVolLookupByName,
|
||||||
|
.volLookupByKey = vboxStorageVolLookupByKey,
|
||||||
|
.volLookupByPath = vboxStorageVolLookupByPath,
|
||||||
|
.volCreateXML = vboxStorageVolCreateXML,
|
||||||
|
.volCreateXMLFrom = NULL,
|
||||||
|
.volDelete = vboxStorageVolDelete,
|
||||||
|
.volGetInfo = vboxStorageVolGetInfo,
|
||||||
|
.volGetXMLDesc = vboxStorageVolGetXMLDesc,
|
||||||
|
.volGetPath = vboxStorageVolGetPath,
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue