mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
Migration (and HMP and virtiofs) pull 2020-06-17
Migration: HMP/migration and test changes from Mao Zhongyi multifd fix from Laurent Vivier HMP qom-set partial reversion/change from David Hildenbrand now you need -j to pass json format, but it's regained the old 100M type format. Memory leak fix from Pan Nengyuan Virtiofs fchmod seccomp fix from Max Reitz Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEERfXHG0oMt/uXep+pBRYzHrxb/ecFAl7qYlIACgkQBRYzHrxb /efT/A//eSmxz0m4LB3Vz3pmwKQosVlvLNYgLgfs/dthdM8f3YyhpnY/bCyEmgL2 J/TJevJvzBinVjiGJZkp1nv3wShcf1gpDGKvuhPpStavEajZoxStfGdiGGSvv/sX XuzQW8efmphoah8qL7J9xE9eC+WOWDATGDlaYIQv4oDG9Ef/OpBOcoYzdwj90ZhR Gl5AqPf3Bn2Xt2TpWK2aIaBfQtRSTu7xGSB/G8BQNzrJOraoALQmCZKvQYbQtlaq Guqj7Ad/x7kic5RGG9I5vxy1rQnM0fQvHG57uNvj+Gvi3lLfsCqI77O3gZZmdTmt mxjHn3OcIiwFmlptM9lNyWaZlrIniB3Di3K7VobHpvnuXbfkXGTElhD2CPNzErNY QDit9I/ZJxHu9kauyoWBuhKKRfn4S9jpmrEiyIe51v3Gr9r2dkfZlFzYyk1wBJi8 caR7g5QVQFm+3TI5LgnVRisv/FQlLsPXiBaRN2rv6dE+CZIVs/7lbwzwOshpbtxR NWv0FOvlIyQhdkZrCo+FIVbRK0vRJNZwpHOQ1ZwdlAbIbKBwyfqitMmHHCAJnpI4 CqLg9Bao8VYf/mynaTYt6h+azVnByBgSpj2KJlDUstPxKFhv+0SDgVXdHCnbOEya 6mknqBy4k/9To2g5Y3spJUinf5H4mcIuCWB0jEAioyZ6CjUfifg= =KYWs -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20200617a' into staging Migration (and HMP and virtiofs) pull 2020-06-17 Migration: HMP/migration and test changes from Mao Zhongyi multifd fix from Laurent Vivier HMP qom-set partial reversion/change from David Hildenbrand now you need -j to pass json format, but it's regained the old 100M type format. Memory leak fix from Pan Nengyuan Virtiofs fchmod seccomp fix from Max Reitz Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> # gpg: Signature made Wed 17 Jun 2020 19:34:58 BST # gpg: using RSA key 45F5C71B4A0CB7FB977A9FA90516331EBC5BFDE7 # gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>" [full] # Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A 9FA9 0516 331E BC5B FDE7 * remotes/dgilbert/tags/pull-migration-20200617a: migration: fix multifd_send_pages() next channel docs/xbzrle: update 'cache miss rate' and 'encoding rate' to docs monitor/hmp-cmds: improvements for the 'info migrate' monitor/hmp-cmds: add 'goto end' to reduce duplicate code. monitor/hmp-cmds: delete redundant Error check before invoke hmp_handle_error() monitor/hmp-cmds: don't silently output when running 'migrate_set_downtime' fails monitor/hmp-cmds: add units for migrate_parameters tests/migration: fix unreachable path in stress test tests/migration: mem leak fix hmp: Make json format optional for qom-set qom-hmp-cmds: fix a memleak in hmp_qom_get virtiofsd: Whitelist fchmod Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
eefe34ea4b
7 changed files with 56 additions and 51 deletions
|
@ -112,10 +112,12 @@ is recommended.
|
||||||
cache size: H bytes
|
cache size: H bytes
|
||||||
xbzrle transferred: I kbytes
|
xbzrle transferred: I kbytes
|
||||||
xbzrle pages: J pages
|
xbzrle pages: J pages
|
||||||
xbzrle cache miss: K
|
xbzrle cache miss: K pages
|
||||||
xbzrle overflow: L
|
xbzrle cache miss rate: L
|
||||||
|
xbzrle encoding rate: M
|
||||||
|
xbzrle overflow: N
|
||||||
|
|
||||||
xbzrle cache-miss: the number of cache misses to date - high cache-miss rate
|
xbzrle cache miss: the number of cache misses to date - high cache-miss rate
|
||||||
indicates that the cache size is set too low.
|
indicates that the cache size is set too low.
|
||||||
xbzrle overflow: the number of overflows in the decoding which where the delta
|
xbzrle overflow: the number of overflows in the decoding which where the delta
|
||||||
could not be compressed. This can happen if the changes in the pages are too
|
could not be compressed. This can happen if the changes in the pages are too
|
||||||
|
|
|
@ -1806,9 +1806,10 @@ ERST
|
||||||
|
|
||||||
{
|
{
|
||||||
.name = "qom-set",
|
.name = "qom-set",
|
||||||
.args_type = "path:s,property:s,value:S",
|
.args_type = "json:-j,path:s,property:s,value:S",
|
||||||
.params = "path property value",
|
.params = "[-j] path property value",
|
||||||
.help = "set QOM property",
|
.help = "set QOM property.\n\t\t\t"
|
||||||
|
"-j: the value is specified in json format.",
|
||||||
.cmd = hmp_qom_set,
|
.cmd = hmp_qom_set,
|
||||||
.flags = "p",
|
.flags = "p",
|
||||||
},
|
},
|
||||||
|
|
|
@ -415,6 +415,12 @@ static int multifd_send_pages(QEMUFile *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_sem_wait(&multifd_send_state->channels_ready);
|
qemu_sem_wait(&multifd_send_state->channels_ready);
|
||||||
|
/*
|
||||||
|
* next_channel can remain from a previous migration that was
|
||||||
|
* using more channels, so ensure it doesn't overflow if the
|
||||||
|
* limit is lower now.
|
||||||
|
*/
|
||||||
|
next_channel %= migrate_multifd_channels();
|
||||||
for (i = next_channel;; i = (i + 1) % migrate_multifd_channels()) {
|
for (i = next_channel;; i = (i + 1) % migrate_multifd_channels()) {
|
||||||
p = &multifd_send_state->params[i];
|
p = &multifd_send_state->params[i];
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,7 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
||||||
info->xbzrle_cache->bytes >> 10);
|
info->xbzrle_cache->bytes >> 10);
|
||||||
monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
|
monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
|
||||||
info->xbzrle_cache->pages);
|
info->xbzrle_cache->pages);
|
||||||
monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
|
monitor_printf(mon, "xbzrle cache miss: %" PRIu64 " pages\n",
|
||||||
info->xbzrle_cache->cache_miss);
|
info->xbzrle_cache->cache_miss);
|
||||||
monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
|
monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
|
||||||
info->xbzrle_cache->cache_miss_rate);
|
info->xbzrle_cache->cache_miss_rate);
|
||||||
|
@ -316,8 +316,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
||||||
info->compression->busy);
|
info->compression->busy);
|
||||||
monitor_printf(mon, "compression busy rate: %0.2f\n",
|
monitor_printf(mon, "compression busy rate: %0.2f\n",
|
||||||
info->compression->busy_rate);
|
info->compression->busy_rate);
|
||||||
monitor_printf(mon, "compressed size: %" PRIu64 "\n",
|
monitor_printf(mon, "compressed size: %" PRIu64 " kbytes\n",
|
||||||
info->compression->compressed_size);
|
info->compression->compressed_size >> 10);
|
||||||
monitor_printf(mon, "compression rate: %0.2f\n",
|
monitor_printf(mon, "compression rate: %0.2f\n",
|
||||||
info->compression->compression_rate);
|
info->compression->compression_rate);
|
||||||
}
|
}
|
||||||
|
@ -443,11 +443,11 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
|
||||||
MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
|
MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
|
||||||
params->max_bandwidth);
|
params->max_bandwidth);
|
||||||
assert(params->has_downtime_limit);
|
assert(params->has_downtime_limit);
|
||||||
monitor_printf(mon, "%s: %" PRIu64 " milliseconds\n",
|
monitor_printf(mon, "%s: %" PRIu64 " ms\n",
|
||||||
MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
|
MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
|
||||||
params->downtime_limit);
|
params->downtime_limit);
|
||||||
assert(params->has_x_checkpoint_delay);
|
assert(params->has_x_checkpoint_delay);
|
||||||
monitor_printf(mon, "%s: %u\n",
|
monitor_printf(mon, "%s: %u ms\n",
|
||||||
MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
|
MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
|
||||||
params->x_checkpoint_delay);
|
params->x_checkpoint_delay);
|
||||||
assert(params->has_block_incremental);
|
assert(params->has_block_incremental);
|
||||||
|
@ -460,7 +460,7 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
|
||||||
monitor_printf(mon, "%s: %s\n",
|
monitor_printf(mon, "%s: %s\n",
|
||||||
MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
|
MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
|
||||||
MultiFDCompression_str(params->multifd_compression));
|
MultiFDCompression_str(params->multifd_compression));
|
||||||
monitor_printf(mon, "%s: %" PRIu64 "\n",
|
monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
|
||||||
MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
|
MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
|
||||||
params->xbzrle_cache_size);
|
params->xbzrle_cache_size);
|
||||||
monitor_printf(mon, "%s: %" PRIu64 "\n",
|
monitor_printf(mon, "%s: %" PRIu64 "\n",
|
||||||
|
@ -1189,8 +1189,11 @@ void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
|
||||||
/* Kept for backwards compatibility */
|
/* Kept for backwards compatibility */
|
||||||
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
|
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
double value = qdict_get_double(qdict, "value");
|
double value = qdict_get_double(qdict, "value");
|
||||||
qmp_migrate_set_downtime(value, NULL);
|
qmp_migrate_set_downtime(value, &err);
|
||||||
|
hmp_handle_error(mon, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
|
void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
|
||||||
|
@ -1499,8 +1502,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
|
||||||
read_only,
|
read_only,
|
||||||
BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err);
|
BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
hmp_handle_error(mon, err);
|
goto end;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1509,6 +1511,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
|
||||||
&err);
|
&err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
hmp_handle_error(mon, err);
|
hmp_handle_error(mon, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1627,16 +1630,15 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
|
||||||
|
|
||||||
opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
|
opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
hmp_handle_error(mon, err);
|
goto end;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = user_creatable_add_opts(opts, &err);
|
obj = user_creatable_add_opts(opts, &err);
|
||||||
qemu_opts_del(opts);
|
qemu_opts_del(opts);
|
||||||
|
|
||||||
if (err) {
|
end:
|
||||||
hmp_handle_error(mon, err);
|
hmp_handle_error(mon, err);
|
||||||
}
|
|
||||||
if (obj) {
|
if (obj) {
|
||||||
object_unref(obj);
|
object_unref(obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,15 +44,27 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict)
|
||||||
|
|
||||||
void hmp_qom_set(Monitor *mon, const QDict *qdict)
|
void hmp_qom_set(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
|
const bool json = qdict_get_try_bool(qdict, "json", false);
|
||||||
const char *path = qdict_get_str(qdict, "path");
|
const char *path = qdict_get_str(qdict, "path");
|
||||||
const char *property = qdict_get_str(qdict, "property");
|
const char *property = qdict_get_str(qdict, "property");
|
||||||
const char *value = qdict_get_str(qdict, "value");
|
const char *value = qdict_get_str(qdict, "value");
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
QObject *obj;
|
|
||||||
|
|
||||||
obj = qobject_from_json(value, &err);
|
if (!json) {
|
||||||
if (err == NULL) {
|
Object *obj = object_resolve_path(path, NULL);
|
||||||
qmp_qom_set(path, property, obj, &err);
|
|
||||||
|
if (!obj) {
|
||||||
|
error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||||
|
"Device '%s' not found", path);
|
||||||
|
} else {
|
||||||
|
object_property_parse(obj, value, property, &err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QObject *obj = qobject_from_json(value, &err);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
qmp_qom_set(path, property, obj, &err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hmp_handle_error(mon, err);
|
hmp_handle_error(mon, err);
|
||||||
|
@ -71,6 +83,7 @@ void hmp_qom_get(Monitor *mon, const QDict *qdict)
|
||||||
qobject_unref(str);
|
qobject_unref(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qobject_unref(obj);
|
||||||
hmp_handle_error(mon, err);
|
hmp_handle_error(mon, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,29 +167,17 @@ static unsigned long long now(void)
|
||||||
return (tv.tv_sec * 1000ull) + (tv.tv_usec / 1000ull);
|
return (tv.tv_sec * 1000ull) + (tv.tv_usec / 1000ull);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stressone(unsigned long long ramsizeMB)
|
static void stressone(unsigned long long ramsizeMB)
|
||||||
{
|
{
|
||||||
size_t pagesPerMB = 1024 * 1024 / PAGE_SIZE;
|
size_t pagesPerMB = 1024 * 1024 / PAGE_SIZE;
|
||||||
char *ram = malloc(ramsizeMB * 1024 * 1024);
|
g_autofree char *ram = g_malloc(ramsizeMB * 1024 * 1024);
|
||||||
char *ramptr;
|
char *ramptr;
|
||||||
size_t i, j, k;
|
size_t i, j, k;
|
||||||
char *data = malloc(PAGE_SIZE);
|
g_autofree char *data = g_malloc(PAGE_SIZE);
|
||||||
char *dataptr;
|
char *dataptr;
|
||||||
size_t nMB = 0;
|
size_t nMB = 0;
|
||||||
unsigned long long before, after;
|
unsigned long long before, after;
|
||||||
|
|
||||||
if (!ram) {
|
|
||||||
fprintf(stderr, "%s (%05d): ERROR: cannot allocate %llu MB of RAM: %s\n",
|
|
||||||
argv0, gettid(), ramsizeMB, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!data) {
|
|
||||||
fprintf(stderr, "%s (%d): ERROR: cannot allocate %d bytes of RAM: %s\n",
|
|
||||||
argv0, gettid(), PAGE_SIZE, strerror(errno));
|
|
||||||
free(ram);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We don't care about initial state, but we do want
|
/* We don't care about initial state, but we do want
|
||||||
* to fault it all into RAM, otherwise the first iter
|
* to fault it all into RAM, otherwise the first iter
|
||||||
* of the loop below will be quite slow. We can't use
|
* of the loop below will be quite slow. We can't use
|
||||||
|
@ -198,9 +186,7 @@ static int stressone(unsigned long long ramsizeMB)
|
||||||
memset(ram, 0xfe, ramsizeMB * 1024 * 1024);
|
memset(ram, 0xfe, ramsizeMB * 1024 * 1024);
|
||||||
|
|
||||||
if (random_bytes(data, PAGE_SIZE) < 0) {
|
if (random_bytes(data, PAGE_SIZE) < 0) {
|
||||||
free(ram);
|
return;
|
||||||
free(data);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
before = now();
|
before = now();
|
||||||
|
@ -227,9 +213,6 @@ static int stressone(unsigned long long ramsizeMB)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
|
||||||
free(ram);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,7 +225,7 @@ static void *stressthread(void *arg)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stress(unsigned long long ramsizeGB, int ncpus)
|
static void stress(unsigned long long ramsizeGB, int ncpus)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
unsigned long long ramsizeMB = ramsizeGB * 1024 / ncpus;
|
unsigned long long ramsizeMB = ramsizeGB * 1024 / ncpus;
|
||||||
|
@ -255,8 +238,6 @@ static int stress(unsigned long long ramsizeGB, int ncpus)
|
||||||
}
|
}
|
||||||
|
|
||||||
stressone(ramsizeMB);
|
stressone(ramsizeMB);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -352,8 +333,7 @@ int main(int argc, char **argv)
|
||||||
fprintf(stdout, "%s (%05d): INFO: RAM %llu GiB across %d CPUs\n",
|
fprintf(stdout, "%s (%05d): INFO: RAM %llu GiB across %d CPUs\n",
|
||||||
argv0, gettid(), ramsizeGB, ncpus);
|
argv0, gettid(), ramsizeGB, ncpus);
|
||||||
|
|
||||||
if (stress(ramsizeGB, ncpus) < 0)
|
stress(ramsizeGB, ncpus);
|
||||||
exit_failure();
|
|
||||||
|
|
||||||
exit_success();
|
exit_failure();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ static const int syscall_whitelist[] = {
|
||||||
SCMP_SYS(exit_group),
|
SCMP_SYS(exit_group),
|
||||||
SCMP_SYS(fallocate),
|
SCMP_SYS(fallocate),
|
||||||
SCMP_SYS(fchdir),
|
SCMP_SYS(fchdir),
|
||||||
|
SCMP_SYS(fchmod),
|
||||||
SCMP_SYS(fchmodat),
|
SCMP_SYS(fchmodat),
|
||||||
SCMP_SYS(fchownat),
|
SCMP_SYS(fchownat),
|
||||||
SCMP_SYS(fcntl),
|
SCMP_SYS(fcntl),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue