Skip to contentSkip to conversation

dump memory when host pci device is used by guest

RFC Superseded Wen Congyang 3 participants 12 messages Dec 20, 2011 – Dec 21, 2011 Kbuild

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover dump memory when host pci device is used by guest

Hi, all

'virsh dump' can not work when host pci device is used by guest. We have discussed this issue here:
http://lists.nongnu.org/archive/html/qemu-devel/2011-10/msg00736.html

We have determined to introduce a new command dump to dump memory. The core file's format can be elf.

Note:
1. The guest should be x86 or x86_64. The other arch is not supported.
2. If you use old gdb, gdb may crash. I use gdb-7.3.1, and it does not crash.
3. If the OS is in the second kernel, gdb may not work well, and crash can work by specifying '--machdep phys_addr=xxx' in the command line. The reason is that the second kernel will update the page table, and we can not get the page table for the first kernel.
4. If the guest OS is 32 bit and the memory size is larger than 4G, the vmcore is elf64 format. You should use the gdb which is built with --enable-64-bit-bfd.

Change from v2 to v3:
1. address Jan Kiszka's comment

Changes from v1 to v2:
1. fix virt addr in the vmcore.

Wen Congyang (8):
Add API to create memory mapping list
Add API to check whether a physical address is I/O address
target-i386: implement cpu_get_memory_mapping()
Add API to get memory mapping
target-i386: Add API to write elf notes to core file
target-i386: Add API to add extra memory mapping
target-i386: add API to get dump info
introduce a new monitor command 'dump' to dump guest's memory

 Makefile.target         |   11 +-
 cpu-all.h               |   18 ++
 cpu-common.h            |    1 +
 dump.c                  |  452 ++++++++++++++++++++++++++++++++++++
 dump.h                  |   14 ++
 exec.c                  |   20 ++
 hmp-commands.hx         |   16 ++
 memory_mapping.c        |  185 +++++++++++++++
 memory_mapping.h        |   39 ++++
 monitor.c               |    3 +
 qmp-commands.hx         |   24 ++
 target-i386/arch-dump.c |  578 +++++++++++++++++++++++++++++++++++++++++++++++
 12 files changed, 1356 insertions(+), 5 deletions(-)
 create mode 100644 dump.c
 create mode 100644 dump.h
 create mode 100644 memory_mapping.c
 create mode 100644 memory_mapping.h
 create mode 100644 target-i386/arch-dump.c
#1 lore raw

RFC PATCH v3 1/8 Add API to create memory mapping list

The memory mapping list stores virtual address and physical address mapping. The folloing patch will use this information to create PT_LOAD in the vmcore.

---
 Makefile.target  |    1 +
 memory_mapping.c |  130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory_mapping.h |   38 ++++++++++++++++
 3 files changed, 169 insertions(+), 0 deletions(-)
 create mode 100644 memory_mapping.c
 create mode 100644 memory_mapping.h
Makefile.target +1 -0
index 3261383..0d5286e 100644
@@ -197,6 +197,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += memory.o
+obj-y += memory_mapping.o
 LIBS+=-lz
 
 QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
memory_mapping.c new file +130 -0

130 lines not on this page · raw message

memory_mapping.h new file +38 -0
new file mode 100644
index 0000000..a4b1532
@@ -0,0 +1,38 @@
+#ifndef MEMORY_MAPPING_H
+#define MEMORY_MAPPING_H
+
+#include "qemu-queue.h"
+
+typedef struct MemoryMapping {
+    target_phys_addr_t phys_addr;
+    target_ulong virt_addr;
+    ram_addr_t length;
+    QTAILQ_ENTRY(MemoryMapping) next;
+} MemoryMapping;
+
+typedef struct MemoryMappingList {
+    unsigned int num;
+    QTAILQ_HEAD(, MemoryMapping) head;
+} MemoryMappingList;
+
+/*
+ * crash needs some memory mapping should be at the head of the list. It will
+ * cause the list is not sorted. So the caller must add the special memory
+ * mapping after adding all the normal memory mapping into list.
+ */
+void create_new_memory_mapping_head(MemoryMappingList *list,
+                                    target_phys_addr_t phys_addr,
+                                    target_phys_addr_t virt_addr,
+                                    ram_addr_t length);
+/*
+ * add or merge the memory region into the memory mapping's list. The list is
+ * sorted by phys_addr.
+ */
+void add_to_memory_mapping(MemoryMappingList *list,
+                           target_phys_addr_t phys_addr,
+                           target_phys_addr_t virt_addr,
+                           ram_addr_t length);
+
+void free_memory_mapping_list(MemoryMappingList *list);
+
+#endif
Signature · 1 line
1.7.1
#2 lore raw

