
2009/7/23 Daniel Veillard <veillard@redhat.com>:
On Tue, Jul 21, 2009 at 04:58:50PM +0200, Matthias Bolte wrote:
Now reviewing the main code,
[...]
+typedef struct _esxPrivate { + esxVI_Context *host; + esxVI_Context *vcenter; + int phantom; // boolean
Do we really need phantom ? this is basically a debug mode with no real ESX server, right ?
The phantom mode allows for using domain-xml-to/from-native without an actual ESX server. But besides that, it has no real use.
+ char *transport; + int32_t nvcpus_max; + esxVI_Boolean supports_vmotion; + int32_t usedCpuTimeCounterId; +} esxPrivate; + [...] + /* Check for 'esx:///phantom' URI */ + if (conn->uri->server == NULL && conn->uri->path != NULL && + STREQ(conn->uri->path, "/phantom")) { + phantom = 1; + }
Comparing against the exact string would have been simpler/more accurate if still available (to avoid esx:///phantom#foo or esx:///phantom?bar)
The driver open function has the URI available is parsed xmlURIPtr form only.
[...]
+ + password = esxUtil_RequestPassword(auth, username, conn->uri->server); [...] + + if (vcenter != NULL) { + if (virAsprintf(&url, "%s://%s/sdk", priv->transport, + vcenter) < 0) { + virReportOOMError(conn); + goto failure; + } + + if (esxVI_Context_Alloc(conn, &priv->vcenter) < 0) { + goto failure; + } + + username = esxUtil_RequestUsername(auth, "administrator", vcenter); + + if (username == NULL) { + ESX_ERROR(conn, VIR_ERR_AUTH_FAILED, + "Username request failed"); + goto failure; + } + + password = esxUtil_RequestPassword(auth, username, vcenter);
I'm not sure I understand why there are 2 requests for authentication needed but there must be a reason :-)
The driver needs to talk to different hosts for different functionality. Most stuff can be done with the ESX host itself, but a vCenter is needed for migration. If the connection URI contains a vCenter parameter the open function requests authentication for the ESX host and the vCenter independently, because authentication information can be different for each of them.
[...]
+static esxVI_Boolean +esxSupportsVMotion(virConnectPtr conn) +{ + esxPrivate *priv = (esxPrivate *)conn->privateData; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *hostSystem = NULL; + esxVI_DynamicProperty *dynamicProperty = NULL; + + if (priv->phantom) { + ESX_ERROR(conn, VIR_ERR_OPERATION_INVALID, + "Not possible with a phantom connection"); + goto failure; + }
I still didn't found the use for phantom :-)
See esxDomainXMLFromNative().
+static virDomainPtr +esxDomainLookupByID(virConnectPtr conn, int id) +{ [...] + char *name_ = NULL;
why the underscore. I was a bit puzzled by the way name_ is freed in the loop but in retrospection that works :)
The underscore is superfluous, will be cleaned up. The loop iterates over all domains and searches for the matching one. esxVI_GetVirtualMachineIdentity() allocates the name, so the name must be freed before calling esxVI_GetVirtualMachineIdentity() again to free the allocated name from the previous iteration. Otherwise memory could leak.
One thing we need to fix is all the erro strings need to be localized
+ if (powerState != esxVI_VirtualMachinePowerState_PoweredOn) { + ESX_ERROR(domain->conn, VIR_ERR_OPERATION_INVALID, + "Domain is not powered on");
should become _("Domain is not powered on") But that's really simple to change
Already on the todo list.
+static char * +esxDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) +{ + return strdup("hvm");
we need to check for failure and use the out of memory handler here. like in esxDomainGetSchedulerType()
Added to the todo list.
+static int +esxDomainGetSchedulerParameters(virDomainPtr domain, + virSchedParameterPtr params, int *nparams) +{
Hum, the scheduler API is so free form that some details of the scheduling parameter handled and their semantic need to be documented, here, and in the future HTML driver page.
Already on the todo list.
+char * +esxUtil_RequestUsername(virConnectAuthPtr auth, const char *default_username, + const char *server) +{ [...] +char * +esxUtil_RequestPassword(virConnectAuthPtr auth, const char *username, + const char *server) +{
auth hooks looks clean to me
might be worth documenting what some of those low level utilities do, as it's not clear just from reading them, especially with things like handling different server version (assuming I understood):
Added to the todo list.
+ if ((*remoteResponse)->response_code == 500) { + (*remoteResponse)->xpathObject = + xmlXPathEval(BAD_CAST + "/soapenv:Envelope/soapenv:Body/soapenv:Fault", + (*remoteResponse)->xpathContext); + + if (esxVI_RemoteResponse_DeserializeXPathObject + (conn, *remoteResponse, + (esxVI_RemoteResponse_DeserializeFunc) + esxVI_Fault_Deserialize, + (void **)&fault) < 0) { + goto failure; + }
the XPath code and handling could probably be made a bit easier and more resistant by using libvirt own wrapper, for example virXPathNode(NULL, "/soapenv:Envelope/soapenv:Body/soapenv:Fault" (*remoteResponse)->xpathContext); or virXPathNodeSet if multiple soapenv:Fault are allowed.
I'll have a look at the virXPath* functions. Added to the todo list.
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
The header is incomparably simpler than what would be generated by csoap !!!
Well, our client implements a small subset of the VI API, only the methods and types that are really needed for the driver. csoap generates code for the whole thing.
+int +esxVI_SessionIsActive(virConnectPtr conn, esxVI_Context *ctx, + const char *sessionID, const char *userName, + esxVI_Boolean *active) +{ [...] + cleanup: + /* + * Remove static values from the data structures to prevent them from + * being freed by the call to esxVI_RemoteRequest_Free(). + */ + if (remoteRequest != NULL) { + remoteRequest->xpathExpression = NULL; + }
Hum, and that doesn't generate a leak ? I see that others routines do the same, or is remoteRequest->xpathExpression still stored somewhere else ?
As the comment states, the remoteRequest->xpathExpression is a static string (not allocated) and esxVI_RemoteRequest_Free() would free it. So setting it to NULL before freeing prevents esxVI_RemoteRequest_Free() from freeing non-allocated memory and doesn't generate a leak. Maybe I'll reverse the logic and esxVI_RemoteRequest_Free() doesn't free xpathExpression anymore, because in most cases xpathExpression is non-allocated. Maybe I'll also precompile the static XPath expressions as you or DPB suggested earlier. Anyway, it's already on the todo list to have a look at the XPath handling again.
Hum more localized strings needed here ... even in convenience macros
+ if (string == NULL) { \ + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, \ + "XML node doesn't contain text, expecting an " \ + _xsdType" value"); \
The problem is that the string is generated as part of the macro, I wonder how this will play with _() ...
The string could be moved out of the macro. Before the macro: static const char *someErrorMessage = gettext_noop("XML node doesn't contain text, expecting an %s value"); And inside the macro: ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, gettext(someErrorMessage), _xsdType); Or even this inside the macro may work: ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, _("XML node doesn't contain text, expecting an %s value"), _xsdType);
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c [...] +## nets: bridged ############################################################### + +... +->type = _NET_TYPE_BRIDGE <=> ethernet0.connectionType = "bridged" # defaults to "bridged" + + +## nets: hostonly ############################################################## + +... # FIXME: maybe not supported by ESX? +->type = _NET_TYPE_NETWORK <=> ethernet0.connectionType = "hostonly" # defaults to "bridged" + + +## nets: nat ################################################################### + +... # FIXME: maybe not supported by ESX? +->type = _NET_TYPE_USER <=> ethernet0.connectionType = "nat" # defaults to "bridged" +
I not so sure about what the question is there ...
Do you refer to "# FIXME: maybe not supported by ESX?"? This is just a remark for me. http://www.sanbarrow.com/vmx.html states that there are 4 modes for networks. But it's not clear if all of them are supported by the ESX host, because http://www.sanbarrow.com/vmx.html contains information about the general VMX format that VMware uses for its other virtualisation software too. I just haven't tested yet if hostonly and nat mode are supported by ESX.
+## nets: custom ################################################################ + +... +->type = _NET_TYPE_BRIDGE <=> ethernet0.connectionType = "custom" # defaults to "bridged" +->data.bridge.brname = <value> <=> ethernet0.vnet = "<value>"
One thing which should be added is test cases for the VMX <-> XML formats conversions, should be relatively easy to add in the infrastructure once we have the examples.
Already on the todo list. Regards, Matthias