Skip to content

Commit 2ff3025

Browse files
ashijeet24juanquintela
authored andcommitted
migrate: move max-bandwidth and downtime-limit to migrate_set_parameter
Mark the old commands 'migrate_set_speed' and 'migrate_set_downtime' as deprecated. Move max-bandwidth and downtime-limit into migrate-set-parameters for setting maximum migration speed and expected downtime limit parameters respectively. Change downtime units to milliseconds (only for new-command) and set its upper bound limit to 2000 seconds. Update the query part in both hmp and qmp qemu control interfaces. Signed-off-by: Ashijeet Acharya <[email protected]> Reviewed-by: Eric Blake <[email protected]> Reviewed-by: Juan Quintela <[email protected]> Signed-off-by: Juan Quintela <[email protected]>
1 parent 9308ae5 commit 2ff3025

File tree

5 files changed

+107
-40
lines changed

5 files changed

+107
-40
lines changed

docs/qmp-commands.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2910,7 +2910,9 @@ Set migration parameters
29102910
throttled for auto-converge (json-int)
29112911
- "cpu-throttle-increment": set throttle increasing percentage for
29122912
auto-converge (json-int)
2913-
2913+
- "max-bandwidth": set maximum speed for migrations (in bytes/sec) (json-int)
2914+
- "downtime-limit": set maximum tolerated downtime (in milliseconds) for
2915+
migrations (json-int)
29142916
Arguments:
29152917

29162918
Example:
@@ -2931,7 +2933,10 @@ Query current migration parameters
29312933
throttled (json-int)
29322934
- "cpu-throttle-increment" : throttle increasing percentage for
29332935
auto-converge (json-int)
2934-
2936+
- "max-bandwidth" : maximium migration speed in bytes per second
2937+
(json-int)
2938+
- "downtime-limit" : maximum tolerated downtime of migration in
2939+
milliseconds (json-int)
29352940
Arguments:
29362941

29372942
Example:
@@ -2943,7 +2948,9 @@ Example:
29432948
"cpu-throttle-increment": 10,
29442949
"compress-threads": 8,
29452950
"compress-level": 1,
2946-
"cpu-throttle-initial": 20
2951+
"cpu-throttle-initial": 20,
2952+
"max-bandwidth": 33554432,
2953+
"downtime-limit": 300
29472954
}
29482955
}
29492956

hmp.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,14 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
310310
monitor_printf(mon, " %s: '%s'",
311311
MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_HOSTNAME],
312312
params->has_tls_hostname ? params->tls_hostname : "");
313+
assert(params->has_max_bandwidth);
314+
monitor_printf(mon, " %s: %" PRId64 " bytes/second",
315+
MigrationParameter_lookup[MIGRATION_PARAMETER_MAX_BANDWIDTH],
316+
params->max_bandwidth);
317+
assert(params->has_downtime_limit);
318+
monitor_printf(mon, " %s: %" PRId64 " milliseconds",
319+
MigrationParameter_lookup[MIGRATION_PARAMETER_DOWNTIME_LIMIT],
320+
params->downtime_limit);
313321
monitor_printf(mon, "\n");
314322
}
315323

@@ -1265,6 +1273,7 @@ void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
12651273
hmp_handle_error(mon, &err);
12661274
}
12671275

1276+
/* Kept for backwards compatibility */
12681277
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
12691278
{
12701279
double value = qdict_get_double(qdict, "value");
@@ -1283,6 +1292,7 @@ void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
12831292
}
12841293
}
12851294