RFC PATCH v3 2/8 Add API to check whether a physical address is I/O address

In reply to Wen Congyang

This API will be used in the following patch.

---
 cpu-common.h |    1 +
 exec.c       |   20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)
cpu-common.h +1 -0
index 8295e4f..75c01c3 100644
@@ -91,6 +91,7 @@ struct CPUPhysMemoryClient {
     QLIST_ENTRY(CPUPhysMemoryClient) list;
 };
 
+bool is_io_addr(target_phys_addr_t phys_addr);
 void cpu_register_phys_memory_client(CPUPhysMemoryClient *);
 void cpu_unregister_phys_memory_client(CPUPhysMemoryClient *);
 
exec.c +20 -0
index 32782b4..cf0ae8b 100644
@@ -4853,3 +4853,23 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
 #undef env
 
 #endif
+
+bool is_io_addr(target_phys_addr_t phys_addr)
+{
+    ram_addr_t pd;
+    PhysPageDesc *p;
+
+    p = phys_page_find(phys_addr >> TARGET_PAGE_BITS);
+    if (!p) {
+        pd = IO_MEM_UNASSIGNED;
+    } else {
+        pd = p->phys_offset;
+    }
+
+    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
+        /* I/O region */
+        return true;
+    }
+
+    return false;
+}
Signature · 1 line
1.7.1
#3 lore raw

RFC PATCH v3 3/8 target-i386: implement cpu_get_memory_mapping()

In reply to Wen Congyang

Walk cpu's page table and collect all virtual address and physical address mapping. Then, add these mapping into memory mapping list.

---
 Makefile.target         |    2 +-
 cpu-all.h               |    7 ++
 target-i386/arch-dump.c |  254 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 262 insertions(+), 1 deletions(-)
 create mode 100644 target-i386/arch-dump.c
Makefile.target +1 -1
index 0d5286e..29562ad 100644
@@ -73,7 +73,7 @@ libobj-$(CONFIG_TCG_INTERPRETER) += tci.o
 libobj-y += fpu/softfloat.o
 libobj-y += op_helper.o helper.o
 ifeq ($(TARGET_BASE_ARCH), i386)
-libobj-y += cpuid.o
+libobj-y += cpuid.o arch-dump.o
 endif
 libobj-$(TARGET_SPARC64) += vis_helper.o
 libobj-$(CONFIG_NEED_MMU) += mmu.o
cpu-all.h +7 -0
index 9d78715..a1f3bc2 100644
@@ -22,6 +22,7 @@
 #include "qemu-common.h"
 #include "qemu-tls.h"
 #include "cpu-common.h"
+#include "memory_mapping.h"
 
 /* some important defines:
  *
@@ -584,4 +585,10 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
 int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
                         uint8_t *buf, int len, int is_write);
 
+#if defined(TARGET_I386)
+void cpu_get_memory_mapping(MemoryMappingList *list, CPUState *env);
+#else
+#define cpu_get_memory_mapping(list, env)
+#endif
+
 #endif /* CPU_ALL_H */
target-i386/arch-dump.c new file +254 -0

254 lines not on this page · raw message

Signature · 1 line
1.7.1
#4 lore raw

RFC PATCH v3 4/8 Add API to get memory mapping

In reply to Wen Congyang

Add API to get all virtual address and physical address mapping. If there is no virtual address for some physical address, the virtual address is 0.

---
 memory_mapping.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 memory_mapping.h |    1 +
 2 files changed, 56 insertions(+), 0 deletions(-)
