[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 6/8] dump-query: implement "status" of "dump-
From: |
Peter Xu |
Subject: |
Re: [Qemu-devel] [PATCH v2 6/8] dump-query: implement "status" of "dump-query" command. |
Date: |
Fri, 27 Nov 2015 19:42:49 +0800 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
On Fri, Nov 27, 2015 at 11:22:48AM +0100, Paolo Bonzini wrote:
>
>
> On 27/11/2015 03:48, Peter Xu wrote:
> > This patch implements the status changes inside dump process. When
> > query dump status, three possible results could be:
> >
> > 1. never started dump:
> > { "status": "NOT_STARTED", "percentage": "N/A" }
> >
> > 2. one dump is running in background:
> > { "status": "IN_PROGRESS", "percentage": "{0..100}%" }
> >
> > 3. no dump is running, and the last dump has finished:
> > { "status": "SUCCEEDED|FAILED", "percentage": "N/A" }
> >
> > It's mostly done. Except that we might need more accurate
> > "percentage" results (which is now 50% all the time!).
>
> As mentioned early, you can use an enum. QEMU usually prints enums in
> lowercase and separates words with "-". Similar to MigrationStatus you
> can use none, active, completed, failed. In fact you might even reuse
> MigrationStatus directly, it's simpler.
I think it might be a little big confusing if I use MigrationStatus
directly. I can define a enum.
>
> The percentage is not necessary as part of the QMP return value. You
> can compute it in hmp_info_dump however and print it to HMP only.
Ok, Then I will drop percentage in QMP query.
>
> I think you can structure the patches like this:
>
> add basic "detach" support
> add qmp event DUMP_COMPLETED
> add total_size and written_size to DumpState
> add "query-dump" QMP command
> add "info dump" HMP command
>
> where the fourth patch already sets all fields correctly.
Ok. Will reorder the patches and make sure there are no fake values
any more.
Thanks!
Peter
>
> Thanks,
>
> Paolo
>
> > Signed-off-by: Peter Xu <address@hidden>
> > ---
> > dump.c | 57
> > +++++++++++++++++++++++++++++++++++++++++++--------
> > hmp.c | 7 +++++--
> > include/qemu-common.h | 4 ++++
> > include/sysemu/dump.h | 13 ++++++++++--
> > 4 files changed, 68 insertions(+), 13 deletions(-)
> >
> > diff --git a/dump.c b/dump.c
> > index 446a991..25298b7 100644
> > --- a/dump.c
> > +++ b/dump.c
> > @@ -1594,11 +1594,44 @@ static GlobalDumpState *dump_state_get_global(void)
> > if (unlikely(!init)) {
> > qemu_mutex_init(&global_dump_state.gds_mutex);
> > global_dump_state.gds_cur = NULL;
> > + global_dump_state.gds_result = DUMP_RES_NOT_STARTED;
> > init = true;
> > }
> > return &global_dump_state;
> > }
> >
> > +static const char *const dump_result_table[] = {
> > + [DUMP_RES_NOT_STARTED] = "NOT_STARTED",
> > + [DUMP_RES_IN_PROGRESS] = "IN_PROGRESS",
> > + [DUMP_RES_SUCCEEDED] = "SUCCEEDED",
> > + [DUMP_RES_FAILED] = "FAILED",
> > +};
> > +
> > +/* Returns DumpStatus. Caller should be responsible to free the
> > + * resources using qapi_free_DumpStatus(). */
> > +DumpStatus *dump_status_query(void)
> > +{
> > + DumpStatus *status = g_malloc0(sizeof(*status));
> > + int percentage = 50;
> > + char buf[64] = {0};
> > +
> > + GlobalDumpState *global = dump_state_get_global();
> > + qemu_mutex_lock(&global->gds_mutex);
> > +
> > + /* TBD: get correct percentage */
> > + status->status = g_strdup(dump_result_table[global->gds_result]);
> > + if (global->gds_result == DUMP_RES_IN_PROGRESS) {
> > + snprintf(buf, sizeof(buf) - 1, "%d%%", percentage);
> > + status->percentage = g_strdup(buf);
> > + } else {
> > + status->percentage = g_strdup("N/A");
> > + }
> > +
> > + qemu_mutex_unlock(&global->gds_mutex);
> > +
> > + return status;
> > +}
> > +
> > /* Returns non-zero if there is existing dump in progress, otherwise
> > * zero is returned. */
> > bool dump_in_progress(void)
> > @@ -1620,27 +1653,37 @@ static DumpState *dump_state_create(GlobalDumpState
> > *global)
> > cur = global->gds_cur;
> > if (cur) {
> > /* one dump in progress */
> > + assert(global->gds_result == DUMP_RES_IN_PROGRESS);
> > cur = NULL;
> > } else {
> > /* we are the first! */
> > + assert(global->gds_result != DUMP_RES_IN_PROGRESS);
> > cur = g_malloc0(sizeof(*cur));
> > global->gds_cur = cur;
> > }
> > + global->gds_result = DUMP_RES_IN_PROGRESS;
> >
> > qemu_mutex_unlock(&global->gds_mutex);
> > return cur;
> > }
> >
> > -/* release current DumpState structure */
> > -static void dump_state_release(GlobalDumpState *global)
> > +/* release current DumpState structure. "done" is hint to show
> > + * whether the dump is succeeded or not. */
> > +static void dump_state_release(GlobalDumpState *global, bool done)
> > {
> > DumpState *cur = NULL;
> > qemu_mutex_lock(&global->gds_mutex);
> >
> > + assert(global->gds_result == DUMP_RES_IN_PROGRESS);
> > cur = global->gds_cur;
> > /* we should never call release before having one */
> > assert(cur);
> > global->gds_cur = NULL;
> > + if (done) {
> > + global->gds_result = DUMP_RES_SUCCEEDED;
> > + } else {
> > + global->gds_result = DUMP_RES_FAILED;
> > + }
> >
> > qemu_mutex_unlock(&global->gds_mutex);
> > dump_cleanup(cur);
> > @@ -1664,7 +1707,7 @@ static void *dump_thread(void *data)
> > const char *msg = "Dump completed successfully";
> >
> > dump_process(global->gds_cur, &local_err);
> > - dump_state_release(global);
> > + dump_state_release(global, (local_err == NULL));
> >
> > /* if detach is used, notify user that dump has finished */
> > if (local_err) {
> > @@ -1769,7 +1812,7 @@ void qmp_dump_guest_memory(bool paging, const char
> > *file,
> > if (!detach_p) {
> > /* sync dump */
> > dump_process(s, errp);
> > - dump_state_release(global);
> > + dump_state_release(global, (*errp == NULL));
> > } else {
> > qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread,
> > global, QEMU_THREAD_DETACHED);
> > @@ -1779,11 +1822,7 @@ void qmp_dump_guest_memory(bool paging, const char
> > *file,
> >
> > DumpStatus *qmp_dump_query(Error **errp)
> > {
> > - DumpStatus *status = g_malloc0(sizeof(*status));
> > - /* TBD */
> > - status->status = g_strdup("WORKING");
> > - status->percentage = g_strdup("50%");
> > - return status;
> > + return dump_status_query();
> > }
> >
> > DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error
> > **errp)
> > diff --git a/hmp.c b/hmp.c
> > index 6d9c127..049ac4b 100644
> > --- a/hmp.c
> > +++ b/hmp.c
> > @@ -1578,8 +1578,11 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
> >
> > void hmp_dump_query(Monitor *mon, const QDict *qdict)
> > {
> > - /* TBD */
> > - monitor_printf(mon, "QUERY DUMP STATUS\n");
> > + DumpStatus *status = dump_status_query();
> > + assert(status);
> > + monitor_printf(mon, "STATUS: %s\n", status->status);
> > + monitor_printf(mon, "PERCENTAGE: %s\n", status->percentage);
> > + qapi_free_DumpStatus(status);
> > }
> >
> > void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
> > diff --git a/include/qemu-common.h b/include/qemu-common.h
> > index 7b74961..fbfa852 100644
> > --- a/include/qemu-common.h
> > +++ b/include/qemu-common.h
> > @@ -505,4 +505,8 @@ void page_size_init(void);
> > * returned. */
> > bool dump_in_progress(void);
> >
> > +/* Returns DumpStatus. Caller should be responsible to free the
> > + * resources using qapi_free_DumpStatus(). */
> > +DumpStatus *dump_status_query(void);
> > +
> > #endif
> > diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
> > index 13c913e..0f0a463 100644
> > --- a/include/sysemu/dump.h
> > +++ b/include/sysemu/dump.h
> > @@ -189,9 +189,18 @@ typedef struct DumpState {
> > DumpGuestMemoryFormat format; /* valid only if has_format == true */
> > } DumpState;
> >
> > +typedef enum DumpResult {
> > + DUMP_RES_NOT_STARTED = 0,
> > + DUMP_RES_IN_PROGRESS,
> > + DUMP_RES_SUCCEEDED,
> > + DUMP_RES_FAILED,
> > + DUMP_RES_MAX,
> > +} DumpResult;
> > +
> > typedef struct GlobalDumpState {
> > - QemuMutex gds_mutex; /* protector for GlobalDumpState itself */
> > - DumpState *gds_cur; /* current DumpState (might be NULL) */
> > + QemuMutex gds_mutex; /* protector for GlobalDumpState itself */
> > + DumpState *gds_cur; /* current DumpState (might be NULL) */
> > + DumpResult gds_result; /* current dump result */
> > } GlobalDumpState;
> >
> > uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
> >
- Re: [Qemu-devel] [PATCH v2 4/8] dump-guest-memory: add qmp event DUMP_COMPLETED, (continued)
[Qemu-devel] [PATCH v2 6/8] dump-query: implement "status" of "dump-query" command., Peter Xu, 2015/11/26
[Qemu-devel] [PATCH v2 7/8] DumpState: adding total_size and written_size fields, Peter Xu, 2015/11/26
[Qemu-devel] [PATCH v2 8/8] dump-query: make the percentage accurate., Peter Xu, 2015/11/26
Re: [Qemu-devel] [PATCH v2 0/8] Add basic "detach" support for dump-guest-memory, Peter Xu, 2015/11/26
Re: [Qemu-devel] [PATCH v2 0/8] Add basic "detach" support for dump-guest-memory, Fam Zheng, 2015/11/27