1 /*
2  * qemu_migration_cookie.h: QEMU migration cookie handling
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library.  If not, see
16  * <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include "qemu_domain.h"
22 #include "qemu_domainjob.h"
23 #include "qemu_migration_params.h"
24 #include "virenum.h"
25 
26 typedef enum {
27     QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS,
28     QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
29     QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
30     QEMU_MIGRATION_COOKIE_FLAG_NETWORK,
31     QEMU_MIGRATION_COOKIE_FLAG_NBD,
32     QEMU_MIGRATION_COOKIE_FLAG_STATS,
33     QEMU_MIGRATION_COOKIE_FLAG_MEMORY_HOTPLUG,
34     QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG,
35     QEMU_MIGRATION_COOKIE_FLAG_CPU,
36     QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT,
37     QEMU_MIGRATION_COOKIE_FLAG_CAPS,
38     QEMU_MIGRATION_COOKIE_FLAG_BLOCK_DIRTY_BITMAPS,
39 
40     QEMU_MIGRATION_COOKIE_FLAG_LAST
41 } qemuMigrationCookieFlags;
42 
43 VIR_ENUM_DECL(qemuMigrationCookieFlag);
44 
45 typedef enum {
46     QEMU_MIGRATION_COOKIE_GRAPHICS  = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
47     QEMU_MIGRATION_COOKIE_LOCKSTATE = (1 << QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE),
48     QEMU_MIGRATION_COOKIE_PERSISTENT = (1 << QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT),
49     QEMU_MIGRATION_COOKIE_NETWORK = (1 << QEMU_MIGRATION_COOKIE_FLAG_NETWORK),
50     QEMU_MIGRATION_COOKIE_NBD = (1 << QEMU_MIGRATION_COOKIE_FLAG_NBD),
51     QEMU_MIGRATION_COOKIE_STATS = (1 << QEMU_MIGRATION_COOKIE_FLAG_STATS),
52     QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG = (1 << QEMU_MIGRATION_COOKIE_FLAG_MEMORY_HOTPLUG),
53     QEMU_MIGRATION_COOKIE_CPU_HOTPLUG = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG),
54     QEMU_MIGRATION_COOKIE_CPU = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU),
55     QEMU_MIGRATION_COOKIE_CAPS = (1 << QEMU_MIGRATION_COOKIE_FLAG_CAPS),
56     QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS = (1 << QEMU_MIGRATION_COOKIE_FLAG_BLOCK_DIRTY_BITMAPS),
57 } qemuMigrationCookieFeatures;
58 
59 typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
60 struct _qemuMigrationCookieGraphics {
61     int type;
62     int port;
63     int tlsPort;
64     char *listen;
65     char *tlsSubject;
66 };
67 
68 typedef struct _qemuMigrationCookieNetData qemuMigrationCookieNetData;
69 struct _qemuMigrationCookieNetData {
70     int vporttype; /* enum virNetDevVPortProfile */
71 
72     /*
73      * Array of pointers to saved data. Each VIF will have its own
74      * data to transfer.
75      */
76     char *portdata;
77 };
78 
79 typedef struct _qemuMigrationCookieNetwork qemuMigrationCookieNetwork;
80 struct _qemuMigrationCookieNetwork {
81     /* How many virtual NICs are we saving data for? */
82     int nnets;
83 
84     qemuMigrationCookieNetData *net;
85 };
86 
87 struct qemuMigrationCookieNBDDisk {
88     char *target;                   /* Disk target */
89     unsigned long long capacity;    /* And its capacity */
90 };
91 
92 typedef struct _qemuMigrationCookieNBD qemuMigrationCookieNBD;
93 struct _qemuMigrationCookieNBD {
94     int port; /* on which port does NBD server listen for incoming data */
95 
96     size_t ndisks;  /* Number of items in @disk array */
97     struct qemuMigrationCookieNBDDisk *disks;
98 };
99 
100 typedef struct _qemuMigrationCookieCaps qemuMigrationCookieCaps;
101 struct _qemuMigrationCookieCaps {
102     virBitmap *supported;
103     virBitmap *automatic;
104 };
105 
106 typedef struct _qemuMigrationBlockDirtyBitmapsDiskBitmap qemuMigrationBlockDirtyBitmapsDiskBitmap;
107 struct _qemuMigrationBlockDirtyBitmapsDiskBitmap {
108     /* config */
109     char *bitmapname;
110     char *alias;
111 
112     /* runtime */
113     virTristateBool persistent; /* force persisting of the bitmap */
114     char *sourcebitmap; /* optional, actual bitmap to migrate in case we needed
115                            to create a temporary one by merging */
116     bool skip; /* omit this bitmap */
117 };
118 
119 
120 typedef struct _qemuMigrationBlockDirtyBitmapsDisk qemuMigrationBlockDirtyBitmapsDisk;
121 struct _qemuMigrationBlockDirtyBitmapsDisk {
122     char *target;
123 
124     GSList *bitmaps;
125 
126     /* runtime data */
127     virDomainDiskDef *disk; /* disk object corresponding to 'target' */
128     const char *nodename; /* nodename of the top level source of 'disk' */
129     bool skip; /* omit this disk */
130 };
131 
132 
133 typedef struct _qemuMigrationCookie qemuMigrationCookie;
134 struct _qemuMigrationCookie {
135     unsigned int flags;
136     unsigned int flagsMandatory;
137 
138     /* Host properties */
139     unsigned char localHostuuid[VIR_UUID_BUFLEN];
140     unsigned char remoteHostuuid[VIR_UUID_BUFLEN];
141     char *localHostname;
142     char *remoteHostname;
143 
144     /* Guest properties */
145     unsigned char uuid[VIR_UUID_BUFLEN];
146     char *name;
147 
148     /* If (flags & QEMU_MIGRATION_COOKIE_LOCKSTATE) */
149     char *lockState;
150     char *lockDriver;
151 
152     /* If (flags & QEMU_MIGRATION_COOKIE_GRAPHICS) */
153     qemuMigrationCookieGraphics *graphics;
154 
155     /* If (flags & QEMU_MIGRATION_COOKIE_PERSISTENT) */
156     virDomainDef *persistent;
157 
158     /* If (flags & QEMU_MIGRATION_COOKIE_NETWORK) */
159     qemuMigrationCookieNetwork *network;
160 
161     /* If (flags & QEMU_MIGRATION_COOKIE_NBD) */
162     qemuMigrationCookieNBD *nbd;
163 
164     /* If (flags & QEMU_MIGRATION_COOKIE_STATS) */
165     qemuDomainJobInfo *jobInfo;
166 
167     /* If flags & QEMU_MIGRATION_COOKIE_CPU */
168     virCPUDef *cpu;
169 
170     /* If flags & QEMU_MIGRATION_COOKIE_CAPS */
171     qemuMigrationCookieCaps *caps;
172 
173     /* If flags & QEMU_MIGRATION_COOKIE_BLOCK_DIRTY_BITMAPS */
174     GSList *blockDirtyBitmaps;
175 };
176 
177 
178 qemuMigrationCookie *
179 qemuMigrationCookieNew(const virDomainDef *def,
180                        const char *origname);
181 
182 int
183 qemuMigrationCookieFormat(qemuMigrationCookie *mig,
184                           virQEMUDriver *driver,
185                           virDomainObj *dom,
186                           qemuMigrationParty party,
187                           char **cookieout,
188                           int *cookieoutlen,
189                           unsigned int flags);
190 
191 qemuMigrationCookie *
192 qemuMigrationCookieParse(virQEMUDriver *driver,
193                         const virDomainDef *def,
194                         const char *origname,
195                         qemuDomainObjPrivate *priv,
196                         const char *cookiein,
197                         int cookieinlen,
198                         unsigned int flags);
199 
200 void
201 qemuMigrationCookieFree(qemuMigrationCookie *mig);
202 G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuMigrationCookie, qemuMigrationCookieFree);
203 
204 int
205 qemuMigrationCookieAddPersistent(qemuMigrationCookie *mig,
206                                  virDomainDef **def);
207 
208 virDomainDef *
209 qemuMigrationCookieGetPersistent(qemuMigrationCookie *mig);
210 
211 /* qemuMigrationCookieXMLFormat is exported for test use only! */
212 int
213 qemuMigrationCookieXMLFormat(virQEMUDriver *driver,
214                              virQEMUCaps *qemuCaps,
215                              virBuffer *buf,
216                              qemuMigrationCookie *mig);
217 
218 int
219 qemuMigrationCookieBlockDirtyBitmapsMatchDisks(virDomainDef *def,
220                                                GSList *disks);
221 
222 int
223 qemuMigrationCookieBlockDirtyBitmapsToParams(GSList *disks,
224                                              virJSONValue **mapping);
225