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