[libvirt] [PATCH] esx: Split VMX code into a general and an ESX specific part
by Matthias Bolte
Introduce esxVMX_Context containing functions pointers to
glue both parts together in an generic way.
Move the ESX specific part to esx_driver.c.
This is a step towards making the VMX code reusable in a
potential VMware Workstation and VMware Player driver.
---
src/esx/esx_driver.c | 417 ++++++++++++++++++++++++++++++++++++++++++++++-
src/esx/esx_vmx.c | 448 +++++---------------------------------------------
src/esx/esx_vmx.h | 71 +++++----
tests/vmx2xmltest.c | 52 ++++++-
tests/xml2vmxtest.c | 64 +++++++-
5 files changed, 611 insertions(+), 441 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index d824371..b0ef704 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -50,6 +50,369 @@
static int esxDomainGetMaxVcpus(virDomainPtr domain);
+typedef struct _esxVMX_Data esxVMX_Data;
+
+struct _esxVMX_Data {
+ esxVI_Context *ctx;
+ const char *datastoreName;
+ const char *directoryName;
+};
+
+
+
+static char *
+esxAbsolutePathToDatastorePath(esxVI_Context *ctx, const char *absolutePath)
+{
+ bool success = false;
+ char *copyOfAbsolutePath = NULL;
+ char *tmp = NULL;
+ char *saveptr = NULL;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *datastore = NULL;
+
+ char *datastorePath = NULL;
+ char *preliminaryDatastoreName = NULL;
+ char *directoryAndFileName = NULL;
+ char *datastoreName = NULL;
+
+ if (esxVI_String_DeepCopyValue(©OfAbsolutePath, absolutePath) < 0) {
+ return NULL;
+ }
+
+ /* Expected format: '/vmfs/volumes/<datastore>/<path>' */
+ if ((tmp = STRSKIP(copyOfAbsolutePath, "/vmfs/volumes/")) == NULL ||
+ (preliminaryDatastoreName = strtok_r(tmp, "/", &saveptr)) == NULL ||
+ (directoryAndFileName = strtok_r(NULL, "", &saveptr)) == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Absolute path '%s' doesn't have expected format "
+ "'/vmfs/volumes/<datastore>/<path>'"), absolutePath);
+ goto cleanup;
+ }
+
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "summary.name") < 0 ||
+ esxVI_LookupDatastoreByAbsolutePath(ctx, absolutePath,
+ propertyNameList, &datastore,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+
+ if (datastore == NULL) {
+ if (esxVI_LookupDatastoreByName(ctx, preliminaryDatastoreName,
+ propertyNameList, &datastore,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+ }
+
+ if (datastore != NULL) {
+ if (esxVI_GetStringValue(datastore, "summary.name", &datastoreName,
+ esxVI_Occurrence_RequiredItem)) {
+ goto cleanup;
+ }
+ }
+
+ if (datastoreName == NULL) {
+ VIR_WARN("Could not retrieve datastore name for absolute "
+ "path '%s', falling back to preliminary name '%s'",
+ absolutePath, preliminaryDatastoreName);
+
+ datastoreName = preliminaryDatastoreName;
+ }
+
+ if (virAsprintf(&datastorePath, "[%s] %s", datastoreName,
+ directoryAndFileName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* FIXME: Check if referenced path/file really exists */
+
+ success = true;
+
+ cleanup:
+ if (! success) {
+ VIR_FREE(datastorePath);
+ }
+
+ VIR_FREE(copyOfAbsolutePath);
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&datastore);
+
+ return datastorePath;
+}
+
+
+
+static char *
+esxParseVMXFileName(const char *fileName, void *opaque)
+{
+ char *src = NULL;
+ esxVMX_Data *data = opaque;
+
+ if (STRPREFIX(fileName, "/vmfs/volumes/")) {
+ /* Found absolute path referencing a file inside a datastore */
+ return esxAbsolutePathToDatastorePath(data->ctx, fileName);
+ } else if (STRPREFIX(fileName, "/")) {
+ /* Found absolute path referencing a file outside a datastore */
+ src = strdup(fileName);
+
+ if (src == NULL) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ /* FIXME: Check if referenced path/file really exists */
+
+ return src;
+ } else if (strchr(fileName, '/') != NULL) {
+ /* Found relative path, this is not supported */
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Found relative path '%s' in VMX file, this is not "
+ "supported"), fileName);
+ return NULL;
+ } else {
+ /* Found single file name referencing a file inside a datastore */
+ if (virAsprintf(&src, "[%s] %s/%s", data->datastoreName,
+ data->directoryName, fileName) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ /* FIXME: Check if referenced path/file really exists */
+
+ return src;
+ }
+}
+
+
+
+static char *
+esxFormatVMXFileName(const char *src, void *opaque ATTRIBUTE_UNUSED)
+{
+ bool success = false;
+ char *datastoreName = NULL;
+ char *directoryName = NULL;
+ char *fileName = NULL;
+ char *absolutePath = NULL;
+
+ if (STRPREFIX(src, "[")) {
+ /* Found potential datastore path */
+ if (esxUtil_ParseDatastorePath(src, &datastoreName, &directoryName,
+ &fileName) < 0) {
+ goto cleanup;
+ }
+
+ if (directoryName == NULL) {
+ if (virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s",
+ datastoreName, fileName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else {
+ if (virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s/%s",
+ datastoreName, directoryName, fileName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ } else if (STRPREFIX(src, "/")) {
+ /* Found absolute path */
+ absolutePath = strdup(src);
+
+ if (absolutePath == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else {
+ /* Found relative path, this is not supported */
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Found relative path '%s' in domain XML, this is not "
+ "supported"), src);
+ goto cleanup;
+ }
+
+ /* FIXME: Check if referenced path/file really exists */
+
+ success = true;
+
+ cleanup:
+ if (! success) {
+ VIR_FREE(absolutePath);
+ }
+
+ VIR_FREE(datastoreName);
+ VIR_FREE(directoryName);
+ VIR_FREE(fileName);
+
+ return absolutePath;
+}
+
+
+
+static int
+esxAutodetectSCSIControllerModel(virDomainDiskDefPtr def, int *model,
+ void *opaque)
+{
+ int result = -1;
+ esxVMX_Data *data = opaque;
+ char *datastoreName = NULL;
+ char *directoryName = NULL;
+ char *fileName = NULL;
+ char *datastorePath = NULL;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *datastore = NULL;
+ esxVI_ManagedObjectReference *hostDatastoreBrowser = NULL;
+ esxVI_HostDatastoreBrowserSearchSpec *searchSpec = NULL;
+ esxVI_VmDiskFileQuery *vmDiskFileQuery = NULL;
+ esxVI_ManagedObjectReference *task = NULL;
+ esxVI_TaskInfoState taskInfoState;
+ esxVI_TaskInfo *taskInfo = NULL;
+ esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
+ esxVI_VmDiskFileInfo *vmDiskFileInfo = NULL;
+
+ if (def->device != VIR_DOMAIN_DISK_DEVICE_DISK ||
+ def->bus != VIR_DOMAIN_DISK_BUS_SCSI ||
+ def->type != VIR_DOMAIN_DISK_TYPE_FILE ||
+ def->src == NULL ||
+ ! STRPREFIX(def->src, "[")) {
+ /*
+ * This isn't a file-based SCSI disk device with a datastore related
+ * source path => do nothing.
+ */
+ return 0;
+ }
+
+ if (esxUtil_ParseDatastorePath(def->src, &datastoreName, &directoryName,
+ &fileName) < 0) {
+ goto cleanup;
+ }
+
+ if (directoryName == NULL) {
+ if (virAsprintf(&datastorePath, "[%s]", datastoreName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else {
+ if (virAsprintf(&datastorePath, "[%s] %s", datastoreName,
+ directoryName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ /* Lookup HostDatastoreBrowser */
+ if (esxVI_String_AppendValueToList(&propertyNameList, "browser") < 0 ||
+ esxVI_LookupDatastoreByName(data->ctx, datastoreName, propertyNameList,
+ &datastore,
+ esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_GetManagedObjectReference(datastore, "browser",
+ &hostDatastoreBrowser,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ /* Build HostDatastoreBrowserSearchSpec */
+ if (esxVI_HostDatastoreBrowserSearchSpec_Alloc(&searchSpec) < 0 ||
+ esxVI_FileQueryFlags_Alloc(&searchSpec->details) < 0) {
+ goto cleanup;
+ }
+
+ searchSpec->details->fileType = esxVI_Boolean_True;
+ searchSpec->details->fileSize = esxVI_Boolean_False;
+ searchSpec->details->modification = esxVI_Boolean_False;
+
+ if (esxVI_VmDiskFileQuery_Alloc(&vmDiskFileQuery) < 0 ||
+ esxVI_VmDiskFileQueryFlags_Alloc(&vmDiskFileQuery->details) < 0 ||
+ esxVI_FileQuery_AppendToList
+ (&searchSpec->query,
+ esxVI_FileQuery_DynamicCast(vmDiskFileQuery)) < 0) {
+ goto cleanup;
+ }
+
+ vmDiskFileQuery->details->diskType = esxVI_Boolean_False;
+ vmDiskFileQuery->details->capacityKb = esxVI_Boolean_False;
+ vmDiskFileQuery->details->hardwareVersion = esxVI_Boolean_False;
+ vmDiskFileQuery->details->controllerType = esxVI_Boolean_True;
+ vmDiskFileQuery->details->diskExtents = esxVI_Boolean_False;
+
+ if (esxVI_String_Alloc(&searchSpec->matchPattern) < 0) {
+ goto cleanup;
+ }
+
+ searchSpec->matchPattern->value = fileName;
+
+ /* Search datastore for file */
+ if (esxVI_SearchDatastore_Task(data->ctx, hostDatastoreBrowser,
+ datastorePath, searchSpec, &task) < 0 ||
+ esxVI_WaitForTaskCompletion(data->ctx, task, NULL, esxVI_Occurrence_None,
+ esxVI_Boolean_False, &taskInfoState) < 0) {
+ goto cleanup;
+ }
+
+ if (taskInfoState != esxVI_TaskInfoState_Success) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not serach in datastore '%s'"), datastoreName);
+ goto cleanup;
+ }
+
+ if (esxVI_LookupTaskInfoByTask(data->ctx, task, &taskInfo) < 0 ||
+ esxVI_HostDatastoreBrowserSearchResults_CastFromAnyType
+ (taskInfo->result, &searchResults) < 0) {
+ goto cleanup;
+ }
+
+ /* Interpret search result */
+ vmDiskFileInfo = esxVI_VmDiskFileInfo_DynamicCast(searchResults->file);
+
+ if (vmDiskFileInfo == NULL || vmDiskFileInfo->controllerType == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup controller model for '%s'"), def->src);
+ goto cleanup;
+ }
+
+ if (STRCASEEQ(vmDiskFileInfo->controllerType,
+ "VirtualBusLogicController")) {
+ *model = VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC;
+ } else if (STRCASEEQ(vmDiskFileInfo->controllerType,
+ "VirtualLsiLogicController")) {
+ *model = VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC;
+ } else if (STRCASEEQ(vmDiskFileInfo->controllerType,
+ "VirtualLsiLogicSASController")) {
+ *model = VIR_DOMAIN_CONTROLLER_MODEL_LSISAS1068;
+ } else if (STRCASEEQ(vmDiskFileInfo->controllerType,
+ "ParaVirtualSCSIController")) {
+ *model = VIR_DOMAIN_CONTROLLER_MODEL_VMPVSCSI;
+ } else {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Found unexpected controller model '%s' for disk '%s'"),
+ vmDiskFileInfo->controllerType, def->src);
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ /* Don't double free fileName */
+ if (searchSpec != NULL && searchSpec->matchPattern != NULL) {
+ searchSpec->matchPattern->value = NULL;
+ }
+
+ VIR_FREE(datastoreName);
+ VIR_FREE(directoryName);
+ VIR_FREE(fileName);
+ VIR_FREE(datastorePath);
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&datastore);
+ esxVI_ManagedObjectReference_Free(&hostDatastoreBrowser);
+ esxVI_HostDatastoreBrowserSearchSpec_Free(&searchSpec);
+ esxVI_ManagedObjectReference_Free(&task);
+ esxVI_TaskInfo_Free(&taskInfo);
+ esxVI_HostDatastoreBrowserSearchResults_Free(&searchResults);
+
+ return result;
+}
+
static esxVI_Boolean
@@ -2176,6 +2539,8 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
virBuffer buffer = VIR_BUFFER_INITIALIZER;
char *url = NULL;
char *vmx = NULL;
+ esxVMX_Context ctx;
+ esxVMX_Data data;
virDomainDefPtr def = NULL;
char *xml = NULL;
@@ -2223,8 +2588,17 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
goto cleanup;
}
- def = esxVMX_ParseConfig(priv->primary, priv->caps, vmx, datastoreName,
- directoryName, priv->primary->productVersion);
+ data.ctx = priv->primary;
+ data.datastoreName = datastoreName;
+ data.directoryName = directoryName;
+
+ ctx.opaque = &data;
+ ctx.parseFileName = esxParseVMXFileName;
+ ctx.formatFileName = NULL;
+ ctx.autodetectSCSIControllerModel = NULL;
+
+ def = esxVMX_ParseConfig(&ctx, priv->caps, vmx,
+ priv->primary->productVersion);
if (def != NULL) {
xml = virDomainDefFormat(def, flags);
@@ -2255,6 +2629,8 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
unsigned int flags ATTRIBUTE_UNUSED)
{
esxPrivate *priv = conn->privateData;
+ esxVMX_Context ctx;
+ esxVMX_Data data;
virDomainDefPtr def = NULL;
char *xml = NULL;
@@ -2264,7 +2640,16 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
return NULL;
}
- def = esxVMX_ParseConfig(priv->primary, priv->caps, nativeConfig, "?", "?",
+ data.ctx = priv->primary;
+ data.datastoreName = "?";
+ data.directoryName = "?";
+
+ ctx.opaque = &data;
+ ctx.parseFileName = esxParseVMXFileName;
+ ctx.formatFileName = NULL;
+ ctx.autodetectSCSIControllerModel = NULL;
+
+ def = esxVMX_ParseConfig(&ctx, priv->caps, nativeConfig,
priv->primary->productVersion);
if (def != NULL) {
@@ -2284,6 +2669,8 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
unsigned int flags ATTRIBUTE_UNUSED)
{
esxPrivate *priv = conn->privateData;
+ esxVMX_Context ctx;
+ esxVMX_Data data;
virDomainDefPtr def = NULL;
char *vmx = NULL;
@@ -2299,7 +2686,16 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
return NULL;
}
- vmx = esxVMX_FormatConfig(priv->primary, priv->caps, def,
+ data.ctx = priv->primary;
+ data.datastoreName = NULL;
+ data.directoryName = NULL;
+
+ ctx.opaque = &data;
+ ctx.parseFileName = NULL;
+ ctx.formatFileName = esxFormatVMXFileName;
+ ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel;
+
+ vmx = esxVMX_FormatConfig(&ctx, priv->caps, def,
priv->primary->productVersion);
virDomainDefFree(def);
@@ -2488,6 +2884,8 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
int i;
virDomainDiskDefPtr disk = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
+ esxVMX_Context ctx;
+ esxVMX_Data data;
char *datastoreName = NULL;
char *directoryName = NULL;
char *fileName = NULL;
@@ -2529,7 +2927,16 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
}
/* Build VMX from domain XML */
- vmx = esxVMX_FormatConfig(priv->primary, priv->caps, def,
+ data.ctx = priv->primary;
+ data.datastoreName = NULL;
+ data.directoryName = NULL;
+
+ ctx.opaque = &data;
+ ctx.parseFileName = NULL;
+ ctx.formatFileName = esxFormatVMXFileName;
+ ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel;
+
+ vmx = esxVMX_FormatConfig(&ctx, priv->caps, def,
priv->primary->productVersion);
if (vmx == NULL) {
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
index 1a5e8d3..d5d9ff0 100644
--- a/src/esx/esx_vmx.c
+++ b/src/esx/esx_vmx.c
@@ -29,9 +29,7 @@
#include "virterror_internal.h"
#include "memory.h"
#include "logging.h"
-#include "esx_vi_methods.h"
#include "esx_private.h"
-#include "esx_util.h"
#include "esx_vmx.h"
/*
@@ -441,6 +439,11 @@ VIR_ENUM_IMPL(esxVMX_SCSIControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST,
"pvscsi");
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Helpers
+ */
+
int
esxVMX_SCSIDiskNameToControllerAndUnit(const char *name, int *controller, int *unit)
{
@@ -718,171 +721,7 @@ esxVMX_HandleLegacySCSIDiskDriverName(virDomainDefPtr def,
int
-esxVMX_AutodetectSCSIControllerModel(esxVI_Context *ctx,
- virDomainDiskDefPtr def, int *model)
-{
- int result = -1;
- char *datastoreName = NULL;
- char *directoryName = NULL;
- char *fileName = NULL;
- char *datastorePath = NULL;
- esxVI_String *propertyNameList = NULL;
- esxVI_ObjectContent *datastore = NULL;
- esxVI_ManagedObjectReference *hostDatastoreBrowser = NULL;
- esxVI_HostDatastoreBrowserSearchSpec *searchSpec = NULL;
- esxVI_VmDiskFileQuery *vmDiskFileQuery = NULL;
- esxVI_ManagedObjectReference *task = NULL;
- esxVI_TaskInfoState taskInfoState;
- esxVI_TaskInfo *taskInfo = NULL;
- esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
- esxVI_VmDiskFileInfo *vmDiskFileInfo = NULL;
-
- if (def->device != VIR_DOMAIN_DISK_DEVICE_DISK ||
- def->bus != VIR_DOMAIN_DISK_BUS_SCSI ||
- def->type != VIR_DOMAIN_DISK_TYPE_FILE ||
- def->src == NULL ||
- ! STRPREFIX(def->src, "[")) {
- /*
- * This isn't a file-based SCSI disk device with a datastore related
- * source path => do nothing.
- */
- return 0;
- }
-
- if (esxUtil_ParseDatastorePath(def->src, &datastoreName, &directoryName,
- &fileName) < 0) {
- goto cleanup;
- }
-
- if (directoryName == NULL) {
- if (virAsprintf(&datastorePath, "[%s]", datastoreName) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- } else {
- if (virAsprintf(&datastorePath, "[%s] %s", datastoreName,
- directoryName) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- }
-
- /* Lookup HostDatastoreBrowser */
- if (esxVI_String_AppendValueToList(&propertyNameList, "browser") < 0 ||
- esxVI_LookupDatastoreByName(ctx, datastoreName, propertyNameList,
- &datastore,
- esxVI_Occurrence_RequiredItem) < 0 ||
- esxVI_GetManagedObjectReference(datastore, "browser",
- &hostDatastoreBrowser,
- esxVI_Occurrence_RequiredItem) < 0) {
- goto cleanup;
- }
-
- /* Build HostDatastoreBrowserSearchSpec */
- if (esxVI_HostDatastoreBrowserSearchSpec_Alloc(&searchSpec) < 0 ||
- esxVI_FileQueryFlags_Alloc(&searchSpec->details) < 0) {
- goto cleanup;
- }
-
- searchSpec->details->fileType = esxVI_Boolean_True;
- searchSpec->details->fileSize = esxVI_Boolean_False;
- searchSpec->details->modification = esxVI_Boolean_False;
-
- if (esxVI_VmDiskFileQuery_Alloc(&vmDiskFileQuery) < 0 ||
- esxVI_VmDiskFileQueryFlags_Alloc(&vmDiskFileQuery->details) < 0 ||
- esxVI_FileQuery_AppendToList
- (&searchSpec->query,
- esxVI_FileQuery_DynamicCast(vmDiskFileQuery)) < 0) {
- goto cleanup;
- }
-
- vmDiskFileQuery->details->diskType = esxVI_Boolean_False;
- vmDiskFileQuery->details->capacityKb = esxVI_Boolean_False;
- vmDiskFileQuery->details->hardwareVersion = esxVI_Boolean_False;
- vmDiskFileQuery->details->controllerType = esxVI_Boolean_True;
- vmDiskFileQuery->details->diskExtents = esxVI_Boolean_False;
-
- if (esxVI_String_Alloc(&searchSpec->matchPattern) < 0) {
- goto cleanup;
- }
-
- searchSpec->matchPattern->value = fileName;
-
- /* Search datastore for file */
- if (esxVI_SearchDatastore_Task(ctx, hostDatastoreBrowser, datastorePath,
- searchSpec, &task) < 0 ||
- esxVI_WaitForTaskCompletion(ctx, task, NULL, esxVI_Occurrence_None,
- esxVI_Boolean_False, &taskInfoState) < 0) {
- goto cleanup;
- }
-
- if (taskInfoState != esxVI_TaskInfoState_Success) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Could not serach in datastore '%s'"), datastoreName);
- goto cleanup;
- }
-
- if (esxVI_LookupTaskInfoByTask(ctx, task, &taskInfo) < 0 ||
- esxVI_HostDatastoreBrowserSearchResults_CastFromAnyType
- (taskInfo->result, &searchResults) < 0) {
- goto cleanup;
- }
-
- /* Interpret search result */
- vmDiskFileInfo = esxVI_VmDiskFileInfo_DynamicCast(searchResults->file);
-
- if (vmDiskFileInfo == NULL || vmDiskFileInfo->controllerType == NULL) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Could not lookup controller model for '%s'"), def->src);
- goto cleanup;
- }
-
- if (STRCASEEQ(vmDiskFileInfo->controllerType,
- "VirtualBusLogicController")) {
- *model = VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC;
- } else if (STRCASEEQ(vmDiskFileInfo->controllerType,
- "VirtualLsiLogicController")) {
- *model = VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC;
- } else if (STRCASEEQ(vmDiskFileInfo->controllerType,
- "VirtualLsiLogicSASController")) {
- *model = VIR_DOMAIN_CONTROLLER_MODEL_LSISAS1068;
- } else if (STRCASEEQ(vmDiskFileInfo->controllerType,
- "ParaVirtualSCSIController")) {
- *model = VIR_DOMAIN_CONTROLLER_MODEL_VMPVSCSI;
- } else {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Found unexpected controller model '%s' for disk '%s'"),
- vmDiskFileInfo->controllerType, def->src);
- goto cleanup;
- }
-
- result = 0;
-
- cleanup:
- /* Don't double free fileName */
- if (searchSpec != NULL && searchSpec->matchPattern != NULL) {
- searchSpec->matchPattern->value = NULL;
- }
-
- VIR_FREE(datastoreName);
- VIR_FREE(directoryName);
- VIR_FREE(fileName);
- VIR_FREE(datastorePath);
- esxVI_String_Free(&propertyNameList);
- esxVI_ObjectContent_Free(&datastore);
- esxVI_ManagedObjectReference_Free(&hostDatastoreBrowser);
- esxVI_HostDatastoreBrowserSearchSpec_Free(&searchSpec);
- esxVI_ManagedObjectReference_Free(&task);
- esxVI_TaskInfo_Free(&taskInfo);
- esxVI_HostDatastoreBrowserSearchResults_Free(&searchResults);
-
- return result;
-}
-
-
-
-int
-esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
+esxVMX_GatherSCSIControllers(esxVMX_Context *ctx, virDomainDefPtr def,
int virtualDev[4], bool present[4])
{
int result = -1;
@@ -923,8 +762,8 @@ esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
continue;
}
- if (ctx != NULL &&
- controller->model == VIR_DOMAIN_CONTROLLER_MODEL_AUTO) {
+ if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_AUTO &&
+ ctx->autodetectSCSIControllerModel != NULL) {
count = 0;
// try to autodetect the SCSI controller model by collecting
@@ -934,8 +773,9 @@ esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI &&
disk->info.addr.drive.controller == controller->idx) {
- if (esxVMX_AutodetectSCSIControllerModel
- (ctx, disk, &autodetectedModels[count]) < 0) {
+ if (ctx->autodetectSCSIControllerModel
+ (disk, &autodetectedModels[count],
+ ctx->opaque) < 0) {
goto cleanup;
}
@@ -985,144 +825,12 @@ esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
-char *
-esxVMX_AbsolutePathToDatastorePath(esxVI_Context *ctx, const char *absolutePath)
-{
- bool success = false;
- char *copyOfAbsolutePath = NULL;
- char *tmp = NULL;
- char *saveptr = NULL;
- esxVI_String *propertyNameList = NULL;
- esxVI_ObjectContent *datastore = NULL;
-
- char *datastorePath = NULL;
- char *preliminaryDatastoreName = NULL;
- char *directoryAndFileName = NULL;
- char *datastoreName = NULL;
-
- if (esxVI_String_DeepCopyValue(©OfAbsolutePath, absolutePath) < 0) {
- return NULL;
- }
-
- /* Expected format: '/vmfs/volumes/<datastore>/<path>' */
- if ((tmp = STRSKIP(copyOfAbsolutePath, "/vmfs/volumes/")) == NULL ||
- (preliminaryDatastoreName = strtok_r(tmp, "/", &saveptr)) == NULL ||
- (directoryAndFileName = strtok_r(NULL, "", &saveptr)) == NULL) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Absolute path '%s' doesn't have expected format "
- "'/vmfs/volumes/<datastore>/<path>'"), absolutePath);
- goto cleanup;
- }
-
- if (ctx != NULL) {
- if (esxVI_String_AppendValueToList(&propertyNameList,
- "summary.name") < 0 ||
- esxVI_LookupDatastoreByAbsolutePath(ctx, absolutePath,
- propertyNameList, &datastore,
- esxVI_Occurrence_OptionalItem) < 0) {
- goto cleanup;
- }
-
- if (datastore == NULL) {
- if (esxVI_LookupDatastoreByName(ctx, preliminaryDatastoreName,
- propertyNameList, &datastore,
- esxVI_Occurrence_OptionalItem) < 0) {
- goto cleanup;
- }
- }
-
- if (datastore != NULL) {
- if (esxVI_GetStringValue(datastore, "summary.name", &datastoreName,
- esxVI_Occurrence_RequiredItem)) {
- goto cleanup;
- }
- }
-
- if (datastoreName == NULL) {
- VIR_WARN("Could not retrieve datastore name for absolute "
- "path '%s', falling back to preliminary name '%s'",
- absolutePath, preliminaryDatastoreName);
-
- datastoreName = preliminaryDatastoreName;
- }
- } else {
- datastoreName = preliminaryDatastoreName;
- }
-
- if (virAsprintf(&datastorePath, "[%s] %s", datastoreName,
- directoryAndFileName) < 0) {
- virReportOOMError();
- goto cleanup;
- }
-
- /* FIXME: Check if referenced path/file really exists */
-
- success = true;
-
- cleanup:
- if (! success) {
- VIR_FREE(datastorePath);
- }
-
- VIR_FREE(copyOfAbsolutePath);
- esxVI_String_Free(&propertyNameList);
- esxVI_ObjectContent_Free(&datastore);
-
- return datastorePath;
-}
-
-
-
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VMX -> Domain XML
*/
-char *
-esxVMX_ParseFileName(esxVI_Context *ctx, const char *fileName,
- const char *datastoreName, const char *directoryName)
-{
- char *src = NULL;
-
- if (STRPREFIX(fileName, "/vmfs/volumes/")) {
- /* Found absolute path referencing a file inside a datastore */
- return esxVMX_AbsolutePathToDatastorePath(ctx, fileName);
- } else if (STRPREFIX(fileName, "/")) {
- /* Found absolute path referencing a file outside a datastore */
- src = strdup(fileName);
-
- if (src == NULL) {
- virReportOOMError();
- return NULL;
- }
-
- /* FIXME: Check if referenced path/file really exists */
-
- return src;
- } else if (strchr(fileName, '/') != NULL) {
- /* Found relative path, this is not supported */
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Found relative path '%s' in VMX file, this is not "
- "supported"), fileName);
- return NULL;
- } else {
- /* Found single file name referencing a file inside a datastore */
- if (virAsprintf(&src, "[%s] %s/%s", datastoreName, directoryName,
- fileName) < 0) {
- virReportOOMError();
- return NULL;
- }
-
- /* FIXME: Check if referenced path/file really exists */
-
- return src;
- }
-}
-
-
-
virDomainDefPtr
-esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
- const char *datastoreName, const char *directoryName,
+esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
esxVI_ProductVersion productVersion)
{
bool success = false;
@@ -1142,6 +850,12 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
int scsi_virtualDev[4] = { -1, -1, -1, -1 };
int unit;
+ if (ctx->parseFileName == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("esxVMX_Context has no parseFileName function set"));
+ return NULL;
+ }
+
conf = virConfReadMem(vmx, strlen(vmx), VIR_CONF_FLAG_VMX_FORMAT);
if (conf == NULL) {
@@ -1429,7 +1143,6 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
VIR_DOMAIN_DISK_BUS_SCSI, controller, unit,
- datastoreName, directoryName,
&def->disks[def->ndisks]) < 0) {
goto cleanup;
}
@@ -1441,7 +1154,6 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
VIR_DOMAIN_DISK_BUS_SCSI, controller, unit,
- datastoreName, directoryName,
&def->disks[def->ndisks]) < 0) {
goto cleanup;
}
@@ -1457,7 +1169,6 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
for (unit = 0; unit < 2; ++unit) {
if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
VIR_DOMAIN_DISK_BUS_IDE, bus, unit,
- datastoreName, directoryName,
&def->disks[def->ndisks]) < 0) {
goto cleanup;
}
@@ -1469,7 +1180,6 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
VIR_DOMAIN_DISK_BUS_IDE, bus, unit,
- datastoreName, directoryName,
&def->disks[def->ndisks]) < 0) {
goto cleanup;
}
@@ -1484,7 +1194,6 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
for (unit = 0; unit < 2; ++unit) {
if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY,
VIR_DOMAIN_DISK_BUS_FDC, 0, unit,
- datastoreName, directoryName,
&def->disks[def->ndisks]) < 0) {
goto cleanup;
}
@@ -1555,7 +1264,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
def->nserials = 0;
for (port = 0; port < 4; ++port) {
- if (esxVMX_ParseSerial(ctx, conf, port, datastoreName, directoryName,
+ if (esxVMX_ParseSerial(ctx, conf, port,
&def->serials[def->nserials]) < 0) {
goto cleanup;
}
@@ -1574,7 +1283,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
def->nparallels = 0;
for (port = 0; port < 3; ++port) {
- if (esxVMX_ParseParallel(ctx, conf, port, datastoreName, directoryName,
+ if (esxVMX_ParseParallel(ctx, conf, port,
&def->parallels[def->nparallels]) < 0) {
goto cleanup;
}
@@ -1752,9 +1461,8 @@ struct _virDomainDiskDef {
};*/
int
-esxVMX_ParseDisk(esxVI_Context *ctx, virCapsPtr caps, virConfPtr conf,
+esxVMX_ParseDisk(esxVMX_Context *ctx, virCapsPtr caps, virConfPtr conf,
int device, int busType, int controllerOrBus, int unit,
- const char *datastoreName, const char *directoryName,
virDomainDiskDefPtr *def)
{
/*
@@ -1996,8 +1704,7 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virCapsPtr caps, virConfPtr conf,
}
(*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
- (*def)->src = esxVMX_ParseFileName(ctx, fileName, datastoreName,
- directoryName);
+ (*def)->src = ctx->parseFileName(fileName, ctx->opaque);
(*def)->cachemode = writeThrough ? VIR_DOMAIN_DISK_CACHE_WRITETHRU
: VIR_DOMAIN_DISK_CACHE_DEFAULT;
@@ -2031,8 +1738,7 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virCapsPtr caps, virConfPtr conf,
}
(*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
- (*def)->src = esxVMX_ParseFileName(ctx, fileName, datastoreName,
- directoryName);
+ (*def)->src = ctx->parseFileName(fileName, ctx->opaque);
if ((*def)->src == NULL) {
goto cleanup;
@@ -2068,8 +1774,7 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virCapsPtr caps, virConfPtr conf,
}
(*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
- (*def)->src = esxVMX_ParseFileName(ctx, fileName, datastoreName,
- directoryName);
+ (*def)->src = ctx->parseFileName(fileName, ctx->opaque);
if ((*def)->src == NULL) {
goto cleanup;
@@ -2358,8 +2063,7 @@ esxVMX_ParseEthernet(virConfPtr conf, int controller, virDomainNetDefPtr *def)
int
-esxVMX_ParseSerial(esxVI_Context *ctx, virConfPtr conf, int port,
- const char *datastoreName, const char *directoryName,
+esxVMX_ParseSerial(esxVMX_Context *ctx, virConfPtr conf, int port,
virDomainChrDefPtr *def)
{
int result = -1;
@@ -2439,9 +2143,7 @@ esxVMX_ParseSerial(esxVI_Context *ctx, virConfPtr conf, int port,
} else if (STRCASEEQ(fileType, "file")) {
(*def)->target.port = port;
(*def)->type = VIR_DOMAIN_CHR_TYPE_FILE;
- (*def)->data.file.path = esxVMX_ParseFileName(ctx, fileName,
- datastoreName,
- directoryName);
+ (*def)->data.file.path = ctx->parseFileName(fileName, ctx->opaque);
if ((*def)->data.file.path == NULL) {
goto cleanup;
@@ -2488,8 +2190,7 @@ esxVMX_ParseSerial(esxVI_Context *ctx, virConfPtr conf, int port,
int
-esxVMX_ParseParallel(esxVI_Context *ctx, virConfPtr conf, int port,
- const char *datastoreName, const char *directoryName,
+esxVMX_ParseParallel(esxVMX_Context *ctx, virConfPtr conf, int port,
virDomainChrDefPtr *def)
{
int result = -1;
@@ -2569,9 +2270,7 @@ esxVMX_ParseParallel(esxVI_Context *ctx, virConfPtr conf, int port,
} else if (STRCASEEQ(fileType, "file")) {
(*def)->target.port = port;
(*def)->type = VIR_DOMAIN_CHR_TYPE_FILE;
- (*def)->data.file.path = esxVMX_ParseFileName(ctx, fileName,
- datastoreName,
- directoryName);
+ (*def)->data.file.path = ctx->parseFileName(fileName, ctx->opaque);
if ((*def)->data.file.path == NULL) {
goto cleanup;
@@ -2612,70 +2311,7 @@ esxVMX_ParseParallel(esxVI_Context *ctx, virConfPtr conf, int port,
*/
char *
-esxVMX_FormatFileName(esxVI_Context *ctx ATTRIBUTE_UNUSED, const char *src)
-{
- bool success = false;
- char *datastoreName = NULL;
- char *directoryName = NULL;
- char *fileName = NULL;
- char *absolutePath = NULL;
-
- if (STRPREFIX(src, "[")) {
- /* Found potential datastore related path */
- if (esxUtil_ParseDatastorePath(src, &datastoreName, &directoryName,
- &fileName) < 0) {
- goto cleanup;
- }
-
- if (directoryName == NULL) {
- if (virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s",
- datastoreName, fileName) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- } else {
- if (virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s/%s",
- datastoreName, directoryName, fileName) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- }
- } else if (STRPREFIX(src, "/")) {
- /* Found absolute path */
- absolutePath = strdup(src);
-
- if (absolutePath == NULL) {
- virReportOOMError();
- goto cleanup;
- }
- } else {
- /* Found relative path, this is not supported */
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Found relative path '%s' in domain XML, this is not "
- "supported"), src);
- goto cleanup;
- }
-
- /* FIXME: Check if referenced path/file really exists */
-
- success = true;
-
- cleanup:
- if (! success) {
- VIR_FREE(absolutePath);
- }
-
- VIR_FREE(datastoreName);
- VIR_FREE(directoryName);
- VIR_FREE(fileName);
-
- return absolutePath;
-}
-
-
-
-char *
-esxVMX_FormatConfig(esxVI_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
+esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
esxVI_ProductVersion productVersion)
{
int i;
@@ -2685,6 +2321,12 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
bool scsi_present[4] = { false, false, false, false };
int scsi_virtualDev[4] = { -1, -1, -1, -1 };
+ if (ctx->formatFileName == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("esxVMX_Context has no formatFileName function set"));
+ return NULL;
+ }
+
memset(zero, 0, VIR_UUID_BUFLEN);
if (def->virtType != VIR_DOMAIN_VIRT_VMWARE) { /* FIXME: maybe add VIR_DOMAIN_VIRT_ESX ? */
@@ -2990,7 +2632,7 @@ esxVMX_FormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer)
int
-esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
+esxVMX_FormatHardDisk(esxVMX_Context *ctx, virDomainDiskDefPtr def,
virBufferPtr buffer)
{
int controllerOrBus, unit;
@@ -3050,7 +2692,7 @@ esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
return -1;
}
- fileName = esxVMX_FormatFileName(ctx, def->src);
+ fileName = ctx->formatFileName(def->src, ctx->opaque);
if (fileName == NULL) {
return -1;
@@ -3081,7 +2723,7 @@ esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
int
-esxVMX_FormatCDROM(esxVI_Context *ctx, virDomainDiskDefPtr def,
+esxVMX_FormatCDROM(esxVMX_Context *ctx, virDomainDiskDefPtr def,
virBufferPtr buffer)
{
int controllerOrBus, unit;
@@ -3132,7 +2774,7 @@ esxVMX_FormatCDROM(esxVI_Context *ctx, virDomainDiskDefPtr def,
return -1;
}
- fileName = esxVMX_FormatFileName(ctx, def->src);
+ fileName = ctx->formatFileName(def->src, ctx->opaque);
if (fileName == NULL) {
return -1;
@@ -3167,7 +2809,7 @@ esxVMX_FormatCDROM(esxVI_Context *ctx, virDomainDiskDefPtr def,
int
-esxVMX_FormatFloppy(esxVI_Context *ctx, virDomainDiskDefPtr def,
+esxVMX_FormatFloppy(esxVMX_Context *ctx, virDomainDiskDefPtr def,
virBufferPtr buffer)
{
int unit;
@@ -3195,7 +2837,7 @@ esxVMX_FormatFloppy(esxVI_Context *ctx, virDomainDiskDefPtr def,
return -1;
}
- fileName = esxVMX_FormatFileName(ctx, def->src);
+ fileName = ctx->formatFileName(def->src, ctx->opaque);
if (fileName == NULL) {
return -1;
@@ -3331,7 +2973,7 @@ esxVMX_FormatEthernet(virDomainNetDefPtr def, int controller,
int
-esxVMX_FormatSerial(esxVI_Context *ctx, virDomainChrDefPtr def,
+esxVMX_FormatSerial(esxVMX_Context *ctx, virDomainChrDefPtr def,
virBufferPtr buffer)
{
char *fileName = NULL;
@@ -3365,7 +3007,7 @@ esxVMX_FormatSerial(esxVI_Context *ctx, virDomainChrDefPtr def,
virBufferVSprintf(buffer, "serial%d.fileType = \"file\"\n",
def->target.port);
- fileName = esxVMX_FormatFileName(ctx, def->data.file.path);
+ fileName = ctx->formatFileName(def->data.file.path, ctx->opaque);
if (fileName == NULL) {
return -1;
@@ -3408,7 +3050,7 @@ esxVMX_FormatSerial(esxVI_Context *ctx, virDomainChrDefPtr def,
int
-esxVMX_FormatParallel(esxVI_Context *ctx, virDomainChrDefPtr def,
+esxVMX_FormatParallel(esxVMX_Context *ctx, virDomainChrDefPtr def,
virBufferPtr buffer)
{
char *fileName = NULL;
@@ -3443,7 +3085,7 @@ esxVMX_FormatParallel(esxVI_Context *ctx, virDomainChrDefPtr def,
virBufferVSprintf(buffer, "parallel%d.fileType = \"file\"\n",
def->target.port);
- fileName = esxVMX_FormatFileName(ctx, def->data.file.path);
+ fileName = ctx->formatFileName(def->data.file.path, ctx->opaque);
if (fileName == NULL) {
return -1;
diff --git a/src/esx/esx_vmx.h b/src/esx/esx_vmx.h
index bda98f0..a77264a 100644
--- a/src/esx/esx_vmx.h
+++ b/src/esx/esx_vmx.h
@@ -30,6 +30,37 @@
# include "domain_conf.h"
# include "esx_vi.h"
+typedef struct _esxVMX_Context esxVMX_Context;
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Context
+ */
+
+typedef char * (*esxVMX_ParseFileName)(const char *fileName, void *opaque);
+typedef char * (*esxVMX_FormatFileName)(const char *src, void *opaque);
+typedef int (*esxVMX_AutodetectSCSIControllerModel)(virDomainDiskDefPtr def,
+ int *model, void *opaque);
+
+/*
+ * esxVMX_ParseFileName is only used by esxVMX_ParseConfig.
+ * esxVMX_FormatFileName is only used by esxVMX_FormatConfig.
+ * esxVMX_AutodetectSCSIControllerModel is optionally used by esxVMX_FormatConfig.
+ */
+struct _esxVMX_Context {
+ void *opaque;
+ esxVMX_ParseFileName parseFileName;
+ esxVMX_FormatFileName formatFileName;
+ esxVMX_AutodetectSCSIControllerModel autodetectSCSIControllerModel;
+};
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Helpers
+ */
+
int
esxVMX_SCSIDiskNameToControllerAndUnit(const char *name, int *controller,
int *unit);
@@ -48,29 +79,17 @@ esxVMX_HandleLegacySCSIDiskDriverName(virDomainDefPtr def,
virDomainDiskDefPtr disk);
int
-esxVMX_AutodetectSCSIControllerModel(esxVI_Context *ctx,
- virDomainDiskDefPtr def, int *model);
-
-int
-esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
+esxVMX_GatherSCSIControllers(esxVMX_Context *ctx, virDomainDefPtr def,
int virtualDev[4], bool present[4]);
-char *
-esxVMX_AbsolutePathToDatastorePath(esxVI_Context *ctx, const char *absolutePath);
-
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VMX -> Domain XML
*/
-char *
-esxVMX_ParseFileName(esxVI_Context *ctx, const char *fileName,
- const char *datastoreName, const char *directoryName);
-
virDomainDefPtr
-esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
- const char *datastoreName, const char *directoryName,
+esxVMX_ParseConfig(esxVMX_Context *ctx, virCapsPtr caps, const char *vmx,
esxVI_ProductVersion productVersion);
int
@@ -81,21 +100,18 @@ esxVMX_ParseSCSIController(virConfPtr conf, int controller, bool *present,
int *virtualDev);
int
-esxVMX_ParseDisk(esxVI_Context *ctx, virCapsPtr caps, virConfPtr conf,
+esxVMX_ParseDisk(esxVMX_Context *ctx, virCapsPtr caps, virConfPtr conf,
int device, int busType, int controllerOrBus, int unit,
- const char *datastoreName, const char *directoryName,
virDomainDiskDefPtr *def);
int
esxVMX_ParseEthernet(virConfPtr conf, int controller, virDomainNetDefPtr *def);
int
-esxVMX_ParseSerial(esxVI_Context *ctx, virConfPtr conf, int port,
- const char *datastoreName, const char *directoryName,
+esxVMX_ParseSerial(esxVMX_Context *ctx, virConfPtr conf, int port,
virDomainChrDefPtr *def);
int
-esxVMX_ParseParallel(esxVI_Context *ctx, virConfPtr conf, int port,
- const char *datastoreName, const char *directoryName,
+esxVMX_ParseParallel(esxVMX_Context *ctx, virConfPtr conf, int port,
virDomainChrDefPtr *def);
@@ -105,25 +121,22 @@ esxVMX_ParseParallel(esxVI_Context *ctx, virConfPtr conf, int port,
*/
char *
-esxVMX_FormatFileName(esxVI_Context *ctx, const char *src);
-
-char *
-esxVMX_FormatConfig(esxVI_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
+esxVMX_FormatConfig(esxVMX_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
esxVI_ProductVersion productVersion);
int
esxVMX_FormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer);
int
-esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
+esxVMX_FormatHardDisk(esxVMX_Context *ctx, virDomainDiskDefPtr def,
virBufferPtr buffer);
int
-esxVMX_FormatCDROM(esxVI_Context *ctx, virDomainDiskDefPtr def,
+esxVMX_FormatCDROM(esxVMX_Context *ctx, virDomainDiskDefPtr def,
virBufferPtr buffer);
int
-esxVMX_FormatFloppy(esxVI_Context *ctx, virDomainDiskDefPtr def,
+esxVMX_FormatFloppy(esxVMX_Context *ctx, virDomainDiskDefPtr def,
virBufferPtr buffer);
int
@@ -131,11 +144,11 @@ esxVMX_FormatEthernet(virDomainNetDefPtr def, int controller,
virBufferPtr buffer);
int
-esxVMX_FormatSerial(esxVI_Context *ctx, virDomainChrDefPtr def,
+esxVMX_FormatSerial(esxVMX_Context *ctx, virDomainChrDefPtr def,
virBufferPtr buffer);
int
-esxVMX_FormatParallel(esxVI_Context *ctx, virDomainChrDefPtr def,
+esxVMX_FormatParallel(esxVMX_Context *ctx, virDomainChrDefPtr def,
virBufferPtr buffer);
#endif /* __ESX_VMX_H__ */
diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
index f1d2471..50e7d0c 100644
--- a/tests/vmx2xmltest.c
+++ b/tests/vmx2xmltest.c
@@ -14,6 +14,7 @@
static char *progname = NULL;
static char *abs_srcdir = NULL;
static virCapsPtr caps = NULL;
+static esxVMX_Context ctx;
# define MAX_FILE 4096
@@ -87,8 +88,7 @@ testCompareFiles(const char *vmx, const char *xml,
goto failure;
}
- def = esxVMX_ParseConfig(NULL, caps, vmxData, "datastore", "directory",
- productVersion);
+ def = esxVMX_ParseConfig(&ctx, caps, vmxData, productVersion);
if (def == NULL) {
err = virGetLastError();
@@ -139,6 +139,49 @@ testCompareHelper(const void *data)
return testCompareFiles(vmx, xml, info->version);
}
+static char *
+testParseVMXFileName(const char *fileName, void *opaque ATTRIBUTE_UNUSED)
+{
+ char *copyOfFileName = NULL;
+ char *tmp = NULL;
+ char *saveptr = NULL;
+ char *datastoreName = NULL;
+ char *directoryAndFileName = NULL;
+ char *src = NULL;
+
+ if (STRPREFIX(fileName, "/vmfs/volumes/")) {
+ /* Found absolute path referencing a file inside a datastore */
+ copyOfFileName = strdup(fileName);
+
+ if (copyOfFileName == NULL) {
+ goto cleanup;
+ }
+
+ /* Expected format: '/vmfs/volumes/<datastore>/<path>' */
+ if ((tmp = STRSKIP(copyOfFileName, "/vmfs/volumes/")) == NULL ||
+ (datastoreName = strtok_r(tmp, "/", &saveptr)) == NULL ||
+ (directoryAndFileName = strtok_r(NULL, "", &saveptr)) == NULL) {
+ goto cleanup;
+ }
+
+ virAsprintf(&src, "[%s] %s", datastoreName, directoryAndFileName);
+ } else if (STRPREFIX(fileName, "/")) {
+ /* Found absolute path referencing a file outside a datastore */
+ src = strdup(fileName);
+ } else if (strchr(fileName, '/') != NULL) {
+ /* Found relative path, this is not supported */
+ src = NULL;
+ } else {
+ /* Found single file name referencing a file inside a datastore */
+ virAsprintf(&src, "[datastore] directory/%s", fileName);
+ }
+
+ cleanup:
+ VIR_FREE(copyOfFileName);
+
+ return src;
+}
+
static int
mymain(int argc, char **argv)
{
@@ -179,6 +222,11 @@ mymain(int argc, char **argv)
return EXIT_FAILURE;
}
+ ctx.opaque = NULL;
+ ctx.parseFileName = testParseVMXFileName;
+ ctx.formatFileName = NULL;
+ ctx.autodetectSCSIControllerModel = NULL;
+
DO_TEST("case-insensitive-1", "case-insensitive-1", esxVI_ProductVersion_ESX35);
DO_TEST("case-insensitive-2", "case-insensitive-2", esxVI_ProductVersion_ESX35);
diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c
index 0a9bc53..eed3ac0 100644
--- a/tests/xml2vmxtest.c
+++ b/tests/xml2vmxtest.c
@@ -14,6 +14,7 @@
static char *progname = NULL;
static char *abs_srcdir = NULL;
static virCapsPtr caps = NULL;
+static esxVMX_Context ctx;
# define MAX_FILE 4096
@@ -92,7 +93,7 @@ testCompareFiles(const char *xml, const char *vmx,
goto failure;
}
- formatted = esxVMX_FormatConfig(NULL, caps, def, productVersion);
+ formatted = esxVMX_FormatConfig(&ctx, caps, def, productVersion);
if (formatted == NULL) {
goto failure;
@@ -134,6 +135,60 @@ testCompareHelper(const void *data)
}
static int
+testAutodetectSCSIControllerModel(virDomainDiskDefPtr def ATTRIBUTE_UNUSED,
+ int *model, void *opaque ATTRIBUTE_UNUSED)
+{
+ *model = VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC;
+
+ return 0;
+}
+
+static char *
+testFormatVMXFileName(const char *src, void *opaque ATTRIBUTE_UNUSED)
+{
+ bool success = false;
+ char *datastoreName = NULL;
+ char *directoryName = NULL;
+ char *fileName = NULL;
+ char *absolutePath = NULL;
+
+ if (STRPREFIX(src, "[")) {
+ /* Found potential datastore path */
+ if (esxUtil_ParseDatastorePath(src, &datastoreName, &directoryName,
+ &fileName) < 0) {
+ goto cleanup;
+ }
+
+ if (directoryName == NULL) {
+ virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s", datastoreName,
+ fileName);
+ } else {
+ virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s/%s", datastoreName,
+ directoryName, fileName);
+ }
+ } else if (STRPREFIX(src, "/")) {
+ /* Found absolute path */
+ absolutePath = strdup(src);
+ } else {
+ /* Found relative path, this is not supported */
+ goto cleanup;
+ }
+
+ success = true;
+
+ cleanup:
+ if (! success) {
+ VIR_FREE(absolutePath);
+ }
+
+ VIR_FREE(datastoreName);
+ VIR_FREE(directoryName);
+ VIR_FREE(fileName);
+
+ return absolutePath;
+}
+
+static int
mymain(int argc, char **argv)
{
int result = 0;
@@ -157,7 +212,7 @@ mymain(int argc, char **argv)
return EXIT_FAILURE;
}
-# define DO_TEST(_in, _out, _version) \
+# define DO_TEST(_in, _out, _version) \
do { \
struct testInfo info = { _in, _out, _version }; \
virResetLastError(); \
@@ -173,6 +228,11 @@ mymain(int argc, char **argv)
return EXIT_FAILURE;
}
+ ctx.opaque = NULL;
+ ctx.parseFileName = NULL;
+ ctx.formatFileName = testFormatVMXFileName;
+ ctx.autodetectSCSIControllerModel = testAutodetectSCSIControllerModel;
+
DO_TEST("minimal", "minimal", esxVI_ProductVersion_ESX35);
DO_TEST("minimal-64bit", "minimal-64bit", esxVI_ProductVersion_ESX35);
--
1.7.0.4
14 years, 8 months
[libvirt] [PATCH] allow memballoon type of none to desactivate it
by Daniel Veillard
The balloon device is automatically added to qemu guests if supported,
but it may be useful to desactivate it. The simplest to not change the
existing behaviour is to allow
<memballoon type="none"/>
as an extra option to desactivate it (it is automatically added if the
memballoon construct is missing for the domain).
The following simple patch just adds the extra option and does not
change the default behaviour but avoid creating a balloon device if
type="none" is used.
Daniel
P.S.: there is also a XEN type uspposedly for xen but I was unable to
find any baloon code in our current xen driver so no change there
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
14 years, 8 months
[libvirt] [PATCH] nodeinfo: skip offline CPUs
by Eric Blake
https://bugzilla.redhat.com/622515 - When hot-unplugging CPUs,
libvirt failed to start a guest that had been pinned to CPUs that
were still online, because it was failing to read status from
unrelated offline CPUs.
Tested on a dual-core laptop, where I also discovered that, per
http://www.cyberciti.biz/files/linux-kernel/Documentation/cpu-hotplug.txt,
/sys/devices/system/cpu/cpu0/online does not exist on systems where it
cannot be hot-unplugged.
* src/nodeinfo.c (linuxNodeInfoCPUPopulate): Ignore CPUs that are
currently offline. Detect readdir failure.
(parse_socket): Move guts...
(get_cpu_value): ...to new function, shared with...
(cpu_online): New function.
---
src/nodeinfo.c | 109 +++++++++++++++++++++++++++++++++++++------------------
1 files changed, 73 insertions(+), 36 deletions(-)
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index 5ec1bcf..6286aa2 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -23,6 +23,7 @@
#include <config.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -60,6 +61,58 @@
int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
virNodeInfoPtr nodeinfo);
+/* Return the positive decimal contents of the given
+ * CPU_SYS_PATH/cpu%u/FILE, or -1 on error. If MISSING_OK and the
+ * file could not be found, return 1 instead of an error; this is
+ * because some machines cannot hot-unplug cpu0. */
+static int get_cpu_value(unsigned int cpu, const char *file, bool missing_ok)
+{
+ char *path;
+ FILE *pathfp;
+ char value_str[1024];
+ char *tmp;
+ int value = -1;
+
+ if (virAsprintf(&path, CPU_SYS_PATH "/cpu%u/%s", cpu, file) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ pathfp = fopen(path, "r");
+ if (pathfp == NULL) {
+ if (missing_ok && errno == ENOENT)
+ value = 1;
+ else
+ virReportSystemError(errno, _("cannot open %s"), path);
+ goto cleanup;
+ }
+
+ if (fgets(value_str, sizeof(value_str), pathfp) == NULL) {
+ virReportSystemError(errno, _("cannot read from %s"), path);
+ goto cleanup;
+ }
+ if (virStrToLong_i(value_str, &tmp, 10, &value) < 0) {
+ nodeReportError(VIR_ERR_INTERNAL_ERROR,
+ _("could not convert '%s' to an integer"),
+ value_str);
+ goto cleanup;
+ }
+
+cleanup:
+ if (pathfp)
+ fclose(pathfp);
+ VIR_FREE(path);
+
+ return value;
+}
+
+/* Check if CPU is online via CPU_SYS_PATH/cpu%u/online. Return 1 if online,
+ 0 if offline, and -1 on error. */
+static int cpu_online(unsigned int cpu)
+{
+ return get_cpu_value(cpu, "online", cpu == 0);
+}
+
static unsigned long count_thread_siblings(unsigned int cpu)
{
unsigned long ret = 0;
@@ -106,41 +159,7 @@ cleanup:
static int parse_socket(unsigned int cpu)
{
- char *path;
- FILE *pathfp;
- char socket_str[1024];
- char *tmp;
- int socket = -1;
-
- if (virAsprintf(&path, CPU_SYS_PATH "/cpu%u/topology/physical_package_id",
- cpu) < 0) {
- virReportOOMError();
- return -1;
- }
-
- pathfp = fopen(path, "r");
- if (pathfp == NULL) {
- virReportSystemError(errno, _("cannot open %s"), path);
- VIR_FREE(path);
- return -1;
- }
-
- if (fgets(socket_str, sizeof(socket_str), pathfp) == NULL) {
- virReportSystemError(errno, _("cannot read from %s"), path);
- goto cleanup;
- }
- if (virStrToLong_i(socket_str, &tmp, 10, &socket) < 0) {
- nodeReportError(VIR_ERR_INTERNAL_ERROR,
- _("could not convert '%s' to an integer"),
- socket_str);
- goto cleanup;
- }
-
-cleanup:
- fclose(pathfp);
- VIR_FREE(path);
-
- return socket;
+ return get_cpu_value(cpu, "topology/physical_package_id", false);
}
int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
@@ -153,6 +172,8 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
unsigned long cur_threads;
int socket;
unsigned long long socket_mask = 0;
+ unsigned int remaining;
+ int online;
nodeinfo->cpus = 0;
nodeinfo->mhz = 0;
@@ -222,15 +243,25 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
/* OK, we've parsed what we can out of /proc/cpuinfo. Get the socket
* and thread information from /sys
*/
+ remaining = nodeinfo->cpus;
cpudir = opendir(CPU_SYS_PATH);
if (cpudir == NULL) {
virReportSystemError(errno, _("cannot opendir %s"), CPU_SYS_PATH);
return -1;
}
- while ((cpudirent = readdir(cpudir))) {
+ while (errno = 0, remaining && (cpudirent = readdir(cpudir))) {
if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
continue;
+ online = cpu_online(cpu);
+ if (online < 0) {
+ closedir(cpudir);
+ return -1;
+ }
+ if (!online)
+ continue;
+ remaining--;
+
socket = parse_socket(cpu);
if (socket < 0) {
closedir(cpudir);
@@ -249,6 +280,12 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
if (cur_threads > nodeinfo->threads)
nodeinfo->threads = cur_threads;
}
+ if (errno) {
+ virReportSystemError(errno,
+ _("problem reading %s"), CPU_SYS_PATH);
+ closedir(cpudir);
+ return -1;
+ }
closedir(cpudir);
--
1.7.1
14 years, 8 months
[libvirt] [PATCH] Avoid autogen loop in VPATH builds
by Jiri Denemark
---
cfg.mk | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index 7226828..e7fd63c 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -459,7 +459,7 @@ ifeq (0,$(MAKELEVEL))
# b653eda3ac4864de205419d9f41eec267cb89eeb
_submodule_hash = sed 's/^[ +-]//;s/ .*//'
_update_required := $(shell \
- test -f po/Makevars || { echo 1; exit; }; \
+ test -f $(srcdir)/po/Makevars || { echo 1; exit; }; \
cd '$(srcdir)'; \
actual=$$(git submodule status | $(_submodule_hash); \
git hash-object bootstrap.conf; \
--
1.7.2
14 years, 8 months
[libvirt] [PATCH 1/2] Fix return value usage
by Doug Goldstein
Fix the error checking to use the return value from brAddTap() instead
of checking the current errno value which might have been changed by
clean up calls inside of brAddTap().
Signed-off-by: Doug Goldstein <cardoe(a)gentoo.org>
---
src/uml/uml_conf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c
index bef8c38..025169f 100644
--- a/src/uml/uml_conf.c
+++ b/src/uml/uml_conf.c
@@ -141,7 +141,7 @@ umlConnectTapDevice(virDomainNetDefPtr net,
tapmac,
0,
&tapfd))) {
- if (errno == ENOTSUP) {
+ if (err == ENOTSUP) {
/* In this particular case, give a better diagnostic. */
umlReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to add tap interface to bridge. "
--
1.7.2
14 years, 9 months
[libvirt] [PATCH] qemu: Hack around asynchronous device_del
by Jiri Denemark
device_del command is not synchronous for PCI devices, it merely asks
the guest to release the device and returns. If the host wants to use
that device before the guest actually releases it, we are in big
trouble. To avoid this, we already added a loop which waits up to 10
seconds until the device is actually released before we do anything else
with that device. But we only added this loop for managed PCI devices
before we try reattach them back to the host.
However, we need to wait even for non-managed devices. We don't reattach
them automatically, but we still want to prevent the host from using it.
This was revealed thanks to sVirt: when we relabel sysfs files
corresponding to the PCI device before the guest finished releasing the
device, qemu is no longer allowed to access those files and if it wants
(as a result of guest's request) to write anything to them, it just
exits, which kills the guest.
This is not a proper fix and needs some further work both on libvirt and
qemu side in the future.
---
I was thinking about another possibility to implement this since the
wait loop doesn't have to be connected to the reattach action. We could
move that loop into a separate function and let qemudReattach function
do just what its name suggest. But in that case, we would need to add
the call to such function before every call to qemudReattach, which
doesn't look any better to me.
Jirka
src/qemu/qemu_driver.c | 17 +++++++++--------
1 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 57b8271..e4f47d4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3209,16 +3209,17 @@ qemuPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
static void
-qemudReattachManagedDevice(pciDevice *dev, struct qemud_driver *driver)
+qemudReattachPciDevice(pciDevice *dev, struct qemud_driver *driver)
{
int retries = 100;
+ while (pciWaitForDeviceCleanup(dev, "kvm_assigned_device")
+ && retries) {
+ usleep(100*1000);
+ retries--;
+ }
+
if (pciDeviceGetManaged(dev)) {
- while (pciWaitForDeviceCleanup(dev, "kvm_assigned_device")
- && retries) {
- usleep(100*1000);
- retries--;
- }
if (pciReAttachDevice(dev, driver->activePciHostdevs) < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to re-attach PCI device: %s"),
@@ -3264,7 +3265,7 @@ qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDevice *dev = pciDeviceListGet(pcidevs, i);
- qemudReattachManagedDevice(dev, driver);
+ qemudReattachPciDevice(dev, driver);
}
pciDeviceListFree(pcidevs);
@@ -8997,7 +8998,7 @@ static int qemudDomainDetachHostPciDevice(struct qemud_driver *driver,
pciDeviceListDel(driver->activePciHostdevs, pci);
if (pciResetDevice(pci, driver->activePciHostdevs, NULL) < 0)
ret = -1;
- qemudReattachManagedDevice(pci, driver);
+ qemudReattachPciDevice(pci, driver);
pciFreeDevice(pci);
}
--
1.7.2
14 years, 9 months
[libvirt] Libvirt storage api and lvm .cache issue
by Thomas Graves
Hello all,
I am using the libvirt storage api with LVM storage on rhel5 with xen and I
noticed that when using the api to create/delete lv's they get added to
/etc/lvm/cache/.cache but old deleted ones never get removed from the
.cache. This causes dmeventd to keep trying to access them but can't which
fills up the logs in /var/log.
Has anyone seen this or have a fix for it? I guess I could force a vgscan
or something to clean it up just seems like I shouldn't need to.
Thanks,
Tom
14 years, 9 months
[libvirt] [PATCH] Add "ubd" to the list of disk prefixes
by Soren Hansen
virDiskNameToIndex has a list of disk name prefixes that it uses in the
process of finding the disk's index. This list is missing "ubd" which
is the disk prefix used for UML domains.
Signed-off-by: Soren Hansen <soren(a)linux2go.dk>
---
src/util/util.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index 8f2a17e..c173e49 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -2367,7 +2367,7 @@ const char *virEnumToString(const char *const*types,
int virDiskNameToIndex(const char *name) {
const char *ptr = NULL;
int idx = 0;
- static char const* const drive_prefix[] = {"fd", "hd", "vd", "sd", "xvd"};
+ static char const* const drive_prefix[] = {"fd", "hd", "vd", "sd", "xvd", "ubd"};
unsigned int i;
for (i = 0; i < ARRAY_CARDINALITY(drive_prefix); i++) {
--
1.7.0.4
14 years, 9 months
[libvirt] [PATCH] build-sys: only build the test programs during the check phase.
by Diego Elio Pettenò
This avoids building the tests when testing libvirt is not the aim.
---
tests/Makefile.am | 26 +++++++++++++-------------
1 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 71c2c74..1dc7f66 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -72,42 +72,42 @@ EXTRA_DIST = \
domainsnapshotxml2xmlin \
qemuhelpdata
-noinst_PROGRAMS = virshtest conftest \
+check_PROGRAMS = virshtest conftest \
nodeinfotest statstest qparamtest
if WITH_XEN
-noinst_PROGRAMS += xml2sexprtest sexpr2xmltest \
+check_PROGRAMS += xml2sexprtest sexpr2xmltest \
reconnect xmconfigtest xencapstest
endif
if WITH_QEMU
-noinst_PROGRAMS += qemuxml2argvtest qemuxml2xmltest qemuargv2xmltest qemuhelptest
+check_PROGRAMS += qemuxml2argvtest qemuxml2xmltest qemuargv2xmltest qemuhelptest
endif
if WITH_ESX
-noinst_PROGRAMS += esxutilstest vmx2xmltest xml2vmxtest
+check_PROGRAMS += esxutilstest vmx2xmltest xml2vmxtest
endif
if WITH_SECDRIVER_SELINUX
-noinst_PROGRAMS += seclabeltest
+check_PROGRAMS += seclabeltest
endif
if WITH_SECDRIVER_APPARMOR
-noinst_PROGRAMS += secaatest
+check_PROGRAMS += secaatest
endif
if WITH_CIL
-noinst_PROGRAMS += object-locking
+check_PROGRAMS += object-locking
endif
-noinst_PROGRAMS += networkxml2xmltest
+check_PROGRAMS += networkxml2xmltest
-noinst_PROGRAMS += nwfilterxml2xmltest
+check_PROGRAMS += nwfilterxml2xmltest
-noinst_PROGRAMS += storagevolxml2xmltest storagepoolxml2xmltest
+check_PROGRAMS += storagevolxml2xmltest storagepoolxml2xmltest
-noinst_PROGRAMS += nodedevxml2xmltest
+check_PROGRAMS += nodedevxml2xmltest
-noinst_PROGRAMS += interfacexml2xmltest
+check_PROGRAMS += interfacexml2xmltest
test_scripts = \
capabilityschematest \
@@ -181,7 +181,7 @@ TESTS += secaatest
endif
if WITH_LIBVIRTD
-noinst_PROGRAMS += eventtest
+check_PROGRAMS += eventtest
TESTS += eventtest
endif
--
1.7.2
14 years, 9 months
[libvirt] [PATCH 1/2] util: add wrapper function to check if address string is an ip
by Justin Clift
---
src/util/network.c | 37 +++++++++++++++++++++++++++++++++++++
src/util/network.h | 2 ++
2 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/src/util/network.c b/src/util/network.c
index 6e24792..2e0cf9c 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -54,6 +54,43 @@ static int getIPv6Addr(virSocketAddrPtr addr, virIPv6AddrPtr tab) {
}
/**
+ * virIsNumericIPAddr:
+ * @address: a text string containing a host name or IPv4/IPv6 address
+ *
+ * Given a text string, determines whether it contains a valid IPv4/IPv6
+ * address.
+ *
+ * Returns 0 if the given string is an IPv4 or IPv6 address, or non-zero
+ * for any other condition.
+ */
+int
+virIsNumericIPAddr(const char *address) {
+ int returnCode;
+ struct addrinfo hints;
+ struct addrinfo *res = NULL;
+
+ /* Sanity check we've been given a text string */
+ if (address == NULL)
+ return(-1);
+
+ /* Do a name lookup on the given string, and see what we're given back */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC; /* Doesn't matter whether IPv4 or IPv6 */
+ hints.ai_socktype = 0; /* Socket type doesn't matter */
+ hints.ai_flags = AI_NUMERICHOST; /* Force a numeric IP address check */
+ hints.ai_protocol = 0; /* Doesn't matter which protocol */
+ returnCode = getaddrinfo (address, NULL, &hints, &res);
+ if (0 == returnCode) {
+ /* A result was returned. This means the text string we were
+ * given is a valid IP address. We now free the result(s) we
+ * were given, and pass back the return code */
+ freeaddrinfo(res);
+ }
+
+ return returnCode;
+}
+
+/**
* virSocketParseAddr:
* @val: a numeric network address IPv4 or IPv6
* @addr: where to store the return value.
diff --git a/src/util/network.h b/src/util/network.h
index 5307c8c..c2e88d8 100644
--- a/src/util/network.h
+++ b/src/util/network.h
@@ -24,6 +24,8 @@ typedef union {
} virSocketAddr;
typedef virSocketAddr *virSocketAddrPtr;
+int virIsNumericIPAddr (const char *address);
+
int virSocketParseAddr (const char *val,
virSocketAddrPtr addr,
int hint);
--
1.7.2.1
14 years, 9 months