From: Bohdan Trach <bohdan.tr...@mailbox.tu-dresden.de> dump-pc-mem command is added for checkpointing guest memory to file. Only system RAM region is saved. This checkpoint is later used to recover unchanged pages.
Signed-off-by: Bohdan Trach <bohdan.tr...@mailbox.tu-dresden.de> --- arch_init.c | 19 +++++++++++++++++++ hmp-commands.hx | 16 ++++++++++++++++ hmp.c | 9 +++++++++ hmp.h | 1 + qapi-schema.json | 11 +++++++++++ qmp-commands.hx | 19 +++++++++++++++++++ 6 files changed, 75 insertions(+) diff --git a/arch_init.c b/arch_init.c index 4c8fcee..b8a4fb1 100644 --- a/arch_init.c +++ b/arch_init.c @@ -603,6 +603,25 @@ static void migration_bitmap_sync(void) } } +void qmp_dump_pc_ram(const char *file, Error **errp) { + + int rc; + int fd; + fd = open(file, + O_CREAT|O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + assert(-1 != fd); + + RAMBlock *block = QLIST_FIRST_RCU(&ram_list.blocks); + uint64_t offset; + for (offset=0; offset<ram_size; offset+=TARGET_PAGE_SIZE) { + rc = write(fd, block->host+offset, TARGET_PAGE_SIZE); + assert(TARGET_PAGE_SIZE == rc); + } + rc = close(fd); + assert(0 == rc); +} + /** * ram_save_page: Send the given page to the stream * diff --git a/hmp-commands.hx b/hmp-commands.hx index 3089533..0c47a4f 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1043,6 +1043,22 @@ gdb. Without -z|-l|-s, the dump format is ELF. ETEXI { + .name = "dump-pc-ram", + .args_type = "filename:F", + .params = "filename", + .help = "dump pc ram to file", + .mhandler.cmd = hmp_dump_pc_ram, + }, + + +STEXI +@item dump-pc-ram +@findex dump-guest-memory +Dump pc ram to file. + filename: dump file name +ETEXI + + { .name = "snapshot_blkdev", .args_type = "reuse:-n,device:B,snapshot-file:s?,format:s?", .params = "[-n] device [new-image-file] [format]", diff --git a/hmp.c b/hmp.c index f31ae27..5e27dd8 100644 --- a/hmp.c +++ b/hmp.c @@ -1473,6 +1473,15 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict) g_free(prot); } +void hmp_dump_pc_ram(Monitor *mon, const QDict *qdict) +{ + Error *errp = NULL; + const char *file = qdict_get_str(qdict, "filename"); + + qmp_dump_pc_ram(file, &errp); + hmp_handle_error(mon, &errp); +} + void hmp_netdev_add(Monitor *mon, const QDict *qdict) { Error *err = NULL; diff --git a/hmp.h b/hmp.h index 2b9308b..805a71b 100644 --- a/hmp.h +++ b/hmp.h @@ -79,6 +79,7 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict); void hmp_migrate(Monitor *mon, const QDict *qdict); void hmp_device_del(Monitor *mon, const QDict *qdict); void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict); +void hmp_dump_pc_ram(Monitor *mon, const QDict *qdict); void hmp_netdev_add(Monitor *mon, const QDict *qdict); void hmp_netdev_del(Monitor *mon, const QDict *qdict); void hmp_getfd(Monitor *mon, const QDict *qdict); diff --git a/qapi-schema.json b/qapi-schema.json index ac9594d..338bfd3 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3648,3 +3648,14 @@ # Since: 2.1 ## { 'command': 'rtc-reset-reinjection' } + +## +# @dump-pc-ram: +# +# Checkpoints guest. +# +# @file: the file to save the memory to as binary data +# +# Returns: Nothing on success +## +{ 'command': 'dump-pc-ram', 'data': {'file': 'str'} } diff --git a/qmp-commands.hx b/qmp-commands.hx index 3a42ad0..0be3c42 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -854,6 +854,25 @@ Notes: EQMP { + .name = "dump-pc-ram", + .args_type = "file:s", + .params = "file", + .help = "dump pc ram to file", + .user_print = monitor_user_noop, + .mhandler.cmd_new = qmp_marshal_input_dump_pc_ram, + }, + +SQMP +dump + + +Dump pc ram to file. + +Arguments: + +EQMP + + { .name = "query-dump-guest-memory-capability", .args_type = "", .mhandler.cmd_new = qmp_marshal_input_query_dump_guest_memory_capability, -- 2.0.5