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;
}
Esempio n. 2
0
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;
}