Most APIs use 'unsigned int flags'; but a few stragglers were using
a signed value. In particular, the vir*GetXMLDesc APIs were
split-brain, with inconsistent choice of types. Although it is
an API break to use 'int' instead of 'unsigned int', it is ABI
compatible (pre-compiled apps will have no difference in behavior),
and generally apps can be recompiled without any issue (only rare
apps that compiled with extremely high warning levels, or which
pass libvirt API around as typed function pointers, would have to
make any code changes to deal with the change).
The migrate APIs use 'unsigned long flags', which can't be changed,
due to ABI constraints.
This patch intentionally touches only the public API, to prove the
claim that most existing code (including driver callbacks and virsh)
still compiles just fine in spite of the type change.
* include/libvirt/libvirt.h.in (virConnectOpenAuth)
(virDomainCoreDump, virDomainGetXMLDesc, virNetworkGetXMLDesc)
(virNWFilterGetXMLDesc): Use unsigned int for flags.
(virDomainHasCurrentSnapshot): Use consistent spelling.
* src/libvirt.c (virConnectOpenAuth, virDomainCoreDump)
(virDomainGetXMLDesc, virNetworkGetXMLDesc)
(virNWFilterGetXMLDesc, do_open): Update accordingly.
We already have a public virDomainPinVcpu, which implies that
Pin and Vcpu are treated as separate words. Unreleased commit
e261987c introduced virDomainGetVcpupinInfo as the first public
API that used Vcpupin, although we had prior internal uses of
that spelling. For consistency, change the spelling to be two
words everywhere, regardless of whether pin comes first or last.
* daemon/remote.c: Treat vcpu and pin as separate words.
* include/libvirt/libvirt.h.in: Likewise.
* src/conf/domain_conf.c: Likewise.
* src/conf/domain_conf.h: Likewise.
* src/driver.h: Likewise.
* src/libvirt.c: Likewise.
* src/libvirt_private.syms: Likewise.
* src/libvirt_public.syms: Likewise.
* src/libxl/libxl_driver.c: Likewise.
* src/qemu/qemu_driver.c: Likewise.
* src/remote/remote_driver.c: Likewise.
* src/xen/xend_internal.c: Likewise.
* tools/virsh.c: Likewise.
* src/remote/remote_protocol.x: Likewise.
* src/remote_protocol-structs: Likewise.
Suggested by Matthias Bolte.
This patch introduces a new libvirt API (virDomainGetVcpupinInfo),
as a counterpart to virDomainPinVcpuFlags.
We can use virDomainGetVcpus API to retrieve CPU affinity information,
but can't use this API against inactive domains (at least in case of KVM),
as it lacks a flags parameter.
The usual thing is to add a new virDomainGetVcpusFlags, but that API name
is already occupied by the counterpart to virDomainGetMaxVcpus, which
has a completely different signature.
The virDomainGetVcpupinInfo is the new API to retrieve CPU affinity
information of active and inactive domains. While the usual convention
is to list an array before its length, this API violates that rule
in order to be more like virDomainGetVcpus (where maxinfo was doing
double-duty as the length of two different arrays).
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Integer overflow and remote code are never a nice mix.
This has existed since commit 56cd414.
* src/libvirt.c (virDomainGetVcpus): Reject overflow up front.
* src/remote/remote_driver.c (remoteDomainGetVcpus): Avoid overflow
on sending rpc.
* daemon/remote.c (remoteDispatchDomainGetVcpus): Avoid overflow on
receiving rpc.
When adding virDomainGetVcpusFlags in commit ea3f5c6, I did
enough rebasing that the doc comments in libvirt.c no longer
matched the final chosen enum names in libvirt.h.
And now we've gone ahead and deprecated the names
VIR_DOMAIN_VCPU_{LIVE,CONFIG}.
* src/libvirt.c (virDomainGetVcpusFlags): Fix comment.
If an application is using libvirt + KVM as a piece of its
internal infrastructure to perform a specific task, it can
be desirable to guarentee the VM dies when the virConnectPtr
disconnects from libvirtd. This ensures the app can't leak
any VMs it was using. Adding VIR_DOMAIN_START_AUTOKILL as
a flag when starting guests enables this to be done.
* include/libvirt/libvirt.h.in: All VIR_DOMAIN_START_AUTOKILL
* src/qemu/qemu_driver.c: Support automatic killing of guests
upon connection close
* tools/virsh.c: Add --autokill flag to 'start' and 'create'
commands
Even though rpc uses 'unsigned int' for the _len parameter that
passes the length of item<length>, the public libvirt APIs all
use 'int' and filter out lengths < 0, except for virDomainSendKey.
* include/libvirt/libvirt.h.in (virDomainSendKey): All other APIs
use int for array length.
* src/libvirt.c (virDomainSendKey): Adjust.
* src/driver.h (virDrvDomainSendKey): Likewise.
* daemon/remote_generator.pl: Likewise.
Qemu once supported following memory stats which will returned by
"query_balloon":
stat_put(dict, "actual", actual);
stat_put(dict, "mem_swapped_in", dev->stats[VIRTIO_BALLOON_S_SWAP_IN]);
stat_put(dict, "mem_swapped_out", dev->stats[VIRTIO_BALLOON_S_SWAP_OUT]);
stat_put(dict, "major_page_faults", dev->stats[VIRTIO_BALLOON_S_MAJFLT]);
stat_put(dict, "minor_page_faults", dev->stats[VIRTIO_BALLOON_S_MINFLT]);
stat_put(dict, "free_mem", dev->stats[VIRTIO_BALLOON_S_MEMFREE]);
stat_put(dict, "total_mem", dev->stats[VIRTIO_BALLOON_S_MEMTOT]);
But it later disabled all the stats except "actual" by commit
07b0403dfc2b2ac179ae5b48105096cc2d03375a.
libvirt doesn't parse "actual", so user will always see a empty result
with "virsh dommemstat $domain". Even qemu haven't disabled the stats,
we should support parsing "actual".
This patch deprecates following enums:
VIR_DOMAIN_MEM_CURRENT
VIR_DOMAIN_MEM_LIVE
VIR_DOMAIN_MEM_CONFIG
VIR_DOMAIN_VCPU_LIVE
VIR_DOMAIN_VCPU_CONFIG
VIR_DOMAIN_DEVICE_MODIFY_CURRENT
VIR_DOMAIN_DEVICE_MODIFY_LIVE
VIR_DOMAIN_DEVICE_MODIFY_CONFIG
And modify internal codes to use virDomainModificationImpact.
Detected by Coverity. Commit a98d8f0d tried to make uuid debugging
more robust, but missed some APIs. And on the APIs that it visited,
the mere act of preparing the debug message ends up dereferencing
uuid prior to the null check. Which means the APIs which are supposed
to gracefully reject NULL arguments now end up with SIGSEGV.
* src/libvirt.c (VIR_UUID_DEBUG): New macro.
(virDomainLookupByUUID, virDomainLookupByUUIDString)
(virNetworkLookupByUUID, virNetworkLookupByUUIDString)
(virStoragePoolLookupByUUID, virStoragePoolLookupByUUIDString)
(virSecretLookupByUUID, virSecretLookupByUUIDString)
(virNWFilterLookupByUUID, virNWFilterLookupByUUIDString): Avoid
null dereference.
virGetVersion itself doesn't take a virConnectPtr, but in order to obtain
the hypervisor version against which libvirt was compiled it is used in
combination with virConnectGetType like this:
hvType = virConnectGetType(conn)
virGetVersion(&libVer, hvType, &typeVer)
When virConnectGetType is called on a remote connection then the remote
driver returns the type of the underlying driver on the server side, for
example QEMU. Then virGetVersion compares hvType to a set of strings that
depend on configure options and returns LIBVIR_VERSION_NUMBER in most
cases. Now this fails in case libvirt on the client side is just compiled
with the remote driver enabled only and the server side has the actual
driver such as the QEMU driver. It just happens to work when the actual
driver is enabled on client and server side. But that's not always true.
I noticed this on FreeBSD:
freebsd# virsh -c qemu+tcp://192.168.178.22/system version
Compiled against library: libvir 0.9.2
error: failed to get the library version
error: this function is not supported by the connection driver: virGetVersion
This is not FreeBSD specific, happens on Windows as well due to the
similar driver support configuration. The problem is that virConnectGetType
returns QEMU, but virGetVersion on the client side only accepts Remote
as hvType due to all other drivers being disabled on the client side.
Daniel P. Berrange suggested to get rid of all the conditional code in
virGetVersion, ignoring the hvType and always setting typeVer to
LIBVIR_VERSION_NUMBER. virConnectGetVersion is supposed to be used to
obtain the hypervisor version.
This commit is safe precisely because there has been no release
for any of the enum values being deleted (they were added post-0.9.1).
After the 0.9.2 release, we can then take advantage of
virDomainModificationImpact in more places.
* include/libvirt/libvirt.h.in (virDomainModificationImpact): New
enum.
(virDomainSchedParameterFlags, virMemoryParamFlags): Delete, since
these were never released, and the new enum works fine here.
* src/libvirt.c (virDomainGetMemoryParameters)
(virDomainSetMemoryParameters)
(virDomainGetSchedulerParametersFlags)
(virDomainSetSchedulerParametersFlags): Update documentation.
* src/qemu/qemu_driver.c (qemuDomainSetMemoryParameters)
(qemuDomainGetMemoryParameters, qemuSetSchedulerParametersFlags)
(qemuSetSchedulerParameters, qemuGetSchedulerParametersFlags)
(qemuGetSchedulerParameters): Adjust clients.
* tools/virsh.c (cmdSchedinfo, cmdMemtune): Likewise.
Based on ideas by Daniel Veillard and Hu Tao.
If we can choose live or config when setting, then we need to
be able to choose which one we are querying.
Also, make the documentation clear that set must use a non-empty
subset (some of the hypervisors fail if params is NULL).
* include/libvirt/libvirt.h.in
(virDomainGetSchedulerParametersFlags): New prototype.
* src/libvirt.c (virDomainGetSchedulerParametersFlags): Implement
it.
* src/libvirt_public.syms: Export it.
* python/generator.py (skip_impl): Don't auto-generate.
* src/driver.h (virDrvDomainGetSchedulerParametersFlags): New
callback.
The current virDomainMigrateFinish3 method signature attempts to
distinguish two types of errors, by allowing return with ret== 0,
but ddomain == NULL, to indicate a failure to start the guest.
This is flawed, because when ret == 0, there is no way for the
virErrorPtr details to be sent back to the client.
Change the signature of virDomainMigrateFinish3 so it simply
returns a virDomainPtr, in the same way as virDomainMigrateFinish2
The disk locking code will protect against the only possible
failure mode this doesn't account for (loosing conenctivity to
libvirtd after Finish3 starts the CPUs, but before the client
sees the reply for Finish3).
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Change
virDomainMigrateFinish3 to return a virDomainPtr instead of int
* src/remote/remote_driver.c, src/remote/remote_protocol.x,
daemon/remote.c, src/qemu/qemu_driver.c, src/qemu/qemu_migration.c:
Update for API change
When doing migration, if an error occurs in Perform, it must not
be overwritten during Finish/Confirm steps. If an error occurs
in Finish, it must not be overwritten in Confirm.
Previous commit a9d12c2444 added
code to qemudDomainMigrateFinish2 to preserve the error. This
is not the right place, because it is not applicable in non-p2p
migration. The src/libvirt.c virDomainMigrateV2/3 methods need
code to preserve errors for non-p2p migration, while the
doPeer2PeerMigrate2 and doPeer2PeerMigrate3 methods contain
code to preverse errors for p2p migration.
Remove the bogus error preservation from qemudDomainMigrateFinish2
and qemudDomainMigrateFinish3.
Fix virDomainMigrateV3 and doPeer2PeerMigrate3 so that they
preserve any error hit during the Finish3 step, before invoking
Confirm3.
Finally if qemuMigrationFinish fails to resume the CPUs, it must
preserve the error before tearing down the VM, so that VM cleanup
doesn't overwrite it.
* src/libvirt.c: Preserve error before invoking Confirm3
* src/qemu/qemu_driver.c: Remove bogus error preservation
code in qemudDomainMigrateFinish2/qemudDomainMigrateFinish3
* src/qemu/qemu_migration.c: Preserve error before invoking Confirm3
and after resume fails in qemuMigrationFinish.
* src/libvirt.c: Add further debug lines in helper APIs for
migration
* src/qemu/qemu_migration.c: Add debug lines for all internal
migration API parameters
There are two pieces of information which are desirable for
migration, which cannot be supplied by applications
- The explicit QEMU migration URI, while using Peer2Peer
migration
- An override for the target VM XML
This introduces two new public APIs to support these extra
parameters. There is no need for extra wire protocool changes,
since this is supported by the v3 migration enhancements
* include/libvirt/libvirt.h.in,
src/libvirt.c, src/libvirt_public.syms: Add virDomainMigrate2
and virDomainMigrateToURI2
The virDomainMigratePerform3 currently has a single URI parameter
whose meaning varies. It is either
- A QEMU migration URI (normal migration)
- A libvirtd connection URI (peer2peer migration)
Unfortunately when using peer2peer migration, without also
using tunnelled migration, it is possible that both URIs are
required.
This adds a second URI parameter to the virDomainMigratePerform3
method, to cope with this scenario. Each parameter how has a fixed
meaning.
NB, there is no way to actually take advantage of this yet,
since virDomainMigrate/virDomainMigrateToURI do not have any
way to provide the 2 separate URIs
* daemon/remote.c, src/remote/remote_driver.c,
src/remote/remote_protocol.x, src/remote_protocol-structs: Add
the second URI parameter to perform3 message
* src/driver.h, src/libvirt.c, src/libvirt_internal.h: Add
the second URI parameter to Perform3 method
* src/libvirt_internal.h, src/qemu/qemu_migration.c,
src/qemu/qemu_migration.h: Update to handle URIs correctly
This extends the v3 migration protocol such that the
virDomainMigrateBegin3 and virDomainMigratePerform3
methods accept an application supplied XML config for
the target VM.
If the 'xmlin' parameter is NULL, then Begin3 uses the
current guest XML as normal. A driver implementing the
Begin3 method should either reject all non-NULL 'xmlin'
parameters, or strictly validate that the app supplied
XML does not change guest ABI.
The Perform3 method also needed the xmlin parameter to
cope with the Peer2Peer migration sequence.
NB it is not yet possible to use this capability since
neither of the public virDomainMigrate/virDomainMigrateToURI
methods have a way to pass in XML.
* daemon/remote.c, src/remote/remote_driver.c,
src/remote/remote_protocol.x, src/remote_protocol-structs:
Add 'remote_string xmlin' parameter to begin3/perform3
RPC messages
* src/libvirt.c, src/driver.h, src/libvirt_internal.h: Add
'const char *xmlin' parameter to Begin3/Perform3 methods
* src/qemu/qemu_driver.c, src/qemu/qemu_migration.c,
src/qemu/qemu_migration.h: Pass xmlin parameter around
migration methods
The internal virDomainMigratePeer2Peer and virDomainMigrateDirect
helper methods were not checking whether the target supports the
v3 migration protocol.
* src/libvirt.c: Use v3 migration protocol for p2p/direct
migration if available.
Improve invalid argument checks in the size query case. The drivers already
relied on this unchecked behavior.
Relax the implementation of virDomainGet(Memory|Blkio)MemoryParameters
in the drivers and allow to pass more memory than necessary for all
parameters.
Add invalid argument checks for params and nparams to the public API
and remove them from the drivers (e.g. xend).
Add subset handling to libxl and test drivers.
params and nparams are essential and cannot be NULL. Check this in
libvirt.c and remove redundant checks from the drivers (e.g. xend).
Instead of enforcing that nparams must point to exact same value as
returned by virDomainGetSchedulerType relax this to a lower bound
check. This is what some drivers (e.g. xen hypervisor and esx)
already did. Other drivers (e.g. xend) didn't check nparams at all
and assumed that there is enough space in params.
Unify the behavior in all drivers to a lower bound check and update
nparams to the number of valid values in params on success.
Some drivers assumed it can be NULL (e.g. qemu and lxc) and check it
before assigning to it, other drivers assumed it must be non-NULL
(e.g. test and esx) and just assigned to it.
Unify this to nparams being optional and document it.
virStreamNew needs to dispatch the error that virGetStream reports
on failure.
remoteCreateClientStream can fail due to virStreamNew or due to
VIR_ALLOC. Report OOM error for VIR_ALLOC failure to report errors
in all error cases.
Remove OOM error reporting from remoteCreateClientStream callers.
virsh didn't call virInitialize(), which (among other things)
initializes virLastErr thread local variable. As a result of that, virsh
could just segfault in virEventRegisterDefaultImpl() since that is the
first call that touches (resets) virLastErr.
I have no idea what lucky coincidence made this bug visible but I was
able to reproduce it in 100% cases but only in one specific environment
which included building in sandbox.
The v2 migration protocol was accidentally missing out the
finish step, when prepare succeeded, but returned an invalid
URI
* src/libvirt.c: Teardown VM if prepare returns invalid URI
Migration just seems to go from bad to worse. We already had to
introduce a second migration protocol when adding the QEMU driver,
since the one from Xen was insufficiently flexible to cope with
passing the data the QEMU driver required.
It turns out that this protocol still has some flaws that we
need to address. The current sequence is
* Src: DumpXML
- Generate XML to pass to dst
* Dst: Prepare
- Get ready to accept incoming VM
- Generate optional cookie to pass to src
* Src: Perform
- Start migration and wait for send completion
- Kill off VM if successful, resume if failed
* Dst: Finish
- Wait for recv completion and check status
- Kill off VM if unsuccessful
The problems with this are:
- Since the first step is a generic 'DumpXML' call, we can't
add in other migration specific data. eg, we can't include
any VM lease data from lock manager plugins
- Since the first step is a generic 'DumpXML' call, we can't
emit any 'migration begin' event on the source, or have
any hook that runs right at the start of the process
- Since there is no final step on the source, if the Finish
method fails to receive all migration data & has to kill
the VM, then there's no way to resume the original VM
on the source
This patch attempts to introduce a version 3 that uses the
improved 5 step sequence
* Src: Begin
- Generate XML to pass to dst
- Generate optional cookie to pass to dst
* Dst: Prepare
- Get ready to accept incoming VM
- Generate optional cookie to pass to src
* Src: Perform
- Start migration and wait for send completion
- Generate optional cookie to pass to dst
* Dst: Finish
- Wait for recv completion and check status
- Kill off VM if failed, resume if success
- Generate optional cookie to pass to src
* Src: Confirm
- Kill off VM if success, resume if failed
The API is designed to allow both input and output cookies
in all methods where applicable. This lets us pass around
arbitrary extra driver specific data between src & dst during
migration. Combined with the extra 'Begin' method this lets
us pass lease information from source to dst at the start of
migration
Moving the killing of the source VM out of Perform and
into Confirm, means we can now recover if the dst host
can't successfully Finish receiving migration data.
Fix some driver names:
s/virDrvCPUCompare/virDrvCompareCPU/
s/virDrvCPUBaseline/virDrvBaselineCPU/
s/virDrvQemuDomainMonitorCommand/virDrvDomainQemuMonitorCommand/
s/virDrvSecretNumOfSecrets/virDrvNumOfSecrets/
s/virDrvSecretListSecrets/virDrvListSecrets/
And some driver struct field names:
s/getFreeMemory/nodeGetFreeMemory/