memory_mapping.c +55 -0
index d83b7d7..55c9266 100644
@@ -128,3 +128,58 @@ void free_memory_mapping_list(MemoryMappingList *list)
 
     list->num = 0;
 }
+
+void get_memory_mapping(MemoryMappingList *list)
+{
+    CPUState *env;
+    MemoryMapping *memory_mapping;
+    RAMBlock *block;
+    ram_addr_t offset, length;
+
+    last_mapping = NULL;
+
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        cpu_get_memory_mapping(list, env);
+    }
+
+    /* some memory may be not mapped, add them into memory mapping's list */
+    QLIST_FOREACH(block, &ram_list.blocks, next) {
+        offset = block->offset;
+        length = block->length;
+
+        QTAILQ_FOREACH(memory_mapping, &list->head, next) {
+            if (memory_mapping->phys_addr >= (offset + length)) {
+                /*
+                 * memory_mapping'list does not conatin the region
+                 * [offset, offset+length)
+                 */
+                create_new_memory_mapping(list, offset, 0, length);
+                break;
+            }
+
+            if ((memory_mapping->phys_addr + memory_mapping->length) <=
+                offset) {
+                continue;
+            }
+
+            if (memory_mapping->phys_addr > offset) {
+                /*
+                 * memory_mapping'list does not conatin the region
+                 * [offset, memory_mapping->phys_addr)
+                 */
+                create_new_memory_mapping(list, offset, 0,
+                                          memory_mapping->phys_addr - offset);
+            }
+
+            if ((offset + length) <=
+                (memory_mapping->phys_addr + memory_mapping->length)) {
+                break;
+            }
+            length -= memory_mapping->phys_addr + memory_mapping->length -
+                      offset;
+            offset = memory_mapping->phys_addr + memory_mapping->length;
+        }
+    }
+
+    return;
+}
memory_mapping.h +1 -0
index a4b1532..679f9ef 100644
@@ -34,5 +34,6 @@ void add_to_memory_mapping(MemoryMappingList *list,
                            ram_addr_t length);
 
 void free_memory_mapping_list(MemoryMappingList *list);
+void get_memory_mapping(MemoryMappingList *list);
 
 #endif
Signature · 1 line
1.7.1
#5 lore raw

RFC PATCH v3 5/8 target-i386: Add API to write elf notes to core file

In reply to Wen Congyang

The core file contains register's value. These API write registers to core file, and them will be called in the following patch.

---
 cpu-all.h               |    6 +
 target-i386/arch-dump.c |  246 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 252 insertions(+), 0 deletions(-)
cpu-all.h +6 -0
index a1f3bc2..038934d 100644
@@ -587,8 +587,14 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
 
 #if defined(TARGET_I386)
 void cpu_get_memory_mapping(MemoryMappingList *list, CPUState *env);
+int cpu_write_elf64_note(Monitor *mon, int fd, CPUState *env, int cpuid,
+                         target_phys_addr_t *offset);
+int cpu_write_elf32_note(Monitor *mon, int fd, CPUState *env, int cpuid,
+                         target_phys_addr_t *offset);
 #else
 #define cpu_get_memory_mapping(list, env)
+#define cpu_write_elf64_note(mon, fd, env, cpuid, offset) ({ -1; })
+#define cpu_write_elf32_note(mon, fd, env, cpuid, offset) ({ -1; })
 #endif
 
 #endif /* CPU_ALL_H */
target-i386/arch-dump.c +246 -0

257 lines not on this page · raw message

Signature · 1 line
1.7.1
#6 lore raw

RFC PATCH v3 6/8 target-i386: Add API to add extra memory mapping

In reply to Wen Congyang

Crash needs extra memory mapping to determine phys_base.

---
 cpu-all.h               |    2 ++
 target-i386/arch-dump.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)
cpu-all.h +2 -0
index 038934d..4d87d51 100644
@@ -591,10 +591,12 @@ int cpu_write_elf64_note(Monitor *mon, int fd, CPUState *env, int cpuid,
                          target_phys_addr_t *offset);
 int cpu_write_elf32_note(Monitor *mon, int fd, CPUState *env, int cpuid,
                          target_phys_addr_t *offset);
