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:
Peter Maydell 2020-06-18 15:30:13 +01:00
commit eefe34ea4b
7 changed files with 56 additions and 51 deletions

View file

@ -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

View file

@ -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",
}, },

View file

@ -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];

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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();
} }

View file

@ -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),