Coverity detected that the only way to get to the cleanup label
is if objectSpec had been successfully allocated, so the null
check was dead code.
* src/esx/esx_vi.c (esxVI_LookupObjectContentByType): Drop
redundant null check.
No need to request the parent of a snapshot if we aren't going to use it.
* src/esx/esx_vi.c (esxVI_GetSnapshotTreeByName): Make parent
optional.
* src/esx/esx_driver.c (esxDomainSnapshotCreateXML)
(esxDomainSnapshotLookupByName, esxDomainRevertToSnapshot)
(esxDomainSnapshotDelete): Simplify accordingly.
Commit 9f5e53e introduced the ability to filter snapshots to
just roots, but it was never implemented for ESX until now.
* src/esx/esx_vi.h (esxVI_GetNumberOfSnapshotTrees)
(esxVI_GetSnapshotTreeNames): Add parameter.
* src/esx/esx_vi.c (esxVI_GetNumberOfSnapshotTrees)
(esxVI_GetSnapshotTreeNames): Allow choice of recursion or not.
* src/esx/esx_driver.c (esxDomainSnapshotNum)
(esxDomainSnapshotListNames): Use it to limit to roots.
Commit 498d783 cleans up some of virtual file names for parsing strings
in memory. This patch cleans up (hopefuly) the rest forgotten by the
first patch.
This patch also changes all of the previously modified "filenames" to
valid URI's replacing spaces for underscores.
Changes to v1:
- Replace all spaces for underscores, so that the strings form valid
URI's
- Replace spaces in places changed by commit 498d783
Detected by Coverity. The beginning of the function already filtered
out NULL objectContentList as invalid. Further investigation shows:
esxVI_RetrieveProperties is generated and returns a list of objects
that match the given propertyFilterSpec.
esxVI_LookupObjectContentByType then tests whether the result
corresponds to the expected occurrence and reports an error otherwise.
This simplifies the callers of esxVI_LookupObjectContentByType, but
due to the missing dereference the check was never performed because
the code thought that at least one item was obtained. NULL represents
an empty list. This is a potential segfault fix because callers of
esxVI_LookupObjectContentByType that specified "required" occurrence
assume *objectContentList to be non-NULL when
esxVI_LookupObjectContentByType succeeds.
* src/esx/esx_vi.c (esxVI_LookupObjectContentByType): Check
correct pointer.
When the session has expired then multiple threads can race while
reestablishing it.
This race condition is not that critical as it requires a special usage
pattern to be triggered. It can only happen when an application doesn't
do API calls for quite some time (the session expires after 30 min
inactivity) and then multiple threads doing simultaneous API calls and
end up doing simultaneous calls to esxVI_EnsureSession.
These VIR_XXXX0 APIs make us confused, use the non-0-suffix APIs instead.
How do these coversions works? The magic is using the gcc extension of ##.
When __VA_ARGS__ is empty, "##" will swallow the "," in "fmt," to
avoid compile error.
example: origin after CPP
high_level_api("%d", a_int) low_level_api("%d", a_int)
high_level_api("a string") low_level_api("a string")
About 400 conversions.
8 special conversions:
VIR_XXXX0("") -> VIR_XXXX("msg") (avoid empty format) 2 conversions
VIR_XXXX0(string_literal_with_%) -> VIR_XXXX(%->%%) 0 conversions
VIR_XXXX0(non_string_literal) -> VIR_XXXX("%s", non_string_literal)
(for security) 6 conversions
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
We already have virAsprintf, so picking a similar name helps for
seeing a similar purpose. Furthermore, the prefix V before printf
generally implies 'va_list', even though this variant was '...', and
the old name got in the way of adding a new va_list version.
global rename performed with:
$ git grep -l virBufferVSprintf \
| xargs -L1 sed -i 's/virBufferVSprintf/virBufferAsprintf/g'
then revert the changes in ChangeLog-old.
This warnings come from partly generated code. Therefore, the best
solution is to mark them as potentially being unused using the
ATTRIBUTE_UNUSED macro. This is suggested by the gcc documentation.
Reported by Christophe Fergeau
Now the VMware driver doesn't depend on the ESX driver anymore.
Add a WITH_VMX option that depends on WITH_ESX and WITH_VMWARE.
Also add a libvirt_vmx.syms file.
Move some escaping functions from esx_util.c to vmx.c.
Adapt the test suite, ESX and VMware driver to the new code layout.
Connecting to a ESX(i) server that is part of a cluster failed
when the connection also involved a vCenter.
Accept ClusterComputeResource type in addition to ComputeResource
type in the object lookup function.
Reported by Guillaume Le Louët.
Instead of just reporting that a task failed get the
localized message from the TaskInfo error and include
it in the reported error message.
Implement minimal deserialization support for the
MethodFault type in order to obtain the actual fault
type.
For example, this changes the reported error message
when trying to create a volume with zero size from
Could not create volume
to
Could not create volume: InvalidArgument - A specified parameter was not correct.
Not perfect yet, but better than before.
Before this commit SessionIsActive was not used because ESX(i)
doesn't implement it. vCenter supports SessionIsActive, so use
it here, but keep the fall back mechanism for ESX(i) and GSX.
QueryVirtualDiskUuid is only available on an ESX(i) server. vCenter
returns an NotImplemented fault and a GSX server is missing the
VirtualDiskManager completely. Therefore only use QueryVirtualDiskUuid
with an ESX(i) server and fall back to path as storage volume key for
vCenter and GSX server.
VirtualDisks are .vmdk file based. Other files in a datastore
like .iso or .flp files don't have a UUID attached, fall back
to the path as key for them.
Instead of splitting the path part of a datastore path into
directory and file name, keep this in one piece. An example:
"[datastore] directory/file"
was split into this before:
datastoreName = "datastore"
directoryName = "directory"
fileName = "file"
Now it's split into this:
datastoreName = "datastore"
directoryName = "directory"
directoryAndFileName = "directory/file"
This simplifies code using esxUtil_ParseDatastorePath, because
directoryAndFileName is used more often than fileName. Also the
old approach expected the datastore path to reference an actual
file, but this isn't always correct, especially when listing
volumes. In that case esxUtil_ParseDatastorePath is used to parse
a path that references a directory. This fails for a vpx://
connection because the vCenter returns directory paths with a
trailing '/'. The new approach is robust against this and the
actual decision if the datastore path should reference a file or
a directory is up to the caller of esxUtil_ParseDatastorePath.
Update the tests accordingly.
The check was altered in 8c48743b97
and got too strict, I've no clue how that snuck in. This check
makes every try to open a connection using the ESX driver fail
with an invalid argument error.
Revert the change to the check and add a comment to prevent future
mistakes with this check.
Instead of using one big traversal spec for lookup use a set of
more fine grained traversal specs that are selected based on the
actual needs of the lookup.
This gives up to 20% speedup for certain operations like domain
listing due to less HTTP(S) traffic.
In case an optional object cannot be found the lookup function is
left early and the cleanup code is not executed.
This pattern occurs in some other functions too.
Don't rely on summary.url anymore, because its value is different
between an esx:// and vpx:// connection. Use host.mountInfo.path
instead.
Don't fallback to lookup by UUID (actually lookup by absolute path)
in esxVI_LookupDatastoreByName when lookup by name fails. Add a
seperate function for this: esxVI_LookupDatastoreByAbsolutePath
Now a vpx:// connection has an explicitly specified host. This
allows to enabled several functions for a vpx:// connection
again, like host UUID, hostname, general node info, max vCPU
count, free memory, migration and defining new domains.
Lookup datacenter, compute resource, resource pool and host
system once and cache them. This simplifies the rest of the
code and reduces overall HTTP(S) traffic a bit.
esx:// and vpx:// can be mixed freely for a migration.
Ensure that migration source and destination refer to the
same vCenter. Also directly encode the resource pool and
host system object IDs into the migration URI in the prepare
function. Then directly build managed object references in
the perform function instead of re-looking up already known
information.
esxVI_WaitForTaskCompletion can take a UUID to lookup the
corresponding domain and check if the current task for it
is blocked by a question. It calls another function to do
this: esxVI_LookupAndHandleVirtualMachineQuestion looks up
the VirtualMachine and checks for a question. If there is
a question it calls esxVI_HandleVirtualMachineQuestion to
handle it.
If there was no question or it has been answered the call
to esxVI_LookupAndHandleVirtualMachineQuestion returns 0.
If any error occurred during the lookup and answering
process -1 is returned. The problem with this is, that -1
is also returned when there was no error but the question
could not be answered. So esxVI_WaitForTaskCompletion cannot
distinguish between this two situations and reports that a
question is blocking the task even when there was actually
another problem.
This inherent problem didn't surface until vSphere 4.1 when
you try to define a new domain. The driver tries to lookup
the domain that is just in the process of being registered.
There seems to be some kind of race condition and the driver
manages to issue a lookup command before the ESX server was
able to register the domain. This used to work before.
Due to the return value problem described above the driver
reported a false error message in that case.
To solve this esxVI_WaitForTaskCompletion now takes an
additional occurrence parameter that describes whether or
not to expect the domain to be existent. Also add a new
parameter to esxVI_LookupAndHandleVirtualMachineQuestion
that allows to distinguish if the call returned -1 because
of an actual error or because the question could not be
answered.
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.
Allows listing existing pools and requesting information about them.
Alter the esxVI_ProductVersion enum in a way that allows to check for
product type by masking.
An empty root snapshot list was considered as error condition. Creating a
new snapshot would fail if the domain didn't have snapshots yet, because
the snapshot-create function tries to lookup the list of existing snapshots
in order to verify that the snapshot name is unique. This fails if the
domain doesn't have snapshots yet.
Removing the NULL check from esxVI_LookupRootSnapshotTreeList fixes this.
Generate almost all SOAP method mapping code.
Update the driver code to use the complete paramater list of some methods
that had parameters skipped before.
Improve the ESX_VI__METHOD marco to do automatic output deserialization
based on output occurrence. Also incorporate automatic _this binding and
output pointer check.
Fix invalid code generating in esx_vi_generator.py regarding deep copy
types that contain enum properties.
Add strptime and timegm to bootstrap.conf. Both are used to convert a
xsd:dateTime to calendar time.
Add a testcase of the xsd:dateTime conversion.
Also define ESX_ERROR and ESX_VI_ERROR in a central place, instead of
defining them in each source file.
Add ESX_ERROR and ESX_VI_ERROR to the msg_gen_function list in cfg.mk.
Update po/POTFILES.in accordingly.
The Python script generates the mappings based on the type descriptions
in the esx_vi_generator.input file.
This also improves the inheritance handling and allows to get rid of the
ugly, inflexible, and error prone _base/_super approach. Now every struct
that represents a SOAP type contains a _type member, that allows to
recreate C++-like dynamic dispatch for "method" calls in C.
If esxVI_String_DeepCopyValue or esxVI_SelectionSpec_AppendToList fail
then selectionSpec would leak. Add a free call in the failure path to
fix the leak.
This is actually a consequence of the reworked required parameter
checking: Unify the required parameter check into a Validate function
instead of doing it separately im the (de)serialization part.
The required parameter checking for the mapped methods parameter was
done in the (de)serialize functions before. Now it's explicitly done
in the mapped method itself.
Currently only the faultcode and faultstring are deserialized, the
detail part is ignored. The implementation of many new SOAP types
would be necessary to deserialize the detail part correctly. As an
intermediate solution the raw response is dumped to the debug log.
The data passed to the callback is not guaranteed to be zero terminated,
take care of that by coping the data and adding a zero terminator.
Also dump the data for other types than CURLINFO_TEXT.
Set CURLOPT_VERBOSE to 1 so the debug callback is called when enabled.
Questions can block tasks, to handle them automatically the driver can answers
them with the default answer. The auto_answer query parameter allows to enable
this automatic question handling.
* src/esx/README: add a detailed explanation for automatic question handling
* src/esx/esx_driver.c: add automatic question handling for all task related
driver functions
* src/esx/esx_util.[ch]: add handling for the auto_answer query parameter
* src/esx/esx_vi.[ch], src/esx/esx_vi_methods.[ch], src/esx/esx_vi_types.[ch]:
add new VI API methods and types and additional helper functions for
automatic question handling
* src/esx/esx_vi.c (esxVI_List_CastFromAnyType): For invalid
inputs, fail right away. Do not "goto failure" where a NULL
input pointer would be dereferenced.
Replace free(virBufferContentAndReset()) with virBufferFreeAndReset().
Update documentation and replace all remaining calls to free() with
calls to VIR_FREE(). Also add missing calls to virBufferFreeAndReset()
and virReportOOMError() in OOM error cases.
If an error occurs between the allocation of an item and appending it
to the list, the item leaks. Free such orphaned items in error cases.
* src/esx/esx_vi.c: free orphaned items in error cases
The default transport for the VI API is HTTPS. If the server redirects
from HTTPS to HTTP the driver would silently follow that redirection.
The user assumes to communicate with the server over a secure transport
but isn't.
This patch disables automatical redirection following. The driver reports
an error if the server tries to redirect.
* src/esx/esx_vi.c: refactor the call to curl_easy_perform() into a
function and do error handling there, disable automatical redirection
following for curl
* src/esx/esx_vi.h: change the type of responseCode to int
Unified function naming scheme:
- 'lookup' functions query the ESX or vCenter for information
- 'get' functions return information from a local object
* src/esx/esx_driver.c, src/esx/esx_vi.[ch]: unify function naming
An inaccessible datastore has no valid URL property so don't
access its URI property.
* src/esx/esx_vi.c: esxVI_LookupDatastoreByName(): check if datastore is
accessible before accessing its URL property
* src/esx/esx_vmx.c: update to changed datastore properties
A given domain XML gets converted to a VMX config, uploaded to the host
and registered as new virtual machine.
* src/esx/esx_driver.c: refactor datastore related path parsing into
esxUtil_ParseDatastoreRelatedPath()
* src/esx/esx_util.[ch]: add esxUtil_ParseDatastoreRelatedPath()
* src/esx/esx_vi.[ch]: add esxVI_Context_UploadFile(), add datastores to
the traversal in esxVI_BuildFullTraversalSpecList(), add
esxVI_LookupDatastoreByName()
* src/esx/esx_vi_methods.[ch]: add esxVI_RegisterVM_Task()
* src/esx/esx_vi_types.c: make some error message more verbose
* src/esx/esx_vmx.[ch]: add esxVMX_AbsolutePathToDatastoreRelatedPath()
to convert a path into a datastore related path, add esxVMX_ParseFileName()
to convert from VMX path format to domain XML path format, extend the other
parsing function to be datastore aware, add esxVMX_FormatFileName() to
convert from domain XML path format to VMX path format, fix VMX ethernet
entry formating
* tests/esxutilstest.c: add test for esxUtil_ParseDatastoreRelatedPath()
* tests/vmx2xmldata/*: update domain XML files to use datastore related paths
* tests/xml2vmxdata/*: update domain XML files to use datastore related paths,
update VMX files to use absolute paths
Add esxVI_Occurence enum to describe expected occurence of items
* src/esx/esx_driver.c: update the use of esxVI_LookupVirtualMachineByUuid()
* src/esx/esx_vi.c: add an esxVI_Occurence parameter to
esxVI_LookupVirtualMachineByUuid() and take care if esxVI_FindByUuid()
can't find anything for a given uuid
* src/esx/esx_vi.h: add esxVI_Occurence enum
* src/esx/esx_vi_methods.c: expect null or more items to be returned
from esxVI_FindByUuid()
* src/esx/esx_driver.c: add esxSupportsLongMode() and update esxCapsInit()
* src/esx/esx_vi.[ch]: Add AnyType handling for lists
* src/esx/esx_vi_types.c: bind VI type HostCpuIdInfo
* src/esx/esx_driver.c: add esxNodeGetFreeMemory(), cache IP address
* src/esx/esx_vi.[ch]: refactor resource pool query into esxVI_GetResourcePool()
* src/esx/esx_vi_types.[ch]: bind VI type ResourcePoolResourceUsage
* src/esx/esx_vi.[ch]: convert esxVI_RemoteRequest_Execute() to a
simpler esxVI_Context_Execute() version, remove esxVI_RemoteRequest
and convert esxVI_RemoteResponse to esxVI_Response
* src/esx/esx_vi_methods.c: update and simplify callers to use
esxVI_Context_Execute() instead of esxVI_RemoteRequest_Execute()
* src/esx/esx_vi.[ch]: use virXPathNode*() in
esxVI_RemoteRequest_Execute() and remove
esxVI_RemoteResponse_DeserializeXPathObject*()
* src/esx/esx_vi_methods.c: update callers to use the new syntax of
esxVI_RemoteRequest_Execute()
* src/esx/esx_driver.c: add configStatus to the requested properties
to check it in esxVI_GetVirtualMachineIdentity()
* src/esx/esx_vi.[ch]: add esxVI_GetManagedEntityStatus()
and use it in esxVI_GetVirtualMachineIdentity()
* src/esx/esx_vi_types.[ch]: add VI type esxVI_ManagedEntityStatus
* src/esx/esx_driver.c: handle spaces in VMX file path and use a
virBuffer to encode spaces correctly in the resulting URL
* src/esx/esx_vi.c: include the URL in the error message in case
of a download error
* src/esx/esx_driver.c src/esx/esx_vi.[ch] src/esx/esx_vmx.[ch]:
adds version checking for GSX 2.0, allows to pass a specific port
for the connection and also add a new specific gsx scheme for
easier connections to GSX hosts
* src/esx/esx_driver.c src/esx/esx_vi.c src/esx/esx_vi.h
src/esx/esx_vmx.c src/esx/esx_vmx.h: extend the VI API version checks
to accept version 4.0 and takes care of the virtualHW.version change
from 4 to 7.
* src/esx/esx_driver.c src/esx/esx_util.c src/esx/esx_util.h
src/esx/esx_vi.c src/esx/esx_vi.h: adds a no_verify query parameter to
stop libcurl from verifying theserver certificate for the https
transport.
* src/esx/esx_*.[ch]: the driver, uses a remote minimal SOAP client
to talk to the VI services on ESX nodes.
* configure.in include/libvirt/virterror.h src/Makefile.am src/driver.h
src/libvirt.c src/virterror.c: glue in the new driver