1295+
/* Kept for backwards compatibility */
12861296
void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
12871297
{
12881298
int64_t value = qdict_get_int(qdict, "value");
@@ -1323,7 +1333,9 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
13231333
{
13241334
const char *param = qdict_get_str(qdict, "parameter");
13251335
const char *valuestr = qdict_get_str(qdict, "value");
1336+
int64_t valuebw = 0;
13261337
long valueint = 0;
1338+
char *endp;
13271339
Error *err = NULL;
13281340
bool use_int_value = false;
13291341
int i;
@@ -1360,6 +1372,20 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
13601372
p.has_tls_hostname = true;
13611373
p.tls_hostname = (char *) valuestr;
13621374
break;
1375+
case MIGRATION_PARAMETER_MAX_BANDWIDTH:
1376+
p.has_max_bandwidth = true;
1377+
valuebw = qemu_strtosz(valuestr, &endp);
1378+
if (valuebw < 0 || (size_t)valuebw != valuebw
1379+
|| *endp != '\0') {
1380+
error_setg(&err, "Invalid size %s", valuestr);
1381+
goto cleanup;
1382+
}
1383+
p.max_bandwidth = valuebw;
1384+
break;
1385+
case MIGRATION_PARAMETER_DOWNTIME_LIMIT:
1386+
p.has_downtime_limit = true;
1387+
use_int_value = true;
1388+
break;
13631389
}
13641390

13651391
if (use_int_value) {
@@ -1375,6 +1401,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
13751401
p.decompress_threads = valueint;
13761402
p.cpu_throttle_initial = valueint;
13771403
p.cpu_throttle_increment = valueint;
1404+
p.downtime_limit = valueint;
13781405
}
13791406

13801407
qmp_migrate_set_parameters(&p, &err);

include/migration/migration.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ struct MigrationSrcPageRequest {
129129

130130
struct MigrationState
131131
{
132-
int64_t bandwidth_limit;
133132
size_t bytes_xfer;
134133
size_t xfer_limit;
135134
QemuThread thread;

migration/migration.c

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
#define BUFFER_DELAY 100
4545
#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY)
4646

47+
/* Time in milliseconds we are allowed to stop the source,
48+
* for sending the last part */
49+
#define DEFAULT_MIGRATE_SET_DOWNTIME 300
50+
4751
/* Default compression thread count */
4852
#define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
4953
/* Default decompression thread count, usually decompression is at
@@ -80,7 +84,6 @@ MigrationState *migrate_get_current(void)
8084
static bool once;
8185
static MigrationState current_migration = {
8286
.state = MIGRATION_STATUS_NONE,
83-
.bandwidth_limit = MAX_THROTTLE,
8487
.xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
8588
.mbps = -1,
8689
.parameters = {
@@ -89,6 +92,8 @@ MigrationState *migrate_get_current(void)
8992
.decompress_threads = DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,
9093
.cpu_throttle_initial = DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL,
9194
.cpu_throttle_increment = DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT,
95+
.max_bandwidth = MAX_THROTTLE,
96+
.downtime_limit = DEFAULT_MIGRATE_SET_DOWNTIME,
9297
},
9398
};
9499

@@ -517,17 +522,6 @@ void migrate_send_rp_pong(MigrationIncomingState *mis,
517522
migrate_send_rp_message(mis, MIG_RP_MSG_PONG, sizeof(buf), &buf);
518523
}
519524

520-
/* amount of nanoseconds we are willing to wait for migration to be down.
521-
* the choice of nanoseconds is because it is the maximum resolution that
522-
* get_clock() can achieve. It is an internal measure. All user-visible
523-
* units must be in seconds */
524-
static uint64_t max_downtime = 300000000;
525-
526-
uint64_t migrate_max_downtime(void)
527-
{
528-
return max_downtime;
529-
}
530-
531525
MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
532526
{
533527
MigrationCapabilityStatusList *head = NULL;
@@ -573,6 +567,10 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
573567
params->tls_creds = g_strdup(s->parameters.tls_creds);
574568
params->has_tls_hostname = !!s->parameters.tls_hostname;
575569
params->tls_hostname = g_strdup(s->parameters.tls_hostname);
570+
params->has_max_bandwidth = true;
571+
params->max_bandwidth = s->parameters.max_bandwidth;
572+
params->has_downtime_limit = true;
573+
params->downtime_limit = s->parameters.downtime_limit;
576574

577575
return params;
578576
}
@@ -806,6 +804,19 @@ void qmp_migrate_set_parameters(MigrationParameters *params, Error **errp)
806804
"an integer in the range of 1 to 99");
807805
return;
808806
}
807+
if (params->has_max_bandwidth &&
808+
(params->max_bandwidth < 0 || params->max_bandwidth > SIZE_MAX)) {
809+
error_setg(errp, "Parameter 'max_bandwidth' expects an integer in the"
810+
" range of 0 to %zu bytes/second", SIZE_MAX);
811+
return;
812+
}
813+
if (params->has_downtime_limit &&
814+
(params->downtime_limit < 0 || params->downtime_limit > 2000000)) {
815+
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
816+
"downtime_limit",
817+
"an integer in the range of 0 to 2000000 milliseconds");
818+
return;
819+
}
809820

810821
if (params->has_compress_level) {
811822
s->parameters.compress_level = params->compress_level;
@@ -830,6 +841,16 @@ void qmp_migrate_set_parameters(MigrationParameters *params, Error **errp)
830841
g_free(s->parameters.tls_hostname);
831842
s->parameters.tls_hostname = g_strdup(params->tls_hostname);
832843
}
844+
if (params->has_max_bandwidth) {
845+
s->parameters.max_bandwidth = params->max_bandwidth;
846+
if (s->to_dst_file) {
847+
qemu_file_set_rate_limit(s->to_dst_file,
848+
s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
849+
}
850+
}
851+
if (params->has_downtime_limit) {
852+
s->parameters.downtime_limit = params->downtime_limit;
853+
}
833854
}
834855

835856

@@ -1163,28 +1184,25 @@ int64_t qmp_query_migrate_cache_size(Error **errp)
11631184

