libvirt/src/esx
Eric Blake 27c8fd7490 domain: Fix unknown flags diagnosis in virDomainGetXMLDesc
Many drivers had a comment that they did not validate the incoming
'flags' to virDomainGetXMLDesc() because they were relying on
virDomainDefFormat() to do it instead. This used to be the case
(at least since 461e0f1a and friends in 0.9.4 added unknown flag
checking in general), but regressed in commit 0ecd6851 (1.2.12),
when all of the drivers were changed to pass 'flags' through the
new helper virDomainDefFormatConvertXMLFlags(). Since this helper
silently ignores unknown flags, we need to implement flag checking
in each driver instead.

Annoyingly, this means that any new flag values added will silently
be ignored when targeting an older libvirt, rather than our usual
practice of loudly diagnosing an unsupported flag.  Add comments
in domain_conf.[ch] to remind us to be extra vigilant about the
impact when adding flags (a new flag to add data is safe if the
older server omitting the requested data doesn't break things in
the newer client; a new flag to suppress data rather than enhancing
the existing VIR_DOMAIN_XML_SECURE may form a data leak or even a
security hole).

In the qemu driver, there are multiple callers all funnelling to
qemuDomainDefFormatBufInternal(); many of them already validated
flags (and often only a subset of the full set of possible flags),
but for ease of maintenance, we can also check flags at the common
helper function.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2019-02-19 16:52:51 -06:00
..
esx_driver.c domain: Fix unknown flags diagnosis in virDomainGetXMLDesc 2019-02-19 16:52:51 -06:00
esx_driver.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_interface_driver.c global: consistently use IP rather than Ip in identifiers 2016-06-26 19:33:07 -04:00
esx_interface_driver.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_network_driver.c network: Use 'switch' control statement with virNetworkForwardType enum 2018-07-25 14:33:52 +02:00
esx_network_driver.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_private.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_storage_backend_iscsi.c src: More cleanup of some system headers already contained in internal.h 2018-09-20 10:16:39 +02:00
esx_storage_backend_iscsi.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_storage_backend_vmfs.c conf: Introduce VIR_DEFINE_AUTOPTR_FUNC for virStorageVolDef 2019-02-12 08:51:23 -05:00
esx_storage_backend_vmfs.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_storage_driver.c Removing probing of secondary drivers 2015-01-27 12:02:04 +00:00
esx_storage_driver.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_stream.c Implement virStreamRecvFlags to some drivers 2017-05-18 07:42:13 +02:00
esx_stream.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_util.c esx: Use ESX_VI_CHECK_ARG_LIST macro to avoid code duplication 2018-07-04 08:17:59 +02:00
esx_util.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_vi_generator.input Add iSCSI backend storage driver for ESX 2012-12-03 21:12:23 +01:00
esx_vi_generator.py python: Remove space around = in keyword args 2018-03-20 12:13:35 +00:00
esx_vi_methods.c esx: Use ESX_VI_CHECK_ARG_LIST macro to avoid code duplication 2018-07-04 08:17:59 +02:00
esx_vi_methods.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_vi_types.c src: More cleanup of some system headers already contained in internal.h 2018-09-20 10:16:39 +02:00
esx_vi_types.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
esx_vi.c esx: Fix build when libcurl debug is enabled 2018-08-13 21:44:33 +02:00
esx_vi.h Enforce a standard header file guard symbol name 2018-12-14 10:47:13 +00:00
Makefile.inc.am make: split ESX driver build rules into esx/Makefile.inc.am 2018-02-23 13:14:25 +00:00
README esx: Handle name escaping properly 2010-10-14 22:43:16 +02:00

Some links to relevant documentation
====================================


VI/vSphere API:
  http://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/
  http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/
  http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/

VMX config:
  http://www.sanbarrow.com/vmx.html

CPUID:
  http://www.sandpile.org/ia32/cpuid.htm

Memory model:
  http://www.vmware.com/pdf/esx3_memory.pdf
  http://www.vmware.com/pdf/usenix_resource_mgmt.pdf

Virtual serial port (network backed):
  http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.device.VirtualSerialPort.URIBackingInfo.html
  http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/vsp41_usingproxy_virtual_serial_ports.pdf



Automatic question handling
===========================


What is a question in the ESX context?
--------------------------------------

The VI API contains methods that start tasks, for example PowerOnVM_Task(). Such
tasks may be blocked by questions if the ESX host detects an issue with the
virtual machine that requires user interaction.

An example: If a virtual machine has a serial port that is realized via a file,
the ESX host will ask a question on power-on of this virtual machine whether
new content should be appended to this file or the file should be replaced.
Until this question is answered the power-on task is blocked and the virtual
machine won't get powered on.

The ESX driver cannot prompt the user to answer a question, libvirt doesn't
have an API for something like this. The VI API provides the AnswerVM() method
to programmatically answer such questions. A question comes together with a list
of possible answers. One of this answers is marked as the default one. For all
questions I've seen so far the default answer is always a non-destructive one.

There are two options how to handle a question that is blocking a task: either
answer it automatically or report it as error and try to cancel the blocked
task.

The auto_answer query parameter defines how the driver should handle questions.
Possible values are 0 for the report-error-and-try-to-cancel option and 1 for
the automatic-answer option.


How is automatic question handling implemented?
-----------------------------------------------

Before any new task is started the driver checks if there is a pending task
blocked by a question. If automatic question handling is disabled the driver
reports an error that includes the question and returns from the driver
function. If automatic question handling is enabled the driver answers the
question with the default answer and returns from the driver function.

In both cases the actual desired task is not started. If the question was not
answered the blocked task is still blocked and because task can't be executed
in parallel in general it's of no use to start yet another task. If the
question was answered the blocked task may already perform the desired action
and one must wait for its completion, so it's of no use to start yet another
task.

If there is no question blocking a task or another pending task that had not
finished yet the driver starts the desired task and waits for its completion.
While polling for status updates of the task it also checks for question that
may have been triggered by the current task and handles them according to the
value of the auto_answer query parameter. If automatic question handling is
enabled the driver answers the question with the default answer and continues
polling for status updates. If automatic question handling is disabled the
driver reports an error that includes the question, tries to cancel the blocked
task and returns from the driver function.

It tries to cancel the blocked task, but this may not be possible, because
there are task like the power-on task that is marked as non-cancelable. So the
driver may leave blocked tasks behind if automatic question handling is
disabled.



Different escaping schemes used in different places
===================================================

A domain name in the vSphere API has [%/\] escaped as %XX (percent-encoding),
where XX is the ASCII code of the escaped char in hex.

A domainName entry in a VMX config file is percent-encoded and has [|"] escaped
as |XX (pipe-encoding).

A annotation entry in a VMX config file is pipe-encoded.

A datastore item name has the special Windows path characters ["*<>:|?]
replaced by underscores (_). The result is escaped using percent-encoding and
base64-encoding. This isn't a bijective encoding. Therefore, escaped datastore
item names cannot be unescaped completely.

For base64-encoding sequences of chars that don't match [a-zA-Z0-9'(),. _-]
are replaced by their base64 form (the padding is omitted). An encoded sequence
begins with a plus (+), ends with a minus (-) and can contain a plus (+). The
minus (-) is omitted if the string ends in a base64-encoded sequence. VMware
uses the comma (,) instead of the slash (/) in the base64 alphabet to avoid
conflicts with the slash as path separator.