mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Extend the ESX URL to habdle ports and GSX
* src/esx/esx_driver.c src/esx/esx_vi.[ch] src/esx/esx_vmx.[ch]: adds version checking for GSX 2.0, allows to pass a specific port for the connection and also add a new specific gsx scheme for easier connections to GSX hosts
This commit is contained in:
parent
8feb499ba2
commit
10a4e969a6
@ -67,16 +67,23 @@ typedef struct _esxPrivate {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* URI format: esx://[<user>@]<server>[?transport={http|https}][&vcenter=<vcenter>][&no_verify={0|1}]
|
* URI format: {esx|gsx}://[<user>@]<server>[:<port>][?transport={http|https}][&vcenter=<vcenter>][&no_verify={0|1}]
|
||||||
* esx:///phantom
|
* esx:///phantom
|
||||||
*
|
*
|
||||||
|
* If no port is specified the default port is set dependent on the scheme and
|
||||||
|
* transport parameter:
|
||||||
|
* - esx+http 80
|
||||||
|
* - esx+https 433
|
||||||
|
* - gsx+http 8222
|
||||||
|
* - gsx+https 8333
|
||||||
|
*
|
||||||
* If no transport parameter is specified https is used.
|
* If no transport parameter is specified https is used.
|
||||||
*
|
*
|
||||||
* The vcenter parameter is only necessary for migration, because the vCenter
|
* The vcenter parameter is only necessary for migration, because the vCenter
|
||||||
* server is in charge to initiate a migration between two ESX hosts.
|
* server is in charge to initiate a migration between two ESX hosts.
|
||||||
*
|
*
|
||||||
* If the no_verify parameter is set to 1, this disables libcurl client checks
|
* If the no_verify parameter is set to 1, this disables libcurl client checks
|
||||||
* of the server's certificate.
|
* of the server's certificate. The default value it 0.
|
||||||
*
|
*
|
||||||
* The esx:///phantom URI may be used for tasks that don't require an actual
|
* The esx:///phantom URI may be used for tasks that don't require an actual
|
||||||
* connection to the hypervisor like domxml-{from,to}-native:
|
* connection to the hypervisor like domxml-{from,to}-native:
|
||||||
@ -95,9 +102,10 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
|
|||||||
char *password = NULL;
|
char *password = NULL;
|
||||||
int phantom = 0; // boolean
|
int phantom = 0; // boolean
|
||||||
|
|
||||||
/* Decline if the URI is NULL or the scheme is not 'esx' */
|
/* Decline if the URI is NULL or the scheme is neither 'esx' nor 'gsx' */
|
||||||
if (conn->uri == NULL || conn->uri->scheme == NULL ||
|
if (conn->uri == NULL || conn->uri->scheme == NULL ||
|
||||||
STRNEQ(conn->uri->scheme, "esx")) {
|
(STRCASENEQ(conn->uri->scheme, "esx") &&
|
||||||
|
STRCASENEQ(conn->uri->scheme, "gsx"))) {
|
||||||
return VIR_DRV_OPEN_DECLINED;
|
return VIR_DRV_OPEN_DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,8 +155,30 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virAsprintf(&url, "%s://%s/sdk", priv->transport,
|
/*
|
||||||
conn->uri->server) < 0) {
|
* Set the port dependent on the transport protocol if no port is
|
||||||
|
* specified. This allows us to rely on the port parameter being
|
||||||
|
* correctly set when building URIs later on, without the need to
|
||||||
|
* distinguish between the situations port == 0 and port != 0
|
||||||
|
*/
|
||||||
|
if (conn->uri->port == 0) {
|
||||||
|
if (STRCASEEQ(conn->uri->scheme, "esx")) {
|
||||||
|
if (STRCASEEQ(priv->transport, "https")) {
|
||||||
|
conn->uri->port = 443;
|
||||||
|
} else {
|
||||||
|
conn->uri->port = 80;
|
||||||
|
}
|
||||||
|
} else { /* GSX */
|
||||||
|
if (STRCASEEQ(priv->transport, "https")) {
|
||||||
|
conn->uri->port = 8333;
|
||||||
|
} else {
|
||||||
|
conn->uri->port = 8222;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport,
|
||||||
|
conn->uri->server, conn->uri->port) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
@ -185,6 +215,22 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (STRCASEEQ(conn->uri->scheme, "esx")) {
|
||||||
|
if (priv->host->productVersion != esxVI_ProductVersion_ESX35 &&
|
||||||
|
priv->host->productVersion != esxVI_ProductVersion_ESX40) {
|
||||||
|
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s is neither an ESX 3.5 host nor an ESX 4.0 host",
|
||||||
|
conn->uri->server);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
} else { /* GSX */
|
||||||
|
if (priv->host->productVersion != esxVI_ProductVersion_GSX20) {
|
||||||
|
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s isn't a GSX 2.0 host", conn->uri->server);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VIR_FREE(url);
|
VIR_FREE(url);
|
||||||
VIR_FREE(password);
|
VIR_FREE(password);
|
||||||
VIR_FREE(username);
|
VIR_FREE(username);
|
||||||
@ -221,6 +267,15 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->vcenter->productVersion != esxVI_ProductVersion_VPX25 &&
|
||||||
|
priv->vcenter->productVersion != esxVI_ProductVersion_VPX40) {
|
||||||
|
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s is neither a vCenter 2.5 server nor a vCenter "
|
||||||
|
"4.0 server",
|
||||||
|
conn->uri->server);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
VIR_FREE(url);
|
VIR_FREE(url);
|
||||||
VIR_FREE(password);
|
VIR_FREE(password);
|
||||||
VIR_FREE(username);
|
VIR_FREE(username);
|
||||||
@ -1996,10 +2051,10 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virAsprintf(&url, "%s://%s/folder/%s?dcPath=%s&dsName=%s",
|
if (virAsprintf(&url, "%s://%s:%d/folder/%s?dcPath=%s&dsName=%s",
|
||||||
priv->transport, domain->conn->uri->server,
|
priv->transport, domain->conn->uri->server,
|
||||||
vmxPath, priv->host->datacenter->value,
|
domain->conn->uri->port, vmxPath,
|
||||||
datastoreName) < 0) {
|
priv->host->datacenter->value, datastoreName) < 0) {
|
||||||
virReportOOMError(domain->conn);
|
virReportOOMError(domain->conn);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
@ -2008,7 +2063,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
def = esxVMX_ParseConfig(domain->conn, vmx, priv->host->serverVersion);
|
def = esxVMX_ParseConfig(domain->conn, vmx, priv->host->apiVersion);
|
||||||
|
|
||||||
if (def != NULL) {
|
if (def != NULL) {
|
||||||
xml = virDomainDefFormat(domain->conn, def, flags);
|
xml = virDomainDefFormat(domain->conn, def, flags);
|
||||||
@ -2039,7 +2094,7 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
|
|||||||
unsigned int flags ATTRIBUTE_UNUSED)
|
unsigned int flags ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
esxPrivate *priv = (esxPrivate *)conn->privateData;
|
esxPrivate *priv = (esxPrivate *)conn->privateData;
|
||||||
int serverVersion = -1;
|
esxVI_APIVersion apiVersion = esxVI_APIVersion_Unknown;
|
||||||
virDomainDefPtr def = NULL;
|
virDomainDefPtr def = NULL;
|
||||||
char *xml = NULL;
|
char *xml = NULL;
|
||||||
|
|
||||||
@ -2050,10 +2105,10 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! priv->phantom) {
|
if (! priv->phantom) {
|
||||||
serverVersion = priv->host->serverVersion;
|
apiVersion = priv->host->apiVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
def = esxVMX_ParseConfig(conn, nativeConfig, serverVersion);
|
def = esxVMX_ParseConfig(conn, nativeConfig, apiVersion);
|
||||||
|
|
||||||
if (def != NULL) {
|
if (def != NULL) {
|
||||||
xml = virDomainDefFormat(conn, def, VIR_DOMAIN_XML_INACTIVE);
|
xml = virDomainDefFormat(conn, def, VIR_DOMAIN_XML_INACTIVE);
|
||||||
@ -2581,8 +2636,8 @@ esxDomainMigratePrepare(virConnectPtr dconn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virAsprintf(uri_out, "%s://%s/sdk", transport,
|
if (virAsprintf(uri_out, "%s://%s:%d/sdk", transport,
|
||||||
dconn->uri->server) < 0) {
|
dconn->uri->server, dconn->uri->port) < 0) {
|
||||||
virReportOOMError(dconn);
|
virReportOOMError(dconn);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
@ -270,9 +270,9 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
|
|||||||
if (STREQ(ctx->service->about->apiType, "HostAgent") ||
|
if (STREQ(ctx->service->about->apiType, "HostAgent") ||
|
||||||
STREQ(ctx->service->about->apiType, "VirtualCenter")) {
|
STREQ(ctx->service->about->apiType, "VirtualCenter")) {
|
||||||
if (STRPREFIX(ctx->service->about->apiVersion, "2.5")) {
|
if (STRPREFIX(ctx->service->about->apiVersion, "2.5")) {
|
||||||
ctx->apiVersion = 25;
|
ctx->apiVersion = esxVI_APIVersion_25;
|
||||||
} else if (STRPREFIX(ctx->service->about->apiVersion, "4.0")) {
|
} else if (STRPREFIX(ctx->service->about->apiVersion, "4.0")) {
|
||||||
ctx->apiVersion = 40;
|
ctx->apiVersion = esxVI_APIVersion_40;
|
||||||
} else {
|
} else {
|
||||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
"Expecting VI API major/minor version '2.5' or '4.0' "
|
"Expecting VI API major/minor version '2.5' or '4.0' "
|
||||||
@ -280,14 +280,44 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STRPREFIX(ctx->service->about->version, "3.5")) {
|
if (STREQ(ctx->service->about->productLineId, "gsx")) {
|
||||||
ctx->serverVersion = 35;
|
if (STRPREFIX(ctx->service->about->version, "2.0")) {
|
||||||
} else if (STRPREFIX(ctx->service->about->version, "4.0")) {
|
ctx->productVersion = esxVI_ProductVersion_GSX20;
|
||||||
ctx->serverVersion = 40;
|
} else {
|
||||||
|
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Expecting GSX major/minor version '2.0' but "
|
||||||
|
"found '%s'", ctx->service->about->version);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
} else if (STREQ(ctx->service->about->productLineId, "esx") ||
|
||||||
|
STREQ(ctx->service->about->productLineId, "embeddedEsx")) {
|
||||||
|
if (STRPREFIX(ctx->service->about->version, "3.5")) {
|
||||||
|
ctx->productVersion = esxVI_ProductVersion_ESX35;
|
||||||
|
} else if (STRPREFIX(ctx->service->about->version, "4.0")) {
|
||||||
|
ctx->productVersion = esxVI_ProductVersion_ESX40;
|
||||||
|
} else {
|
||||||
|
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Expecting ESX major/minor version '3.5' or "
|
||||||
|
"'4.0' but found '%s'",
|
||||||
|
ctx->service->about->version);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
} else if (STREQ(ctx->service->about->productLineId, "vpx")) {
|
||||||
|
if (STRPREFIX(ctx->service->about->version, "2.5")) {
|
||||||
|
ctx->productVersion = esxVI_ProductVersion_VPX25;
|
||||||
|
} else if (STRPREFIX(ctx->service->about->version, "4.0")) {
|
||||||
|
ctx->productVersion = esxVI_ProductVersion_VPX40;
|
||||||
|
} else {
|
||||||
|
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Expecting VPX major/minor version '2.5' or '4.0' "
|
||||||
|
"but found '%s'", ctx->service->about->version);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
"Expecting server major/minor version '3.5' or '4.0' "
|
"Expecting product 'gsx' or 'esx' or 'embeddedEsx' "
|
||||||
"but found '%s'", ctx->service->about->version);
|
"or 'vpx' but found '%s'",
|
||||||
|
ctx->service->about->productLineId);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
#include "esx_vi_types.h"
|
#include "esx_vi_types.h"
|
||||||
|
|
||||||
|
typedef enum _esxVI_APIVersion esxVI_APIVersion;
|
||||||
|
typedef enum _esxVI_ProductVersion esxVI_ProductVersion;
|
||||||
typedef struct _esxVI_Context esxVI_Context;
|
typedef struct _esxVI_Context esxVI_Context;
|
||||||
typedef struct _esxVI_RemoteResponse esxVI_RemoteResponse;
|
typedef struct _esxVI_RemoteResponse esxVI_RemoteResponse;
|
||||||
typedef struct _esxVI_RemoteRequest esxVI_RemoteRequest;
|
typedef struct _esxVI_RemoteRequest esxVI_RemoteRequest;
|
||||||
@ -40,6 +42,24 @@ typedef struct _esxVI_List esxVI_List;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum _esxVI_APIVersion {
|
||||||
|
esxVI_APIVersion_Undefined = 0,
|
||||||
|
esxVI_APIVersion_Unknown,
|
||||||
|
esxVI_APIVersion_25,
|
||||||
|
esxVI_APIVersion_40
|
||||||
|
};
|
||||||
|
|
||||||
|
enum _esxVI_ProductVersion {
|
||||||
|
esxVI_ProductVersion_Undefined = 0,
|
||||||
|
esxVI_ProductVersion_GSX20,
|
||||||
|
esxVI_ProductVersion_ESX35,
|
||||||
|
esxVI_ProductVersion_ESX40,
|
||||||
|
esxVI_ProductVersion_VPX25,
|
||||||
|
esxVI_ProductVersion_VPX40
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* Context
|
* Context
|
||||||
*/
|
*/
|
||||||
@ -52,8 +72,8 @@ struct _esxVI_Context {
|
|||||||
char *username;
|
char *username;
|
||||||
char *password;
|
char *password;
|
||||||
esxVI_ServiceContent *service;
|
esxVI_ServiceContent *service;
|
||||||
int apiVersion;
|
esxVI_APIVersion apiVersion;
|
||||||
int serverVersion;
|
esxVI_ProductVersion productVersion;
|
||||||
esxVI_UserSession *session;
|
esxVI_UserSession *session;
|
||||||
esxVI_ManagedObjectReference *datacenter;
|
esxVI_ManagedObjectReference *datacenter;
|
||||||
esxVI_ManagedObjectReference *vmFolder;
|
esxVI_ManagedObjectReference *vmFolder;
|
||||||
|
@ -406,7 +406,8 @@ def->parallels[0]...
|
|||||||
|
|
||||||
|
|
||||||
virDomainDefPtr
|
virDomainDefPtr
|
||||||
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx, int serverVersion)
|
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||||
|
esxVI_APIVersion apiVersion)
|
||||||
{
|
{
|
||||||
virConfPtr conf = NULL;
|
virConfPtr conf = NULL;
|
||||||
virDomainDefPtr def = NULL;
|
virDomainDefPtr def = NULL;
|
||||||
@ -453,28 +454,28 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx, int serverVersion)
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (serverVersion) {
|
switch (apiVersion) {
|
||||||
case 35:
|
case esxVI_APIVersion_25:
|
||||||
if (virtualHW_version != 4) {
|
if (virtualHW_version != 4) {
|
||||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
"Expecting VMX entry 'virtualHW.version' to be 4 for "
|
"Expecting VMX entry 'virtualHW.version' to be 4 for "
|
||||||
"server version 3.5 but found %lld", virtualHW_version);
|
"VI API version 2.5 but found %lld", virtualHW_version);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40:
|
case esxVI_APIVersion_40:
|
||||||
if (virtualHW_version != 7) {
|
if (virtualHW_version != 7) {
|
||||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
"Expecting VMX entry 'virtualHW.version' to be 7 for "
|
"Expecting VMX entry 'virtualHW.version' to be 7 for "
|
||||||
"server version 4.0 but found %lld", virtualHW_version);
|
"VI API version 4.0 but found %lld", virtualHW_version);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1:
|
case esxVI_APIVersion_Unknown:
|
||||||
if (virtualHW_version != 4 && virtualHW_version != 7) {
|
if (virtualHW_version != 4 && virtualHW_version != 7) {
|
||||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
"Expecting VMX entry 'virtualHW.version' to be 4 or 7 "
|
"Expecting VMX entry 'virtualHW.version' to be 4 or 7 "
|
||||||
@ -486,8 +487,7 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx, int serverVersion)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
"Expecting server version 3.5 or 4.0 but got %d",
|
"Expecting VI API version 2.5 or 4.0");
|
||||||
serverVersion);
|
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1343,6 +1343,7 @@ esxVMX_ParseEthernet(virConnectPtr conn, virConfPtr conf, int controller,
|
|||||||
ESX_BUILD_VMX_NAME(generatedAddress);
|
ESX_BUILD_VMX_NAME(generatedAddress);
|
||||||
ESX_BUILD_VMX_NAME(address);
|
ESX_BUILD_VMX_NAME(address);
|
||||||
ESX_BUILD_VMX_NAME(virtualDev);
|
ESX_BUILD_VMX_NAME(virtualDev);
|
||||||
|
ESX_BUILD_VMX_NAME(vnet);
|
||||||
|
|
||||||
/* vmx:present */
|
/* vmx:present */
|
||||||
if (esxUtil_GetConfigBoolean(conn, conf, present_name,
|
if (esxUtil_GetConfigBoolean(conn, conf, present_name,
|
||||||
|
@ -25,13 +25,15 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "domain_conf.h"
|
#include "domain_conf.h"
|
||||||
|
#include "esx_vi.h"
|
||||||
|
|
||||||
virDomainDefPtr
|
virDomainDefPtr
|
||||||
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx, int serverVersion);
|
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||||
|
esxVI_APIVersion apiVersion);
|
||||||
|
|
||||||
int
|
int
|
||||||
esxVMX_ParseSCSIController(virConnectPtr conn, virConfPtr conf,
|
esxVMX_ParseSCSIController(virConnectPtr conn, virConfPtr conf,
|
||||||
int controller, int *present, char **virtualDev);
|
int controller, int *present, char **virtualDev);
|
||||||
|
|
||||||
char *
|
char *
|
||||||
esxVMX_IndexToDiskName(virConnectPtr conn, int idx, const char *prefix);
|
esxVMX_IndexToDiskName(virConnectPtr conn, int idx, const char *prefix);
|
||||||
|
Loading…
Reference in New Issue
Block a user