static virStorageVolPtr esxStorageVolLookupByName(virStoragePoolPtr pool, const char *name) { virStorageVolPtr volume = NULL; esxPrivate *priv = pool->conn->privateData; char *datastorePath = NULL; char *key = NULL; if (virAsprintf(&datastorePath, "[%s] %s", pool->name, name) < 0) goto cleanup; if (esxVI_LookupStorageVolumeKeyByDatastorePath(priv->primary, datastorePath, &key) < 0) { goto cleanup; } volume = virGetStorageVol(pool->conn, pool->name, name, key, &esxStorageBackendVMFS, NULL); cleanup: VIR_FREE(datastorePath); VIR_FREE(key); return volume; }
static virStorageVolPtr esxStorageVolLookupByPath(virConnectPtr conn, const char *path) { virStorageVolPtr volume = NULL; esxPrivate *priv = conn->privateData; char *datastoreName = NULL; char *directoryAndFileName = NULL; char *key = NULL; if (esxUtil_ParseDatastorePath(path, &datastoreName, NULL, &directoryAndFileName) < 0) { goto cleanup; } if (esxVI_LookupStorageVolumeKeyByDatastorePath(priv->primary, path, &key) < 0) { goto cleanup; } volume = virGetStorageVol(conn, datastoreName, directoryAndFileName, key, &esxStorageBackendVMFS, NULL); cleanup: VIR_FREE(datastoreName); VIR_FREE(directoryAndFileName); VIR_FREE(key); return volume; }
virStorageVolPtr parallelsStorageVolLookupByPathLocked(virConnectPtr conn, const char *path) { parallelsConnPtr privconn = conn->privateData; size_t i; virStorageVolPtr ret = NULL; for (i = 0; i < privconn->pools.count; i++) { virStoragePoolObjLock(privconn->pools.objs[i]); if (virStoragePoolObjIsActive(privconn->pools.objs[i])) { virStorageVolDefPtr privvol = virStorageVolDefFindByPath(privconn->pools.objs[i], path); if (privvol) { ret = virGetStorageVol(conn, privconn->pools.objs[i]->def->name, privvol->name, privvol->key, NULL, NULL); virStoragePoolObjUnlock(privconn->pools.objs[i]); break; } } virStoragePoolObjUnlock(privconn->pools.objs[i]); } if (!ret) virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching path '%s'"), path); return ret; }
static virStorageVolPtr esxStorageVolLookupByKey(virConnectPtr conn, const char *key) { virStorageVolPtr volume = NULL; esxPrivate *priv = conn->storagePrivateData; char *poolName = NULL; esxVI_ScsiLun *scsiLunList = NULL; esxVI_ScsiLun *scsiLun; /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */ unsigned char md5[MD5_DIGEST_SIZE]; char uuid_string[VIR_UUID_STRING_BUFLEN] = ""; /* key may be LUN device path */ if (STRPREFIX(key, "/")) { return esxStorageVolLookupByPath(conn, key); } if (esxVI_LookupScsiLunList(priv->primary, &scsiLunList) < 0) { goto cleanup; } for (scsiLun = scsiLunList; scsiLun; scsiLun = scsiLun->_next) { memset(uuid_string, '\0', sizeof(uuid_string)); memset(md5, '\0', sizeof(md5)); md5_buffer(scsiLun->uuid, strlen(scsiLun->uuid), md5); virUUIDFormat(md5, uuid_string); if (STREQ(key, uuid_string)) { /* Found matching UUID */ VIR_FREE(poolName); if (esxVI_LookupStoragePoolNameByScsiLunKey(priv->primary, scsiLun->key, &poolName) < 0) { goto cleanup; } volume = virGetStorageVol(conn, poolName, scsiLun->deviceName, uuid_string, &esxStorageBackendISCSI, NULL); break; } } cleanup: esxVI_ScsiLun_Free(&scsiLunList); VIR_FREE(poolName); return volume; }
static virStorageVolPtr esxStorageVolLookupByPath(virConnectPtr conn, const char *path) { virStorageVolPtr volume = NULL; esxPrivate *priv = conn->storagePrivateData; esxVI_ScsiLun *scsiLunList = NULL; esxVI_ScsiLun *scsiLun; esxVI_HostScsiDisk *hostScsiDisk = NULL; char *poolName = NULL; /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */ unsigned char md5[MD5_DIGEST_SIZE]; char uuid_string[VIR_UUID_STRING_BUFLEN] = ""; if (esxVI_LookupScsiLunList(priv->primary, &scsiLunList) < 0) { goto cleanup; } for (scsiLun = scsiLunList; scsiLun; scsiLun = scsiLun->_next) { hostScsiDisk = esxVI_HostScsiDisk_DynamicCast(scsiLun); if (hostScsiDisk && STREQ(hostScsiDisk->devicePath, path)) { /* Found matching device */ VIR_FREE(poolName); if (esxVI_LookupStoragePoolNameByScsiLunKey(priv->primary, hostScsiDisk->key, &poolName) < 0) { goto cleanup; } md5_buffer(scsiLun->uuid, strlen(scsiLun->uuid), md5); virUUIDFormat(md5, uuid_string); volume = virGetStorageVol(conn, poolName, path, uuid_string, &esxStorageBackendISCSI, NULL); break; } } cleanup: esxVI_ScsiLun_Free(&scsiLunList); VIR_FREE(poolName); return volume; }
static virStorageVolPtr esxStorageVolLookupByName(virStoragePoolPtr pool, const char *name) { virStorageVolPtr volume = NULL; esxPrivate *priv = pool->conn->storagePrivateData; esxVI_ScsiLun *scsiLunList = NULL; esxVI_ScsiLun *scsiLun; /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */ unsigned char md5[MD5_DIGEST_SIZE]; char uuid_string[VIR_UUID_STRING_BUFLEN] = ""; if (esxVI_LookupScsiLunList(priv->primary, &scsiLunList) < 0) { goto cleanup; } for (scsiLun = scsiLunList; scsiLun; scsiLun = scsiLun->_next) { if (STREQ(scsiLun->deviceName, name)) { /* * ScsiLun provides an UUID field that is unique accross * multiple servers. But this field length is ~55 characters * compute MD5 hash to transform it to an acceptable * libvirt format */ md5_buffer(scsiLun->uuid, strlen(scsiLun->uuid), md5); virUUIDFormat(md5, uuid_string); /* * ScsiLun provides displayName and canonicalName but both are * optional and its observed that they can be NULL, using * deviceName to create volume. */ volume = virGetStorageVol(pool->conn, pool->name, name, uuid_string, &esxStorageBackendISCSI, NULL); break; } } cleanup: esxVI_ScsiLun_Free(&scsiLunList); return volume; }
static virStorageVolPtr parallelsStorageVolLookupByName(virStoragePoolPtr pool, const char *name) { parallelsConnPtr privconn = pool->conn->privateData; virStoragePoolObjPtr privpool; virStorageVolDefPtr privvol; virStorageVolPtr ret = NULL; parallelsDriverLock(privconn); privpool = virStoragePoolObjFindByName(&privconn->pools, pool->name); parallelsDriverUnlock(privconn); if (privpool == NULL) { parallelsPoolNotFoundError(pool->name); goto cleanup; } if (!virStoragePoolObjIsActive(privpool)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; } privvol = virStorageVolDefFindByName(privpool, name); if (!privvol) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), name); goto cleanup; } ret = virGetStorageVol(pool->conn, privpool->def->name, privvol->name, privvol->key, NULL, NULL); cleanup: if (privpool) virStoragePoolObjUnlock(privpool); return ret; }
static virStorageVolPtr parallelsStorageVolCreateXML(virStoragePoolPtr pool, const char *xmldesc, unsigned int flags) { parallelsConnPtr privconn = pool->conn->privateData; virStoragePoolObjPtr privpool; virStorageVolPtr ret = NULL; virStorageVolDefPtr privvol = NULL; virCheckFlags(0, NULL); parallelsDriverLock(privconn); privpool = virStoragePoolObjFindByName(&privconn->pools, pool->name); parallelsDriverUnlock(privconn); if (privpool == NULL) { parallelsPoolNotFoundError(pool->name); goto cleanup; } if (!virStoragePoolObjIsActive(privpool)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; } privvol = parallelsStorageVolDefineXML(privpool, xmldesc, NULL, true); if (!privvol) goto cleanup; ret = virGetStorageVol(pool->conn, privpool->def->name, privvol->name, privvol->key, NULL, NULL); cleanup: if (privpool) virStoragePoolObjUnlock(privpool); return ret; }
static virStorageVolPtr esxStorageVolCreateXML(virStoragePoolPtr pool, const char *xmldesc, unsigned int flags) { virStorageVolPtr volume = NULL; esxPrivate *priv = pool->conn->privateData; virStoragePoolDef poolDef; virStorageVolDefPtr def = NULL; char *tmp; char *unescapedDatastorePath = NULL; char *unescapedDirectoryName = NULL; char *unescapedDirectoryAndFileName = NULL; char *directoryName = NULL; char *fileName = NULL; char *datastorePathWithoutFileName = NULL; char *datastorePath = NULL; esxVI_FileInfo *fileInfo = NULL; esxVI_FileBackedVirtualDiskSpec *virtualDiskSpec = NULL; esxVI_ManagedObjectReference *task = NULL; esxVI_TaskInfoState taskInfoState; char *taskInfoErrorMessage = NULL; char *uuid_string = NULL; char *key = NULL; virCheckFlags(0, NULL); memset(&poolDef, 0, sizeof(poolDef)); if (esxLookupVMFSStoragePoolType(priv->primary, pool->name, &poolDef.type) < 0) { goto cleanup; } /* Parse config */ def = virStorageVolDefParseString(&poolDef, xmldesc); if (!def) goto cleanup; if (def->type != VIR_STORAGE_VOL_FILE) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Creating non-file volumes is not supported")); goto cleanup; } /* Validate config */ tmp = strrchr(def->name, '/'); if (!tmp || *def->name == '/' || tmp[1] == '\0') { virReportError(VIR_ERR_INTERNAL_ERROR, _("Volume name '%s' doesn't have expected format " "'<directory>/<file>'"), def->name); goto cleanup; } if (! virFileHasSuffix(def->name, ".vmdk")) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Volume name '%s' has unsupported suffix, " "expecting '.vmdk'"), def->name); goto cleanup; } if (virAsprintf(&unescapedDatastorePath, "[%s] %s", pool->name, def->name) < 0) goto cleanup; if (def->target.format == VIR_STORAGE_FILE_VMDK) { /* Parse and escape datastore path */ if (esxUtil_ParseDatastorePath(unescapedDatastorePath, NULL, &unescapedDirectoryName, &unescapedDirectoryAndFileName) < 0) { goto cleanup; } directoryName = esxUtil_EscapeDatastoreItem(unescapedDirectoryName); if (!directoryName) goto cleanup; fileName = esxUtil_EscapeDatastoreItem(unescapedDirectoryAndFileName + strlen(unescapedDirectoryName) + 1); if (!fileName) goto cleanup; if (virAsprintf(&datastorePathWithoutFileName, "[%s] %s", pool->name, directoryName) < 0) goto cleanup; if (virAsprintf(&datastorePath, "[%s] %s/%s", pool->name, directoryName, fileName) < 0) goto cleanup; /* Create directory, if it doesn't exist yet */ if (esxVI_LookupFileInfoByDatastorePath (priv->primary, datastorePathWithoutFileName, true, &fileInfo, esxVI_Occurrence_OptionalItem) < 0) { goto cleanup; } if (!fileInfo) { if (esxVI_MakeDirectory(priv->primary, datastorePathWithoutFileName, priv->primary->datacenter->_reference, esxVI_Boolean_True) < 0) { goto cleanup; } } /* Create VirtualDisk */ if (esxVI_FileBackedVirtualDiskSpec_Alloc(&virtualDiskSpec) < 0 || esxVI_Long_Alloc(&virtualDiskSpec->capacityKb) < 0) { goto cleanup; } /* From the vSphere API documentation about VirtualDiskType ... */ if (def->target.allocation == def->target.capacity) { /* * "A preallocated disk has all space allocated at creation time * and the space is zeroed on demand as the space is used." */ virtualDiskSpec->diskType = (char *)"preallocated"; } else if (def->target.allocation == 0) { /* * "Space required for thin-provisioned virtual disk is allocated * and zeroed on demand as the space is used." */ virtualDiskSpec->diskType = (char *)"thin"; } else { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unsupported capacity-to-allocation relation")); goto cleanup; } /* * FIXME: The adapter type is a required parameter, but there is no * way to let the user specify it in the volume XML config. Therefore, * default to 'busLogic' here. */ virtualDiskSpec->adapterType = (char *)"busLogic"; virtualDiskSpec->capacityKb->value = VIR_DIV_UP(def->target.capacity, 1024); /* Scale from byte to kilobyte */ if (esxVI_CreateVirtualDisk_Task (priv->primary, datastorePath, priv->primary->datacenter->_reference, esxVI_VirtualDiskSpec_DynamicCast(virtualDiskSpec), &task) < 0 || esxVI_WaitForTaskCompletion(priv->primary, task, NULL, esxVI_Occurrence_None, priv->parsedUri->autoAnswer, &taskInfoState, &taskInfoErrorMessage) < 0) { goto cleanup; } if (taskInfoState != esxVI_TaskInfoState_Success) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not create volume: %s"), taskInfoErrorMessage); goto cleanup; } if (priv->primary->hasQueryVirtualDiskUuid) { if (VIR_ALLOC_N(key, VIR_UUID_STRING_BUFLEN) < 0) goto cleanup; if (esxVI_QueryVirtualDiskUuid(priv->primary, datastorePath, priv->primary->datacenter->_reference, &uuid_string) < 0) { goto cleanup; } if (esxUtil_ReformatUuid(uuid_string, key) < 0) goto cleanup; } else { /* Fall back to the path as key */ if (VIR_STRDUP(key, datastorePath) < 0) goto cleanup; } } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("Creation of %s volumes is not supported"), virStorageFileFormatTypeToString(def->target.format)); goto cleanup; } volume = virGetStorageVol(pool->conn, pool->name, def->name, key, &esxStorageBackendVMFS, NULL); cleanup: if (virtualDiskSpec) { virtualDiskSpec->diskType = NULL; virtualDiskSpec->adapterType = NULL; } virStorageVolDefFree(def); VIR_FREE(unescapedDatastorePath); VIR_FREE(unescapedDirectoryName); VIR_FREE(unescapedDirectoryAndFileName); VIR_FREE(directoryName); VIR_FREE(fileName); VIR_FREE(datastorePathWithoutFileName); VIR_FREE(datastorePath); esxVI_FileInfo_Free(&fileInfo); esxVI_FileBackedVirtualDiskSpec_Free(&virtualDiskSpec); esxVI_ManagedObjectReference_Free(&task); VIR_FREE(taskInfoErrorMessage); VIR_FREE(uuid_string); VIR_FREE(key); return volume; }
static virStorageVolPtr esxStorageVolLookupByKey(virConnectPtr conn, const char *key) { virStorageVolPtr volume = NULL; esxPrivate *priv = conn->privateData; esxVI_String *propertyNameList = NULL; esxVI_ObjectContent *datastoreList = NULL; esxVI_ObjectContent *datastore = NULL; char *datastoreName = NULL; esxVI_HostDatastoreBrowserSearchResults *searchResultsList = NULL; esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL; char *directoryAndFileName = NULL; size_t length; char *datastorePath = NULL; char *volumeName = NULL; esxVI_FileInfo *fileInfo = NULL; char *uuid_string = NULL; char key_candidate[VIR_UUID_STRING_BUFLEN] = ""; if (STRPREFIX(key, "[")) { /* Key is probably a datastore path */ return esxStorageVolLookupByPath(conn, key); } if (!priv->primary->hasQueryVirtualDiskUuid) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("QueryVirtualDiskUuid not available, " "cannot lookup storage volume by UUID")); return NULL; } /* Lookup all datastores */ if (esxVI_String_AppendValueToList(&propertyNameList, "summary.name") < 0 || esxVI_LookupDatastoreList(priv->primary, propertyNameList, &datastoreList) < 0) { goto cleanup; } for (datastore = datastoreList; datastore; datastore = datastore->_next) { datastoreName = NULL; if (esxVI_GetStringValue(datastore, "summary.name", &datastoreName, esxVI_Occurrence_RequiredItem) < 0) { goto cleanup; } /* Lookup datastore content */ esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList); if (esxVI_LookupDatastoreContentByDatastoreName (priv->primary, datastoreName, &searchResultsList) < 0) { goto cleanup; } /* Interpret search result */ for (searchResults = searchResultsList; searchResults; searchResults = searchResults->_next) { VIR_FREE(directoryAndFileName); if (esxUtil_ParseDatastorePath(searchResults->folderPath, NULL, NULL, &directoryAndFileName) < 0) { goto cleanup; } /* Strip trailing separators */ length = strlen(directoryAndFileName); while (length > 0 && directoryAndFileName[length - 1] == '/') { directoryAndFileName[length - 1] = '\0'; --length; } /* Build datastore path and query the UUID */ for (fileInfo = searchResults->file; fileInfo; fileInfo = fileInfo->_next) { VIR_FREE(datastorePath); if (length < 1) { if (VIR_STRDUP(volumeName, fileInfo->path) < 0) goto cleanup; } else if (virAsprintf(&volumeName, "%s/%s", directoryAndFileName, fileInfo->path) < 0) { goto cleanup; } if (virAsprintf(&datastorePath, "[%s] %s", datastoreName, volumeName) < 0) goto cleanup; if (!esxVI_VmDiskFileInfo_DynamicCast(fileInfo)) { /* Only a VirtualDisk has a UUID */ continue; } VIR_FREE(uuid_string); if (esxVI_QueryVirtualDiskUuid (priv->primary, datastorePath, priv->primary->datacenter->_reference, &uuid_string) < 0) { goto cleanup; } if (esxUtil_ReformatUuid(uuid_string, key_candidate) < 0) goto cleanup; if (STREQ(key, key_candidate)) { /* Found matching UUID */ volume = virGetStorageVol(conn, datastoreName, volumeName, key, &esxStorageBackendVMFS, NULL); goto cleanup; } } } } cleanup: esxVI_String_Free(&propertyNameList); esxVI_ObjectContent_Free(&datastoreList); esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList); VIR_FREE(directoryAndFileName); VIR_FREE(datastorePath); VIR_FREE(volumeName); VIR_FREE(uuid_string); return volume; }
static virStorageVolPtr esxStorageVolCreateXMLFrom(virStoragePoolPtr pool, const char *xmldesc, virStorageVolPtr sourceVolume, unsigned int flags) { virStorageVolPtr volume = NULL; esxPrivate *priv = pool->conn->privateData; virStoragePoolDef poolDef; char *sourceDatastorePath = NULL; virStorageVolDefPtr def = NULL; char *tmp; char *unescapedDatastorePath = NULL; char *unescapedDirectoryName = NULL; char *unescapedDirectoryAndFileName = NULL; char *directoryName = NULL; char *fileName = NULL; char *datastorePathWithoutFileName = NULL; char *datastorePath = NULL; esxVI_FileInfo *fileInfo = NULL; esxVI_ManagedObjectReference *task = NULL; esxVI_TaskInfoState taskInfoState; char *taskInfoErrorMessage = NULL; char *uuid_string = NULL; char *key = NULL; virCheckFlags(0, NULL); memset(&poolDef, 0, sizeof(poolDef)); if (esxLookupVMFSStoragePoolType(priv->primary, pool->name, &poolDef.type) < 0) { goto cleanup; } if (virAsprintf(&sourceDatastorePath, "[%s] %s", sourceVolume->pool, sourceVolume->name) < 0) goto cleanup; /* Parse config */ def = virStorageVolDefParseString(&poolDef, xmldesc); if (!def) goto cleanup; if (def->type != VIR_STORAGE_VOL_FILE) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Creating non-file volumes is not supported")); goto cleanup; } /* Validate config */ tmp = strrchr(def->name, '/'); if (!tmp || *def->name == '/' || tmp[1] == '\0') { virReportError(VIR_ERR_INTERNAL_ERROR, _("Volume name '%s' doesn't have expected format " "'<directory>/<file>'"), def->name); goto cleanup; } if (! virFileHasSuffix(def->name, ".vmdk")) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Volume name '%s' has unsupported suffix, " "expecting '.vmdk'"), def->name); goto cleanup; } if (virAsprintf(&unescapedDatastorePath, "[%s] %s", pool->name, def->name) < 0) goto cleanup; if (def->target.format == VIR_STORAGE_FILE_VMDK) { /* Parse and escape datastore path */ if (esxUtil_ParseDatastorePath(unescapedDatastorePath, NULL, &unescapedDirectoryName, &unescapedDirectoryAndFileName) < 0) { goto cleanup; } directoryName = esxUtil_EscapeDatastoreItem(unescapedDirectoryName); if (!directoryName) goto cleanup; fileName = esxUtil_EscapeDatastoreItem(unescapedDirectoryAndFileName + strlen(unescapedDirectoryName) + 1); if (!fileName) goto cleanup; if (virAsprintf(&datastorePathWithoutFileName, "[%s] %s", pool->name, directoryName) < 0) goto cleanup; if (virAsprintf(&datastorePath, "[%s] %s/%s", pool->name, directoryName, fileName) < 0) goto cleanup; /* Create directory, if it doesn't exist yet */ if (esxVI_LookupFileInfoByDatastorePath (priv->primary, datastorePathWithoutFileName, true, &fileInfo, esxVI_Occurrence_OptionalItem) < 0) { goto cleanup; } if (!fileInfo) { if (esxVI_MakeDirectory(priv->primary, datastorePathWithoutFileName, priv->primary->datacenter->_reference, esxVI_Boolean_True) < 0) { goto cleanup; } } /* Copy VirtualDisk */ if (esxVI_CopyVirtualDisk_Task(priv->primary, sourceDatastorePath, priv->primary->datacenter->_reference, datastorePath, priv->primary->datacenter->_reference, NULL, esxVI_Boolean_False, &task) < 0 || esxVI_WaitForTaskCompletion(priv->primary, task, NULL, esxVI_Occurrence_None, priv->parsedUri->autoAnswer, &taskInfoState, &taskInfoErrorMessage) < 0) { goto cleanup; } if (taskInfoState != esxVI_TaskInfoState_Success) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not copy volume: %s"), taskInfoErrorMessage); goto cleanup; } if (priv->primary->hasQueryVirtualDiskUuid) { if (VIR_ALLOC_N(key, VIR_UUID_STRING_BUFLEN) < 0) goto cleanup; if (esxVI_QueryVirtualDiskUuid(priv->primary, datastorePath, priv->primary->datacenter->_reference, &uuid_string) < 0) { goto cleanup; } if (esxUtil_ReformatUuid(uuid_string, key) < 0) goto cleanup; } else { /* Fall back to the path as key */ if (VIR_STRDUP(key, datastorePath) < 0) goto cleanup; } } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("Creation of %s volumes is not supported"), virStorageFileFormatTypeToString(def->target.format)); goto cleanup; } volume = virGetStorageVol(pool->conn, pool->name, def->name, key, &esxStorageBackendVMFS, NULL); cleanup: VIR_FREE(sourceDatastorePath); virStorageVolDefFree(def); VIR_FREE(unescapedDatastorePath); VIR_FREE(unescapedDirectoryName); VIR_FREE(unescapedDirectoryAndFileName); VIR_FREE(directoryName); VIR_FREE(fileName); VIR_FREE(datastorePathWithoutFileName); VIR_FREE(datastorePath); esxVI_FileInfo_Free(&fileInfo); esxVI_ManagedObjectReference_Free(&task); VIR_FREE(taskInfoErrorMessage); VIR_FREE(uuid_string); VIR_FREE(key); return volume; }
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 virStorageVolPtr parallelsStorageVolCreateXMLFrom(virStoragePoolPtr pool, const char *xmldesc, virStorageVolPtr clonevol, unsigned int flags) { parallelsConnPtr privconn = pool->conn->privateData; virStoragePoolObjPtr privpool; virStorageVolDefPtr privvol = NULL, origvol = NULL; virStorageVolPtr ret = NULL; virCheckFlags(0, NULL); parallelsDriverLock(privconn); privpool = virStoragePoolObjFindByName(&privconn->pools, pool->name); parallelsDriverUnlock(privconn); if (privpool == NULL) { parallelsPoolNotFoundError(pool->name); goto cleanup; } if (!virStoragePoolObjIsActive(privpool)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; } privvol = virStorageVolDefParseString(privpool->def, xmldesc); if (privvol == NULL) goto cleanup; if (virStorageVolDefFindByName(privpool, privvol->name)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("storage vol already exists")); goto cleanup; } origvol = virStorageVolDefFindByName(privpool, clonevol->name); if (!origvol) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), clonevol->name); goto cleanup; } /* Make sure enough space */ if ((privpool->def->allocation + privvol->target.allocation) > privpool->def->capacity) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Not enough free space in pool for volume '%s'"), privvol->name); goto cleanup; } privpool->def->available = (privpool->def->capacity - privpool->def->allocation); if (virAsprintf(&privvol->target.path, "%s/%s", privpool->def->target.path, privvol->name) == -1) goto cleanup; if (VIR_STRDUP(privvol->key, privvol->target.path) < 0) goto cleanup; privpool->def->allocation += privvol->target.allocation; privpool->def->available = (privpool->def->capacity - privpool->def->allocation); if (VIR_APPEND_ELEMENT_COPY(privpool->volumes.objs, privpool->volumes.count, privvol) < 0) goto cleanup; ret = virGetStorageVol(pool->conn, privpool->def->name, privvol->name, privvol->key, NULL, NULL); privvol = NULL; cleanup: virStorageVolDefFree(privvol); if (privpool) virStoragePoolObjUnlock(privpool); return ret; }