[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 6/8] dump-query: implement "status" of "dump-quer
From: |
Peter Xu |
Subject: |
[Qemu-devel] [PATCH v2 6/8] dump-query: implement "status" of "dump-query" command. |
Date: |
Fri, 27 Nov 2015 10:48:15 +0800 |
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!).
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);
--
2.4.3
[Qemu-devel] [PATCH v2 6/8] dump-query: implement "status" of "dump-query" command.,
Peter Xu <=
[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