mirror of https://github.com/xqemu/xqemu.git
migration: Update docs to discourage version bumps
Version bumps break backwards migration; update the docs to explain to people that's bad and how to avoid it. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20170210110359.8210-1-dgilbert@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
parent
128e4e1089
commit
5f9412bbac
|
@ -161,6 +161,11 @@ include/hw/hw.h.
|
||||||
|
|
||||||
=== More about versions ===
|
=== More about versions ===
|
||||||
|
|
||||||
|
Version numbers are intended for major incompatible changes to the
|
||||||
|
migration of a device, and using them breaks backwards-migration
|
||||||
|
compatibility; in general most changes can be made by adding Subsections
|
||||||
|
(see below) or _TEST macros (see below) which won't break compatibility.
|
||||||
|
|
||||||
You can see that there are several version fields:
|
You can see that there are several version fields:
|
||||||
|
|
||||||
- version_id: the maximum version_id supported by VMState for that device.
|
- version_id: the maximum version_id supported by VMState for that device.
|
||||||
|
@ -175,6 +180,9 @@ version_id. And the function load_state_old() (if present) is able to
|
||||||
load state from minimum_version_id_old to minimum_version_id. This
|
load state from minimum_version_id_old to minimum_version_id. This
|
||||||
function is deprecated and will be removed when no more users are left.
|
function is deprecated and will be removed when no more users are left.
|
||||||
|
|
||||||
|
Saving state will always create a section with the 'version_id' value
|
||||||
|
and thus can't be loaded by any older QEMU.
|
||||||
|
|
||||||
=== Massaging functions ===
|
=== Massaging functions ===
|
||||||
|
|
||||||
Sometimes, it is not enough to be able to save the state directly
|
Sometimes, it is not enough to be able to save the state directly
|
||||||
|
@ -292,6 +300,56 @@ save/send this state when we are in the middle of a pio operation
|
||||||
not enabled, the values on that fields are garbage and don't need to
|
not enabled, the values on that fields are garbage and don't need to
|
||||||
be sent.
|
be sent.
|
||||||
|
|
||||||
|
Using a condition function that checks a 'property' to determine whether
|
||||||
|
to send a subsection allows backwards migration compatibility when
|
||||||
|
new subsections are added.
|
||||||
|
|
||||||
|
For example;
|
||||||
|
a) Add a new property using DEFINE_PROP_BOOL - e.g. support-foo and
|
||||||
|
default it to true.
|
||||||
|
b) Add an entry to the HW_COMPAT_ for the previous version
|
||||||
|
that sets the property to false.
|
||||||
|
c) Add a static bool support_foo function that tests the property.
|
||||||
|
d) Add a subsection with a .needed set to the support_foo function
|
||||||
|
e) (potentially) Add a pre_load that sets up a default value for 'foo'
|
||||||
|
to be used if the subsection isn't loaded.
|
||||||
|
|
||||||
|
Now that subsection will not be generated when using an older
|
||||||
|
machine type and the migration stream will be accepted by older
|
||||||
|
QEMU versions. pre-load functions can be used to initialise state
|
||||||
|
on the newer version so that they default to suitable values
|
||||||
|
when loading streams created by older QEMU versions that do not
|
||||||
|
generate the subsection.
|
||||||
|
|
||||||
|
In some cases subsections are added for data that had been accidentally
|
||||||
|
omitted by earlier versions; if the missing data causes the migration
|
||||||
|
process to succeed but the guest to behave badly then it may be better
|
||||||
|
to send the subsection and cause the migration to explicitly fail
|
||||||
|
with the unknown subsection error. If the bad behaviour only happens
|
||||||
|
with certain data values, making the subsection conditional on
|
||||||
|
the data value (rather than the machine type) allows migrations to succeed
|
||||||
|
in most cases. In general the preference is to tie the subsection to
|
||||||
|
the machine type, and allow reliable migrations, unless the behaviour
|
||||||
|
from omission of the subsection is really bad.
|
||||||
|
|
||||||
|
= Not sending existing elements =
|
||||||
|
|
||||||
|
Sometimes members of the VMState are no longer needed;
|
||||||
|
removing them will break migration compatibility
|
||||||
|
making them version dependent and bumping the version will break backwards
|
||||||
|
migration compatibility.
|
||||||
|
|
||||||
|
The best way is to:
|
||||||
|
a) Add a new property/compatibility/function in the same way for subsections
|
||||||
|
above.
|
||||||
|
b) replace the VMSTATE macro with the _TEST version of the macro, e.g.:
|
||||||
|
VMSTATE_UINT32(foo, barstruct)
|
||||||
|
becomes
|
||||||
|
VMSTATE_UINT32_TEST(foo, barstruct, pre_version_baz)
|
||||||
|
|
||||||
|
Sometime in the future when we no longer care about the ancient
|
||||||
|
versions these can be killed off.
|
||||||
|
|
||||||
= Return path =
|
= Return path =
|
||||||
|
|
||||||
In most migration scenarios there is only a single data path that runs
|
In most migration scenarios there is only a single data path that runs
|
||||||
|
|
Loading…
Reference in New Issue