+int cpu_add_extra_memory_mapping(Monitor *mon, MemoryMappingList *list);
 #else
 #define cpu_get_memory_mapping(list, env)
 #define cpu_write_elf64_note(mon, fd, env, cpuid, offset) ({ -1; })
 #define cpu_write_elf32_note(mon, fd, env, cpuid, offset) ({ -1; })
+#define cpu_add_extra_memory_mapping(mon, list) ({ 0; })
 #endif
 
 #endif /* CPU_ALL_H */
target-i386/arch-dump.c +44 -0

47 lines not on this page · raw message

Signature · 1 line
1.7.1
#7 lore raw

RFC PATCH v3 7/8 target-i386: add API to get dump info

In reply to Wen Congyang

Dump info contains: endian, class and architecture. The next patch will use these information to create vmcore.

---
 cpu-all.h               |    3 +++
 dump.h                  |   10 ++++++++++
 target-i386/arch-dump.c |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 0 deletions(-)
 create mode 100644 dump.h
cpu-all.h +3 -0
index 4d87d51..c53221a 100644
@@ -23,6 +23,7 @@
 #include "qemu-tls.h"
 #include "cpu-common.h"
 #include "memory_mapping.h"
+#include "dump.h"
 
 /* some important defines:
  *
@@ -592,11 +593,13 @@ int cpu_write_elf64_note(Monitor *mon, int fd, CPUState *env, int cpuid,
 int cpu_write_elf32_note(Monitor *mon, int fd, CPUState *env, int cpuid,
                          target_phys_addr_t *offset);
 int cpu_add_extra_memory_mapping(Monitor *mon, MemoryMappingList *list);
+int cpu_get_dump_info(DumpInfo *info);
 #else
 #define cpu_get_memory_mapping(list, env)
 #define cpu_write_elf64_note(mon, fd, env, cpuid, offset) ({ -1; })
 #define cpu_write_elf32_note(mon, fd, env, cpuid, offset) ({ -1; })
 #define cpu_add_extra_memory_mapping(mon, list) ({ 0; })
+#define cpu_get_dump_info(info) ({ -1; })
 #endif
 
 #endif /* CPU_ALL_H */
dump.h new file +10 -0
new file mode 100644
index 0000000..a37de45
@@ -0,0 +1,10 @@
+#ifndef DUMP_H
+#define DUMP_H
+
+typedef struct DumpInfo {
+    int d_machine;  /* Architecture */
+    int d_endian;   /* ELFDATA2LSB or ELFDATA2MSB */
+    int d_class;    /* ELFCLASS32 or ELFCLASS64 */
+} DumpInfo;
+
+#endif
target-i386/arch-dump.c +34 -0
index 2410c6a..87b19b6 100644
@@ -15,6 +15,7 @@
 
 #include "cpu.h"
 #include "cpu-all.h"
+#include "dump.h"
 #include "monitor.h"
 
 /* PAE Paging or IA-32e Paging */
@@ -542,3 +543,36 @@ int cpu_add_extra_memory_mapping(Monitor *mon, MemoryMappingList *list)
 #endif
     return 0;
 }
+
+int cpu_get_dump_info(DumpInfo *info)
+{
+    bool lma = false;
+    RAMBlock *block;
+
+#ifdef TARGET_X86_64
+    lma = !!(first_cpu->hflags & HF_LMA_MASK);
+#endif
+
+    if (lma) {
+        info->d_machine = EM_X86_64;
+    } else {
+        info->d_machine = EM_386;
+    }
+    info->d_endian = ELFDATA2LSB;
+
+    if (lma) {
+        info->d_class = ELFCLASS64;
+    } else {
+        info->d_class = ELFCLASS32;
+    }
+
+    QLIST_FOREACH(block, &ram_list.blocks, next) {
+        if (!lma && (block->offset + block->length > UINT_MAX)) {
+            /* The memory size is greater than 4G */
+            info->d_class = ELFCLASS32;
+            break;
+        }
+    }
+
+    return 0;
+}
Signature · 1 line
1.7.1
#8 lore raw

