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