static int vboxConnectListNetworks(virConnectPtr conn, char **const names, int nnames) { vboxDriverPtr data = conn->privateData; vboxArray networkInterfaces = VBOX_ARRAY_INITIALIZER; IHost *host = NULL; size_t i = 0; int ret = -1; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; gVBoxAPI.UArray.vboxArrayGet(&networkInterfaces, host, gVBoxAPI.UArray.handleHostGetNetworkInterfaces(host)); ret = 0; for (i = 0; (ret < nnames) && (i < networkInterfaces.count); i++) { IHostNetworkInterface *networkInterface = networkInterfaces.items[i]; char *nameUtf8 = NULL; PRUnichar *nameUtf16 = NULL; PRUint32 interfaceType = 0; PRUint32 status = HostNetworkInterfaceStatus_Unknown; if (!networkInterface) continue; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) continue; gVBoxAPI.UIHNInterface.GetStatus(networkInterface, &status); if (status != HostNetworkInterfaceStatus_Up) continue; gVBoxAPI.UIHNInterface.GetName(networkInterface, &nameUtf16); VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8); VIR_DEBUG("nnames[%d]: %s", ret, nameUtf8); if (VIR_STRDUP(names[ret], nameUtf8) >= 0) ret++; VBOX_UTF8_FREE(nameUtf8); VBOX_UTF16_FREE(nameUtf16); } gVBoxAPI.UArray.vboxArrayRelease(&networkInterfaces); VBOX_RELEASE(host); return ret; }
static int vboxStoragePoolListVolumes(virStoragePoolPtr pool, char **const names, int nnames) { vboxDriverPtr data = pool->conn->privateData; vboxArray hardDisks = VBOX_ARRAY_INITIALIZER; PRUint32 numActive = 0; nsresult rc; size_t i; int ret = -1; if (!data->vboxObj) return ret; rc = gVBoxAPI.UArray.vboxArrayGet(&hardDisks, data->vboxObj, gVBoxAPI.UArray.handleGetHardDisks(data->vboxObj)); if (NS_FAILED(rc)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("could not get the volume list in the pool: %s, rc=%08x"), pool->name, (unsigned)rc); return ret; } for (i = 0; i < hardDisks.count && numActive < nnames; ++i) { IMedium *hardDisk = hardDisks.items[i]; PRUint32 hddstate; char *nameUtf8 = NULL; PRUnichar *nameUtf16 = NULL; if (!hardDisk) continue; gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate); if (hddstate == MediaState_Inaccessible) continue; gVBoxAPI.UIMedium.GetName(hardDisk, &nameUtf16); VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8); VBOX_UTF16_FREE(nameUtf16); if (!nameUtf8) continue; VIR_DEBUG("nnames[%d]: %s", numActive, nameUtf8); if (VIR_STRDUP(names[numActive], nameUtf8) > 0) numActive++; VBOX_UTF8_FREE(nameUtf8); } gVBoxAPI.UArray.vboxArrayRelease(&hardDisks); ret = numActive; return ret; }
static char *vboxStorageVolGetPath(virStorageVolPtr vol) { vboxDriverPtr data = vol->conn->privateData; IMedium *hardDisk = NULL; PRUnichar *hddLocationUtf16 = NULL; char *hddLocationUtf8 = NULL; unsigned char uuid[VIR_UUID_BUFLEN]; vboxIID hddIID; PRUint32 hddstate; nsresult rc; char *ret = NULL; if (!data->vboxObj) return ret; if (virUUIDParse(vol->key, uuid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Could not parse UUID from '%s'"), vol->key); return ret; } VBOX_IID_INITIALIZE(&hddIID); vboxIIDFromUUID(&hddIID, uuid); rc = gVBoxAPI.UIVirtualBox.GetHardDiskByIID(data->vboxObj, &hddIID, &hardDisk); if (NS_FAILED(rc)) goto cleanup; gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate); if (hddstate == MediaState_Inaccessible) goto cleanup; gVBoxAPI.UIMedium.GetLocation(hardDisk, &hddLocationUtf16); if (!hddLocationUtf16) goto cleanup; VBOX_UTF16_TO_UTF8(hddLocationUtf16, &hddLocationUtf8); if (!hddLocationUtf8) goto cleanup; ignore_value(VIR_STRDUP(ret, hddLocationUtf8)); VIR_DEBUG("Storage Volume Name: %s", vol->name); VIR_DEBUG("Storage Volume Path: %s", hddLocationUtf8); VIR_DEBUG("Storage Volume Pool: %s", vol->pool); VBOX_UTF8_FREE(hddLocationUtf8); cleanup: VBOX_UTF16_FREE(hddLocationUtf16); VBOX_MEDIUM_RELEASE(hardDisk); vboxIIDUnalloc(&hddIID); return ret; }
static virNetworkPtr vboxNetworkLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { vboxDriverPtr data = conn->privateData; PRUint32 interfaceType = 0; char *nameUtf8 = NULL; PRUnichar *nameUtf16 = NULL; IHostNetworkInterface *networkInterface = NULL; vboxIIDUnion iid; IHost *host = NULL; virNetworkPtr ret = NULL; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; VBOX_IID_INITIALIZE(&iid); vboxIIDFromUUID(&iid, uuid); /* TODO: "internal" networks are just strings and * thus can't do much with them */ gVBoxAPI.UIHost.FindHostNetworkInterfaceById(host, &iid, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) goto cleanup; gVBoxAPI.UIHNInterface.GetName(networkInterface, &nameUtf16); VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8); ret = virGetNetwork(conn, nameUtf8, uuid); VIR_DEBUG("Network Name: %s", nameUtf8); DEBUGIID("Network UUID", &iid); VBOX_UTF8_FREE(nameUtf8); VBOX_UTF16_FREE(nameUtf16); cleanup: VBOX_RELEASE(networkInterface); VBOX_RELEASE(host); vboxIIDUnalloc(&iid); return ret; }
static virNetworkPtr vboxNetworkLookupByName(virConnectPtr conn, const char *name) { vboxDriverPtr data = conn->privateData; PRUnichar *nameUtf16 = NULL; IHostNetworkInterface *networkInterface = NULL; PRUint32 interfaceType = 0; unsigned char uuid[VIR_UUID_BUFLEN]; vboxIIDUnion iid; IHost *host = NULL; virNetworkPtr ret = NULL; nsresult rc; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; VBOX_IID_INITIALIZE(&iid); VBOX_UTF8_TO_UTF16(name, &nameUtf16); gVBoxAPI.UIHost.FindHostNetworkInterfaceByName(host, nameUtf16, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) goto cleanup; rc = gVBoxAPI.UIHNInterface.GetId(networkInterface, &iid); if (NS_FAILED(rc)) goto cleanup; vboxIIDToUUID(&iid, uuid); ret = virGetNetwork(conn, name, uuid); VIR_DEBUG("Network Name: %s", name); DEBUGIID("Network UUID", &iid); vboxIIDUnalloc(&iid); cleanup: VBOX_RELEASE(networkInterface); VBOX_UTF16_FREE(nameUtf16); VBOX_RELEASE(host); return ret; }
static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags) { vboxDriverPtr data = vol->conn->privateData; IMedium *hardDisk = NULL; unsigned char uuid[VIR_UUID_BUFLEN]; PRUnichar *hddFormatUtf16 = NULL; char *hddFormatUtf8 = NULL; PRUint64 hddLogicalSize = 0; PRUint64 hddActualSize = 0; virStoragePoolDef pool; virStorageVolDef def; vboxIID hddIID; PRUint32 hddstate; nsresult rc; char *ret = NULL; if (!data->vboxObj) return ret; virCheckFlags(0, NULL); memset(&pool, 0, sizeof(pool)); memset(&def, 0, sizeof(def)); if (virUUIDParse(vol->key, uuid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Could not parse UUID from '%s'"), vol->key); return ret; } VBOX_IID_INITIALIZE(&hddIID); vboxIIDFromUUID(&hddIID, uuid); rc = gVBoxAPI.UIVirtualBox.GetHardDiskByIID(data->vboxObj, &hddIID, &hardDisk); if (NS_FAILED(rc)) goto cleanup; gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate); if (hddstate == MediaState_Inaccessible) goto cleanup; /* 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; def.type = VIR_STORAGE_VOL_FILE; rc = gVBoxAPI.UIMedium.GetLogicalSize(hardDisk, &hddLogicalSize); if (NS_FAILED(rc)) goto cleanup; def.target.capacity = hddLogicalSize; rc = gVBoxAPI.UIMedium.GetSize(hardDisk, &hddActualSize); if (NS_FAILED(rc)) goto cleanup; if (VIR_STRDUP(def.name, vol->name) < 0) goto cleanup; if (VIR_STRDUP(def.key, vol->key) < 0) goto cleanup; rc = gVBoxAPI.UIMedium.GetFormat(hardDisk, &hddFormatUtf16); if (NS_FAILED(rc)) goto cleanup; VBOX_UTF16_TO_UTF8(hddFormatUtf16, &hddFormatUtf8); if (!hddFormatUtf8) goto cleanup; VIR_DEBUG("Storage Volume Format: %s", hddFormatUtf8); if (STRCASEEQ("vmdk", hddFormatUtf8)) def.target.format = VIR_STORAGE_FILE_VMDK; else if (STRCASEEQ("vhd", hddFormatUtf8)) def.target.format = VIR_STORAGE_FILE_VPC; else if (STRCASEEQ("vdi", hddFormatUtf8)) def.target.format = VIR_STORAGE_FILE_VDI; else def.target.format = VIR_STORAGE_FILE_RAW; ret = virStorageVolDefFormat(&pool, &def); cleanup: VBOX_UTF16_FREE(hddFormatUtf16); VBOX_UTF8_FREE(hddFormatUtf8); VBOX_MEDIUM_RELEASE(hardDisk); vboxIIDUnalloc(&hddIID); return ret; }
static int vboxStorageVolDelete(virStorageVolPtr vol, unsigned int flags) { vboxDriverPtr data = vol->conn->privateData; unsigned char uuid[VIR_UUID_BUFLEN]; IMedium *hardDisk = NULL; int deregister = 0; PRUint32 hddstate = 0; size_t i = 0; size_t j = 0; PRUint32 machineIdsSize = 0; vboxArray machineIds = VBOX_ARRAY_INITIALIZER; vboxIID hddIID; int ret = -1; if (!data->vboxObj) return ret; VBOX_IID_INITIALIZE(&hddIID); virCheckFlags(0, -1); if (virUUIDParse(vol->key, uuid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Could not parse UUID from '%s'"), vol->key); return -1; } vboxIIDFromUUID(&hddIID, uuid); if (NS_FAILED(gVBoxAPI.UIVirtualBox.GetHardDiskByIID(data->vboxObj, &hddIID, &hardDisk))) goto cleanup; gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate); if (hddstate == MediaState_Inaccessible) goto cleanup; gVBoxAPI.UArray.vboxArrayGet(&machineIds, hardDisk, gVBoxAPI.UArray.handleMediumGetMachineIds(hardDisk)); #if defined WIN32 /* VirtualBox 2.2 on Windows represents IIDs as GUIDs and the * machineIds array contains direct instances of the GUID struct * instead of pointers to the actual struct instances. But there * is no 128bit width simple item type for a SafeArray to fit a * GUID in. The largest simple type it 64bit width and VirtualBox * uses two of this 64bit items to represents one GUID. Therefore, * we divide the size of the SafeArray by two, to compensate for * this workaround in VirtualBox */ if (gVBoxAPI.uVersion >= 2001052 && gVBoxAPI.uVersion < 2002051) machineIds.count /= 2; #endif /* !defined WIN32 */ machineIdsSize = machineIds.count; for (i = 0; i < machineIds.count; i++) { IMachine *machine = NULL; vboxIID machineId; vboxArray hddAttachments = VBOX_ARRAY_INITIALIZER; VBOX_IID_INITIALIZE(&machineId); vboxIIDFromArrayItem(&machineId, &machineIds, i); if (NS_FAILED(gVBoxAPI.UIVirtualBox.GetMachine(data->vboxObj, &machineId, &machine))) { virReportError(VIR_ERR_NO_DOMAIN, "%s", _("no domain with matching uuid")); break; } if (NS_FAILED(gVBoxAPI.UISession.Open(data, &machineId, machine))) { vboxIIDUnalloc(&machineId); continue; } if (NS_FAILED(gVBoxAPI.UISession.GetMachine(data->vboxSession, &machine))) goto cleanupLoop; gVBoxAPI.UArray.vboxArrayGet(&hddAttachments, machine, gVBoxAPI.UArray.handleMachineGetMediumAttachments(machine)); for (j = 0; j < hddAttachments.count; j++) { IMediumAttachment *hddAttachment = hddAttachments.items[j]; IMedium *hdd = NULL; vboxIID iid; if (!hddAttachment) continue; if (NS_FAILED(gVBoxAPI.UIMediumAttachment.GetMedium(hddAttachment, &hdd)) || !hdd) continue; VBOX_IID_INITIALIZE(&iid); if (NS_FAILED(gVBoxAPI.UIMedium.GetId(hdd, &iid))) { VBOX_MEDIUM_RELEASE(hdd); continue; } DEBUGIID("HardDisk (to delete) UUID", &hddIID); DEBUGIID("HardDisk (currently processing) UUID", &iid); if (vboxIIDIsEqual(&hddIID, &iid)) { PRUnichar *controller = NULL; PRInt32 port = 0; PRInt32 device = 0; DEBUGIID("Found HardDisk to delete, UUID", &hddIID); gVBoxAPI.UIMediumAttachment.GetController(hddAttachment, &controller); gVBoxAPI.UIMediumAttachment.GetPort(hddAttachment, &port); gVBoxAPI.UIMediumAttachment.GetDevice(hddAttachment, &device); if (NS_SUCCEEDED(gVBoxAPI.UIMachine.DetachDevice(machine, controller, port, device))) { ignore_value(gVBoxAPI.UIMachine.SaveSettings(machine)); VIR_DEBUG("saving machine settings"); deregister++; VIR_DEBUG("deregistering hdd:%d", deregister); } VBOX_UTF16_FREE(controller); } vboxIIDUnalloc(&iid); VBOX_MEDIUM_RELEASE(hdd); } cleanupLoop: gVBoxAPI.UArray.vboxArrayRelease(&hddAttachments); VBOX_RELEASE(machine); gVBoxAPI.UISession.Close(data->vboxSession); vboxIIDUnalloc(&machineId); } gVBoxAPI.UArray.vboxArrayUnalloc(&machineIds); if (machineIdsSize == 0 || machineIdsSize == deregister) { IProgress *progress = NULL; if (NS_SUCCEEDED(gVBoxAPI.UIMedium.DeleteStorage(hardDisk, &progress)) && progress) { gVBoxAPI.UIProgress.WaitForCompletion(progress, -1); VBOX_RELEASE(progress); DEBUGIID("HardDisk deleted, UUID", &hddIID); ret = 0; } } cleanup: VBOX_MEDIUM_RELEASE(hardDisk); vboxIIDUnalloc(&hddIID); return ret; }
static virStorageVolPtr vboxStorageVolCreateXML(virStoragePoolPtr pool, const char *xml, unsigned int flags) { vboxDriverPtr data = pool->conn->privateData; virStorageVolDefPtr def = NULL; PRUnichar *hddFormatUtf16 = NULL; PRUnichar *hddNameUtf16 = NULL; virStoragePoolDef poolDef; nsresult rc; vboxIID hddIID; unsigned char uuid[VIR_UUID_BUFLEN]; char key[VIR_UUID_STRING_BUFLEN] = ""; IMedium *hardDisk = NULL; IProgress *progress = NULL; PRUint64 logicalSize = 0; PRUint32 variant = HardDiskVariant_Standard; resultCodeUnion resultCode; virStorageVolPtr ret = NULL; if (!data->vboxObj) return ret; virCheckFlags(0, NULL); /* 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(&poolDef, xml, 0)) == NULL) goto cleanup; if (!def->name || (def->type != VIR_STORAGE_VOL_FILE)) goto cleanup; /* For now only the vmdk, vpc and vdi type harddisk * variants can be created. For historical reason, we default to vdi */ if (def->target.format == VIR_STORAGE_FILE_VMDK) { VBOX_UTF8_TO_UTF16("VMDK", &hddFormatUtf16); } else if (def->target.format == VIR_STORAGE_FILE_VPC) { VBOX_UTF8_TO_UTF16("VHD", &hddFormatUtf16); } else { VBOX_UTF8_TO_UTF16("VDI", &hddFormatUtf16); } /* If target.path isn't given, use default path ~/.VirtualBox/image_name */ if (def->target.path == NULL && virAsprintf(&def->target.path, "%s/.VirtualBox/%s", virGetUserDirectory(), def->name) < 0) goto cleanup; VBOX_UTF8_TO_UTF16(def->target.path, &hddNameUtf16); if (!hddFormatUtf16 || !hddNameUtf16) goto cleanup; rc = gVBoxAPI.UIVirtualBox.CreateHardDisk(data->vboxObj, hddFormatUtf16, hddNameUtf16, &hardDisk); if (NS_FAILED(rc)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not create harddisk, rc=%08x"), (unsigned)rc); goto cleanup; } logicalSize = VIR_DIV_UP(def->target.capacity, 1024 * 1024); if (def->target.capacity == def->target.allocation) variant = HardDiskVariant_Fixed; rc = gVBoxAPI.UIMedium.CreateBaseStorage(hardDisk, logicalSize, variant, &progress); if (NS_FAILED(rc) || !progress) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not create base storage, rc=%08x"), (unsigned)rc); goto cleanup; } gVBoxAPI.UIProgress.WaitForCompletion(progress, -1); gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode); if (RC_FAILED(resultCode)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not create base storage, rc=%08x"), (unsigned)resultCode.uResultCode); goto cleanup; } VBOX_IID_INITIALIZE(&hddIID); rc = gVBoxAPI.UIMedium.GetId(hardDisk, &hddIID); if (NS_FAILED(rc)) goto cleanup; vboxIIDToUUID(&hddIID, uuid); virUUIDFormat(uuid, key); ret = virGetStorageVol(pool->conn, pool->name, def->name, key, NULL, NULL); cleanup: vboxIIDUnalloc(&hddIID); VBOX_RELEASE(progress); VBOX_UTF16_FREE(hddFormatUtf16); VBOX_UTF16_FREE(hddNameUtf16); virStorageVolDefFree(def); return ret; }
static virStorageVolPtr vboxStorageVolLookupByPath(virConnectPtr conn, const char *path) { vboxDriverPtr data = conn->privateData; PRUnichar *hddPathUtf16 = NULL; IMedium *hardDisk = NULL; PRUnichar *hddNameUtf16 = NULL; char *hddNameUtf8 = NULL; unsigned char uuid[VIR_UUID_BUFLEN]; char key[VIR_UUID_STRING_BUFLEN] = ""; vboxIID hddIID; PRUint32 hddstate; nsresult rc; virStorageVolPtr ret = NULL; if (!data->vboxObj) return ret; VBOX_IID_INITIALIZE(&hddIID); if (!path) return ret; VBOX_UTF8_TO_UTF16(path, &hddPathUtf16); if (!hddPathUtf16) return ret; rc = gVBoxAPI.UIVirtualBox.FindHardDisk(data->vboxObj, hddPathUtf16, DeviceType_HardDisk, AccessMode_ReadWrite, &hardDisk); if (NS_FAILED(rc)) goto cleanup; gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate); if (hddstate == MediaState_Inaccessible) goto cleanup; gVBoxAPI.UIMedium.GetName(hardDisk, &hddNameUtf16); if (!hddNameUtf16) goto cleanup; VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8); VBOX_UTF16_FREE(hddNameUtf16); if (!hddNameUtf8) goto cleanup; rc = gVBoxAPI.UIMedium.GetId(hardDisk, &hddIID); if (NS_FAILED(rc)) { VBOX_UTF8_FREE(hddNameUtf8); goto cleanup; } vboxIIDToUUID(&hddIID, uuid); virUUIDFormat(uuid, key); /* TODO: currently only one default pool and thus * the check below, change it when pools are supported */ if (vboxConnectNumOfStoragePools(conn) == 1) ret = virGetStorageVol(conn, "default-pool", hddNameUtf8, key, NULL, NULL); VIR_DEBUG("Storage Volume Pool: %s", "default-pool"); VIR_DEBUG("Storage Volume Name: %s", hddNameUtf8); VIR_DEBUG("Storage Volume key : %s", key); vboxIIDUnalloc(&hddIID); VBOX_UTF8_FREE(hddNameUtf8); cleanup: VBOX_MEDIUM_RELEASE(hardDisk); VBOX_UTF16_FREE(hddPathUtf16); return ret; }
static virStorageVolPtr vboxStorageVolLookupByKey(virConnectPtr conn, const char *key) { vboxDriverPtr data = conn->privateData; vboxIID hddIID; unsigned char uuid[VIR_UUID_BUFLEN]; IMedium *hardDisk = NULL; PRUnichar *hddNameUtf16 = NULL; char *hddNameUtf8 = NULL; PRUint32 hddstate; nsresult rc; virStorageVolPtr ret = NULL; if (!data->vboxObj) return ret; VBOX_IID_INITIALIZE(&hddIID); if (!key) return ret; if (virUUIDParse(key, uuid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Could not parse UUID from '%s'"), key); return NULL; } vboxIIDFromUUID(&hddIID, uuid); rc = gVBoxAPI.UIVirtualBox.GetHardDiskByIID(data->vboxObj, &hddIID, &hardDisk); if (NS_FAILED(rc)) goto cleanup; gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate); if (hddstate == MediaState_Inaccessible) goto cleanup; gVBoxAPI.UIMedium.GetName(hardDisk, &hddNameUtf16); if (!hddNameUtf16) goto cleanup; VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8); if (!hddNameUtf8) { VBOX_UTF16_FREE(hddNameUtf16); goto cleanup; } if (vboxConnectNumOfStoragePools(conn) == 1) { ret = virGetStorageVol(conn, "default-pool", hddNameUtf8, key, NULL, NULL); VIR_DEBUG("Storage Volume Pool: %s", "default-pool"); } else { /* TODO: currently only one default pool and thus * nothing here, change it when pools are supported */ } VIR_DEBUG("Storage Volume Name: %s", key); VIR_DEBUG("Storage Volume key : %s", hddNameUtf8); VBOX_UTF8_FREE(hddNameUtf8); VBOX_UTF16_FREE(hddNameUtf16); cleanup: VBOX_MEDIUM_RELEASE(hardDisk); vboxIIDUnalloc(&hddIID); return ret; }
static virStorageVolPtr vboxStorageVolLookupByName(virStoragePoolPtr pool, const char *name) { vboxDriverPtr data = pool->conn->privateData; vboxArray hardDisks = VBOX_ARRAY_INITIALIZER; nsresult rc; size_t i; virStorageVolPtr ret = NULL; if (!data->vboxObj) return ret; if (!name) return ret; rc = gVBoxAPI.UArray.vboxArrayGet(&hardDisks, data->vboxObj, gVBoxAPI.UArray.handleGetHardDisks(data->vboxObj)); if (NS_FAILED(rc)) return ret; for (i = 0; i < hardDisks.count; ++i) { IMedium *hardDisk = hardDisks.items[i]; PRUint32 hddstate; char *nameUtf8 = NULL; PRUnichar *nameUtf16 = NULL; if (!hardDisk) continue; gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate); if (hddstate == MediaState_Inaccessible) continue; gVBoxAPI.UIMedium.GetName(hardDisk, &nameUtf16); if (nameUtf16) { VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8); VBOX_UTF16_FREE(nameUtf16); } if (nameUtf8 && STREQ(nameUtf8, name)) { vboxIID hddIID; unsigned char uuid[VIR_UUID_BUFLEN]; char key[VIR_UUID_STRING_BUFLEN] = ""; VBOX_IID_INITIALIZE(&hddIID); rc = gVBoxAPI.UIMedium.GetId(hardDisk, &hddIID); if (NS_SUCCEEDED(rc)) { vboxIIDToUUID(&hddIID, uuid); virUUIDFormat(uuid, key); ret = virGetStorageVol(pool->conn, pool->name, name, key, NULL, NULL); VIR_DEBUG("virStorageVolPtr: %p", ret); VIR_DEBUG("Storage Volume Name: %s", name); VIR_DEBUG("Storage Volume key : %s", key); VIR_DEBUG("Storage Volume Pool: %s", pool->name); } vboxIIDUnalloc(&hddIID); VBOX_UTF8_FREE(nameUtf8); break; } VBOX_UTF8_FREE(nameUtf8); } gVBoxAPI.UArray.vboxArrayRelease(&hardDisks); return ret; }
static char *vboxNetworkGetXMLDesc(virNetworkPtr network, unsigned int flags) { vboxDriverPtr data = network->conn->privateData; virNetworkDefPtr def = NULL; virNetworkIPDefPtr ipdef = NULL; char *networkNameUtf8 = NULL; PRUnichar *networkInterfaceNameUtf16 = NULL; IHostNetworkInterface *networkInterface = NULL; PRUint32 interfaceType = 0; PRUnichar *networkNameUtf16 = NULL; IDHCPServer *dhcpServer = NULL; vboxIIDUnion vboxnet0IID; IHost *host = NULL; char *ret = NULL; nsresult rc; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; VBOX_IID_INITIALIZE(&vboxnet0IID); virCheckFlags(0, NULL); if (VIR_ALLOC(def) < 0) goto cleanup; if (VIR_ALLOC(ipdef) < 0) goto cleanup; def->ips = ipdef; def->nips = 1; if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0) goto cleanup; VBOX_UTF8_TO_UTF16(network->name, &networkInterfaceNameUtf16); gVBoxAPI.UIHost.FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) goto cleanup; if (VIR_STRDUP(def->name, network->name) < 0) goto cleanup; rc = gVBoxAPI.UIHNInterface.GetId(networkInterface, &vboxnet0IID); if (NS_FAILED(rc)) goto cleanup; vboxIIDToUUID(&vboxnet0IID, def->uuid); VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16); def->forward.type = VIR_NETWORK_FORWARD_NONE; gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj, networkNameUtf16, &dhcpServer); if (dhcpServer) { ipdef->nranges = 1; if (VIR_ALLOC_N(ipdef->ranges, ipdef->nranges) >= 0) { PRUnichar *ipAddressUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL; PRUnichar *fromIPAddressUtf16 = NULL; PRUnichar *toIPAddressUtf16 = NULL; bool errorOccurred = false; gVBoxAPI.UIDHCPServer.GetIPAddress(dhcpServer, &ipAddressUtf16); gVBoxAPI.UIDHCPServer.GetNetworkMask(dhcpServer, &networkMaskUtf16); gVBoxAPI.UIDHCPServer.GetLowerIP(dhcpServer, &fromIPAddressUtf16); gVBoxAPI.UIDHCPServer.GetUpperIP(dhcpServer, &toIPAddressUtf16); /* Currently virtualbox supports only one dhcp server per network * with contigious address space from start to end */ if (vboxSocketParseAddrUtf16(data, ipAddressUtf16, &ipdef->address) < 0 || vboxSocketParseAddrUtf16(data, networkMaskUtf16, &ipdef->netmask) < 0 || vboxSocketParseAddrUtf16(data, fromIPAddressUtf16, &ipdef->ranges[0].start) < 0 || vboxSocketParseAddrUtf16(data, toIPAddressUtf16, &ipdef->ranges[0].end) < 0) { errorOccurred = true; } VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); VBOX_UTF16_FREE(fromIPAddressUtf16); VBOX_UTF16_FREE(toIPAddressUtf16); if (errorOccurred) goto cleanup; } else { ipdef->nranges = 0; } ipdef->nhosts = 1; if (VIR_ALLOC_N(ipdef->hosts, ipdef->nhosts) >= 0) { if (VIR_STRDUP(ipdef->hosts[0].name, network->name) < 0) { VIR_FREE(ipdef->hosts); ipdef->nhosts = 0; } else { PRUnichar *macAddressUtf16 = NULL; PRUnichar *ipAddressUtf16 = NULL; bool errorOccurred = false; gVBoxAPI.UIHNInterface.GetHardwareAddress(networkInterface, &macAddressUtf16); gVBoxAPI.UIHNInterface.GetIPAddress(networkInterface, &ipAddressUtf16); VBOX_UTF16_TO_UTF8(macAddressUtf16, &ipdef->hosts[0].mac); if (vboxSocketParseAddrUtf16(data, ipAddressUtf16, &ipdef->hosts[0].ip) < 0) { errorOccurred = true; } VBOX_UTF16_FREE(macAddressUtf16); VBOX_UTF16_FREE(ipAddressUtf16); if (errorOccurred) goto cleanup; } } else { ipdef->nhosts = 0; } } else { PRUnichar *networkMaskUtf16 = NULL; PRUnichar *ipAddressUtf16 = NULL; bool errorOccurred = false; gVBoxAPI.UIHNInterface.GetNetworkMask(networkInterface, &networkMaskUtf16); gVBoxAPI.UIHNInterface.GetIPAddress(networkInterface, &ipAddressUtf16); if (vboxSocketParseAddrUtf16(data, networkMaskUtf16, &ipdef->netmask) < 0 || vboxSocketParseAddrUtf16(data, ipAddressUtf16, &ipdef->address) < 0) { errorOccurred = true; } VBOX_UTF16_FREE(networkMaskUtf16); VBOX_UTF16_FREE(ipAddressUtf16); if (errorOccurred) goto cleanup; } DEBUGIID("Network UUID", &vboxnet0IID); ret = virNetworkDefFormat(def, 0); cleanup: vboxIIDUnalloc(&vboxnet0IID); VBOX_UTF16_FREE(networkNameUtf16); VBOX_RELEASE(networkInterface); VBOX_UTF16_FREE(networkInterfaceNameUtf16); VBOX_RELEASE(host); virNetworkDefFree(def); VIR_FREE(networkNameUtf8); VBOX_RELEASE(dhcpServer); return ret; }
static int vboxNetworkCreate(virNetworkPtr network) { vboxDriverPtr data = network->conn->privateData; char *networkNameUtf8 = NULL; PRUnichar *networkInterfaceNameUtf16 = NULL; IHostNetworkInterface *networkInterface = NULL; PRUnichar *networkNameUtf16 = NULL; IDHCPServer *dhcpServer = NULL; PRUnichar *trunkTypeUtf16 = NULL; PRUint32 interfaceType = 0; IHost *host = NULL; int ret = -1; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; /* Current limitation of the function for VirtualBox 2.2.* is * that the default hostonly network "vboxnet0" is always active * and thus all this functions does is start the dhcp server, * but the network can still be used without starting the dhcp * server by giving the machine static IP */ if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0) goto cleanup; VBOX_UTF8_TO_UTF16(network->name, &networkInterfaceNameUtf16); gVBoxAPI.UIHost.FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) goto cleanup; VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16); gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj, networkNameUtf16, &dhcpServer); if (!dhcpServer) goto cleanup; gVBoxAPI.UIDHCPServer.SetEnabled(dhcpServer, PR_TRUE); VBOX_UTF8_TO_UTF16("netflt", &trunkTypeUtf16); gVBoxAPI.UIDHCPServer.Start(dhcpServer, networkNameUtf16, networkInterfaceNameUtf16, trunkTypeUtf16); VBOX_UTF16_FREE(trunkTypeUtf16); ret = 0; cleanup: VBOX_RELEASE(dhcpServer); VBOX_UTF16_FREE(networkNameUtf16); VBOX_RELEASE(networkInterface); VBOX_UTF16_FREE(networkInterfaceNameUtf16); VBOX_RELEASE(host); VIR_FREE(networkNameUtf8); return ret; }
static int vboxNetworkUndefineDestroy(virNetworkPtr network, bool removeinterface) { vboxDriverPtr data = network->conn->privateData; char *networkNameUtf8 = NULL; PRUnichar *networkInterfaceNameUtf16 = NULL; IHostNetworkInterface *networkInterface = NULL; PRUnichar *networkNameUtf16 = NULL; IDHCPServer *dhcpServer = NULL; PRUint32 interfaceType = 0; IHost *host = NULL; int ret = -1; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; /* Current limitation of the function for VirtualBox 2.2.* is * that you can't delete the default hostonly adaptor namely: * vboxnet0 and thus all this functions does is remove the * dhcp server configuration, but the network can still be used * by giving the machine static IP and also it will still * show up in the net-list in virsh */ if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0) goto cleanup; VBOX_UTF8_TO_UTF16(network->name, &networkInterfaceNameUtf16); gVBoxAPI.UIHost.FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) goto cleanup; if (gVBoxAPI.networkRemoveInterface && removeinterface) { vboxIIDUnion iid; IProgress *progress = NULL; nsresult rc; resultCodeUnion resultCode; VBOX_IID_INITIALIZE(&iid); rc = gVBoxAPI.UIHNInterface.GetId(networkInterface, &iid); if (NS_FAILED(rc)) goto cleanup; gVBoxAPI.UIHost.RemoveHostOnlyNetworkInterface(host, &iid, &progress); vboxIIDUnalloc(&iid); if (!progress) goto cleanup; gVBoxAPI.UIProgress.WaitForCompletion(progress, -1); gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode); if (RC_FAILED(resultCode)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Error while removing hostonly network interface, rc=%08x"), resultCode.uResultCode); goto cleanup; } VBOX_RELEASE(progress); } VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16); gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj, networkNameUtf16, &dhcpServer); if (!dhcpServer) goto cleanup; gVBoxAPI.UIDHCPServer.SetEnabled(dhcpServer, PR_FALSE); gVBoxAPI.UIDHCPServer.Stop(dhcpServer); if (removeinterface) gVBoxAPI.UIVirtualBox.RemoveDHCPServer(data->vboxObj, dhcpServer); ret = 0; VBOX_RELEASE(dhcpServer); cleanup: VBOX_UTF16_FREE(networkNameUtf16); VBOX_RELEASE(networkInterface); VBOX_UTF16_FREE(networkInterfaceNameUtf16); VBOX_RELEASE(host); VIR_FREE(networkNameUtf8); return ret; }
static virNetworkPtr vboxNetworkDefineCreateXML(virConnectPtr conn, const char *xml, bool start) { vboxDriverPtr data = conn->privateData; PRUnichar *networkInterfaceNameUtf16 = NULL; char *networkInterfaceNameUtf8 = NULL; PRUnichar *networkNameUtf16 = NULL; char *networkNameUtf8 = NULL; IHostNetworkInterface *networkInterface = NULL; virNetworkDefPtr def = virNetworkDefParseString(xml); virNetworkIPDefPtr ipdef = NULL; unsigned char uuid[VIR_UUID_BUFLEN]; vboxIIDUnion vboxnetiid; virSocketAddr netmask; IHost *host = NULL; virNetworkPtr ret = NULL; nsresult rc; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; VBOX_IID_INITIALIZE(&vboxnetiid); if ((!def) || (def->forward.type != VIR_NETWORK_FORWARD_NONE) || (def->nips == 0 || !def->ips)) goto cleanup; /* Look for the first IPv4 IP address definition and use that. * If there weren't any IPv4 addresses, ignore the network (since it's * required below to have an IPv4 address) */ ipdef = virNetworkDefGetIPByIndex(def, AF_INET, 0); if (!ipdef) goto cleanup; if (virNetworkIPDefNetmask(ipdef, &netmask) < 0) goto cleanup; /* the current limitation of hostonly network is that you can't * assign a name to it and it defaults to vboxnet*, for e.g: * vboxnet0, vboxnet1, etc. Also the UUID is assigned to it * automatically depending on the mac address and thus both * these paramters are ignored here for now. * * If the vbox is in 2.x and the def->name not equal to vboxnet0, * the function call will fail and the networkInterface set to * NULL. (We can't assign a new name to hostonly network, only * take the given name, say vboxnet0) */ gVBoxAPI.UIHost.CreateHostOnlyNetworkInterface(data, host, def->name, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetName(networkInterface, &networkInterfaceNameUtf16); if (!networkInterfaceNameUtf16) goto cleanup; VBOX_UTF16_TO_UTF8(networkInterfaceNameUtf16, &networkInterfaceNameUtf8); if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", networkInterfaceNameUtf8) < 0) goto cleanup; VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16); /* Currently support only one dhcp server per network * with contigious address space from start to end */ if ((ipdef->nranges >= 1) && VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].start) && VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].end)) { IDHCPServer *dhcpServer = NULL; gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj, networkNameUtf16, &dhcpServer); if (!dhcpServer) { /* create a dhcp server */ gVBoxAPI.UIVirtualBox.CreateDHCPServer(data->vboxObj, networkNameUtf16, &dhcpServer); VIR_DEBUG("couldn't find dhcp server so creating one"); } if (dhcpServer) { PRUnichar *ipAddressUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL; PRUnichar *fromIPAddressUtf16 = NULL; PRUnichar *toIPAddressUtf16 = NULL; PRUnichar *trunkTypeUtf16 = NULL; ipAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->address); networkMaskUtf16 = vboxSocketFormatAddrUtf16(data, &netmask); fromIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->ranges[0].start); toIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->ranges[0].end); if (ipAddressUtf16 == NULL || networkMaskUtf16 == NULL || fromIPAddressUtf16 == NULL || toIPAddressUtf16 == NULL) { VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); VBOX_UTF16_FREE(fromIPAddressUtf16); VBOX_UTF16_FREE(toIPAddressUtf16); VBOX_RELEASE(dhcpServer); goto cleanup; } VBOX_UTF8_TO_UTF16("netflt", &trunkTypeUtf16); gVBoxAPI.UIDHCPServer.SetEnabled(dhcpServer, PR_TRUE); gVBoxAPI.UIDHCPServer.SetConfiguration(dhcpServer, ipAddressUtf16, networkMaskUtf16, fromIPAddressUtf16, toIPAddressUtf16); if (start) gVBoxAPI.UIDHCPServer.Start(dhcpServer, networkNameUtf16, networkInterfaceNameUtf16, trunkTypeUtf16); VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); VBOX_UTF16_FREE(fromIPAddressUtf16); VBOX_UTF16_FREE(toIPAddressUtf16); VBOX_UTF16_FREE(trunkTypeUtf16); VBOX_RELEASE(dhcpServer); } } if ((ipdef->nhosts >= 1) && VIR_SOCKET_ADDR_VALID(&ipdef->hosts[0].ip)) { PRUnichar *ipAddressUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL; ipAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->hosts[0].ip); networkMaskUtf16 = vboxSocketFormatAddrUtf16(data, &netmask); if (ipAddressUtf16 == NULL || networkMaskUtf16 == NULL) { VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); goto cleanup; } /* Current drawback is that since EnableStaticIpConfig() sets * IP and enables the interface so even if the dhcpserver is not * started the interface is still up and running */ gVBoxAPI.UIHNInterface.EnableStaticIPConfig(networkInterface, ipAddressUtf16, networkMaskUtf16); VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); } else { gVBoxAPI.UIHNInterface.EnableDynamicIPConfig(networkInterface); gVBoxAPI.UIHNInterface.DHCPRediscover(networkInterface); } rc = gVBoxAPI.UIHNInterface.GetId(networkInterface, &vboxnetiid); if (NS_FAILED(rc)) goto cleanup; vboxIIDToUUID(&vboxnetiid, uuid); DEBUGIID("Real Network UUID", &vboxnetiid); vboxIIDUnalloc(&vboxnetiid); ret = virGetNetwork(conn, networkInterfaceNameUtf8, uuid); cleanup: VIR_FREE(networkNameUtf8); VBOX_UTF16_FREE(networkNameUtf16); VBOX_RELEASE(networkInterface); VBOX_UTF8_FREE(networkInterfaceNameUtf8); VBOX_UTF16_FREE(networkInterfaceNameUtf16); VBOX_RELEASE(host); virNetworkDefFree(def); return ret; }