Let the user to choose whether to block other monitor command while dumping.
Signed-off-by: Wen Congyang <we...@cn.fujitsu.com> --- dump.c | 2 +- hmp-commands.hx | 9 +++++---- hmp.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- qapi-schema.json | 3 ++- qmp-commands.hx | 7 +++++-- 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/dump.c b/dump.c index 8224116..dd3a72c 100644 --- a/dump.c +++ b/dump.c @@ -721,7 +721,7 @@ static DumpState *dump_init_fd(int fd, Error **errp) return s; } -void qmp_dump(const char *file, Error **errp) +void qmp_dump(bool detach, const char *file, Error **errp) { const char *p; int fd = -1; diff --git a/hmp-commands.hx b/hmp-commands.hx index 0c0a7b4..bd0c95d 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -883,20 +883,21 @@ ETEXI #if defined(CONFIG_HAVE_CORE_DUMP) { .name = "dump", - .args_type = "file:s", - .params = "file", - .help = "dump to file", + .args_type = "detach:-d,file:s", + .params = "[-d] file", + .help = "dump to file (using -d to not wait for completion)", .user_print = monitor_user_noop, .mhandler.cmd = hmp_dump, }, STEXI -@item dump @var{file} +@item dump [-d] @var{file} @findex dump Dump to @var{file}. The file can be processed with crash or gdb. file: destination file(started with "file:") or destination file descriptor (started with "fd:") + -d: donot wait for completion. ETEXI #endif diff --git a/hmp.c b/hmp.c index 476d355..707701b 100644 --- a/hmp.c +++ b/hmp.c @@ -857,13 +857,58 @@ void hmp_block_job_cancel(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &error); } +typedef struct DumpingStatus +{ + QEMUTimer *timer; + Monitor *mon; +} DumpingStatus; + +static void hmp_dumping_status_cb(void *opaque) +{ + DumpingStatus *status = opaque; + DumpInfo *info; + + info = qmp_query_dump(NULL); + if (!info->has_status || strcmp(info->status, "active") == 0) { + qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock) + 1000); + } else { + monitor_resume(status->mon); + qemu_del_timer(status->timer); + g_free(status); + } + + qapi_free_DumpInfo(info); +} + void hmp_dump(Monitor *mon, const QDict *qdict) { Error *errp = NULL; + int detach = qdict_get_try_bool(qdict, "detach", 0); const char *file = qdict_get_str(qdict, "file"); - qmp_dump(file, &errp); - hmp_handle_error(mon, &errp); + qmp_dump(!!detach, file, &errp); + if (errp) { + hmp_handle_error(mon, &errp); + return; + } + + if (!detach) { + DumpingStatus *status; + int ret; + + ret = monitor_suspend(mon); + if (ret < 0) { + monitor_printf(mon, "terminal does not allow synchronous " + "migration, continuing detached\n"); + return; + } + + status = g_malloc0(sizeof(*status)); + status->mon = mon; + status->timer = qemu_new_timer_ms(rt_clock, hmp_dumping_status_cb, + status); + qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock)); + } } void hmp_dump_cancel(Monitor *mon, const QDict *qdict) diff --git a/qapi-schema.json b/qapi-schema.json index 1e9af32..ed157d7 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1599,13 +1599,14 @@ # # Dump guest's memory to vmcore. # +# @detach: detached dumping. # @file: the filename or file descriptor of the vmcore. # # Returns: nothing on success # # Since: 1.1 ## -{ 'command': 'dump', 'data': { 'file': 'str' } } +{ 'command': 'dump', 'data': { 'detach': 'bool', 'file': 'str' } } ## # @dump_cancel diff --git a/qmp-commands.hx b/qmp-commands.hx index 666f1bc..c7b9c82 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -589,8 +589,8 @@ EQMP #if defined(CONFIG_HAVE_CORE_DUMP) { .name = "dump", - .args_type = "file:s", - .params = "file", + .args_type = "detach:-d,file:s", + .params = "[-d] file", .help = "dump to file", .user_print = monitor_user_noop, .mhandler.cmd_new = qmp_marshal_input_dump, @@ -616,6 +616,9 @@ Notes: (1) The 'info dump' command should be used to check dumping's progress and final result (this information is provided by the 'status' member) +(2) All boolean arguments default to false +(3) The user Monitor's "detach" argument is invalid in QMP and should not + be used EQMP #endif -- 1.7.1