If "detach" is provided, one thread is created to do the dump work,
while main thread will return immediately. For each GuestPhysBlock,
adding one more field "mr" to points to MemoryRegion that it
belongs, also ref the mr before use.
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-Id: <
1455772616-8668-8-git-send-email-peterx@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+static void *dump_thread(void *data)
+{
+ Error *err = NULL;
+ DumpState *s = (DumpState *)data;
+
+ dump_process(s, &err);
+
+ if (err) {
+ /* TODO: notify user the error */
+ error_free(err);
+ }
+ return NULL;
+}
+
void qmp_dump_guest_memory(bool paging, const char *file,
bool has_detach, bool detach,
bool has_begin, int64_t begin, bool has_length,
void qmp_dump_guest_memory(bool paging, const char *file,
bool has_detach, bool detach,
bool has_begin, int64_t begin, bool has_length,
int fd = -1;
DumpState *s;
Error *local_err = NULL;
int fd = -1;
DumpState *s;
Error *local_err = NULL;
if (runstate_check(RUN_STATE_INMIGRATE)) {
error_setg(errp, "Dump not allowed during incoming migration.");
if (runstate_check(RUN_STATE_INMIGRATE)) {
error_setg(errp, "Dump not allowed during incoming migration.");
error_setg(errp, QERR_MISSING_PARAMETER, "begin");
return;
}
error_setg(errp, QERR_MISSING_PARAMETER, "begin");
return;
}
+ if (has_detach) {
+ detach_p = detach;
+ }
/* check whether lzo/snappy is supported */
#ifndef CONFIG_LZO
/* check whether lzo/snappy is supported */
#ifndef CONFIG_LZO
+ if (detach_p) {
+ /* detached dump */
+ qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread,
+ s, QEMU_THREAD_DETACHED);
+ } else {
+ /* sync dump */
+ dump_process(s, errp);
+ }
}
DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
}
DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
bool has_format; /* whether format is provided */
DumpGuestMemoryFormat format; /* valid only if has_format == true */
bool has_format; /* whether format is provided */
DumpGuestMemoryFormat format; /* valid only if has_format == true */
+ QemuThread dump_thread; /* thread for detached dump */
} DumpState;
uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
} DumpState;
uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
#include "qemu/queue.h"
#include "qemu/typedefs.h"
#include "qemu/queue.h"
#include "qemu/typedefs.h"
+#include "exec/memory.h"
typedef struct GuestPhysBlock {
/* visible to guest, reflects PCI hole, etc */
typedef struct GuestPhysBlock {
/* visible to guest, reflects PCI hole, etc */
/* points into host memory */
uint8_t *host_addr;
/* points into host memory */
uint8_t *host_addr;
+ /* points to the MemoryRegion that this block belongs to */
+ MemoryRegion *mr;
+
QTAILQ_ENTRY(GuestPhysBlock) next;
} GuestPhysBlock;
QTAILQ_ENTRY(GuestPhysBlock) next;
} GuestPhysBlock;
QTAILQ_FOREACH_SAFE(p, &list->head, next, q) {
QTAILQ_REMOVE(&list->head, p, next);
QTAILQ_FOREACH_SAFE(p, &list->head, next, q) {
QTAILQ_REMOVE(&list->head, p, next);
+ memory_region_unref(p->mr);
g_free(p);
}
list->num = 0;
g_free(p);
}
list->num = 0;
block->target_start = target_start;
block->target_end = target_end;
block->host_addr = host_addr;
block->target_start = target_start;
block->target_end = target_end;
block->host_addr = host_addr;
+ block->mr = section->mr;
+ memory_region_ref(section->mr);
QTAILQ_INSERT_TAIL(&g->list->head, block, next);
++g->list->num;
QTAILQ_INSERT_TAIL(&g->list->head, block, next);
++g->list->num;