RFC PATCH v3 8/8 introduce a new monitor command 'dump' to dump guest's memory

In reply to Wen Congyang
---
 Makefile.target |    8 +-
 dump.c          |  452 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 dump.h          |    4 +
 hmp-commands.hx |   16 ++
 monitor.c       |    3 +
 qmp-commands.hx |   24 +++
 6 files changed, 503 insertions(+), 4 deletions(-)
 create mode 100644 dump.c
Makefile.target +4 -4
index 29562ad..f7cc2b9 100644
@@ -110,7 +110,7 @@ $(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR
 QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
 obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
       elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
-      user-exec.o $(oslib-obj-y)
+      user-exec.o $(oslib-obj-y) dump.o
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 
@@ -148,7 +148,7 @@ LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 -image_base 0x0e000000
 LIBS+=-lmx
 
 obj-y = main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o \
-        gdbstub.o user-exec.o
+        gdbstub.o user-exec.o dump.o
 
 obj-i386-y += ioport-user.o
 
@@ -170,7 +170,7 @@ $(call set-vpath, $(SRC_PATH)/bsd-user)
 QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH)
 
 obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
-        gdbstub.o uaccess.o user-exec.o
+        gdbstub.o uaccess.o user-exec.o dump.o
 
 obj-i386-y += ioport-user.o
 
@@ -186,7 +186,7 @@ endif #CONFIG_BSD_USER
 # System emulator target
 ifdef CONFIG_SOFTMMU
 
-obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o
+obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o dump.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
 obj-$(CONFIG_NO_PCI) += pci-stub.o
dump.c new file +452 -0

452 lines not on this page · raw message

dump.h +4 -0
index a37de45..0280215 100644
@@ -1,10 +1,14 @@
 #ifndef DUMP_H
 #define DUMP_H
 
+#include "qdict.h"
+
 typedef struct DumpInfo {
     int d_machine;  /* Architecture */
     int d_endian;   /* ELFDATA2LSB or ELFDATA2MSB */
     int d_class;    /* ELFCLASS32 or ELFCLASS64 */
 } DumpInfo;
 
+int do_dump(Monitor *mon, const QDict *qdict, QObject **ret_data);
+
 #endif
