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