[libvirt] VMware ESX driver progress
Matthias Bolte
matthias.bolte at googlemail.com
Sat Jul 25 14:34:58 UTC 2009
2009/7/23 Daniel Veillard <veillard at 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
More information about the libvir-list
mailing list