* [Qemu-devel] [PULL 01/32] QMP: Allow dot separated dict path arguments in qmp-shell
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
@ 2014-03-03 17:11 ` Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 02/32] MAINTAINERS: update status for HMP, QAPI and QMP trees Luiz Capitulino
` (31 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:11 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Fam Zheng <famz@redhat.com>
As another convenience to allow using commands that expect a dict as
argument, this patch adds support for foo.bar=value syntax, similar to
command line argument style:
(QEMU) blockdev-add options.driver=file options.id=drive1 options.filename=...
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
scripts/qmp/qmp-shell | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index d374b35..e0e848b 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -112,13 +112,29 @@ class QMPShell(qmp.QEMUMonitorProtocol):
value = json.loads(opt[1])
else:
value = opt[1]
- qmpcmd['arguments'][opt[0]] = value
+ optpath = opt[0].split('.')
+ parent = qmpcmd['arguments']
+ curpath = []
+ for p in optpath[:-1]:
+ curpath.append(p)
+ d = parent.get(p, {})
+ if type(d) is not dict:
+ raise QMPShellError('Cannot use "%s" as both leaf and non-leaf key' % '.'.join(curpath))
+ parent[p] = d
+ parent = d
+ if optpath[-1] in parent:
+ if type(parent[optpath[-1]]) is dict:
+ raise QMPShellError('Cannot use "%s" as both leaf and non-leaf key' % '.'.join(curpath))
+ else:
+ raise QMPShellError('Cannot set "%s" multiple times' % opt[0])
+ parent[optpath[-1]] = value
return qmpcmd
def _execute_cmd(self, cmdline):
try:
qmpcmd = self.__build_cmd(cmdline)
- except:
+ except Exception, e:
+ print 'Error while parsing command line: %s' % e
print 'command format: <command-name> ',
print '[arg-name1=arg1] ... [arg-nameN=argN]'
return True
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 02/32] MAINTAINERS: update status for HMP, QAPI and QMP trees
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 01/32] QMP: Allow dot separated dict path arguments in qmp-shell Luiz Capitulino
@ 2014-03-03 17:11 ` Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 03/32] dump: const-qualify the buf of WriteCoreDumpFunction Luiz Capitulino
` (30 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:11 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
This commit updates the status for the HMP, QAPI and QMP trees from
"Supported" to "Maintained".
In practice this means that patch review and pull requests may take
longer. Also, I'll rely more on reviewers such as Eric Blake so that
I'm able to send pull requests regularly.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
MAINTAINERS | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 026ea4f..7efaccf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -726,7 +726,7 @@ F: vl.c
Human Monitor (HMP)
M: Luiz Capitulino <lcapitulino@redhat.com>
-S: Supported
+S: Maintained
F: monitor.c
F: hmp.c
F: hmp-commands.hx
@@ -758,7 +758,7 @@ T: git git://github.com/bonzini/qemu.git nbd-next
QAPI
M: Luiz Capitulino <lcapitulino@redhat.com>
M: Michael Roth <mdroth@linux.vnet.ibm.com>
-S: Supported
+S: Maintained
F: qapi/
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
@@ -772,7 +772,7 @@ T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
QMP
M: Luiz Capitulino <lcapitulino@redhat.com>
-S: Supported
+S: Maintained
F: qmp.c
F: monitor.c
F: qmp-commands.hx
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 03/32] dump: const-qualify the buf of WriteCoreDumpFunction
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 01/32] QMP: Allow dot separated dict path arguments in qmp-shell Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 02/32] MAINTAINERS: update status for HMP, QAPI and QMP trees Luiz Capitulino
@ 2014-03-03 17:11 ` Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 04/32] dump: add argument to write_elfxx_notes Luiz Capitulino
` (29 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:11 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
WriteCoreDumpFunction is a function pointer that points to the function used to
write content in "buf" into core file, so "buf" should be const-qualify.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 2 +-
include/qom/cpu.h | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/dump.c b/dump.c
index 80a9116..42622de 100644
--- a/dump.c
+++ b/dump.c
@@ -99,7 +99,7 @@ static void dump_error(DumpState *s, const char *reason)
dump_cleanup(s);
}
-static int fd_write_vmcore(void *buf, size_t size, void *opaque)
+static int fd_write_vmcore(const void *buf, size_t size, void *opaque)
{
DumpState *s = opaque;
size_t written_size;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 367eda1..d734be8 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -28,7 +28,8 @@
#include "qemu/tls.h"
#include "qemu/typedefs.h"
-typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
+typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
+ void *opaque);
/**
* vaddr:
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 04/32] dump: add argument to write_elfxx_notes
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (2 preceding siblings ...)
2014-03-03 17:11 ` [Qemu-devel] [PULL 03/32] dump: const-qualify the buf of WriteCoreDumpFunction Luiz Capitulino
@ 2014-03-03 17:11 ` Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 05/32] dump: add API to write header of flatten format Luiz Capitulino
` (28 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:11 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
write_elf32_notes/wirte_elf64_notes use fd_write_vmcore to write elf notes to
vmcore. Adding parameter "WriteCoreDumpFunction f" makes it available to choose
the method of writing elf notes
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/dump.c b/dump.c
index 42622de..c9d3492 100644
--- a/dump.c
+++ b/dump.c
@@ -271,7 +271,7 @@ static inline int cpu_index(CPUState *cpu)
return cpu->cpu_index + 1;
}
-static int write_elf64_notes(DumpState *s)
+static int write_elf64_notes(WriteCoreDumpFunction f, DumpState *s)
{
CPUState *cpu;
int ret;
@@ -279,7 +279,7 @@ static int write_elf64_notes(DumpState *s)
CPU_FOREACH(cpu) {
id = cpu_index(cpu);
- ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s);
+ ret = cpu_write_elf64_note(f, cpu, id, s);
if (ret < 0) {
dump_error(s, "dump: failed to write elf notes.\n");
return -1;
@@ -287,7 +287,7 @@ static int write_elf64_notes(DumpState *s)
}
CPU_FOREACH(cpu) {
- ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s);
+ ret = cpu_write_elf64_qemunote(f, cpu, s);
if (ret < 0) {
dump_error(s, "dump: failed to write CPU status.\n");
return -1;
@@ -321,7 +321,7 @@ static int write_elf32_note(DumpState *s)
return 0;
}
-static int write_elf32_notes(DumpState *s)
+static int write_elf32_notes(WriteCoreDumpFunction f, DumpState *s)
{
CPUState *cpu;
int ret;
@@ -329,7 +329,7 @@ static int write_elf32_notes(DumpState *s)
CPU_FOREACH(cpu) {
id = cpu_index(cpu);
- ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s);
+ ret = cpu_write_elf32_note(f, cpu, id, s);
if (ret < 0) {
dump_error(s, "dump: failed to write elf notes.\n");
return -1;
@@ -337,7 +337,7 @@ static int write_elf32_notes(DumpState *s)
}
CPU_FOREACH(cpu) {
- ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
+ ret = cpu_write_elf32_qemunote(f, cpu, s);
if (ret < 0) {
dump_error(s, "dump: failed to write CPU status.\n");
return -1;
@@ -574,7 +574,7 @@ static int dump_begin(DumpState *s)
}
/* write notes to vmcore */
- if (write_elf64_notes(s) < 0) {
+ if (write_elf64_notes(fd_write_vmcore, s) < 0) {
return -1;
}
@@ -597,7 +597,7 @@ static int dump_begin(DumpState *s)
}
/* write notes to vmcore */
- if (write_elf32_notes(s) < 0) {
+ if (write_elf32_notes(fd_write_vmcore, s) < 0) {
return -1;
}
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 05/32] dump: add API to write header of flatten format
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (3 preceding siblings ...)
2014-03-03 17:11 ` [Qemu-devel] [PULL 04/32] dump: add argument to write_elfxx_notes Luiz Capitulino
@ 2014-03-03 17:11 ` Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 06/32] dump: add API to write vmcore Luiz Capitulino
` (27 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:11 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
flatten format will be used when writing kdump-compressed format. The format is
also used by makedumpfile, you can refer to the following URL to get more
detailed information about flatten format of kdump-compressed format:
http://sourceforge.net/projects/makedumpfile/
The two functions here are used to write start flat header and end flat header
to vmcore, and they will be called later when flatten format is used.
struct MakedumpfileHeader stored at the head of vmcore is used to indicate the
vmcore is in flatten format.
struct MakedumpfileHeader {
char signature[16]; /* = "makedumpfile" */
int64_t type; /* = 1 */
int64_t version; /* = 1 */
};
And struct MakedumpfileDataHeader, with offset and buf_size set to -1, is used
to indicate the end of vmcore in flatten format.
struct MakedumpfileDataHeader {
int64_t offset; /* = -1 */
int64_t buf_size; /* = -1 */
};
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/sysemu/dump.h | 17 +++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/dump.c b/dump.c
index c9d3492..f233b3e 100644
--- a/dump.c
+++ b/dump.c
@@ -686,6 +686,48 @@ static int create_vmcore(DumpState *s)
return 0;
}
+static int write_start_flat_header(int fd)
+{
+ uint8_t *buf;
+ MakedumpfileHeader mh;
+ int ret = 0;
+
+ memset(&mh, 0, sizeof(mh));
+ strncpy(mh.signature, MAKEDUMPFILE_SIGNATURE,
+ strlen(MAKEDUMPFILE_SIGNATURE));
+
+ mh.type = cpu_to_be64(TYPE_FLAT_HEADER);
+ mh.version = cpu_to_be64(VERSION_FLAT_HEADER);
+
+ buf = g_malloc0(MAX_SIZE_MDF_HEADER);
+ memcpy(buf, &mh, sizeof(mh));
+
+ size_t written_size;
+ written_size = qemu_write_full(fd, buf, MAX_SIZE_MDF_HEADER);
+ if (written_size != MAX_SIZE_MDF_HEADER) {
+ ret = -1;
+ }
+
+ g_free(buf);
+ return ret;
+}
+
+static int write_end_flat_header(int fd)
+{
+ MakedumpfileDataHeader mdh;
+
+ mdh.offset = END_FLAG_FLAT_HEADER;
+ mdh.buf_size = END_FLAG_FLAT_HEADER;
+
+ size_t written_size;
+ written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
+ if (written_size != sizeof(mdh)) {
+ return -1;
+ }
+
+ return 0;
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 19fafb2..b32b390 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -14,12 +14,29 @@
#ifndef DUMP_H
#define DUMP_H
+#define MAKEDUMPFILE_SIGNATURE "makedumpfile"
+#define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header */
+#define TYPE_FLAT_HEADER (1) /* type of flattened format */
+#define VERSION_FLAT_HEADER (1) /* version of flattened format */
+#define END_FLAG_FLAT_HEADER (-1)
+
typedef struct ArchDumpInfo {
int d_machine; /* Architecture */
int d_endian; /* ELFDATA2LSB or ELFDATA2MSB */
int d_class; /* ELFCLASS32 or ELFCLASS64 */
} ArchDumpInfo;
+typedef struct QEMU_PACKED MakedumpfileHeader {
+ char signature[16]; /* = "makedumpfile" */
+ int64_t type;
+ int64_t version;
+} MakedumpfileHeader;
+
+typedef struct QEMU_PACKED MakedumpfileDataHeader {
+ int64_t offset;
+ int64_t buf_size;
+} MakedumpfileDataHeader;
+
struct GuestPhysBlockList; /* memory_mapping.h */
int cpu_get_dump_info(ArchDumpInfo *info,
const struct GuestPhysBlockList *guest_phys_blocks);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 06/32] dump: add API to write vmcore
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (4 preceding siblings ...)
2014-03-03 17:11 ` [Qemu-devel] [PULL 05/32] dump: add API to write header of flatten format Luiz Capitulino
@ 2014-03-03 17:11 ` Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 07/32] dump: add API to write elf notes to buffer Luiz Capitulino
` (26 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:11 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
Function is used to write vmcore in flatten format. In flatten format, data is
written block by block, and in front of each block, a struct
MakedumpfileDataHeader is stored there to indicate the offset and size of the
data block.
struct MakedumpfileDataHeader {
int64_t offset;
int64_t buf_size;
};
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/dump.c b/dump.c
index f233b3e..238ffa5 100644
--- a/dump.c
+++ b/dump.c
@@ -728,6 +728,27 @@ static int write_end_flat_header(int fd)
return 0;
}
+static int write_buffer(int fd, off_t offset, const void *buf, size_t size)
+{
+ size_t written_size;
+ MakedumpfileDataHeader mdh;
+
+ mdh.offset = cpu_to_be64(offset);
+ mdh.buf_size = cpu_to_be64(size);
+
+ written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
+ if (written_size != sizeof(mdh)) {
+ return -1;
+ }
+
+ written_size = qemu_write_full(fd, buf, size);
+ if (written_size != size) {
+ return -1;
+ }
+
+ return 0;
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 07/32] dump: add API to write elf notes to buffer
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (5 preceding siblings ...)
2014-03-03 17:11 ` [Qemu-devel] [PULL 06/32] dump: add API to write vmcore Luiz Capitulino
@ 2014-03-03 17:11 ` Luiz Capitulino
2014-03-03 17:11 ` [Qemu-devel] [PULL 08/32] dump: add support for lzo/snappy Luiz Capitulino
` (25 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:11 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
the function can be used by write_elf32_notes/write_elf64_notes to write notes
to a buffer. If fd_write_vmcore is used, write_elf32_notes/write_elf64_notes
will write elf notes to vmcore directly. Instead, if buf_write_note is used,
elf notes will be written to opaque->note_buf at first.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/dump.c b/dump.c
index 238ffa5..2b940bd 100644
--- a/dump.c
+++ b/dump.c
@@ -76,6 +76,9 @@ typedef struct DumpState {
int64_t begin;
int64_t length;
Error **errp;
+
+ uint8_t *note_buf; /* buffer for notes */
+ size_t note_buf_offset; /* the writing place in note_buf */
} DumpState;
static int dump_cleanup(DumpState *s)
@@ -749,6 +752,22 @@ static int write_buffer(int fd, off_t offset, const void *buf, size_t size)
return 0;
}
+static int buf_write_note(const void *buf, size_t size, void *opaque)
+{
+ DumpState *s = opaque;
+
+ /* note_buf is not enough */
+ if (s->note_buf_offset + size > s->note_size) {
+ return -1;
+ }
+
+ memcpy(s->note_buf + s->note_buf_offset, buf, size);
+
+ s->note_buf_offset += size;
+
+ return 0;
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 08/32] dump: add support for lzo/snappy
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (6 preceding siblings ...)
2014-03-03 17:11 ` [Qemu-devel] [PULL 07/32] dump: add API to write elf notes to buffer Luiz Capitulino
@ 2014-03-03 17:11 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 09/32] dump: add members to DumpState and init some of them Luiz Capitulino
` (24 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:11 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
kdump-compressed format supports three compression format, zlib/lzo/snappy.
Currently, only zlib is available. This patch is used to support lzo/snappy.
'--enable-lzo/--enable-snappy' is needed to be specified with configure to make
lzo/snappy available for qemu
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
configure | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/configure b/configure
index 8ad03ea..6ccadc3 100755
--- a/configure
+++ b/configure
@@ -283,6 +283,8 @@ libusb=""
usb_redir=""
glx=""
zlib="yes"
+lzo="no"
+snappy="no"
guest_agent=""
guest_agent_with_vss="no"
vss_win32_sdk=""
@@ -995,6 +997,10 @@ for opt do
;;
--disable-zlib-test) zlib="no"
;;
+ --enable-lzo) lzo="yes"
+ ;;
+ --enable-snappy) snappy="yes"
+ ;;
--enable-guest-agent) guest_agent="yes"
;;
--disable-guest-agent) guest_agent="no"
@@ -1289,6 +1295,8 @@ Advanced options (experts only):
--enable-libusb enable libusb (for usb passthrough)
--disable-usb-redir disable usb network redirection support
--enable-usb-redir enable usb network redirection support
+ --enable-lzo enable the support of lzo compression library
+ --enable-snappy enable the support of snappy compression library
--disable-guest-agent disable building of the QEMU Guest Agent
--enable-guest-agent enable building of the QEMU Guest Agent
--with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent
@@ -1660,6 +1668,42 @@ fi
LIBS="$LIBS -lz"
##########################################
+# lzo check
+
+if test "$lzo" != "no" ; then
+ cat > $TMPC << EOF
+#include <lzo/lzo1x.h>
+int main(void) { lzo_version(); return 0; }
+EOF
+ if compile_prog "" "-llzo2" ; then
+ :
+ else
+ error_exit "lzo check failed" \
+ "Make sure to have the lzo libs and headers installed."
+ fi
+
+ libs_softmmu="$libs_softmmu -llzo2"
+fi
+
+##########################################
+# snappy check
+
+if test "$snappy" != "no" ; then
+ cat > $TMPC << EOF
+#include <snappy-c.h>
+int main(void) { snappy_max_compressed_length(4096); return 0; }
+EOF
+ if compile_prog "" "-lsnappy" ; then
+ :
+ else
+ error_exit "snappy check failed" \
+ "Make sure to have the snappy libs and headers installed."
+ fi
+
+ libs_softmmu="$libs_softmmu -lsnappy"
+fi
+
+##########################################
# libseccomp check
if test "$seccomp" != "no" ; then
@@ -4045,6 +4089,8 @@ echo "TPM passthrough $tpm_passthrough"
echo "QOM debugging $qom_cast_debug"
echo "vhdx $vhdx"
echo "Quorum $quorum"
+echo "lzo support $lzo"
+echo "snappy support $snappy"
if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -4368,6 +4414,14 @@ if test "$glx" = "yes" ; then
echo "GLX_LIBS=$glx_libs" >> $config_host_mak
fi
+if test "$lzo" = "yes" ; then
+ echo "CONFIG_LZO=y" >> $config_host_mak
+fi
+
+if test "$snappy" = "yes" ; then
+ echo "CONFIG_SNAPPY=y" >> $config_host_mak
+fi
+
if test "$libiscsi" = "yes" ; then
echo "CONFIG_LIBISCSI=m" >> $config_host_mak
if test "$libiscsi_version" = "1.4.0"; then
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 09/32] dump: add members to DumpState and init some of them
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (7 preceding siblings ...)
2014-03-03 17:11 ` [Qemu-devel] [PULL 08/32] dump: add support for lzo/snappy Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 10/32] dump: add API to write dump header Luiz Capitulino
` (23 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
add some members to DumpState that will be used in writing vmcore in
kdump-compressed format. some of them, like page_size, will be initialized
in the patch.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 28 ++++++++++++++++++++++++++++
include/sysemu/dump.h | 7 +++++++
2 files changed, 35 insertions(+)
diff --git a/dump.c b/dump.c
index 2b940bd..3a1944e 100644
--- a/dump.c
+++ b/dump.c
@@ -79,6 +79,16 @@ typedef struct DumpState {
uint8_t *note_buf; /* buffer for notes */
size_t note_buf_offset; /* the writing place in note_buf */
+ uint32_t nr_cpus; /* number of guest's cpu */
+ size_t page_size; /* guest's page size */
+ uint32_t page_shift; /* guest's page shift */
+ uint64_t max_mapnr; /* the biggest guest's phys-mem's number */
+ size_t len_dump_bitmap; /* the size of the place used to store
+ dump_bitmap in vmcore */
+ off_t offset_dump_bitmap; /* offset of dump_bitmap part in vmcore */
+ off_t offset_page; /* offset of page part in vmcore */
+ size_t num_dumpable; /* number of page that can be dumped */
+ uint32_t flag_compress; /* indicate the compression format */
} DumpState;
static int dump_cleanup(DumpState *s)
@@ -796,6 +806,14 @@ static ram_addr_t get_start_block(DumpState *s)
return -1;
}
+static void get_max_mapnr(DumpState *s)
+{
+ GuestPhysBlock *last_block;
+
+ last_block = QTAILQ_LAST(&s->guest_phys_blocks.head, GuestPhysBlockHead);
+ s->max_mapnr = paddr_to_pfn(last_block->target_end, s->page_shift);
+}
+
static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
int64_t begin, int64_t length, Error **errp)
{
@@ -864,6 +882,16 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);
}
+ s->nr_cpus = nr_cpus;
+ s->page_size = TARGET_PAGE_SIZE;
+ s->page_shift = ffs(s->page_size) - 1;
+
+ get_max_mapnr(s);
+
+ uint64_t tmp;
+ tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size);
+ s->len_dump_bitmap = tmp * s->page_size;
+
if (s->has_filter) {
memory_mapping_filter(&s->list, s->begin, s->length);
}
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index b32b390..995bf47 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -20,6 +20,13 @@
#define VERSION_FLAT_HEADER (1) /* version of flattened format */
#define END_FLAG_FLAT_HEADER (-1)
+#define ARCH_PFN_OFFSET (0)
+
+#define paddr_to_pfn(X, page_shift) \
+ (((unsigned long long)(X) >> (page_shift)) - ARCH_PFN_OFFSET)
+#define pfn_to_paddr(X, page_shift) \
+ (((unsigned long long)(X) + ARCH_PFN_OFFSET) << (page_shift))
+
typedef struct ArchDumpInfo {
int d_machine; /* Architecture */
int d_endian; /* ELFDATA2LSB or ELFDATA2MSB */
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 10/32] dump: add API to write dump header
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (8 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 09/32] dump: add members to DumpState and init some of them Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 11/32] dump: add API to write dump_bitmap Luiz Capitulino
` (22 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
the functions are used to write header of kdump-compressed format to vmcore.
Header of kdump-compressed format includes:
1. common header: DiskDumpHeader32 / DiskDumpHeader64
2. sub header: KdumpSubHeader32 / KdumpSubHeader64
3. extra information: only elf notes here
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/sysemu/dump.h | 96 ++++++++++++++++++++++
2 files changed, 319 insertions(+)
diff --git a/dump.c b/dump.c
index 3a1944e..4b2799f 100644
--- a/dump.c
+++ b/dump.c
@@ -778,6 +778,229 @@ static int buf_write_note(const void *buf, size_t size, void *opaque)
return 0;
}
+/* write common header, sub header and elf note to vmcore */
+static int create_header32(DumpState *s)
+{
+ int ret = 0;
+ DiskDumpHeader32 *dh = NULL;
+ KdumpSubHeader32 *kh = NULL;
+ size_t size;
+ int endian = s->dump_info.d_endian;
+ uint32_t block_size;
+ uint32_t sub_hdr_size;
+ uint32_t bitmap_blocks;
+ uint32_t status = 0;
+ uint64_t offset_note;
+
+ /* write common header, the version of kdump-compressed format is 6th */
+ size = sizeof(DiskDumpHeader32);
+ dh = g_malloc0(size);
+
+ strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
+ dh->header_version = cpu_convert_to_target32(6, endian);
+ block_size = s->page_size;
+ dh->block_size = cpu_convert_to_target32(block_size, endian);
+ sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
+ sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
+ dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
+ /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
+ dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
+ endian);
+ dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
+ bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
+ dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
+ memcpy(&(dh->utsname.machine), "i686", 4);
+
+ if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
+ status |= DUMP_DH_COMPRESSED_ZLIB;
+ }
+#ifdef CONFIG_LZO
+ if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
+ status |= DUMP_DH_COMPRESSED_LZO;
+ }
+#endif
+#ifdef CONFIG_SNAPPY
+ if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
+ status |= DUMP_DH_COMPRESSED_SNAPPY;
+ }
+#endif
+ dh->status = cpu_convert_to_target32(status, endian);
+
+ if (write_buffer(s->fd, 0, dh, size) < 0) {
+ dump_error(s, "dump: failed to write disk dump header.\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* write sub header */
+ size = sizeof(KdumpSubHeader32);
+ kh = g_malloc0(size);
+
+ /* 64bit max_mapnr_64 */
+ kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
+ kh->phys_base = cpu_convert_to_target32(PHYS_BASE, endian);
+ kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
+
+ offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
+ kh->offset_note = cpu_convert_to_target64(offset_note, endian);
+ kh->note_size = cpu_convert_to_target32(s->note_size, endian);
+
+ if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
+ block_size, kh, size) < 0) {
+ dump_error(s, "dump: failed to write kdump sub header.\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* write note */
+ s->note_buf = g_malloc0(s->note_size);
+ s->note_buf_offset = 0;
+
+ /* use s->note_buf to store notes temporarily */
+ if (write_elf32_notes(buf_write_note, s) < 0) {
+ ret = -1;
+ goto out;
+ }
+
+ if (write_buffer(s->fd, offset_note, s->note_buf,
+ s->note_size) < 0) {
+ dump_error(s, "dump: failed to write notes");
+ ret = -1;
+ goto out;
+ }
+
+ /* get offset of dump_bitmap */
+ s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
+ block_size;
+
+ /* get offset of page */
+ s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
+ block_size;
+
+out:
+ g_free(dh);
+ g_free(kh);
+ g_free(s->note_buf);
+
+ return ret;
+}
+
+/* write common header, sub header and elf note to vmcore */
+static int create_header64(DumpState *s)
+{
+ int ret = 0;
+ DiskDumpHeader64 *dh = NULL;
+ KdumpSubHeader64 *kh = NULL;
+ size_t size;
+ int endian = s->dump_info.d_endian;
+ uint32_t block_size;
+ uint32_t sub_hdr_size;
+ uint32_t bitmap_blocks;
+ uint32_t status = 0;
+ uint64_t offset_note;
+
+ /* write common header, the version of kdump-compressed format is 6th */
+ size = sizeof(DiskDumpHeader64);
+ dh = g_malloc0(size);
+
+ strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
+ dh->header_version = cpu_convert_to_target32(6, endian);
+ block_size = s->page_size;
+ dh->block_size = cpu_convert_to_target32(block_size, endian);
+ sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
+ sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
+ dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
+ /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
+ dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
+ endian);
+ dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
+ bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
+ dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
+ memcpy(&(dh->utsname.machine), "x86_64", 6);
+
+ if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
+ status |= DUMP_DH_COMPRESSED_ZLIB;
+ }
+#ifdef CONFIG_LZO
+ if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
+ status |= DUMP_DH_COMPRESSED_LZO;
+ }
+#endif
+#ifdef CONFIG_SNAPPY
+ if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
+ status |= DUMP_DH_COMPRESSED_SNAPPY;
+ }
+#endif
+ dh->status = cpu_convert_to_target32(status, endian);
+
+ if (write_buffer(s->fd, 0, dh, size) < 0) {
+ dump_error(s, "dump: failed to write disk dump header.\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* write sub header */
+ size = sizeof(KdumpSubHeader64);
+ kh = g_malloc0(size);
+
+ /* 64bit max_mapnr_64 */
+ kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
+ kh->phys_base = cpu_convert_to_target64(PHYS_BASE, endian);
+ kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
+
+ offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
+ kh->offset_note = cpu_convert_to_target64(offset_note, endian);
+ kh->note_size = cpu_convert_to_target64(s->note_size, endian);
+
+ if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
+ block_size, kh, size) < 0) {
+ dump_error(s, "dump: failed to write kdump sub header.\n");
+ ret = -1;
+ goto out;
+ }
+
+ /* write note */
+ s->note_buf = g_malloc0(s->note_size);
+ s->note_buf_offset = 0;
+
+ /* use s->note_buf to store notes temporarily */
+ if (write_elf64_notes(buf_write_note, s) < 0) {
+ ret = -1;
+ goto out;
+ }
+
+ if (write_buffer(s->fd, offset_note, s->note_buf,
+ s->note_size) < 0) {
+ dump_error(s, "dump: failed to write notes");
+ ret = -1;
+ goto out;
+ }
+
+ /* get offset of dump_bitmap */
+ s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
+ block_size;
+
+ /* get offset of page */
+ s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
+ block_size;
+
+out:
+ g_free(dh);
+ g_free(kh);
+ g_free(s->note_buf);
+
+ return ret;
+}
+
+static int write_dump_header(DumpState *s)
+{
+ if (s->dump_info.d_machine == EM_386) {
+ return create_header32(s);
+ } else {
+ return create_header64(s);
+ }
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 995bf47..dfee238 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -27,6 +27,19 @@
#define pfn_to_paddr(X, page_shift) \
(((unsigned long long)(X) + ARCH_PFN_OFFSET) << (page_shift))
+/*
+ * flag for compressed format
+ */
+#define DUMP_DH_COMPRESSED_ZLIB (0x1)
+#define DUMP_DH_COMPRESSED_LZO (0x2)
+#define DUMP_DH_COMPRESSED_SNAPPY (0x4)
+
+#define KDUMP_SIGNATURE "KDUMP "
+#define SIG_LEN (sizeof(KDUMP_SIGNATURE) - 1)
+#define PHYS_BASE (0)
+#define DUMP_LEVEL (1)
+#define DISKDUMP_HEADER_BLOCKS (1)
+
typedef struct ArchDumpInfo {
int d_machine; /* Architecture */
int d_endian; /* ELFDATA2LSB or ELFDATA2MSB */
@@ -44,6 +57,89 @@ typedef struct QEMU_PACKED MakedumpfileDataHeader {
int64_t buf_size;
} MakedumpfileDataHeader;
+typedef struct QEMU_PACKED NewUtsname {
+ char sysname[65];
+ char nodename[65];
+ char release[65];
+ char version[65];
+ char machine[65];
+ char domainname[65];
+} NewUtsname;
+
+typedef struct QEMU_PACKED DiskDumpHeader32 {
+ char signature[SIG_LEN]; /* = "KDUMP " */
+ uint32_t header_version; /* Dump header version */
+ NewUtsname utsname; /* copy of system_utsname */
+ char timestamp[10]; /* Time stamp */
+ uint32_t status; /* Above flags */
+ uint32_t block_size; /* Size of a block in byte */
+ uint32_t sub_hdr_size; /* Size of arch dependent header in block */
+ uint32_t bitmap_blocks; /* Size of Memory bitmap in block */
+ uint32_t max_mapnr; /* = max_mapnr ,
+ obsoleted in header_version 6 */
+ uint32_t total_ram_blocks; /* Number of blocks should be written */
+ uint32_t device_blocks; /* Number of total blocks in dump device */
+ uint32_t written_blocks; /* Number of written blocks */
+ uint32_t current_cpu; /* CPU# which handles dump */
+ uint32_t nr_cpus; /* Number of CPUs */
+} DiskDumpHeader32;
+
+typedef struct QEMU_PACKED DiskDumpHeader64 {
+ char signature[SIG_LEN]; /* = "KDUMP " */
+ uint32_t header_version; /* Dump header version */
+ NewUtsname utsname; /* copy of system_utsname */
+ char timestamp[22]; /* Time stamp */
+ uint32_t status; /* Above flags */
+ uint32_t block_size; /* Size of a block in byte */
+ uint32_t sub_hdr_size; /* Size of arch dependent header in block */
+ uint32_t bitmap_blocks; /* Size of Memory bitmap in block */
+ uint32_t max_mapnr; /* = max_mapnr,
+ obsoleted in header_version 6 */
+ uint32_t total_ram_blocks; /* Number of blocks should be written */
+ uint32_t device_blocks; /* Number of total blocks in dump device */
+ uint32_t written_blocks; /* Number of written blocks */
+ uint32_t current_cpu; /* CPU# which handles dump */
+ uint32_t nr_cpus; /* Number of CPUs */
+} DiskDumpHeader64;
+
+typedef struct QEMU_PACKED KdumpSubHeader32 {
+ uint32_t phys_base;
+ uint32_t dump_level; /* header_version 1 and later */
+ uint32_t split; /* header_version 2 and later */
+ uint32_t start_pfn; /* header_version 2 and later,
+ obsoleted in header_version 6 */
+ uint32_t end_pfn; /* header_version 2 and later,
+ obsoleted in header_version 6 */
+ uint64_t offset_vmcoreinfo; /* header_version 3 and later */
+ uint32_t size_vmcoreinfo; /* header_version 3 and later */
+ uint64_t offset_note; /* header_version 4 and later */
+ uint32_t note_size; /* header_version 4 and later */
+ uint64_t offset_eraseinfo; /* header_version 5 and later */
+ uint32_t size_eraseinfo; /* header_version 5 and later */
+ uint64_t start_pfn_64; /* header_version 6 and later */
+ uint64_t end_pfn_64; /* header_version 6 and later */
+ uint64_t max_mapnr_64; /* header_version 6 and later */
+} KdumpSubHeader32;
+
+typedef struct QEMU_PACKED KdumpSubHeader64 {
+ uint64_t phys_base;
+ uint32_t dump_level; /* header_version 1 and later */
+ uint32_t split; /* header_version 2 and later */
+ uint64_t start_pfn; /* header_version 2 and later,
+ obsoleted in header_version 6 */
+ uint64_t end_pfn; /* header_version 2 and later,
+ obsoleted in header_version 6 */
+ uint64_t offset_vmcoreinfo; /* header_version 3 and later */
+ uint64_t size_vmcoreinfo; /* header_version 3 and later */
+ uint64_t offset_note; /* header_version 4 and later */
+ uint64_t note_size; /* header_version 4 and later */
+ uint64_t offset_eraseinfo; /* header_version 5 and later */
+ uint64_t size_eraseinfo; /* header_version 5 and later */
+ uint64_t start_pfn_64; /* header_version 6 and later */
+ uint64_t end_pfn_64; /* header_version 6 and later */
+ uint64_t max_mapnr_64; /* header_version 6 and later */
+} KdumpSubHeader64;
+
struct GuestPhysBlockList; /* memory_mapping.h */
int cpu_get_dump_info(ArchDumpInfo *info,
const struct GuestPhysBlockList *guest_phys_blocks);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 11/32] dump: add API to write dump_bitmap
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (9 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 10/32] dump: add API to write dump header Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 12/32] dump: add APIs to operate DataCache Luiz Capitulino
` (21 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
functions are used to write 1st and 2nd dump_bitmap of kdump-compressed format,
which is used to indicate whether the corresponded page is existed in vmcore.
1st and 2nd dump_bitmap are same, because dump level is specified to 1 here.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/sysemu/dump.h | 2 +
2 files changed, 166 insertions(+)
diff --git a/dump.c b/dump.c
index 4b2799f..5755534 100644
--- a/dump.c
+++ b/dump.c
@@ -1001,6 +1001,170 @@ static int write_dump_header(DumpState *s)
}
}
+/*
+ * set dump_bitmap sequencely. the bit before last_pfn is not allowed to be
+ * rewritten, so if need to set the first bit, set last_pfn and pfn to 0.
+ * set_dump_bitmap will always leave the recently set bit un-sync. And setting
+ * (last bit + sizeof(buf) * 8) to 0 will do flushing the content in buf into
+ * vmcore, ie. synchronizing un-sync bit into vmcore.
+ */
+static int set_dump_bitmap(uint64_t last_pfn, uint64_t pfn, bool value,
+ uint8_t *buf, DumpState *s)
+{
+ off_t old_offset, new_offset;
+ off_t offset_bitmap1, offset_bitmap2;
+ uint32_t byte, bit;
+
+ /* should not set the previous place */
+ assert(last_pfn <= pfn);
+
+ /*
+ * if the bit needed to be set is not cached in buf, flush the data in buf
+ * to vmcore firstly.
+ * making new_offset be bigger than old_offset can also sync remained data
+ * into vmcore.
+ */
+ old_offset = BUFSIZE_BITMAP * (last_pfn / PFN_BUFBITMAP);
+ new_offset = BUFSIZE_BITMAP * (pfn / PFN_BUFBITMAP);
+
+ while (old_offset < new_offset) {
+ /* calculate the offset and write dump_bitmap */
+ offset_bitmap1 = s->offset_dump_bitmap + old_offset;
+ if (write_buffer(s->fd, offset_bitmap1, buf,
+ BUFSIZE_BITMAP) < 0) {
+ return -1;
+ }
+
+ /* dump level 1 is chosen, so 1st and 2nd bitmap are same */
+ offset_bitmap2 = s->offset_dump_bitmap + s->len_dump_bitmap +
+ old_offset;
+ if (write_buffer(s->fd, offset_bitmap2, buf,
+ BUFSIZE_BITMAP) < 0) {
+ return -1;
+ }
+
+ memset(buf, 0, BUFSIZE_BITMAP);
+ old_offset += BUFSIZE_BITMAP;
+ }
+
+ /* get the exact place of the bit in the buf, and set it */
+ byte = (pfn % PFN_BUFBITMAP) / CHAR_BIT;
+ bit = (pfn % PFN_BUFBITMAP) % CHAR_BIT;
+ if (value) {
+ buf[byte] |= 1u << bit;
+ } else {
+ buf[byte] &= ~(1u << bit);
+ }
+
+ return 0;
+}
+
+/*
+ * exam every page and return the page frame number and the address of the page.
+ * bufptr can be NULL. note: the blocks here is supposed to reflect guest-phys
+ * blocks, so block->target_start and block->target_end should be interal
+ * multiples of the target page size.
+ */
+static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
+ uint8_t **bufptr, DumpState *s)
+{
+ GuestPhysBlock *block = *blockptr;
+ hwaddr addr;
+ uint8_t *buf;
+
+ /* block == NULL means the start of the iteration */
+ if (!block) {
+ block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
+ *blockptr = block;
+ assert(block->target_start % s->page_size == 0);
+ assert(block->target_end % s->page_size == 0);
+ *pfnptr = paddr_to_pfn(block->target_start, s->page_shift);
+ if (bufptr) {
+ *bufptr = block->host_addr;
+ }
+ return true;
+ }
+
+ *pfnptr = *pfnptr + 1;
+ addr = pfn_to_paddr(*pfnptr, s->page_shift);
+
+ if ((addr >= block->target_start) &&
+ (addr + s->page_size <= block->target_end)) {
+ buf = block->host_addr + (addr - block->target_start);
+ } else {
+ /* the next page is in the next block */
+ block = QTAILQ_NEXT(block, next);
+ *blockptr = block;
+ if (!block) {
+ return false;
+ }
+ assert(block->target_start % s->page_size == 0);
+ assert(block->target_end % s->page_size == 0);
+ *pfnptr = paddr_to_pfn(block->target_start, s->page_shift);
+ buf = block->host_addr;
+ }
+
+ if (bufptr) {
+ *bufptr = buf;
+ }
+
+ return true;
+}
+
+static int write_dump_bitmap(DumpState *s)
+{
+ int ret = 0;
+ uint64_t last_pfn, pfn;
+ void *dump_bitmap_buf;
+ size_t num_dumpable;
+ GuestPhysBlock *block_iter = NULL;
+
+ /* dump_bitmap_buf is used to store dump_bitmap temporarily */
+ dump_bitmap_buf = g_malloc0(BUFSIZE_BITMAP);
+
+ num_dumpable = 0;
+ last_pfn = 0;
+
+ /*
+ * exam memory page by page, and set the bit in dump_bitmap corresponded
+ * to the existing page.
+ */
+ while (get_next_page(&block_iter, &pfn, NULL, s)) {
+ ret = set_dump_bitmap(last_pfn, pfn, true, dump_bitmap_buf, s);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to set dump_bitmap.\n");
+ ret = -1;
+ goto out;
+ }
+
+ last_pfn = pfn;
+ num_dumpable++;
+ }
+
+ /*
+ * set_dump_bitmap will always leave the recently set bit un-sync. Here we
+ * set last_pfn + PFN_BUFBITMAP to 0 and those set but un-sync bit will be
+ * synchronized into vmcore.
+ */
+ if (num_dumpable > 0) {
+ ret = set_dump_bitmap(last_pfn, last_pfn + PFN_BUFBITMAP, false,
+ dump_bitmap_buf, s);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to sync dump_bitmap.\n");
+ ret = -1;
+ goto out;
+ }
+ }
+
+ /* number of dumpable pages that will be dumped later */
+ s->num_dumpable = num_dumpable;
+
+out:
+ g_free(dump_bitmap_buf);
+
+ return ret;
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index dfee238..6d4d0bc 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -39,6 +39,8 @@
#define PHYS_BASE (0)
#define DUMP_LEVEL (1)
#define DISKDUMP_HEADER_BLOCKS (1)
+#define BUFSIZE_BITMAP (TARGET_PAGE_SIZE)
+#define PFN_BUFBITMAP (CHAR_BIT * BUFSIZE_BITMAP)
typedef struct ArchDumpInfo {
int d_machine; /* Architecture */
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 12/32] dump: add APIs to operate DataCache
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (10 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 11/32] dump: add API to write dump_bitmap Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 13/32] dump: add API to write dump pages Luiz Capitulino
` (20 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
DataCache is used to store data temporarily, then the data will be written to
vmcore. These functions will be called later when writing data of page to
vmcore.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
include/sysemu/dump.h | 9 +++++++++
2 files changed, 56 insertions(+)
diff --git a/dump.c b/dump.c
index 5755534..a7a85d3 100644
--- a/dump.c
+++ b/dump.c
@@ -1165,6 +1165,53 @@ out:
return ret;
}
+static void prepare_data_cache(DataCache *data_cache, DumpState *s,
+ off_t offset)
+{
+ data_cache->fd = s->fd;
+ data_cache->data_size = 0;
+ data_cache->buf_size = BUFSIZE_DATA_CACHE;
+ data_cache->buf = g_malloc0(BUFSIZE_DATA_CACHE);
+ data_cache->offset = offset;
+}
+
+static int write_cache(DataCache *dc, const void *buf, size_t size,
+ bool flag_sync)
+{
+ /*
+ * dc->buf_size should not be less than size, otherwise dc will never be
+ * enough
+ */
+ assert(size <= dc->buf_size);
+
+ /*
+ * if flag_sync is set, synchronize data in dc->buf into vmcore.
+ * otherwise check if the space is enough for caching data in buf, if not,
+ * write the data in dc->buf to dc->fd and reset dc->buf
+ */
+ if ((!flag_sync && dc->data_size + size > dc->buf_size) ||
+ (flag_sync && dc->data_size > 0)) {
+ if (write_buffer(dc->fd, dc->offset, dc->buf, dc->data_size) < 0) {
+ return -1;
+ }
+
+ dc->offset += dc->data_size;
+ dc->data_size = 0;
+ }
+
+ if (!flag_sync) {
+ memcpy(dc->buf + dc->data_size, buf, size);
+ dc->data_size += size;
+ }
+
+ return 0;
+}
+
+static void free_data_cache(DataCache *data_cache)
+{
+ g_free(data_cache->buf);
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 6d4d0bc..92a95e4 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -41,6 +41,7 @@
#define DISKDUMP_HEADER_BLOCKS (1)
#define BUFSIZE_BITMAP (TARGET_PAGE_SIZE)
#define PFN_BUFBITMAP (CHAR_BIT * BUFSIZE_BITMAP)
+#define BUFSIZE_DATA_CACHE (TARGET_PAGE_SIZE * 4)
typedef struct ArchDumpInfo {
int d_machine; /* Architecture */
@@ -142,6 +143,14 @@ typedef struct QEMU_PACKED KdumpSubHeader64 {
uint64_t max_mapnr_64; /* header_version 6 and later */
} KdumpSubHeader64;
+typedef struct DataCache {
+ int fd; /* fd of the file where to write the cached data */
+ uint8_t *buf; /* buffer for cached data */
+ size_t buf_size; /* size of the buf */
+ size_t data_size; /* size of cached data in buf */
+ off_t offset; /* offset of the file */
+} DataCache;
+
struct GuestPhysBlockList; /* memory_mapping.h */
int cpu_get_dump_info(ArchDumpInfo *info,
const struct GuestPhysBlockList *guest_phys_blocks);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 13/32] dump: add API to write dump pages
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (11 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 12/32] dump: add APIs to operate DataCache Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 19:05 ` Eric Blake
2014-03-03 17:12 ` [Qemu-devel] [PULL 14/32] dump: make kdump-compressed format available for 'dump-guest-memory' Luiz Capitulino
` (19 subsequent siblings)
32 siblings, 1 reply; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
functions are used to write page to vmcore. vmcore is written page by page.
page desc is used to store the information of a page, including a page's size,
offset, compression format, etc.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/sysemu/dump.h | 7 ++
2 files changed, 238 insertions(+)
diff --git a/dump.c b/dump.c
index a7a85d3..a7b5117 100644
--- a/dump.c
+++ b/dump.c
@@ -25,6 +25,14 @@
#include "qapi/error.h"
#include "qmp-commands.h"
+#include <zlib.h>
+#ifdef CONFIG_LZO
+#include <lzo/lzo1x.h>
+#endif
+#ifdef CONFIG_SNAPPY
+#include <snappy-c.h>
+#endif
+
static uint16_t cpu_convert_to_target16(uint16_t val, int endian)
{
if (endian == ELFDATA2LSB) {
@@ -1212,6 +1220,229 @@ static void free_data_cache(DataCache *data_cache)
g_free(data_cache->buf);
}
+static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
+{
+ size_t len_buf_out_zlib, len_buf_out_lzo, len_buf_out_snappy;
+ size_t len_buf_out;
+
+ /* init buf_out */
+ len_buf_out_zlib = len_buf_out_lzo = len_buf_out_snappy = 0;
+
+ /* buf size for zlib */
+ len_buf_out_zlib = compressBound(page_size);
+
+ /* buf size for lzo */
+#ifdef CONFIG_LZO
+ if (flag_compress & DUMP_DH_COMPRESSED_LZO) {
+ if (lzo_init() != LZO_E_OK) {
+ /* return 0 to indicate lzo is unavailable */
+ return 0;
+ }
+ }
+
+ /*
+ * LZO will expand incompressible data by a little amount. please check the
+ * following URL to see the expansion calculation:
+ * http://www.oberhumer.com/opensource/lzo/lzofaq.php
+ */
+ len_buf_out_lzo = page_size + page_size / 16 + 64 + 3;
+#endif
+
+#ifdef CONFIG_SNAPPY
+ /* buf size for snappy */
+ len_buf_out_snappy = snappy_max_compressed_length(page_size);
+#endif
+
+ /* get the biggest that can store all kinds of compressed page */
+ len_buf_out = MAX(len_buf_out_zlib,
+ MAX(len_buf_out_lzo, len_buf_out_snappy));
+
+ return len_buf_out;
+}
+
+/*
+ * check if the page is all 0
+ */
+static inline bool is_zero_page(const uint8_t *buf, size_t page_size)
+{
+ return buffer_is_zero(buf, page_size);
+}
+
+static int write_dump_pages(DumpState *s)
+{
+ int ret = 0;
+ DataCache page_desc, page_data;
+ size_t len_buf_out, size_out;
+#ifdef CONFIG_LZO
+ lzo_bytep wrkmem = NULL;
+#endif
+ uint8_t *buf_out = NULL;
+ off_t offset_desc, offset_data;
+ PageDescriptor pd, pd_zero;
+ uint8_t *buf;
+ int endian = s->dump_info.d_endian;
+ GuestPhysBlock *block_iter = NULL;
+ uint64_t pfn_iter;
+
+ /* get offset of page_desc and page_data in dump file */
+ offset_desc = s->offset_page;
+ offset_data = offset_desc + sizeof(PageDescriptor) * s->num_dumpable;
+
+ prepare_data_cache(&page_desc, s, offset_desc);
+ prepare_data_cache(&page_data, s, offset_data);
+
+ /* prepare buffer to store compressed data */
+ len_buf_out = get_len_buf_out(s->page_size, s->flag_compress);
+ if (len_buf_out == 0) {
+ dump_error(s, "dump: failed to get length of output buffer.\n");
+ goto out;
+ }
+
+#ifdef CONFIG_LZO
+ wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);
+#endif
+
+ buf_out = g_malloc(len_buf_out);
+
+ /*
+ * init zero page's page_desc and page_data, because every zero page
+ * uses the same page_data
+ */
+ pd_zero.size = cpu_convert_to_target32(s->page_size, endian);
+ pd_zero.flags = cpu_convert_to_target32(0, endian);
+ pd_zero.offset = cpu_convert_to_target64(offset_data, endian);
+ pd_zero.page_flags = cpu_convert_to_target64(0, endian);
+ buf = g_malloc0(s->page_size);
+ ret = write_cache(&page_data, buf, s->page_size, false);
+ g_free(buf);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write page data(zero page).\n");
+ goto out;
+ }
+
+ offset_data += s->page_size;
+
+ /*
+ * dump memory to vmcore page by page. zero page will all be resided in the
+ * first page of page section
+ */
+ while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
+ /* check zero page */
+ if (is_zero_page(buf, s->page_size)) {
+ ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
+ false);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write page desc.\n");
+ goto out;
+ }
+ } else {
+ /*
+ * not zero page, then:
+ * 1. compress the page
+ * 2. write the compressed page into the cache of page_data
+ * 3. get page desc of the compressed page and write it into the
+ * cache of page_desc
+ *
+ * only one compression format will be used here, for
+ * s->flag_compress is set. But when compression fails to work,
+ * we fall back to save in plaintext.
+ */
+ size_out = len_buf_out;
+ if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
+ (compress2(buf_out, (uLongf *)&size_out, buf, s->page_size,
+ Z_BEST_SPEED) == Z_OK) && (size_out < s->page_size)) {
+ pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_ZLIB,
+ endian);
+ pd.size = cpu_convert_to_target32(size_out, endian);
+
+ ret = write_cache(&page_data, buf_out, size_out, false);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write page data.\n");
+ goto out;
+ }
+#ifdef CONFIG_LZO
+ } else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
+ (lzo1x_1_compress(buf, s->page_size, buf_out,
+ (lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
+ (size_out < s->page_size)) {
+ pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_LZO,
+ endian);
+ pd.size = cpu_convert_to_target32(size_out, endian);
+
+ ret = write_cache(&page_data, buf_out, size_out, false);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write page data.\n");
+ goto out;
+ }
+#endif
+#ifdef CONFIG_SNAPPY
+ } else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
+ (snappy_compress((char *)buf, s->page_size,
+ (char *)buf_out, &size_out) == SNAPPY_OK) &&
+ (size_out < s->page_size)) {
+ pd.flags = cpu_convert_to_target32(
+ DUMP_DH_COMPRESSED_SNAPPY, endian);
+ pd.size = cpu_convert_to_target32(size_out, endian);
+
+ ret = write_cache(&page_data, buf_out, size_out, false);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write page data.\n");
+ goto out;
+ }
+#endif
+ } else {
+ /*
+ * fall back to save in plaintext, size_out should be
+ * assigned to s->page_size
+ */
+ pd.flags = cpu_convert_to_target32(0, endian);
+ size_out = s->page_size;
+ pd.size = cpu_convert_to_target32(size_out, endian);
+
+ ret = write_cache(&page_data, buf, s->page_size, false);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write page data.\n");
+ goto out;
+ }
+ }
+
+ /* get and write page desc here */
+ pd.page_flags = cpu_convert_to_target64(0, endian);
+ pd.offset = cpu_convert_to_target64(offset_data, endian);
+ offset_data += size_out;
+
+ ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write page desc.\n");
+ goto out;
+ }
+ }
+ }
+
+ ret = write_cache(&page_desc, NULL, 0, true);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to sync cache for page_desc.\n");
+ goto out;
+ }
+ ret = write_cache(&page_data, NULL, 0, true);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to sync cache for page_data.\n");
+ goto out;
+ }
+
+out:
+ free_data_cache(&page_desc);
+ free_data_cache(&page_data);
+
+#ifdef CONFIG_LZO
+ g_free(wrkmem);
+#endif
+
+ g_free(buf_out);
+
+ return ret;
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 92a95e4..efab7a3 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -151,6 +151,13 @@ typedef struct DataCache {
off_t offset; /* offset of the file */
} DataCache;
+typedef struct QEMU_PACKED PageDescriptor {
+ uint64_t offset; /* the offset of the page data*/
+ uint32_t size; /* the size of this dump page */
+ uint32_t flags; /* flags */
+ uint64_t page_flags; /* page flags */
+} PageDescriptor;
+
struct GuestPhysBlockList; /* memory_mapping.h */
int cpu_get_dump_info(ArchDumpInfo *info,
const struct GuestPhysBlockList *guest_phys_blocks);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PULL 13/32] dump: add API to write dump pages
2014-03-03 17:12 ` [Qemu-devel] [PULL 13/32] dump: add API to write dump pages Luiz Capitulino
@ 2014-03-03 19:05 ` Eric Blake
0 siblings, 0 replies; 35+ messages in thread
From: Eric Blake @ 2014-03-03 19:05 UTC (permalink / raw)
To: Luiz Capitulino, peter.maydell; +Cc: qemu-devel, anthony
[-- Attachment #1: Type: text/plain, Size: 797 bytes --]
On 03/03/2014 10:12 AM, Luiz Capitulino wrote:
> From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
>
> functions are used to write page to vmcore. vmcore is written page by page.
> page desc is used to store the information of a page, including a page's size,
> offset, compression format, etc.
>
> Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Here and in other patches, the 'From:' author attribution differs from
the 'S-o-b:' attribution. Which spelling do you prefer? Can you fix
your git config and/or patch .mailmap so that browsing git history finds
all entries from you under a single preferred name, rather than having
to look through variant spellings?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 14/32] dump: make kdump-compressed format available for 'dump-guest-memory'
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (12 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 13/32] dump: add API to write dump pages Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 15/32] Define the architecture for compressed dump format Luiz Capitulino
` (18 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
Make monitor command 'dump-guest-memory' be able to dump in kdump-compressed
format. The command's usage:
dump [-p] protocol [begin] [length] [format]
'format' is used to specified the format of vmcore and can be:
1. 'elf': ELF format, without compression
2. 'kdump-zlib': kdump-compressed format, with zlib-compressed
3. 'kdump-lzo': kdump-compressed format, with lzo-compressed
4. 'kdump-snappy': kdump-compressed format, with snappy-compressed
Without 'format' being set, it is same as 'elf'. And if non-elf format is
specified, paging and filter is not allowed.
Note:
1. The kdump-compressed format is readable only with the crash utility and
makedumpfile, and it can be smaller than the ELF format because of the
compression support.
2. The kdump-compressed format is the 6th edition.
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
hmp.c | 5 ++-
qapi-schema.json | 25 ++++++++++-
qmp-commands.hx | 7 ++-
4 files changed, 158 insertions(+), 10 deletions(-)
diff --git a/dump.c b/dump.c
index a7b5117..fb0c896 100644
--- a/dump.c
+++ b/dump.c
@@ -1443,6 +1443,64 @@ out:
return ret;
}
+static int create_kdump_vmcore(DumpState *s)
+{
+ int ret;
+
+ /*
+ * the kdump-compressed format is:
+ * File offset
+ * +------------------------------------------+ 0x0
+ * | main header (struct disk_dump_header) |
+ * |------------------------------------------+ block 1
+ * | sub header (struct kdump_sub_header) |
+ * |------------------------------------------+ block 2
+ * | 1st-dump_bitmap |
+ * |------------------------------------------+ block 2 + X blocks
+ * | 2nd-dump_bitmap | (aligned by block)
+ * |------------------------------------------+ block 2 + 2 * X blocks
+ * | page desc for pfn 0 (struct page_desc) | (aligned by block)
+ * | page desc for pfn 1 (struct page_desc) |
+ * | : |
+ * |------------------------------------------| (not aligned by block)
+ * | page data (pfn 0) |
+ * | page data (pfn 1) |
+ * | : |
+ * +------------------------------------------+
+ */
+
+ ret = write_start_flat_header(s->fd);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write start flat header.\n");
+ return -1;
+ }
+
+ ret = write_dump_header(s);
+ if (ret < 0) {
+ return -1;
+ }
+
+ ret = write_dump_bitmap(s);
+ if (ret < 0) {
+ return -1;
+ }
+
+ ret = write_dump_pages(s);
+ if (ret < 0) {
+ return -1;
+ }
+
+ ret = write_end_flat_header(s->fd);
+ if (ret < 0) {
+ dump_error(s, "dump: failed to write end flat header.\n");
+ return -1;
+ }
+
+ dump_completed(s);
+
+ return 0;
+}
+
static ram_addr_t get_start_block(DumpState *s)
{
GuestPhysBlock *block;
@@ -1479,7 +1537,8 @@ static void get_max_mapnr(DumpState *s)
s->max_mapnr = paddr_to_pfn(last_block->target_end, s->page_shift);
}
-static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
+static int dump_init(DumpState *s, int fd, bool has_format,
+ DumpGuestMemoryFormat format, bool paging, bool has_filter,
int64_t begin, int64_t length, Error **errp)
{
CPUState *cpu;
@@ -1487,6 +1546,11 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
Error *err = NULL;
int ret;
+ /* kdump-compressed is conflict with paging and filter */
+ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ assert(!paging && !has_filter);
+ }
+
if (runstate_is_running()) {
vm_stop(RUN_STATE_SAVE_VM);
s->resume = true;
@@ -1557,6 +1621,28 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size);
s->len_dump_bitmap = tmp * s->page_size;
+ /* init for kdump-compressed format */
+ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ switch (format) {
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB:
+ s->flag_compress = DUMP_DH_COMPRESSED_ZLIB;
+ break;
+
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
+ s->flag_compress = DUMP_DH_COMPRESSED_LZO;
+ break;
+
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY:
+ s->flag_compress = DUMP_DH_COMPRESSED_SNAPPY;
+ break;
+
+ default:
+ s->flag_compress = 0;
+ }
+
+ return 0;
+ }
+
if (s->has_filter) {
memory_mapping_filter(&s->list, s->begin, s->length);
}
@@ -1616,14 +1702,25 @@ cleanup:
}
void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
- int64_t begin, bool has_length, int64_t length,
- Error **errp)
+ int64_t begin, bool has_length,
+ int64_t length, bool has_format,
+ DumpGuestMemoryFormat format, Error **errp)
{
const char *p;
int fd = -1;
DumpState *s;
int ret;
+ /*
+ * kdump-compressed format need the whole memory dumped, so paging or
+ * filter is not supported here.
+ */
+ if ((has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) &&
+ (paging || has_begin || has_length)) {
+ error_setg(errp, "kdump-compressed format doesn't support paging or "
+ "filter");
+ return;
+ }
if (has_begin && !has_length) {
error_set(errp, QERR_MISSING_PARAMETER, "length");
return;
@@ -1633,6 +1730,21 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
return;
}
+ /* check whether lzo/snappy is supported */
+#ifndef CONFIG_LZO
+ if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO) {
+ error_setg(errp, "kdump-lzo is not available now");
+ return;
+ }
+#endif
+
+#ifndef CONFIG_SNAPPY
+ if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY) {
+ error_setg(errp, "kdump-snappy is not available now");
+ return;
+ }
+#endif
+
#if !defined(WIN32)
if (strstart(file, "fd:", &p)) {
fd = monitor_get_fd(cur_mon, p, errp);
@@ -1657,14 +1769,21 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
s = g_malloc0(sizeof(DumpState));
- ret = dump_init(s, fd, paging, has_begin, begin, length, errp);
+ ret = dump_init(s, fd, has_format, format, paging, has_begin,
+ begin, length, errp);
if (ret < 0) {
g_free(s);
return;
}
- if (create_vmcore(s) < 0 && !error_is_set(s->errp)) {
- error_set(errp, QERR_IO_ERROR);
+ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ if (create_kdump_vmcore(s) < 0 && !error_is_set(s->errp)) {
+ error_set(errp, QERR_IO_ERROR);
+ }
+ } else {
+ if (create_vmcore(s) < 0 && !error_is_set(s->errp)) {
+ error_set(errp, QERR_IO_ERROR);
+ }
}
g_free(s);
diff --git a/hmp.c b/hmp.c
index e3ddd46..2f279c4 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1311,8 +1311,11 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
const char *file = qdict_get_str(qdict, "filename");
bool has_begin = qdict_haskey(qdict, "begin");
bool has_length = qdict_haskey(qdict, "length");
+ /* kdump-compressed format is not supported for HMP */
+ bool has_format = false;
int64_t begin = 0;
int64_t length = 0;
+ enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
char *prot;
if (has_begin) {
@@ -1325,7 +1328,7 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
prot = g_strconcat("file:", file, NULL);
qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
- &errp);
+ has_format, dump_format, &errp);
hmp_handle_error(mon, &errp);
g_free(prot);
}
diff --git a/qapi-schema.json b/qapi-schema.json
index ac8ad24..0d04ace 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2795,6 +2795,24 @@
{ 'command': 'device_del', 'data': {'id': 'str'} }
##
+# @DumpGuestMemoryFormat:
+#
+# An enumeration of guest-memory-dump's format.
+#
+# @elf: elf format
+#
+# @kdump-zlib: kdump-compressed format with zlib-compressed
+#
+# @kdump-lzo: kdump-compressed format with lzo-compressed
+#
+# @kdump-snappy: kdump-compressed format with snappy-compressed
+#
+# Since: 2.0
+##
+{ 'enum': 'DumpGuestMemoryFormat',
+ 'data': [ 'elf', 'kdump-zlib', 'kdump-lzo', 'kdump-snappy' ] }
+
+##
# @dump-guest-memory
#
# Dump guest's memory to vmcore. It is a synchronous operation that can take
@@ -2830,13 +2848,18 @@
# want to dump all guest's memory, please specify the start @begin
# and @length
#
+# @format: #optional if specified, the format of guest memory dump. But non-elf
+# format is conflict with paging and filter, ie. @paging, @begin and
+# @length is not allowed to be specified with non-elf @format at the
+# same time (since 2.0)
+#
# Returns: nothing on success
#
# Since: 1.2
##
{ 'command': 'dump-guest-memory',
'data': { 'paging': 'bool', 'protocol': 'str', '*begin': 'int',
- '*length': 'int' } }
+ '*length': 'int', '*format': 'DumpGuestMemoryFormat' } }
##
# @netdev_add:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 8a0e832..8da11ac 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -791,8 +791,8 @@ EQMP
{
.name = "dump-guest-memory",
- .args_type = "paging:b,protocol:s,begin:i?,end:i?",
- .params = "-p protocol [begin] [length]",
+ .args_type = "paging:b,protocol:s,begin:i?,end:i?,format:s?",
+ .params = "-p protocol [begin] [length] [format]",
.help = "dump guest memory to file",
.user_print = monitor_user_noop,
.mhandler.cmd_new = qmp_marshal_input_dump_guest_memory,
@@ -813,6 +813,9 @@ Arguments:
with length together (json-int)
- "length": the memory size, in bytes. It's optional, and should be specified
with begin together (json-int)
+- "format": the format of guest memory dump. It's optional, and can be
+ elf|kdump-zlib|kdump-lzo|kdump-snappy, but non-elf formats will
+ conflict with paging and filter, ie. begin and length (json-string)
Example:
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 15/32] Define the architecture for compressed dump format
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (13 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 14/32] dump: make kdump-compressed format available for 'dump-guest-memory' Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 16/32] dump: add 'query-dump-guest-memory-capability' command Luiz Capitulino
` (17 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
Signed-off-by: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 7 +++++--
target-i386/cpu.h | 2 ++
target-s390x/cpu.h | 1 +
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/dump.c b/dump.c
index fb0c896..2c81318 100644
--- a/dump.c
+++ b/dump.c
@@ -32,6 +32,9 @@
#ifdef CONFIG_SNAPPY
#include <snappy-c.h>
#endif
+#ifndef ELF_MACHINE_UNAME
+#define ELF_MACHINE_UNAME "Unknown"
+#endif
static uint16_t cpu_convert_to_target16(uint16_t val, int endian)
{
@@ -817,7 +820,7 @@ static int create_header32(DumpState *s)
dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
- memcpy(&(dh->utsname.machine), "i686", 4);
+ strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
status |= DUMP_DH_COMPRESSED_ZLIB;
@@ -924,7 +927,7 @@ static int create_header64(DumpState *s)
dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
- memcpy(&(dh->utsname.machine), "x86_64", 6);
+ strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
status |= DUMP_DH_COMPRESSED_ZLIB;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 1b94f0f..6abcd23 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -38,8 +38,10 @@
#ifdef TARGET_X86_64
#define ELF_MACHINE EM_X86_64
+#define ELF_MACHINE_UNAME "x86_64"
#else
#define ELF_MACHINE EM_386
+#define ELF_MACHINE_UNAME "i686"
#endif
#define CPUArchState struct CPUX86State
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 96c2b4a..6d46827 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -28,6 +28,7 @@
#define TARGET_LONG_BITS 64
#define ELF_MACHINE EM_S390
+#define ELF_MACHINE_UNAME "S390X"
#define CPUArchState struct CPUS390XState
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 16/32] dump: add 'query-dump-guest-memory-capability' command
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (14 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 15/32] Define the architecture for compressed dump format Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 17/32] qmp: Check for returned data from __json_read in get_events Luiz Capitulino
` (16 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
'query-dump-guest-memory-capability' is used to query the available formats for
'dump-guest-memory'. The output of the command will be like:
-> { "execute": "query-dump-guest-memory-capability" }
<- { "return": { "formats":
["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] }
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
dump.c | 33 +++++++++++++++++++++++++++++++++
qapi-schema.json | 24 ++++++++++++++++++++++++
qmp-commands.hx | 20 ++++++++++++++++++++
3 files changed, 77 insertions(+)
diff --git a/dump.c b/dump.c
index 2c81318..14b3d1d 100644
--- a/dump.c
+++ b/dump.c
@@ -1791,3 +1791,36 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
g_free(s);
}
+
+DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
+{
+ DumpGuestMemoryFormatList *item;
+ DumpGuestMemoryCapability *cap =
+ g_malloc0(sizeof(DumpGuestMemoryCapability));
+
+ /* elf is always available */
+ item = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ cap->formats = item;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_ELF;
+
+ /* kdump-zlib is always available */
+ item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ item = item->next;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
+
+ /* add new item if kdump-lzo is available */
+#ifdef CONFIG_LZO
+ item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ item = item->next;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
+#endif
+
+ /* add new item if kdump-snappy is available */
+#ifdef CONFIG_SNAPPY
+ item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ item = item->next;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
+#endif
+
+ return cap;
+}
diff --git a/qapi-schema.json b/qapi-schema.json
index 0d04ace..1a5f93e 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2862,6 +2862,30 @@
'*length': 'int', '*format': 'DumpGuestMemoryFormat' } }
##
+# @DumpGuestMemoryCapability:
+#
+# A list of the available formats for dump-guest-memory
+#
+# Since: 2.0
+##
+{ 'type': 'DumpGuestMemoryCapability',
+ 'data': {
+ 'formats': ['DumpGuestMemoryFormat'] } }
+
+##
+# @query-dump-guest-memory-capability:
+#
+# Returns the available formats for dump-guest-memory
+#
+# Returns: A @DumpGuestMemoryCapability object listing available formats for
+# dump-guest-memory
+#
+# Since: 2.0
+##
+{ 'command': 'query-dump-guest-memory-capability',
+ 'returns': 'DumpGuestMemoryCapability' }
+
+##
# @netdev_add:
#
# Add a network backend.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 8da11ac..d982cd6 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -829,6 +829,26 @@ Notes:
EQMP
{
+ .name = "query-dump-guest-memory-capability",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_dump_guest_memory_capability,
+ },
+
+SQMP
+query-dump-guest-memory-capability
+----------
+
+Show available formats for 'dump-guest-memory'
+
+Example:
+
+-> { "execute": "query-dump-guest-memory-capability" }
+<- { "return": { "formats":
+ ["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] }
+
+EQMP
+
+ {
.name = "netdev_add",
.args_type = "netdev:O",
.mhandler.cmd_new = qmp_netdev_add,
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 17/32] qmp: Check for returned data from __json_read in get_events
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (15 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 16/32] dump: add 'query-dump-guest-memory-capability' command Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 18/32] qerror: Improve QERR_DEVICE_NOT_ACTIVE message Luiz Capitulino
` (15 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Fam Zheng <famz@redhat.com>
When QEMU process aborts and socket is closed, qmp client will not
detect it. When this happens, some qemu-iotests scripts will enter an
endless loop waiting for qmp events.
It's better we raise an exception in qmp.py to catch this and make the
test script stop.
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
scripts/qmp/qmp.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/scripts/qmp/qmp.py b/scripts/qmp/qmp.py
index 5c97175..20b6ec7 100644
--- a/scripts/qmp/qmp.py
+++ b/scripts/qmp/qmp.py
@@ -171,7 +171,12 @@ class QEMUMonitorProtocol:
pass
self.__sock.setblocking(1)
if not self.__events and wait:
- self.__json_read(only_event=True)
+ ret = self.__json_read(only_event=True)
+ if ret == None:
+ # We are in blocking mode, if don't get anything, something
+ # went wrong
+ raise QMPConnectError("Error while reading from socket")
+
return self.__events
def clear_events(self):
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 18/32] qerror: Improve QERR_DEVICE_NOT_ACTIVE message
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (16 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 17/32] qmp: Check for returned data from __json_read in get_events Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 19/32] monitor: Remove left-over code in do_info_profile Luiz Capitulino
` (14 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Hani Benhabiles <kroosec@gmail.com>
The error message as currently used is confusing as there are no "balloon" or
"spice" devices.
(qemu) balloon 1024
balloon: Device 'balloon' has not been activated
With this patch:
(qemu) balloon 1024
balloon: No balloon device has been activated
Signed-off-by: Hani Benhabiles <hani@linux.com>
Suggested-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
include/qapi/qmp/qerror.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 73c67b7..25193c9 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -105,7 +105,7 @@ void qerror_report_err(Error *err);
ERROR_CLASS_GENERIC_ERROR, "Device '%s' does not support hotplugging"
#define QERR_DEVICE_NOT_ACTIVE \
- ERROR_CLASS_DEVICE_NOT_ACTIVE, "Device '%s' has not been activated"
+ ERROR_CLASS_DEVICE_NOT_ACTIVE, "No %s device has been activated"
#define QERR_DEVICE_NOT_ENCRYPTED \
ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not encrypted"
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 19/32] monitor: Remove left-over code in do_info_profile.
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (17 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 18/32] qerror: Improve QERR_DEVICE_NOT_ACTIVE message Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 20/32] tests/qapi-schema: Actually check successful QMP command response Luiz Capitulino
` (13 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Hani Benhabiles <kroosec@gmail.com>
This is a left-over from 4a1418e.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
monitor.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/monitor.c b/monitor.c
index aebcbd8..3863d83 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2021,10 +2021,6 @@ int64_t dev_time;
static void do_info_profile(Monitor *mon, const QDict *qdict)
{
- int64_t total;
- total = qemu_time;
- if (total == 0)
- total = 1;
monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n",
dev_time, dev_time / (double)get_ticks_per_sec());
monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n",
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 20/32] tests/qapi-schema: Actually check successful QMP command response
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (18 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 19/32] monitor: Remove left-over code in do_info_profile Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 21/32] tests/qapi-schema: Cover optional command arguments Luiz Capitulino
` (12 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/test-qmp-commands.c | 43 +++++++++++++++++++++++++++++++++++--------
1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 5a3e82a..d039b87 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -71,6 +71,23 @@ static void test_dispatch_cmd_error(void)
QDECREF(req);
}
+static QObject *test_qmp_dispatch(QDict *req)
+{
+ QObject *resp_obj;
+ QDict *resp;
+ QObject *ret;
+
+ resp_obj = qmp_dispatch(QOBJECT(req));
+ assert(resp_obj);
+ resp = qobject_to_qdict(resp_obj);
+ assert(resp && !qdict_haskey(resp, "error"));
+ ret = qdict_get(resp, "return");
+ assert(ret);
+ qobject_incref(ret);
+ qobject_decref(resp_obj);
+ return ret;
+}
+
/* test commands that involve both input parameters and return values */
static void test_dispatch_cmd_io(void)
{
@@ -78,7 +95,8 @@ static void test_dispatch_cmd_io(void)
QDict *args = qdict_new();
QDict *ud1a = qdict_new();
QDict *ud1b = qdict_new();
- QObject *resp;
+ QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef;
+ QDict *ret_dict_dict2, *ret_dict_dict2_userdef;
qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42)));
qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello")));
@@ -87,15 +105,24 @@ static void test_dispatch_cmd_io(void)
qdict_put_obj(args, "ud1a", QOBJECT(ud1a));
qdict_put_obj(args, "ud1b", QOBJECT(ud1b));
qdict_put_obj(req, "arguments", QOBJECT(args));
-
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
- /* TODO: put in full payload and check for errors */
- resp = qmp_dispatch(QOBJECT(req));
- assert(resp != NULL);
- assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
-
- qobject_decref(resp);
+ ret = qobject_to_qdict(test_qmp_dispatch(req));
+
+ assert(!strcmp(qdict_get_str(ret, "string"), "blah1"));
+ ret_dict = qdict_get_qdict(ret, "dict");
+ assert(!strcmp(qdict_get_str(ret_dict, "string"), "blah2"));
+ ret_dict_dict = qdict_get_qdict(ret_dict, "dict");
+ ret_dict_dict_userdef = qdict_get_qdict(ret_dict_dict, "userdef");
+ assert(qdict_get_int(ret_dict_dict_userdef, "integer") == 42);
+ assert(!strcmp(qdict_get_str(ret_dict_dict_userdef, "string"), "hello"));
+ assert(!strcmp(qdict_get_str(ret_dict_dict, "string"), "blah3"));
+ ret_dict_dict2 = qdict_get_qdict(ret_dict, "dict2");
+ ret_dict_dict2_userdef = qdict_get_qdict(ret_dict_dict2, "userdef");
+ assert(qdict_get_int(ret_dict_dict2_userdef, "integer") == 422);
+ assert(!strcmp(qdict_get_str(ret_dict_dict2_userdef, "string"), "hello2"));
+ assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4"));
+ QDECREF(ret);
QDECREF(req);
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 21/32] tests/qapi-schema: Cover optional command arguments
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (19 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 20/32] tests/qapi-schema: Actually check successful QMP command response Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 22/32] tests/qapi-schema: Cover simple argument types Luiz Capitulino
` (11 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/qapi-schema/qapi-schema-test.json | 4 +++-
tests/qapi-schema/qapi-schema-test.out | 2 +-
tests/test-qmp-commands.c | 8 +++++---
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index fe5af75..d2b1397 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -50,7 +50,9 @@
# testing commands
{ 'command': 'user_def_cmd', 'data': {} }
{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
-{ 'command': 'user_def_cmd2', 'data': {'ud1a': 'UserDefOne', 'ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' }
+{ 'command': 'user_def_cmd2',
+ 'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'},
+ 'returns': 'UserDefTwo' }
# For testing integer range flattening in opts-visitor. The following schema
# corresponds to the option format:
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 3851880..af9829e 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -9,7 +9,7 @@
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 'UserDefOne')]))]),
- OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
+ OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('*ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
['EnumOne', 'UserDefUnionKind', 'UserDefNativeListUnionKind']
[OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index d039b87..d7720ab 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -16,7 +16,9 @@ void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp)
{
}
-UserDefTwo * qmp_user_def_cmd2(UserDefOne * ud1a, UserDefOne * ud1b, Error **errp)
+UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
+ bool has_udb1, UserDefOne *ud1b,
+ Error **errp)
{
UserDefTwo *ret;
UserDefOne *ud1c = g_malloc0(sizeof(UserDefOne));
@@ -24,8 +26,8 @@ UserDefTwo * qmp_user_def_cmd2(UserDefOne * ud1a, UserDefOne * ud1b, Error **err
ud1c->string = strdup(ud1a->string);
ud1c->integer = ud1a->integer;
- ud1d->string = strdup(ud1b->string);
- ud1d->integer = ud1b->integer;
+ ud1d->string = strdup(has_udb1 ? ud1b->string : "blah0");
+ ud1d->integer = has_udb1 ? ud1b->integer : 0;
ret = g_malloc0(sizeof(UserDefTwo));
ret->string = strdup("blah1");
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 22/32] tests/qapi-schema: Cover simple argument types
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (20 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 21/32] tests/qapi-schema: Cover optional command arguments Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 23/32] tests/qapi-schema: Cover anonymous union types Luiz Capitulino
` (10 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/qapi-schema/qapi-schema-test.json | 2 ++
tests/qapi-schema/qapi-schema-test.out | 1 +
tests/test-qmp-commands.c | 16 ++++++++++++++++
3 files changed, 19 insertions(+)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index d2b1397..3f62821 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -53,6 +53,8 @@
{ 'command': 'user_def_cmd2',
'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'},
'returns': 'UserDefTwo' }
+{ 'command': 'user_def_cmd3', 'data': {'a': 'int', '*b': 'int' },
+ 'returns': 'int' }
# For testing integer range flattening in opts-visitor. The following schema
# corresponds to the option format:
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index af9829e..59468ac 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -10,6 +10,7 @@
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 'UserDefOne')]))]),
OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('*ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
+ OrderedDict([('command', 'user_def_cmd3'), ('data', OrderedDict([('a', 'int'), ('*b', 'int')])), ('returns', 'int')]),
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
['EnumOne', 'UserDefUnionKind', 'UserDefNativeListUnionKind']
[OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index d7720ab..4586cee 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -41,6 +41,11 @@ UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
return ret;
}
+int64_t qmp_user_def_cmd3(int64_t a, bool has_b, int64_t b, Error **errp)
+{
+ return a + (has_b ? b : 0);
+}
+
/* test commands with no input and no return value */
static void test_dispatch_cmd(void)
{
@@ -95,10 +100,12 @@ static void test_dispatch_cmd_io(void)
{
QDict *req = qdict_new();
QDict *args = qdict_new();
+ QDict *args3 = qdict_new();
QDict *ud1a = qdict_new();
QDict *ud1b = qdict_new();
QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef;
QDict *ret_dict_dict2, *ret_dict_dict2_userdef;
+ QInt *ret3;
qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42)));
qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello")));
@@ -125,6 +132,15 @@ static void test_dispatch_cmd_io(void)
assert(!strcmp(qdict_get_str(ret_dict_dict2_userdef, "string"), "hello2"));
assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4"));
QDECREF(ret);
+
+ qdict_put(args3, "a", qint_from_int(66));
+ qdict_put(req, "arguments", args3);
+ qdict_put(req, "execute", qstring_from_str("user_def_cmd3"));
+
+ ret3 = qobject_to_qint(test_qmp_dispatch(req));
+ assert(qint_get_int(ret3) == 66);
+ QDECREF(ret);
+
QDECREF(req);
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 23/32] tests/qapi-schema: Cover anonymous union types
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (21 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 22/32] tests/qapi-schema: Cover simple argument types Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 24/32] tests/qapi-schema: Cover complex types with base Luiz Capitulino
` (9 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/qapi-schema/qapi-schema-test.json | 4 ++++
tests/qapi-schema/qapi-schema-test.out | 6 +++++-
tests/test-qmp-input-strict.c | 32 ++++++++++++++++++++++++++++++++
tests/test-qmp-input-visitor.c | 18 ++++++++++++++++++
tests/test-qmp-output-visitor.c | 22 ++++++++++++++++++++++
5 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 3f62821..8405021 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -32,6 +32,10 @@
{ 'union': 'UserDefUnion',
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
+{ 'union': 'UserDefAnonUnion',
+ 'discriminator': {},
+ 'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }
+
# for testing native lists
{ 'union': 'UserDefNativeListUnion',
'data': { 'integer': ['int'],
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 59468ac..ac98f32 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -6,13 +6,17 @@
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
OrderedDict([('union', 'UserDefUnion'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
+ OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 'UserDefOne')]))]),
OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('*ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
OrderedDict([('command', 'user_def_cmd3'), ('data', OrderedDict([('a', 'int'), ('*b', 'int')])), ('returns', 'int')]),
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
-['EnumOne', 'UserDefUnionKind', 'UserDefNativeListUnionKind']
+['EnumOne',
+ 'UserDefUnionKind',
+ 'UserDefAnonUnionKind',
+ 'UserDefNativeListUnionKind']
[OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
OrderedDict([('type', 'UserDefOne'), ('data', OrderedDict([('integer', 'int'), ('string', 'str'), ('*enum1', 'EnumOne')]))]),
OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string', 'str'), ('dict', OrderedDict([('string', 'str'), ('dict', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict2', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 38bdf5e..67adc2a 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -139,6 +139,20 @@ static void test_validate_union(TestInputVisitorData *data,
qapi_free_UserDefUnion(tmp);
}
+static void test_validate_union_anon(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefAnonUnion *tmp = NULL;
+ Visitor *v;
+ Error *errp = NULL;
+
+ v = validate_test_init(data, "42");
+
+ visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ qapi_free_UserDefAnonUnion(tmp);
+}
+
static void test_validate_fail_struct(TestInputVisitorData *data,
const void *unused)
{
@@ -198,6 +212,20 @@ static void test_validate_fail_union(TestInputVisitorData *data,
qapi_free_UserDefUnion(tmp);
}
+static void test_validate_fail_union_anon(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefAnonUnion *tmp = NULL;
+ Visitor *v;
+ Error *errp = NULL;
+
+ v = validate_test_init(data, "3.14");
+
+ visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);
+ g_assert(error_is_set(&errp));
+ qapi_free_UserDefAnonUnion(tmp);
+}
+
static void validate_test_add(const char *testpath,
TestInputVisitorData *data,
void (*test_func)(TestInputVisitorData *data, const void *user_data))
@@ -220,6 +248,8 @@ int main(int argc, char **argv)
&testdata, test_validate_list);
validate_test_add("/visitor/input-strict/pass/union",
&testdata, test_validate_union);
+ validate_test_add("/visitor/input-strict/pass/union-anon",
+ &testdata, test_validate_union_anon);
validate_test_add("/visitor/input-strict/fail/struct",
&testdata, test_validate_fail_struct);
validate_test_add("/visitor/input-strict/fail/struct-nested",
@@ -228,6 +258,8 @@ int main(int argc, char **argv)
&testdata, test_validate_fail_list);
validate_test_add("/visitor/input-strict/fail/union",
&testdata, test_validate_fail_union);
+ validate_test_add("/visitor/input-strict/fail/union-anon",
+ &testdata, test_validate_fail_union_anon);
g_test_run();
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 6eb7dc5..eadb6e9 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -302,6 +302,22 @@ static void test_visitor_in_union(TestInputVisitorData *data,
qapi_free_UserDefUnion(tmp);
}
+static void test_visitor_in_union_anon(TestInputVisitorData *data,
+ const void *unused)
+{
+ Visitor *v;
+ Error *err = NULL;
+ UserDefAnonUnion *tmp;
+
+ v = visitor_input_test_init(data, "42");
+
+ visit_type_UserDefAnonUnion(v, &tmp, NULL, &err);
+ g_assert(err == NULL);
+ g_assert_cmpint(tmp->kind, ==, USER_DEF_ANON_UNION_KIND_I);
+ g_assert_cmpint(tmp->i, ==, 42);
+ qapi_free_UserDefAnonUnion(tmp);
+}
+
static void test_native_list_integer_helper(TestInputVisitorData *data,
const void *unused,
UserDefNativeListUnionKind kind)
@@ -635,6 +651,8 @@ int main(int argc, char **argv)
&in_visitor_data, test_visitor_in_list);
input_visitor_test_add("/visitor/input/union",
&in_visitor_data, test_visitor_in_union);
+ input_visitor_test_add("/visitor/input/union-anon",
+ &in_visitor_data, test_visitor_in_union_anon);
input_visitor_test_add("/visitor/input/errors",
&in_visitor_data, test_visitor_in_errors);
input_visitor_test_add("/visitor/input/native_list/int",
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index f31d168..ae4e68c 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -434,6 +434,26 @@ static void test_visitor_out_union(TestOutputVisitorData *data,
QDECREF(qdict);
}
+static void test_visitor_out_union_anon(TestOutputVisitorData *data,
+ const void *unused)
+{
+ QObject *arg;
+ Error *err = NULL;
+
+ UserDefAnonUnion *tmp = g_malloc0(sizeof(UserDefAnonUnion));
+ tmp->kind = USER_DEF_ANON_UNION_KIND_I;
+ tmp->i = 42;
+
+ visit_type_UserDefAnonUnion(data->ov, &tmp, NULL, &err);
+ g_assert(err == NULL);
+ arg = qmp_output_get_qobject(data->qov);
+
+ g_assert(qobject_type(arg) == QTYPE_QINT);
+ g_assert_cmpint(qint_get_int(qobject_to_qint(arg)), ==, 42);
+
+ qapi_free_UserDefAnonUnion(tmp);
+}
+
static void init_native_list(UserDefNativeListUnion *cvalue)
{
int i;
@@ -782,6 +802,8 @@ int main(int argc, char **argv)
&out_visitor_data, test_visitor_out_list_qapi_free);
output_visitor_test_add("/visitor/output/union",
&out_visitor_data, test_visitor_out_union);
+ output_visitor_test_add("/visitor/output/union-anon",
+ &out_visitor_data, test_visitor_out_union_anon);
output_visitor_test_add("/visitor/output/native_list/int",
&out_visitor_data, test_visitor_out_native_list_int);
output_visitor_test_add("/visitor/output/native_list/int8",
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 24/32] tests/qapi-schema: Cover complex types with base
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (22 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 23/32] tests/qapi-schema: Cover anonymous union types Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 25/32] tests/qapi-schema: Cover union " Luiz Capitulino
` (8 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/qapi-schema/qapi-schema-test.json | 6 +++++-
tests/qapi-schema/qapi-schema-test.out | 6 ++++--
tests/test-qmp-commands.c | 15 ++++++++++-----
tests/test-qmp-input-visitor.c | 4 ++--
tests/test-qmp-output-visitor.c | 12 ++++++++----
tests/test-visitor-serialization.c | 14 ++++++++------
6 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 8405021..c7e6be8 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -7,8 +7,12 @@
'data': { 'enum1': 'EnumOne', '*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } }
# for testing nested structs
+{ 'type': 'UserDefZero',
+ 'data': { 'integer': 'int' } }
+
{ 'type': 'UserDefOne',
- 'data': { 'integer': 'int', 'string': 'str', '*enum1': 'EnumOne' } }
+ 'base': 'UserDefZero',
+ 'data': { 'string': 'str', '*enum1': 'EnumOne' } }
{ 'type': 'UserDefTwo',
'data': { 'string': 'str',
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index ac98f32..89e213a 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -1,6 +1,7 @@
[OrderedDict([('enum', 'EnumOne'), ('data', ['value1', 'value2', 'value3'])]),
OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
- OrderedDict([('type', 'UserDefOne'), ('data', OrderedDict([('integer', 'int'), ('string', 'str'), ('*enum1', 'EnumOne')]))]),
+ OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string', 'str'), ('dict', OrderedDict([('string', 'str'), ('dict', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict2', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
@@ -18,7 +19,8 @@
'UserDefAnonUnionKind',
'UserDefNativeListUnionKind']
[OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
- OrderedDict([('type', 'UserDefOne'), ('data', OrderedDict([('integer', 'int'), ('string', 'str'), ('*enum1', 'EnumOne')]))]),
+ OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string', 'str'), ('dict', OrderedDict([('string', 'str'), ('dict', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict2', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 4586cee..8e62c2d 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -25,9 +25,11 @@ UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));
ud1c->string = strdup(ud1a->string);
- ud1c->integer = ud1a->integer;
+ ud1c->base = g_new0(UserDefZero, 1);
+ ud1c->base->integer = ud1a->base->integer;
ud1d->string = strdup(has_udb1 ? ud1b->string : "blah0");
- ud1d->integer = has_udb1 ? ud1b->integer : 0;
+ ud1d->base = g_new0(UserDefZero, 1);
+ ud1d->base->integer = has_udb1 ? ud1b->base->integer : 0;
ret = g_malloc0(sizeof(UserDefTwo));
ret->string = strdup("blah1");
@@ -151,17 +153,20 @@ static void test_dealloc_types(void)
UserDefOneList *ud1list;
ud1test = g_malloc0(sizeof(UserDefOne));
- ud1test->integer = 42;
+ ud1test->base = g_new0(UserDefZero, 1);
+ ud1test->base->integer = 42;
ud1test->string = g_strdup("hi there 42");
qapi_free_UserDefOne(ud1test);
ud1a = g_malloc0(sizeof(UserDefOne));
- ud1a->integer = 43;
+ ud1a->base = g_new0(UserDefZero, 1);
+ ud1a->base->integer = 43;
ud1a->string = g_strdup("hi there 43");
ud1b = g_malloc0(sizeof(UserDefOne));
- ud1b->integer = 44;
+ ud1b->base = g_new0(UserDefZero, 1);
+ ud1b->base->integer = 44;
ud1b->string = g_strdup("hi there 44");
ud1list = g_malloc0(sizeof(UserDefOneList));
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index eadb6e9..9c7bf38 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -252,7 +252,7 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
check_and_free_str(udp->string0, "string0");
check_and_free_str(udp->dict1.string1, "string1");
- g_assert_cmpint(udp->dict1.dict2.userdef1->integer, ==, 42);
+ g_assert_cmpint(udp->dict1.dict2.userdef1->base->integer, ==, 42);
check_and_free_str(udp->dict1.dict2.userdef1->string, "string");
check_and_free_str(udp->dict1.dict2.string2, "string2");
g_assert(udp->dict1.has_dict3 == false);
@@ -280,7 +280,7 @@ static void test_visitor_in_list(TestInputVisitorData *data,
snprintf(string, sizeof(string), "string%d", i);
g_assert_cmpstr(item->value->string, ==, string);
- g_assert_cmpint(item->value->integer, ==, 42 + i);
+ g_assert_cmpint(item->value->base->integer, ==, 42 + i);
}
qapi_free_UserDefOneList(head);
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index ae4e68c..6b29849 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -231,13 +231,15 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
ud2->dict1.string1 = g_strdup(strings[1]);
ud2->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
ud2->dict1.dict2.userdef1->string = g_strdup(string);
- ud2->dict1.dict2.userdef1->integer = value;
+ ud2->dict1.dict2.userdef1->base = g_new0(UserDefZero, 1);
+ ud2->dict1.dict2.userdef1->base->integer = value;
ud2->dict1.dict2.string2 = g_strdup(strings[2]);
ud2->dict1.has_dict3 = true;
ud2->dict1.dict3.userdef2 = g_malloc0(sizeof(UserDefOne));
ud2->dict1.dict3.userdef2->string = g_strdup(string);
- ud2->dict1.dict3.userdef2->integer = value;
+ ud2->dict1.dict3.userdef2->base = g_new0(UserDefZero, 1);
+ ud2->dict1.dict3.userdef2->base->integer = value;
ud2->dict1.dict3.string3 = g_strdup(strings[3]);
visit_type_UserDefNested(data->ov, &ud2, "unused", &errp);
@@ -279,7 +281,8 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
const void *unused)
{
EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
- UserDefOne u = { 0 }, *pu = &u;
+ UserDefZero b;
+ UserDefOne u = { .base = &b }, *pu = &u;
Error *errp;
int i;
@@ -391,7 +394,8 @@ static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
p->value->dict1.string1 = g_strdup(string);
p->value->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
p->value->dict1.dict2.userdef1->string = g_strdup(string);
- p->value->dict1.dict2.userdef1->integer = 42;
+ p->value->dict1.dict2.userdef1->base = g_new0(UserDefZero, 1);
+ p->value->dict1.dict2.userdef1->base->integer = 42;
p->value->dict1.dict2.string2 = g_strdup(string);
p->value->dict1.has_dict3 = false;
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index 6bff950..8166cf1 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -239,12 +239,14 @@ static UserDefNested *nested_struct_create(void)
udnp->string0 = strdup("test_string0");
udnp->dict1.string1 = strdup("test_string1");
udnp->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
- udnp->dict1.dict2.userdef1->integer = 42;
+ udnp->dict1.dict2.userdef1->base = g_new0(UserDefZero, 1);
+ udnp->dict1.dict2.userdef1->base->integer = 42;
udnp->dict1.dict2.userdef1->string = strdup("test_string");
udnp->dict1.dict2.string2 = strdup("test_string2");
udnp->dict1.has_dict3 = true;
udnp->dict1.dict3.userdef2 = g_malloc0(sizeof(UserDefOne));
- udnp->dict1.dict3.userdef2->integer = 43;
+ udnp->dict1.dict3.userdef2->base = g_new0(UserDefZero, 1);
+ udnp->dict1.dict3.userdef2->base->integer = 43;
udnp->dict1.dict3.userdef2->string = strdup("test_string");
udnp->dict1.dict3.string3 = strdup("test_string3");
return udnp;
@@ -256,14 +258,14 @@ static void nested_struct_compare(UserDefNested *udnp1, UserDefNested *udnp2)
g_assert(udnp2);
g_assert_cmpstr(udnp1->string0, ==, udnp2->string0);
g_assert_cmpstr(udnp1->dict1.string1, ==, udnp2->dict1.string1);
- g_assert_cmpint(udnp1->dict1.dict2.userdef1->integer, ==,
- udnp2->dict1.dict2.userdef1->integer);
+ g_assert_cmpint(udnp1->dict1.dict2.userdef1->base->integer, ==,
+ udnp2->dict1.dict2.userdef1->base->integer);
g_assert_cmpstr(udnp1->dict1.dict2.userdef1->string, ==,
udnp2->dict1.dict2.userdef1->string);
g_assert_cmpstr(udnp1->dict1.dict2.string2, ==, udnp2->dict1.dict2.string2);
g_assert(udnp1->dict1.has_dict3 == udnp2->dict1.has_dict3);
- g_assert_cmpint(udnp1->dict1.dict3.userdef2->integer, ==,
- udnp2->dict1.dict3.userdef2->integer);
+ g_assert_cmpint(udnp1->dict1.dict3.userdef2->base->integer, ==,
+ udnp2->dict1.dict3.userdef2->base->integer);
g_assert_cmpstr(udnp1->dict1.dict3.userdef2->string, ==,
udnp2->dict1.dict3.userdef2->string);
g_assert_cmpstr(udnp1->dict1.dict3.string3, ==, udnp2->dict1.dict3.string3);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 25/32] tests/qapi-schema: Cover union types with base
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (23 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 24/32] tests/qapi-schema: Cover complex types with base Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 26/32] tests/qapi-schema: Cover flat union types Luiz Capitulino
` (7 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/qapi-schema/qapi-schema-test.json | 1 +
tests/qapi-schema/qapi-schema-test.out | 2 +-
tests/test-qmp-input-strict.c | 4 ++--
tests/test-qmp-input-visitor.c | 3 ++-
tests/test-qmp-output-visitor.c | 2 ++
5 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index c7e6be8..f5c5d37 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -34,6 +34,7 @@
'data': { 'integer': 'int' } }
{ 'union': 'UserDefUnion',
+ 'base': 'UserDefZero',
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
{ 'union': 'UserDefAnonUnion',
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 89e213a..3f51afd 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -6,7 +6,7 @@
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
- OrderedDict([('union', 'UserDefUnion'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
+ OrderedDict([('union', 'UserDefUnion'), ('base', 'UserDefZero'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 67adc2a..9b99b48 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -132,7 +132,7 @@ static void test_validate_union(TestInputVisitorData *data,
Visitor *v;
Error *errp = NULL;
- v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
+ v = validate_test_init(data, "{ 'type': 'b', 'integer': 41, 'data' : { 'integer': 42 } }");
visit_type_UserDefUnion(v, &tmp, NULL, &errp);
g_assert(!errp);
@@ -205,7 +205,7 @@ static void test_validate_fail_union(TestInputVisitorData *data,
Error *errp = NULL;
Visitor *v;
- v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 }, 'extra': 'yyy' }");
+ v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
visit_type_UserDefUnion(v, &tmp, NULL, &errp);
g_assert(errp);
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 9c7bf38..a0607cf 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -293,11 +293,12 @@ static void test_visitor_in_union(TestInputVisitorData *data,
Error *err = NULL;
UserDefUnion *tmp;
- v = visitor_input_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
+ v = visitor_input_test_init(data, "{ 'type': 'b', 'integer': 41, 'data' : { 'integer': 42 } }");
visit_type_UserDefUnion(v, &tmp, NULL, &err);
g_assert(err == NULL);
g_assert_cmpint(tmp->kind, ==, USER_DEF_UNION_KIND_B);
+ g_assert_cmpint(tmp->integer, ==, 41);
g_assert_cmpint(tmp->b->integer, ==, 42);
qapi_free_UserDefUnion(tmp);
}
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 6b29849..c932871 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -416,6 +416,7 @@ static void test_visitor_out_union(TestOutputVisitorData *data,
UserDefUnion *tmp = g_malloc0(sizeof(UserDefUnion));
tmp->kind = USER_DEF_UNION_KIND_A;
+ tmp->integer = 41;
tmp->a = g_malloc0(sizeof(UserDefA));
tmp->a->boolean = true;
@@ -427,6 +428,7 @@ static void test_visitor_out_union(TestOutputVisitorData *data,
qdict = qobject_to_qdict(arg);
g_assert_cmpstr(qdict_get_str(qdict, "type"), ==, "a");
+ g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
qvalue = qdict_get(qdict, "data");
g_assert(data != NULL);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 26/32] tests/qapi-schema: Cover flat union types
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (24 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 25/32] tests/qapi-schema: Cover union " Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 27/32] qapi: Fix licensing of scripts Luiz Capitulino
` (6 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
The test demonstrates a generator bug: the generated struct
UserDefFlatUnion doesn't include members for the indirect base
UserDefZero.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
tests/qapi-schema/qapi-schema-test.json | 7 +++++++
tests/qapi-schema/qapi-schema-test.out | 2 ++
tests/test-qmp-input-strict.c | 33 +++++++++++++++++++++++++++++++++
tests/test-qmp-input-visitor.c | 20 ++++++++++++++++++++
tests/test-qmp-output-visitor.c | 31 +++++++++++++++++++++++++++++++
5 files changed, 93 insertions(+)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index f5c5d37..471ba47 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -37,6 +37,13 @@
'base': 'UserDefZero',
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
+{ 'union': 'UserDefFlatUnion',
+ 'base': 'UserDefOne',
+ 'discriminator': 'string',
+ 'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
+# FIXME generated struct UserDefFlatUnion has members for direct base
+# UserDefOne, but lacks members for indirect base UserDefZero
+
{ 'union': 'UserDefAnonUnion',
'discriminator': {},
'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 3f51afd..89b53d4 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -7,6 +7,7 @@
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
OrderedDict([('union', 'UserDefUnion'), ('base', 'UserDefZero'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
+ OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefOne'), ('discriminator', 'string'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
@@ -16,6 +17,7 @@
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
['EnumOne',
'UserDefUnionKind',
+ 'UserDefFlatUnionKind',
'UserDefAnonUnionKind',
'UserDefNativeListUnionKind']
[OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 9b99b48..64d72f6 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -139,6 +139,21 @@ static void test_validate_union(TestInputVisitorData *data,
qapi_free_UserDefUnion(tmp);
}
+static void test_validate_union_flat(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefFlatUnion *tmp = NULL;
+ Visitor *v;
+ Error *errp = NULL;
+
+ v = validate_test_init(data, "{ 'string': 'a', 'boolean': true }");
+ /* TODO when generator bug is fixed, add 'integer': 41 */
+
+ visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ qapi_free_UserDefFlatUnion(tmp);
+}
+
static void test_validate_union_anon(TestInputVisitorData *data,
const void *unused)
{
@@ -212,6 +227,20 @@ static void test_validate_fail_union(TestInputVisitorData *data,
qapi_free_UserDefUnion(tmp);
}
+static void test_validate_fail_union_flat(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefFlatUnion *tmp = NULL;
+ Error *errp = NULL;
+ Visitor *v;
+
+ v = validate_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");
+
+ visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
+ g_assert(error_is_set(&errp));
+ qapi_free_UserDefFlatUnion(tmp);
+}
+
static void test_validate_fail_union_anon(TestInputVisitorData *data,
const void *unused)
{
@@ -248,6 +277,8 @@ int main(int argc, char **argv)
&testdata, test_validate_list);
validate_test_add("/visitor/input-strict/pass/union",
&testdata, test_validate_union);
+ validate_test_add("/visitor/input-strict/pass/union-flat",
+ &testdata, test_validate_union_flat);
validate_test_add("/visitor/input-strict/pass/union-anon",
&testdata, test_validate_union_anon);
validate_test_add("/visitor/input-strict/fail/struct",
@@ -258,6 +289,8 @@ int main(int argc, char **argv)
&testdata, test_validate_fail_list);
validate_test_add("/visitor/input-strict/fail/union",
&testdata, test_validate_fail_union);
+ validate_test_add("/visitor/input-strict/fail/union-flat",
+ &testdata, test_validate_fail_union_flat);
validate_test_add("/visitor/input-strict/fail/union-anon",
&testdata, test_validate_fail_union_anon);
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index a0607cf..2dffafc 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -303,6 +303,24 @@ static void test_visitor_in_union(TestInputVisitorData *data,
qapi_free_UserDefUnion(tmp);
}
+static void test_visitor_in_union_flat(TestInputVisitorData *data,
+ const void *unused)
+{
+ Visitor *v;
+ Error *err = NULL;
+ UserDefFlatUnion *tmp;
+
+ v = visitor_input_test_init(data, "{ 'string': 'a', 'boolean': true }");
+ /* TODO when generator bug is fixed, add 'integer': 41 */
+
+ visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
+ g_assert(err == NULL);
+ g_assert_cmpint(tmp->kind, ==, USER_DEF_UNION_KIND_A);
+ /* TODO g_assert_cmpint(tmp->integer, ==, 41); */
+ g_assert_cmpint(tmp->a->boolean, ==, true);
+ qapi_free_UserDefFlatUnion(tmp);
+}
+
static void test_visitor_in_union_anon(TestInputVisitorData *data,
const void *unused)
{
@@ -652,6 +670,8 @@ int main(int argc, char **argv)
&in_visitor_data, test_visitor_in_list);
input_visitor_test_add("/visitor/input/union",
&in_visitor_data, test_visitor_in_union);
+ input_visitor_test_add("/visitor/input/union-flat",
+ &in_visitor_data, test_visitor_in_union_flat);
input_visitor_test_add("/visitor/input/union-anon",
&in_visitor_data, test_visitor_in_union_anon);
input_visitor_test_add("/visitor/input/errors",
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index c932871..105f4cf 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -440,6 +440,35 @@ static void test_visitor_out_union(TestOutputVisitorData *data,
QDECREF(qdict);
}
+static void test_visitor_out_union_flat(TestOutputVisitorData *data,
+ const void *unused)
+{
+ QObject *arg;
+ QDict *qdict;
+
+ Error *err = NULL;
+
+ UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
+ tmp->kind = USER_DEF_UNION_KIND_A;
+ tmp->a = g_malloc0(sizeof(UserDefA));
+ /* TODO when generator bug is fixed: tmp->integer = 41; */
+ tmp->a->boolean = true;
+
+ visit_type_UserDefFlatUnion(data->ov, &tmp, NULL, &err);
+ g_assert(err == NULL);
+ arg = qmp_output_get_qobject(data->qov);
+
+ g_assert(qobject_type(arg) == QTYPE_QDICT);
+ qdict = qobject_to_qdict(arg);
+
+ g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "a");
+ /* TODO g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41); */
+ g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
+
+ qapi_free_UserDefFlatUnion(tmp);
+ QDECREF(qdict);
+}
+
static void test_visitor_out_union_anon(TestOutputVisitorData *data,
const void *unused)
{
@@ -808,6 +837,8 @@ int main(int argc, char **argv)
&out_visitor_data, test_visitor_out_list_qapi_free);
output_visitor_test_add("/visitor/output/union",
&out_visitor_data, test_visitor_out_union);
+ output_visitor_test_add("/visitor/output/union-flat",
+ &out_visitor_data, test_visitor_out_union_flat);
output_visitor_test_add("/visitor/output/union-anon",
&out_visitor_data, test_visitor_out_union_anon);
output_visitor_test_add("/visitor/output/native_list/int",
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 27/32] qapi: Fix licensing of scripts
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (25 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 26/32] tests/qapi-schema: Cover flat union types Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 28/32] qapi: Drop nonsensical header guard in generated qapi-visit.c Luiz Capitulino
` (5 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
The scripts carry this copyright notice:
# This work is licensed under the terms of the GNU GPLv2.
# See the COPYING.LIB file in the top-level directory.
The sentences contradict each other, as COPYING.LIB contains the LGPL
2.1. Michael Roth says this was a simple pasto, and he meant to refer
COPYING. Let's fix that.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
scripts/qapi-commands.py | 4 ++--
scripts/qapi-types.py | 4 ++--
scripts/qapi-visit.py | 4 ++--
scripts/qapi.py | 4 ++--
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index b12b696..38c2347 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -7,8 +7,8 @@
# Anthony Liguori <aliguori@us.ibm.com>
# Michael Roth <mdroth@linux.vnet.ibm.com>
#
-# This work is licensed under the terms of the GNU GPLv2.
-# See the COPYING.LIB file in the top-level directory.
+# This work is licensed under the terms of the GNU GPL, version 2.
+# See the COPYING file in the top-level directory.
from ordereddict import OrderedDict
from qapi import *
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 4a1652b..2c6e0dc 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -6,8 +6,8 @@
# Authors:
# Anthony Liguori <aliguori@us.ibm.com>
#
-# This work is licensed under the terms of the GNU GPLv2.
-# See the COPYING.LIB file in the top-level directory.
+# This work is licensed under the terms of the GNU GPL, version 2.
+# See the COPYING file in the top-level directory.
from ordereddict import OrderedDict
from qapi import *
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 65f1a54..b2a1c1c 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -7,8 +7,8 @@
# Anthony Liguori <aliguori@us.ibm.com>
# Michael Roth <mdroth@linux.vnet.ibm.com>
#
-# This work is licensed under the terms of the GNU GPLv2.
-# See the COPYING.LIB file in the top-level directory.
+# This work is licensed under the terms of the GNU GPL, version 2.
+# See the COPYING file in the top-level directory.
from ordereddict import OrderedDict
from qapi import *
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 9b3de4c..f3c2a20 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -8,8 +8,8 @@
# Anthony Liguori <aliguori@us.ibm.com>
# Markus Armbruster <armbru@redhat.com>
#
-# This work is licensed under the terms of the GNU GPLv2.
-# See the COPYING.LIB file in the top-level directory.
+# This work is licensed under the terms of the GNU GPL, version 2.
+# See the COPYING file in the top-level directory.
from ordereddict import OrderedDict
import sys
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 28/32] qapi: Drop nonsensical header guard in generated qapi-visit.c
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (26 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 27/32] qapi: Fix licensing of scripts Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 29/32] qapi: Drop unused code in qapi-commands.py Luiz Capitulino
` (4 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
scripts/qapi-visit.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index b2a1c1c..97e9b11 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -494,10 +494,8 @@ fdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL"))
# have the functions defined, so we use -b option to provide control
# over these cases
if do_builtins:
- fdef.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
for typename in builtin_types:
fdef.write(generate_visit_list(typename, None))
- fdef.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DEF"))
for expr in exprs:
if expr.has_key('type'):
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 29/32] qapi: Drop unused code in qapi-commands.py
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (27 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 28/32] qapi: Drop nonsensical header guard in generated qapi-visit.c Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 30/32] qapi: Clean up null checking in generated visitors Luiz Capitulino
` (3 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
scripts/qapi-commands.py | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 38c2347..9734ab0 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -23,13 +23,6 @@ def type_visitor(name):
else:
return 'visit_type_%s' % name
-def generate_decl_enum(name, members, genlist=True):
- return mcgen('''
-
-void %(visitor)s(Visitor *m, %(name)s * obj, const char *name, Error **errp);
-''',
- visitor=type_visitor(name))
-
def generate_command_decl(name, args, ret_type):
arglist=""
for argname, argtype, optional, structured in parse_args(args):
@@ -76,19 +69,6 @@ def gen_marshal_output_call(name, ret_type):
return ""
return "qmp_marshal_output_%s(retval, ret, errp);" % c_fun(name)
-def gen_visitor_output_containers_decl(ret_type):
- ret = ""
- push_indent()
- if ret_type:
- ret += mcgen('''
-QmpOutputVisitor *mo;
-QapiDeallocVisitor *md;
-Visitor *v;
-''')
- pop_indent()
-
- return ret
-
def gen_visitor_input_containers_decl(args):
ret = ""
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 30/32] qapi: Clean up null checking in generated visitors
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (28 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 29/32] qapi: Drop unused code in qapi-commands.py Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 31/32] qapi: Clean up superfluous null check in qapi_dealloc_type_str() Luiz Capitulino
` (2 subsequent siblings)
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Visitors get passed a pointer to the visited object. The generated
visitors try to cope with this pointer being null in some places, for
instance like this:
visit_start_optional(m, obj ? &(*obj)->has_name : NULL, "name", &err);
visit_start_optional() passes its second argument to Visitor method
start_optional. Three out of three methods dereference it
unconditionally.
I fail to see how this pointer could legitimately be null.
All this useless null checking is highly redundant, which Coverity
duly reports. About 200 times.
Remove the useless null checks.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
scripts/qapi-visit.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 97e9b11..c6de9ae 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -47,9 +47,9 @@ static void visit_type_%(full_name)s_fields(Visitor *m, %(name)s ** obj, Error *
if base:
ret += mcgen('''
-visit_start_implicit_struct(m, obj ? (void**) &(*obj)->%(c_name)s : NULL, sizeof(%(type)s), &err);
+visit_start_implicit_struct(m, (void**) &(*obj)->%(c_name)s, sizeof(%(type)s), &err);
if (!err) {
- visit_type_%(type)s_fields(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, &err);
+ visit_type_%(type)s_fields(m, &(*obj)->%(c_prefix)s%(c_name)s, &err);
error_propagate(errp, err);
err = NULL;
visit_end_implicit_struct(m, &err);
@@ -61,8 +61,8 @@ if (!err) {
for argname, argentry, optional, structured in parse_args(members):
if optional:
ret += mcgen('''
-visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err);
-if (obj && (*obj)->%(prefix)shas_%(c_name)s) {
+visit_start_optional(m, &(*obj)->%(c_prefix)shas_%(c_name)s, "%(name)s", &err);
+if ((*obj)->%(prefix)shas_%(c_name)s) {
''',
c_prefix=c_var(field_prefix), prefix=field_prefix,
c_name=c_var(argname), name=argname)
@@ -72,7 +72,7 @@ if (obj && (*obj)->%(prefix)shas_%(c_name)s) {
ret += generate_visit_struct_body(full_name, argname, argentry)
else:
ret += mcgen('''
-visit_type_%(type)s(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", &err);
+visit_type_%(type)s(m, &(*obj)->%(c_prefix)s%(c_name)s, "%(name)s", &err);
''',
c_prefix=c_var(field_prefix), prefix=field_prefix,
type=type_name(argentry), c_name=c_var(argname),
@@ -121,7 +121,7 @@ visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
ret += mcgen('''
if (!err) {
- if (!obj || *obj) {
+ if (*obj) {
visit_type_%(name)s_fields(m, obj, &err);
error_propagate(errp, err);
err = NULL;
@@ -273,7 +273,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
if (!error_is_set(errp)) {
visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
if (!err) {
- if (obj && *obj) {
+ if (*obj) {
''',
name=name)
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 31/32] qapi: Clean up superfluous null check in qapi_dealloc_type_str()
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (29 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 30/32] qapi: Clean up null checking in generated visitors Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-03 17:12 ` [Qemu-devel] [PULL 32/32] qapi: Add missing null check to opts_start_struct() Luiz Capitulino
2014-03-04 18:13 ` [Qemu-devel] [PULL 00/32] QMP queue Peter Maydell
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Argument can't be null. No other Visitor method type_str() checks for
null.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
qapi/qapi-dealloc-visitor.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index dc53545..d0ea118 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -131,9 +131,7 @@ static void qapi_dealloc_end_list(Visitor *v, Error **errp)
static void qapi_dealloc_type_str(Visitor *v, char **obj, const char *name,
Error **errp)
{
- if (obj) {
- g_free(*obj);
- }
+ g_free(*obj);
}
static void qapi_dealloc_type_int(Visitor *v, int64_t *obj, const char *name,
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [Qemu-devel] [PULL 32/32] qapi: Add missing null check to opts_start_struct()
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (30 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 31/32] qapi: Clean up superfluous null check in qapi_dealloc_type_str() Luiz Capitulino
@ 2014-03-03 17:12 ` Luiz Capitulino
2014-03-04 18:13 ` [Qemu-devel] [PULL 00/32] QMP queue Peter Maydell
32 siblings, 0 replies; 35+ messages in thread
From: Luiz Capitulino @ 2014-03-03 17:12 UTC (permalink / raw)
To: peter.maydell; +Cc: qemu-devel, anthony
From: Markus Armbruster <armbru@redhat.com>
Argument is null when visiting an unboxed struct. I can't see such a
visit in the current code. Fix it anyway.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
qapi/opts-visitor.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 96ed858..5d830a2 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -124,7 +124,9 @@ opts_start_struct(Visitor *v, void **obj, const char *kind,
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
const QemuOpt *opt;
- *obj = g_malloc0(size > 0 ? size : 1);
+ if (obj) {
+ *obj = g_malloc0(size > 0 ? size : 1);
+ }
if (ov->depth++ > 0) {
return;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [Qemu-devel] [PULL 00/32] QMP queue
2014-03-03 17:11 [Qemu-devel] [PULL 00/32] QMP queue Luiz Capitulino
` (31 preceding siblings ...)
2014-03-03 17:12 ` [Qemu-devel] [PULL 32/32] qapi: Add missing null check to opts_start_struct() Luiz Capitulino
@ 2014-03-04 18:13 ` Peter Maydell
32 siblings, 0 replies; 35+ messages in thread
From: Peter Maydell @ 2014-03-04 18:13 UTC (permalink / raw)
To: Luiz Capitulino; +Cc: QEMU Developers, Anthony Liguori
On 3 March 2014 17:11, Luiz Capitulino <lcapitulino@redhat.com> wrote:
> The following changes since commit d844a7b6569fb2b5252773444b18841426e5b906:
>
> modules: Fix building with --enable-modules (2014-02-28 12:30:13 +0000)
>
> are available in the git repository at:
>
> git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
>
> for you to fetch changes up to b774539743c52ef605c6e2cbac19376c2757cb86:
>
> qapi: Add missing null check to opts_start_struct() (2014-03-03 11:17:45 -0500)
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 35+ messages in thread