hmp-commands.hx +16 -0
index 14838b7..49faa01 100644
@@ -767,6 +767,22 @@ Migrate to @var{uri} (using -d to not wait for completion).
 ETEXI
 
     {
+        .name       = "dump",
+        .args_type  = "file:s",
+        .params     = "file",
+        .help       = "dump to file",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = do_dump,
+    },
+
+
+STEXI
+@item dump @var{file}
+@findex dump
+Dump to @var{file}.
+ETEXI
+
+    {
         .name       = "migrate_cancel",
         .args_type  = "",
         .params     = "",
monitor.c +3 -0
index 7334401..edd6aa7 100644
@@ -73,6 +73,9 @@
 #endif
 #include "hw/lm32_pic.h"
 
+/* for dump */
+#include "dump.h"
+
 //#define DEBUG
 //#define DEBUG_COMPLETION
 
qmp-commands.hx +24 -0
index 7e3f4b9..34c7593 100644
@@ -469,6 +469,30 @@ Notes:
 EQMP
 
     {
+        .name       = "dump",
+        .args_type  = "file:s",
+        .params     = "file",
+        .help       = "dump to file",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = do_dump,
+    },
+
+SQMP
+dump
+-------
+
+Dump to file.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "dump", "arguments": { "file": "fd:dump" } }
+<- { "return": {} }
+
+EQMP
+
+    {
         .name       = "migrate_cancel",
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_input_migrate_cancel,
Signature · 1 line
1.7.1
#9 lore raw

Re: [Qemu-devel] [RFC][PATCH 8/8 v3] introduce a new monitor command 'dump' to dump guest's memory

Quoted 13 lines · Wen Congyang
---
 Makefile.target |    8 +-
 dump.c          |  452 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 dump.h          |    4 +
 hmp-commands.hx |   16 ++
 monitor.c       |    3 +
 qmp-commands.hx |   24 +++
 6 files changed, 503 insertions(+), 4 deletions(-)
 create mode 100644 dump.c

+++ b/qmp-commands.hx

qmp-commands.hx Notes: · line 478

Quoted 10 lines
qmp-commands.hx +7 -0
@@ -469,6 +469,30 @@ Notes:
 EQMP
 
     {
+        .name       = "dump",
+        .args_type  = "file:s",
+        .params     = "file",
+        .help       = "dump to file",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = do_dump,
+    },

From a libvirt perspective, we would like the option to be able to pass in an already-open fd rather than just a file name. This is possible if the 'file' argument is required to start with '/' for an absolute path, vs. 'file:name' for an fd previously passed in via the getfd monitor command.

Also, does this command block? It sounds like it is long-running, which means it probably needs to be asynchronous, as well as issue an event upon completion, so that other monitor commands can be issued in the meantime.

Signature · 2 lines
Eric Blake   [email protected]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org
#10 lore raw

Re: [Qemu-devel] [RFC][PATCH 8/8 v3] introduce a new monitor command 'dump' to dump guest's memory

At 12/21/2011 12:25 AM, Eric Blake Write:

Quoted 16 lines · Wen Congyang
Quoted 15 lines
---
 Makefile.target |    8 +-
 dump.c          |  452 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 dump.h          |    4 +
 hmp-commands.hx |   16 ++
 monitor.c       |    3 +
 qmp-commands.hx |   24 +++
 6 files changed, 503 insertions(+), 4 deletions(-)
 create mode 100644 dump.c

+++ b/qmp-commands.hx

(quoted diff) +0 -0
@@ -469,6 +469,30 @@ Notes:
 EQMP
 
Quoted 14 lines

hmp-commands.hx Migrate to @var{uri} (using -d to not wait for completion). · line 776

Quoted 8 lines
hmp-commands.hx +7 -0
     {
+        .name       = "dump",
+        .args_type  = "file:s",
+        .params     = "file",
+        .help       = "dump to file",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = do_dump,
+    },

From a libvirt perspective, we would like the option to be able to pass in an already-open fd rather than just a file name. This is possible if the 'file' argument is required to start with '/' for an absolute path, vs. 'file:name' for an fd previously passed in via the getfd monitor command.

file:s means the parameter is a file, and the type is string. s can be file:path or fd:fd's name here. Sorry for confusing you.

Quoted 6 lines

Also, does this command block? It sounds like it is long-running, which means it probably needs to be asynchronous, as well as issue an event upon completion, so that other monitor commands can be issued in the meantime.

Good idea, i will try to implement it in the next version.

Thanks
Wen Congyang

#11 lore raw

Re: [Qemu-devel] [RFC][PATCH 8/8 v3] introduce a new monitor command 'dump' to dump guest's memory

In reply to Eric Blake
Quoted 31 lines · Eric Blake
Quoted 15 lines · Wen Congyang

---
 Makefile.target |    8 +-
 dump.c          |  452 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ dump.h          |    4 +
 hmp-commands.hx |   16 ++
 monitor.c       |    3 +
 qmp-commands.hx |   24 +++

 6 files changed, 503 insertions(+), 4 deletions(-)

 create mode 100644 dump.c

+++ b/qmp-commands.hx

(quoted diff) +0 -0
@@ -469,6 +469,30 @@ Notes:

 EQMP

Quoted 8 lines

     {
+        .name       = "dump",
+        .args_type  = "file:s",
+        .params     = "file",
+        .help       = "dump to file",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = do_dump,
+    },

From a libvirt perspective, we would like the option to be able to pass in an already-open fd rather than just a file name.  This is possible if the 'file' argument is required to start with '/' for an absolute path, vs. 'file:name' for an fd previously passed in via the getfd monitor command.

Quoted 4 lines

Also, does this command block?  It sounds like it is long-running, which means it probably needs to be asynchronous, as well as issue an event upon completion, so that other monitor commands can be issued in the meantime.

Note that it needs to stop the VM and it'd need to prevent other commands from resuming if this command becomes asynchronous, like during migration.

Cheers