1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
QEMU Migration Phases
=====================
.. contents::
QEMU supports only migration protocols 2 and 3 (1 was lacking too many
steps). Repeating the protocol sequences from libvirt.c:
Migration protocol v2 API Sequence
----------------------------------
**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
Migration protocol v3 API 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
QEMU Migration Locking Rules
============================
Migration is a complicated beast which may span across several APIs on both
source and destination side and we need to keep the domain we are migrating in
a consistent state during the whole process.
To avoid anyone from changing the domain in the middle of migration we need to
keep ``MIGRATION_OUT`` job active during migration from ``Begin`` to
``Confirm`` on the source side and ``MIGRATION_IN`` job has to be active from
``Prepare`` to ``Finish`` on the destination side.
For this purpose we introduce several helper methods to deal with locking
primitives (described in `qemu-threads <qemu-threads.html>`__) in the right way:
* ``qemuMigrationJobStart``
* ``qemuMigrationJobContinue``
* ``qemuMigrationJobStartPhase``
* ``qemuMigrationJobSetPhase``
* ``qemuMigrationJobFinish``
The sequence of calling ``qemuMigrationJob*`` helper methods is as follows:
- The first API of a migration protocol (``Prepare`` or ``Perform/Begin``
depending on migration type and version) has to start migration job and keep
it active::
qemuMigrationJobStart(driver, vm, VIR_JOB_MIGRATION_{IN,OUT});
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_*);
...do work...
qemuMigrationJobContinue(vm);
- All consequent phases except for the last one have to keep the job active::
if (!qemuMigrationJobIsActive(vm, VIR_JOB_MIGRATION_{IN,OUT}))
return;
qemuMigrationJobStartPhase(driver, vm, QEMU_MIGRATION_PHASE_*);
...do work...
qemuMigrationJobContinue(vm);
- The last migration phase finally finishes the migration job::
if (!qemuMigrationJobIsActive(vm, VIR_JOB_MIGRATION_{IN,OUT}))
return;
qemuMigrationJobStartPhase(driver, vm, QEMU_MIGRATION_PHASE_*);
...do work...
qemuMigrationJobFinish(driver, vm);
While migration job is running (i.e., after ``qemuMigrationJobStart*`` but before
``qemuMigrationJob{Continue,Finish}``), migration phase can be advanced using::
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_*);
|