[libvirt] [PATCH] esx: Simplify goto usage (part 1/2)
by Matthias Bolte
Eliminate almost all backward jumps by replacing this common pattern:
int
some_random_function(void)
{
int result = 0;
...
cleanup:
<unconditional cleanup code>
return result;
failure:
<cleanup code in case of an error>
result = -1;
goto cleanup
}
with this simpler pattern:
int
some_random_function(void)
{
int result = -1;
...
result = 0;
cleanup:
if (result < 0) {
<cleanup code in case of an error>
}
<unconditional cleanup code>
return result;
}
Add a bool success variable in functions that don't have a int result
that can be used for the new pattern.
Also remove some unnecessary memsets in error paths.
---
I've split this 200kb patch into two 100kb parts.
Part 1:
src/esx/esx_driver.c | 840 ++++++++++++++++++------------------------
src/esx/esx_storage_driver.c | 4 -
src/esx/esx_util.c | 74 ++--
Part 2:
src/esx/esx_vi.c | 488 +++++++++++--------------
src/esx/esx_vi_methods.c | 44 +--
src/esx/esx_vi_types.c | 23 +-
src/esx/esx_vmx.c | 298 ++++++++-------
7 files changed, 793 insertions(+), 978 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index b89de72..7257d6a 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -68,7 +68,7 @@ esxSupportsLongMode(esxPrivate *priv)
}
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return esxVI_Boolean_Undefined;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -76,13 +76,13 @@ esxSupportsLongMode(esxPrivate *priv)
esxVI_LookupObjectContentByType(priv->host, priv->host->hostFolder,
"HostSystem", propertyNameList,
esxVI_Boolean_True, &hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
if (hostSystem == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not retrieve the HostSystem object"));
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
@@ -90,7 +90,7 @@ esxSupportsLongMode(esxPrivate *priv)
if (STREQ(dynamicProperty->name, "hardware.cpuFeature")) {
if (esxVI_HostCpuIdInfo_CastListFromAnyType
(dynamicProperty->val, &hostCpuIdInfoList) < 0) {
- goto failure;
+ goto cleanup;
}
for (hostCpuIdInfo = hostCpuIdInfoList; hostCpuIdInfo != NULL;
@@ -98,7 +98,7 @@ esxSupportsLongMode(esxPrivate *priv)
if (hostCpuIdInfo->level->value == -2147483647) { /* 0x80000001 */
if (esxVI_ParseHostCpuIdInfo(&parsedHostCpuIdInfo,
hostCpuIdInfo) < 0) {
- goto failure;
+ goto cleanup;
}
edxLongModeBit = parsedHostCpuIdInfo.edx[29];
@@ -113,7 +113,7 @@ esxSupportsLongMode(esxPrivate *priv)
"'hardware.cpuFeature[].edx' with value '%s' "
"has unexpected value '%c', expecting '0' "
"or '1'"), hostCpuIdInfo->edx, edxLongModeBit);
- goto failure;
+ goto cleanup;
}
break;
@@ -127,16 +127,15 @@ esxSupportsLongMode(esxPrivate *priv)
}
cleanup:
+ /*
+ * If we goto cleanup in case of an error then priv->supportsLongMode
+ * is still esxVI_Boolean_Undefined, therefore we don't need to set it.
+ */
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&hostSystem);
esxVI_HostCpuIdInfo_Free(&hostCpuIdInfoList);
return priv->supportsLongMode;
-
- failure:
- priv->supportsLongMode = esxVI_Boolean_Undefined;
-
- goto cleanup;
}
@@ -313,7 +312,7 @@ esxCapsInit(esxPrivate *priv)
static virDrvOpenStatus
esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
{
- virDrvOpenStatus result = VIR_DRV_OPEN_SUCCESS;
+ virDrvOpenStatus result = VIR_DRV_OPEN_ERROR;
esxPrivate *priv = NULL;
char hostIpAddress[NI_MAXHOST] = "";
char vCenterIpAddress[NI_MAXHOST] = "";
@@ -347,7 +346,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
/* Allocate per-connection private data */
if (VIR_ALLOC(priv) < 0) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
priv->maxVcpus = -1;
@@ -358,7 +357,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
if (esxUtil_ParseQuery(conn->uri, &priv->transport, &vCenter, &noVerify,
&autoAnswer) < 0) {
- goto failure;
+ goto cleanup;
}
if (autoAnswer) {
@@ -390,13 +389,13 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
/* Login to host */
if (esxUtil_ResolveHostname(conn->uri->server, hostIpAddress,
NI_MAXHOST) < 0) {
- goto failure;
+ goto cleanup;
}
if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport,
conn->uri->server, conn->uri->port) < 0) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
if (conn->uri->user != NULL) {
@@ -404,31 +403,31 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
if (username == NULL) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
} else {
username = virRequestUsername(auth, "root", conn->uri->server);
if (username == NULL) {
ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
- goto failure;
+ goto cleanup;
}
}
if (esxVI_Context_Alloc(&priv->host) < 0) {
- goto failure;
+ goto cleanup;
}
password = virRequestPassword(auth, username, conn->uri->server);
if (password == NULL) {
ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
- goto failure;
+ goto cleanup;
}
if (esxVI_Context_Connect(priv->host, url, hostIpAddress, username,
password, noVerify) < 0) {
- goto failure;
+ goto cleanup;
}
if (STRCASEEQ(conn->uri->scheme, "esx")) {
@@ -437,13 +436,13 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("%s is neither an ESX 3.5 host nor an ESX 4.0 host"),
conn->uri->server);
- goto failure;
+ goto cleanup;
}
} else { /* GSX */
if (priv->host->productVersion != esxVI_ProductVersion_GSX20) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("%s isn't a GSX 2.0 host"), conn->uri->server);
- goto failure;
+ goto cleanup;
}
}
@@ -453,7 +452,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
"summary.managementServerIp\0") < 0 ||
esxVI_LookupHostSystemByIp(priv->host, hostIpAddress, propertyNameList,
&hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
/* Warn if host is in maintenance mode */
@@ -462,7 +461,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
if (STREQ(dynamicProperty->name, "runtime.inMaintenanceMode")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Boolean) < 0) {
- goto failure;
+ goto cleanup;
}
if (dynamicProperty->val->boolean == esxVI_Boolean_True) {
@@ -483,7 +482,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
if (STRNEQ(vCenter, "*") &&
esxUtil_ResolveHostname(vCenter, vCenterIpAddress,
NI_MAXHOST) < 0) {
- goto failure;
+ goto cleanup;
}
/* Lookup the vCenter from the ESX host */
@@ -492,7 +491,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
if (STREQ(dynamicProperty->name, "summary.managementServerIp")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
- goto failure;
+ goto cleanup;
}
/* Get the vCenter IP address or verify the specified one */
@@ -503,7 +502,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
if (vCenter == NULL) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
if (virStrcpyStatic(vCenterIpAddress,
@@ -512,7 +511,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
_("vCenter IP address %s too big for "
"destination"),
dynamicProperty->val->string);
- goto failure;
+ goto cleanup;
}
} else if (STRNEQ(vCenterIpAddress,
dynamicProperty->val->string)) {
@@ -522,7 +521,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
"(%s) has been specified"),
dynamicProperty->val->string, vCenter,
vCenterIpAddress);
- goto failure;
+ goto cleanup;
}
break;
@@ -532,36 +531,36 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
if (STREQ(vCenter, "*")) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("This host is not managed by a vCenter"));
- goto failure;
+ goto cleanup;
}
if (virAsprintf(&url, "%s://%s/sdk", priv->transport,
vCenter) < 0) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
if (esxVI_Context_Alloc(&priv->vCenter) < 0) {
- goto failure;
+ goto cleanup;
}
username = virRequestUsername(auth, "administrator", vCenter);
if (username == NULL) {
ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
- goto failure;
+ goto cleanup;
}
password = virRequestPassword(auth, username, vCenter);
if (password == NULL) {
ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
- goto failure;
+ goto cleanup;
}
if (esxVI_Context_Connect(priv->vCenter, url, vCenterIpAddress,
username, password, noVerify) < 0) {
- goto failure;
+ goto cleanup;
}
if (priv->vCenter->productVersion != esxVI_ProductVersion_VPX25 &&
@@ -569,7 +568,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("%s is neither a vCenter 2.5 server nor a vCenter "
"4.0 server"), conn->uri->server);
- goto failure;
+ goto cleanup;
}
}
@@ -579,21 +578,13 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
priv->caps = esxCapsInit(priv);
if (priv->caps == NULL) {
- goto failure;
+ goto cleanup;
}
- cleanup:
- VIR_FREE(url);
- VIR_FREE(vCenter);
- VIR_FREE(password);
- VIR_FREE(username);
- esxVI_String_Free(&propertyNameList);
- esxVI_ObjectContent_Free(&hostSystem);
-
- return result;
+ result = VIR_DRV_OPEN_SUCCESS;
- failure:
- if (priv != NULL) {
+ cleanup:
+ if (result == VIR_DRV_OPEN_ERROR && priv != NULL) {
esxVI_Context_Free(&priv->host);
esxVI_Context_Free(&priv->vCenter);
@@ -603,9 +594,14 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
VIR_FREE(priv);
}
- result = VIR_DRV_OPEN_ERROR;
+ VIR_FREE(url);
+ VIR_FREE(vCenter);
+ VIR_FREE(password);
+ VIR_FREE(username);
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostSystem);
- goto cleanup;
+ return result;
}
@@ -656,7 +652,7 @@ esxSupportsVMotion(esxPrivate *priv)
}
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return esxVI_Boolean_Undefined;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -664,13 +660,13 @@ esxSupportsVMotion(esxPrivate *priv)
esxVI_LookupObjectContentByType(priv->host, priv->host->hostFolder,
"HostSystem", propertyNameList,
esxVI_Boolean_True, &hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
if (hostSystem == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not retrieve the HostSystem object"));
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
@@ -678,7 +674,7 @@ esxSupportsVMotion(esxPrivate *priv)
if (STREQ(dynamicProperty->name, "capability.vmotionSupported")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Boolean) < 0) {
- goto failure;
+ goto cleanup;
}
priv->supportsVMotion = dynamicProperty->val->boolean;
@@ -689,15 +685,14 @@ esxSupportsVMotion(esxPrivate *priv)
}
cleanup:
+ /*
+ * If we goto cleanup in case of an error then priv->supportsVMotion is
+ * still esxVI_Boolean_Undefined, therefore we don't need to set it.
+ */
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&hostSystem);
return priv->supportsVMotion;
-
- failure:
- priv->supportsVMotion = esxVI_Boolean_Undefined;
-
- goto cleanup;
}
@@ -766,7 +761,7 @@ esxGetHostname(virConnectPtr conn)
char *complete = NULL;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return NULL;
}
if (esxVI_String_AppendValueListToList
@@ -776,13 +771,13 @@ esxGetHostname(virConnectPtr conn)
esxVI_LookupObjectContentByType(priv->host, priv->host->hostFolder,
"HostSystem", propertyNameList,
esxVI_Boolean_True, &hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
if (hostSystem == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not retrieve the HostSystem object"));
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
@@ -791,7 +786,7 @@ esxGetHostname(virConnectPtr conn)
"config.network.dnsConfig.hostName")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
- goto failure;
+ goto cleanup;
}
hostName = dynamicProperty->val->string;
@@ -799,7 +794,7 @@ esxGetHostname(virConnectPtr conn)
"config.network.dnsConfig.domainName")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
- goto failure;
+ goto cleanup;
}
domainName = dynamicProperty->val->string;
@@ -811,7 +806,7 @@ esxGetHostname(virConnectPtr conn)
if (hostName == NULL || strlen(hostName) < 1) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing or empty 'hostName' property"));
- goto failure;
+ goto cleanup;
}
if (domainName == NULL || strlen(domainName) < 1) {
@@ -819,25 +814,25 @@ esxGetHostname(virConnectPtr conn)
if (complete == NULL) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
} else {
if (virAsprintf(&complete, "%s.%s", hostName, domainName) < 0) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
}
cleanup:
+ /*
+ * If we goto cleanup in case of an error then complete is still NULL,
+ * either strdup returned NULL or virAsprintf failed. When virAsprintf
+ * fails it guarantees setting complete to NULL
+ */
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&hostSystem);
return complete;
-
- failure:
- VIR_FREE(complete);
-
- goto cleanup;
}
@@ -845,7 +840,7 @@ esxGetHostname(virConnectPtr conn)
static int
esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = conn->privateData;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *hostSystem = NULL;
@@ -858,10 +853,10 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
int32_t numaInfo_numNodes = 0;
char *ptr = NULL;
- memset(nodeinfo, 0, sizeof(virNodeInfo));
+ memset(nodeinfo, 0, sizeof (*nodeinfo));
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
@@ -875,13 +870,13 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
esxVI_LookupObjectContentByType(priv->host, priv->host->hostFolder,
"HostSystem", propertyNameList,
esxVI_Boolean_True, &hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
if (hostSystem == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not retrieve the HostSystem object"));
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
@@ -889,7 +884,7 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
if (STREQ(dynamicProperty->name, "hardware.cpuInfo.hz")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Long) < 0) {
- goto failure;
+ goto cleanup;
}
cpuInfo_hz = dynamicProperty->val->int64;
@@ -897,7 +892,7 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
"hardware.cpuInfo.numCpuCores")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Short) < 0) {
- goto failure;
+ goto cleanup;
}
cpuInfo_numCpuCores = dynamicProperty->val->int16;
@@ -905,7 +900,7 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
"hardware.cpuInfo.numCpuPackages")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Short) < 0) {
- goto failure;
+ goto cleanup;
}
cpuInfo_numCpuPackages = dynamicProperty->val->int16;
@@ -913,14 +908,14 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
"hardware.cpuInfo.numCpuThreads")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Short) < 0) {
- goto failure;
+ goto cleanup;
}
cpuInfo_numCpuThreads = dynamicProperty->val->int16;
} else if (STREQ(dynamicProperty->name, "hardware.memorySize")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Long) < 0) {
- goto failure;
+ goto cleanup;
}
memorySize = dynamicProperty->val->int64;
@@ -928,7 +923,7 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
"hardware.numaInfo.numNodes")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Int) < 0) {
- goto failure;
+ goto cleanup;
}
numaInfo_numNodes = dynamicProperty->val->int32;
@@ -936,7 +931,7 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
"summary.hardware.cpuModel")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
- goto failure;
+ goto cleanup;
}
ptr = dynamicProperty->val->string;
@@ -963,7 +958,7 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("CPU Model %s too long for destination"),
dynamicProperty->val->string);
- goto failure;
+ goto cleanup;
}
} else {
VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
@@ -982,16 +977,13 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
? cpuInfo_numCpuThreads / cpuInfo_numCpuCores
: 0;
+ result = 0;
+
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&hostSystem);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -1015,6 +1007,7 @@ esxGetCapabilities(virConnectPtr conn)
static int
esxListDomains(virConnectPtr conn, int *ids, int maxids)
{
+ bool success = false;
esxPrivate *priv = conn->privateData;
esxVI_ObjectContent *virtualMachineList = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
@@ -1032,7 +1025,7 @@ esxListDomains(virConnectPtr conn, int *ids, int maxids)
}
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -1041,14 +1034,14 @@ esxListDomains(virConnectPtr conn, int *ids, int maxids)
"VirtualMachine", propertyNameList,
esxVI_Boolean_True,
&virtualMachineList) < 0) {
- goto failure;
+ goto cleanup;
}
for (virtualMachine = virtualMachineList; virtualMachine != NULL;
virtualMachine = virtualMachine->_next) {
if (esxVI_GetVirtualMachinePowerState(virtualMachine,
&powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
@@ -1061,7 +1054,7 @@ esxListDomains(virConnectPtr conn, int *ids, int maxids)
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Failed to parse positive integer from '%s'"),
virtualMachine->obj->value);
- goto failure;
+ goto cleanup;
}
count++;
@@ -1071,16 +1064,13 @@ esxListDomains(virConnectPtr conn, int *ids, int maxids)
}
}
+ success = true;
+
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&virtualMachineList);
- return count;
-
- failure:
- count = -1;
-
- goto cleanup;
+ return success ? count : -1;
}
@@ -1115,7 +1105,7 @@ esxDomainLookupByID(virConnectPtr conn, int id)
virDomainPtr domain = NULL;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return NULL;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
@@ -1127,14 +1117,14 @@ esxDomainLookupByID(virConnectPtr conn, int id)
"VirtualMachine", propertyNameList,
esxVI_Boolean_True,
&virtualMachineList) < 0) {
- goto failure;
+ goto cleanup;
}
for (virtualMachine = virtualMachineList; virtualMachine != NULL;
virtualMachine = virtualMachine->_next) {
if (esxVI_GetVirtualMachinePowerState(virtualMachine,
&powerState) < 0) {
- goto failure;
+ goto cleanup;
}
/* Only running/suspended domains have an ID != -1 */
@@ -1147,7 +1137,7 @@ esxDomainLookupByID(virConnectPtr conn, int id)
if (esxVI_GetVirtualMachineIdentity(virtualMachine,
&id_candidate, &name_candidate,
uuid_candidate) < 0) {
- goto failure;
+ goto cleanup;
}
if (id != id_candidate) {
@@ -1157,7 +1147,7 @@ esxDomainLookupByID(virConnectPtr conn, int id)
domain = virGetDomain(conn, name_candidate, uuid_candidate);
if (domain == NULL) {
- goto failure;
+ goto cleanup;
}
domain->id = id;
@@ -1175,11 +1165,6 @@ esxDomainLookupByID(virConnectPtr conn, int id)
VIR_FREE(name_candidate);
return domain;
-
- failure:
- domain = NULL;
-
- goto cleanup;
}
@@ -1196,7 +1181,7 @@ esxDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
virDomainPtr domain = NULL;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return NULL;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
@@ -1207,13 +1192,13 @@ esxDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, NULL) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
domain = virGetDomain(conn, name, uuid);
if (domain == NULL) {
- goto failure;
+ goto cleanup;
}
/* Only running/suspended virtual machines have an ID != -1 */
@@ -1229,11 +1214,6 @@ esxDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
VIR_FREE(name);
return domain;
-
- failure:
- domain = NULL;
-
- goto cleanup;
}
@@ -1250,7 +1230,7 @@ esxDomainLookupByName(virConnectPtr conn, const char *name)
virDomainPtr domain = NULL;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return NULL;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
@@ -1260,28 +1240,24 @@ esxDomainLookupByName(virConnectPtr conn, const char *name)
esxVI_LookupVirtualMachineByName(priv->host, name, propertyNameList,
&virtualMachine,
esxVI_Occurrence_OptionalItem) < 0) {
- goto failure;
+ goto cleanup;
}
if (virtualMachine == NULL) {
ESX_ERROR(VIR_ERR_NO_DOMAIN, _("No domain with name '%s'"), name);
- goto failure;
+ goto cleanup;
}
- if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id, NULL, uuid) < 0) {
- goto failure;
- }
-
- if (esxVI_GetVirtualMachinePowerState(virtualMachine,
- &powerState) < 0) {
- goto failure;
+ if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id, NULL, uuid) < 0 ||
+ esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
+ goto cleanup;
}
domain = virGetDomain(conn, name, uuid);
if (domain == NULL) {
- goto failure;
+ goto cleanup;
}
/* Only running/suspended virtual machines have an ID != -1 */
@@ -1296,11 +1272,6 @@ esxDomainLookupByName(virConnectPtr conn, const char *name)
esxVI_ObjectContent_Free(&virtualMachine);
return domain;
-
- failure:
- domain = NULL;
-
- goto cleanup;
}
@@ -1308,7 +1279,7 @@ esxDomainLookupByName(virConnectPtr conn, const char *name)
static int
esxDomainSuspend(virDomainPtr domain)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_String *propertyNameList = NULL;
@@ -1317,7 +1288,7 @@ esxDomainSuspend(virDomainPtr domain)
esxVI_TaskInfoState taskInfoState;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -1326,37 +1297,34 @@ esxDomainSuspend(virDomainPtr domain)
(priv->host, domain->uuid, propertyNameList, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
_("Domain is not powered on"));
- goto failure;
+ goto cleanup;
}
if (esxVI_SuspendVM_Task(priv->host, virtualMachine->obj, &task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not suspend domain"));
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -1364,7 +1332,7 @@ esxDomainSuspend(virDomainPtr domain)
static int
esxDomainResume(virDomainPtr domain)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_String *propertyNameList = NULL;
@@ -1373,7 +1341,7 @@ esxDomainResume(virDomainPtr domain)
esxVI_TaskInfoState taskInfoState;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -1382,37 +1350,34 @@ esxDomainResume(virDomainPtr domain)
(priv->host, domain->uuid, propertyNameList, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_Suspended) {
ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not suspended"));
- goto failure;
+ goto cleanup;
}
if (esxVI_PowerOnVM_Task(priv->host, virtualMachine->obj, NULL,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not resume domain"));
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -1420,14 +1385,14 @@ esxDomainResume(virDomainPtr domain)
static int
esxDomainShutdown(virDomainPtr domain)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_String *propertyNameList = NULL;
esxVI_VirtualMachinePowerState powerState;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -1436,29 +1401,26 @@ esxDomainShutdown(virDomainPtr domain)
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
_("Domain is not powered on"));
- goto failure;
+ goto cleanup;
}
if (esxVI_ShutdownGuest(priv->host, virtualMachine->obj) < 0) {
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -1466,14 +1428,14 @@ esxDomainShutdown(virDomainPtr domain)
static int
esxDomainReboot(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_String *propertyNameList = NULL;
esxVI_VirtualMachinePowerState powerState;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -1482,29 +1444,26 @@ esxDomainReboot(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED)
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
_("Domain is not powered on"));
- goto failure;
+ goto cleanup;
}
if (esxVI_RebootGuest(priv->host, virtualMachine->obj) < 0) {
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -1512,7 +1471,7 @@ esxDomainReboot(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED)
static int
esxDomainDestroy(virDomainPtr domain)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_Context *ctx = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
@@ -1528,7 +1487,7 @@ esxDomainDestroy(virDomainPtr domain)
}
if (esxVI_EnsureSession(ctx) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -1537,37 +1496,34 @@ esxDomainDestroy(virDomainPtr domain)
(ctx, domain->uuid, propertyNameList, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) {
ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
_("Domain is not powered on"));
- goto failure;
+ goto cleanup;
}
if (esxVI_PowerOffVM_Task(ctx, virtualMachine->obj, &task) < 0 ||
esxVI_WaitForTaskCompletion(ctx, task, domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not destroy domain"));
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -1597,7 +1553,7 @@ esxDomainGetMaxMemory(virDomainPtr domain)
unsigned long memoryMB = 0;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return 0;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -1605,7 +1561,7 @@ esxDomainGetMaxMemory(virDomainPtr domain)
esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = virtualMachine->propSet; dynamicProperty != NULL;
@@ -1613,7 +1569,7 @@ esxDomainGetMaxMemory(virDomainPtr domain)
if (STREQ(dynamicProperty->name, "config.hardware.memoryMB")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Int) < 0) {
- goto failure;
+ goto cleanup;
}
if (dynamicProperty->val->int32 < 0) {
@@ -1635,11 +1591,6 @@ esxDomainGetMaxMemory(virDomainPtr domain)
esxVI_ObjectContent_Free(&virtualMachine);
return memoryMB * 1024; /* Scale from megabyte to kilobyte */
-
- failure:
- memoryMB = 0;
-
- goto cleanup;
}
@@ -1647,7 +1598,7 @@ esxDomainGetMaxMemory(virDomainPtr domain)
static int
esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_VirtualMachineConfigSpec *spec = NULL;
@@ -1655,7 +1606,7 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
esxVI_TaskInfoState taskInfoState;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
@@ -1663,7 +1614,7 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
priv->autoAnswer) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
esxVI_Long_Alloc(&spec->memoryMB) < 0) {
- goto failure;
+ goto cleanup;
}
spec->memoryMB->value =
@@ -1673,26 +1624,23 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not set max-memory to %lu kilobytes"), memory);
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -1700,7 +1648,7 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
static int
esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_VirtualMachineConfigSpec *spec = NULL;
@@ -1708,7 +1656,7 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
esxVI_TaskInfoState taskInfoState;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
@@ -1717,7 +1665,7 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
esxVI_ResourceAllocationInfo_Alloc(&spec->memoryAllocation) < 0 ||
esxVI_Long_Alloc(&spec->memoryAllocation->limit) < 0) {
- goto failure;
+ goto cleanup;
}
spec->memoryAllocation->limit->value =
@@ -1727,26 +1675,23 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not set memory to %lu kilobytes"), memory);
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -1754,7 +1699,7 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
static int
esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
@@ -1774,8 +1719,10 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
esxVI_PerfMetricIntSeries *perfMetricIntSeries = NULL;
esxVI_Long *value = NULL;
+ memset(info, 0, sizeof (*info));
+
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
@@ -1786,21 +1733,17 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
- goto failure;
+ goto cleanup;
}
info->state = VIR_DOMAIN_NOSTATE;
- info->maxMem = 0;
- info->memory = 0;
- info->nrVirtCpu = 0;
- info->cpuTime = 0; /* FIXME */
for (dynamicProperty = virtualMachine->propSet; dynamicProperty != NULL;
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "runtime.powerState")) {
if (esxVI_VirtualMachinePowerState_CastFromAnyType
(dynamicProperty->val, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
info->state = esxVI_VirtualMachinePowerState_ConvertToLibvirt
@@ -1808,14 +1751,14 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
} else if (STREQ(dynamicProperty->name, "config.hardware.memoryMB")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Int) < 0) {
- goto failure;
+ goto cleanup;
}
info->maxMem = dynamicProperty->val->int32 * 1024; /* Scale from megabyte to kilobyte */
} else if (STREQ(dynamicProperty->name, "config.hardware.numCPU")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Int) < 0) {
- goto failure;
+ goto cleanup;
}
info->nrVirtCpu = dynamicProperty->val->int32;
@@ -1823,7 +1766,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
"config.memoryAllocation.limit")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Long) < 0) {
- goto failure;
+ goto cleanup;
}
memory_limit = dynamicProperty->val->int64;
@@ -1842,18 +1785,18 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
/* Verify the cached 'used CPU time' performance counter ID */
if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) {
if (esxVI_Int_Alloc(&counterId) < 0) {
- goto failure;
+ goto cleanup;
}
counterId->value = priv->usedCpuTimeCounterId;
if (esxVI_Int_AppendToList(&counterIdList, counterId) < 0) {
- goto failure;
+ goto cleanup;
}
if (esxVI_QueryPerfCounter(priv->host, counterIdList,
&perfCounterInfo) < 0) {
- goto failure;
+ goto cleanup;
}
if (STRNEQ(perfCounterInfo->groupInfo->key, "cpu") ||
@@ -1877,7 +1820,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
if (esxVI_QueryAvailablePerfMetric(priv->host, virtualMachine->obj,
NULL, NULL, NULL,
&perfMetricIdList) < 0) {
- goto failure;
+ goto cleanup;
}
for (perfMetricId = perfMetricIdList; perfMetricId != NULL;
@@ -1889,13 +1832,13 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
if (esxVI_Int_DeepCopy(&counterId, perfMetricId->counterId) < 0 ||
esxVI_Int_AppendToList(&counterIdList, counterId) < 0) {
- goto failure;
+ goto cleanup;
}
}
if (esxVI_QueryPerfCounter(priv->host, counterIdList,
&perfCounterInfoList) < 0) {
- goto failure;
+ goto cleanup;
}
for (perfCounterInfo = perfCounterInfoList; perfCounterInfo != NULL;
@@ -1933,7 +1876,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
esxVI_Int_Alloc(&querySpec->maxSample) < 0 ||
esxVI_PerfMetricId_Alloc(&querySpec->metricId) < 0 ||
esxVI_Int_Alloc(&querySpec->metricId->counterId) < 0) {
- goto failure;
+ goto cleanup;
}
querySpec->entity = virtualMachine->obj;
@@ -1947,7 +1890,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
querySpec->entity = NULL;
querySpec->metricId->instance = NULL;
querySpec->format = NULL;
- goto failure;
+ goto cleanup;
}
for (perfEntityMetricBase = perfEntityMetricBaseList;
@@ -1986,8 +1929,15 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
querySpec->format = NULL;
VIR_DEBUG("usedCpuTimeCounterId %d END", priv->usedCpuTimeCounterId);
+
+ /*
+ * FIXME: Cannot map between realtive used-cpu-time and absolute
+ * info->cpuTime
+ */
}
+ result = 0;
+
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&virtualMachine);
@@ -1998,11 +1948,6 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
esxVI_PerfEntityMetricBase_Free(&perfEntityMetricBaseList);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -2010,7 +1955,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
static int
esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
int maxVcpus;
esxVI_ObjectContent *virtualMachine = NULL;
@@ -2021,17 +1966,17 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
if (nvcpus < 1) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
_("Requested number of virtual CPUs must at least be 1"));
- goto failure;
+ return -1;
}
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
maxVcpus = esxDomainGetMaxVcpus(domain);
if (maxVcpus < 0) {
- goto failure;
+ return -1;
}
if (nvcpus > maxVcpus) {
@@ -2039,7 +1984,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
_("Requested number of virtual CPUs is greater than max "
"allowable number of virtual CPUs for the domain: %d > %d"),
nvcpus, maxVcpus);
- goto failure;
+ return -1;
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
@@ -2047,7 +1992,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
priv->autoAnswer) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
esxVI_Int_Alloc(&spec->numCPUs) < 0) {
- goto failure;
+ goto cleanup;
}
spec->numCPUs->value = nvcpus;
@@ -2056,26 +2001,23 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not set number of virtual CPUs to %d"), nvcpus);
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -2092,8 +2034,10 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
return priv->maxVcpus;
}
+ priv->maxVcpus = -1;
+
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -2101,13 +2045,13 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
esxVI_LookupObjectContentByType(priv->host, priv->host->hostFolder,
"HostSystem", propertyNameList,
esxVI_Boolean_True, &hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
if (hostSystem == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not retrieve the HostSystem object"));
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
@@ -2115,7 +2059,7 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
if (STREQ(dynamicProperty->name, "capability.maxSupportedVcpus")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Int) < 0) {
- goto failure;
+ goto cleanup;
}
priv->maxVcpus = dynamicProperty->val->int32;
@@ -2130,11 +2074,6 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
esxVI_ObjectContent_Free(&hostSystem);
return priv->maxVcpus;
-
- failure:
- priv->maxVcpus = -1;
-
- goto cleanup;
}
@@ -2157,7 +2096,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
char *xml = NULL;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return NULL;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -2165,7 +2104,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = virtualMachine->propSet; dynamicProperty != NULL;
@@ -2173,7 +2112,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
if (STREQ(dynamicProperty->name, "config.files.vmPathName")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
- goto failure;
+ goto cleanup;
}
vmPathName = dynamicProperty->val->string;
@@ -2183,7 +2122,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
if (esxUtil_ParseDatastoreRelatedPath(vmPathName, &datastoreName,
&directoryName, &fileName) < 0) {
- goto failure;
+ goto cleanup;
}
virBufferVSprintf(&buffer, "%s://%s:%d/folder/", priv->transport,
@@ -2202,13 +2141,13 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
if (virBufferError(&buffer)) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
url = virBufferContentAndReset(&buffer);
if (esxVI_Context_DownloadFile(priv->host, url, &vmx) < 0) {
- goto failure;
+ goto cleanup;
}
def = esxVMX_ParseConfig(priv->host, vmx, datastoreName, directoryName,
@@ -2219,6 +2158,10 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
}
cleanup:
+ if (url == NULL) {
+ virBufferFreeAndReset(&buffer);
+ }
+
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&virtualMachine);
VIR_FREE(datastoreName);
@@ -2229,12 +2172,6 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
virDomainDefFree(def);
return xml;
-
- failure:
- virBufferFreeAndReset(&buffer);
- VIR_FREE(xml);
-
- goto cleanup;
}
@@ -2301,6 +2238,7 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
static int
esxListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
{
+ bool success = false;
esxPrivate *priv = conn->privateData;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *virtualMachineList = NULL;
@@ -2320,7 +2258,7 @@ esxListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
}
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
@@ -2330,14 +2268,14 @@ esxListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
"VirtualMachine", propertyNameList,
esxVI_Boolean_True,
&virtualMachineList) < 0) {
- goto failure;
+ goto cleanup;
}
for (virtualMachine = virtualMachineList; virtualMachine != NULL;
virtualMachine = virtualMachine->_next) {
if (esxVI_GetVirtualMachinePowerState(virtualMachine,
&powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState == esxVI_VirtualMachinePowerState_PoweredOn) {
@@ -2350,14 +2288,14 @@ esxListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
if (STREQ(dynamicProperty->name, "name")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
- goto failure;
+ goto cleanup;
}
names[count] = strdup(dynamicProperty->val->string);
if (names[count] == NULL) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
count++;
@@ -2370,20 +2308,21 @@ esxListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
}
}
- cleanup:
- esxVI_String_Free(&propertyNameList);
- esxVI_ObjectContent_Free(&virtualMachineList);
+ success = true;
- return count;
+ cleanup:
+ if (! success) {
+ for (i = 0; i < count; ++i) {
+ VIR_FREE(names[i]);
+ }
- failure:
- for (i = 0; i < count; ++i) {
- VIR_FREE(names[i]);
+ count = -1;
}
- count = -1;
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&virtualMachineList);
- goto cleanup;
+ return count;
}
@@ -2407,7 +2346,7 @@ esxNumberOfDefinedDomains(virConnectPtr conn)
static int
esxDomainCreate(virDomainPtr domain)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_String *propertyNameList = NULL;
@@ -2416,7 +2355,7 @@ esxDomainCreate(virDomainPtr domain)
esxVI_TaskInfoState taskInfoState;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -2426,38 +2365,35 @@ esxDomainCreate(virDomainPtr domain)
priv->autoAnswer) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine,
&powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_PoweredOff) {
ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
_("Domain is not powered off"));
- goto failure;
+ goto cleanup;
}
if (esxVI_PowerOnVM_Task(priv->host, virtualMachine->obj, NULL,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not start domain"));
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -2485,7 +2421,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
virDomainPtr domain = NULL;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return NULL;
}
/* Parse domain XML */
@@ -2493,14 +2429,14 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
VIR_DOMAIN_XML_INACTIVE);
if (def == NULL) {
- goto failure;
+ return NULL;
}
/* Check if an existing domain should be edited */
if (esxVI_LookupVirtualMachineByUuid(priv->host, def->uuid, NULL,
&virtualMachine,
esxVI_Occurrence_OptionalItem) < 0) {
- goto failure;
+ goto cleanup;
}
if (virtualMachine != NULL) {
@@ -2508,14 +2444,14 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Domain already exists, editing existing domains is not "
"supported yet"));
- goto failure;
+ goto cleanup;
}
/* Build VMX from domain XML */
vmx = esxVMX_FormatConfig(priv->host, def, priv->host->productVersion);
if (vmx == NULL) {
- goto failure;
+ goto cleanup;
}
/*
@@ -2529,7 +2465,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Domain XML doesn't contain any disks, cannot deduce "
"datastore and path for VMX file"));
- goto failure;
+ goto cleanup;
}
for (i = 0; i < def->ndisks; ++i) {
@@ -2544,26 +2480,26 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Domain XML doesn't contain any file-based harddisks, "
"cannot deduce datastore and path for VMX file"));
- goto failure;
+ goto cleanup;
}
if (disk->src == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("First file-based harddisk has no source, cannot deduce "
"datastore and path for VMX file"));
- goto failure;
+ goto cleanup;
}
if (esxUtil_ParseDatastoreRelatedPath(disk->src, &datastoreName,
&directoryName, &fileName) < 0) {
- goto failure;
+ goto cleanup;
}
if (! virFileHasSuffix(fileName, ".vmdk")) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Expecting source '%s' of first file-based harddisk to "
"be a VMDK image"), disk->src);
- goto failure;
+ goto cleanup;
}
virBufferVSprintf(&buffer, "%s://%s:%d/folder/", priv->transport,
@@ -2582,7 +2518,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
if (virBufferError(&buffer)) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
url = virBufferContentAndReset(&buffer);
@@ -2591,13 +2527,13 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
if (virAsprintf(&datastoreRelatedPath, "[%s] %s/%s.vmx", datastoreName,
directoryName, def->name) < 0) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
} else {
if (virAsprintf(&datastoreRelatedPath, "[%s] %s.vmx", datastoreName,
def->name) < 0) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
}
@@ -2605,12 +2541,12 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
if (esxVI_String_AppendValueToList(&propertyNameList, "parent") < 0 ||
esxVI_LookupHostSystemByIp(priv->host, priv->host->ipAddress,
propertyNameList, &hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
if (esxVI_LookupResourcePoolByHostSystem(priv->host, hostSystem,
&resourcePool) < 0) {
- goto failure;
+ goto cleanup;
}
/* Check, if VMX file already exists */
@@ -2618,7 +2554,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
/* Upload VMX file */
if (esxVI_Context_UploadFile(priv->host, url, vmx) < 0) {
- goto failure;
+ goto cleanup;
}
/* Register the domain */
@@ -2627,12 +2563,12 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
resourcePool, hostSystem->obj, &task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, def->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not define domain"));
- goto failure;
+ goto cleanup;
}
domain = virGetDomain(conn, def->name, def->uuid);
@@ -2644,6 +2580,10 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
/* FIXME: Add proper rollback in case of an error */
cleanup:
+ if (url == NULL) {
+ virBufferFreeAndReset(&buffer);
+ }
+
virDomainDefFree(def);
VIR_FREE(vmx);
VIR_FREE(datastoreName);
@@ -2658,13 +2598,6 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
esxVI_ManagedObjectReference_Free(&task);
return domain;
-
- failure:
- virBufferFreeAndReset(&buffer);
-
- domain = NULL;
-
- goto cleanup;
}
@@ -2672,7 +2605,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
static int
esxDomainUndefine(virDomainPtr domain)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_Context *ctx = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
@@ -2686,7 +2619,7 @@ esxDomainUndefine(virDomainPtr domain)
}
if (esxVI_EnsureSession(ctx) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -2695,30 +2628,27 @@ esxDomainUndefine(virDomainPtr domain)
&virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_Suspended &&
powerState != esxVI_VirtualMachinePowerState_PoweredOff) {
ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
_("Domain is not suspended or powered off"));
- goto failure;
+ goto cleanup;
}
if (esxVI_UnregisterVM(ctx, virtualMachine->obj) < 0) {
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -2774,7 +2704,7 @@ static int
esxDomainGetSchedulerParameters(virDomainPtr domain,
virSchedParameterPtr params, int *nparams)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
@@ -2786,11 +2716,11 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
if (*nparams < 3) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
_("Parameter array must have space for 3 items"));
- goto failure;
+ return -1;
}
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
@@ -2800,7 +2730,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = virtualMachine->propSet;
@@ -2815,7 +2745,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Long) < 0) {
- goto failure;
+ goto cleanup;
}
params[i].value.l = dynamicProperty->val->int64;
@@ -2831,7 +2761,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Long) < 0) {
- goto failure;
+ goto cleanup;
}
params[i].value.l = dynamicProperty->val->int64;
@@ -2847,7 +2777,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
if (esxVI_SharesInfo_CastFromAnyType(dynamicProperty->val,
&sharesInfo) < 0) {
- goto failure;
+ goto cleanup;
}
switch (sharesInfo->level) {
@@ -2871,7 +2801,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Shares level has unknown value %d"),
(int)sharesInfo->level);
- goto failure;
+ goto cleanup;
}
esxVI_SharesInfo_Free(&sharesInfo);
@@ -2884,17 +2814,13 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
}
*nparams = i;
+ result = 0;
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&virtualMachine);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -2903,7 +2829,7 @@ static int
esxDomainSetSchedulerParameters(virDomainPtr domain,
virSchedParameterPtr params, int nparams)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_VirtualMachineConfigSpec *spec = NULL;
@@ -2913,7 +2839,7 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
int i;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
@@ -2921,28 +2847,28 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
priv->autoAnswer) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
esxVI_ResourceAllocationInfo_Alloc(&spec->cpuAllocation) < 0) {
- goto failure;
+ goto cleanup;
}
for (i = 0; i < nparams; ++i) {
if (STREQ (params[i].field, "reservation") &&
params[i].type == VIR_DOMAIN_SCHED_FIELD_LLONG) {
if (esxVI_Long_Alloc(&spec->cpuAllocation->reservation) < 0) {
- goto failure;
+ goto cleanup;
}
if (params[i].value.l < 0) {
ESX_ERROR(VIR_ERR_INVALID_ARG,
_("Could not set reservation to %lld MHz, expecting "
"positive value"), params[i].value.l);
- goto failure;
+ goto cleanup;
}
spec->cpuAllocation->reservation->value = params[i].value.l;
} else if (STREQ (params[i].field, "limit") &&
params[i].type == VIR_DOMAIN_SCHED_FIELD_LLONG) {
if (esxVI_Long_Alloc(&spec->cpuAllocation->limit) < 0) {
- goto failure;
+ goto cleanup;
}
if (params[i].value.l < -1) {
@@ -2950,7 +2876,7 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
_("Could not set limit to %lld MHz, expecting "
"positive value or -1 (unlimited)"),
params[i].value.l);
- goto failure;
+ goto cleanup;
}
spec->cpuAllocation->limit->value = params[i].value.l;
@@ -2958,7 +2884,7 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
params[i].type == VIR_DOMAIN_SCHED_FIELD_INT) {
if (esxVI_SharesInfo_Alloc(&sharesInfo) < 0 ||
esxVI_Int_Alloc(&sharesInfo->shares) < 0) {
- goto failure;
+ goto cleanup;
}
spec->cpuAllocation->shares = sharesInfo;
@@ -2990,13 +2916,13 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
_("Could not set shares to %d, expecting positive "
"value or -1 (low), -2 (normal) or -3 (high)"),
params[i].value.i);
- goto failure;
+ goto cleanup;
}
}
} else {
ESX_ERROR(VIR_ERR_INVALID_ARG, _("Unknown field '%s'"),
params[i].field);
- goto failure;
+ goto cleanup;
}
}
@@ -3004,26 +2930,23 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not change scheduler parameters"));
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -3037,7 +2960,7 @@ esxDomainMigratePrepare(virConnectPtr dconn,
const char *dname ATTRIBUTE_UNUSED,
unsigned long resource ATTRIBUTE_UNUSED)
{
- int result = 0;
+ int result = -1;
char *transport = NULL;
if (uri_in == NULL) {
@@ -3048,19 +2971,16 @@ esxDomainMigratePrepare(virConnectPtr dconn,
if (virAsprintf(uri_out, "%s://%s:%d/sdk", transport,
dconn->uri->server, dconn->uri->port) < 0) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
}
+ result = 0;
+
cleanup:
VIR_FREE(transport);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -3074,7 +2994,7 @@ esxDomainMigratePerform(virDomainPtr domain,
const char *dname,
unsigned long bandwidth ATTRIBUTE_UNUSED)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
xmlURIPtr xmlUri = NULL;
char hostIpAddress[NI_MAXHOST] = "";
@@ -3089,17 +3009,17 @@ esxDomainMigratePerform(virDomainPtr domain,
if (priv->vCenter == NULL) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
_("Migration not possible without a vCenter"));
- goto failure;
+ return -1;
}
if (dname != NULL) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
_("Renaming domains on migration not supported"));
- goto failure;
+ return -1;
}
if (esxVI_EnsureSession(priv->vCenter) < 0) {
- goto failure;
+ return -1;
}
/* Parse the destination URI and resolve the hostname */
@@ -3107,12 +3027,12 @@ esxDomainMigratePerform(virDomainPtr domain,
if (xmlUri == NULL) {
virReportOOMError();
- goto failure;
+ return -1;
}
if (esxUtil_ResolveHostname(xmlUri->server, hostIpAddress,
NI_MAXHOST) < 0) {
- goto failure;
+ goto cleanup;
}
/* Lookup VirtualMachine, HostSystem and ResourcePool */
@@ -3122,12 +3042,12 @@ esxDomainMigratePerform(virDomainPtr domain,
esxVI_String_AppendValueToList(&propertyNameList, "parent") < 0 ||
esxVI_LookupHostSystemByIp(priv->vCenter, hostIpAddress,
propertyNameList, &hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
if (esxVI_LookupResourcePoolByHostSystem(priv->vCenter, hostSystem,
&resourcePool) < 0) {
- goto failure;
+ goto cleanup;
}
/* Validate the purposed migration */
@@ -3135,7 +3055,7 @@ esxDomainMigratePerform(virDomainPtr domain,
esxVI_VirtualMachinePowerState_Undefined,
NULL, resourcePool, hostSystem->obj,
&eventList) < 0) {
- goto failure;
+ goto cleanup;
}
if (eventList != NULL) {
@@ -3153,7 +3073,7 @@ esxDomainMigratePerform(virDomainPtr domain,
"problem"));
}
- goto failure;
+ goto cleanup;
}
/* Perform the purposed migration */
@@ -3164,16 +3084,18 @@ esxDomainMigratePerform(virDomainPtr domain,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->vCenter, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not migrate domain, migration task finished with "
"an error"));
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
xmlFreeURI(xmlUri);
esxVI_ObjectContent_Free(&virtualMachine);
@@ -3184,11 +3106,6 @@ esxDomainMigratePerform(virDomainPtr domain,
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -3218,19 +3135,19 @@ esxNodeGetFreeMemory(virConnectPtr conn)
esxVI_ResourcePoolResourceUsage *resourcePoolResourceUsage = NULL;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return 0;
}
/* Lookup host system with its resource pool */
if (esxVI_String_AppendValueToList(&propertyNameList, "parent") < 0 ||
esxVI_LookupHostSystemByIp(priv->host, priv->host->ipAddress,
propertyNameList, &hostSystem) < 0) {
- goto failure;
+ goto cleanup;
}
if (esxVI_LookupResourcePoolByHostSystem(priv->host, hostSystem,
&managedObjectReference) < 0) {
- goto failure;
+ goto cleanup;
}
esxVI_String_Free(&propertyNameList);
@@ -3242,7 +3159,7 @@ esxNodeGetFreeMemory(virConnectPtr conn)
"ResourcePool", propertyNameList,
esxVI_Boolean_False,
&resourcePool) < 0) {
- goto failure;
+ goto cleanup;
}
for (dynamicProperty = resourcePool->propSet; dynamicProperty != NULL;
@@ -3250,7 +3167,7 @@ esxNodeGetFreeMemory(virConnectPtr conn)
if (STREQ(dynamicProperty->name, "runtime.memory")) {
if (esxVI_ResourcePoolResourceUsage_CastFromAnyType
(dynamicProperty->val, &resourcePoolResourceUsage) < 0) {
- goto failure;
+ goto cleanup;
}
break;
@@ -3262,7 +3179,7 @@ esxNodeGetFreeMemory(virConnectPtr conn)
if (resourcePoolResourceUsage == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not retrieve memory usage of resource pool"));
- goto failure;
+ goto cleanup;
}
result = resourcePoolResourceUsage->unreservedForVm->value;
@@ -3275,11 +3192,6 @@ esxNodeGetFreeMemory(virConnectPtr conn)
esxVI_ResourcePoolResourceUsage_Free(&resourcePoolResourceUsage);
return result;
-
- failure:
- result = 0;
-
- goto cleanup;
}
@@ -3315,14 +3227,14 @@ esxIsSecure(virConnectPtr conn)
static int
esxDomainIsActive(virDomainPtr domain)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = domain->conn->privateData;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_String *propertyNameList = NULL;
esxVI_VirtualMachinePowerState powerState;
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
@@ -3331,7 +3243,7 @@ esxDomainIsActive(virDomainPtr domain)
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
- goto failure;
+ goto cleanup;
}
if (powerState != esxVI_VirtualMachinePowerState_PoweredOff) {
@@ -3345,11 +3257,6 @@ esxDomainIsActive(virDomainPtr domain)
esxVI_String_Free(&propertyNameList);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -3380,13 +3287,13 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
virCheckFlags(0, NULL);
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return NULL;
}
def = virDomainSnapshotDefParseString(xmlDesc, 1);
if (def == NULL) {
- goto failure;
+ return NULL;
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
@@ -3397,13 +3304,13 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
esxVI_GetSnapshotTreeByName(rootSnapshotList, def->name,
&snapshotTree, &snapshotTreeParent,
esxVI_Occurrence_OptionalItem) < 0) {
- goto failure;
+ goto cleanup;
}
if (snapshotTree != NULL) {
ESX_ERROR(VIR_ERR_OPERATION_INVALID,
_("Snapshot '%s' already exists"), def->name);
- goto failure;
+ goto cleanup;
}
if (esxVI_CreateSnapshot_Task(priv->host, virtualMachine->obj,
@@ -3412,12 +3319,12 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
esxVI_Boolean_False, &task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create snapshot"));
- goto failure;
+ goto cleanup;
}
snapshot = virGetDomainSnapshot(domain, def->name);
@@ -3429,11 +3336,6 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
esxVI_ManagedObjectReference_Free(&task);
return snapshot;
-
- failure:
- domain = NULL;
-
- goto cleanup;
}
@@ -3452,10 +3354,10 @@ esxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot,
virCheckFlags(0, NULL);
- memset(&def, 0, sizeof (virDomainSnapshotDef));
+ memset(&def, 0, sizeof (def));
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return NULL;
}
if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid,
@@ -3463,7 +3365,7 @@ esxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot,
esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
&snapshotTree, &snapshotTreeParent,
esxVI_Occurrence_RequiredItem) < 0) {
- goto failure;
+ goto cleanup;
}
def.name = snapshot->name;
@@ -3472,7 +3374,7 @@ esxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot,
if (esxVI_DateTime_ConvertToCalendarTime(snapshotTree->createTime,
&def.creationTime) < 0) {
- goto failure;
+ goto cleanup;
}
def.state = esxVI_VirtualMachinePowerState_ConvertToLibvirt
@@ -3486,11 +3388,6 @@ esxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot,
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
return xml;
-
- failure:
- VIR_FREE(xml);
-
- goto cleanup;
}
@@ -3498,32 +3395,26 @@ esxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot,
static int
esxDomainSnapshotNum(virDomainPtr domain, unsigned int flags)
{
- int result = 0;
+ int count;
esxPrivate *priv = domain->conn->privateData;
esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL;
virCheckFlags(0, -1);
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
&rootSnapshotTreeList) < 0) {
- goto failure;
+ return -1;
}
- result = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList);
+ count = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList);
- cleanup:
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
- return result;
-
- failure:
- result = -1;
-
- goto cleanup;
+ return count;
}
@@ -3532,7 +3423,7 @@ static int
esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
unsigned int flags)
{
- int result = 0;
+ int result;
esxPrivate *priv = domain->conn->privateData;
esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL;
@@ -3548,25 +3439,19 @@ esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
}
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
&rootSnapshotTreeList) < 0) {
- goto failure;
+ return -1;
}
result = esxVI_GetSnapshotTreeNames(rootSnapshotTreeList, names, nameslen);
- cleanup:
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -3584,7 +3469,7 @@ esxDomainSnapshotLookupByName(virDomainPtr domain, const char *name,
virCheckFlags(0, NULL);
if (esxVI_EnsureSession(priv->host) < 0) {
- goto cleanup;
+ return NULL;
}
if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
@@ -3608,35 +3493,27 @@ esxDomainSnapshotLookupByName(virDomainPtr domain, const char *name,
static int
esxDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags)
{
- int result = 0;
esxPrivate *priv = domain->conn->privateData;
esxVI_VirtualMachineSnapshotTree *currentSnapshotTree = NULL;
virCheckFlags(0, -1);
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_LookupCurrentSnapshotTree(priv->host, domain->uuid,
¤tSnapshotTree,
esxVI_Occurrence_OptionalItem) < 0) {
- goto failure;
+ return -1;
}
if (currentSnapshotTree != NULL) {
- result = 1;
+ esxVI_VirtualMachineSnapshotTree_Free(¤tSnapshotTree);
+ return 1;
}
- cleanup:
- esxVI_VirtualMachineSnapshotTree_Free(¤tSnapshotTree);
-
- return result;
-
- failure:
- result = -1;
-
- goto cleanup;
+ return 0;
}
@@ -3644,25 +3521,24 @@ esxDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags)
static virDomainSnapshotPtr
esxDomainSnapshotCurrent(virDomainPtr domain, unsigned int flags)
{
- virDomainSnapshotPtr snapshot = NULL;
esxPrivate *priv = domain->conn->privateData;
esxVI_VirtualMachineSnapshotTree *currentSnapshotTree = NULL;
+ virDomainSnapshotPtr snapshot = NULL;
virCheckFlags(0, NULL);
if (esxVI_EnsureSession(priv->host) < 0) {
- goto cleanup;
+ return NULL;
}
if (esxVI_LookupCurrentSnapshotTree(priv->host, domain->uuid,
¤tSnapshotTree,
esxVI_Occurrence_RequiredItem) < 0) {
- goto cleanup;
+ return NULL;
}
snapshot = virGetDomainSnapshot(domain, currentSnapshotTree->name);
- cleanup:
esxVI_VirtualMachineSnapshotTree_Free(¤tSnapshotTree);
return snapshot;
@@ -3673,7 +3549,7 @@ esxDomainSnapshotCurrent(virDomainPtr domain, unsigned int flags)
static int
esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = snapshot->domain->conn->privateData;
esxVI_VirtualMachineSnapshotTree *rootSnapshotList = NULL;
esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
@@ -3684,7 +3560,7 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
virCheckFlags(0, -1);
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid,
@@ -3692,32 +3568,29 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
&snapshotTree, &snapshotTreeParent,
esxVI_Occurrence_RequiredItem) < 0) {
- goto failure;
+ goto cleanup;
}
if (esxVI_RevertToSnapshot_Task(priv->host, snapshotTree->snapshot, NULL,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, snapshot->domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not revert to snapshot '%s'"), snapshot->name);
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
@@ -3725,7 +3598,7 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
static int
esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
{
- int result = 0;
+ int result = -1;
esxPrivate *priv = snapshot->domain->conn->privateData;
esxVI_VirtualMachineSnapshotTree *rootSnapshotList = NULL;
esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
@@ -3737,7 +3610,7 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, -1);
if (esxVI_EnsureSession(priv->host) < 0) {
- goto failure;
+ return -1;
}
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) {
@@ -3749,32 +3622,29 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
&snapshotTree, &snapshotTreeParent,
esxVI_Occurrence_RequiredItem) < 0) {
- goto failure;
+ goto cleanup;
}
if (esxVI_RemoveSnapshot_Task(priv->host, snapshotTree->snapshot,
removeChildren, &task) < 0 ||
esxVI_WaitForTaskCompletion(priv->host, task, snapshot->domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
- goto failure;
+ goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not delete snapshot '%s'"), snapshot->name);
- goto failure;
+ goto cleanup;
}
+ result = 0;
+
cleanup:
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
esxVI_ManagedObjectReference_Free(&task);
return result;
-
- failure:
- result = -1;
-
- goto cleanup;
}
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 0e2e1a3..98e7137 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -467,10 +467,6 @@ esxStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info)
result = 0;
cleanup:
- if (result < 0) {
- memset(info, 0, sizeof (*info));
- }
-
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore);
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index 51c9afc..1ffcc22 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -43,7 +43,7 @@ int
esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
int *noVerify, int *autoAnswer)
{
- int result = 0;
+ int result = -1;
int i;
struct qparam_set *queryParamSet = NULL;
struct qparam *queryParam = NULL;
@@ -71,7 +71,7 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
#endif
if (queryParamSet == NULL) {
- goto failure;
+ return -1;
}
for (i = 0; i < queryParamSet->n; i++) {
@@ -86,14 +86,14 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
if (*transport == NULL) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
if (STRNEQ(*transport, "http") && STRNEQ(*transport, "https")) {
ESX_ERROR(VIR_ERR_INVALID_ARG,
_("Query parameter 'transport' has unexpected value "
"'%s' (should be http|https)"), *transport);
- goto failure;
+ goto cleanup;
}
} else if (STRCASEEQ(queryParam->name, "vcenter")) {
if (vCenter == NULL) {
@@ -104,7 +104,7 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
if (*vCenter == NULL) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
} else if (STRCASEEQ(queryParam->name, "no_verify")) {
if (noVerify == NULL) {
@@ -116,7 +116,7 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
ESX_ERROR(VIR_ERR_INVALID_ARG,
_("Query parameter 'no_verify' has unexpected value "
"'%s' (should be 0 or 1)"), queryParam->value);
- goto failure;
+ goto cleanup;
}
} else if (STRCASEEQ(queryParam->name, "auto_answer")) {
if (autoAnswer == NULL) {
@@ -128,7 +128,7 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
ESX_ERROR(VIR_ERR_INVALID_ARG,
_("Query parameter 'auto_answer' has unexpected "
"value '%s' (should be 0 or 1)"), queryParam->value);
- goto failure;
+ goto cleanup;
}
} else {
VIR_WARN("Ignoring unexpected query parameter '%s'",
@@ -141,29 +141,28 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
if (*transport == NULL) {
virReportOOMError();
- goto failure;
+ goto cleanup;
}
}
- cleanup:
- if (queryParamSet != NULL) {
- free_qparam_set(queryParamSet);
- }
+ result = 0;
- return result;
+ cleanup:
+ if (result < 0) {
+ if (transport != NULL) {
+ VIR_FREE(*transport);
+ }
- failure:
- if (transport != NULL) {
- VIR_FREE(*transport);
+ if (vCenter != NULL) {
+ VIR_FREE(*vCenter);
+ }
}
- if (vCenter != NULL) {
- VIR_FREE(*vCenter);
+ if (queryParamSet != NULL) {
+ free_qparam_set(queryParamSet);
}
- result = -1;
-
- goto cleanup;
+ return result;
}
@@ -196,7 +195,7 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
char **datastoreName,
char **directoryName, char **fileName)
{
- int result = 0;
+ int result = -1;
char *copyOfDatastoreRelatedPath = NULL;
char *tmp = NULL;
char *saveptr = NULL;
@@ -213,7 +212,7 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
if (esxVI_String_DeepCopyValue(©OfDatastoreRelatedPath,
datastoreRelatedPath) < 0) {
- goto failure;
+ goto cleanup;
}
/* Expected format: '[<datastore>] <path>' */
@@ -223,12 +222,12 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Datastore related path '%s' doesn't have expected format "
"'[<datastore>] <path>'"), datastoreRelatedPath);
- goto failure;
+ goto cleanup;
}
if (esxVI_String_DeepCopyValue(datastoreName,
preliminaryDatastoreName) < 0) {
- goto failure;
+ goto cleanup;
}
directoryAndFileName += strspn(directoryAndFileName, " ");
@@ -243,33 +242,32 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Datastore related path '%s' doesn't reference a file"),
datastoreRelatedPath);
- goto failure;
+ goto cleanup;
}
if (esxVI_String_DeepCopyValue(directoryName,
directoryAndFileName) < 0 ||
esxVI_String_DeepCopyValue(fileName, separator) < 0) {
- goto failure;
+ goto cleanup;
}
} else {
if (esxVI_String_DeepCopyValue(fileName, directoryAndFileName) < 0) {
- goto failure;
+ goto cleanup;
}
}
+ result = 0;
+
cleanup:
+ if (result < 0) {
+ VIR_FREE(*datastoreName);
+ VIR_FREE(*directoryName);
+ VIR_FREE(*fileName);
+ }
+
VIR_FREE(copyOfDatastoreRelatedPath);
return result;
-
- failure:
- VIR_FREE(*datastoreName);
- VIR_FREE(*directoryName);
- VIR_FREE(*fileName);
-
- result = -1;
-
- goto cleanup;
}
@@ -282,7 +280,7 @@ esxUtil_ResolveHostname(const char *hostname,
struct addrinfo *result = NULL;
int errcode;
- memset(&hints, 0, sizeof(struct addrinfo));
+ memset(&hints, 0, sizeof (hints));
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_family = AF_INET;
14 years, 7 months
[libvirt] [PATCH] Install, distribute and package domainsnapshot.rng
by Matthias Bolte
---
docs/schemas/Makefile.am | 1 +
libvirt.spec.in | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/docs/schemas/Makefile.am b/docs/schemas/Makefile.am
index 22f9f3f..dbad35f 100644
--- a/docs/schemas/Makefile.am
+++ b/docs/schemas/Makefile.am
@@ -3,6 +3,7 @@
schemadir = $(pkgdatadir)/schemas
schema_DATA = \
domain.rng \
+ domainsnapshot.rng \
interface.rng \
network.rng \
secret.rng \
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 0629f67..20ccfda 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -832,6 +832,7 @@ fi
%dir %{_datadir}/libvirt/schemas/
%{_datadir}/libvirt/schemas/domain.rng
+%{_datadir}/libvirt/schemas/domainsnapshot.rng
%{_datadir}/libvirt/schemas/network.rng
%{_datadir}/libvirt/schemas/storagepool.rng
%{_datadir}/libvirt/schemas/storagevol.rng
--
1.7.0.4
14 years, 7 months
[libvirt] [PATCH] Use printf instead of echo -e in libvirt.spec.in
by Matthias Bolte
make rpm created dummy tests containing '-e #!/bin/sh' for me.
---
libvirt.spec.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 20ccfda..09f554e 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -658,7 +658,7 @@ cd tests
for i in nodeinfotest daemon-conf seclabeltest
do
rm -f $i
- echo -e "#!/bin/sh\nexit 0" > $i
+ printf "#!/bin/sh\nexit 0" > $i
chmod +x $i
done
make check
--
1.7.0.4
14 years, 7 months
[libvirt] [PATCH] build: support 'make check' in pristine tree
by Eric Blake
Otherwise, 'make check' in the python dir tries to reference a file in
docs that is built by 'make' but not by 'make check'.
* docs/Makefile.am (check-local): New rule.
Reported by Matthias Bolte.
---
Test with make && rm docs/libvirt-api.xml && make check
docs/Makefile.am | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 70b9e51..41068c6 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -143,6 +143,8 @@ html/%-%.html html/%-virterror.html %-api.xml %-refs.xml: \
$(srcdir)/../src/%.c \
$(srcdir)/../src/util/virterror.c
+check-local: all
+
clean-local:
rm -f *~ *.bak *.hierarchy *.signals *-unused.txt
--
1.7.0.1
14 years, 7 months
[libvirt] [PATCH] esx: Expose host UUID in the capabilities XML
by Matthias Bolte
Parse the BIOS UUID. This information may not be available, in that
case no host UUID is exposed in the capabilities XML.
---
src/esx/esx_driver.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 7c9c50e..b89de72 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -141,6 +141,69 @@ esxSupportsLongMode(esxPrivate *priv)
+static int
+esxLookupHostSystemBiosUuid(esxPrivate *priv, unsigned char *uuid)
+{
+ int result = -1;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *hostSystem = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ return -1;
+ }
+
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "hardware.systemInfo.uuid") < 0 ||
+ esxVI_LookupObjectContentByType(priv->host, priv->host->hostFolder,
+ "HostSystem", propertyNameList,
+ esxVI_Boolean_True, &hostSystem) < 0) {
+ goto cleanup;
+ }
+
+ if (hostSystem == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve the HostSystem object"));
+ goto cleanup;
+ }
+
+ for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "hardware.systemInfo.uuid")) {
+ if (esxVI_AnyType_ExpectType(dynamicProperty->val,
+ esxVI_Type_String) < 0) {
+ goto cleanup;
+ }
+
+ if (strlen(dynamicProperty->val->string) > 0) {
+ if (virUUIDParse(dynamicProperty->val->string, uuid) < 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not parse UUID from string '%s'"),
+ dynamicProperty->val->string);
+ goto cleanup;
+ }
+ } else {
+ /* HostSystem has an empty UUID */
+ memset(uuid, 0, VIR_UUID_BUFLEN);
+ }
+
+ break;
+ } else {
+ VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+ }
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostSystem);
+
+ return result;
+}
+
+
+
static virCapsPtr
esxCapsInit(esxPrivate *priv)
{
@@ -166,6 +229,10 @@ esxCapsInit(esxPrivate *priv)
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 });
virCapabilitiesAddHostMigrateTransport(caps, "esx");
+ if (esxLookupHostSystemBiosUuid(priv, caps->host.host_uuid) < 0) {
+ goto failure;
+ }
+
/* i686 */
guest = virCapabilitiesAddGuest(caps, "hvm", "i686", 32, NULL, NULL, 0,
NULL);
--
1.7.0.4
14 years, 7 months
[libvirt] [PATCH v8] add 802.1Qbh and 802.1Qbg handling
by Stefan Berger
A problem I am encountering is when trying to build after configuring
with --without-macvtap. [I apologize for the recent build errors...] In
that case the [dis|]associatePortProfileId functions become unused and
the compiler complains. I am trying to solve this now by making them
non-static functions that also later on, probably after some
changes/extensions to their passed parameters, can be used in the PCI
device passthrough case. I preprended 'vp' before their names, for
'virtualPort'. So the change in this version of the patch now is to not
define these two functions as static. However, I have not added them to
libvirt_private.syms.
In case of 802.1Qbg I am sending netlink messages to (future) lldpad,
another user space program. I used to use netlink multicast for doing
that, but now it's unicast. I am renaming the variable multicast to
nltarget_kernel and invert the logic for its testing. The two places
where the variable multicast received a boolean value has now the
opposite assigned to nltarget_kernel.
V8:
- To enable build with --without-macvtap rename the
[dis|]associatePortProfileId functions, prepend 'vp' before their
name and make them non-static functions.
- Renaming variable multicast to nltarget_kernel and inverting
the logic
V7:
- Addressing Jim Meyering's comments; this also touches existing
code for example for correcting indentation of break statements or
simplification of switch statements.
Changes from v5 to v6:
- Renamed occurrencvirVirtualPortProfileDef to
virVirtualPortProfileParamses
- 802.1Qbg part prepared for sending a RTM_SETLINK and getting
processing status back plus a subsequent RTM_GETLINK to
get IFLA_PORT_RESPONSE.
Note: This interface for 802.1Qbg may still change
Changes from v4 to v5:
- [David Allan] move getPhysfn inside IFLA_VF_PORT_MAX to avoid
compiler
warning when latest if_link.h isn't available
Changes from v3 to v4:
- move from Stefan's 802.1Qb{g|h} XML v8 to v9
- move hostuuid and vf index calcs to inside doPortProfileOp8021Qbh
Changes from v2 to v3:
- remove debug fprintfs
- use virGetHostUUID (thanks Stefan!)
- fix compile issue when latest if_link.h isn't available
- change poll timeout to 10s, at 1/8 intervals
- if polling times out, log msg and return -ETIMEDOUT
Changes from v1 to v2:
- Add Stefan's code for getPortProfileStatus
- Poll for up to 2 secs for port-profile status, at 1/8 sec intervals:
- if status indicates error, abort openMacvtapTap
- if status indicates success, exit polling
- if status is "in-progress" after 2 secs of polling, exit
polling loop silently, without error
My patch finishes out the 802.1Qbh parts, which Stefan had mostly complete.
I've tested using the recent kernel updates for VF_PORT netlink msgs and
enic for Cisco's 10G Ethernet NIC. I tested many VMs, each with several
direct interfaces, each configured with a port-profile per the XML. VM-to-VM,
and VM-to-external work as expected. VM-to-VM on same host (using same NIC)
works same as VM-to-VM where VMs are on diff hosts. I'm able to change
settings on the port-profile while the VM is running to change the virtual
port behaviour. For example, adjusting a QoS setting like rate limit. All
VMs with interfaces using that port-profile immediatly see the effect of the
change to the port-profile.
I don't have a SR-IOV device to test so source dev is a non-SR-IOV device,
but most of the code paths include support for specifing the source dev and
VF index. We'll need to complete this by discovering the PF given the VF
linkdev. Once we have the PF, we'll also have the VF index. All this info-
mation is available from sysfs.
Signed-off-by: Scott Feldman <scofeldm(a)cisco.com>
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
---
configure.ac | 16
src/qemu/qemu_conf.c | 2
src/qemu/qemu_driver.c | 4
src/util/macvtap.c | 833 +++++++++++++++++++++++++++++++++++++++++++++----
src/util/macvtap.h | 1
5 files changed, 785 insertions(+), 71 deletions(-)
Index: libvirt-acl/configure.ac
===================================================================
--- libvirt-acl.orig/configure.ac
+++ libvirt-acl/configure.ac
@@ -2005,13 +2005,26 @@ if test "$with_macvtap" != "no" ; then
fi
AM_CONDITIONAL([WITH_MACVTAP], [test "$with_macvtap" = "yes"])
+AC_TRY_COMPILE([ #include <sys/socket.h>
+ #include <linux/rtnetlink.h> ],
+ [ int x = IFLA_PORT_MAX; ],
+ [ with_virtualport=yes ],
+ [ with_virtualport=no ])
+if test "$with_virtualport" = "yes"; then
+ val=1
+else
+ val=0
+fi
+AC_DEFINE_UNQUOTED([WITH_VIRTUALPORT], $val, [whether vsi vepa support is enabled])
+AM_CONDITIONAL([WITH_VIRTUALPORT], [test "$with_virtualport" = "yes"])
+
dnl netlink library
LIBNL_CFLAGS=""
LIBNL_LIBS=""
-if test "$with_macvtap" = "yes"; then
+if test "$with_macvtap" = "yes" || test "$with_virtualport" = "yes"; then
PKG_CHECK_MODULES([LIBNL], [libnl-1 >= $LIBNL_REQUIRED], [
], [
AC_MSG_ERROR([libnl >= $LIBNL_REQUIRED is required for macvtap support])
@@ -2084,6 +2097,7 @@ AC_MSG_NOTICE([ Network: $with_network])
AC_MSG_NOTICE([Libvirtd: $with_libvirtd])
AC_MSG_NOTICE([ netcf: $with_netcf])
AC_MSG_NOTICE([ macvtap: $with_macvtap])
+AC_MSG_NOTICE([virtport: $with_virtualport])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Storage Drivers])
AC_MSG_NOTICE([])
Index: libvirt-acl/src/qemu/qemu_conf.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_conf.c
+++ libvirt-acl/src/qemu/qemu_conf.c
@@ -1509,7 +1509,7 @@ qemudPhysIfaceConnect(virConnectPtr conn
if (err) {
close(rc);
rc = -1;
- delMacvtap(net->ifname,
+ delMacvtap(net->ifname, net->data.direct.linkdev,
&net->data.direct.virtPortProfile);
}
}
Index: libvirt-acl/src/qemu/qemu_driver.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_driver.c
+++ libvirt-acl/src/qemu/qemu_driver.c
@@ -3709,7 +3709,7 @@ static void qemudShutdownVMDaemon(struct
for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr net = def->nets[i];
if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT)
- delMacvtap(net->ifname,
+ delMacvtap(net->ifname, net->data.direct.linkdev,
&net->data.direct.virtPortProfile);
}
#endif
@@ -8514,7 +8514,7 @@ qemudDomainDetachNetDevice(struct qemud_
#if WITH_MACVTAP
if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT)
- delMacvtap(detach->ifname,
+ delMacvtap(detach->ifname, detach->data.direct.linkdev,
&detach->data.direct.virtPortProfile);
#endif
Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -27,7 +27,7 @@
#include <config.h>
-#if WITH_MACVTAP
+#if WITH_MACVTAP || WITH_VIRTUALPORT
# include <stdio.h>
# include <errno.h>
@@ -41,6 +41,8 @@
# include <linux/rtnetlink.h>
# include <linux/if_tun.h>
+# include <netlink/msg.h>
+
# include "util.h"
# include "memory.h"
# include "logging.h"
@@ -48,6 +50,7 @@
# include "interface.h"
# include "conf/domain_conf.h"
# include "virterror_internal.h"
+# include "uuid.h"
# define VIR_FROM_THIS VIR_FROM_NET
@@ -58,14 +61,22 @@
# define MACVTAP_NAME_PREFIX "macvtap"
# define MACVTAP_NAME_PATTERN "macvtap%d"
+# define MICROSEC_PER_SEC (1000 * 1000)
+
+# define NLMSGBUF_SIZE 256
+# define RATTBUF_SIZE 64
+
+
+# define STATUS_POLL_TIMEOUT_USEC (10 * MICROSEC_PER_SEC)
+# define STATUS_POLL_INTERVL_USEC (MICROSEC_PER_SEC / 8)
+
+
-static int associatePortProfileId(const char *macvtap_ifname,
- const virVirtualPortProfileParamsPtr virtPort,
- int vf,
- const unsigned char *vmuuid);
-static int disassociatePortProfileId(const char *macvtap_ifname,
- const virVirtualPortProfileParamsPtr virtPort);
+enum virVirtualPortOp {
+ ASSOCIATE = 0x1,
+ DISASSOCIATE = 0x2,
+};
static int nlOpen(void)
@@ -97,7 +108,7 @@ static void nlClose(int fd)
*/
static
int nlComm(struct nlmsghdr *nlmsg,
- char **respbuf, int *respbuflen)
+ char **respbuf, unsigned int *respbuflen)
{
int rc = 0;
struct sockaddr_nl nladdr = {
@@ -159,6 +170,162 @@ err_exit:
}
+# ifdef IFLA_VF_PORT_MAX
+
+/**
+ * nlCommWaitSuccess:
+ *
+ * @nlmsg: pointer to netlink message
+ * @nl_grousp: the netlink multicast groups to send to
+ * @respbuf: pointer to pointer where response buffer will be allocated
+ * @respbuflen: pointer to integer holding the size of the response buffer
+ * on return of the function.
+ * @timeout_usecs: timeout in microseconds to wait for a success message
+ * to be returned
+ *
+ * Send the given message to the netlink multicast group and receive
+ * responses. Skip responses indicating an error and keep on receiving
+ * responses until a success response is returned.
+ * Returns 0 on success, -1 on error. In case of error, no response
+ * buffer will be returned.
+ */
+static int
+nlCommWaitSuccess(struct nlmsghdr *nlmsg, uint32_t nl_groups,
+ char **respbuf, unsigned int *respbuflen,
+ unsigned long long timeout_usecs)
+{
+ int rc = 0;
+ struct sockaddr_nl nladdr = {
+ .nl_family = AF_NETLINK,
+ .nl_pid = getpid(),
+ .nl_groups = nl_groups,
+ };
+ int rcvChunkSize = 1024; // expecting less than that
+ size_t rcv_offset = 0;
+ ssize_t nbytes;
+ struct timeval tv = {
+ .tv_sec = timeout_usecs / MICROSEC_PER_SEC,
+ .tv_usec = timeout_usecs % MICROSEC_PER_SEC,
+ };
+ bool got_valid = false;
+ int fd = nlOpen();
+ static uint32_t seq = 0x1234;
+ uint32_t myseq = seq++;
+ uint32_t mypid = getpid();
+
+ if (fd < 0)
+ return -1;
+
+ nlmsg->nlmsg_pid = mypid;
+ nlmsg->nlmsg_seq = myseq;
+ nlmsg->nlmsg_flags |= NLM_F_ACK;
+
+ nbytes = sendto(fd, (void *)nlmsg, nlmsg->nlmsg_len, 0,
+ (struct sockaddr *)&nladdr, sizeof(nladdr));
+ if (nbytes < 0) {
+ virReportSystemError(errno,
+ "%s", _("cannot send to netlink socket"));
+ rc = -1;
+ goto err_exit;
+ }
+
+ while (!got_valid) {
+
+ rcv_offset = 0;
+
+ while (1) {
+ int n;
+ fd_set rfds;
+ socklen_t addrlen = sizeof(nladdr);
+
+ if (VIR_REALLOC_N(*respbuf, rcv_offset + rcvChunkSize) < 0) {
+ virReportOOMError();
+ rc = -1;
+ goto err_exit;
+ }
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+
+ n = select(fd + 1, &rfds, NULL, NULL, &tv);
+ if (n <= 0) {
+ if (n < 0)
+ virReportSystemError(errno, "%s",
+ _("error in select call"));
+ if (n == 0)
+ virReportSystemError(ETIMEDOUT, "%s",
+ _("no valid netlink response was received"));
+ rc = -1;
+ goto err_exit;
+ }
+
+ nbytes = recvfrom(fd, &((*respbuf)[rcv_offset]), rcvChunkSize, 0,
+ (struct sockaddr *)&nladdr, &addrlen);
+ if (nbytes < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ virReportSystemError(errno, "%s",
+ _("error receiving from netlink socket"));
+ rc = -1;
+ goto err_exit;
+ }
+ rcv_offset += nbytes;
+ break;
+ }
+ *respbuflen = rcv_offset;
+
+ /* check message for error */
+ if (*respbuflen > NLMSG_LENGTH(0) && *respbuf != NULL) {
+ struct nlmsghdr *resp = (struct nlmsghdr *)*respbuf;
+ struct nlmsgerr *err;
+
+ if (resp->nlmsg_pid != mypid ||
+ resp->nlmsg_seq != myseq)
+ continue;
+
+ /* skip reflected message */
+ if (resp->nlmsg_type & 0x10)
+ continue;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len >= NLMSG_LENGTH(sizeof(*err))) {
+ if (err->error != -EOPNOTSUPP) {
+ /* assuming error msg from daemon */
+ got_valid = true;
+ break;
+ }
+ }
+ /* whatever this is, skip it */
+ VIR_FREE(*respbuf);
+ *respbuflen = 0;
+ break;
+
+ case NLMSG_DONE:
+ got_valid = true;
+ break;
+
+ default:
+ VIR_FREE(*respbuf);
+ *respbuflen = 0;
+ break;
+ }
+ }
+ }
+
+err_exit:
+ if (rc == -1) {
+ VIR_FREE(*respbuf);
+ *respbuflen = 0;
+ }
+
+ nlClose(fd);
+ return rc;
+}
+
+# endif /* IFLA_VF_PORT_MAX */
+
static struct rtattr *
rtattrCreate(char *buffer, int bufsize, int type,
const void *data, int datalen)
@@ -204,6 +371,8 @@ nlAppend(struct nlmsghdr *nlm, int totle
}
+# if WITH_MACVTAP
+
static int
link_add(const char *type,
const unsigned char *macaddress, int macaddrsize,
@@ -213,15 +382,15 @@ link_add(const char *type,
int *retry)
{
int rc = 0;
- char nlmsgbuf[256];
+ char nlmsgbuf[NLMSGBUF_SIZE];
struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
struct nlmsgerr *err;
- char rtattbuf[64];
+ char rtattbuf[RATTBUF_SIZE];
struct rtattr *rta, *rta1, *li;
- struct ifinfomsg i = { .ifi_family = AF_UNSPEC };
+ struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
int ifindex;
char *recvbuf = NULL;
- int recvbuflen;
+ unsigned int recvbuflen;
if (ifaceGetIndex(true, srcdev, &ifindex) != 0)
return -1;
@@ -232,65 +401,46 @@ link_add(const char *type,
nlInit(nlm, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL, RTM_NEWLINK);
- if (!nlAppend(nlm, sizeof(nlmsgbuf), &i, sizeof(i)))
+ if (!nlAppend(nlm, sizeof(nlmsgbuf), &ifinfo, sizeof(ifinfo)))
goto buffer_too_small;
rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_LINK,
&ifindex, sizeof(ifindex));
- if (!rta)
- goto buffer_too_small;
-
- if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
goto buffer_too_small;
rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_ADDRESS,
macaddress, macaddrsize);
- if (!rta)
- goto buffer_too_small;
-
- if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
goto buffer_too_small;
if (ifname) {
rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME,
ifname, strlen(ifname) + 1);
- if (!rta)
- goto buffer_too_small;
-
- if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
goto buffer_too_small;
}
rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_LINKINFO, NULL, 0);
- if (!rta)
- goto buffer_too_small;
-
- if (!(li = nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len)))
+ if (!rta ||
+ !(li = nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len)))
goto buffer_too_small;
rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_INFO_KIND,
type, strlen(type));
- if (!rta)
- goto buffer_too_small;
-
- if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
goto buffer_too_small;
if (macvlan_mode > 0) {
rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_INFO_DATA,
NULL, 0);
- if (!rta)
- goto buffer_too_small;
-
- if (!(rta1 = nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len)))
+ if (!rta ||
+ !(rta1 = nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len)))
goto buffer_too_small;
rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_MACVLAN_MODE,
&macvlan_mode, sizeof(macvlan_mode));
- if (!rta)
- goto buffer_too_small;
-
- if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
goto buffer_too_small;
rta1->rta_len = (char *)nlm + nlm->nlmsg_len - (char *)rta1;
@@ -312,15 +462,15 @@ link_add(const char *type,
if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
goto malformed_resp;
- switch (-err->error) {
+ switch (err->error) {
case 0:
- break;
+ break;
- case EEXIST:
+ case -EEXIST:
*retry = 1;
rc = -1;
- break;
+ break;
default:
virReportSystemError(-err->error,
@@ -328,10 +478,10 @@ link_add(const char *type,
type);
rc = -1;
}
- break;
+ break;
case NLMSG_DONE:
- break;
+ break;
default:
goto malformed_resp;
@@ -358,14 +508,14 @@ static int
link_del(const char *name)
{
int rc = 0;
- char nlmsgbuf[256];
+ char nlmsgbuf[NLMSGBUF_SIZE];
struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
struct nlmsgerr *err;
- char rtattbuf[64];
+ char rtattbuf[RATTBUF_SIZE];
struct rtattr *rta;
struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
char *recvbuf = NULL;
- int recvbuflen;
+ unsigned int recvbuflen;
memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));
@@ -376,10 +526,7 @@ link_del(const char *name)
rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME,
name, strlen(name)+1);
- if (!rta)
- goto buffer_too_small;
-
- if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
goto buffer_too_small;
if (nlComm(nlm, &recvbuf, &recvbuflen) < 0)
@@ -396,20 +543,16 @@ link_del(const char *name)
if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
goto malformed_resp;
- switch (-err->error) {
- case 0:
- break;
-
- default:
+ if (err->error) {
virReportSystemError(-err->error,
_("error destroying %s interface"),
name);
rc = -1;
}
- break;
+ break;
case NLMSG_DONE:
- break;
+ break;
default:
goto malformed_resp;
@@ -509,11 +652,9 @@ macvtapModeFromInt(enum virDomainNetdevM
switch (mode) {
case VIR_DOMAIN_NETDEV_MACVTAP_MODE_PRIVATE:
return MACVLAN_MODE_PRIVATE;
- break;
case VIR_DOMAIN_NETDEV_MACVTAP_MODE_BRIDGE:
return MACVLAN_MODE_BRIDGE;
- break;
case VIR_DOMAIN_NETDEV_MACVTAP_MODE_VEPA:
default:
@@ -654,10 +795,10 @@ create_name:
cr_ifname = ifname;
}
- if (associatePortProfileId(cr_ifname,
- virtPortProfile,
- -1,
- vmuuid) != 0) {
+ if (vpAssociatePortProfileId(cr_ifname,
+ linkdev,
+ virtPortProfile,
+ vmuuid) != 0) {
rc = -1;
goto link_del_exit;
}
@@ -688,8 +829,9 @@ create_name:
return rc;
disassociate_exit:
- disassociatePortProfileId(cr_ifname,
- virtPortProfile);
+ vpDisassociatePortProfileId(cr_ifname,
+ linkdev,
+ virtPortProfile);
link_del_exit:
link_del(cr_ifname);
@@ -701,6 +843,7 @@ link_del_exit:
/**
* delMacvtap:
* @ifname : The name of the macvtap interface
+ * @linkdev: The interface name of the NIC to connect to the external bridge
* @virtPortProfile: pointer to object holding the virtual port profile data
*
* Delete an interface given its name. Disassociate
@@ -709,22 +852,564 @@ link_del_exit:
*/
void
delMacvtap(const char *ifname,
+ const char *linkdev,
virVirtualPortProfileParamsPtr virtPortProfile)
{
if (ifname) {
- disassociatePortProfileId(ifname,
- virtPortProfile);
+ vpDisassociatePortProfileId(ifname,
+ linkdev,
+ virtPortProfile);
link_del(ifname);
}
}
+# endif /* WITH_MACVTAP */
+
+# ifdef IFLA_PORT_MAX
+
+static struct nla_policy ifla_policy[IFLA_MAX + 1] =
+{
+ [IFLA_VF_PORTS] = { .type = NLA_NESTED },
+};
+
+static struct nla_policy ifla_vf_ports_policy[IFLA_VF_PORT_MAX + 1] =
+{
+ [IFLA_VF_PORT] = { .type = NLA_NESTED },
+};
+
+static struct nla_policy ifla_port_policy[IFLA_PORT_MAX + 1] =
+{
+ [IFLA_PORT_RESPONSE] = { .type = NLA_U16 },
+};
+
+
+static int
+link_dump(bool nltarget_kernel, int ifindex,
+ struct nlattr **tb, char **recvbuf)
+{
+ int rc = 0;
+ char nlmsgbuf[NLMSGBUF_SIZE] = { 0, };
+ struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
+ struct nlmsgerr *err;
+ struct ifinfomsg ifinfo = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = ifindex
+ };
+ unsigned int recvbuflen;
+
+ *recvbuf = NULL;
+
+ nlInit(nlm, NLM_F_REQUEST, RTM_GETLINK);
+
+ if (!nlAppend(nlm, sizeof(nlmsgbuf), &ifinfo, sizeof(ifinfo)))
+ goto buffer_too_small;
+
+ if (nltarget_kernel) {
+ if (nlComm(nlm, recvbuf, &recvbuflen) < 0)
+ return -1;
+ } else {
+ if (nlCommWaitSuccess(nlm, RTMGRP_LINK, recvbuf, &recvbuflen,
+ 5 * MICROSEC_PER_SEC) < 0)
+ return -1;
+ }
+
+ if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
+ goto malformed_resp;
+
+ resp = (struct nlmsghdr *)*recvbuf;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
+ goto malformed_resp;
+
+ if (err->error) {
+ virReportSystemError(-err->error,
+ _("error dumping %d interface"),
+ ifindex);
+ rc = -1;
+ }
+ break;
+
+ case GENL_ID_CTRL:
+ case NLMSG_DONE:
+ if (nlmsg_parse(resp, sizeof(struct ifinfomsg),
+ tb, IFLA_MAX, ifla_policy)) {
+ goto malformed_resp;
+ }
+ break;
+
+ default:
+ goto malformed_resp;
+ }
+
+ if (rc != 0)
+ VIR_FREE(*recvbuf);
+
+ return rc;
+
+malformed_resp:
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ VIR_FREE(*recvbuf);
+ return -1;
+
+buffer_too_small:
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("internal buffer is too small"));
+ return -1;
+}
+
+
+static int
+getPortProfileStatus(struct nlattr **tb, int32_t vf, uint16_t *status)
+{
+ int rc = 1;
+ const char *msg = NULL;
+ struct nlattr *tb2[IFLA_VF_PORT_MAX + 1],
+ *tb3[IFLA_PORT_MAX+1];
+
+ if (vf == PORT_SELF_VF) {
+ if (tb[IFLA_PORT_SELF]) {
+ if (nla_parse_nested(tb3, IFLA_PORT_MAX, tb[IFLA_PORT_SELF],
+ ifla_port_policy)) {
+ msg = _("error parsing nested IFLA_VF_PORT part");
+ goto err_exit;
+ }
+ }
+ } else {
+ if (tb[IFLA_VF_PORTS]) {
+ if (nla_parse_nested(tb2, IFLA_VF_PORT_MAX, tb[IFLA_VF_PORTS],
+ ifla_vf_ports_policy)) {
+ msg = _("error parsing nested IFLA_VF_PORTS part");
+ goto err_exit;
+ }
+ if (tb2[IFLA_VF_PORT]) {
+ if (nla_parse_nested(tb3, IFLA_PORT_MAX, tb2[IFLA_VF_PORT],
+ ifla_port_policy)) {
+ msg = _("error parsing nested IFLA_VF_PORT part");
+ goto err_exit;
+ }
+ }
+ }
+ }
+
+ if (tb3[IFLA_PORT_RESPONSE]) {
+ *status = *(uint16_t *)RTA_DATA(tb3[IFLA_PORT_RESPONSE]);
+ rc = 0;
+ } else {
+ msg = _("no IFLA_PORT_RESPONSE found in netlink message");
+ goto err_exit;
+ }
+
+err_exit:
+ if (msg)
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", msg);
+
+ return rc;
+}
+
+
+static int
+doPortProfileOpSetLink(bool nltarget_kernel,
+ int ifindex,
+ const char *profileId,
+ struct ifla_port_vsi *portVsi,
+ const unsigned char *instanceId,
+ const unsigned char *hostUUID,
+ int32_t vf,
+ uint8_t op)
+{
+ int rc = 0;
+ char nlmsgbuf[NLMSGBUF_SIZE];
+ struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
+ struct nlmsgerr *err;
+ char rtattbuf[RATTBUF_SIZE];
+ struct rtattr *rta, *vfports = NULL, *vfport;
+ struct ifinfomsg ifinfo = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = ifindex,
+ };
+ char *recvbuf = NULL;
+ unsigned int recvbuflen = 0;
+
+ memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));
+
+ nlInit(nlm, NLM_F_REQUEST, RTM_SETLINK);
+
+ if (!nlAppend(nlm, sizeof(nlmsgbuf), &ifinfo, sizeof(ifinfo)))
+ goto buffer_too_small;
+
+ if (vf == PORT_SELF_VF) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_SELF, NULL, 0);
+ } else {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_PORTS, NULL, 0);
+ if (!rta ||
+ !(vfports = nlAppend(nlm, sizeof(nlmsgbuf),
+ rtattbuf, rta->rta_len)))
+ goto buffer_too_small;
+
+ /* begin nesting vfports */
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_PORT, NULL, 0);
+ }
+
+ if (!rta ||
+ !(vfport = nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len)))
+ goto buffer_too_small;
+
+ if (profileId) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_PROFILE,
+ profileId, strlen(profileId) + 1);
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ goto buffer_too_small;
+ }
+
+ if (portVsi) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_VSI_TYPE,
+ portVsi, sizeof(*portVsi));
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ goto buffer_too_small;
+ }
+
+ if (instanceId) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_INSTANCE_UUID,
+ instanceId, VIR_UUID_BUFLEN);
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ goto buffer_too_small;
+ }
+
+ if (hostUUID) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_HOST_UUID,
+ hostUUID, VIR_UUID_BUFLEN);
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ goto buffer_too_small;
+ }
+
+ if (vf != PORT_SELF_VF) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_VF,
+ &vf, sizeof(vf));
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ goto buffer_too_small;
+ }
+
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_REQUEST,
+ &op, sizeof(op));
+ if (!rta || !nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ goto buffer_too_small;
+
+ /* end nesting of vport */
+ vfport->rta_len = (char *)nlm + nlm->nlmsg_len - (char *)vfport;
+
+ if (vf != PORT_SELF_VF) {
+ /* end nesting of vfports */
+ vfports->rta_len = (char *)nlm + nlm->nlmsg_len - (char *)vfports;
+ }
+
+ if (nltarget_kernel) {
+ if (nlComm(nlm, &recvbuf, &recvbuflen) < 0)
+ return -1;
+ } else {
+ if (nlCommWaitSuccess(nlm, RTMGRP_LINK, &recvbuf, &recvbuflen,
+ 5 * MICROSEC_PER_SEC) < 0)
+ return -1;
+ }
+
+ if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
+ goto malformed_resp;
+
+ resp = (struct nlmsghdr *)recvbuf;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
+ goto malformed_resp;
+
+ if (err->error) {
+ virReportSystemError(-err->error,
+ _("error during virtual port configuration of ifindex %d"),
+ ifindex);
+ rc = -1;
+ }
+ break;
+
+ case NLMSG_DONE:
+ break;
+
+ default:
+ goto malformed_resp;
+ }
+
+ VIR_FREE(recvbuf);
+
+ return rc;
+
+malformed_resp:
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ VIR_FREE(recvbuf);
+ return -1;
+
+buffer_too_small:
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("internal buffer is too small"));
+ return -1;
+}
+
+
+static int
+doPortProfileOpCommon(bool nltarget_kernel,
+ int ifindex,
+ const char *profileId,
+ struct ifla_port_vsi *portVsi,
+ const unsigned char *instanceId,
+ const unsigned char *hostUUID,
+ int32_t vf,
+ uint8_t op)
+{
+ int rc;
+ char *recvbuf = NULL;
+ struct nlattr *tb[IFLA_MAX + 1];
+ int repeats = STATUS_POLL_TIMEOUT_USEC / STATUS_POLL_INTERVL_USEC;
+ uint16_t status = 0;
+
+ rc = doPortProfileOpSetLink(nltarget_kernel,
+ ifindex,
+ profileId,
+ portVsi,
+ instanceId,
+ hostUUID,
+ vf,
+ op);
+
+ if (rc != 0) {
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("sending of PortProfileRequest failed."));
+ return rc;
+ }
+
+ while (--repeats >= 0) {
+ rc = link_dump(nltarget_kernel, ifindex, tb, &recvbuf);
+ if (rc)
+ goto err_exit;
+ rc = getPortProfileStatus(tb, vf, &status);
+ if (rc == 0) {
+ if (status == PORT_PROFILE_RESPONSE_SUCCESS ||
+ status == PORT_VDP_RESPONSE_SUCCESS) {
+ break;
+ } else if (status == PORT_PROFILE_RESPONSE_INPROGRESS) {
+ // keep trying...
+ } else {
+ virReportSystemError(EINVAL,
+ _("error %d during port-profile setlink on ifindex %d"),
+ status, ifindex);
+ rc = 1;
+ break;
+ }
+ } else
+ goto err_exit;
+
+ usleep(STATUS_POLL_INTERVL_USEC);
+
+ VIR_FREE(recvbuf);
+ }
+
+ if (status == PORT_PROFILE_RESPONSE_INPROGRESS) {
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("port-profile setlink timed out"));
+ rc = -ETIMEDOUT;
+ }
+
+err_exit:
+ VIR_FREE(recvbuf);
+
+ return rc;
+}
+
+# endif /* IFLA_PORT_MAX */
+
+static int
+doPortProfileOp8021Qbg(const char *ifname,
+ const virVirtualPortProfileParamsPtr virtPort,
+ enum virVirtualPortOp virtPortOp)
+{
+ int rc;
+
+# ifndef IFLA_VF_PORT_MAX
+
+ (void)ifname;
+ (void)virtPort;
+ (void)virtPortOp;
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Kernel VF Port support was missing at compile time."));
+ rc = 1;
+
+# else /* IFLA_VF_PORT_MAX */
+
+ int op = PORT_REQUEST_ASSOCIATE;
+ struct ifla_port_vsi portVsi = {
+ .vsi_mgr_id = virtPort->u.virtPort8021Qbg.managerID,
+ .vsi_type_version = virtPort->u.virtPort8021Qbg.typeIDVersion,
+ };
+ bool nltarget_kernel = false;
+ int ifindex;
+
+ if (ifaceGetIndex(true, ifname, &ifindex) != 0) {
+ rc = 1;
+ goto err_exit;
+ }
+
+ portVsi.vsi_type_id[2] = virtPort->u.virtPort8021Qbg.typeID >> 16;
+ portVsi.vsi_type_id[1] = virtPort->u.virtPort8021Qbg.typeID >> 8;
+ portVsi.vsi_type_id[0] = virtPort->u.virtPort8021Qbg.typeID;
+
+ switch (virtPortOp) {
+ case ASSOCIATE:
+ op = PORT_REQUEST_ASSOCIATE;
+ break;
+ case DISASSOCIATE:
+ op = PORT_REQUEST_DISASSOCIATE;
+ break;
+ default:
+ macvtapError(VIR_ERR_INTERNAL_ERROR,
+ _("operation type %d not supported"), op);
+ rc = 1;
+ goto err_exit;
+ }
+
+ rc = doPortProfileOpCommon(nltarget_kernel, ifindex,
+ NULL,
+ &portVsi,
+ virtPort->u.virtPort8021Qbg.instanceID,
+ NULL,
+ PORT_SELF_VF,
+ op);
+
+err_exit:
+
+# endif /* IFLA_VF_PORT_MAX */
+
+ return rc;
+}
+
+
+# ifdef IFLA_VF_PORT_MAX
+static int
+getPhysfn(const char *linkdev,
+ int32_t *vf,
+ char **physfndev)
+{
+ int rc = 0;
+ bool virtfn = false;
+
+ if (virtfn) {
+
+ // XXX: if linkdev is SR-IOV VF, then set vf = VF index
+ // XXX: and set linkdev = PF device
+ // XXX: need to use get_physical_function_linux() or
+ // XXX: something like that to get PF
+ // XXX: device and figure out VF index
+
+ rc = 1;
+
+ } else {
+
+ /* Not SR-IOV VF: physfndev is linkdev and VF index
+ * refers to linkdev self
+ */
+
+ *vf = PORT_SELF_VF;
+ *physfndev = (char *)linkdev;
+ }
+
+ return rc;
+}
+# endif /* IFLA_VF_PORT_MAX */
+
+static int
+doPortProfileOp8021Qbh(const char *ifname,
+ const virVirtualPortProfileParamsPtr virtPort,
+ const unsigned char *vm_uuid,
+ enum virVirtualPortOp virtPortOp)
+{
+ int rc;
+
+# ifndef IFLA_VF_PORT_MAX
+
+ (void)ifname;
+ (void)virtPort;
+ (void)vm_uuid;
+ (void)virtPortOp;
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Kernel VF Port support was missing at compile time."));
+ rc = 1;
+
+# else /* IFLA_VF_PORT_MAX */
+
+ char *physfndev;
+ unsigned char hostuuid[VIR_UUID_BUFLEN];
+ int32_t vf;
+ int op = PORT_REQUEST_ASSOCIATE;
+ bool nltarget_kernel = true;
+ int ifindex;
+
+ rc = virGetHostUUID(hostuuid);
+ if (rc)
+ goto err_exit;
+
+ rc = getPhysfn(ifname, &vf, &physfndev);
+ if (rc)
+ goto err_exit;
+
+ if (ifaceGetIndex(true, physfndev, &ifindex) != 0) {
+ rc = 1;
+ goto err_exit;
+ }
+
+ switch (virtPortOp) {
+ case ASSOCIATE:
+ op = PORT_REQUEST_ASSOCIATE;
+ break;
+ case DISASSOCIATE:
+ op = PORT_REQUEST_DISASSOCIATE;
+ break;
+ default:
+ macvtapError(VIR_ERR_INTERNAL_ERROR,
+ _("operation type %d not supported"), op);
+ rc = 1;
+ goto err_exit;
+ }
+
+ rc = doPortProfileOpCommon(nltarget_kernel, ifindex,
+ virtPort->u.virtPort8021Qbh.profileID,
+ NULL,
+ vm_uuid,
+ hostuuid,
+ vf,
+ op);
+
+ switch (virtPortOp) {
+ case ASSOCIATE:
+ ifaceUp(ifname);
+ break;
+ case DISASSOCIATE:
+ ifaceDown(ifname);
+ break;
+ }
+
+err_exit:
+
+# endif /* IFLA_VF_PORT_MAX */
+
+ return rc;
+}
/**
- * associatePortProfile
+ * vpAssociatePortProfile
*
* @macvtap_ifname: The name of the macvtap device
* @virtPort: pointer to the object holding port profile parameters
- * @vf: virtual function number, -1 if to be ignored
* @vmuuid : the UUID of the virtual machine
*
* Associate a port on a swtich with a profile. This function
@@ -736,17 +1421,16 @@ delMacvtap(const char *ifname,
* Returns 0 in case of success, != 0 otherwise with error
* having been reported.
*/
-static int
-associatePortProfileId(const char *macvtap_ifname,
- const virVirtualPortProfileParamsPtr virtPort,
- int vf,
- const unsigned char *vmuuid)
+int
+vpAssociatePortProfileId(const char *macvtap_ifname,
+ const char *linkdev,
+ const virVirtualPortProfileParamsPtr virtPort,
+ const unsigned char *vmuuid)
{
int rc = 0;
+
VIR_DEBUG("Associating port profile '%p' on link device '%s'",
virtPort, macvtap_ifname);
- (void)vf;
- (void)vmuuid;
switch (virtPort->virtPortType) {
case VIR_VIRTUALPORT_NONE:
@@ -754,11 +1438,14 @@ associatePortProfileId(const char *macvt
break;
case VIR_VIRTUALPORT_8021QBG:
-
+ rc = doPortProfileOp8021Qbg(macvtap_ifname, virtPort,
+ ASSOCIATE);
break;
case VIR_VIRTUALPORT_8021QBH:
-
+ rc = doPortProfileOp8021Qbh(linkdev, virtPort,
+ vmuuid,
+ ASSOCIATE);
break;
}
@@ -767,19 +1454,22 @@ associatePortProfileId(const char *macvt
/**
- * disassociatePortProfile
+ * vpDisassociatePortProfile
*
* @macvtap_ifname: The name of the macvtap device
+ * @linkdev: The link device in case of macvtap
* @virtPort: point to object holding port profile parameters
*
* Returns 0 in case of success, != 0 otherwise with error
* having been reported.
*/
-static int
-disassociatePortProfileId(const char *macvtap_ifname,
- const virVirtualPortProfileParamsPtr virtPort)
+int
+vpDisassociatePortProfileId(const char *macvtap_ifname,
+ const char *linkdev,
+ const virVirtualPortProfileParamsPtr virtPort)
{
int rc = 0;
+
VIR_DEBUG("Disassociating port profile id '%p' on link device '%s' ",
virtPort, macvtap_ifname);
@@ -789,15 +1479,18 @@ disassociatePortProfileId(const char *ma
break;
case VIR_VIRTUALPORT_8021QBG:
-
+ rc = doPortProfileOp8021Qbg(macvtap_ifname, virtPort,
+ DISASSOCIATE);
break;
case VIR_VIRTUALPORT_8021QBH:
-
+ rc = doPortProfileOp8021Qbh(linkdev, virtPort,
+ NULL,
+ DISASSOCIATE);
break;
}
return rc;
}
-#endif /* WITH_MACVTAP */
+#endif /* WITH_MACVTAP || WITH_VIRTUALPORT */
Index: libvirt-acl/src/util/macvtap.h
===================================================================
--- libvirt-acl.orig/src/util/macvtap.h
+++ libvirt-acl/src/util/macvtap.h
@@ -72,6 +72,7 @@ int openMacvtapTap(const char *ifname,
char **res_ifname);
void delMacvtap(const char *ifname,
+ const char *linkdev,
virVirtualPortProfileParamsPtr virtPortProfile);
# endif /* WITH_MACVTAP */
@@ -80,6 +81,14 @@ void delMacvtap(const char *ifname,
# define MACVTAP_MODE_VEPA_STR "vepa"
# define MACVTAP_MODE_BRIDGE_STR "bridge"
+int vpAssociatePortProfileId(const char *macvtap_ifname,
+ const char *linkdev,
+ const virVirtualPortProfileParamsPtr virtPort,
+ const unsigned char *vmuuid);
+
+int vpDisassociatePortProfileId(const char *macvtap_ifname,
+ const char *linkdev,
+ const virVirtualPortProfileParamsPtr virtPort);
VIR_ENUM_DECL(virVirtualPort)
14 years, 7 months
[libvirt] Just pushed a simple doc patch
by Cole Robinson
With my recent addition of vnc_allow_host_audio to qemu.conf, the user
facing comment in /etc/sysconfig/libvirtd wasn't accurate. I've pushed
this small fix:
daemon: sysconf: Update comment about VNC audio
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
daemon/libvirtd.sysconf | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/daemon/libvirtd.sysconf b/daemon/libvirtd.sysconf
index 28080a0..b730c5e 100644
--- a/daemon/libvirtd.sysconf
+++ b/daemon/libvirtd.sysconf
@@ -11,7 +11,8 @@
# Override the QEMU/SDL default audio driver probing when
# starting virtual machines using SDL graphics
#
-# NB these have no effect for VMs using VNC
+# NB these have no effect for VMs using VNC, unless vnc_allow_host_audio
+# is enabled in /etc/libvirt/qemu.conf
#QEMU_AUDIO_DRV=sdl
#
#SDL_AUDIODRIVER=pulse
--
1.6.6.1
14 years, 7 months
[libvirt] [PATCH 0/3 RFC] Demonstrating a new API for spawning processes
by Daniel P. Berrange
We have had great success with our APIs for memory allocation and
string buffer management, removing most of the potential for incorrect
API usage, thus avoiding many common errors. It is time todo the same
for command execution.
This patch series is a proof of concept for a set of APIs I've
been thinking about for many months. They are intended to replace
all current usage of virExec and virRun with a more flexible and
less error prone API. In particular they improve of OOM handling,
prevent more memory leaks & simplify alot of code that used horrible
macros
Patch 1 contains the actual implementation and comprehensive test
suite. Patch 2 contains HTML docs. Patch 3 ports two current methods
to the new APIs to demonstrate the improved code clarity.
What follows is a plain text rendering of the HTML docs from the
second patch describing these APIs.
Spawning processes / commands from libvirt drivers
This page describes the usage of libvirt APIs for spawning processes /
commands from libvirt drivers. All code is required to use these APIs
Problems with standard POSIX APIs
The POSIX specification includes a number of APIs for spawning processes /
commands, but they suffer from a number of flaws
* fork+exec: The lowest & most flexible level, but very hard to use
correctly / safely. It is easy to leak file descriptors, have
unexpected signal handler behaviour and not handle edge cases
* system: Convenient if you don't care about capturing command output,
but has the serious downside that the command string is interpreted by
the shell. This makes it very dangerous to use, because improperly
validated user input can lead to exploits via shell meta characters.
* posix_spawn: A half-way house between simplicity of system() and the
flexibility of fork+exec. It does not allow for a couple of important
features though, such as running a hook between the fork+exec stage,
or closing all open file descriptors.
Due to the problems mentioned with each of these, libvirt driver code must
not use any of the above APIs. Historically libvirt provided a higher
level API known as virExec. This was wrapper around fork+exec, in a
similar style to posix_spawn, but with a few more features.
This wrapper still suffered from a number of problems. Handling command
cleanup via waitpid() is overly complex & error prone for most usage.
Building up the argv[] + env[] string arrays is quite cumbersome and error
prone, particularly wrt memory leak / OOM handling.
The libvirt command execution API
There is now a high level API that provides a safe and flexible way to
spawn commands, which prevents the most common errors & is easy to code
against. This code is provided in the src/util/command.h header which can
be imported using #include "command.h"
Defining commands in libvirt
The first step is to declare what command is to be executed. The command
name can be either a fully qualified path, or a bare command name. In the
latter case it will be resolved wrt the $PATH environment variable.
virCommandPtr cmd = virCommandNew("/usr/bin/dnsmasq");
There is no need to check for allocation failure after virCommandNew. This
will be detected and reported at a later time.
Adding arguments to the command
There are a number of APIs for adding arguments to a command. To add a
direct string arg
virCommandAddArg(cmd, "-strict-order");
If an argument takes an attached value of the form -arg=val, then this can
be done using
virCommandAddArgPair(cmd, "--conf-file", "/etc/dnsmasq.conf");
To add a entire NULL terminated array of arguments in one go
const char *const args[] = {
"--strict-order", "--except-interface",
"lo", "--domain", "localdomain", NULL
};
virCommandAddArgSet(cmd, args);
This latter option can also be used at time of initial construction of the
virCommandPtr object
const char *const args[] = {
"--strict-order", "--except-interface",
"lo", "--domain", "localdomain", NULL
};
virCommandPtr cmd = virCommandNewArgs(cmd, args);
Setting up the environment
By default a command will inherit all environment variables from the
current process. Generally this is not desirable and a customized
environment will be more suitable. Any customization done via the
following APIs will prevent inheritance of any existing environment
variables unless explicitly allowed. The first step is usually to pass
through a small number of variables from the current process.
virCommandAddEnvPassCommon(cmd);
This has now set up a clean environment for the child, passing through
PATH, LD_PRELOAD, LD_LIBRARY_PATH, HOME, USER, LOGNAME and TMPDIR.
Furthermore it will explicitly set LC_ALL=C to avoid unexpected
localization of command output. Further variables can be passed through
from parent explicitly:
virCommandAddEnvPass(cmd, "DISPLAY");
virCommandAddEnvPass(cmd, "XAUTHORITY");
To define an environment variable in the child with an separate key /
value:
virCommandAddEnvPair(cmd, "TERM", "xterm");
If the key/value pair is pre-formatted in the right format, it can be set
directly
virCommandAddEnvString(cmd, "TERM=xterm");
Miscellaneous other options
Normally the spawned command will retain the current process as its
parent. If the current process dies, the child will then (usually) be
terminated too. If this cleanup is not desired, then the command should be
marked as daemonized:
virCommandDaemonize(cmd);
When daemonizing a command, the PID visible from the caller will be that
of the intermediate process, not the actual damonized command. If the PID
of the real command is required then a pidfile can be requested
virCommandSetPidFile(cmd, "/var/run/dnsmasq.pid");
This PID file is guaranteed to be written before the intermediate process
exits.
Reducing command privileges
Normally a command will inherit all privileges of the current process. To
restrict what a command can do, it is possible to request that all its
capabilities are cleared. With this done it will only be able to access
resources for which it has explicit DAC permissions
virCommandClearCaps(cmd);
Managing file handles
To prevent unintended resource leaks to child processes, all open file
handles will be closed in the child, and its stdin/out/err all connected
to /dev/null. It is possible to allow an open file handle to be passed
into the child:
virCommandPreserveFD(cmd, 5);
With this file descriptor 5 in the current process remains open as file
descriptor 5 in the child. For stdin/out/err it is usually neccessary to
map a file handle. To attach file descriptor 7 in the current process to
stdin in the child:
virCommandSetInputFD(cmd, 7);
Equivalently to redirect stdout or stderr in the child, pass in a pointer
to the desired handle
int outfd = open("out.log", "w+");
int errfd = open("err.log", "w+");
virCommandSetOutputFD(cmd, &outfd);
virCommandSetErrorFD(cmd, &errfd);
Alternatively it is possible to request that a pipe be created to fetch
stdout/err in the parent, by initializing the FD to -1.
int outfd = -1;
int errfd = -1
virCommandSetOutputFD(cmd, &outfd);
virCommandSetErrorFD(cmd, &errfd);
Once the command is running, outfd and errfd will be initialized with
valid file handles that can be read from.
Feeding & capturing strings to/from the child
Often dealing with file handles for stdin/out/err is unneccessarily
complex. It is possible to specify a string buffer to act as the data
source for the child's stdin
const char *input = "Hello World\n";
virCommandSetInputBuffer(cmd, input);
Similarly it is possible to request that the child's stdout/err be
redirected into a string buffer
char *output = NULL, *errors = NULL;
virCommandSetOutputBuffer(cmd, &output);
virCommandSetErrorBuffer(cmd, &errors);
Once the command has finished executing, these buffers will contain the
output. It is the callers responsibility to free these buffers.
Running commands synchronously
For most commands, the desired behaviour is to spawn the command, wait for
it to complete & exit and then check that its exit status is zero.
if (virCommandRun(cmd, NULL) < 0)
return -1;
Note: if the command has been daemonized this will only block & wait for
the intermediate process, not the real command. virCommandRun will report
on any errors that have occured upon this point with all previous API
calls. If the command fails to run, or exits with non-zero status an error
will be reported via normal libvirt error infrastructure. If a non-zero
exit status can represent a success condition, it is possible to request
the exit status and perform that check manually instead of letting
virCommandRun raise the error
int status;
if (virCommandRun(cmd, &status) < 0)
return -1;
if (WEXITSTATUS(status) ...) {
...do stuff...
}
Running commands asynchronously
In certain complex scenarios, particularly special I/O handling is
required for the child's stdin/err/out it will be neccessary to run the
command asynchronously and wait for completion separately.
pid_t pid;
if (virCommandRunAsync(cmd, &pid) < 0)
return -1;
... do something while pid is running ...
int status;
if (virCommandWait(cmd, &status) < 0)
return -1;
if (WEXITSTATUS(status)...) {
..do stuff..
}
As with virCommandRun, the status arg for virCommandWait can be omitted,
in which case it will validate that exit status is zero and raise an error
if not.
Releasing resources
Once the command has been executed, or if execution has been abandoned, it
is neccessary to release resources associated with the virCommandPtr
object. This is done with:
virCommandFree(cmd);
There is no need to check if cmd is NULL before calling virCommandFree.
This scenario is handled automatically. If the command is still running,
it will be forcably killed and cleaned up (via waitpid).
Complete examples
This shows a complete example usage of the APIs roughly using the libvirt
source src/util/hooks.c
int runhook(const char *drvstr, const char *id,
const char *opstr, const char *subopstr,
const char *extra) {
int ret;
char *path;
virCommandPtr cmd;
ret = virBuildPath(&path, LIBVIRT_HOOK_DIR, drvstr);
if ((ret < 0) || (path == NULL)) {
virHookReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to build path for %s hook"),
drvstr);
return -1;
}
cmd = virCommandNew(path);
VIR_FREE(path);
virCommandAddEnvPassCommon(cmd);
virCommandAddArg(cmd, id);
virCommandAddArg(cmd, opstr);
virCommandAddArg(cmd, subopstr);
virCommandAddArg(cmd, extra);
virCommandSetInputBuffer(cmd, input);
ret = virCommandRun(cmd, NULL);
virCommandFree(cmd);
return ret;
In this example, the command is being run synchronously. A pre-formatted
string is being fed to the command as its stdin. The command takes four
arguments, and has a minimal set of environment variables passed down. In
this example, the code does not require any error checking. All errors are
reported by the virCommandRun method, and the exit status from this is
returned to the caller to handle as desired.
14 years, 7 months
[libvirt] [PATCH] build: fix HTML errors in nwfilter docs
by Eric Blake
A build on Ubuntu reported:
|| Generating formatnwfilter.html.tmp
/dados/develop/libvirt/docs/formatnwfilter.html.in|390| HTML parser error : Unexpected end tag : p
|| </p>
|| ^
/dados/develop/libvirt/docs/formatnwfilter.html.in|705| HTML parser error : Unexpected end tag : code
|| <td>End of range of valid source ports</code></td>
|| ^
/dados/develop/libvirt/docs/formatnwfilter.html.in|710| HTML parser error : Unexpected end tag : code
|| <td>Start of range of valid destination ports</code></td>
|| ^
* docs/formatnwfilter.html.in: Fix invalid HTML constructs.
Reported by Eduardo Otubo.
---
Don't know why a build on Fedora didn't catch these, so I
won't push until I get an ack that this fixes things on Ubuntu.
docs/formatnwfilter.html.in | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in
index f03e9ce..586a4fb 100644
--- a/docs/formatnwfilter.html.in
+++ b/docs/formatnwfilter.html.in
@@ -384,10 +384,11 @@
</table>
<p>
Valid Strings for <code>protocolid</code> are: arp, rarp, ipv4, ipv6
- <br><br>
- Example: <pre><mac match='no' srcmacaddr='$MAC'/></pre>
- <br><br>
</p>
+<pre>
+[...]
+<mac match='no' srcmacaddr='$MAC'/>
+</pre>
<h5><a name="nwfelemsRulesProtoARP">ARP/RARP</a></h5>
<p>
@@ -702,12 +703,12 @@
<tr>
<td>srcportend</td>
<td>UINT16</td>
- <td>End of range of valid source ports</code></td>
+ <td>End of range of valid source ports</td>
</tr>
<tr>
<td>dstportstart</td>
<td>UINT16</td>
- <td>Start of range of valid destination ports</code></td>
+ <td>Start of range of valid destination ports</td>
</tr>
<tr>
<td>dstportend</td>
--
1.7.0.1
14 years, 7 months
[libvirt] [PATCH] Clear/invalidate partially parsed UUIDs
by Stefan Berger
Getting paranoid now... Clear possibly partially parsed UUIDs. Question
is whether to do this in the parsing function itself.
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
---
src/util/uuid.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
Index: libvirt-acl/src/util/uuid.c
===================================================================
--- libvirt-acl.orig/src/util/uuid.c
+++ libvirt-acl/src/util/uuid.c
@@ -289,14 +289,19 @@ virSetHostUUIDStr(const char *uuid)
if (!getDMISystemUUID(dmiuuid, sizeof(dmiuuid))) {
if (!virUUIDParse(dmiuuid, host_uuid))
return 0;
+ // clear partially parsed UUID
+ memset(host_uuid, 0x0, sizeof(host_uuid));
}
if (!virUUIDIsValid(host_uuid))
return virUUIDGenerate(host_uuid);
} else {
rc = virUUIDParse(uuid, host_uuid);
- if (rc)
+ if (rc) {
+ // clear partially parsed UUID
+ memset(host_uuid, 0x0, sizeof(host_uuid));
return rc;
+ }
if (!virUUIDIsValid(host_uuid))
return EINVAL;
}
14 years, 7 months