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