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
514 if (new_caps[MIGRATION_CAPABILITY_BACKGROUND_SNAPSHOT]) {
515 WriteTrackingSupport wt_support;
516 int idx;
517 /*
518 * Check if 'background-snapshot' capability is supported by
519 * host kernel and compatible with guest memory configuration.
520 */
521 wt_support = migrate_query_write_tracking();
522 if (wt_support < WT_SUPPORT_AVAILABLE) {
523 error_setg(errp, "Background-snapshot is not supported by host kernel");
524 return false;
525 }
526 if (wt_support < WT_SUPPORT_COMPATIBLE) {
527 error_setg(errp, "Background-snapshot is not compatible "
528 "with guest memory configuration");
529 return false;
530 }
531
532 /*
533 * Check if there are any migration capabilities
534 * incompatible with 'background-snapshot'.
535 */
536 for (idx = 0; idx < check_caps_background_snapshot.size; idx++) {
537 int incomp_cap = check_caps_background_snapshot.caps[idx];
538 if (new_caps[incomp_cap]) {
539 error_setg(errp,
540 "Background-snapshot is not compatible with %s",
541 MigrationCapability_str(incomp_cap));
542 return false;
543 }
544 }
545 }
546
547 #ifdef CONFIG_LINUX
548 if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND] &&
549 (!new_caps[MIGRATION_CAPABILITY_MULTIFD] ||
550 new_caps[MIGRATION_CAPABILITY_XBZRLE] ||
551 migrate_multifd_compression() ||
552 migrate_tls())) {
553 error_setg(errp,
554 "Zero copy only available for non-compressed non-TLS multifd migration");
555 return false;
556 }
557 #else
558 if (new_caps[MIGRATION_CAPABILITY_ZERO_COPY_SEND]) {
559 error_setg(errp,
560 "Zero copy currently only available on Linux");
561 return false;
562 }
563 #endif
564
565 if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT]) {
566 if (!new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
567 error_setg(errp, "Postcopy preempt requires postcopy-ram");
568 return false;
569 }
570
571 if (!migrate_postcopy_preempt() && migrate_incoming_started()) {
572 error_setg(errp,
573 "Postcopy preempt must be set before incoming starts");
574 return false;
575 }
576 }
577
578 if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
579 if (!migrate_multifd() && migrate_incoming_started()) {
580 error_setg(errp, "Multifd must be set before incoming starts");
581 return false;
582 }
583 }
584
585 if (new_caps[MIGRATION_CAPABILITY_SWITCHOVER_ACK]) {
586 if (!new_caps[MIGRATION_CAPABILITY_RETURN_PATH]) {
587 error_setg(errp, "Capability 'switchover-ack' requires capability "
588 "'return-path'");
589 return false;
590 }
591 }
592 if (new_caps[MIGRATION_CAPABILITY_DIRTY_LIMIT]) {
593 if (new_caps[MIGRATION_CAPABILITY_AUTO_CONVERGE]) {
594 error_setg(errp, "dirty-limit conflicts with auto-converge"
595 " either of then available currently");
596 return false;
597 }
598
599 if (!kvm_enabled() || !kvm_dirty_ring_enabled()) {
600 error_setg(errp, "dirty-limit requires KVM with accelerator"
601 " property 'dirty-ring-size' set");
602 return false;
603 }
604 }
605
606 if (new_caps[MIGRATION_CAPABILITY_MULTIFD]) {
607 if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
608 error_setg(errp, "Multifd is not compatible with xbzrle");
609 return false;
610 }
611 }
612
613 if (new_caps[MIGRATION_CAPABILITY_MAPPED_RAM]) {
614 if (new_caps[MIGRATION_CAPABILITY_XBZRLE]) {
615 error_setg(errp,
616 "Mapped-ram migration is incompatible with xbzrle");
617 return false;
618 }
619
620 if (new_caps[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
621 error_setg(errp,
622 "Mapped-ram migration is incompatible with postcopy");
623 return false;
624 }
625 }
626
627 /*
628 * On destination side, check the cases that capability is being set
629 * after incoming thread has started.
630 */
631 if (migrate_rdma() && !migrate_rdma_caps_check(new_caps, errp)) {
632 return false;
633 }
634 return true;
635 }
636
qmp_query_migrate_capabilities(Error ** errp)637 MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
638 {
639 MigrationCapabilityStatusList *head = NULL, **tail = &head;
640 MigrationCapabilityStatus *caps;
641 MigrationState *s = migrate_get_current();
642 int i;
643
644 for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
645 caps = g_malloc0(sizeof(*caps));
646 caps->capability = i;
647 caps->state = s->capabilities[i];
648 QAPI_LIST_APPEND(tail, caps);
649 }
650
651 return head;
652 }
653
qmp_migrate_set_capabilities(MigrationCapabilityStatusList * params,Error ** errp)654 void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
655 Error **errp)
656 {
657 MigrationState *s = migrate_get_current();
658 MigrationCapabilityStatusList *cap;
659 bool new_caps[MIGRATION_CAPABILITY__MAX];
660
661 if (migration_is_running() || migration_in_colo_state()) {
662 error_setg(errp, "There's a migration process in progress");
663 return;
664 }
665
666 memcpy(new_caps, s->capabilities, sizeof(new_caps));
667 for (cap = params; cap; cap = cap->next) {
668 new_caps[cap->value->capability] = cap->value->state;
669 }
670
671 if (!migrate_caps_check(s->capabilities, new_caps, errp)) {
672 return;
673 }
674
675 for (cap = params; cap; cap = cap->next) {
676 s->capabilities[cap->value->capability] = cap->value->state;
677 }
678 }
679
680 /* parameters */
681
migrate_block_bitmap_mapping(void)682 const BitmapMigrationNodeAliasList *migrate_block_bitmap_mapping(void)
683 {
684 MigrationState *s = migrate_get_current();
685
686 return s->parameters.block_bitmap_mapping;
687 }
688
migrate_has_block_bitmap_mapping(void)689 bool migrate_has_block_bitmap_mapping(void)
690 {
691 MigrationState *s = migrate_get_current();
692
693 return s->parameters.has_block_bitmap_mapping;
694 }
695
migrate_checkpoint_delay(void)696 uint32_t migrate_checkpoint_delay(void)
697 {
698 MigrationState *s = migrate_get_current();
699
700 return s->parameters.x_checkpoint_delay;
701 }
702
migrate_cpu_throttle_increment(void)703 uint8_t migrate_cpu_throttle_increment(void)
704 {
705 MigrationState *s = migrate_get_current();
706
707 return s->parameters.cpu_throttle_increment;
708 }
709
migrate_cpu_throttle_initial(void)710 uint8_t migrate_cpu_throttle_initial(void)
711 {
712 MigrationState *s = migrate_get_current();
713
714 return s->parameters.cpu_throttle_initial;
715 }
716
migrate_cpu_throttle_tailslow(void)717 bool migrate_cpu_throttle_tailslow(void)
718 {
719 MigrationState *s = migrate_get_current();
720
721 return s->parameters.cpu_throttle_tailslow;
722 }
723
migrate_direct_io(void)724 bool migrate_direct_io(void)
725 {
726 MigrationState *s = migrate_get_current();
727
728 /*
729 * O_DIRECT is only supported with mapped-ram and multifd.
730 *
731 * mapped-ram is needed because filesystems impose restrictions on
732 * O_DIRECT IO alignment (see MAPPED_RAM_FILE_OFFSET_ALIGNMENT).
733 *
734 * multifd is needed to keep the unaligned portion of the stream
735 * isolated to the main migration thread while multifd channels
736 * process the aligned data with O_DIRECT enabled.
737 */
738 return s->parameters.direct_io &&
739 s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM] &&
740 s->capabilities[MIGRATION_CAPABILITY_MULTIFD];
741 }
742
migrate_downtime_limit(void)743 uint64_t migrate_downtime_limit(void)
744 {
745 MigrationState *s = migrate_get_current();
746
747 return s->parameters.downtime_limit;
748 }
749
migrate_max_cpu_throttle(void)750 uint8_t migrate_max_cpu_throttle(void)
751 {
752 MigrationState *s = migrate_get_current();
753
754 return s->parameters.max_cpu_throttle;
755 }
756
migrate_max_bandwidth(void)757 uint64_t migrate_max_bandwidth(void)
758 {
759 MigrationState *s = migrate_get_current();
760
761 return s->parameters.max_bandwidth;
762 }
763
migrate_avail_switchover_bandwidth(void)764 uint64_t migrate_avail_switchover_bandwidth(void)
765 {
766 MigrationState *s = migrate_get_current();
767
768 return s->parameters.avail_switchover_bandwidth;
769 }
770
migrate_max_postcopy_bandwidth(void)771 uint64_t migrate_max_postcopy_bandwidth(void)
772 {
773 MigrationState *s = migrate_get_current();
774
775 return s->parameters.max_postcopy_bandwidth;
776 }
777
migrate_mode(void)778 MigMode migrate_mode(void)
779 {
780 MigMode mode = cpr_get_incoming_mode();
781
782 if (mode == MIG_MODE_NONE) {
783 mode = migrate_get_current()->parameters.mode;
784 }
785
786 assert(mode >= 0 && mode < MIG_MODE__MAX);
787 return mode;
788 }
789
migrate_multifd_channels(void)790 int migrate_multifd_channels(void)
791 {
792 MigrationState *s = migrate_get_current();
793
794 return s->parameters.multifd_channels;
795 }
796
migrate_multifd_compression(void)797 MultiFDCompression migrate_multifd_compression(void)
798 {
799 MigrationState *s = migrate_get_current();
800
801 assert(s->parameters.multifd_compression < MULTIFD_COMPRESSION__MAX);
802 return s->parameters.multifd_compression;
803 }
804
migrate_multifd_zlib_level(void)805 int migrate_multifd_zlib_level(void)
806 {
807 MigrationState *s = migrate_get_current();
808
809 return s->parameters.multifd_zlib_level;
810 }
811
migrate_multifd_qatzip_level(void)812 int migrate_multifd_qatzip_level(void)
813 {
814 MigrationState *s = migrate_get_current();
815
816 return s->parameters.multifd_qatzip_level;
817 }
818
migrate_multifd_zstd_level(void)819 int migrate_multifd_zstd_level(void)
820 {
821 MigrationState *s = migrate_get_current();
822
823 return s->parameters.multifd_zstd_level;
824 }
825
migrate_throttle_trigger_threshold(void)826 uint8_t migrate_throttle_trigger_threshold(void)
827 {
828 MigrationState *s = migrate_get_current();
829
830 return s->parameters.throttle_trigger_threshold;
831 }
832
migrate_tls_authz(void)833 const char *migrate_tls_authz(void)
834 {
835 MigrationState *s = migrate_get_current();
836
837 return s->parameters.tls_authz;
838 }
839
migrate_tls_creds(void)840 const char *migrate_tls_creds(void)
841 {
842 MigrationState *s = migrate_get_current();
843
844 return s->parameters.tls_creds;
845 }
846
migrate_tls_hostname(void)847 const char *migrate_tls_hostname(void)
848 {
849 MigrationState *s = migrate_get_current();
850
851 return s->parameters.tls_hostname;
852 }
853
migrate_vcpu_dirty_limit_period(void)854 uint64_t migrate_vcpu_dirty_limit_period(void)
855 {
856 MigrationState *s = migrate_get_current();
857
858 return s->parameters.x_vcpu_dirty_limit_period;
859 }
860
migrate_xbzrle_cache_size(void)861 uint64_t migrate_xbzrle_cache_size(void)
862 {
863 MigrationState *s = migrate_get_current();
864
865 return s->parameters.xbzrle_cache_size;
866 }
867
migrate_zero_page_detection(void)868 ZeroPageDetection migrate_zero_page_detection(void)
869 {
870 MigrationState *s = migrate_get_current();
871
872 return s->parameters.zero_page_detection;
873 }
874
875 /* parameters helpers */
876
migrate_announce_params(void)877 AnnounceParameters *migrate_announce_params(void)
878 {
879 static AnnounceParameters ap;
880
881 MigrationState *s = migrate_get_current();
882
883 ap.initial = s->parameters.announce_initial;
884 ap.max = s->parameters.announce_max;
885 ap.rounds = s->parameters.announce_rounds;
886 ap.step = s->parameters.announce_step;
887
888 return ≈
889 }
890
qmp_query_migrate_parameters(Error ** errp)891 MigrationParameters *qmp_query_migrate_parameters(Error **errp)
892 {
893 MigrationParameters *params;
894 MigrationState *s = migrate_get_current();
895
896 /* TODO use QAPI_CLONE() instead of duplicating it inline */
897 params = g_malloc0(sizeof(*params));
898 params->has_throttle_trigger_threshold = true;
899 params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold;
900 params->has_cpu_throttle_initial = true;
901 params->cpu_throttle_initial = s->parameters.cpu_throttle_initial;
902 params->has_cpu_throttle_increment = true;
903 params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
904 params->has_cpu_throttle_tailslow = true;
905 params->cpu_throttle_tailslow = s->parameters.cpu_throttle_tailslow;
906 params->tls_creds = g_strdup(s->parameters.tls_creds);
907 params->tls_hostname = g_strdup(s->parameters.tls_hostname);
908 params->tls_authz = g_strdup(s->parameters.tls_authz ?
909 s->parameters.tls_authz : "");
910 params->has_max_bandwidth = true;
911 params->max_bandwidth = s->parameters.max_bandwidth;
912 params->has_avail_switchover_bandwidth = true;
913 params->avail_switchover_bandwidth = s->parameters.avail_switchover_bandwidth;
914 params->has_downtime_limit = true;
915 params->downtime_limit = s->parameters.downtime_limit;
916 params->has_x_checkpoint_delay = true;
917 params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
918 params->has_multifd_channels = true;
919 params->multifd_channels = s->parameters.multifd_channels;
920 params->has_multifd_compression = true;
921 params->multifd_compression = s->parameters.multifd_compression;
922 params->has_multifd_zlib_level = true;
923 params->multifd_zlib_level = s->parameters.multifd_zlib_level;
924 params->has_multifd_qatzip_level = true;
925 params->multifd_qatzip_level = s->parameters.multifd_qatzip_level;
926 params->has_multifd_zstd_level = true;
927 params->multifd_zstd_level = s->parameters.multifd_zstd_level;
928 params->has_xbzrle_cache_size = true;
929 params->xbzrle_cache_size = s->parameters.xbzrle_cache_size;
930 params->has_max_postcopy_bandwidth = true;
931 params->max_postcopy_bandwidth = s->parameters.max_postcopy_bandwidth;
932 params->has_max_cpu_throttle = true;
933 params->max_cpu_throttle = s->parameters.max_cpu_throttle;
934 params->has_announce_initial = true;
935 params->announce_initial = s->parameters.announce_initial;
936 params->has_announce_max = true;
937 params->announce_max = s->parameters.announce_max;
938 params->has_announce_rounds = true;
939 params->announce_rounds = s->parameters.announce_rounds;
940 params->has_announce_step = true;
941 params->announce_step = s->parameters.announce_step;
942
943 if (s->parameters.has_block_bitmap_mapping) {
944 params->has_block_bitmap_mapping = true;
945 params->block_bitmap_mapping =
946 QAPI_CLONE(BitmapMigrationNodeAliasList,
947 s->parameters.block_bitmap_mapping);
948 }
949
950 params->has_x_vcpu_dirty_limit_period = true;
951 params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period;
952 params->has_vcpu_dirty_limit = true;
953 params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit;
954 params->has_mode = true;
955 params->mode = s->parameters.mode;
956 params->has_zero_page_detection = true;
957 params->zero_page_detection = s->parameters.zero_page_detection;
958 params->has_direct_io = true;
959 params->direct_io = s->parameters.direct_io;
960
961 return params;
962 }
963
migrate_params_init(MigrationParameters * params)964 void migrate_params_init(MigrationParameters *params)
965 {
966 params->tls_hostname = g_strdup("");
967 params->tls_creds = g_strdup("");
968
969 /* Set has_* up only for parameter checks */
970 params->has_throttle_trigger_threshold = true;
971 params->has_cpu_throttle_initial = true;
972 params->has_cpu_throttle_increment = true;
973 params->has_cpu_throttle_tailslow = true;
974 params->has_max_bandwidth = true;
975 params->has_downtime_limit = true;
976 params->has_x_checkpoint_delay = true;
977 params->has_multifd_channels = true;
978 params->has_multifd_compression = true;
979 params->has_multifd_zlib_level = true;
980 params->has_multifd_qatzip_level = true;
981 params->has_multifd_zstd_level = true;
982 params->has_xbzrle_cache_size = true;
983 params->has_max_postcopy_bandwidth = true;
984 params->has_max_cpu_throttle = true;
985 params->has_announce_initial = true;
986 params->has_announce_max = true;
987 params->has_announce_rounds = true;
988 params->has_announce_step = true;
989 params->has_x_vcpu_dirty_limit_period = true;
990 params->has_vcpu_dirty_limit = true;
991 params->has_mode = true;
992 params->has_zero_page_detection = true;
993 params->has_direct_io = true;
994 }
995
996 /*
997 * Check whether the parameters are valid. Error will be put into errp
998 * (if provided). Return true if valid, otherwise false.
999 */
migrate_params_check(MigrationParameters * params,Error ** errp)1000 bool migrate_params_check(MigrationParameters *params, Error **errp)
1001 {
1002 ERRP_GUARD();
1003
1004 if (params->has_throttle_trigger_threshold &&
1005 (params->throttle_trigger_threshold < 1 ||
1006 params->throttle_trigger_threshold > 100)) {
1007 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1008 "throttle_trigger_threshold",
1009 "an integer in the range of 1 to 100");
1010 return false;
1011 }
1012
1013 if (params->has_cpu_throttle_initial &&
1014 (params->cpu_throttle_initial < 1 ||
1015 params->cpu_throttle_initial > 99)) {
1016 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1017 "cpu_throttle_initial",
1018 "an integer in the range of 1 to 99");
1019 return false;
1020 }
1021
1022 if (params->has_cpu_throttle_increment &&
1023 (params->cpu_throttle_increment < 1 ||
1024 params->cpu_throttle_increment > 99)) {
1025 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1026 "cpu_throttle_increment",
1027 "an integer in the range of 1 to 99");
1028 return false;
1029 }
1030
1031 if (params->has_max_bandwidth && (params->max_bandwidth > SIZE_MAX)) {
1032 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1033 "max_bandwidth",
1034 "an integer in the range of 0 to "stringify(SIZE_MAX)
1035 " bytes/second");
1036 return false;
1037 }
1038
1039 if (params->has_avail_switchover_bandwidth &&
1040 (params->avail_switchover_bandwidth > SIZE_MAX)) {
1041 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1042 "avail_switchover_bandwidth",
1043 "an integer in the range of 0 to "stringify(SIZE_MAX)
1044 " bytes/second");
1045 return false;
1046 }
1047
1048 if (params->has_downtime_limit &&
1049 (params->downtime_limit > MAX_MIGRATE_DOWNTIME)) {
1050 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1051 "downtime_limit",
1052 "an integer in the range of 0 to "
1053 stringify(MAX_MIGRATE_DOWNTIME)" ms");
1054 return false;
1055 }
1056
1057 /* x_checkpoint_delay is now always positive */
1058
1059 if (params->has_multifd_channels && (params->multifd_channels < 1)) {
1060 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1061 "multifd_channels",
1062 "a value between 1 and 255");
1063 return false;
1064 }
1065
1066 if (params->has_multifd_zlib_level &&
1067 (params->multifd_zlib_level > 9)) {
1068 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zlib_level",
1069 "a value between 0 and 9");
1070 return false;
1071 }
1072
1073 if (params->has_multifd_qatzip_level &&
1074 ((params->multifd_qatzip_level > 9) ||
1075 (params->multifd_qatzip_level < 1))) {
1076 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_qatzip_level",
1077 "a value between 1 and 9");
1078 return false;
1079 }
1080
1081 if (params->has_multifd_zstd_level &&
1082 (params->multifd_zstd_level > 20)) {
1083 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "multifd_zstd_level",
1084 "a value between 0 and 20");
1085 return false;
1086 }
1087
1088 if (params->has_xbzrle_cache_size &&
1089 (params->xbzrle_cache_size < qemu_target_page_size() ||
1090 !is_power_of_2(params->xbzrle_cache_size))) {
1091 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1092 "xbzrle_cache_size",
1093 "a power of two no less than the target page size");
1094 return false;
1095 }
1096
1097 if (params->has_max_cpu_throttle &&
1098 (params->max_cpu_throttle < params->cpu_throttle_initial ||
1099 params->max_cpu_throttle > 99)) {
1100 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1101 "max_cpu_throttle",
1102 "an integer in the range of cpu_throttle_initial to 99");
1103 return false;
1104 }
1105
1106 if (params->has_announce_initial &&
1107 params->announce_initial > 100000) {
1108 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1109 "announce_initial",
1110 "a value between 0 and 100000");
1111 return false;
1112 }
1113 if (params->has_announce_max &&
1114 params->announce_max > 100000) {
1115 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1116 "announce_max",
1117 "a value between 0 and 100000");
1118 return false;
1119 }
1120 if (params->has_announce_rounds &&
1121 params->announce_rounds > 1000) {
1122 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1123 "announce_rounds",
1124 "a value between 0 and 1000");
1125 return false;
1126 }
1127 if (params->has_announce_step &&
1128 (params->announce_step < 1 ||
1129 params->announce_step > 10000)) {
1130 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1131 "announce_step",
1132 "a value between 0 and 10000");
1133 return false;
1134 }
1135
1136 if (params->has_block_bitmap_mapping &&
1137 !check_dirty_bitmap_mig_alias_map(params->block_bitmap_mapping, errp)) {
1138 error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: ");
1139 return false;
1140 }
1141
1142 #ifdef CONFIG_LINUX
1143 if (migrate_zero_copy_send() &&
1144 ((params->has_multifd_compression && params->multifd_compression) ||
1145 (params->tls_creds && *params->tls_creds))) {
1146 error_setg(errp,
1147 "Zero copy only available for non-compressed non-TLS multifd migration");
1148 return false;
1149 }
1150 #endif
1151
1152 if (migrate_mapped_ram() &&
1153 (migrate_multifd_compression() || migrate_tls())) {
1154 error_setg(errp,
1155 "Mapped-ram only available for non-compressed non-TLS multifd migration");
1156 return false;
1157 }
1158
1159 if (params->has_x_vcpu_dirty_limit_period &&
1160 (params->x_vcpu_dirty_limit_period < 1 ||
1161 params->x_vcpu_dirty_limit_period > 1000)) {
1162 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
1163 "x-vcpu-dirty-limit-period",
1164 "a value between 1 and 1000");
1165 return false;
1166 }
1167
1168 if (params->has_vcpu_dirty_limit &&
1169 (params->vcpu_dirty_limit < 1)) {
1170 error_setg(errp,
1171 "Parameter 'vcpu_dirty_limit' must be greater than 1 MB/s");
1172 return false;
1173 }
1174
1175 if (params->has_direct_io && params->direct_io && !qemu_has_direct_io()) {
1176 error_setg(errp, "No build-time support for direct-io");
1177 return false;
1178 }
1179
1180 return true;
1181 }
1182
migrate_params_test_apply(MigrateSetParameters * params,MigrationParameters * dest)1183 static void migrate_params_test_apply(MigrateSetParameters *params,
1184 MigrationParameters *dest)
1185 {
1186 *dest = migrate_get_current()->parameters;
1187
1188 /* TODO use QAPI_CLONE() instead of duplicating it inline */
1189
1190 if (params->has_throttle_trigger_threshold) {
1191 dest->throttle_trigger_threshold = params->throttle_trigger_threshold;
1192 }
1193
1194 if (params->has_cpu_throttle_initial) {
1195 dest->cpu_throttle_initial = params->cpu_throttle_initial;
1196 }
1197
1198 if (params->has_cpu_throttle_increment) {
1199 dest->cpu_throttle_increment = params->cpu_throttle_increment;
1200 }
1201
1202 if (params->has_cpu_throttle_tailslow) {
1203 dest->cpu_throttle_tailslow = params->cpu_throttle_tailslow;
1204 }
1205
1206 if (params->tls_creds) {
1207 assert(params->tls_creds->type == QTYPE_QSTRING);
1208 dest->tls_creds = params->tls_creds->u.s;
1209 }
1210
1211 if (params->tls_hostname) {
1212 assert(params->tls_hostname->type == QTYPE_QSTRING);
1213 dest->tls_hostname = params->tls_hostname->u.s;
1214 }
1215
1216 if (params->tls_authz) {
1217 assert(params->tls_authz->type == QTYPE_QSTRING);
1218 dest->tls_authz = params->tls_authz->u.s;
1219 }
1220
1221 if (params->has_max_bandwidth) {
1222 dest->max_bandwidth = params->max_bandwidth;
1223 }
1224
1225 if (params->has_avail_switchover_bandwidth) {
1226 dest->avail_switchover_bandwidth = params->avail_switchover_bandwidth;
1227 }
1228
1229 if (params->has_downtime_limit) {
1230 dest->downtime_limit = params->downtime_limit;
1231 }
1232
1233 if (params->has_x_checkpoint_delay) {
1234 dest->x_checkpoint_delay = params->x_checkpoint_delay;
1235 }
1236
1237 if (params->has_multifd_channels) {
1238 dest->multifd_channels = params->multifd_channels;
1239 }
1240 if (params->has_multifd_compression) {
1241 dest->multifd_compression = params->multifd_compression;
1242 }
1243 if (params->has_multifd_qatzip_level) {
1244 dest->multifd_qatzip_level = params->multifd_qatzip_level;
1245 }
1246 if (params->has_multifd_zlib_level) {
1247 dest->multifd_zlib_level = params->multifd_zlib_level;
1248 }
1249 if (params->has_multifd_zstd_level) {
1250 dest->multifd_zstd_level = params->multifd_zstd_level;
1251 }
1252 if (params->has_xbzrle_cache_size) {
1253 dest->xbzrle_cache_size = params->xbzrle_cache_size;
1254 }
1255 if (params->has_max_postcopy_bandwidth) {
1256 dest->max_postcopy_bandwidth = params->max_postcopy_bandwidth;
1257 }
1258 if (params->has_max_cpu_throttle) {
1259 dest->max_cpu_throttle = params->max_cpu_throttle;
1260 }
1261 if (params->has_announce_initial) {
1262 dest->announce_initial = params->announce_initial;
1263 }
1264 if (params->has_announce_max) {
1265 dest->announce_max = params->announce_max;
1266 }
1267 if (params->has_announce_rounds) {
1268 dest->announce_rounds = params->announce_rounds;
1269 }
1270 if (params->has_announce_step) {
1271 dest->announce_step = params->announce_step;
1272 }
1273
1274 if (params->has_block_bitmap_mapping) {
1275 dest->has_block_bitmap_mapping = true;
1276 dest->block_bitmap_mapping = params->block_bitmap_mapping;
1277 }
1278
1279 if (params->has_x_vcpu_dirty_limit_period) {
1280 dest->x_vcpu_dirty_limit_period =
1281 params->x_vcpu_dirty_limit_period;
1282 }
1283 if (params->has_vcpu_dirty_limit) {
1284 dest->vcpu_dirty_limit = params->vcpu_dirty_limit;
1285 }
1286
1287 if (params->has_mode) {
1288 dest->mode = params->mode;
1289 }
1290
1291 if (params->has_zero_page_detection) {
1292 dest->zero_page_detection = params->zero_page_detection;
1293 }
1294
1295 if (params->has_direct_io) {
1296 dest->direct_io = params->direct_io;
1297 }
1298 }
1299
migrate_params_apply(MigrateSetParameters * params,Error ** errp)1300 static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
1301 {
1302 MigrationState *s = migrate_get_current();
1303
1304 /* TODO use QAPI_CLONE() instead of duplicating it inline */
1305
1306 if (params->has_throttle_trigger_threshold) {
1307 s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold;
1308 }
1309
1310 if (params->has_cpu_throttle_initial) {
1311 s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;
1312 }
1313
1314 if (params->has_cpu_throttle_increment) {
1315 s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;
1316 }
1317
1318 if (params->has_cpu_throttle_tailslow) {
1319 s->parameters.cpu_throttle_tailslow = params->cpu_throttle_tailslow;
1320 }
1321
1322 if (params->tls_creds) {
1323 g_free(s->parameters.tls_creds);
1324 assert(params->tls_creds->type == QTYPE_QSTRING);
1325 s->parameters.tls_creds = g_strdup(params->tls_creds->u.s);
1326 }
1327
1328 if (params->tls_hostname) {
1329 g_free(s->parameters.tls_hostname);
1330 assert(params->tls_hostname->type == QTYPE_QSTRING);
1331 s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
1332 }
1333
1334 if (params->tls_authz) {
1335 g_free(s->parameters.tls_authz);
1336 assert(params->tls_authz->type == QTYPE_QSTRING);
1337 s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
1338 }
1339
1340 if (params->has_max_bandwidth) {
1341 s->parameters.max_bandwidth = params->max_bandwidth;
1342 if (s->to_dst_file && !migration_in_postcopy()) {
1343 migration_rate_set(s->parameters.max_bandwidth);
1344 }
1345 }
1346
1347 if (params->has_avail_switchover_bandwidth) {
1348 s->parameters.avail_switchover_bandwidth = params->avail_switchover_bandwidth;
1349 }
1350
1351 if (params->has_downtime_limit) {
1352 s->parameters.downtime_limit = params->downtime_limit;
1353 }
1354
1355 if (params->has_x_checkpoint_delay) {
1356 s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
1357 colo_checkpoint_delay_set();
1358 }
1359
1360 if (params->has_multifd_channels) {
1361 s->parameters.multifd_channels = params->multifd_channels;
1362 }
1363 if (params->has_multifd_compression) {
1364 s->parameters.multifd_compression = params->multifd_compression;
1365 }
1366 if (params->has_multifd_qatzip_level) {
1367 s->parameters.multifd_qatzip_level = params->multifd_qatzip_level;
1368 }
1369 if (params->has_multifd_zlib_level) {
1370 s->parameters.multifd_zlib_level = params->multifd_zlib_level;
1371 }
1372 if (params->has_multifd_zstd_level) {
1373 s->parameters.multifd_zstd_level = params->multifd_zstd_level;
1374 }
1375 if (params->has_xbzrle_cache_size) {
1376 s->parameters.xbzrle_cache_size = params->xbzrle_cache_size;
1377 xbzrle_cache_resize(params->xbzrle_cache_size, errp);
1378 }
1379 if (params->has_max_postcopy_bandwidth) {
1380 s->parameters.max_postcopy_bandwidth = params->max_postcopy_bandwidth;
1381 if (s->to_dst_file && migration_in_postcopy()) {
1382 migration_rate_set(s->parameters.max_postcopy_bandwidth);
1383 }
1384 }
1385 if (params->has_max_cpu_throttle) {
1386 s->parameters.max_cpu_throttle = params->max_cpu_throttle;
1387 }
1388 if (params->has_announce_initial) {
1389 s->parameters.announce_initial = params->announce_initial;
1390 }
1391 if (params->has_announce_max) {
1392 s->parameters.announce_max = params->announce_max;
1393 }
1394 if (params->has_announce_rounds) {
1395 s->parameters.announce_rounds = params->announce_rounds;
1396 }
1397 if (params->has_announce_step) {
1398 s->parameters.announce_step = params->announce_step;
1399 }
1400
1401 if (params->has_block_bitmap_mapping) {
1402 qapi_free_BitmapMigrationNodeAliasList(
1403 s->parameters.block_bitmap_mapping);
1404
1405 s->parameters.has_block_bitmap_mapping = true;
1406 s->parameters.block_bitmap_mapping =
1407 QAPI_CLONE(BitmapMigrationNodeAliasList,
1408 params->block_bitmap_mapping);
1409 }
1410
1411 if (params->has_x_vcpu_dirty_limit_period) {
1412 s->parameters.x_vcpu_dirty_limit_period =
1413 params->x_vcpu_dirty_limit_period;
1414 }
1415 if (params->has_vcpu_dirty_limit) {
1416 s->parameters.vcpu_dirty_limit = params->vcpu_dirty_limit;
1417 }
1418
1419 if (params->has_mode) {
1420 s->parameters.mode = params->mode;
1421 }
1422
1423 if (params->has_zero_page_detection) {
1424 s->parameters.zero_page_detection = params->zero_page_detection;
1425 }
1426
1427 if (params->has_direct_io) {
1428 s->parameters.direct_io = params->direct_io;
1429 }
1430 }
1431
qmp_migrate_set_parameters(MigrateSetParameters * params,Error ** errp)1432 void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
1433 {
1434 MigrationParameters tmp;
1435
1436 /* TODO Rewrite "" to null instead for all three tls_* parameters */
1437 if (params->tls_creds
1438 && params->tls_creds->type == QTYPE_QNULL) {
1439 qobject_unref(params->tls_creds->u.n);
1440 params->tls_creds->type = QTYPE_QSTRING;
1441 params->tls_creds->u.s = strdup("");
1442 }
1443 if (params->tls_hostname
1444 && params->tls_hostname->type == QTYPE_QNULL) {
1445 qobject_unref(params->tls_hostname->u.n);
1446 params->tls_hostname->type = QTYPE_QSTRING;
1447 params->tls_hostname->u.s = strdup("");
1448 }
1449 if (params->tls_authz
1450 && params->tls_authz->type == QTYPE_QNULL) {
1451 qobject_unref(params->tls_authz->u.n);
1452 params->tls_authz->type = QTYPE_QSTRING;
1453 params->tls_authz->u.s = strdup("");
1454 }
1455
1456 migrate_params_test_apply(params, &tmp);
1457
1458 if (!migrate_params_check(&tmp, errp)) {
1459 /* Invalid parameter */
1460 return;
1461 }
1462
1463 migrate_params_apply(params, errp);
1464 }
1465