xref: /qemu/migration/options.c (revision b6f568262b48ca0cb3dc018909908017551b5679)
1 /*
2  * QEMU migration capabilities
3  *
4  * Copyright (c) 2012-2023 Red Hat Inc
5  *
6  * Authors:
7  *   Orit Wasserman <owasserm@redhat.com>
8  *   Juan Quintela <quintela@redhat.com>
9  *
10  * This work is licensed under the terms of the GNU GPL, version 2 or later.
11  * See the COPYING file in the top-level directory.
12  */
13 
14 #include "qemu/osdep.h"
15 #include "qemu/error-report.h"
16 #include "exec/target_page.h"
17 #include "qapi/clone-visitor.h"
18 #include "qapi/error.h"
19 #include "qapi/qapi-commands-migration.h"
20 #include "qapi/qapi-visit-migration.h"
21 #include "qapi/qmp/qerror.h"
22 #include "qobject/qnull.h"
23 #include "system/runstate.h"
24 #include "migration/colo.h"
25 #include "migration/cpr.h"
26 #include "migration/misc.h"
27 #include "migration.h"
28 #include "migration-stats.h"
29 #include "qemu-file.h"
30 #include "ram.h"
31 #include "options.h"
32 #include "system/kvm.h"
33 
34 /* Maximum migrate downtime set to 2000 seconds */
35 #define MAX_MIGRATE_DOWNTIME_SECONDS 2000
36 #define MAX_MIGRATE_DOWNTIME (MAX_MIGRATE_DOWNTIME_SECONDS * 1000)
37 
38 #define MAX_THROTTLE  (128 << 20)      /* Migration transfer speed throttling */
39 
40 /* Time in milliseconds we are allowed to stop the source,
41  * for sending the last part */
42 #define DEFAULT_MIGRATE_SET_DOWNTIME 300
43 
44 /* Define default autoconverge cpu throttle migration parameters */
45 #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50
46 #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
47 #define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
48 #define DEFAULT_MIGRATE_MAX_CPU_THROTTLE 99
49 
50 /* Migration XBZRLE default cache size */
51 #define DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE (64 * 1024 * 1024)
52 
53 /* The delay time (in ms) between two COLO checkpoints */
54 #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY (200 * 100)
55 #define DEFAULT_MIGRATE_MULTIFD_CHANNELS 2
56 #define DEFAULT_MIGRATE_MULTIFD_COMPRESSION MULTIFD_COMPRESSION_NONE
57 /* 0: means nocompress, 1: best speed, ... 9: best compress ratio */
58 #define DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL 1
59 /*
60  * 1: best speed, ... 9: best compress ratio
61  * There is some nuance here. Refer to QATzip documentation to understand
62  * the mapping of QATzip levels to standard deflate levels.
63  */
64 #define DEFAULT_MIGRATE_MULTIFD_QATZIP_LEVEL 1
65 
66 /* 0: means nocompress, 1: best speed, ... 20: best compress ratio */
67 #define DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL 1
68 
69 /* Background transfer rate for postcopy, 0 means unlimited, note
70  * that page requests can still exceed this limit.
71  */
72 #define DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH 0
73 
74 /*
75  * Parameters for self_announce_delay giving a stream of RARP/ARP
76  * packets after migration.
77  */
78 #define DEFAULT_MIGRATE_ANNOUNCE_INITIAL  50
79 #define DEFAULT_MIGRATE_ANNOUNCE_MAX     550
80 #define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS    5
81 #define DEFAULT_MIGRATE_ANNOUNCE_STEP    100
82 
83 #define DEFINE_PROP_MIG_CAP(name, x)             \
84     DEFINE_PROP_BOOL(name, MigrationState, capabilities[x], false)
85 
86 #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD     1000    /* milliseconds */
87 #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT            1       /* MB/s */
88 
89 const Property migration_properties[] = {
90     DEFINE_PROP_BOOL("store-global-state", MigrationState,
91                      store_global_state, true),
92     DEFINE_PROP_BOOL("send-configuration", MigrationState,
93                      send_configuration, true),
94     DEFINE_PROP_BOOL("send-section-footer", MigrationState,
95                      send_section_footer, true),
96     DEFINE_PROP_BOOL("send-switchover-start", MigrationState,
97                      send_switchover_start, true),
98     DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
99                       multifd_flush_after_each_section, false),
100     DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
101                       clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
102     DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
103                      preempt_pre_7_2, false),
104     DEFINE_PROP_BOOL("multifd-clean-tls-termination", MigrationState,
105                      multifd_clean_tls_termination, true),
106 
107     /* Migration parameters */
108     DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState,
109                       parameters.throttle_trigger_threshold,
110                       DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD),
111     DEFINE_PROP_UINT8("x-cpu-throttle-initial", MigrationState,
112                       parameters.cpu_throttle_initial,
113                       DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL),
114     DEFINE_PROP_UINT8("x-cpu-throttle-increment", MigrationState,
115                       parameters.cpu_throttle_increment,
116                       DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT),
117     DEFINE_PROP_BOOL("x-cpu-throttle-tailslow", MigrationState,
118                       parameters.cpu_throttle_tailslow, false),
119     DEFINE_PROP_SIZE("x-max-bandwidth", MigrationState,
120                       parameters.max_bandwidth, MAX_THROTTLE),
121     DEFINE_PROP_SIZE("avail-switchover-bandwidth", MigrationState,
122                       parameters.avail_switchover_bandwidth, 0),
123     DEFINE_PROP_UINT64("x-downtime-limit", MigrationState,
124                       parameters.downtime_limit,
125                       DEFAULT_MIGRATE_SET_DOWNTIME),
126     DEFINE_PROP_UINT32("x-checkpoint-delay", MigrationState,
127                       parameters.x_checkpoint_delay,
128                       DEFAULT_MIGRATE_X_CHECKPOINT_DELAY),
129     DEFINE_PROP_UINT8("multifd-channels", MigrationState,
130                       parameters.multifd_channels,
131                       DEFAULT_MIGRATE_MULTIFD_CHANNELS),
132     DEFINE_PROP_MULTIFD_COMPRESSION("multifd-compression", MigrationState,
133                       parameters.multifd_compression,
134                       DEFAULT_MIGRATE_MULTIFD_COMPRESSION),
135     DEFINE_PROP_UINT8("multifd-zlib-level", MigrationState,
136                       parameters.multifd_zlib_level,
137                       DEFAULT_MIGRATE_MULTIFD_ZLIB_LEVEL),
138     DEFINE_PROP_UINT8("multifd-qatzip-level", MigrationState,
139                       parameters.multifd_qatzip_level,
140                       DEFAULT_MIGRATE_MULTIFD_QATZIP_LEVEL),
141     DEFINE_PROP_UINT8("multifd-zstd-level", MigrationState,
142                       parameters.multifd_zstd_level,
143                       DEFAULT_MIGRATE_MULTIFD_ZSTD_LEVEL),
144     DEFINE_PROP_SIZE("xbzrle-cache-size", MigrationState,
145                       parameters.xbzrle_cache_size,
146                       DEFAULT_MIGRATE_XBZRLE_CACHE_SIZE),
147     DEFINE_PROP_SIZE("max-postcopy-bandwidth", MigrationState,
148                       parameters.max_postcopy_bandwidth,
149                       DEFAULT_MIGRATE_MAX_POSTCOPY_BANDWIDTH),
150     DEFINE_PROP_UINT8("max-cpu-throttle", MigrationState,
151                       parameters.max_cpu_throttle,
152                       DEFAULT_MIGRATE_MAX_CPU_THROTTLE),
153     DEFINE_PROP_SIZE("announce-initial", MigrationState,
154                       parameters.announce_initial,
155                       DEFAULT_MIGRATE_ANNOUNCE_INITIAL),
156     DEFINE_PROP_SIZE("announce-max", MigrationState,
157                       parameters.announce_max,
158                       DEFAULT_MIGRATE_ANNOUNCE_MAX),
159     DEFINE_PROP_SIZE("announce-rounds", MigrationState,
160                       parameters.announce_rounds,
161                       DEFAULT_MIGRATE_ANNOUNCE_ROUNDS),
162     DEFINE_PROP_SIZE("announce-step", MigrationState,
163                       parameters.announce_step,
164                       DEFAULT_MIGRATE_ANNOUNCE_STEP),
165     DEFINE_PROP_STRING("tls-creds", MigrationState, parameters.tls_creds),
166     DEFINE_PROP_STRING("tls-hostname", MigrationState, parameters.tls_hostname),
167     DEFINE_PROP_STRING("tls-authz", MigrationState, parameters.tls_authz),
168     DEFINE_PROP_UINT64("x-vcpu-dirty-limit-period", MigrationState,
169                        parameters.x_vcpu_dirty_limit_period,
170                        DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD),
171     DEFINE_PROP_UINT64("vcpu-dirty-limit", MigrationState,
172                        parameters.vcpu_dirty_limit,
173                        DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT),
174     DEFINE_PROP_MIG_MODE("mode", MigrationState,
175                       parameters.mode,
176                       MIG_MODE_NORMAL),
177     DEFINE_PROP_ZERO_PAGE_DETECTION("zero-page-detection", MigrationState,
178                        parameters.zero_page_detection,
179                        ZERO_PAGE_DETECTION_MULTIFD),
180 
181     /* Migration capabilities */
182     DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
183     DEFINE_PROP_MIG_CAP("x-rdma-pin-all", MIGRATION_CAPABILITY_RDMA_PIN_ALL),
184     DEFINE_PROP_MIG_CAP("x-auto-converge", MIGRATION_CAPABILITY_AUTO_CONVERGE),
185     DEFINE_PROP_MIG_CAP("x-zero-blocks", MIGRATION_CAPABILITY_ZERO_BLOCKS),
186     DEFINE_PROP_MIG_CAP("x-events", MIGRATION_CAPABILITY_EVENTS),
187     DEFINE_PROP_MIG_CAP("x-postcopy-ram", MIGRATION_CAPABILITY_POSTCOPY_RAM),
188     DEFINE_PROP_MIG_CAP("x-postcopy-preempt",
189                         MIGRATION_CAPABILITY_POSTCOPY_PREEMPT),
190     DEFINE_PROP_MIG_CAP("x-colo", MIGRATION_CAPABILITY_X_COLO),
191     DEFINE_PROP_MIG_CAP("x-release-ram", MIGRATION_CAPABILITY_RELEASE_RAM),
192     DEFINE_PROP_MIG_CAP("x-return-path", MIGRATION_CAPABILITY_RETURN_PATH),
193     DEFINE_PROP_MIG_CAP("x-multifd", MIGRATION_CAPABILITY_MULTIFD),
194     DEFINE_PROP_MIG_CAP("x-background-snapshot",
195             MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT),
196 #ifdef CONFIG_LINUX
197     DEFINE_PROP_MIG_CAP("x-zero-copy-send",
198             MIGRATION_CAPABILITY_ZERO_COPY_SEND),
199 #endif
200     DEFINE_PROP_MIG_CAP("x-switchover-ack",
201                         MIGRATION_CAPABILITY_SWITCHOVER_ACK),
202     DEFINE_PROP_MIG_CAP("x-dirty-limit", MIGRATION_CAPABILITY_DIRTY_LIMIT),
203     DEFINE_PROP_MIG_CAP("mapped-ram", MIGRATION_CAPABILITY_MAPPED_RAM),
204 };
205 const size_t migration_properties_count = ARRAY_SIZE(migration_properties);
206 
migrate_auto_converge(void)207 bool migrate_auto_converge(void)
208 {
209     MigrationState *s = migrate_get_current();
210 
211     return s->capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];
212 }
213 
migrate_send_switchover_start(void)214 bool migrate_send_switchover_start(void)
215 {
216     MigrationState *s = migrate_get_current();
217 
218     return s->send_switchover_start;
219 }
220 
migrate_background_snapshot(void)221 bool migrate_background_snapshot(void)
222 {
223     MigrationState *s = migrate_get_current();
224 
225     return s->capabilities[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT];
226 }
227 
migrate_colo(void)228 bool migrate_colo(void)
229 {
230     MigrationState *s = migrate_get_current();
231 
232     return s->capabilities[MIGRATION_CAPABILITY_X_COLO];
233 }
234 
migrate_dirty_bitmaps(void)235 bool migrate_dirty_bitmaps(void)
236 {
237     MigrationState *s = migrate_get_current();
238 
239     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
240 }
241 
migrate_dirty_limit(void)242 bool migrate_dirty_limit(void)
243 {
244     MigrationState *s = migrate_get_current();
245 
246     return s->capabilities[MIGRATION_CAPABILITY_DIRTY_LIMIT];
247 }
248 
migrate_events(void)249 bool migrate_events(void)
250 {
251     MigrationState *s = migrate_get_current();
252 
253     return s->capabilities[MIGRATION_CAPABILITY_EVENTS];
254 }
255 
migrate_mapped_ram(void)256 bool migrate_mapped_ram(void)
257 {
258     MigrationState *s = migrate_get_current();
259 
260     return s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM];
261 }
262 
migrate_ignore_shared(void)263 bool migrate_ignore_shared(void)
264 {
265     MigrationState *s = migrate_get_current();
266 
267     return s->capabilities[MIGRATION_CAPABILITY_X_IGNORE_SHARED];
268 }
269 
migrate_late_block_activate(void)270 bool migrate_late_block_activate(void)
271 {
272     MigrationState *s = migrate_get_current();
273 
274     return s->capabilities[MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE];
275 }
276 
migrate_multifd(void)277 bool migrate_multifd(void)
278 {
279     MigrationState *s = migrate_get_current();
280 
281     return s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
282 }
283 
migrate_pause_before_switchover(void)284 bool migrate_pause_before_switchover(void)
285 {
286     MigrationState *s = migrate_get_current();
287 
288     return s->capabilities[MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER];
289 }
290 
migrate_postcopy_blocktime(void)291 bool migrate_postcopy_blocktime(void)
292 {
293     MigrationState *s = migrate_get_current();
294 
295     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME];
296 }
297 
migrate_postcopy_preempt(void)298 bool migrate_postcopy_preempt(void)
299 {
300     MigrationState *s = migrate_get_current();
301 
302     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT];
303 }
304 
migrate_postcopy_ram(void)305 bool migrate_postcopy_ram(void)
306 {
307     MigrationState *s = migrate_get_current();
308 
309     return s->capabilities[MIGRATION_CAPABILITY_POSTCOPY_RAM];
310 }
311 
migrate_rdma_pin_all(void)312 bool migrate_rdma_pin_all(void)
313 {
314     MigrationState *s = migrate_get_current();
315 
316     return s->capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
317 }
318 
migrate_release_ram(void)319 bool migrate_release_ram(void)
320 {
321     MigrationState *s = migrate_get_current();
322 
323     return s->capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
324 }
325 
migrate_return_path(void)326 bool migrate_return_path(void)
327 {
328     MigrationState *s = migrate_get_current();
329 
330     return s->capabilities[MIGRATION_CAPABILITY_RETURN_PATH];
331 }
332 
migrate_switchover_ack(void)333 bool migrate_switchover_ack(void)
334 {
335     MigrationState *s = migrate_get_current();
336 
337     return s->capabilities[MIGRATION_CAPABILITY_SWITCHOVER_ACK];
338 }
339 
migrate_validate_uuid(void)340 bool migrate_validate_uuid(void)
341 {
342     MigrationState *s = migrate_get_current();
343 
344     return s->capabilities[MIGRATION_CAPABILITY_VALIDATE_UUID];
345 }
346 
migrate_xbzrle(void)347 bool migrate_xbzrle(void)
348 {
349     MigrationState *s = migrate_get_current();
350 
351     return s->capabilities[MIGRATION_CAPABILITY_XBZRLE];
352 }
353 
migrate_zero_copy_send(void)354 bool migrate_zero_copy_send(void)
355 {
356     MigrationState *s = migrate_get_current();
357 
358     return s->capabilities[MIGRATION_CAPABILITY_ZERO_COPY_SEND];
359 }
360 
361 /* pseudo capabilities */
362 
migrate_multifd_flush_after_each_section(void)363 bool migrate_multifd_flush_after_each_section(void)
364 {
365     MigrationState *s = migrate_get_current();
366 
367     return s->multifd_flush_after_each_section;
368 }
369 
migrate_postcopy(void)370 bool migrate_postcopy(void)
371 {
372     return migrate_postcopy_ram() || migrate_dirty_bitmaps();
373 }
374 
migrate_rdma(void)375 bool migrate_rdma(void)
376 {
377     MigrationState *s = migrate_get_current();
378 
379     return s->rdma_migration;
380 }
381 
migrate_tls(void)382 bool migrate_tls(void)
383 {
384     MigrationState *s = migrate_get_current();
385 
386     return s->parameters.tls_creds && *s->parameters.tls_creds;
387 }
388 
389 typedef enum WriteTrackingSupport {
390     WT_SUPPORT_UNKNOWN = 0,
391     WT_SUPPORT_ABSENT,
392     WT_SUPPORT_AVAILABLE,
393     WT_SUPPORT_COMPATIBLE
394 } WriteTrackingSupport;
395 
396 static
migrate_query_write_tracking(void)397 WriteTrackingSupport migrate_query_write_tracking(void)
398 {
399     /* Check if kernel supports required UFFD features */
400     if (!ram_write_tracking_available()) {
401         return WT_SUPPORT_ABSENT;
402     }
403     /*
404      * Check if current memory configuration is
405      * compatible with required UFFD features.
406      */
407     if (!ram_write_tracking_compatible()) {
408         return WT_SUPPORT_AVAILABLE;
409     }
410 
411     return WT_SUPPORT_COMPATIBLE;
412 }
413 
414 /* Migration capabilities set */
415 struct MigrateCapsSet {
416     int size;                       /* Capability set size */
417     MigrationCapability caps[];     /* Variadic array of capabilities */
418 };
419 typedef struct MigrateCapsSet MigrateCapsSet;
420 
421 /* Define and initialize MigrateCapsSet */
422 #define INITIALIZE_MIGRATE_CAPS_SET(_name, ...)   \
423     MigrateCapsSet _name = {    \
424         .size = sizeof((int []) { __VA_ARGS__ }) / sizeof(int), \
425         .caps = { __VA_ARGS__ } \
426     }
427 
428 /* Background-snapshot compatibility check list */
429 static const
430 INITIALIZE_MIGRATE_CAPS_SET(check_caps_background_snapshot,
431     MIGRATION_CAPABILITY_POSTCOPY_RAM,
432     MIGRATION_CAPABILITY_DIRTY_BITMAPS,
433     MIGRATION_CAPABILITY_POSTCOPY_BLOCKTIME,
434     MIGRATION_CAPABILITY_LATE_BLOCK_ACTIVATE,
435     MIGRATION_CAPABILITY_RETURN_PATH,
436     MIGRATION_CAPABILITY_MULTIFD,
437     MIGRATION_CAPABILITY_PAUSE_BEFORE_SWITCHOVER,
438     MIGRATION_CAPABILITY_AUTO_CONVERGE,
439     MIGRATION_CAPABILITY_RELEASE_RAM,
440     MIGRATION_CAPABILITY_RDMA_PIN_ALL,
441     MIGRATION_CAPABILITY_XBZRLE,
442     MIGRATION_CAPABILITY_X_COLO,
443     MIGRATION_CAPABILITY_VALIDATE_UUID,
444     MIGRATION_CAPABILITY_ZERO_COPY_SEND);
445 
migrate_incoming_started(void)446 static bool migrate_incoming_started(void)
447 {
448     return !!migration_incoming_get_current()->transport_data;
449 }
450 
migrate_rdma_caps_check(bool * caps,Error ** errp)451 bool migrate_rdma_caps_check(bool *caps, Error **errp)
452 {
453     if (caps[MIGRATION_CAPABILITY_XBZRLE]) {
454         error_setg(errp, "RDMA and XBZRLE can't be used together");
455         return false;
456     }
457     if (caps[MIGRATION_CAPABILITY_MULTIFD]) {
458         error_setg(errp, "RDMA and multifd can't be used together");
459         return false;
460     }
461     if (caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
462         error_setg(errp, "RDMA and postcopy-ram can't be used together");
463         return false;
464     }
465 
466     return true;
467 }
468 
469 /**
470  * @migration_caps_check - check capability compatibility
471  *
472  * @old_caps: old capability list
473  * @new_caps: new capability list
474  * @errp: set *errp if the check failed, with reason
475  *
476  * Returns true if check passed, otherwise false.
477  */
migrate_caps_check(bool * old_caps,bool * new_caps,Error ** errp)478 bool migrate_caps_check(bool *old_caps, bool *new_caps, Error **errp)
479 {
480     ERRP_GUARD();
481     MigrationIncomingState *mis = migration_incoming_get_current();
482 
483     if (new_caps[MIGRATION_CAPABILITY_ZERO_BLOCKS]) {
484         warn_report("zero-blocks capability is deprecated");
485     }
486 
487 #ifndef CONFIG_REPLICATION
488     if (new_caps[MIGRATION_CAPABILITY_X_COLO]) {
489         error_setg(errp, "QEMU compiled without replication module"
490                    " can't enable COLO");
491         error_append_hint(errp, "Please enable replication before COLO.\n");
492         return false;
493     }
494 #endif
495 
496     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
497         /* This check is reasonably expensive, so only when it's being
498          * set the first time, also it's only the destination that needs
499          * special support.
500          */
501         if (!old_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] &&
502             runstate_check(RUN_STATE_INMIGRATE) &&
503             !postcopy_ram_supported_by_host(mis, errp)) {
504             error_prepend(errp, "Postcopy is not supported: ");
505             return false;
506         }
507 
508         if (new_caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED]) {
509             error_setg(errp, "Postcopy is not compatible with ignore-shared");
510             return false;
511         }
512 
513         if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
514             error_setg(errp, "Postcopy is not yet compatible with multifd");
515             return false;
516         }
517     }
518 
519     if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
520         WriteTrackingSupport wt_support;
521         int idx;
522         /*
523          * Check if 'background-snapshot' capability is supported by
524          * host kernel and compatible with guest memory configuration.
525          */
526         wt_support = migrate_query_write_tracking();
527         if (wt_support < WT_SUPPORT_AVAILABLE) {
528             error_setg(errp, "Background-snapshot is not supported by host kernel");
529             return false;
530         }
531         if (wt_support < WT_SUPPORT_COMPATIBLE) {
532             error_setg(errp, "Background-snapshot is not compatible "
533                     "with guest memory configuration");
534             return false;
535         }
536 
537         /*
538          * Check if there are any migration capabilities
539          * incompatible with 'background-snapshot'.
540          */
541         for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
542             int incomp_cap = check_caps_background_snapshot.caps[idx];
543             if (new_caps[incomp_cap]) {
544                 error_setg(errp,
545                         "Background-snapshot is not compatible with %s",
546                         MigrationCapability_str(incomp_cap));
547                 return false;
548             }
549         }
550     }
551 
552 #ifdef CONFIG_LINUX
553     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
554         (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
555          new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
556          migrate_multifd_compression() ||
557          migrate_tls())) {
558         error_setg(errp,
559                    "Zero copy only available for non-compressed non-TLS multifd migration");
560         return false;
561     }
562 #else
563     if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
564         error_setg(errp,
565                    "Zero copy currently only available on Linux");
566         return false;
567     }
568 #endif
569 
570     if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
571         if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
572             error_setg(errp, "Postcopy preempt requires postcopy-ram");
573             return false;
574         }
575 
576         if (migrate_incoming_started()) {
577             error_setg(errp,
578                        "Postcopy preempt must be set before incoming starts");
579             return false;
580         }
581     }
582 
583     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
584         if (migrate_incoming_started()) {
585             error_setg(errp, "Multifd must be set before incoming starts");
586             return false;
587         }
588     }
589 
590     if (new_caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK]) {
591         if (!new_caps[MIGRATION_CAPABILITY_RETURN_PATH]) {
592             error_setg(errp, "Capability 'switchover-ack' requires capability "
593                              "'return-path'");
594             return false;
595         }
596     }
597     if (new_caps[MIGRATION_CAPABILITY_DIRTY_LIMIT]) {
598         if (new_caps[MIGRATION_CAPABILITY_AUTO_CONVERGE]) {
599             error_setg(errp, "dirty-limit conflicts with auto-converge"
600                        " either of then available currently");
601             return false;
602         }
603 
604         if (!kvm_enabled() || !kvm_dirty_ring_enabled()) {
605             error_setg(errp, "dirty-limit requires KVM with accelerator"
606                    " property 'dirty-ring-size' set");
607             return false;
608         }
609     }
610 
611     if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
612         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
613             error_setg(errp, "Multifd is not compatible with xbzrle");
614             return false;
615         }
616     }
617 
618     if (new_caps[MIGRATION_CAPABILITY_MAPPED_RAM]) {
619         if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
620             error_setg(errp,
621                        "Mapped-ram migration is incompatible with xbzrle");
622             return false;
623         }
624 
625         if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
626             error_setg(errp,
627                        "Mapped-ram migration is incompatible with postcopy");
628             return false;
629         }
630     }
631 
632     /*
633      * On destination side, check the cases that capability is being set
634      * after incoming thread has started.
635      */
636     if (migrate_rdma() && !migrate_rdma_caps_check(new_caps, errp)) {
637         return false;
638     }
639     return true;
640 }
641 
qmp_query_migrate_capabilities(Error ** errp)642 MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
643 {
644     MigrationCapabilityStatusList *head = NULL, **tail = &head;
645     MigrationCapabilityStatus *caps;
646     MigrationState *s = migrate_get_current();
647     int i;
648 
649     for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
650         caps = g_malloc0(sizeof(*caps));
651         caps->capability = i;
652         caps->state = s->capabilities[i];
653         QAPI_LIST_APPEND(tail, caps);
654     }
655 
656     return head;
657 }
658 
qmp_migrate_set_capabilities(MigrationCapabilityStatusList * params,Error ** errp)659 void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
660                                   Error **errp)
661 {
662     MigrationState *s = migrate_get_current();
663     MigrationCapabilityStatusList *cap;
664     bool new_caps[MIGRATION_CAPABILITY__MAX];
665 
666     if (migration_is_running() || migration_in_colo_state()) {
667         error_setg(errp, "There's a migration process in progress");
668         return;
669     }
670 
671     memcpy(new_caps, s->capabilities, sizeof(new_caps));
672     for (cap = params; cap; cap = cap->next) {
673         new_caps[cap->value->capability] = cap->value->state;
674     }
675 
676     if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
677         return;
678     }
679 
680     for (cap = params; cap; cap = cap->next) {
681         s->capabilities[cap->value->capability] = cap->value->state;
682     }
683 }
684 
685 /* parameters */
686 
migrate_block_bitmap_mapping(void)687 const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
688 {
689     MigrationState *s = migrate_get_current();
690 
691     return s->parameters.block_bitmap_mapping;
692 }
693 
migrate_has_block_bitmap_mapping(void)694 bool migrate_has_block_bitmap_mapping(void)
695 {
696     MigrationState *s = migrate_get_current();
697 
698     return s->parameters.has_block_bitmap_mapping;
699 }
700 
migrate_checkpoint_delay(void)701 uint32_t migrate_checkpoint_delay(void)
702 {
703     MigrationState *s = migrate_get_current();
704 
705     return s->parameters.x_checkpoint_delay;
706 }
707 
migrate_cpu_throttle_increment(void)708 uint8_t migrate_cpu_throttle_increment(void)
709 {
710     MigrationState *s = migrate_get_current();
711 
712     return s->parameters.cpu_throttle_increment;
713 }
714 
migrate_cpu_throttle_initial(void)715 uint8_t migrate_cpu_throttle_initial(void)
716 {
717     MigrationState *s = migrate_get_current();
718 
719     return s->parameters.cpu_throttle_initial;
720 }
721 
migrate_cpu_throttle_tailslow(void)722 bool migrate_cpu_throttle_tailslow(void)
723 {
724     MigrationState *s = migrate_get_current();
725 
726     return s->parameters.cpu_throttle_tailslow;
727 }
728 
migrate_direct_io(void)729 bool migrate_direct_io(void)
730 {
731     MigrationState *s = migrate_get_current();
732 
733     /*
734      * O_DIRECT is only supported with mapped-ram and multifd.
735      *
736      * mapped-ram is needed because filesystems impose restrictions on
737      * O_DIRECT IO alignment (see MAPPED_RAM_FILE_OFFSET_ALIGNMENT).
738      *
739      * multifd is needed to keep the unaligned portion of the stream
740      * isolated to the main migration thread while multifd channels
741      * process the aligned data with O_DIRECT enabled.
742      */
743     return s->parameters.direct_io &&
744         s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM] &&
745         s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
746 }
747 
migrate_downtime_limit(void)748 uint64_t migrate_downtime_limit(void)
749 {
750     MigrationState *s = migrate_get_current();
751 
752     return s->parameters.downtime_limit;
753 }
754 
migrate_max_cpu_throttle(void)755 uint8_t migrate_max_cpu_throttle(void)
756 {
757     MigrationState *s = migrate_get_current();
758 
759     return s->parameters.max_cpu_throttle;
760 }
761 
migrate_max_bandwidth(void)762 uint64_t migrate_max_bandwidth(void)
763 {
764     MigrationState *s = migrate_get_current();
765 
766     return s->parameters.max_bandwidth;
767 }
768 
migrate_avail_switchover_bandwidth(void)769 uint64_t migrate_avail_switchover_bandwidth(void)
770 {
771     MigrationState *s = migrate_get_current();
772 
773     return s->parameters.avail_switchover_bandwidth;
774 }
775 
migrate_max_postcopy_bandwidth(void)776 uint64_t migrate_max_postcopy_bandwidth(void)
777 {
778     MigrationState *s = migrate_get_current();
779 
780     return s->parameters.max_postcopy_bandwidth;
781 }
782 
migrate_mode(void)783 MigMode migrate_mode(void)
784 {
785     MigMode mode = cpr_get_incoming_mode();
786 
787     if (mode == MIG_MODE_NONE) {
788         mode = migrate_get_current()->parameters.mode;
789     }
790 
791     assert(mode >= 0 && mode < MIG_MODE__MAX);
792     return mode;
793 }
794 
migrate_multifd_channels(void)795 int migrate_multifd_channels(void)
796 {
797     MigrationState *s = migrate_get_current();
798 
799     return s->parameters.multifd_channels;
800 }
801 
migrate_multifd_compression(void)802 MultiFDCompression migrate_multifd_compression(void)
803 {
804     MigrationState *s = migrate_get_current();
805 
806     assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
807     return s->parameters.multifd_compression;
808 }
809 
migrate_multifd_zlib_level(void)810 int migrate_multifd_zlib_level(void)
811 {
812     MigrationState *s = migrate_get_current();
813 
814     return s->parameters.multifd_zlib_level;
815 }
816 
migrate_multifd_qatzip_level(void)817 int migrate_multifd_qatzip_level(void)
818 {
819     MigrationState *s = migrate_get_current();
820 
821     return s->parameters.multifd_qatzip_level;
822 }
823 
migrate_multifd_zstd_level(void)824 int migrate_multifd_zstd_level(void)
825 {
826     MigrationState *s = migrate_get_current();
827 
828     return s->parameters.multifd_zstd_level;
829 }
830 
migrate_throttle_trigger_threshold(void)831 uint8_t migrate_throttle_trigger_threshold(void)
832 {
833     MigrationState *s = migrate_get_current();
834 
835     return s->parameters.throttle_trigger_threshold;
836 }
837 
migrate_tls_authz(void)838 const char *migrate_tls_authz(void)
839 {
840     MigrationState *s = migrate_get_current();
841 
842     return s->parameters.tls_authz;
843 }
844 
migrate_tls_creds(void)845 const char *migrate_tls_creds(void)
846 {
847     MigrationState *s = migrate_get_current();
848 
849     return s->parameters.tls_creds;
850 }
851 
migrate_tls_hostname(void)852 const char *migrate_tls_hostname(void)
853 {
854     MigrationState *s = migrate_get_current();
855 
856     return s->parameters.tls_hostname;
857 }
858 
migrate_vcpu_dirty_limit_period(void)859 uint64_t migrate_vcpu_dirty_limit_period(void)
860 {
861     MigrationState *s = migrate_get_current();
862 
863     return s->parameters.x_vcpu_dirty_limit_period;
864 }
865 
migrate_xbzrle_cache_size(void)866 uint64_t migrate_xbzrle_cache_size(void)
867 {
868     MigrationState *s = migrate_get_current();
869 
870     return s->parameters.xbzrle_cache_size;
871 }
872 
migrate_zero_page_detection(void)873 ZeroPageDetection migrate_zero_page_detection(void)
874 {
875     MigrationState *s = migrate_get_current();
876 
877     return s->parameters.zero_page_detection;
878 }
879 
880 /* parameters helpers */
881 
migrate_announce_params(void)882 AnnounceParameters *migrate_announce_params(void)
883 {
884     static AnnounceParameters ap;
885 
886     MigrationState *s = migrate_get_current();
887 
888     ap.initial = s->parameters.announce_initial;
889     ap.max = s->parameters.announce_max;
890     ap.rounds = s->parameters.announce_rounds;
891     ap.step = s->parameters.announce_step;
892 
893     return &ap;
894 }
895 
qmp_query_migrate_parameters(Error ** errp)896 MigrationParameters *qmp_query_migrate_parameters(Error **errp)
897 {
898     MigrationParameters *params;
899     MigrationState *s = migrate_get_current();
900 
901     /* TODO use QAPI_CLONE() instead of duplicating it inline */
902     params = g_malloc0(sizeof(*params));
903     params->has_throttle_trigger_threshold = true;
904     params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
905     params->has_cpu_throttle_initial = true;
906     params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
907     params->has_cpu_throttle_increment = true;
908     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
909     params->has_cpu_throttle_tailslow = true;
910     params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
911     params->tls_creds = g_strdup(s->parameters.tls_creds);
912     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
913     params->tls_authz = g_strdup(s->parameters.tls_authz ?
914                                  s->parameters.tls_authz : "");
915     params->has_max_bandwidth = true;
916     params->max_bandwidth = s->parameters.max_bandwidth;
917     params->has_avail_switchover_bandwidth = true;
918     params->avail_switchover_bandwidth = s->parameters.avail_switchover_bandwidth;
919     params->has_downtime_limit = true;
920     params->downtime_limit = s->parameters.downtime_limit;
921     params->has_x_checkpoint_delay = true;
922     params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
923     params->has_multifd_channels = true;
924     params->multifd_channels = s->parameters.multifd_channels;
925     params->has_multifd_compression = true;
926     params->multifd_compression = s->parameters.multifd_compression;
927     params->has_multifd_zlib_level = true;
928     params->multifd_zlib_level = s->parameters.multifd_zlib_level;
929     params->has_multifd_qatzip_level = true;
930     params->multifd_qatzip_level = s->parameters.multifd_qatzip_level;
931     params->has_multifd_zstd_level = true;
932     params->multifd_zstd_level = s->parameters.multifd_zstd_level;
933     params->has_xbzrle_cache_size = true;
934     params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
935     params->has_max_postcopy_bandwidth = true;
936     params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
937     params->has_max_cpu_throttle = true;
938     params->max_cpu_throttle = s->parameters.max_cpu_throttle;
939     params->has_announce_initial = true;
940     params->announce_initial = s->parameters.announce_initial;
941     params->has_announce_max = true;
942     params->announce_max = s->parameters.announce_max;
943     params->has_announce_rounds = true;
944     params->announce_rounds = s->parameters.announce_rounds;
945     params->has_announce_step = true;
946     params->announce_step = s->parameters.announce_step;
947 
948     if (s->parameters.has_block_bitmap_mapping) {
949         params->has_block_bitmap_mapping = true;
950         params->block_bitmap_mapping =
951             QAPI_CLONE(BitmapMigrationNodeAliasList,
952                        s->parameters.block_bitmap_mapping);
953     }
954 
955     params->has_x_vcpu_dirty_limit_period = true;
956     params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period;
957     params->has_vcpu_dirty_limit = true;
958     params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit;
959     params->has_mode = true;
960     params->mode = s->parameters.mode;
961     params->has_zero_page_detection = true;
962     params->zero_page_detection = s->parameters.zero_page_detection;
963     params->has_direct_io = true;
964     params->direct_io = s->parameters.direct_io;
965 
966     return params;
967 }
968 
migrate_params_init(MigrationParameters * params)969 void migrate_params_init(MigrationParameters *params)
970 {
971     params->tls_hostname = g_strdup("");
972     params->tls_creds = g_strdup("");
973 
974     /* Set has_* up only for parameter checks */
975     params->has_throttle_trigger_threshold = true;
976     params->has_cpu_throttle_initial = true;
977     params->has_cpu_throttle_increment = true;
978     params->has_cpu_throttle_tailslow = true;
979     params->has_max_bandwidth = true;
980     params->has_downtime_limit = true;
981     params->has_x_checkpoint_delay = true;
982     params->has_multifd_channels = true;
983     params->has_multifd_compression = true;
984     params->has_multifd_zlib_level = true;
985     params->has_multifd_qatzip_level = true;
986     params->has_multifd_zstd_level = true;
987     params->has_xbzrle_cache_size = true;
988     params->has_max_postcopy_bandwidth = true;
989     params->has_max_cpu_throttle = true;
990     params->has_announce_initial = true;
991     params->has_announce_max = true;
992     params->has_announce_rounds = true;
993     params->has_announce_step = true;
994     params->has_x_vcpu_dirty_limit_period = true;
995     params->has_vcpu_dirty_limit = true;
996     params->has_mode = true;
997     params->has_zero_page_detection = true;
998     params->has_direct_io = true;
999 }
1000 
1001 /*
1002  * Check whether the parameters are valid. Error will be put into errp
1003  * (if provided). Return true if valid, otherwise false.
1004  */
migrate_params_check(MigrationParameters * params,Error ** errp)1005 bool migrate_params_check(MigrationParameters *params, Error **errp)
1006 {
1007     ERRP_GUARD();
1008 
1009     if (params->has_throttle_trigger_threshold &&
1010         (params->throttle_trigger_threshold < 1 ||
1011          params->throttle_trigger_threshold > 100)) {
1012         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1013                    "throttle_trigger_threshold",
1014                    "an integer in the range of 1 to 100");
1015         return false;
1016     }
1017 
1018     if (params->has_cpu_throttle_initial &&
1019         (params->cpu_throttle_initial < 1 ||
1020          params->cpu_throttle_initial > 99)) {
1021         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1022                    "cpu_throttle_initial",
1023                    "an integer in the range of 1 to 99");
1024         return false;
1025     }
1026 
1027     if (params->has_cpu_throttle_increment &&
1028         (params->cpu_throttle_increment < 1 ||
1029          params->cpu_throttle_increment > 99)) {
1030         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1031                    "cpu_throttle_increment",
1032                    "an integer in the range of 1 to 99");
1033         return false;
1034     }
1035 
1036     if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
1037         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1038                    "max_bandwidth",
1039                    "an integer in the range of 0 to "stringify(SIZE_MAX)
1040                    " bytes/second");
1041         return false;
1042     }
1043 
1044     if (params->has_avail_switchover_bandwidth &&
1045         (params->avail_switchover_bandwidth > SIZE_MAX)) {
1046         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1047                    "avail_switchover_bandwidth",
1048                    "an integer in the range of 0 to "stringify(SIZE_MAX)
1049                    " bytes/second");
1050         return false;
1051     }
1052 
1053     if (params->has_downtime_limit &&
1054         (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
1055         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1056                    "downtime_limit",
1057                    "an integer in the range of 0 to "
1058                     stringify(MAX_MIGRATE_DOWNTIME)" ms");
1059         return false;
1060     }
1061 
1062     /* x_checkpoint_delay is now always positive */
1063 
1064     if (params->has_multifd_channels && (params->multifd_channels < 1)) {
1065         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1066                    "multifd_channels",
1067                    "a value between 1 and 255");
1068         return false;
1069     }
1070 
1071     if (params->has_multifd_zlib_level &&
1072         (params->multifd_zlib_level > 9)) {
1073         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
1074                    "a value between 0 and 9");
1075         return false;
1076     }
1077 
1078     if (params->has_multifd_qatzip_level &&
1079         ((params->multifd_qatzip_level > 9) ||
1080         (params->multifd_qatzip_level < 1))) {
1081         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_qatzip_level",
1082                    "a value between 1 and 9");
1083         return false;
1084     }
1085 
1086     if (params->has_multifd_zstd_level &&
1087         (params->multifd_zstd_level > 20)) {
1088         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
1089                    "a value between 0 and 20");
1090         return false;
1091     }
1092 
1093     if (params->has_xbzrle_cache_size &&
1094         (params->xbzrle_cache_size < qemu_target_page_size() ||
1095          !is_power_of_2(params->xbzrle_cache_size))) {
1096         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1097                    "xbzrle_cache_size",
1098                    "a power of two no less than the target page size");
1099         return false;
1100     }
1101 
1102     if (params->has_max_cpu_throttle &&
1103         (params->max_cpu_throttle < params->cpu_throttle_initial ||
1104          params->max_cpu_throttle > 99)) {
1105         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1106                    "max_cpu_throttle",
1107                    "an integer in the range of cpu_throttle_initial to 99");
1108         return false;
1109     }
1110 
1111     if (params->has_announce_initial &&
1112         params->announce_initial > 100000) {
1113         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1114                    "announce_initial",
1115                    "a value between 0 and 100000");
1116         return false;
1117     }
1118     if (params->has_announce_max &&
1119         params->announce_max > 100000) {
1120         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1121                    "announce_max",
1122                    "a value between 0 and 100000");
1123        return false;
1124     }
1125     if (params->has_announce_rounds &&
1126         params->announce_rounds > 1000) {
1127         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1128                    "announce_rounds",
1129                    "a value between 0 and 1000");
1130        return false;
1131     }
1132     if (params->has_announce_step &&
1133         (params->announce_step < 1 ||
1134         params->announce_step > 10000)) {
1135         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1136                    "announce_step",
1137                    "a value between 0 and 10000");
1138        return false;
1139     }
1140 
1141     if (params->has_block_bitmap_mapping &&
1142         !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
1143         error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
1144         return false;
1145     }
1146 
1147 #ifdef CONFIG_LINUX
1148     if (migrate_zero_copy_send() &&
1149         ((params->has_multifd_compression && params->multifd_compression) ||
1150          (params->tls_creds && *params->tls_creds))) {
1151         error_setg(errp,
1152                    "Zero copy only available for non-compressed non-TLS multifd migration");
1153         return false;
1154     }
1155 #endif
1156 
1157     if (migrate_mapped_ram() &&
1158         (migrate_multifd_compression() || migrate_tls())) {
1159         error_setg(errp,
1160                    "Mapped-ram only available for non-compressed non-TLS multifd migration");
1161         return false;
1162     }
1163 
1164     if (params->has_x_vcpu_dirty_limit_period &&
1165         (params->x_vcpu_dirty_limit_period < 1 ||
1166          params->x_vcpu_dirty_limit_period > 1000)) {
1167         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1168                    "x-vcpu-dirty-limit-period",
1169                    "a value between 1 and 1000");
1170         return false;
1171     }
1172 
1173     if (params->has_vcpu_dirty_limit &&
1174         (params->vcpu_dirty_limit < 1)) {
1175         error_setg(errp,
1176                    "Parameter 'vcpu_dirty_limit' must be greater than 1 MB/s");
1177         return false;
1178     }
1179 
1180     if (params->has_direct_io && params->direct_io && !qemu_has_direct_io()) {
1181         error_setg(errp, "No build-time support for direct-io");
1182         return false;
1183     }
1184 
1185     return true;
1186 }
1187 
migrate_params_test_apply(MigrateSetParameters * params,MigrationParameters * dest)1188 static void migrate_params_test_apply(MigrateSetParameters *params,
1189                                       MigrationParameters *dest)
1190 {
1191     *dest = migrate_get_current()->parameters;
1192 
1193     /* TODO use QAPI_CLONE() instead of duplicating it inline */
1194 
1195     if (params->has_throttle_trigger_threshold) {
1196         dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
1197     }
1198 
1199     if (params->has_cpu_throttle_initial) {
1200         dest->cpu_throttle_initial = params->cpu_throttle_initial;
1201     }
1202 
1203     if (params->has_cpu_throttle_increment) {
1204         dest->cpu_throttle_increment = params->cpu_throttle_increment;
1205     }
1206 
1207     if (params->has_cpu_throttle_tailslow) {
1208         dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
1209     }
1210 
1211     if (params->tls_creds) {
1212         assert(params->tls_creds->type == QTYPE_QSTRING);
1213         dest->tls_creds = params->tls_creds->u.s;
1214     }
1215 
1216     if (params->tls_hostname) {
1217         assert(params->tls_hostname->type == QTYPE_QSTRING);
1218         dest->tls_hostname = params->tls_hostname->u.s;
1219     }
1220 
1221     if (params->tls_authz) {
1222         assert(params->tls_authz->type == QTYPE_QSTRING);
1223         dest->tls_authz = params->tls_authz->u.s;
1224     }
1225 
1226     if (params->has_max_bandwidth) {
1227         dest->max_bandwidth = params->max_bandwidth;
1228     }
1229 
1230     if (params->has_avail_switchover_bandwidth) {
1231         dest->avail_switchover_bandwidth = params->avail_switchover_bandwidth;
1232     }
1233 
1234     if (params->has_downtime_limit) {
1235         dest->downtime_limit = params->downtime_limit;
1236     }
1237 
1238     if (params->has_x_checkpoint_delay) {
1239         dest->x_checkpoint_delay = params->x_checkpoint_delay;
1240     }
1241 
1242     if (params->has_multifd_channels) {
1243         dest->multifd_channels = params->multifd_channels;
1244     }
1245     if (params->has_multifd_compression) {
1246         dest->multifd_compression = params->multifd_compression;
1247     }
1248     if (params->has_multifd_qatzip_level) {
1249         dest->multifd_qatzip_level = params->multifd_qatzip_level;
1250     }
1251     if (params->has_multifd_zlib_level) {
1252         dest->multifd_zlib_level = params->multifd_zlib_level;
1253     }
1254     if (params->has_multifd_zstd_level) {
1255         dest->multifd_zstd_level = params->multifd_zstd_level;
1256     }
1257     if (params->has_xbzrle_cache_size) {
1258         dest->xbzrle_cache_size = params->xbzrle_cache_size;
1259     }
1260     if (params->has_max_postcopy_bandwidth) {
1261         dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
1262     }
1263     if (params->has_max_cpu_throttle) {
1264         dest->max_cpu_throttle = params->max_cpu_throttle;
1265     }
1266     if (params->has_announce_initial) {
1267         dest->announce_initial = params->announce_initial;
1268     }
1269     if (params->has_announce_max) {
1270         dest->announce_max = params->announce_max;
1271     }
1272     if (params->has_announce_rounds) {
1273         dest->announce_rounds = params->announce_rounds;
1274     }
1275     if (params->has_announce_step) {
1276         dest->announce_step = params->announce_step;
1277     }
1278 
1279     if (params->has_block_bitmap_mapping) {
1280         dest->has_block_bitmap_mapping = true;
1281         dest->block_bitmap_mapping = params->block_bitmap_mapping;
1282     }
1283 
1284     if (params->has_x_vcpu_dirty_limit_period) {
1285         dest->x_vcpu_dirty_limit_period =
1286             params->x_vcpu_dirty_limit_period;
1287     }
1288     if (params->has_vcpu_dirty_limit) {
1289         dest->vcpu_dirty_limit = params->vcpu_dirty_limit;
1290     }
1291 
1292     if (params->has_mode) {
1293         dest->mode = params->mode;
1294     }
1295 
1296     if (params->has_zero_page_detection) {
1297         dest->zero_page_detection = params->zero_page_detection;
1298     }
1299 
1300     if (params->has_direct_io) {
1301         dest->direct_io = params->direct_io;
1302     }
1303 }
1304 
migrate_params_apply(MigrateSetParameters * params,Error ** errp)1305 static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
1306 {
1307     MigrationState *s = migrate_get_current();
1308 
1309     /* TODO use QAPI_CLONE() instead of duplicating it inline */
1310 
1311     if (params->has_throttle_trigger_threshold) {
1312         s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
1313     }
1314 
1315     if (params->has_cpu_throttle_initial) {
1316         s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
1317     }
1318 
1319     if (params->has_cpu_throttle_increment) {
1320         s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
1321     }
1322 
1323     if (params->has_cpu_throttle_tailslow) {
1324         s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
1325     }
1326 
1327     if (params->tls_creds) {
1328         g_free(s->parameters.tls_creds);
1329         assert(params->tls_creds->type == QTYPE_QSTRING);
1330         s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
1331     }
1332 
1333     if (params->tls_hostname) {
1334         g_free(s->parameters.tls_hostname);
1335         assert(params->tls_hostname->type == QTYPE_QSTRING);
1336         s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
1337     }
1338 
1339     if (params->tls_authz) {
1340         g_free(s->parameters.tls_authz);
1341         assert(params->tls_authz->type == QTYPE_QSTRING);
1342         s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
1343     }
1344 
1345     if (params->has_max_bandwidth) {
1346         s->parameters.max_bandwidth = params->max_bandwidth;
1347         if (s->to_dst_file && !migration_in_postcopy()) {
1348             migration_rate_set(s->parameters.max_bandwidth);
1349         }
1350     }
1351 
1352     if (params->has_avail_switchover_bandwidth) {
1353         s->parameters.avail_switchover_bandwidth = params->avail_switchover_bandwidth;
1354     }
1355 
1356     if (params->has_downtime_limit) {
1357         s->parameters.downtime_limit = params->downtime_limit;
1358     }
1359 
1360     if (params->has_x_checkpoint_delay) {
1361         s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
1362         colo_checkpoint_delay_set();
1363     }
1364 
1365     if (params->has_multifd_channels) {
1366         s->parameters.multifd_channels = params->multifd_channels;
1367     }
1368     if (params->has_multifd_compression) {
1369         s->parameters.multifd_compression = params->multifd_compression;
1370     }
1371     if (params->has_multifd_qatzip_level) {
1372         s->parameters.multifd_qatzip_level = params->multifd_qatzip_level;
1373     }
1374     if (params->has_multifd_zlib_level) {
1375         s->parameters.multifd_zlib_level = params->multifd_zlib_level;
1376     }
1377     if (params->has_multifd_zstd_level) {
1378         s->parameters.multifd_zstd_level = params->multifd_zstd_level;
1379     }
1380     if (params->has_xbzrle_cache_size) {
1381         s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
1382         xbzrle_cache_resize(params->xbzrle_cache_size, errp);
1383     }
1384     if (params->has_max_postcopy_bandwidth) {
1385         s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
1386         if (s->to_dst_file && migration_in_postcopy()) {
1387             migration_rate_set(s->parameters.max_postcopy_bandwidth);
1388         }
1389     }
1390     if (params->has_max_cpu_throttle) {
1391         s->parameters.max_cpu_throttle = params->max_cpu_throttle;
1392     }
1393     if (params->has_announce_initial) {
1394         s->parameters.announce_initial = params->announce_initial;
1395     }
1396     if (params->has_announce_max) {
1397         s->parameters.announce_max = params->announce_max;
1398     }
1399     if (params->has_announce_rounds) {
1400         s->parameters.announce_rounds = params->announce_rounds;
1401     }
1402     if (params->has_announce_step) {
1403         s->parameters.announce_step = params->announce_step;
1404     }
1405 
1406     if (params->has_block_bitmap_mapping) {
1407         qapi_free_BitmapMigrationNodeAliasList(
1408             s->parameters.block_bitmap_mapping);
1409 
1410         s->parameters.has_block_bitmap_mapping = true;
1411         s->parameters.block_bitmap_mapping =
1412             QAPI_CLONE(BitmapMigrationNodeAliasList,
1413                        params->block_bitmap_mapping);
1414     }
1415 
1416     if (params->has_x_vcpu_dirty_limit_period) {
1417         s->parameters.x_vcpu_dirty_limit_period =
1418             params->x_vcpu_dirty_limit_period;
1419     }
1420     if (params->has_vcpu_dirty_limit) {
1421         s->parameters.vcpu_dirty_limit = params->vcpu_dirty_limit;
1422     }
1423 
1424     if (params->has_mode) {
1425         s->parameters.mode = params->mode;
1426     }
1427 
1428     if (params->has_zero_page_detection) {
1429         s->parameters.zero_page_detection = params->zero_page_detection;
1430     }
1431 
1432     if (params->has_direct_io) {
1433         s->parameters.direct_io = params->direct_io;
1434     }
1435 }
1436 
qmp_migrate_set_parameters(MigrateSetParameters * params,Error ** errp)1437 void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
1438 {
1439     MigrationParameters tmp;
1440 
1441     /* TODO Rewrite "" to null instead for all three tls_* parameters */
1442     if (params->tls_creds
1443         && params->tls_creds->type == QTYPE_QNULL) {
1444         qobject_unref(params->tls_creds->u.n);
1445         params->tls_creds->type = QTYPE_QSTRING;
1446         params->tls_creds->u.s = strdup("");
1447     }
1448     if (params->tls_hostname
1449         && params->tls_hostname->type == QTYPE_QNULL) {
1450         qobject_unref(params->tls_hostname->u.n);
1451         params->tls_hostname->type = QTYPE_QSTRING;
1452         params->tls_hostname->u.s = strdup("");
1453     }
1454     if (params->tls_authz
1455         && params->tls_authz->type == QTYPE_QNULL) {
1456         qobject_unref(params->tls_authz->u.n);
1457         params->tls_authz->type = QTYPE_QSTRING;
1458         params->tls_authz->u.s = strdup("");
1459     }
1460 
1461     migrate_params_test_apply(params, &tmp);
1462 
1463     if (!migrate_params_check(&tmp, errp)) {
1464         /* Invalid parameter */
1465         return;
1466     }
1467 
1468     migrate_params_apply(params, errp);
1469 }
1470