11641185
void qmp_migrate_set_speed(int64_t value, Error **errp)
11651186
{
1166-
MigrationState *s;
1167-
1168-
if (value < 0) {
1169-
value = 0;
1170-
}
1171-
if (value > SIZE_MAX) {
1172-
value = SIZE_MAX;
1173-
}
1187+
MigrationParameters p = {
1188+
.has_max_bandwidth = true,
1189+
.max_bandwidth = value,
1190+
};
11741191

1175-
s = migrate_get_current();
1176-
s->bandwidth_limit = value;
1177-
if (s->to_dst_file) {
1178-
qemu_file_set_rate_limit(s->to_dst_file,
1179-
s->bandwidth_limit / XFER_LIMIT_RATIO);
1180-
}
1192+
qmp_migrate_set_parameters(&p, errp);
11811193
}
11821194

11831195
void qmp_migrate_set_downtime(double value, Error **errp)
11841196
{
1185-
value *= 1e9;
1186-
value = MAX(0, MIN(UINT64_MAX, value));
1187-
max_downtime = (uint64_t)value;
1197+
value *= 1000; /* Convert to milliseconds */
1198+
value = MAX(0, MIN(INT64_MAX, value));
1199+
1200+
MigrationParameters p = {
1201+
.has_downtime_limit = true,
1202+
.downtime_limit = value,
1203+
};
1204+
1205+
qmp_migrate_set_parameters(&p, errp);
11881206
}
11891207

11901208
bool migrate_postcopy_ram(void)
@@ -1791,7 +1809,7 @@ static void *migration_thread(void *opaque)
17911809
initial_bytes;
17921810
uint64_t time_spent = current_time - initial_time;
17931811
double bandwidth = (double)transferred_bytes / time_spent;
1794-
max_size = bandwidth * migrate_max_downtime() / 1000000;
1812+
max_size = bandwidth * s->parameters.downtime_limit;
17951813

17961814
s->mbps = (((double) transferred_bytes * 8.0) /
17971815
((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
@@ -1850,13 +1868,12 @@ static void *migration_thread(void *opaque)
18501868

18511869
void migrate_fd_connect(MigrationState *s)
18521870
{
1853-
/* This is a best 1st approximation. ns to ms */
1854-
s->expected_downtime = max_downtime/1000000;
1871+
s->expected_downtime = s->parameters.downtime_limit;
18551872
s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s);
18561873

18571874
qemu_file_set_blocking(s->to_dst_file, true);
18581875
qemu_file_set_rate_limit(s->to_dst_file,
1859-
s->bandwidth_limit / XFER_LIMIT_RATIO);
1876+
s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
18601877

18611878
/* Notify before starting migration thread */
18621879
notifier_list_notify(&migration_state_notifiers, s);

qapi-schema.json

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -658,12 +658,19 @@
658658
# hostname must be provided so that the server's x509
659659
# certificate identity can be validated. (Since 2.7)
660660
#
661+
# @max-bandwidth: to set maximum speed for migration. maximum speed in
662+
# bytes per second. (Since 2.8)
663+
#
664+
# @downtime-limit: set maximum tolerated downtime for migration. maximum
665+
# downtime in milliseconds (Since 2.8)
666+
#
661667
# Since: 2.4
662668
##
663669
{ 'enum': 'MigrationParameter',
664670
'data': ['compress-level', 'compress-threads', 'decompress-threads',
665671
'cpu-throttle-initial', 'cpu-throttle-increment',
666-
'tls-creds', 'tls-hostname'] }
672+
'tls-creds', 'tls-hostname', 'max-bandwidth',
673+
'downtime-limit'] }
667674

668675
#
669676
# @migrate-set-parameters
@@ -712,6 +719,12 @@
712719
# hostname must be provided so that the server's x509
713720
# certificate identity can be validated. (Since 2.7)
714721
#
722+
# @max-bandwidth: to set maximum speed for migration. maximum speed in
723+
# bytes per second. (Since 2.8)
724+
#
725+
# @downtime-limit: set maximum tolerated downtime for migration. maximum
726+
# downtime in milliseconds (Since 2.8)
727+
#
715728
# Since: 2.4
716729
##
717730
{ 'struct': 'MigrationParameters',
@@ -721,7 +734,9 @@
721734
'*cpu-throttle-initial': 'int',
722735
'*cpu-throttle-increment': 'int',
723736
'*tls-creds': 'str',
724-
'*tls-hostname': 'str'} }
737+
'*tls-hostname': 'str',
738+
'*max-bandwidth': 'int',
739+
'*downtime-limit': 'int'} }
725740
##
726741
# @query-migrate-parameters
727742
#
@@ -1803,6 +1818,8 @@
18031818
#
18041819
# Returns: nothing on success
18051820
#
1821+
# Notes: This command is deprecated in favor of 'migrate-set-parameters'
1822+
#
18061823
# Since: 0.14.0
18071824
##
18081825
{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} }
@@ -1816,7 +1833,7 @@
18161833
#
18171834
# Returns: nothing on success
18181835
#
1819-
# Notes: A value lesser than zero will be automatically round up to zero.
1836+
# Notes: This command is deprecated in favor of 'migrate-set-parameters'
18201837
#
18211838
# Since: 0.14.0
18221839
##

0 commit comments

Comments
 (0)