Re: [Qemu-devel] [PATCH] json-lexer: fix escaped backslash in single-quoted string
On Fri, Jun 13, 2014 at 10:13:02AM +0200, Paolo Bonzini wrote: This made the lexer wait for a closing *double* quote. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Amos Kong ak...@redhat.com --- qobject/json-lexer.c | 4 ++-- tests/check-qjson.c | 7 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c index 440df60..b19623e 100644 --- a/qobject/json-lexer.c +++ b/qobject/json-lexer.c @@ -138,8 +138,8 @@ static const uint8_t json_lexer[][256] = { ['n'] = IN_SQ_STRING, ['r'] = IN_SQ_STRING, ['t'] = IN_SQ_STRING, -['/'] = IN_DQ_STRING, -['\\'] = IN_DQ_STRING, +['/'] = IN_SQ_STRING, +['\\'] = IN_SQ_STRING, ['\''] = IN_SQ_STRING, ['\'] = IN_SQ_STRING, ['u'] = IN_SQ_UCODE0, diff --git a/tests/check-qjson.c b/tests/check-qjson.c index 4e74548..95497a0 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -45,6 +45,13 @@ static void escaped_string(void) { \single byte utf-8 \\u0020\, single byte utf-8 , .skip = 1 }, { \double byte utf-8 \\u00A2\, double byte utf-8 \xc2\xa2 }, { \triple byte utf-8 \\u20AC\, triple byte utf-8 \xe2\x82\xac }, +{ '\\b', \b, .skip = 1 }, +{ '\\f', \f, .skip = 1 }, +{ '\\n', \n, .skip = 1 }, +{ '\\r', \r, .skip = 1 }, +{ '\\t', \t, .skip = 1 }, +{ '\\/', /, .skip = 1 }, +{ '', \\, .skip = 1 }, {} }; -- 1.8.3.1 -- Amos.
Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
Il 18/06/2014 06:00, Eric Blake ha scritto: -typedef void (*QMPEventFuncEmit)(int event_kind, QDict *dict, Error **errp); +typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp); It looks like you have some churn on this definition; patch 4/29 in your qapi-event branch did: -enum QAPIEvent; -typedef void (*QMPEventFuncEmit)(enum QAPIEvent event, QDict *dict, Error **errp); +typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp); Can you hoist the use of 'unsigned' directly into 2/29 to minimize the churn? Yes, will fix in a couple of hours. Paolo
Re: [Qemu-devel] [PATCH V6 03/29] qapi script: add event support
Il 18/06/2014 05:33, Eric Blake ha scritto: +# This work is licensed under the terms of the GNU GPL, version 2. +# See the COPYING file in the top-level directory. Any reason this can't be GPLv2+ instead of GPLv2-only? I suppose because it copies parts of other qapi-* scripts. :( Paolo
Re: [Qemu-devel] [PATCH v4 2/4] qtest: introduce qmp_exec_hmp_cmd()
On Tue, Jun 17, 2014 at 07:37:06PM +0200, Paolo Bonzini wrote: Il 06/06/2014 16:33, Amos Kong ha scritto: +va_end(ap); + +escaped_cmd = g_strescape(cmd, NULL); +response = qmp({\execute\: \human-monitor-command\, +\arguments\: { + \command-line\: \%s\ + }}, escaped_cmd); +g_free(escaped_cmd); Instead of adding g_strescape everywhere, we should use json-parser's own interpolation support. See this patch: http://article.gmane.org/gmane.comp.emulators.qemu/279836 which also fixes a leak as a bonus. Also, you can use ' instead of if you fix another long-standing bug: http://article.gmane.org/gmane.comp.emulators.qemu/279835 I will use ' instead of , and escape string in QMP command as http://article.gmane.org/gmane.comp.emulators.qemu/279836 Thanks. Paolo -- Amos.
Re: [Qemu-devel] [PATCH v4 3/4] virtio-blk-test.c: add hotplug subtest
On Tue, Jun 17, 2014 at 03:25:34PM +0200, Andreas Färber wrote: Am 06.06.2014 16:33, schrieb Amos Kong: This patch adds a new subtest, it hotplugs 29 * 8 = 232 virtio-blk devices to guest, and try to hot-unplug them. Note: the hot-unplug can't work without cooperation of guest OS. Signed-off-by: Amos Kong ak...@redhat.com Reviewed-by: Stefan Hajnoczi stefa...@redhat.com --- tests/virtio-blk-test.c | 31 +++ 1 file changed, 31 insertions(+) diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 0fdec01..7358203 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -7,11 +7,41 @@ * See the COPYING file in the top-level directory. */ +#include stdio.h #include glib.h #include string.h #include libqtest.h #include qemu/osdep.h +static void test_blk_hotplug(void) +{ +int i, j; + +/* start with no network/block device, slots 3~0x1f are free */ 3-0x1f or 3 to 0x1f? +qtest_start(-net none); + +for (i = 3; i = 0x1f; i++) { +for (j = 7; j = 0; j--) { +qmp_exec_hmp_cmd(OK\r\n, + drive_add 0 if=none,file=/dev/null,id=drv-%x.%x, + i, j); +qmp_exec_hmp_cmd(, + device_add virtio-blk-pci,id=dev-%x.%x,drive=drv-%x.%x, + addr=0x%x.%x,multifunction=on, i, j, i, j, i, j); Hi Andreas, Why are you using HMP-via-QMP here and not QMP directly? I referenced existed test code. +} +} + +/* hot-unplug doesn't work without cooperation of guest OS */ +for (i = 3; i = 0x1f; i++) { +for (j = 7; j = 0; j--) { While the function is still small, using a define or static const would be a small improvement. :) Could be a follow-up of course. Sorry I don't get it. test_blk_hotplug() was already decorated by 'static' and we can't decorate a function that returns nothing. tests/virtio-blk-test.c:16:19: error: function definition has qualified void return type [-Werror] static const void test_blk_hotplug(void) Test looks good, thanks for your effort. Regards, Andreas Thanks, Amos +qmp_exec_hmp_cmd(, drive_del drv-%x.%x, i, j); +qmp_exec_hmp_cmd(, device_del dev-%x.%x, i, j); +} +} + +qtest_end(); +} + /* Tests only initialization */ static void virtblk_init(void) { @@ -26,6 +56,7 @@ int main(int argc, char **argv) g_test_init(argc, argv, NULL); qtest_add_func(/virtio/blk/pci/init, virtblk_init); +qtest_add_func(/virtio/blk/pci/hotplug, test_blk_hotplug); ret = g_test_run(); -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg -- Amos.
[Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1
This includes: - Max's dependency fixes for QAPI scripts - Wenchao's QAPI event series - my thread-safety fixes, rebased onto QAPI events Paolo Max Reitz (1): qapi: Add includes from qapi/ as dependencies Paolo Bonzini (6): qemu-char: introduce qemu_chr_alloc qemu-char: do not call chr_write directly qemu-char: move pty_chr_update_read_handler around qemu-char: make writes thread-safe monitor: protect outbuf and mux_out with mutex monitor: protect event emission Wenchao Xia (29): os-posix: include sys/time.h qapi: add event helper functions qapi script: add event support test: add test cases for qapi event qapi: adjust existing defines monitor: add an implemention of qapi event emit method qapi: add new schema file qapi-event.json qapi event: convert SHUTDOWN qapi event: convert POWERDOWN qapi event: convert RESET qapi event: convert STOP qapi event: convert RESUME qapi event: convert SUSPEND qapi event: convert SUSPEND_DISK qapi event: convert WAKEUP qapi event: convert RTC_CHANGE qapi event: convert WATCHDOG qapi event: convert DEVICE_DELETED qapi event: convert DEVICE_TRAY_MOVED qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR qapi event: convert BLOCK_IMAGE_CORRUPTED qapi event: convert other BLOCK_JOB events qapi event: convert NIC_RX_FILTER_CHANGED qapi event: convert VNC events qapi event: convert SPICE events qapi event: convert BALLOON_CHANGE qapi event: convert GUEST_PANICKED qapi event: convert QUORUM events qapi event: clean up Makefile | 21 +- Makefile.objs| 2 +- backends/baum.c | 2 +- backends/msmouse.c | 2 +- balloon.c| 13 - block.c | 68 +--- block/backup.c | 2 +- block/mirror.c | 9 +- block/qcow2-refcount.c | 14 +- block/quorum.c | 25 +- block/stream.c | 4 +- blockdev.c | 12 +- blockjob.c | 53 +-- cpus.c | 5 +- docs/qapi-code-gen.txt | 18 + docs/qmp/qmp-events.txt | 541 --- hmp.c| 5 +- hw/acpi/core.c | 4 +- hw/block/virtio-blk.c| 6 +- hw/core/qdev.c | 12 +- hw/ide/core.c| 6 +- hw/misc/pvpanic.c| 13 +- hw/net/virtio-net.c | 13 +- hw/ppc/spapr_rtas.c | 3 +- hw/scsi/scsi-disk.c | 6 +- hw/timer/mc146818rtc.c | 3 +- hw/virtio/virtio-balloon.c | 6 +- hw/watchdog/watchdog.c | 23 +- include/block/block.h| 4 - include/block/block_int.h| 3 - include/block/blockjob.h | 17 +- include/monitor/monitor.h| 40 --- include/qapi/qmp-event.h | 27 ++ include/qemu/sockets.h | 3 +- include/sysemu/balloon.h | 2 - include/sysemu/char.h| 20 +- include/sysemu/os-posix.h| 2 + include/sysemu/sysemu.h | 2 - monitor.c| 226 ++--- qapi-event.json | 306 + qapi-schema.json | 162 +++-- qapi/Makefile.objs | 1 + qapi/block-core.json | 150 + qapi/block.json | 14 + qapi/qmp-event.c | 74 + qemu-char.c | 134 +--- scripts/qapi-event.py| 369 + scripts/qapi.py | 12 + spice-qemu-char.c| 2 +- stubs/Makefile.objs | 1 - stubs/mon-protocol-event.c | 6 - target-s390x/kvm.c | 9 +- tests/Makefile | 18 +- tests/qapi-schema/event-nest-struct.err | 1 + tests/qapi-schema/event-nest-struct.exit | 1 + tests/qapi-schema/event-nest-struct.json | 2 + tests/qapi-schema/event-nest-struct.out | 0 tests/qapi-schema/qapi-schema-test.json | 12 + tests/qapi-schema/qapi-schema-test.out | 10 +- tests/test-qmp-event.c | 265 +++ ui/console.c | 2 +- ui/spice-core.c | 77 ++--- ui/vnc.c | 120 +++ ui/vnc.h | 4 +- util/qemu-sockets.c | 10 +- vl.c
[Qemu-devel] [PATCH 2.1 02/36] qapi: Add includes from qapi/ as dependencies
From: Max Reitz mre...@redhat.com qapi-schema.json has been split into three smaller JSON files in qapi/. Add them as dependencies for the code generation in the Makefile, so changes to them will result in a rebuilt of all QAPI-dependent code. Signed-off-by: Max Reitz mre...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- Makefile | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 3c8f19c..800fbf3 100644 --- a/Makefile +++ b/Makefile @@ -246,18 +246,21 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) $(gen-out-type) -o qga/qapi-generated -p qga- -i $, \ GEN $@) +qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \ + $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json + qapi-types.c qapi-types.h :\ -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) +$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \ $(gen-out-type) -o . -b -i $, \ GEN $@) qapi-visit.c qapi-visit.h :\ -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py) +$(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \ $(gen-out-type) -o . -b -i $, \ GEN $@) qmp-commands.h qmp-marshal.c :\ -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) +$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \ $(gen-out-type) -o . -m -i $, \ GEN $@) -- 1.9.3
[Qemu-devel] [PATCH 2.1 01/36] os-posix: include sys/time.h
From: Wenchao Xia wenchaoq...@gmail.com Since gettimeofday() is used in this header file as a macro define, include the function's define header file, to avoid compile warning when other file include os-posix.h. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/sysemu/os-posix.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h index 25d0b2a..f131521 100644 --- a/include/sysemu/os-posix.h +++ b/include/sysemu/os-posix.h @@ -26,6 +26,8 @@ #ifndef QEMU_OS_POSIX_H #define QEMU_OS_POSIX_H +#include sys/time.h + void os_set_line_buffering(void); void os_set_proc_name(const char *s); void os_setup_signal_handling(void); -- 1.9.3
[Qemu-devel] [PATCH 2.1 09/36] qapi event: convert SHUTDOWN
From: Wenchao Xia wenchaoq...@gmail.com This patch also eliminates build time warning caused by QAPI_EVENT_MAX = 0. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 15 --- qapi-event.json | 12 vl.c| 3 ++- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 145402e..ff2f30d 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -304,21 +304,6 @@ Example: data: { offset: 78 }, timestamp: { seconds: 1267020223, microseconds: 435656 } } -SHUTDOWN - - -Emitted when the Virtual Machine is powered down. - -Data: None. - -Example: - -{ event: SHUTDOWN, -timestamp: { seconds: 1267040730, microseconds: 682951 } } - -Note: If the command-line option -no-shutdown has been specified, a STOP -event will eventually follow the SHUTDOWN event. - SPICE_CONNECTED, SPICE_DISCONNECTED --- diff --git a/qapi-event.json b/qapi-event.json index e69de29..7a6e6bf 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -0,0 +1,12 @@ +## +# @SHUTDOWN +# +# Emitted when the virtual machine has shutdown, possibly indicating that QEMU +# is about about to exit. +# +# Note: If the command-line option -no-shutdown has been specified, qemu will +# not exit, and a STOP event will eventually follow the SHUTDOWN event +# +# Since: 0.12.0 +## +{ 'event': 'SHUTDOWN' } diff --git a/vl.c b/vl.c index be69c7f..4dc21d3 100644 --- a/vl.c +++ b/vl.c @@ -117,6 +117,7 @@ int main(int argc, char **argv) #include ui/qemu-spice.h #include qapi/string-input-visitor.h #include qom/object_interfaces.h +#include qapi-event.h #define DEFAULT_RAM_SIZE 128 @@ -2028,7 +2029,7 @@ static bool main_loop_should_exit(void) } if (qemu_shutdown_requested()) { qemu_kill_report(); -monitor_protocol_event(QEVENT_SHUTDOWN, NULL); +qapi_event_send_shutdown(error_abort); if (no_shutdown) { vm_stop(RUN_STATE_SHUTDOWN); } else { -- 1.9.3
[Qemu-devel] [PATCH 2.1 03/36] qapi: add event helper functions
From: Wenchao Xia wenchaoq...@gmail.com This file holds some functions that do not need to be generated. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/qapi/qmp-event.h | 27 ++ qapi/Makefile.objs | 1 + qapi/qmp-event.c | 74 3 files changed, 102 insertions(+) create mode 100644 include/qapi/qmp-event.h create mode 100644 qapi/qmp-event.c diff --git a/include/qapi/qmp-event.h b/include/qapi/qmp-event.h new file mode 100644 index 000..8a8ffb5 --- /dev/null +++ b/include/qapi/qmp-event.h @@ -0,0 +1,27 @@ +/* + * QMP Event related + * + * Copyright (c) 2014 Wenchao Xia + * + * Authors: + * Wenchao Xia wenchaoq...@gmail.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#ifndef QMP_EVENT_H +#define QMP_EVENT_H + +#include qapi/error.h +#include qapi/qmp/qdict.h + +typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp); + +void qmp_event_set_func_emit(QMPEventFuncEmit emit); + +QMPEventFuncEmit qmp_event_get_func_emit(void); + +QDict *qmp_event_build_dict(const char *event_name); +#endif diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index 1f9c973..d14b769 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -3,3 +3,4 @@ util-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o util-obj-y += string-input-visitor.o string-output-visitor.o util-obj-y += opts-visitor.o +util-obj-y += qmp-event.o diff --git a/qapi/qmp-event.c b/qapi/qmp-event.c new file mode 100644 index 000..0d1ce0b --- /dev/null +++ b/qapi/qmp-event.c @@ -0,0 +1,74 @@ +/* + * QMP Event related + * + * Copyright (c) 2014 Wenchao Xia + * + * Authors: + * Wenchao Xia wenchaoq...@gmail.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include inttypes.h + +#include qemu-common.h +#include qapi/qmp-event.h +#include qapi/qmp/qstring.h +#include qapi/qmp/qjson.h + +#ifdef _WIN32 +#include sysemu/os-win32.h +#endif + +#ifdef CONFIG_POSIX +#include sysemu/os-posix.h +#endif + +static QMPEventFuncEmit qmp_emit; + +void qmp_event_set_func_emit(QMPEventFuncEmit emit) +{ +qmp_emit = emit; +} + +QMPEventFuncEmit qmp_event_get_func_emit(void) +{ +return qmp_emit; +} + +static void timestamp_put(QDict *qdict) +{ +int err; +QObject *obj; +qemu_timeval tv; +int64_t sec, usec; + +err = qemu_gettimeofday(tv); +if (err 0) { +/* Put -1 to indicate failure of getting host time */ +sec = -1; +usec = -1; +} else { +sec = tv.tv_sec; +usec = tv.tv_usec; +} + +obj = qobject_from_jsonf({ 'seconds': % PRId64 , + 'microseconds': % PRId64 }, + sec, usec); +qdict_put_obj(qdict, timestamp, obj); +} + +/* + * Build a QDict, then fill event name and time stamp, caller should free the + * QDict after usage. + */ +QDict *qmp_event_build_dict(const char *event_name) +{ +QDict *dict = qdict_new(); +qdict_put(dict, event, qstring_from_str(event_name)); +timestamp_put(dict); +return dict; +} -- 1.9.3
[Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support
From: Wenchao Xia wenchaoq...@gmail.com qapi-event.py will parse the schema and generate qapi-event.c, then the API in qapi-event.c can be used to handle events in qemu code. All API have prefix qapi_event. The script mainly includes two parts: generate API for each event define, generate an enum type for all defined events. Since in some cases the real emit behavior may change, for example, qemu-img would not send a event, a callback layer is used to control the behavior. As a result, the stubs at compile time can be saved, the binding of block layer code and monitor code will become looser. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- Makefile | 11 +- Makefile.objs| 2 +- docs/qapi-code-gen.txt | 18 ++ scripts/qapi-event.py| 369 +++ scripts/qapi.py | 12 + tests/Makefile | 2 +- tests/qapi-schema/event-nest-struct.err | 1 + tests/qapi-schema/event-nest-struct.exit | 1 + tests/qapi-schema/event-nest-struct.json | 2 + tests/qapi-schema/event-nest-struct.out | 0 10 files changed, 413 insertions(+), 5 deletions(-) create mode 100644 scripts/qapi-event.py create mode 100644 tests/qapi-schema/event-nest-struct.err create mode 100644 tests/qapi-schema/event-nest-struct.exit create mode 100644 tests/qapi-schema/event-nest-struct.json create mode 100644 tests/qapi-schema/event-nest-struct.out diff --git a/Makefile b/Makefile index 800fbf3..f473cf5 100644 --- a/Makefile +++ b/Makefile @@ -45,8 +45,8 @@ endif endif GENERATED_HEADERS = config-host.h qemu-options.def -GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h -GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c +GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h +GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c GENERATED_HEADERS += trace/generated-events.h GENERATED_SOURCES += trace/generated-events.c @@ -202,7 +202,7 @@ Makefile: $(version-obj-y) $(version-lobj-y) # Build libraries libqemustub.a: $(stub-obj-y) -libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o +libqemuutil.a: $(util-obj-y) qapi-types.o qapi-visit.o qapi-event.o block-modules = $(foreach o,$(block-obj-m),$(basename $(subst /,-,$o)),) NULL util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)' @@ -259,6 +259,11 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \ $(gen-out-type) -o . -b -i $, \ GEN $@) +qapi-event.c qapi-event.h :\ +$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py) + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \ + $(gen-out-type) -o . -b -i $, \ + GEN $@) qmp-commands.h qmp-marshal.c :\ $(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \ diff --git a/Makefile.objs b/Makefile.objs index b897e1d..1f76cea 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -12,7 +12,7 @@ block-obj-y += main-loop.o iohandler.o qemu-timer.o block-obj-$(CONFIG_POSIX) += aio-posix.o block-obj-$(CONFIG_WIN32) += aio-win32.o block-obj-y += block/ -block-obj-y += qapi-types.o qapi-visit.o +block-obj-y += qapi-types.o qapi-visit.o qapi-event.o block-obj-y += qemu-io-cmds.o block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index dea0d50..c3d315f 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -215,6 +215,24 @@ An example command is: 'data': { 'arg1': 'str', '*arg2': 'str' }, 'returns': 'str' } +=== Events === + +Events are defined with the keyword 'event'. When 'data' is also specified, +additional info will be carried on. Finally there will be C API generated +in qapi-event.h; when called by QEMU code, a message with timestamp will +be emitted on the wire. If timestamp is -1, it means failure to retrieve host +time. + +An example event is: + +{ 'event': 'EVENT_C', + 'data': { '*a': 'int', 'b': 'str' } } + +Resulting in this JSON object: + +{ event: EVENT_C, + data: { b: test string }, + timestamp: { seconds: 1267020223, microseconds: 435656 } } == Code generation == diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py new file mode 100644 index 000..3a1cd61 --- /dev/null +++ b/scripts/qapi-event.py @@ -0,0 +1,369 @@ +# +# QAPI event generator +# +# Copyright (c) 2014 Wenchao Xia +# +# Authors: +# Wenchao Xia wenchaoq...@gmail.com +# +# 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 * +import sys
[Qemu-devel] [PATCH 2.1 13/36] qapi event: convert RESUME
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 12 qapi-event.json | 9 + vl.c| 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index c241a07..cda67d4 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -264,18 +264,6 @@ Example: data: { node-name: 1.raw, sector-num: 345435, sector-count: 5 }, timestamp: { seconds: 1344522075, microseconds: 745528 } } -RESUME --- - -Emitted when the Virtual Machine resumes execution. - -Data: None. - -Example: - -{ event: RESUME, -timestamp: { seconds: 1271770767, microseconds: 582542 } } - RTC_CHANGE -- diff --git a/qapi-event.json b/qapi-event.json index bac7fdc..ac903ef 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -38,3 +38,12 @@ # Since: 0.12.0 ## { 'event': 'STOP' } + +## +# @RESUME +# +# Emitted when the virtual machine resumes execution +# +# Since: 0.12.0 +## +{ 'event': 'RESUME' } diff --git a/vl.c b/vl.c index 097fa65..3d56d40 100644 --- a/vl.c +++ b/vl.c @@ -1755,7 +1755,7 @@ void vm_start(void) runstate_set(RUN_STATE_RUNNING); vm_state_notify(1, RUN_STATE_RUNNING); resume_all_vcpus(); -monitor_protocol_event(QEVENT_RESUME, NULL); +qapi_event_send_resume(error_abort); } } -- 1.9.3
[Qemu-devel] [PATCH 2.1 10/36] qapi event: convert POWERDOWN
From: Wenchao Xia wenchaoq...@gmail.com There is no existing comments for POWERDOWN in doc/qmp/qmp-events.txt, so no change on it like other conversion patch. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- qapi-event.json | 10 ++ vl.c| 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/qapi-event.json b/qapi-event.json index 7a6e6bf..ca08289 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -10,3 +10,13 @@ # Since: 0.12.0 ## { 'event': 'SHUTDOWN' } + +## +# @POWERDOWN +# +# Emitted when the virtual machine is powered down through the power control +# system, such as via ACPI. +# +# Since: 0.12.0 +## +{ 'event': 'POWERDOWN' } diff --git a/vl.c b/vl.c index 4dc21d3..9ade3cb 100644 --- a/vl.c +++ b/vl.c @@ -1991,7 +1991,7 @@ void qemu_system_shutdown_request(void) static void qemu_system_powerdown(void) { -monitor_protocol_event(QEVENT_POWERDOWN, NULL); +qapi_event_send_powerdown(error_abort); notifier_list_notify(powerdown_notifiers, NULL); } -- 1.9.3
[Qemu-devel] [PATCH 2.1 15/36] qapi event: convert SUSPEND_DISK
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 14 -- hw/acpi/core.c | 4 ++-- qapi-event.json | 12 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index d86a077..c2f23ef 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -342,20 +342,6 @@ Example: channel-id: 0, tls: true} }} -SUSPEND_DISK - - -Emitted when the guest makes a request to enter S4 state. - -Data: None. - -Example: - -{ event: SUSPEND_DISK, - timestamp: { seconds: 1344456160, microseconds: 309119 } } - -Note: QEMU shuts down when entering S4 state. - VNC_CONNECTED - diff --git a/hw/acpi/core.c b/hw/acpi/core.c index 79414b4..a7368fb 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -22,11 +22,11 @@ #include hw/hw.h #include hw/i386/pc.h #include hw/acpi/acpi.h -#include monitor/monitor.h #include qemu/config-file.h #include qapi/opts-visitor.h #include qapi/dealloc-visitor.h #include qapi-visit.h +#include qapi-event.h struct acpi_table_header { uint16_t _length; /* our length, not actual part of the hdr */ @@ -550,7 +550,7 @@ static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) break; default: if (sus_typ == ar-pm1.cnt.s4_val) { /* S4 request */ -monitor_protocol_event(QEVENT_SUSPEND_DISK, NULL); +qapi_event_send_suspend_disk(error_abort); qemu_system_shutdown_request(); } break; diff --git a/qapi-event.json b/qapi-event.json index d45b341..469353c 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -57,3 +57,15 @@ # Since: 1.1 ## { 'event': 'SUSPEND' } + +## +# @SUSPEND_DISK +# +# Emitted when guest enters a hardware suspension state with data saved on +# disk, for example, S4 state, which is sometimes called hibernate state +# +# Note: QEMU shuts down (similar to event @SHUTDOWN) when entering this state +# +# Since: 1.2 +## +{ 'event': 'SUSPEND_DISK' } -- 1.9.3
[Qemu-devel] [PATCH 2.1 11/36] qapi event: convert RESET
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 12 qapi-event.json | 9 + vl.c| 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index ff2f30d..20e3151 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -264,18 +264,6 @@ Example: data: { node-name: 1.raw, sector-num: 345435, sector-count: 5 }, timestamp: { seconds: 1344522075, microseconds: 745528 } } -RESET -- - -Emitted when the Virtual Machine is reseted. - -Data: None. - -Example: - -{ event: RESET, -timestamp: { seconds: 1267041653, microseconds: 9518 } } - RESUME -- diff --git a/qapi-event.json b/qapi-event.json index ca08289..f38669d 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -20,3 +20,12 @@ # Since: 0.12.0 ## { 'event': 'POWERDOWN' } + +## +# @RESET +# +# Emitted when the virtual machine is reset +# +# Since: 0.12.0 +## +{ 'event': 'RESET' } diff --git a/vl.c b/vl.c index 9ade3cb..097fa65 100644 --- a/vl.c +++ b/vl.c @@ -1907,7 +1907,7 @@ void qemu_system_reset(bool report) qemu_devices_reset(); } if (report) { -monitor_protocol_event(QEVENT_RESET, NULL); +qapi_event_send_reset(error_abort); } cpu_synchronize_all_post_reset(); } -- 1.9.3
[Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events
From: Wenchao Xia wenchaoq...@gmail.com Since BLOCK_JOB_COMPLETED, BLOCK_JOB_CANCELLED, BLOCK_JOB_READY are related, convert them in one patch. The block_job_event_* functions are used to keep encapsulation of BlockJob structure. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- block/mirror.c | 2 +- blockdev.c | 12 blockjob.c | 36 +--- docs/qmp/qmp-events.txt | 71 include/block/blockjob.h | 17 +--- qapi/block-core.json | 71 6 files changed, 110 insertions(+), 99 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index df58aea..301a04d 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -427,7 +427,7 @@ static void coroutine_fn mirror_run(void *opaque) */ s-common.offset = end * BDRV_SECTOR_SIZE; if (!s-synced) { -block_job_ready(s-common); +block_job_event_ready(s-common); s-synced = true; } diff --git a/blockdev.c b/blockdev.c index 9b0f8ac..03ab153 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1847,23 +1847,21 @@ void qmp_block_resize(bool has_device, const char *device, static void block_job_cb(void *opaque, int ret) { BlockDriverState *bs = opaque; -QObject *obj; +const char *msg = NULL; trace_block_job_cb(bs, bs-job, ret); assert(bs-job); -obj = qobject_from_block_job(bs-job); + if (ret 0) { -QDict *dict = qobject_to_qdict(obj); -qdict_put(dict, error, qstring_from_str(strerror(-ret))); +msg = strerror(-ret); } if (block_job_is_cancelled(bs-job)) { -monitor_protocol_event(QEVENT_BLOCK_JOB_CANCELLED, obj); +block_job_event_cancelled(bs-job); } else { -monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, obj); +block_job_event_completed(bs-job, msg); } -qobject_decref(obj); bdrv_put_ref_bh_schedule(bs); } diff --git a/blockjob.c b/blockjob.c index ee2a6fb..4da86cd 100644 --- a/blockjob.c +++ b/blockjob.c @@ -26,7 +26,6 @@ #include config-host.h #include qemu-common.h #include trace.h -#include monitor/monitor.h #include block/block.h #include block/blockjob.h #include block/block_int.h @@ -233,26 +232,31 @@ static void block_job_iostatus_set_err(BlockJob *job, int error) } } +void block_job_event_cancelled(BlockJob *job) +{ +qapi_event_send_block_job_cancelled(job-driver-job_type, +bdrv_get_device_name(job-bs), +job-len, +job-offset, +job-speed, +error_abort); +} -QObject *qobject_from_block_job(BlockJob *job) +void block_job_event_completed(BlockJob *job, const char *msg) { -return qobject_from_jsonf({ 'type': %s, - 'device': %s, - 'len': % PRId64 , - 'offset': % PRId64 , - 'speed': % PRId64 }, - BlockJobType_lookup[job-driver-job_type], - bdrv_get_device_name(job-bs), - job-len, - job-offset, - job-speed); +qapi_event_send_block_job_completed(job-driver-job_type, +bdrv_get_device_name(job-bs), +job-len, +job-offset, +job-speed, +!!msg, +msg, +error_abort); } -void block_job_ready(BlockJob *job) +void block_job_event_ready(BlockJob *job) { -QObject *data = qobject_from_block_job(job); -monitor_protocol_event(QEVENT_BLOCK_JOB_READY, data); -qobject_decref(data); +qapi_event_send_block_job_ready(bdrv_get_device_name(job-bs), error_abort); } BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs, diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index eec3955..c57d5df 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -18,77 +18,6 @@ Example: data: { actual: 944766976 }, timestamp: { seconds: 1267020223, microseconds: 435656 } } -BLOCK_JOB_CANCELLED - -Emitted when a block job has been cancelled. - -Data: - -- type: Job type (json-string; stream for image streaming - commit for block commit) -- device: Device name (json-string) -- len: Maximum progress value (json-int) -- offset: Current
[Qemu-devel] [PATCH 2.1 08/36] qapi: add new schema file qapi-event.json
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- Makefile | 3 ++- qapi-event.json | 0 qapi-schema.json | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 qapi-event.json diff --git a/Makefile b/Makefile index f473cf5..7d0c8ec 100644 --- a/Makefile +++ b/Makefile @@ -247,7 +247,8 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) GEN $@) qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \ - $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json + $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \ + $(SRC_PATH)/qapi-event.json qapi-types.c qapi-types.h :\ $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) diff --git a/qapi-event.json b/qapi-event.json new file mode 100644 index 000..e69de29 diff --git a/qapi-schema.json b/qapi-schema.json index 3d23042..26e0278 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3140,3 +3140,5 @@ 'btn' : 'InputBtnEvent', 'rel' : 'InputMoveEvent', 'abs' : 'InputMoveEvent' } } + +{ 'include': 'qapi-event.json' } -- 1.9.3
[Qemu-devel] [PATCH 2.1 17/36] qapi event: convert RTC_CHANGE
From: Wenchao Xia wenchaoq...@gmail.com This patch also eliminates build time warning caused by no caller of monitor_qapi_event_throttle(). Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 16 hw/ppc/spapr_rtas.c | 3 ++- hw/timer/mc146818rtc.c | 3 ++- include/sysemu/sysemu.h | 2 -- monitor.c | 4 +++- qapi-event.json | 13 + vl.c| 9 - 7 files changed, 20 insertions(+), 30 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 3d82db4..8cad3e7 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -264,22 +264,6 @@ Example: data: { node-name: 1.raw, sector-num: 345435, sector-count: 5 }, timestamp: { seconds: 1344522075, microseconds: 745528 } } -RTC_CHANGE --- - -Emitted when the guest changes the RTC time. - -Data: - -- offset: Offset between base RTC clock (as specified by -rtc base), and -new RTC clock value (json-number) - -Example: - -{ event: RTC_CHANGE, -data: { offset: 78 }, -timestamp: { seconds: 1267020223, microseconds: 435656 } } - SPICE_CONNECTED, SPICE_DISCONNECTED --- diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index ea4a2b2..8d08539 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -32,6 +32,7 @@ #include hw/ppc/spapr.h #include hw/ppc/spapr_vio.h +#include qapi-event.h #include libfdt.h @@ -93,7 +94,7 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr, tm.tm_sec = rtas_ld(args, 5); /* Just generate a monitor event for the change */ -rtc_change_mon_event(tm); +qapi_event_send_rtc_change(qemu_timedate_diff(tm), error_abort); spapr-rtc_offset = qemu_timedate_diff(tm); rtas_st(rets, 0, RTAS_OUT_SUCCESS); diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 1201f90..05002bf 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -26,6 +26,7 @@ #include sysemu/sysemu.h #include hw/timer/mc146818rtc.h #include qapi/visitor.h +#include qapi-event.h #ifdef TARGET_I386 #include hw/i386/apic.h @@ -530,7 +531,7 @@ static void rtc_set_time(RTCState *s) s-base_rtc = mktimegm(tm); s-last_update = qemu_clock_get_ns(rtc_clock); -rtc_change_mon_event(tm); +qapi_event_send_rtc_change(qemu_timedate_diff(tm), error_abort); } static void rtc_set_cmos(RTCState *s, const struct tm *tm) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index ba5c7f8..0046b27 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -189,8 +189,6 @@ void do_usb_add(Monitor *mon, const QDict *qdict); void do_usb_del(Monitor *mon, const QDict *qdict); void usb_info(Monitor *mon, const QDict *qdict); -void rtc_change_mon_event(struct tm *tm); - void add_boot_device_path(int32_t bootindex, DeviceState *dev, const char *suffix); char *get_boot_devices_list(size_t *size, bool ignore_suffixes); diff --git a/monitor.c b/monitor.c index 2e36fed..cfaed60 100644 --- a/monitor.c +++ b/monitor.c @@ -613,6 +613,9 @@ monitor_qapi_event_throttle(QAPIEvent event, int64_t rate) static void monitor_qapi_event_init(void) { +/* Limit guest-triggerable events to 1 per second */ +monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000); + qmp_event_set_func_emit(monitor_qapi_event_queue); } @@ -739,7 +742,6 @@ monitor_protocol_event_throttle(MonitorEvent event, static void monitor_protocol_event_init(void) { /* Limit RTC BALLOON events to 1 per second */ -monitor_protocol_event_throttle(QEVENT_RTC_CHANGE, 1000); monitor_protocol_event_throttle(QEVENT_BALLOON_CHANGE, 1000); monitor_protocol_event_throttle(QEVENT_WATCHDOG, 1000); /* limit the rate of quorum events to avoid hammering the management */ diff --git a/qapi-event.json b/qapi-event.json index 807a6f5..e6cfafa 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -78,3 +78,16 @@ # Since: 1.1 ## { 'event': 'WAKEUP' } + +## +# @RTC_CHANGE +# +# Emitted when the guest changes the RTC time. +# +# @offset: offset between base RTC clock (as specified by -rtc base), and +# new RTC clock value +# +# Since: 0.13.0 +## +{ 'event': 'RTC_CHANGE', + 'data': { 'offset': 'int' } } diff --git a/vl.c b/vl.c index bcda808..198c77a 100644 --- a/vl.c +++ b/vl.c @@ -727,15 +727,6 @@ int qemu_timedate_diff(struct tm *tm) return seconds - time(NULL); } -void rtc_change_mon_event(struct tm *tm) -{ -QObject *data; - -data = qobject_from_jsonf({ 'offset': %d }, qemu_timedate_diff(tm)); -monitor_protocol_event(QEVENT_RTC_CHANGE, data); -qobject_decref(data); -} - static void configure_rtc_date_offset(const char *startdate, int legacy) { time_t rtc_start_date; -- 1.9.3
[Qemu-devel] [PATCH 2.1 24/36] qapi event: convert NIC_RX_FILTER_CHANGED
From: Wenchao Xia wenchaoq...@gmail.com Param name is declared as optional, since in code it is an optional one. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 17 - hw/net/virtio-net.c | 13 +++-- qapi-event.json | 15 +++ 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index c57d5df..101f207 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -32,23 +32,6 @@ Example: { event: GUEST_PANICKED, data: { action: pause } } -NIC_RX_FILTER_CHANGED -- - -The event is emitted once until the query command is executed, -the first event will always be emitted. - -Data: - -- name: net client name (json-string) -- path: device path (json-string) - -{ event: NIC_RX_FILTER_CHANGED, - data: { name: vnet0, -path: /machine/peripheral/vnet0/virtio-backend }, - timestamp: { seconds: 1368697518, microseconds: 326866 } } -} - QUORUM_FAILURE -- diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 940a7cf..a423a7b 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -22,7 +22,7 @@ #include net/vhost_net.h #include hw/virtio/virtio-bus.h #include qapi/qmp/qjson.h -#include monitor/monitor.h +#include qapi-event.h #define VIRTIO_NET_VM_VERSION11 @@ -196,19 +196,12 @@ static void virtio_net_set_link_status(NetClientState *nc) static void rxfilter_notify(NetClientState *nc) { -QObject *event_data; VirtIONet *n = qemu_get_nic_opaque(nc); if (nc-rxfilter_notify_enabled) { gchar *path = object_get_canonical_path(OBJECT(n-qdev)); -if (n-netclient_name) { -event_data = qobject_from_jsonf({ 'name': %s, 'path': %s }, -n-netclient_name, path); -} else { -event_data = qobject_from_jsonf({ 'path': %s }, path); -} -monitor_protocol_event(QEVENT_NIC_RX_FILTER_CHANGED, event_data); -qobject_decref(event_data); +qapi_event_send_nic_rx_filter_changed(!!n-netclient_name, + n-netclient_name, path, error_abort); g_free(path); /* disable event notification to avoid events flooding */ diff --git a/qapi-event.json b/qapi-event.json index c880d77..b8dec47 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -122,3 +122,18 @@ ## { 'event': 'DEVICE_DELETED', 'data': { '*device': 'str', 'path': 'str' } } + +## +# @NIC_RX_FILTER_CHANGED +# +# Emitted once until the 'query-rx-filter' command is executed, the first event +# will always be emitted +# +# @name: #optional, net client name +# +# @path: device path +# +# Since: 1.6 +## +{ 'event': 'NIC_RX_FILTER_CHANGED', + 'data': { '*name': 'str', 'path': 'str' } } -- 1.9.3
[Qemu-devel] [PATCH 2.1 07/36] monitor: add an implemention of qapi event emit method
From: Wenchao Xia wenchaoq...@gmail.com The monitor is now hooked on the new event mechanism, so that later patches can convert event callers one by one. Most code are copied from old monitor_protocol_* functions with some modification. Note that two build time warnings will be raised after this patch. One is caused by no caller of monitor_qapi_event_throttle(), the other one is caused by QAPI_EVENT_MAX = 0. They will be fixed automatically after full event conversion later. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- monitor.c | 128 +- 1 file changed, 127 insertions(+), 1 deletion(-) diff --git a/monitor.c b/monitor.c index 2901187..2e36fed 100644 --- a/monitor.c +++ b/monitor.c @@ -71,6 +71,8 @@ #include hmp.h #include qemu/thread.h #include block/qapi.h +#include qapi/qmp-event.h +#include qapi-event.h /* for pic/irq_info */ #if defined(TARGET_SPARC) @@ -187,6 +189,14 @@ typedef struct MonitorEventState { QObject *data; /* Event pending delayed dispatch */ } MonitorEventState; +typedef struct MonitorQAPIEventState { +QAPIEvent event;/* Event being tracked */ +int64_t rate; /* Minimum time (in ns) between two events */ +int64_t last; /* QEMU_CLOCK_REALTIME value at last emission */ +QEMUTimer *timer; /* Timer for handling delayed events */ +QObject *data; /* Event pending delayed dispatch */ +} MonitorQAPIEventState; + struct Monitor { CharDriverState *chr; int mux_out; @@ -491,6 +501,121 @@ static const char *monitor_event_names[] = { QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) static MonitorEventState monitor_event_state[QEVENT_MAX]; +static MonitorQAPIEventState monitor_qapi_event_state[QAPI_EVENT_MAX]; + +/* + * Emits the event to every monitor instance, @event is only used for trace + */ +static void monitor_qapi_event_emit(QAPIEvent event, QObject *data) +{ +Monitor *mon; + +trace_monitor_protocol_event_emit(event, data); +QLIST_FOREACH(mon, mon_list, entry) { +if (monitor_ctrl_mode(mon) qmp_cmd_mode(mon)) { +monitor_json_emitter(mon, data); +} +} +} + +/* + * Queue a new event for emission to Monitor instances, + * applying any rate limiting if required. + */ +static void +monitor_qapi_event_queue(QAPIEvent event, QDict *data, Error **errp) +{ +MonitorQAPIEventState *evstate; +assert(event QAPI_EVENT_MAX); +int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + +evstate = (monitor_qapi_event_state[event]); +trace_monitor_protocol_event_queue(event, + data, + evstate-rate, + evstate-last, + now); + +/* Rate limit of 0 indicates no throttling */ +if (!evstate-rate) { +monitor_qapi_event_emit(event, QOBJECT(data)); +evstate-last = now; +} else { +int64_t delta = now - evstate-last; +if (evstate-data || +delta evstate-rate) { +/* If there's an existing event pending, replace + * it with the new event, otherwise schedule a + * timer for delayed emission + */ +if (evstate-data) { +qobject_decref(evstate-data); +} else { +int64_t then = evstate-last + evstate-rate; +timer_mod_ns(evstate-timer, then); +} +evstate-data = QOBJECT(data); +qobject_incref(evstate-data); +} else { +monitor_qapi_event_emit(event, QOBJECT(data)); +evstate-last = now; +} +} +} + +/* + * The callback invoked by QemuTimer when a delayed + * event is ready to be emitted + */ +static void monitor_qapi_event_handler(void *opaque) +{ +MonitorQAPIEventState *evstate = opaque; +int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + +trace_monitor_protocol_event_handler(evstate-event, + evstate-data, + evstate-last, + now); +if (evstate-data) { +monitor_qapi_event_emit(evstate-event, evstate-data); +qobject_decref(evstate-data); +evstate-data = NULL; +} +evstate-last = now; +} + +/* + * @event: the event ID to be limited + * @rate: the rate limit in milliseconds + * + * Sets a rate limit on a particular event, so no + * more than 1 event will be emitted within @rate + * milliseconds + */ +static void __attribute__((__unused__)) +monitor_qapi_event_throttle(QAPIEvent event, int64_t rate) +{ +MonitorQAPIEventState *evstate; +assert(event QAPI_EVENT_MAX); + +evstate = (monitor_qapi_event_state[event]); + +trace_monitor_protocol_event_throttle(event, rate); +
[Qemu-devel] [PATCH 2.1 29/36] qapi event: convert QUORUM events
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- block/quorum.c | 25 - docs/qmp/qmp-events.txt | 41 - monitor.c | 6 +++--- qapi-event.json | 38 ++ 4 files changed, 49 insertions(+), 61 deletions(-) delete mode 100644 docs/qmp/qmp-events.txt diff --git a/block/quorum.c b/block/quorum.c index 426077a..86802d3 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -17,6 +17,7 @@ #include gnutls/crypto.h #include block/block_int.h #include qapi/qmp/qjson.h +#include qapi-event.h #define HASH_LENGTH 32 @@ -198,32 +199,22 @@ static QuorumAIOCB *quorum_aio_get(BDRVQuorumState *s, static void quorum_report_bad(QuorumAIOCB *acb, char *node_name, int ret) { -QObject *data; -assert(node_name); -data = qobject_from_jsonf({ 'node-name': %s - , 'sector-num': % PRId64 - , 'sectors-count': %d }, - node_name, acb-sector_num, acb-nb_sectors); +const char *msg = NULL; if (ret 0) { -QDict *dict = qobject_to_qdict(data); -qdict_put(dict, error, qstring_from_str(strerror(-ret))); +msg = strerror(-ret); } -monitor_protocol_event(QEVENT_QUORUM_REPORT_BAD, data); -qobject_decref(data); +qapi_event_send_quorum_report_bad(!!msg, msg, node_name, + acb-sector_num, acb-nb_sectors, error_abort); } static void quorum_report_failure(QuorumAIOCB *acb) { -QObject *data; const char *reference = acb-common.bs-device_name[0] ? acb-common.bs-device_name : acb-common.bs-node_name; -data = qobject_from_jsonf({ 'reference': %s - , 'sector-num': % PRId64 - , 'sectors-count': %d }, - reference, acb-sector_num, acb-nb_sectors); -monitor_protocol_event(QEVENT_QUORUM_FAILURE, data); -qobject_decref(data); + +qapi_event_send_quorum_failure(reference, acb-sector_num, + acb-nb_sectors, error_abort); } static int quorum_vote_error(QuorumAIOCB *acb); diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt deleted file mode 100644 index adf45d3..000 --- a/docs/qmp/qmp-events.txt +++ /dev/null @@ -1,41 +0,0 @@ - QEMU Machine Protocol Events - - -QUORUM_FAILURE --- - -Emitted by the Quorum block driver if it fails to establish a quorum. - -Data: - -- reference:device name if defined else node name. -- sector-num: Number of the first sector of the failed read operation. -- sector-count: Failed read operation sector count. - -Example: - -{ event: QUORUM_FAILURE, - data: { reference: usr1, sector-num: 345435, sector-count: 5 }, - timestamp: { seconds: 1344522075, microseconds: 745528 } } - -QUORUM_REPORT_BAD -- - -Emitted to report a corruption of a Quorum file. - -Data: - -- error:Error message (json-string, optional) - Only present on failure. This field contains a human-readable - error message. There are no semantics other than that the - block layer reported an error and clients should not try to - interpret the error string. -- node-name:The graph node name of the block driver state. -- sector-num: Number of the first sector of the failed read operation. -- sector-count: Failed read operation sector count. - -Example: - -{ event: QUORUM_REPORT_BAD, - data: { node-name: 1.raw, sector-num: 345435, sector-count: 5 }, - timestamp: { seconds: 1344522075, microseconds: 745528 } } diff --git a/monitor.c b/monitor.c index e82f75e..db154e0 100644 --- a/monitor.c +++ b/monitor.c @@ -617,6 +617,9 @@ static void monitor_qapi_event_init(void) monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000); monitor_qapi_event_throttle(QAPI_EVENT_WATCHDOG, 1000); monitor_qapi_event_throttle(QAPI_EVENT_BALLOON_CHANGE, 1000); +/* limit the rate of quorum events to avoid hammering the management */ +monitor_qapi_event_throttle(QAPI_EVENT_QUORUM_REPORT_BAD, 1000); +monitor_qapi_event_throttle(QAPI_EVENT_QUORUM_FAILURE, 1000); qmp_event_set_func_emit(monitor_qapi_event_queue); } @@ -743,9 +746,6 @@ monitor_protocol_event_throttle(MonitorEvent event, * and initialize state */ static void monitor_protocol_event_init(void) { -/* limit the rate of quorum events to avoid hammering the management */ -monitor_protocol_event_throttle(QEVENT_QUORUM_REPORT_BAD, 1000); -monitor_protocol_event_throttle(QEVENT_QUORUM_FAILURE, 1000); } /** diff --git a/qapi-event.json b/qapi-event.json index
[Qemu-devel] [PATCH 2.1 35/36] monitor: protect outbuf and mux_out with mutex
This lets the block layer emit QMP events from outside the I/O thread. Reviewed-by: Luiz Capitulino lcapitul...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- monitor.c | 45 - 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/monitor.c b/monitor.c index 66a1db7..2b97e4e 100644 --- a/monitor.c +++ b/monitor.c @@ -191,13 +191,18 @@ typedef struct MonitorQAPIEventState { struct Monitor { CharDriverState *chr; -int mux_out; int reset_seen; int flags; int suspend_cnt; bool skip_flush; + +QemuMutex out_lock; QString *outbuf; -guint watch; +guint out_watch; + +/* Read under either BQL or out_lock, written with BQL+out_lock. */ +int mux_out; + ReadLineState *rs; MonitorControl *mc; CPUState *mon_cpu; @@ -270,17 +275,22 @@ int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, } } +static void monitor_flush_locked(Monitor *mon); + static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond, void *opaque) { Monitor *mon = opaque; -mon-watch = 0; -monitor_flush(mon); +qemu_mutex_lock(mon-out_lock); +mon-out_watch = 0; +monitor_flush_locked(mon); +qemu_mutex_unlock(mon-out_lock); return FALSE; } -void monitor_flush(Monitor *mon) +/* Called with mon-out_lock held. */ +static void monitor_flush_locked(Monitor *mon) { int rc; size_t len; @@ -307,18 +317,26 @@ void monitor_flush(Monitor *mon) QDECREF(mon-outbuf); mon-outbuf = tmp; } -if (mon-watch == 0) { -mon-watch = qemu_chr_fe_add_watch(mon-chr, G_IO_OUT, - monitor_unblocked, mon); +if (mon-out_watch == 0) { +mon-out_watch = qemu_chr_fe_add_watch(mon-chr, G_IO_OUT, + monitor_unblocked, mon); } } } +void monitor_flush(Monitor *mon) +{ +qemu_mutex_lock(mon-out_lock); +monitor_flush_locked(mon); +qemu_mutex_unlock(mon-out_lock); +} + /* flush at every end of line */ static void monitor_puts(Monitor *mon, const char *str) { char c; +qemu_mutex_lock(mon-out_lock); for(;;) { c = *str++; if (c == '\0') @@ -328,9 +346,10 @@ static void monitor_puts(Monitor *mon, const char *str) } qstring_append_chr(mon-outbuf, c); if (c == '\n') { -monitor_flush(mon); +monitor_flush_locked(mon); } } +qemu_mutex_unlock(mon-out_lock); } void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) @@ -581,6 +600,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline); static void monitor_data_init(Monitor *mon) { memset(mon, 0, sizeof(Monitor)); +qemu_mutex_init(mon-out_lock); mon-outbuf = qstring_new(); /* Use *mon_cmds by default. */ mon-cmd_table = mon_cmds; @@ -589,6 +609,7 @@ static void monitor_data_init(Monitor *mon) static void monitor_data_destroy(Monitor *mon) { QDECREF(mon-outbuf); +qemu_mutex_destroy(mon-out_lock); } char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, @@ -616,11 +637,13 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, handle_user_command(hmp, command_line); cur_mon = old_mon; +qemu_mutex_lock(hmp.out_lock); if (qstring_get_length(hmp.outbuf) 0) { output = g_strdup(qstring_get_str(hmp.outbuf)); } else { output = g_strdup(); } +qemu_mutex_unlock(hmp.out_lock); out: monitor_data_destroy(hmp); @@ -5173,7 +5196,9 @@ static void monitor_event(void *opaque, int event) switch (event) { case CHR_EVENT_MUX_IN: +qemu_mutex_lock(mon-out_lock); mon-mux_out = 0; +qemu_mutex_unlock(mon-out_lock); if (mon-reset_seen) { readline_restart(mon-rs); monitor_resume(mon); @@ -5193,7 +5218,9 @@ static void monitor_event(void *opaque, int event) } else { mon-suspend_cnt++; } +qemu_mutex_lock(mon-out_lock); mon-mux_out = 1; +qemu_mutex_unlock(mon-out_lock); break; case CHR_EVENT_OPENED: -- 1.9.3
[Qemu-devel] [PATCH 2.1 32/36] qemu-char: do not call chr_write directly
Make the mux always go through qemu_chr_fe_write, so that we'll get the mutex for the underlying chardev. Reviewed-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- qemu-char.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 56a0a9a..26994aa 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -279,7 +279,7 @@ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) MuxDriver *d = chr-opaque; int ret; if (!d-timestamps) { -ret = d-drv-chr_write(d-drv, buf, len); +ret = qemu_chr_fe_write(d-drv, buf, len); } else { int i; @@ -301,10 +301,10 @@ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) (secs / 60) % 60, secs % 60, (int)(ti % 1000)); -d-drv-chr_write(d-drv, (uint8_t *)buf1, strlen(buf1)); +qemu_chr_fe_write(d-drv, (uint8_t *)buf1, strlen(buf1)); d-linestart = 0; } -ret += d-drv-chr_write(d-drv, buf+i, 1); +ret += qemu_chr_fe_write(d-drv, buf+i, 1); if (buf[i] == '\n') { d-linestart = 1; } @@ -339,13 +339,13 @@ static void mux_print_help(CharDriverState *chr) \n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r, term_escape_char); } -chr-chr_write(chr, (uint8_t *)cbuf, strlen(cbuf)); +qemu_chr_fe_write(chr, (uint8_t *)cbuf, strlen(cbuf)); for (i = 0; mux_help[i] != NULL; i++) { for (j=0; mux_help[i][j] != '\0'; j++) { if (mux_help[i][j] == '%') -chr-chr_write(chr, (uint8_t *)ebuf, strlen(ebuf)); +qemu_chr_fe_write(chr, (uint8_t *)ebuf, strlen(ebuf)); else -chr-chr_write(chr, (uint8_t *)mux_help[i][j], 1); +qemu_chr_fe_write(chr, (uint8_t *)mux_help[i][j], 1); } } } @@ -370,7 +370,7 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) case 'x': { const char *term = QEMU: Terminated\n\r; - chr-chr_write(chr,(uint8_t *)term,strlen(term)); + qemu_chr_fe_write(chr, (uint8_t *)term, strlen(term)); exit(0); break; } -- 1.9.3
[Qemu-devel] [PATCH 2.1 25/36] qapi event: convert VNC events
From: Wenchao Xia wenchaoq...@gmail.com Since VNC_CONNECTED, VNC_DISCONNECTED, VNC_INITIALIZED share some common functions, convert them in one patch. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 90 --- qapi-event.json | 49 + ui/vnc.c| 111 +--- ui/vnc.h| 4 +- 4 files changed, 108 insertions(+), 146 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 101f207..37bc891 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -132,93 +132,3 @@ Example: connection-id: 1804289383, host: 127.0.0.1, channel-id: 0, tls: true} }} - -VNC_CONNECTED -- - -Emitted when a VNC client establishes a connection. - -Data: - -- server: Server information (json-object) - - host: IP address (json-string) - - service: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - - auth: authentication method (json-string, optional) -- client: Client information (json-object) - - host: IP address (json-string) - - service: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - -Example: - -{ event: VNC_CONNECTED, -data: { -server: { auth: sasl, family: ipv4, -service: 5901, host: 0.0.0.0 }, -client: { family: ipv4, service: 58425, -host: 127.0.0.1 } }, -timestamp: { seconds: 1262976601, microseconds: 975795 } } - - -Note: This event is emitted before any authentication takes place, thus -the authentication ID is not provided. - -VNC_DISCONNECTED - - -Emitted when the connection is closed. - -Data: - -- server: Server information (json-object) - - host: IP address (json-string) - - service: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - - auth: authentication method (json-string, optional) -- client: Client information (json-object) - - host: IP address (json-string) - - service: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - - x509_dname: TLS dname (json-string, optional) - - sasl_username: SASL username (json-string, optional) - -Example: - -{ event: VNC_DISCONNECTED, -data: { -server: { auth: sasl, family: ipv4, -service: 5901, host: 0.0.0.0 }, -client: { family: ipv4, service: 58425, -host: 127.0.0.1, sasl_username: luiz } }, -timestamp: { seconds: 1262976601, microseconds: 975795 } } - -VNC_INITIALIZED - -Emitted after authentication takes place (if any) and the VNC session is -made active. - -Data: - -- server: Server information (json-object) - - host: IP address (json-string) - - service: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - - auth: authentication method (json-string, optional) -- client: Client information (json-object) - - host: IP address (json-string) - - service: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - - x509_dname: TLS dname (json-string, optional) - - sasl_username: SASL username (json-string, optional) - -Example: - -{ event: VNC_INITIALIZED, -data: { -server: { auth: sasl, family: ipv4, -service: 5901, host: 0.0.0.0}, -client: { family: ipv4, service: 46089, -host: 127.0.0.1, sasl_username: luiz } }, -timestamp: { seconds: 1263475302, microseconds: 150772 } } diff --git a/qapi-event.json b/qapi-event.json index b8dec47..a86f8c9 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -137,3 +137,52 @@ ## { 'event': 'NIC_RX_FILTER_CHANGED', 'data': { '*name': 'str', 'path': 'str' } } + +## +# @VNC_CONNECTED +# +# Emitted when a VNC client establishes a connection +# +# @server: server information +# +# @client: client information +# +# Note: This event is emitted before any authentication takes place, thus +# the authentication ID is not provided +# +# Since: 0.13.0 +## +{ 'event': 'VNC_CONNECTED', + 'data': { 'server': 'VncServerInfo', +'client': 'VncBasicInfo' } } + +## +# @VNC_INITIALIZED +# +# Emitted after authentication takes place (if any) and the VNC session is +# made active +# +# @server: server information +# +# @client: client information +# +# Since: 0.13.0 +## +{ 'event': 'VNC_INITIALIZED', + 'data': { 'server': 'VncServerInfo', +'client': 'VncClientInfo' } } + +## +# @VNC_DISCONNECTED +# +# Emitted when the connection is closed +# +# @server: server information +# +# @client: client information +# +# Since: 0.13.0 +## +{ 'event': 'VNC_DISCONNECTED', + 'data': { 'server': 'VncServerInfo', +'client': 'VncClientInfo' } } diff --git a/ui/vnc.c b/ui/vnc.c index 95eee5a..9ccd5e3
[Qemu-devel] [PATCH 2.1 16/36] qapi event: convert WAKEUP
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 12 qapi-event.json | 9 + vl.c| 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index c2f23ef..3d82db4 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -432,18 +432,6 @@ Example: host: 127.0.0.1, sasl_username: luiz } }, timestamp: { seconds: 1263475302, microseconds: 150772 } } -WAKEUP --- - -Emitted when the guest has woken up from S3 and is running. - -Data: None. - -Example: - -{ event: WAKEUP, - timestamp: { seconds: 1344522075, microseconds: 745528 } } - WATCHDOG diff --git a/qapi-event.json b/qapi-event.json index 469353c..807a6f5 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -69,3 +69,12 @@ # Since: 1.2 ## { 'event': 'SUSPEND_DISK' } + +## +# @WAKEUP +# +# Emitted when the guest has woken up from suspend state and is running +# +# Since: 1.1 +## +{ 'event': 'WAKEUP' } diff --git a/vl.c b/vl.c index 107176c..bcda808 100644 --- a/vl.c +++ b/vl.c @@ -2052,7 +2052,7 @@ static bool main_loop_should_exit(void) notifier_list_notify(wakeup_notifiers, wakeup_reason); wakeup_reason = QEMU_WAKEUP_REASON_NONE; resume_all_vcpus(); -monitor_protocol_event(QEVENT_WAKEUP, NULL); +qapi_event_send_wakeup(error_abort); } if (qemu_powerdown_requested()) { qemu_system_powerdown(); -- 1.9.3
[Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe
This will let threads other than the I/O thread raise QMP events. GIOChannel is thread-safe, and send and receive state is usually well-separated. The only driver that requires some care is the pty driver, where some of the state is shared by the read and write sides. That state is protected with the chr_write_lock too. Reviewed-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/sysemu/char.h | 11 ++ qemu-char.c | 58 --- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 65782c0..b3e4735 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -54,6 +54,7 @@ typedef struct { typedef void IOEventHandler(void *opaque, int event); struct CharDriverState { +QemuMutex chr_write_lock; void (*init)(struct CharDriverState *s); int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond); @@ -160,6 +161,7 @@ void qemu_chr_fe_event(CharDriverState *s, int event); * @qemu_chr_fe_printf: * * Write to a character backend using a printf style interface. + * This function is thread-safe. * * @fmt see #printf */ @@ -172,8 +174,9 @@ int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, /** * @qemu_chr_fe_write: * - * Write data to a character backend from the front end. This function will - * send data from the front end to the back end. + * Write data to a character backend from the front end. This function + * will send data from the front end to the back end. This function + * is thread-safe. * * @buf the data * @len the number of bytes to send @@ -188,7 +191,7 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); * Write data to a character backend from the front end. This function will * send data from the front end to the back end. Unlike @qemu_chr_fe_write, * this function will block if the back end cannot consume all of the data - * attempted to be written. + * attempted to be written. This function is thread-safe. * * @buf the data * @len the number of bytes to send @@ -200,7 +203,7 @@ int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len); /** * @qemu_chr_fe_ioctl: * - * Issue a device specific ioctl to a backend. + * Issue a device specific ioctl to a backend. This function is thread-safe. * * @cmd see CHR_IOCTL_* * @arg the data associated with @cmd diff --git a/qemu-char.c b/qemu-char.c index 9470ea2..b0f3ff4 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -121,7 +121,12 @@ void qemu_chr_be_generic_open(CharDriverState *s) int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len) { -return s-chr_write(s, buf, len); +int ret; + +qemu_mutex_lock(s-chr_write_lock); +ret = s-chr_write(s, buf, len); +qemu_mutex_unlock(s-chr_write_lock); +return ret; } int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len) @@ -129,6 +134,7 @@ int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len) int offset = 0; int res; +qemu_mutex_lock(s-chr_write_lock); while (offset len) { do { res = s-chr_write(s, buf + offset, len - offset); @@ -137,17 +143,17 @@ int qemu_chr_fe_write_all(CharDriverState *s, const uint8_t *buf, int len) } } while (res == -1 errno == EAGAIN); -if (res == 0) { +if (res = 0) { break; } -if (res 0) { -return res; -} - offset += res; } +qemu_mutex_unlock(s-chr_write_lock); +if (res 0) { +return res; +} return offset; } @@ -269,11 +275,14 @@ typedef struct { int prod[MAX_MUX]; int cons[MAX_MUX]; int timestamps; + +/* Protected by the CharDriverState chr_write_lock. */ int linestart; int64_t timestamps_start; } MuxDriver; +/* Called with chr_write_lock held. */ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { MuxDriver *d = chr-opaque; @@ -819,6 +828,7 @@ typedef struct FDCharDriver { QTAILQ_ENTRY(FDCharDriver) node; } FDCharDriver; +/* Called with chr_write_lock held. */ static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { FDCharDriver *s = chr-opaque; @@ -1018,12 +1028,14 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) typedef struct { GIOChannel *fd; -int connected; int read_bytes; + +/* Protected by the CharDriverState chr_write_lock. */ +int connected; guint timer_tag; } PtyCharDriver; -static void pty_chr_update_read_handler(CharDriverState *chr); +static void pty_chr_update_read_handler_locked(CharDriverState *chr); static void pty_chr_state(CharDriverState *chr, int connected);
[Qemu-devel] [PATCH 2.1 18/36] qapi event: convert WATCHDOG
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 19 --- hw/watchdog/watchdog.c | 23 +++ monitor.c | 2 +- qapi-event.json | 15 +++ qapi-schema.json| 24 5 files changed, 47 insertions(+), 36 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 8cad3e7..df15dc8 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -415,22 +415,3 @@ Example: client: { family: ipv4, service: 46089, host: 127.0.0.1, sasl_username: luiz } }, timestamp: { seconds: 1263475302, microseconds: 150772 } } - -WATCHDOG - - -Emitted when the watchdog device's timer is expired. - -Data: - -- action: Action that has been taken, it's one of the following (json-string): -reset, shutdown, poweroff, pause, debug, or none - -Example: - -{ event: WATCHDOG, - data: { action: reset }, - timestamp: { seconds: 1267061043, microseconds: 959568 } } - -Note: If action is reset, shutdown, or pause the WATCHDOG event is -followed respectively by the RESET, SHUTDOWN, or STOP events. diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c index f28161b..4aebd34 100644 --- a/hw/watchdog/watchdog.c +++ b/hw/watchdog/watchdog.c @@ -24,9 +24,9 @@ #include qemu/config-file.h #include qemu/queue.h #include qapi/qmp/types.h -#include monitor/monitor.h #include sysemu/sysemu.h #include sysemu/watchdog.h +#include qapi-event.h /* Possible values for action parameter. */ #define WDT_RESET1 /* Hard reset. */ @@ -101,15 +101,6 @@ int select_watchdog_action(const char *p) return 0; } -static void watchdog_mon_event(const char *action) -{ -QObject *data; - -data = qobject_from_jsonf({ 'action': %s }, action); -monitor_protocol_event(QEVENT_WATCHDOG, data); -qobject_decref(data); -} - /* This actually performs the action once a watchdog has expired, * ie. reboot, shutdown, exit, etc. */ @@ -117,31 +108,31 @@ void watchdog_perform_action(void) { switch(watchdog_action) { case WDT_RESET: /* same as 'system_reset' in monitor */ -watchdog_mon_event(reset); +qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_RESET, error_abort); qemu_system_reset_request(); break; case WDT_SHUTDOWN: /* same as 'system_powerdown' in monitor */ -watchdog_mon_event(shutdown); +qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_SHUTDOWN, error_abort); qemu_system_powerdown_request(); break; case WDT_POWEROFF: /* same as 'quit' command in monitor */ -watchdog_mon_event(poweroff); +qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_POWEROFF, error_abort); exit(0); case WDT_PAUSE: /* same as 'stop' command in monitor */ -watchdog_mon_event(pause); +qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_PAUSE, error_abort); vm_stop(RUN_STATE_WATCHDOG); break; case WDT_DEBUG: -watchdog_mon_event(debug); +qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_DEBUG, error_abort); fprintf(stderr, watchdog: timer fired\n); break; case WDT_NONE: -watchdog_mon_event(none); +qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_NONE, error_abort); break; } } diff --git a/monitor.c b/monitor.c index cfaed60..589ae37 100644 --- a/monitor.c +++ b/monitor.c @@ -615,6 +615,7 @@ static void monitor_qapi_event_init(void) { /* Limit guest-triggerable events to 1 per second */ monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000); +monitor_qapi_event_throttle(QAPI_EVENT_WATCHDOG, 1000); qmp_event_set_func_emit(monitor_qapi_event_queue); } @@ -743,7 +744,6 @@ static void monitor_protocol_event_init(void) { /* Limit RTC BALLOON events to 1 per second */ monitor_protocol_event_throttle(QEVENT_BALLOON_CHANGE, 1000); -monitor_protocol_event_throttle(QEVENT_WATCHDOG, 1000); /* limit the rate of quorum events to avoid hammering the management */ monitor_protocol_event_throttle(QEVENT_QUORUM_REPORT_BAD, 1000); monitor_protocol_event_throttle(QEVENT_QUORUM_FAILURE, 1000); diff --git a/qapi-event.json b/qapi-event.json index e6cfafa..e7dbfab 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -91,3 +91,18 @@ ## { 'event': 'RTC_CHANGE', 'data': { 'offset': 'int' } } + +## +# @WATCHDOG +# +# Emitted when the watchdog device's timer is expired +# +# @action: action that has been taken +# +# Note: If action is reset, shutdown, or pause the WATCHDOG event is +# followed respectively by the RESET, SHUTDOWN, or STOP events +# +# Since: 0.13.0 +## +{ 'event': 'WATCHDOG', + 'data': { 'action':
[Qemu-devel] [PATCH 2.1 20/36] qapi event: convert DEVICE_TRAY_MOVED
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- block.c | 21 +++-- docs/qmp/qmp-events.txt | 18 -- qapi/block.json | 14 ++ 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/block.c b/block.c index b31d546..0d0e5cd 100644 --- a/block.c +++ b/block.c @@ -35,6 +35,7 @@ #include block/qapi.h #include qmp-commands.h #include qemu/timer.h +#include qapi-event.h #ifdef CONFIG_BSD #include sys/types.h @@ -2162,17 +2163,6 @@ void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv, qobject_decref(data); } -static void bdrv_emit_qmp_eject_event(BlockDriverState *bs, bool ejected) -{ -QObject *data; - -data = qobject_from_jsonf({ 'device': %s, 'tray-open': %i }, - bdrv_get_device_name(bs), ejected); -monitor_protocol_event(QEVENT_DEVICE_TRAY_MOVED, data); - -qobject_decref(data); -} - static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load) { if (bs-dev_ops bs-dev_ops-change_media_cb) { @@ -2180,11 +2170,13 @@ static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load) bs-dev_ops-change_media_cb(bs-dev_opaque, load); if (tray_was_closed) { /* tray open */ -bdrv_emit_qmp_eject_event(bs, true); +qapi_event_send_device_tray_moved(bdrv_get_device_name(bs), + true, error_abort); } if (load) { /* tray close */ -bdrv_emit_qmp_eject_event(bs, false); +qapi_event_send_device_tray_moved(bdrv_get_device_name(bs), + false, error_abort); } } } @@ -5200,7 +5192,8 @@ void bdrv_eject(BlockDriverState *bs, bool eject_flag) } if (bs-device_name[0] != '\0') { -bdrv_emit_qmp_eject_event(bs, eject_flag); +qapi_event_send_device_tray_moved(bdrv_get_device_name(bs), + eject_flag, error_abort); } } diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index fda68df..1ee6f53 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -158,24 +158,6 @@ Example: Note: The ready to complete status is always reset by a BLOCK_JOB_ERROR event. -DEVICE_TRAY_MOVED -- - -It's emitted whenever the tray of a removable device is moved by the guest -or by HMP/QMP commands. - -Data: - -- device: device name (json-string) -- tray-open: true if the tray has been opened or false if it has been closed - (json-bool) - -{ event: DEVICE_TRAY_MOVED, - data: { device: ide1-cd0, -tray-open: true - }, - timestamp: { seconds: 1265044230, microseconds: 450486 } } - GUEST_PANICKED -- diff --git a/qapi/block.json b/qapi/block.json index 61c463a..e313465 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -164,3 +164,17 @@ ## { 'command': 'nbd-server-stop' } +## +# @DEVICE_TRAY_MOVED +# +# Emitted whenever the tray of a removable device is moved by the guest or by +# HMP/QMP commands +# +# @device: device name +# +# @tray-open: true if the tray has been opened or false if it has been closed +# +# Since: 1.1 +## +{ 'event': 'DEVICE_TRAY_MOVED', + 'data': { 'device': 'str', 'tray-open': 'bool' } } -- 1.9.3
[Qemu-devel] [PATCH 2.1 26/36] qapi event: convert SPICE events
From: Wenchao Xia wenchaoq...@gmail.com SPICE_INITIALIZED, SPICE_CONNECTED, SPICE_DISCONNECTED and SPICE_MIGRATE_COMPLETED are converted in one patch, since they use some common functions. inet_strfamily() is removed since no callers exist anymore. Note that there is no existing doc for SPICE_MIGRATE_COMPLETED in docs/qmp/qmp-events.txt before this patch. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 62 --- include/qemu/sockets.h | 1 - qapi-event.json | 55 ++ ui/spice-core.c | 70 + util/qemu-sockets.c | 10 --- 5 files changed, 91 insertions(+), 107 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 37bc891..4fbc3de 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -70,65 +70,3 @@ Example: { event: QUORUM_REPORT_BAD, data: { node-name: 1.raw, sector-num: 345435, sector-count: 5 }, timestamp: { seconds: 1344522075, microseconds: 745528 } } - -SPICE_CONNECTED, SPICE_DISCONNECTED - -Emitted when a SPICE client connects or disconnects. - -Data: - -- server: Server information (json-object) - - host: IP address (json-string) - - port: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) -- client: Client information (json-object) - - host: IP address (json-string) - - port: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - -Example: - -{ timestamp: {seconds: 1290688046, microseconds: 388707}, - event: SPICE_CONNECTED, - data: { -server: { port: 5920, family: ipv4, host: 127.0.0.1}, -client: {port: 52873, family: ipv4, host: 127.0.0.1} -}} - -SPICE_INITIALIZED -- - -Emitted after initial handshake and authentication takes place (if any) -and the SPICE channel is up'n'running - -Data: - -- server: Server information (json-object) - - host: IP address (json-string) - - port: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - - auth: authentication method (json-string, optional) -- client: Client information (json-object) - - host: IP address (json-string) - - port: port number (json-string) - - family: address family (json-string, ipv4 or ipv6) - - connection-id: spice connection id. All channels with the same id - belong to the same spice session (json-int) - - channel-type: channel type. 1 is the main control channel, filter for -this one if you want track spice sessions only (json-int) - - channel-id: channel id. Usually 0, might be different needed when - multiple channels of the same type exist, such as multiple - display channels in a multihead setup (json-int) - - tls: whevener the channel is encrypted (json-bool) - -Example: - -{ timestamp: {seconds: 1290688046, microseconds: 417172}, - event: SPICE_INITIALIZED, - data: {server: {auth: spice, port: 5921, - family: ipv4, host: 127.0.0.1}, - client: {port: 49004, family: ipv4, channel-type: 3, - connection-id: 1804289383, host: 127.0.0.1, - channel-id: 0, tls: true} -}} diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index af24669..fdbb196 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -61,7 +61,6 @@ int inet_nonblocking_connect(const char *str, void *opaque, Error **errp); int inet_dgram_opts(QemuOpts *opts, Error **errp); -const char *inet_strfamily(int family); NetworkAddressFamily inet_netfamily(int family); int unix_listen_opts(QemuOpts *opts, Error **errp); diff --git a/qapi-event.json b/qapi-event.json index a86f8c9..1e23549 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -186,3 +186,58 @@ { 'event': 'VNC_DISCONNECTED', 'data': { 'server': 'VncServerInfo', 'client': 'VncClientInfo' } } + +## +# @SPICE_CONNECTED +# +# Emitted when a SPICE client establishes a connection +# +# @server: server information +# +# @client: client information +# +# Since: 0.14.0 +## +{ 'event': 'SPICE_CONNECTED', + 'data': { 'server': 'SpiceBasicInfo', +'client': 'SpiceBasicInfo' } } + +## +# @SPICE_INITIALIZED +# +# Emitted after initial handshake and authentication takes place (if any) +# and the SPICE channel is up and running +# +# @server: server information +# +# @client: client information +# +# Since: 0.14.0 +## +{ 'event': 'SPICE_INITIALIZED', + 'data': { 'server': 'SpiceServerInfo', +'client': 'SpiceChannel' } } + +## +# @SPICE_DISCONNECTED +# +# Emitted when the SPICE connection is closed +# +# @server: server information +# +# @client: client information +# +# Since: 0.14.0 +## +{ 'event': 'SPICE_DISCONNECTED', + 'data': {
[Qemu-devel] [PATCH 2.1 28/36] qapi event: convert GUEST_PANICKED
From: Wenchao Xia wenchaoq...@gmail.com 'monitor.h' is still included in target-s390x/kvm.c, since I have no good way to verify whether other code need it on my x86 host. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 14 -- hw/misc/pvpanic.c | 13 ++--- qapi-event.json | 12 qapi-schema.json| 12 target-s390x/kvm.c | 9 +++-- 5 files changed, 29 insertions(+), 31 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 1b0e25f..adf45d3 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -1,20 +1,6 @@ QEMU Machine Protocol Events -GUEST_PANICKED --- - -Emitted when guest OS panic is detected. - -Data: - -- action: Action that has been taken (json-string, currently always pause). - -Example: - -{ event: GUEST_PANICKED, - data: { action: pause } } - QUORUM_FAILURE -- diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c index 5377fee..994f8af 100644 --- a/hw/misc/pvpanic.c +++ b/hw/misc/pvpanic.c @@ -14,12 +14,12 @@ #include qapi/qmp/qobject.h #include qapi/qmp/qjson.h -#include monitor/monitor.h #include sysemu/sysemu.h #include qemu/log.h #include hw/nvram/fw_cfg.h #include hw/i386/pc.h +#include qapi-event.h /* The bit of supported pv event */ #define PVPANIC_F_PANICKED 0 @@ -31,15 +31,6 @@ #define ISA_PVPANIC_DEVICE(obj)\ OBJECT_CHECK(PVPanicState, (obj), TYPE_ISA_PVPANIC_DEVICE) -static void panicked_mon_event(const char *action) -{ -QObject *data; - -data = qobject_from_jsonf({ 'action': %s }, action); -monitor_protocol_event(QEVENT_GUEST_PANICKED, data); -qobject_decref(data); -} - static void handle_event(int event) { static bool logged; @@ -50,7 +41,7 @@ static void handle_event(int event) } if (event PVPANIC_PANICKED) { -panicked_mon_event(pause); +qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, error_abort); vm_stop(RUN_STATE_GUEST_PANICKED); return; } diff --git a/qapi-event.json b/qapi-event.json index 07190c2..d07da39 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -254,3 +254,15 @@ ## { 'event': 'BALLOON_CHANGE', 'data': { 'actual': 'int' } } + +## +# @GUEST_PANICKED +# +# Emitted when guest OS panic is detected +# +# @action: action that has been taken, currently always pause +# +# Since: 1.5 +## +{ 'event': 'GUEST_PANICKED', + 'data': { 'action': 'GuestPanicAction' } } diff --git a/qapi-schema.json b/qapi-schema.json index 0a8df60..d62bb7d 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3179,4 +3179,16 @@ { 'enum': 'IoOperationType', 'data': [ 'read', 'write' ] } +## +# @GuestPanicAction +# +# An enumeration of the actions taken when guest OS panic is detected +# +# @pause: system pauses +# +# Since: 2.1 +## +{ 'enum': 'GuestPanicAction', + 'data': [ 'pause' ] } + { 'include': 'qapi-event.json' } diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index a1a4cc2..a6e587b 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -39,6 +39,7 @@ #include monitor/monitor.h #include exec/gdbstub.h #include trace.h +#include qapi-event.h /* #define DEBUG_KVM */ @@ -1029,12 +1030,8 @@ static bool is_special_wait_psw(CPUState *cs) static void guest_panicked(void) { -QObject *data; - -data = qobject_from_jsonf({ 'action': %s }, pause); -monitor_protocol_event(QEVENT_GUEST_PANICKED, data); -qobject_decref(data); - +qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, + error_abort); vm_stop(RUN_STATE_GUEST_PANICKED); } -- 1.9.3
[Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/monitor/monitor.h | 40 - monitor.c | 220 + stubs/Makefile.objs| 1 - stubs/mon-protocol-event.c | 6 -- 4 files changed, 4 insertions(+), 263 deletions(-) delete mode 100644 stubs/mon-protocol-event.c diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index 1c1f56f..3d6929d 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -19,48 +19,8 @@ extern Monitor *default_mon; /* flags for monitor commands */ #define MONITOR_CMD_ASYNC 0x0001 -/* QMP events */ -typedef enum MonitorEvent { -QEVENT_SHUTDOWN, -QEVENT_RESET, -QEVENT_POWERDOWN, -QEVENT_STOP, -QEVENT_RESUME, -QEVENT_VNC_CONNECTED, -QEVENT_VNC_INITIALIZED, -QEVENT_VNC_DISCONNECTED, -QEVENT_BLOCK_IO_ERROR, -QEVENT_RTC_CHANGE, -QEVENT_WATCHDOG, -QEVENT_SPICE_CONNECTED, -QEVENT_SPICE_INITIALIZED, -QEVENT_SPICE_DISCONNECTED, -QEVENT_BLOCK_JOB_COMPLETED, -QEVENT_BLOCK_JOB_CANCELLED, -QEVENT_BLOCK_JOB_ERROR, -QEVENT_BLOCK_JOB_READY, -QEVENT_DEVICE_DELETED, -QEVENT_DEVICE_TRAY_MOVED, -QEVENT_NIC_RX_FILTER_CHANGED, -QEVENT_SUSPEND, -QEVENT_SUSPEND_DISK, -QEVENT_WAKEUP, -QEVENT_BALLOON_CHANGE, -QEVENT_SPICE_MIGRATE_COMPLETED, -QEVENT_GUEST_PANICKED, -QEVENT_BLOCK_IMAGE_CORRUPTED, -QEVENT_QUORUM_FAILURE, -QEVENT_QUORUM_REPORT_BAD, - -/* Add to 'monitor_event_names' array in monitor.c when - * defining new events here */ - -QEVENT_MAX, -} MonitorEvent; - int monitor_cur_is_qmp(void); -void monitor_protocol_event(MonitorEvent event, QObject *data); void monitor_init(CharDriverState *chr, int flags); int monitor_suspend(Monitor *mon); diff --git a/monitor.c b/monitor.c index db154e0..66a1db7 100644 --- a/monitor.c +++ b/monitor.c @@ -181,14 +181,6 @@ typedef struct MonitorControl { * throttling is calculated globally, rather than per-Monitor * instance. */ -typedef struct MonitorEventState { -MonitorEvent event; /* Event being tracked */ -int64_t rate; /* Period over which to throttle. 0 to disable */ -int64_t last; /* Time at which event was last emitted */ -QEMUTimer *timer; /* Timer for handling delayed events */ -QObject *data; /* Event pending delayed dispatch */ -} MonitorEventState; - typedef struct MonitorQAPIEventState { QAPIEvent event;/* Event being tracked */ int64_t rate; /* Minimum time (in ns) between two events */ @@ -449,58 +441,7 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data) QDECREF(qmp); } -static void timestamp_put(QDict *qdict) -{ -int err; -QObject *obj; -qemu_timeval tv; - -err = qemu_gettimeofday(tv); -if (err 0) -return; - -obj = qobject_from_jsonf({ 'seconds': % PRId64 , -'microseconds': % PRId64 }, -(int64_t) tv.tv_sec, (int64_t) tv.tv_usec); -qdict_put_obj(qdict, timestamp, obj); -} - - -static const char *monitor_event_names[] = { -[QEVENT_SHUTDOWN] = SHUTDOWN, -[QEVENT_RESET] = RESET, -[QEVENT_POWERDOWN] = POWERDOWN, -[QEVENT_STOP] = STOP, -[QEVENT_RESUME] = RESUME, -[QEVENT_VNC_CONNECTED] = VNC_CONNECTED, -[QEVENT_VNC_INITIALIZED] = VNC_INITIALIZED, -[QEVENT_VNC_DISCONNECTED] = VNC_DISCONNECTED, -[QEVENT_BLOCK_IO_ERROR] = BLOCK_IO_ERROR, -[QEVENT_RTC_CHANGE] = RTC_CHANGE, -[QEVENT_WATCHDOG] = WATCHDOG, -[QEVENT_SPICE_CONNECTED] = SPICE_CONNECTED, -[QEVENT_SPICE_INITIALIZED] = SPICE_INITIALIZED, -[QEVENT_SPICE_DISCONNECTED] = SPICE_DISCONNECTED, -[QEVENT_BLOCK_JOB_COMPLETED] = BLOCK_JOB_COMPLETED, -[QEVENT_BLOCK_JOB_CANCELLED] = BLOCK_JOB_CANCELLED, -[QEVENT_BLOCK_JOB_ERROR] = BLOCK_JOB_ERROR, -[QEVENT_BLOCK_JOB_READY] = BLOCK_JOB_READY, -[QEVENT_DEVICE_DELETED] = DEVICE_DELETED, -[QEVENT_DEVICE_TRAY_MOVED] = DEVICE_TRAY_MOVED, -[QEVENT_NIC_RX_FILTER_CHANGED] = NIC_RX_FILTER_CHANGED, -[QEVENT_SUSPEND] = SUSPEND, -[QEVENT_SUSPEND_DISK] = SUSPEND_DISK, -[QEVENT_WAKEUP] = WAKEUP, -[QEVENT_BALLOON_CHANGE] = BALLOON_CHANGE, -[QEVENT_SPICE_MIGRATE_COMPLETED] = SPICE_MIGRATE_COMPLETED, -[QEVENT_GUEST_PANICKED] = GUEST_PANICKED, -[QEVENT_BLOCK_IMAGE_CORRUPTED] = BLOCK_IMAGE_CORRUPTED, -[QEVENT_QUORUM_FAILURE] = QUORUM_FAILURE, -[QEVENT_QUORUM_REPORT_BAD] = QUORUM_REPORT_BAD, -}; -QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) -static MonitorEventState monitor_event_state[QEVENT_MAX]; static MonitorQAPIEventState monitor_qapi_event_state[QAPI_EVENT_MAX]; /* @@ -592,7 +533,7 @@ static void monitor_qapi_event_handler(void *opaque) * more than 1 event will be emitted within @rate *
[Qemu-devel] [PATCH 2.1 33/36] qemu-char: move pty_chr_update_read_handler around
Reviewed-by: Fam Zheng f...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- qemu-char.c | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 26994aa..9470ea2 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1055,6 +1055,22 @@ static void pty_chr_rearm_timer(CharDriverState *chr, int ms) } } +static void pty_chr_update_read_handler(CharDriverState *chr) +{ +PtyCharDriver *s = chr-opaque; +GPollFD pfd; + +pfd.fd = g_io_channel_unix_get_fd(s-fd); +pfd.events = G_IO_OUT; +pfd.revents = 0; +g_poll(pfd, 1, 0); +if (pfd.revents G_IO_HUP) { +pty_chr_state(chr, 0); +} else { +pty_chr_state(chr, 1); +} +} + static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { PtyCharDriver *s = chr-opaque; @@ -1107,22 +1123,6 @@ static gboolean pty_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) return TRUE; } -static void pty_chr_update_read_handler(CharDriverState *chr) -{ -PtyCharDriver *s = chr-opaque; -GPollFD pfd; - -pfd.fd = g_io_channel_unix_get_fd(s-fd); -pfd.events = G_IO_OUT; -pfd.revents = 0; -g_poll(pfd, 1, 0); -if (pfd.revents G_IO_HUP) { -pty_chr_state(chr, 0); -} else { -pty_chr_state(chr, 1); -} -} - static void pty_chr_state(CharDriverState *chr, int connected) { PtyCharDriver *s = chr-opaque; -- 1.9.3
[Qemu-devel] [PATCH 2.1 36/36] monitor: protect event emission
Event emission must be protected by a mutex because of access to the shared rate-limiting state, and to guard against concurrent monitor hot-plug by means of human-monitor-command. Reviewed-by: Luiz Capitulino lcapitul...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- monitor.c | 16 1 file changed, 16 insertions(+) diff --git a/monitor.c b/monitor.c index 2b97e4e..38a64a3 100644 --- a/monitor.c +++ b/monitor.c @@ -217,6 +217,9 @@ struct Monitor { /* QMP checker flags */ #define QMP_ACCEPT_UNKNOWNS 1 +/* Protects mon_list, monitor_event_state. */ +static QemuMutex monitor_lock; + static QLIST_HEAD(mon_list, Monitor) mon_list; static QLIST_HEAD(mon_fdsets, MonFdset) mon_fdsets; static int mon_refcount; @@ -465,6 +468,7 @@ static MonitorQAPIEventState monitor_qapi_event_state[QAPI_EVENT_MAX]; /* * Emits the event to every monitor instance, @event is only used for trace + * Called with monitor_lock held. */ static void monitor_qapi_event_emit(QAPIEvent event, QObject *data) { @@ -497,6 +501,7 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *data, Error **errp) now); /* Rate limit of 0 indicates no throttling */ +qemu_mutex_lock(monitor_lock); if (!evstate-rate) { monitor_qapi_event_emit(event, QOBJECT(data)); evstate-last = now; @@ -521,6 +526,7 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *data, Error **errp) evstate-last = now; } } +qemu_mutex_unlock(monitor_lock); } /* @@ -536,12 +542,14 @@ static void monitor_qapi_event_handler(void *opaque) evstate-data, evstate-last, now); +qemu_mutex_lock(monitor_lock); if (evstate-data) { monitor_qapi_event_emit(evstate-event, evstate-data); qobject_decref(evstate-data); evstate-data = NULL; } evstate-last = now; +qemu_mutex_unlock(monitor_lock); } /* @@ -5285,6 +5293,11 @@ static void monitor_readline_flush(void *opaque) monitor_flush(opaque); } +static void __attribute__((constructor)) monitor_lock_init(void) +{ +qemu_mutex_init(monitor_lock); +} + void monitor_init(CharDriverState *chr, int flags) { static int is_first_init = 1; @@ -5322,7 +5335,10 @@ void monitor_init(CharDriverState *chr, int flags) monitor_event, mon); } +qemu_mutex_lock(monitor_lock); QLIST_INSERT_HEAD(mon_list, mon, entry); +qemu_mutex_unlock(monitor_lock); + if (!default_mon || (flags MONITOR_IS_DEFAULT)) default_mon = mon; } -- 1.9.3
Re: [Qemu-devel] [PATCH v4 2/4] qtest: introduce qmp_exec_hmp_cmd()
Il 18/06/2014 08:29, Amos Kong ha scritto: Instead of adding g_strescape everywhere, we should use json-parser's own interpolation support. See this patch: http://article.gmane.org/gmane.comp.emulators.qemu/279836 which also fixes a leak as a bonus. Also, you can use ' instead of if you fix another long-standing bug: http://article.gmane.org/gmane.comp.emulators.qemu/279835 I will use ' instead of , and escape string in QMP command as http://article.gmane.org/gmane.comp.emulators.qemu/279836 Thanks Amos! This will avoid duplicating work as well as semantic conflicts. I've added your Reviewed-by for the lexer patch. Paolo
[Qemu-devel] [PATCH 2.1 19/36] qapi event: convert DEVICE_DELETED
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 18 -- hw/core/qdev.c | 12 ++-- qapi-event.json | 16 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index df15dc8..fda68df 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -158,24 +158,6 @@ Example: Note: The ready to complete status is always reset by a BLOCK_JOB_ERROR event. -DEVICE_DELETED --- - -Emitted whenever the device removal completion is acknowledged -by the guest. -At this point, it's safe to reuse the specified device ID. -Device removal can be initiated by the guest or by HMP/QMP commands. - -Data: - -- device: device name (json-string, optional) -- path: device path (json-string) - -{ event: DEVICE_DELETED, - data: { device: virtio-net-pci-0, -path: /machine/peripheral/virtio-net-pci-0 }, - timestamp: { seconds: 1265044230, microseconds: 450486 } } - DEVICE_TRAY_MOVED - diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e65a5aa..cbe8bdd 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -32,8 +32,8 @@ #include qapi/qmp/qerror.h #include qapi/visitor.h #include qapi/qmp/qjson.h -#include monitor/monitor.h #include hw/hotplug.h +#include qapi-event.h int qdev_hotplug = 0; static bool qdev_hot_added = false; @@ -939,7 +939,6 @@ static void device_unparent(Object *obj) { DeviceState *dev = DEVICE(obj); BusState *bus; -QObject *event_data; bool have_realized = dev-realized; if (dev-realized) { @@ -959,14 +958,7 @@ static void device_unparent(Object *obj) if (have_realized) { gchar *path = object_get_canonical_path(OBJECT(dev)); -if (dev-id) { -event_data = qobject_from_jsonf({ 'device': %s, 'path': %s }, -dev-id, path); -} else { -event_data = qobject_from_jsonf({ 'path': %s }, path); -} -monitor_protocol_event(QEVENT_DEVICE_DELETED, event_data); -qobject_decref(event_data); +qapi_event_send_device_deleted(!!dev-id, dev-id, path, error_abort); g_free(path); } } diff --git a/qapi-event.json b/qapi-event.json index e7dbfab..c880d77 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -106,3 +106,19 @@ ## { 'event': 'WATCHDOG', 'data': { 'action': 'WatchdogExpirationAction' } } + +## +# @DEVICE_DELETED +# +# Emitted whenever the device removal completion is acknowledged by the guest. +# At this point, it's safe to reuse the specified device ID. Device removal can +# be initiated by the guest or by HMP/QMP commands. +# +# @device: #optional, device name +# +# @path: device path +# +# Since: 1.5 +## +{ 'event': 'DEVICE_DELETED', + 'data': { '*device': 'str', 'path': 'str' } } -- 1.9.3
Re: [Qemu-devel] [PATCH 5/5] mc146818rtc: add rtc link to /machine
Il 17/06/2014 19:38, Andreas Färber ha scritto: Am 17.06.2014 19:30, schrieb Paolo Bonzini: Il 17/06/2014 19:09, Andreas Färber ha scritto: Or at least give the rtc node a more generic property type for ABI stability? I.e. you only want date here, not any other properties of the mc146818rtc. The idea is to make a few selected properties well-known and link to them via aliases, in this case date from /machine/rtc is the well-known property. Now I'm confused. Then why not just alias date onto /machine? Because we hadn't thought of it? :) If that's fine for you, all the better. So rtc.date would be aliased as /machine.rtc_date. Works for me. Paolo
[Qemu-devel] [PATCH] virtio: move common virtio properties to bus class device
The two common virtio features can be defined per bus, so move all into bus class device to make code more clean. As discussed with cornelia, s390-virtio-blk doesn't support the two features at all, so keep s390-virtio as it. Acked-by: Cornelia Huck cornelia.h...@de.ibm.com #for s390 ccw Suggested-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Ming Lei ming@canonical.com --- hw/s390x/s390-virtio-bus.c |2 ++ hw/s390x/virtio-ccw.c | 11 ++- hw/virtio/virtio-pci.c | 12 ++-- include/hw/virtio/virtio-blk.h |3 --- include/hw/virtio/virtio-net.h |1 - include/hw/virtio/virtio-scsi.h |1 - 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 9c71afa..921cdc2 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -504,6 +504,7 @@ static unsigned virtio_s390_get_features(DeviceState *d) static Property s390_virtio_net_properties[] = { DEFINE_NIC_PROPERTIES(VirtIONetS390, vdev.nic_conf), +DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features), DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features), DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetS390, vdev.net_conf), DEFINE_PROP_END_OF_LIST(), @@ -631,6 +632,7 @@ static const TypeInfo virtio_s390_device_info = { static Property s390_virtio_scsi_properties[] = { DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.parent_obj.conf), +DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features), DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 2bf0af8..c0124e1 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1126,7 +1126,6 @@ static const TypeInfo virtio_ccw_net = { static Property virtio_ccw_blk_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), -DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]), DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), @@ -1158,7 +1157,6 @@ static const TypeInfo virtio_ccw_blk = { static Property virtio_ccw_serial_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial), -DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_END_OF_LIST(), @@ -1185,7 +1183,6 @@ static const TypeInfo virtio_ccw_serial = { static Property virtio_ccw_balloon_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), -DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_END_OF_LIST(), @@ -1242,7 +1239,6 @@ static const TypeInfo virtio_ccw_scsi = { static Property vhost_ccw_scsi_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf), -DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]), DEFINE_PROP_END_OF_LIST(), }; @@ -1279,7 +1275,6 @@ static void virtio_ccw_rng_instance_init(Object *obj) static Property virtio_ccw_rng_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), -DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]), DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), @@ -1345,10 +1340,16 @@ static int virtio_ccw_busdev_unplug(DeviceState *dev) return 0; } +static Property virtio_ccw_properties[] = { +DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]), +DEFINE_PROP_END_OF_LIST(), +}; + static void virtio_ccw_device_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); +dc-props = virtio_ccw_properties; dc-init = virtio_ccw_busdev_init; dc-exit = virtio_ccw_busdev_exit; dc-unplug = virtio_ccw_busdev_unplug; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index b437f19..af2e1c3 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -917,7 +917,6 @@ static Property virtio_9p_pci_properties[] = { DEFINE_PROP_BIT(ioeventfd, VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32(vectors, VirtIOPCIProxy, nvectors, 2), -DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), DEFINE_VIRTIO_9P_PROPERTIES(V9fsPCIState, vdev.fsconf), DEFINE_PROP_END_OF_LIST(), }; @@ -1038,11 +1037,17 @@
[Qemu-devel] [PATCH 2.1 14/36] qapi event: convert SUSPEND
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- docs/qmp/qmp-events.txt | 12 qapi-event.json | 10 ++ vl.c| 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index cda67d4..d86a077 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -342,18 +342,6 @@ Example: channel-id: 0, tls: true} }} -SUSPEND - -Emitted when guest enters S3 state. - -Data: None. - -Example: - -{ event: SUSPEND, - timestamp: { seconds: 1344456160, microseconds: 309119 } } - SUSPEND_DISK diff --git a/qapi-event.json b/qapi-event.json index ac903ef..d45b341 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -47,3 +47,13 @@ # Since: 0.12.0 ## { 'event': 'RESUME' } + +## +# @SUSPEND +# +# Emitted when guest enters a hardware suspension state, for example, S3 state, +# which is sometimes called standby state +# +# Since: 1.1 +## +{ 'event': 'SUSPEND' } diff --git a/vl.c b/vl.c index 3d56d40..107176c 100644 --- a/vl.c +++ b/vl.c @@ -1928,7 +1928,7 @@ static void qemu_system_suspend(void) pause_all_vcpus(); notifier_list_notify(suspend_notifiers, NULL); runstate_set(RUN_STATE_SUSPENDED); -monitor_protocol_event(QEVENT_SUSPEND, NULL); +qapi_event_send_suspend(error_abort); } void qemu_system_suspend_request(void) -- 1.9.3
[Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- block.c | 36 blockjob.c| 6 +- docs/qmp/qmp-events.txt | 47 --- include/block/block_int.h | 3 --- qapi-schema.json | 14 ++ qapi/block-core.json | 39 +++ 6 files changed, 62 insertions(+), 83 deletions(-) diff --git a/block.c b/block.c index 0d0e5cd..041f17a 100644 --- a/block.c +++ b/block.c @@ -24,7 +24,6 @@ #include config-host.h #include qemu-common.h #include trace.h -#include monitor/monitor.h #include block/block_int.h #include block/blockjob.h #include qemu/module.h @@ -2133,36 +2132,6 @@ void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, bs-dev_opaque = opaque; } -void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv, - enum MonitorEvent ev, - BlockErrorAction action, bool is_read) -{ -QObject *data; -const char *action_str; - -switch (action) { -case BLOCK_ERROR_ACTION_REPORT: -action_str = report; -break; -case BLOCK_ERROR_ACTION_IGNORE: -action_str = ignore; -break; -case BLOCK_ERROR_ACTION_STOP: -action_str = stop; -break; -default: -abort(); -} - -data = qobject_from_jsonf({ 'device': %s, 'action': %s, 'operation': %s }, - bdrv-device_name, - action_str, - is_read ? read : write); -monitor_protocol_event(ev, data); - -qobject_decref(data); -} - static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load) { if (bs-dev_ops bs-dev_ops-change_media_cb) { @@ -3619,7 +3588,10 @@ void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action, bool is_read, int error) { assert(error = 0); -bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, is_read); +qapi_event_send_block_io_error(bdrv_get_device_name(bs), + is_read ? IO_OPERATION_TYPE_READ : + IO_OPERATION_TYPE_WRITE, + action, error_abort); if (action == BLOCK_ERROR_ACTION_STOP) { vm_stop(RUN_STATE_IO_ERROR); bdrv_iostatus_set_err(bs, error); diff --git a/blockjob.c b/blockjob.c index bc63d42..ee2a6fb 100644 --- a/blockjob.c +++ b/blockjob.c @@ -34,6 +34,7 @@ #include block/coroutine.h #include qmp-commands.h #include qemu/timer.h +#include qapi-event.h void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs, int64_t speed, BlockDriverCompletionFunc *cb, @@ -277,7 +278,10 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs, default: abort(); } -bdrv_emit_qmp_error_event(job-bs, QEVENT_BLOCK_JOB_ERROR, action, is_read); +qapi_event_send_block_job_error(bdrv_get_device_name(bs), +is_read ? IO_OPERATION_TYPE_READ : +IO_OPERATION_TYPE_WRITE, +action, error_abort); if (action == BLOCK_ERROR_ACTION_STOP) { block_job_pause(job); block_job_iostatus_set_err(job, error); diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 1ee6f53..f67a9ec 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -40,31 +40,6 @@ Example: size: 65536 }, timestamp: { seconds: 1378126126, microseconds: 966463 } } -BLOCK_IO_ERROR --- - -Emitted when a disk I/O error occurs. - -Data: - -- device: device name (json-string) -- operation: I/O operation (json-string, read or write) -- action: action that has been taken, it's one of the following (json-string): -ignore: error has been ignored -report: error has been reported to the device -stop: error caused VM to be stopped - -Example: - -{ event: BLOCK_IO_ERROR, -data: { device: ide0-hd1, - operation: write, - action: stop }, -timestamp: { seconds: 1265044230, microseconds: 450486 } } - -Note: If action is stop, a STOP event will eventually follow the -BLOCK_IO_ERROR event. - BLOCK_JOB_CANCELLED --- @@ -118,28 +93,6 @@ Example: speed: 0 }, timestamp: { seconds: 1267061043, microseconds: 959568 } } -BLOCK_JOB_ERROR - -Emitted when a block job encounters an error. - -Data: - -- device: device name (json-string) -- operation: I/O operation (json-string, read or write) -- action: action that has been taken, it's one of the following (json-string): -ignore: error has been ignored, the job may fail later -report: error will be reported
[Qemu-devel] [PATCH 2.1 06/36] qapi: adjust existing defines
From: Wenchao Xia wenchaoq...@gmail.com In order to let event defines use existing types later, instead of redefine new ones, some old type defines for spice and vnc are changed, and BlockErrorAction is moved from block.h to qapi schema. Note that BlockErrorAction is not merged with BlockdevOnError. At this point, VncInfo is not made a child of VncBasicInfo, because VncBasicInfo has mandatory fields where VncInfo makes them optional. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- block.c| 17 block/backup.c | 2 +- block/mirror.c | 7 ++-- block/stream.c | 4 +- blockjob.c | 11 ++--- hmp.c | 5 ++- hw/block/virtio-blk.c | 6 +-- hw/ide/core.c | 6 +-- hw/scsi/scsi-disk.c| 6 +-- include/block/block.h | 4 -- include/qemu/sockets.h | 2 + qapi-schema.json | 110 ++--- qapi/block-core.json | 16 +++ ui/spice-core.c| 7 ++-- ui/vnc.c | 9 ++-- util/qemu-sockets.c| 10 + 16 files changed, 156 insertions(+), 66 deletions(-) diff --git a/block.c b/block.c index 43abe96..b31d546 100644 --- a/block.c +++ b/block.c @@ -2140,13 +2140,13 @@ void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv, const char *action_str; switch (action) { -case BDRV_ACTION_REPORT: +case BLOCK_ERROR_ACTION_REPORT: action_str = report; break; -case BDRV_ACTION_IGNORE: +case BLOCK_ERROR_ACTION_IGNORE: action_str = ignore; break; -case BDRV_ACTION_STOP: +case BLOCK_ERROR_ACTION_STOP: action_str = stop; break; default: @@ -3606,13 +3606,14 @@ BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int e switch (on_err) { case BLOCKDEV_ON_ERROR_ENOSPC: -return (error == ENOSPC) ? BDRV_ACTION_STOP : BDRV_ACTION_REPORT; +return (error == ENOSPC) ? + BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT; case BLOCKDEV_ON_ERROR_STOP: -return BDRV_ACTION_STOP; +return BLOCK_ERROR_ACTION_STOP; case BLOCKDEV_ON_ERROR_REPORT: -return BDRV_ACTION_REPORT; +return BLOCK_ERROR_ACTION_REPORT; case BLOCKDEV_ON_ERROR_IGNORE: -return BDRV_ACTION_IGNORE; +return BLOCK_ERROR_ACTION_IGNORE; default: abort(); } @@ -3627,7 +3628,7 @@ void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action, { assert(error = 0); bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, is_read); -if (action == BDRV_ACTION_STOP) { +if (action == BLOCK_ERROR_ACTION_STOP) { vm_stop(RUN_STATE_IO_ERROR); bdrv_iostatus_set_err(bs, error); } diff --git a/block/backup.c b/block/backup.c index 15a2e55..7978ae2 100644 --- a/block/backup.c +++ b/block/backup.c @@ -325,7 +325,7 @@ static void coroutine_fn backup_run(void *opaque) /* Depending on error action, fail now or retry cluster */ BlockErrorAction action = backup_error_action(job, error_is_read, -ret); -if (action == BDRV_ACTION_REPORT) { +if (action == BLOCK_ERROR_ACTION_REPORT) { break; } else { start--; diff --git a/block/mirror.c b/block/mirror.c index 94c8661..df58aea 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -118,7 +118,7 @@ static void mirror_write_complete(void *opaque, int ret) bdrv_set_dirty(source, op-sector_num, op-nb_sectors); action = mirror_error_action(s, false, -ret); -if (action == BDRV_ACTION_REPORT s-ret = 0) { +if (action == BLOCK_ERROR_ACTION_REPORT s-ret = 0) { s-ret = ret; } } @@ -135,7 +135,7 @@ static void mirror_read_complete(void *opaque, int ret) bdrv_set_dirty(source, op-sector_num, op-nb_sectors); action = mirror_error_action(s, true, -ret); -if (action == BDRV_ACTION_REPORT s-ret = 0) { +if (action == BLOCK_ERROR_ACTION_REPORT s-ret = 0) { s-ret = ret; } @@ -415,7 +415,8 @@ static void coroutine_fn mirror_run(void *opaque) trace_mirror_before_flush(s); ret = bdrv_flush(s-target); if (ret 0) { -if (mirror_error_action(s, false, -ret) == BDRV_ACTION_REPORT) { +if (mirror_error_action(s, false, -ret) == +BLOCK_ERROR_ACTION_REPORT) { goto immediate_exit; } } else { diff --git a/block/stream.c b/block/stream.c index 91d18a2..0433409 100644 --- a/block/stream.c +++ b/block/stream.c @@ -159,14 +159,14 @@ wait: BlockErrorAction action = block_job_error_action(s-common, s-common.bs, s-on_error,
[Qemu-devel] [PATCH 2.1 05/36] test: add test cases for qapi event
From: Wenchao Xia wenchaoq...@gmail.com These cases will verify whether the expected qdict is built. Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- tests/Makefile | 16 +- tests/qapi-schema/qapi-schema-test.json | 12 ++ tests/qapi-schema/qapi-schema-test.out | 10 +- tests/test-qmp-event.c | 265 4 files changed, 298 insertions(+), 5 deletions(-) create mode 100644 tests/test-qmp-event.c diff --git a/tests/Makefile b/tests/Makefile index 4bb63a6..d0f5e5a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -27,6 +27,8 @@ check-unit-y += tests/test-string-input-visitor$(EXESUF) gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c check-unit-y += tests/test-string-output-visitor$(EXESUF) gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c +check-unit-y += tests/test-qmp-event$(EXESUF) +gcov-files-test-qmp-event-y += qapi/qmp-event.c check-unit-y += tests/test-opts-visitor$(EXESUF) gcov-files-test-opts-visitor-y = qapi/opts-visitor.c check-unit-y += tests/test-coroutine$(EXESUF) @@ -200,7 +202,8 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \ include-nested-err.json include-self-cycle.json include-cycle.json \ include-repetition.json event-nest-struct.json) -GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h +GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h \ + tests/test-qmp-commands.h tests/test-qapi-event.h test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/check-qlist.o tests/check-qfloat.o tests/check-qjson.o \ @@ -209,9 +212,10 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \ tests/test-qmp-commands.o tests/test-visitor-serialization.o \ tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \ - tests/test-opts-visitor.o + tests/test-opts-visitor.o tests/test-qmp-event.o -test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o +test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \ + tests/test-qapi-event.o $(test-obj-y): QEMU_INCLUDES += -Itests QEMU_CFLAGS += -I$(SRC_PATH)/tests @@ -263,9 +267,15 @@ $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-com $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \ $(gen-out-type) -o tests -p test- -i $, \ GEN $@) +tests/test-qapi-event.c tests/test-qapi-event.h :\ +$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-event.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \ + $(gen-out-type) -o tests -p test- -i $, \ + GEN $@) tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a +tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-qmp-output-visitor$(EXESUF): tests/test-qmp-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 818c06d..ab4d3d9 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -89,3 +89,15 @@ '*u16' : [ 'uint16' ], '*i64x': 'int' , '*u64x': 'uint64' } } + +# testing event +{ 'type': 'EventStructOne', + 'data': { 'struct1': 'UserDefOne', 'string': 'str', '*enum2': 'EnumOne' } } + +{ 'event': 'EVENT_A' } +{ 'event': 'EVENT_B', + 'data': { } } +{ 'event': 'EVENT_C', + 'data': { '*a': 'int', '*b': 'UserDefOne', 'c': 'str' } } +{ 'event': 'EVENT_D', + 'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 6cd03f3..95e9899 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -15,7 +15,12 @@ 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'),
[Qemu-devel] [PATCH 2.1 22/36] qapi event: convert BLOCK_IMAGE_CORRUPTED
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- block/qcow2-refcount.c | 14 -- docs/qmp/qmp-events.txt | 22 -- qapi/block-core.json| 24 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 9507aef..cc6cf74 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -27,6 +27,7 @@ #include block/qcow2.h #include qemu/range.h #include qapi/qmp/types.h +#include qapi-event.h static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size); static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, @@ -1807,7 +1808,6 @@ int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset, } else if (ret 0) { int metadata_ol_bitnr = ffs(ret) - 1; char *message; -QObject *data; assert(metadata_ol_bitnr QCOW2_OL_MAX_BITNR); @@ -1816,12 +1816,14 @@ int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset, metadata_ol_names[metadata_ol_bitnr]); message = g_strdup_printf(Prevented %s overwrite, metadata_ol_names[metadata_ol_bitnr]); -data = qobject_from_jsonf({ 'device': %s, 'msg': %s, 'offset': % -PRId64 , 'size': % PRId64 }, bs-device_name, message, -offset, size); -monitor_protocol_event(QEVENT_BLOCK_IMAGE_CORRUPTED, data); +qapi_event_send_block_image_corrupted(bdrv_get_device_name(bs), + message, + true, + offset, + true, + size, + error_abort); g_free(message); -qobject_decref(data); qcow2_mark_corrupt(bs); bs-drv = NULL; /* make BDS unusable */ diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index f67a9ec..eec3955 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -18,28 +18,6 @@ Example: data: { actual: 944766976 }, timestamp: { seconds: 1267020223, microseconds: 435656 } } -BLOCK_IMAGE_CORRUPTED -- - -Emitted when a disk image is being marked corrupt. - -Data: - -- device: Device name (json-string) -- msg:Informative message (e.g., reason for the corruption) (json-string) -- offset: If the corruption resulted from an image access, this is the access -offset into the image (json-int) -- size: If the corruption resulted from an image access, this is the access -size (json-int) - -Example: - -{ event: BLOCK_IMAGE_CORRUPTED, -data: { device: ide0-hd0, -msg: Prevented active L1 table overwrite, offset: 196608, -size: 65536 }, -timestamp: { seconds: 1378126126, microseconds: 966463 } } - BLOCK_JOB_CANCELLED --- diff --git a/qapi/block-core.json b/qapi/block-core.json index 682864d..2dbac42 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1429,6 +1429,30 @@ ## +# @BLOCK_IMAGE_CORRUPTED +# +# Emitted when a disk image is being marked corrupt +# +# @device: device name +# +# @msg: informative message for human consumption, such as the kind of +# corruption being detected +# +# @offset: #optional, if the corruption resulted from an image access, this is +# the access offset into the image +# +# @size: #optional, if the corruption resulted from an image access, this is +#the access size +# +# Since: 1.7 +## +{ 'event': 'BLOCK_IMAGE_CORRUPTED', + 'data': { 'device' : 'str', +'msg': 'str', +'*offset': 'int', +'*size' : 'int' } } + +## # @BLOCK_IO_ERROR # # Emitted when a disk I/O error occurs -- 1.9.3
Re: [Qemu-devel] [PATCH] libqtest: escape strings in QMP commands, fix leak
- Fixed Andreas's mail address On Fri, Jun 13, 2014 at 10:15:00AM +0200, Paolo Bonzini wrote: libqtest is using g_strdup_printf to format QMP commands, but this does not work if the argument strings need to be escaped. Instead, use the fancy %-formatting functionality of QObject. The only change required in tests is that strings have to be formatted as %s, not '%s' or \%s\. Luckily this usage of parameterized QMP commands is not that frequent. I got this error when I apply this patch (it works without this patch): {error: {class: GenericError, desc: Parameter 'id' expects an identifier}} Code: |QDict *response; |int i, j; | |/* start with no network/block device, slots 3 to 0x1f are free */ |qtest_start(-net none); | |for (i = 3; i = 0x1f; i++) { |for (j = 7; j = 0; j--) { |response = qmp({ 'execute': 'blockdev-add', |'arguments': { | 'options': { |'driver': 'file', |'filename': '/dev/null', |'id': 'drv-%x.%x' ^ | } } }, i, j); |g_assert(response); |g_assert(!qdict_haskey(response, error)); |QDECREF(response); Then I have to fix it by : /* start with no network/block device, slots 3 to 0x1f are free */ qtest_start(-net none); for (i = 3; i = 0x1f; i++) { for (j = 7; j = 0; j--) { +sprintf(drive_id, drv-%x.%x, i, j); response = qmp({ 'execute': 'blockdev-add', 'arguments': { 'options': { 'driver': 'file', 'filename': '/dev/null', -'id': 'drv-%x.%x' - } } }, i, j); +'id': %s + } } }, drive_id); Is it the expected result? Thanks, Amos The leak is in socket_sendf. Since we are extracting the send loop to a new function, fix it now. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- tests/fdc-test.c| 2 +- tests/libqtest.c| 47 +-- tests/qom-test.c| 6 +++--- tests/tmp105-test.c | 4 ++-- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/tests/fdc-test.c b/tests/fdc-test.c index 37096dc..c8e1e7b 100644 --- a/tests/fdc-test.c +++ b/tests/fdc-test.c @@ -291,7 +291,7 @@ static void test_media_insert(void) /* Insert media in drive. DSKCHK should not be reset until a step pulse * is sent. */ qmp_discard_response({'execute':'change', 'arguments':{ - 'device':'floppy0', 'target': '%s' }}, + 'device':'floppy0', 'target': %s }}, test_image); qmp_discard_response(); /* ignore event (FIXME open - open transition?!) */ diff --git a/tests/libqtest.c b/tests/libqtest.c index 71468ac..98e8f4b 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -30,8 +30,9 @@ #include qemu/compiler.h #include qemu/osdep.h -#include qapi/qmp/json-streamer.h #include qapi/qmp/json-parser.h +#include qapi/qmp/json-streamer.h +#include qapi/qmp/qjson.h #define MAX_IRQ 256 #define SOCKET_TIMEOUT 5 @@ -220,19 +221,15 @@ void qtest_quit(QTestState *s) g_free(s); } -static void socket_sendf(int fd, const char *fmt, va_list ap) +static void socket_send(int fd, const char *buf, size_t size) { -gchar *str; -size_t size, offset; - -str = g_strdup_vprintf(fmt, ap); -size = strlen(str); +size_t offset; offset = 0; while (offset size) { ssize_t len; -len = write(fd, str + offset, size - offset); +len = write(fd, buf + offset, size - offset); if (len == -1 errno == EINTR) { continue; } @@ -244,6 +241,15 @@ static void socket_sendf(int fd, const char *fmt, va_list ap) } } +static void socket_sendf(int fd, const char *fmt, va_list ap) +{ +gchar *str = g_strdup_vprintf(fmt, ap); +size_t size = strlen(str); + +socket_send(fd, str, size); +g_free(str); +} + static void GCC_FMT_ATTR(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...) { va_list ap; @@ -378,8 +384,29 @@ QDict *qtest_qmp_receive(QTestState *s) QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap) { -/* Send QMP request */ -socket_sendf(s-qmp_fd, fmt, ap); +va_list ap_copy; +QObject *qobj; + +/* Going through qobject ensures we escape strings properly. + * This seemingly unnecessary copy is required in case va_list + * is an array type. + */ +va_copy(ap_copy, ap); +qobj = qobject_from_jsonv(fmt,
[Qemu-devel] [PATCH 2.1 27/36] qapi event: convert BALLOON_CHANGE
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- balloon.c | 13 - docs/qmp/qmp-events.txt| 17 - hw/virtio/virtio-balloon.c | 6 -- include/sysemu/balloon.h | 2 -- monitor.c | 3 +-- qapi-event.json| 13 + 6 files changed, 18 insertions(+), 36 deletions(-) diff --git a/balloon.c b/balloon.c index e321f2c..b70da4f 100644 --- a/balloon.c +++ b/balloon.c @@ -81,19 +81,6 @@ static int qemu_balloon_status(BalloonInfo *info) return 1; } -void qemu_balloon_changed(int64_t actual) -{ -QObject *data; - -data = qobject_from_jsonf({ 'actual': % PRId64 }, - actual); - -monitor_protocol_event(QEVENT_BALLOON_CHANGE, data); - -qobject_decref(data); -} - - BalloonInfo *qmp_query_balloon(Error **errp) { BalloonInfo *info; diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 4fbc3de..1b0e25f 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -1,23 +1,6 @@ QEMU Machine Protocol Events -BALLOON_CHANGE --- - -Emitted when the guest changes the actual BALLOON level. This -value is equivalent to the 'actual' field return by the -'query-balloon' command - -Data: - -- actual: actual level of the guest memory balloon in bytes (json-number) - -Example: - -{ event: BALLOON_CHANGE, -data: { actual: 944766976 }, -timestamp: { seconds: 1267020223, microseconds: 435656 } } - GUEST_PANICKED -- diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 22cd52e..2a2e58a 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -24,6 +24,7 @@ #include sysemu/kvm.h #include exec/address-spaces.h #include qapi/visitor.h +#include qapi-event.h #if defined(__linux__) #include sys/mman.h @@ -289,8 +290,9 @@ static void virtio_balloon_set_config(VirtIODevice *vdev, memcpy(config, config_data, sizeof(struct virtio_balloon_config)); dev-actual = le32_to_cpu(config.actual); if (dev-actual != oldactual) { -qemu_balloon_changed(ram_size - - ((ram_addr_t) dev-actual VIRTIO_BALLOON_PFN_SHIFT)); +qapi_event_send_balloon_change(ram_size - +((ram_addr_t) dev-actual VIRTIO_BALLOON_PFN_SHIFT), +error_abort); } } diff --git a/include/sysemu/balloon.h b/include/sysemu/balloon.h index bd9d395..0345e01 100644 --- a/include/sysemu/balloon.h +++ b/include/sysemu/balloon.h @@ -24,6 +24,4 @@ int qemu_add_balloon_handler(QEMUBalloonEvent *event_func, QEMUBalloonStatus *stat_func, void *opaque); void qemu_remove_balloon_handler(void *opaque); -void qemu_balloon_changed(int64_t actual); - #endif diff --git a/monitor.c b/monitor.c index 589ae37..e82f75e 100644 --- a/monitor.c +++ b/monitor.c @@ -616,6 +616,7 @@ static void monitor_qapi_event_init(void) /* Limit guest-triggerable events to 1 per second */ monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000); monitor_qapi_event_throttle(QAPI_EVENT_WATCHDOG, 1000); +monitor_qapi_event_throttle(QAPI_EVENT_BALLOON_CHANGE, 1000); qmp_event_set_func_emit(monitor_qapi_event_queue); } @@ -742,8 +743,6 @@ monitor_protocol_event_throttle(MonitorEvent event, * and initialize state */ static void monitor_protocol_event_init(void) { -/* Limit RTC BALLOON events to 1 per second */ -monitor_protocol_event_throttle(QEVENT_BALLOON_CHANGE, 1000); /* limit the rate of quorum events to avoid hammering the management */ monitor_protocol_event_throttle(QEVENT_QUORUM_REPORT_BAD, 1000); monitor_protocol_event_throttle(QEVENT_QUORUM_FAILURE, 1000); diff --git a/qapi-event.json b/qapi-event.json index 1e23549..07190c2 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -241,3 +241,16 @@ # Since: 1.3 ## { 'event': 'SPICE_MIGRATE_COMPLETED' } + +## +# @BALLOON_CHANGE +# +# Emitted when the guest changes the actual BALLOON level. This value is +# equivalent to the @actual field return by the 'query-balloon' command +# +# @actual: actual level of the guest memory balloon in bytes +# +# Since: 1.2 +## +{ 'event': 'BALLOON_CHANGE', + 'data': { 'actual': 'int' } } -- 1.9.3
[Qemu-devel] [PATCH 2.1 12/36] qapi event: convert STOP
From: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Wenchao Xia wenchaoq...@gmail.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- cpus.c | 5 +++-- docs/qmp/qmp-events.txt | 12 qapi-event.json | 9 + 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/cpus.c b/cpus.c index dd7ac13..87ac99f 100644 --- a/cpus.c +++ b/cpus.c @@ -25,7 +25,7 @@ /* Needed early for CONFIG_BSD etc. */ #include config-host.h -#include monitor/monitor.h +#include qapi/qmp/qerror.h #include sysemu/sysemu.h #include exec/gdbstub.h #include sysemu/dma.h @@ -38,6 +38,7 @@ #include qemu/main-loop.h #include qemu/bitmap.h #include qemu/seqlock.h +#include qapi-event.h #ifndef _WIN32 #include qemu/compatfd.h @@ -530,7 +531,7 @@ static int do_vm_stop(RunState state) pause_all_vcpus(); runstate_set(state); vm_state_notify(0, state); -monitor_protocol_event(QEVENT_STOP, NULL); +qapi_event_send_stop(error_abort); } bdrv_drain_all(); diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 20e3151..c241a07 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -354,18 +354,6 @@ Example: channel-id: 0, tls: true} }} -STOP - - -Emitted when the Virtual Machine is stopped. - -Data: None. - -Example: - -{ event: STOP, -timestamp: { seconds: 1267041730, microseconds: 281295 } } - SUSPEND --- diff --git a/qapi-event.json b/qapi-event.json index f38669d..bac7fdc 100644 --- a/qapi-event.json +++ b/qapi-event.json @@ -29,3 +29,12 @@ # Since: 0.12.0 ## { 'event': 'RESET' } + +## +# @STOP +# +# Emitted when the virtual machine is stopped +# +# Since: 0.12.0 +## +{ 'event': 'STOP' } -- 1.9.3
Re: [Qemu-devel] [PATCH v6 2/3] qapi: add const prefix to 'char *' insider c_type()
On Tue, Jun 17, 2014 at 09:51:21PM -0600, Eric Blake wrote: On 06/10/2014 05:25 AM, Amos Kong wrote: It's ugly to add const prefix for parameter type by an if statement outside c_type(). This patch adds a parameter to do it. Signed-off-by: Amos Kong ak...@redhat.com Suggested-by: Markus Armbruster arm...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Markus Armbruster arm...@redhat.com --- scripts/qapi-commands.py | 4 +--- scripts/qapi.py | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) Wenchao's series introduces another client that needs this treatment: https://lists.gnu.org/archive/html/qemu-devel/2014-06/msg01225.html Depending on what order things get merged in, you may need followup patches or conflict resolution. Thanks for the reminder. I just checked the patch, c_type() is only used once, and the output is used insider mcgen(). So it's safe to apply my patchset. diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 7d93d01..34f200a 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -29,9 +29,7 @@ def type_visitor(name): def generate_command_decl(name, args, ret_type): arglist= for argname, argtype, optional, structured in parse_args(args): -argtype = c_type(argtype) -if argtype == char *: -argtype = const char * +argtype = c_type(argtype, is_param=True) -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org -- Amos. pgpO4MiJ8WPkp.pgp Description: PGP signature
[Qemu-devel] [PATCH qom v2 0/4] QOMify IRQs
Hi Andreas and all, I have done some cleanup of your WIP IRQ QOMification and have it in a hopefully ready state. Its now link safe and the allocation/freeing process is not as complex as before. For fuller context of the motivation behind this series, please see: http://lists.gnu.org/archive/html/qemu-devel/2014-05/msg03265.html changed since v1: Fixed sh4 instance of [0] bug (Kirill review) Regards, Peter Andreas Färber (3): sdhci: Fix misuse of qemu_free_irqs() hw: Fix qemu_allocate_irqs() leaks irq: Slim conversion of qemu_irq to QOM Peter Crosthwaite (1): irq: Allocate IRQs individually hw/arm/omap1.c | 14 +++--- hw/arm/omap2.c | 2 +- hw/arm/pxa2xx.c | 4 ++-- hw/arm/spitz.c | 4 ++-- hw/arm/z2.c | 2 +- hw/char/serial-pci.c| 2 +- hw/core/irq.c | 46 +- hw/core/qdev.c | 2 +- hw/dma/omap_dma.c | 4 ++-- hw/ide/microdrive.c | 2 +- hw/ipack/ipack.c| 2 +- hw/misc/cbus.c | 6 +++--- hw/pcmcia/pxa2xx.c | 2 +- hw/sd/omap_mmc.c| 2 +- hw/sd/sdhci.c | 8 hw/sh4/sh7750.c | 3 +-- hw/timer/omap_gptimer.c | 4 ++-- include/hw/irq.h| 4 +++- 18 files changed, 63 insertions(+), 50 deletions(-) -- 2.0.0
[Qemu-devel] [PATCH qom v2 2/4] hw: Fix qemu_allocate_irqs() leaks
From: Andreas Färber afaer...@suse.de Replace qemu_allocate_irqs(foo, bar, 1)[0] with qemu_allocate_irq(foo, bar, 0). This avoids leaking the dereferenced qemu_irq *. Cc: Kirill Batuzov batuz...@ispras.ru Cc: Markus Armbruster arm...@redhat.com Cc: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andreas Färber afaer...@suse.de [PC Changes: * Applied change to instance in sh4/sh7750.c ] Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- Changed since 1: Applied change to instance in sh4/sh7750.c (Kirill review) hw/arm/omap1.c | 14 +++--- hw/arm/omap2.c | 2 +- hw/arm/pxa2xx.c | 4 ++-- hw/arm/spitz.c | 4 ++-- hw/arm/z2.c | 2 +- hw/core/irq.c | 4 ++-- hw/dma/omap_dma.c | 4 ++-- hw/ide/microdrive.c | 2 +- hw/misc/cbus.c | 6 +++--- hw/pcmcia/pxa2xx.c | 2 +- hw/sd/omap_mmc.c| 2 +- hw/sd/sdhci.c | 4 ++-- hw/sh4/sh7750.c | 3 +-- hw/timer/omap_gptimer.c | 4 ++-- 14 files changed, 28 insertions(+), 29 deletions(-) diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index b28e052..e7cc5d7 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -172,7 +172,7 @@ static void omap_timer_clk_update(void *opaque, int line, int on) static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer) { omap_clk_adduser(timer-clk, -qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]); +qemu_allocate_irq(omap_timer_clk_update, timer, 0)); timer-rate = omap_clk_getrate(timer-clk); } @@ -2098,7 +2098,7 @@ static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory, omap-mpuio, 0x800); memory_region_add_subregion(memory, base, s-iomem); -omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]); +omap_clk_adduser(clk, qemu_allocate_irq(omap_mpuio_onoff, s, 0)); return s; } @@ -2401,7 +2401,7 @@ static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory, omap-pwl, 0x800); memory_region_add_subregion(system_memory, base, s-iomem); -omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]); +omap_clk_adduser(clk, qemu_allocate_irq(omap_pwl_clk_update, s, 0)); return s; } @@ -3485,8 +3485,8 @@ static void omap_mcbsp_i2s_start(void *opaque, int line, int level) void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave) { s-codec = slave; -slave-rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0]; -slave-tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0]; +slave-rx_swallow = qemu_allocate_irq(omap_mcbsp_i2s_swallow, s, 0); +slave-tx_start = qemu_allocate_irq(omap_mcbsp_i2s_start, s, 0); } /* LED Pulse Generators */ @@ -3634,7 +3634,7 @@ static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory, memory_region_init_io(s-iomem, NULL, omap_lpg_ops, s, omap-lpg, 0x800); memory_region_add_subregion(system_memory, base, s-iomem); -omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]); +omap_clk_adduser(clk, qemu_allocate_irq(omap_lpg_clk_update, s, 0)); return s; } @@ -3848,7 +3848,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory, s-sdram_size = sdram_size; s-sram_size = OMAP15XX_SRAM_SIZE; -s-wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0]; +s-wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0); /* Clocks */ omap_clk_init(s); diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c index 36efde0..dc53a7a 100644 --- a/hw/arm/omap2.c +++ b/hw/arm/omap2.c @@ -2260,7 +2260,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem, s-sdram_size = sdram_size; s-sram_size = OMAP242X_SRAM_SIZE; -s-wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0]; +s-wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0); /* Clocks */ omap_clk_init(s); diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index 2d28a11..557e0f1 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -2052,7 +2052,7 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space, fprintf(stderr, Unable to find CPU definition\n); exit(1); } -s-reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0]; +s-reset = qemu_allocate_irq(pxa2xx_reset, s, 0); /* SDRAM Internal Memory Storage */ memory_region_init_ram(s-sdram, NULL, pxa270.sdram, sdram_size); @@ -2183,7 +2183,7 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size) fprintf(stderr, Unable to find CPU definition\n); exit(1); } -s-reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0]; +s-reset = qemu_allocate_irq(pxa2xx_reset, s, 0); /* SDRAM Internal Memory Storage */
[Qemu-devel] [PATCH qom v2 1/4] sdhci: Fix misuse of qemu_free_irqs()
From: Andreas Färber afaer...@suse.de It does a g_free() on the pointer. Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andreas Färber afaer...@suse.de Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/sd/sdhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index e2951e6..3e13d70 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1184,8 +1184,8 @@ static void sdhci_uninitfn(Object *obj) timer_free(s-insert_timer); timer_del(s-transfer_timer); timer_free(s-transfer_timer); -qemu_free_irqs(s-eject_cb); -qemu_free_irqs(s-ro_cb); +qemu_free_irq(s-eject_cb); +qemu_free_irq(s-ro_cb); if (s-fifo_buffer) { g_free(s-fifo_buffer); -- 2.0.0
[Qemu-devel] [PATCH qom v2 3/4] irq: Allocate IRQs individually
Allocate each IRQ individually on array allocations. This prepares for QOMification of IRQs, where pointers to individual IRQs may be taken and handed around for usage as QOM Links. The g_renew scheme used here is too fragile and would break all existing links should an IRQ list be extended. We now have to pass the IRQ count to qemu_free_irqs(). We have so few call sites however, so this change is reasonably trivial. Cc: agar...@igalia.com Cc: m...@redhat.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Acked-by: Alberto Garcia agar...@igalia.com Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/char/serial-pci.c | 2 +- hw/core/irq.c| 20 +++- hw/core/qdev.c | 2 +- hw/ipack/ipack.c | 2 +- include/hw/irq.h | 2 +- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c index 6c25296..f53bb9c 100644 --- a/hw/char/serial-pci.c +++ b/hw/char/serial-pci.c @@ -152,7 +152,7 @@ static void multi_serial_pci_exit(PCIDevice *dev) g_free(pci-name[i]); } memory_region_destroy(pci-iobar); -qemu_free_irqs(pci-irqs); +qemu_free_irqs(pci-irqs, pci-ports); } static const VMStateDescription vmstate_pci_serial = { diff --git a/hw/core/irq.c b/hw/core/irq.c index 3d284c6..bc982a7 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c @@ -42,23 +42,14 @@ qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler, void *opaque, int n) { qemu_irq *s; -struct IRQState *p; int i; if (!old) { n_old = 0; } s = old ? g_renew(qemu_irq, old, n + n_old) : g_new(qemu_irq, n); -p = old ? g_renew(struct IRQState, s[0], n + n_old) : -g_new(struct IRQState, n); -for (i = 0; i n + n_old; i++) { -if (i = n_old) { -p-handler = handler; -p-opaque = opaque; -p-n = i; -} -s[i] = p; -p++; +for (i = n_old; i n + n_old; i++) { +s[i] = qemu_allocate_irq(handler, opaque, i); } return s; } @@ -80,9 +71,12 @@ qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n) return irq; } -void qemu_free_irqs(qemu_irq *s) +void qemu_free_irqs(qemu_irq *s, int n) { -g_free(s[0]); +int i; +for (i = 0; i n; i++) { +qemu_free_irq(s[i]); +} g_free(s); } diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e65a5aa..02377c7 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -916,7 +916,7 @@ static void device_finalize(Object *obj) QLIST_FOREACH_SAFE(ngl, dev-gpios, node, next) { QLIST_REMOVE(ngl, node); -qemu_free_irqs(ngl-in); +qemu_free_irqs(ngl-in, ngl-num_in); g_free(ngl-name); g_free(ngl); /* ngl-out irqs are owned by the other end and should not be freed diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c index ef032e6..59bfe28 100644 --- a/hw/ipack/ipack.c +++ b/hw/ipack/ipack.c @@ -66,7 +66,7 @@ static void ipack_device_unrealize(DeviceState *dev, Error **errp) return; } -qemu_free_irqs(idev-irq); +qemu_free_irqs(idev-irq, 2); } static Property ipack_device_props[] = { diff --git a/include/hw/irq.h b/include/hw/irq.h index d08bc02..9f34c96 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -42,7 +42,7 @@ qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n); qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler, void *opaque, int n); -void qemu_free_irqs(qemu_irq *s); +void qemu_free_irqs(qemu_irq *s, int n); void qemu_free_irq(qemu_irq irq); /* Returns a new IRQ with opposite polarity. */ -- 2.0.0
[Qemu-devel] [PATCH qom v2 4/4] irq: Slim conversion of qemu_irq to QOM
From: Andreas Färber afaer...@suse.de As a prequel to any big Pin refactoring plans, do an in-place conversion of qemu_irq to an Object, so that we can reference it in link properties. Reviewed-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andreas Färber afaer...@suse.de [ PC Changes: * Removed array-alloctor ref counting logic (limit changes just to * single IRQ allocator) * Removed WIP marking from subject line ] Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/core/irq.c| 22 -- include/hw/irq.h | 2 ++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hw/core/irq.c b/hw/core/irq.c index bc982a7..cffced0 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c @@ -23,8 +23,13 @@ */ #include qemu-common.h #include hw/irq.h +#include qom/object.h + +#define IRQ(obj) OBJECT_CHECK(struct IRQState, (obj), TYPE_IRQ) struct IRQState { +Object parent_obj; + qemu_irq_handler handler; void *opaque; int n; @@ -63,7 +68,7 @@ qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n) { struct IRQState *irq; -irq = g_new(struct IRQState, 1); +irq = IRQ(object_new(TYPE_IRQ)); irq-handler = handler; irq-opaque = opaque; irq-n = n; @@ -82,7 +87,7 @@ void qemu_free_irqs(qemu_irq *s, int n) void qemu_free_irq(qemu_irq irq) { -g_free(irq); +object_unref(OBJECT(irq)); } static void qemu_notirq(void *opaque, int line, int level) @@ -144,3 +149,16 @@ void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n qemu_irq *old_irqs = *gpio_out; *gpio_out = qemu_allocate_irqs(handler, old_irqs, n); } + +static const TypeInfo irq_type_info = { + .name = TYPE_IRQ, + .parent = TYPE_OBJECT, + .instance_size = sizeof(struct IRQState), +}; + +static void irq_register_types(void) +{ +type_register_static(irq_type_info); +} + +type_init(irq_register_types) diff --git a/include/hw/irq.h b/include/hw/irq.h index 9f34c96..6f874f5 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -3,6 +3,8 @@ /* Generic IRQ/GPIO pin infrastructure. */ +#define TYPE_IRQ irq + typedef struct IRQState *qemu_irq; typedef void (*qemu_irq_handler)(void *opaque, int n, int level); -- 2.0.0
[Qemu-devel] [PATCH v4 00/18] migration: add static analysis tool to check vmstate compat
Hello, v4: - Return value capped to 255 to prevent wrap-around (Eric Blake) v3: - Python script returns an error code: 0 if no errors, positive for the number of errors identified. v2: - Tabs-spaces (Dave Gilbert) - Several changes to the python script to make it more python-like (Vitaly Kuznetsov) - Don't store the empty fields created by VMSTATE_VALIDATE in the json output This series adds a static vmstate checker to check for breakage of live migration by analyzing the vmstate information between different QEMU versions. In patch 1, QEMU is modified to add a -dump-vmstate commandline option, which takes a filename as the argument. When invoked, QEMU dumps the vmstate info in JSON format for the current machine type to the file. This patch is loosely based on a version from Andreas Färber. This JSON file is then fed into the Python script introduced in patch 2. The script takes 'src' and 'dest' arguments, indicating the direction of migration. The script then performs a series of checks and spews out information on inconsistencies it finds in the data. Two stripped-down versions of JSON dumps are included in this patchset (patch 3). Patches 4 - 18 contain modifications to those dumps, to show the checks that are performed by the script. The result of running the script against the final version of those files is appended below. The checks are to be performed for a particular machine type, and comparing different machine types is bound to turn up false-positives: e.g. (in a qemu 2.0 tree): ./x86_64-softmmu/qemu-system-x86_64 -dump-vmstate qemu-2.0.json (in a qemu 2.2 tree:) ./x86_64-softmmu/qemu-system-x86_64 -dump-vmstate -M pc-i440fx-2.0 \ qemu-2.2-m2.0.json ./scripts/vmstate-static-checker.py -s qemu-2.0.json -d qemu-2.2-m2.0.json should not show any output. The idea is to include this script in 'make check', ensuring new commits don't break migration. Later, this script can also be baked into the release process: vmstate dumps for released versions of qemu for various machine types can be stored in a directory in the tree. At the time of freezing the tree for releases, (like -rc2), the dump for the current release can be updated. A policy that says No more live migration-breaking changes can be accepted post -rc2 can be put in place. Also, for checks for older machine types on the current tree with the saved dumps should not indicate any regressions. I expect there to be a few false positives at the start (though there aren't any right now). The script will keep evolving, though, to include new scenarios, to make it more helpful. A later project would be to also store other guest-visible information and use that output for more checks (including lspci output from inside guests). As mentioned earlier, this is the result of running the script against the sample json data included in this patchset: $ ./scripts/vmstate-static-checker.py --src ./tests/vmstate-static-checker-data/dump1.json --dest ./tests/vmstate-static-checker-data/dump2.json Section usb-kbd Description usb-kbd Field kbd.keycodes size mismatch: 4 , 2 Section PIIX3-xen Description PIIX3: minimum version error: 1 2 Section PIIX3-xen Description PIIX3: Entry Subsections missing Section tpci200: Description tpci200 missing, got tpci2002 instead; skipping Section megasas, Description PCIDevice: expected field irq_state, while dest has no further fields Section SUNW,fdtwo Description fdc: version error: 2 1 Section SUNW,fdtwo, Description fdrive: Subsection fdrive/media_rate not found Section fusbh200-ehci-usb version error: 2 1 Section fusbh200-ehci-usb, Description ehci-core: expected field usbsts, got usbsts_pending; skipping rest Section intel-hda-generic, Description intel-hda, Field pci: missing description Section cfi.pflash01: Entry Description missing Section pci-serial-4x Description pci-serial-multi: Entry Fields missing Warning: checking incompatible machine types: pc-i440fx-2.1, pc-i440fx-2.2 Section fw_cfg does not exist in dest $ echo $? 13 Amit Shah (18): migration: dump vmstate info as a json file for static analysis vmstate-static-checker: script to validate vmstate changes tests: vmstate static checker: add dump1 and dump2 files tests: vmstate static checker: incompat machine types tests: vmstate static checker: add version error in main section tests: vmstate static checker: version mismatch inside a Description tests: vmstate static checker: minimum_version_id check tests: vmstate static checker: remove a section tests: vmstate static checker: remove a field tests: vmstate static checker: remove last field in a struct tests: vmstate static checker: change description name tests: vmstate static checker: remove Fields tests: vmstate static checker: remove Description tests: vmstate static checker: remove Description inside Fields tests: vmstate static checker: remove a subsection tests: vmstate static checker: remove Subsections
[Qemu-devel] [PATCH v4 02/18] vmstate-static-checker: script to validate vmstate changes
This script compares the vmstate dumps in JSON format as output by QEMU with the -dump-vmstate option. It flags various errors, like version mismatch, sections going away, size mismatches, etc. This script is tolerant of a few changes that do not change the on-wire format, like embedding a few fields within substructs. The script takes -s/--src and -d/--dest parameters, to which filenames are given as arguments. Signed-off-by: Amit Shah amit.s...@redhat.com --- scripts/vmstate-static-checker.py | 329 ++ 1 file changed, 329 insertions(+) create mode 100755 scripts/vmstate-static-checker.py diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py new file mode 100755 index 000..cbb4c6f --- /dev/null +++ b/scripts/vmstate-static-checker.py @@ -0,0 +1,329 @@ +#!/usr/bin/python +# +# Compares vmstate information stored in JSON format, obtained from +# the -dump-vmstate QEMU command. +# +# Copyright 2014 Amit Shah amit.s...@redhat.com +# Copyright 2014 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, see http://www.gnu.org/licenses/. + +import argparse +import json +import sys + +taint = 0 + +def bump_taint(): +global taint + +# Ensure we don't wrap around or reset to 0 -- the shell only has +# an 8-bit return value. +if taint 255: +taint = taint + 1 + + +def check_fields_match(s_field, d_field): +if s_field == d_field: +return True + +# Some fields changed names between qemu versions. This list +# is used to whitelist such changes. +changed_names = [ + ['d', 'dev', 'pcidev', 'pci_dev', 'parent_obj'], + ['card', 'parent_obj'], + ['bridge.dev', 'parent_obj'], + ['br.dev', 'parent_obj.parent_obj'], + ['port.br.dev', 'parent_obj.parent_obj.parent_obj'], + ['port.br.dev.exp.aer_log', + 'parent_obj.parent_obj.parent_obj.exp.aer_log'], + ['br.dev.exp.aer_log', + 'parent_obj.parent_obj.exp.aer_log'], + ['shpc', 'bridge.dev.shpc'], + ['pci0_status', + 'acpi_pci_hotplug.acpi_pcihp_pci_status[0x0]'], + ['pci_irq_levels', 'pci_irq_levels_vmstate'], + ['usb-ptr-queue', 'HIDPointerEventQueue'], + ['num_surfaces', 'ssd.num_surfaces'], + ['timer', 'timer_expiry'], +] + +for grp in changed_names: +if s_field in grp and d_field in grp: +return True + +return False + + +def exists_in_substruct(fields, item): +# Some QEMU versions moved a few fields inside a substruct. This +# kept the on-wire format the same. This function checks if +# something got shifted inside a substruct. For example, the +# change in commit 1f42d22233b4f3d1a2933ff30e8d6a6d9ee2d08f + +if not Description in fields: +return False + +if not Fields in fields[Description]: +return False + +substruct_fields = fields[Description][Fields] + +if substruct_fields == []: +return False + +return check_fields_match(substruct_fields[0][field], item) + + +def check_fields(src_fields, dest_fields, desc, sec): +# This function checks for all the fields in a section. If some +# fields got embedded into a substruct, this function will also +# attempt to check inside the substruct. + +d_iter = iter(dest_fields) +s_iter = iter(src_fields) + +# Using these lists as stacks to store previous value of s_iter +# and d_iter, so that when time comes to exit out of a substruct, +# we can go back one level up and continue from where we left off. + +s_iter_list = [] +d_iter_list = [] + +advance_src = True +advance_dest = True + +while True: +if advance_src: +try: +s_item = s_iter.next() +except StopIteration: +if s_iter_list == []: +break + +s_iter = s_iter_list.pop() +continue +else: +# We want to avoid advancing just once -- when entering a +# substruct, or when exiting one. +advance_src = True + +if advance_dest: +try: +d_item
[Qemu-devel] [PATCH v4 01/18] migration: dump vmstate info as a json file for static analysis
This commit adds a new command, '-dump-vmstate', that takes a filename as a parameter. When executed, QEMU will dump the vmstate information for the machine type it's invoked with to the file, and quit. The JSON-format output can then be used to compare the vmstate info for different QEMU versions, specifically to test whether live migration would break due to changes in the vmstate data. A Python script that compares the output of such JSON dumps is included in the following commit. Signed-off-by: Amit Shah amit.s...@redhat.com --- include/migration/vmstate.h | 2 + qemu-options.hx | 9 +++ savevm.c| 139 vl.c| 13 + 4 files changed, 163 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 7e45048..9829c0e 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -778,4 +778,6 @@ void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev); void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev); void vmstate_register_ram_global(struct MemoryRegion *memory); +void dump_vmstate_json_to_file(FILE *out_fp); + #endif diff --git a/qemu-options.hx b/qemu-options.hx index d0714c4..48d493b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3221,6 +3221,15 @@ STEXI prepend a timestamp to each log message.(default:on) ETEXI +DEF(dump-vmstate, HAS_ARG, QEMU_OPTION_dump_vmstate, +-dump-vmstate file\n , QEMU_ARCH_ALL) +STEXI +@item -dump-vmstate @var{file} +@findex -dump-vmstate +Dump json-encoded vmstate information for current machine type to file +in @var{file} +ETEXI + HXCOMM This is the last statement. Insert new options before this line! STEXI @end table diff --git a/savevm.c b/savevm.c index da8aa24..0c8ad45 100644 --- a/savevm.c +++ b/savevm.c @@ -24,6 +24,7 @@ #include config-host.h #include qemu-common.h +#include hw/boards.h #include hw/hw.h #include hw/qdev.h #include net/net.h @@ -241,6 +242,144 @@ static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers = QTAILQ_HEAD_INITIALIZER(savevm_handlers); static int global_section_id; +static void dump_vmstate_vmsd(FILE *out_file, + const VMStateDescription *vmsd, int indent, + bool is_subsection); + +static void dump_vmstate_vmsf(FILE *out_file, const VMStateField *field, + int indent) +{ +fprintf(out_file, %*s{\n, indent, ); +indent += 2; +fprintf(out_file, %*s\field\: \%s\,\n, indent, , field-name); +fprintf(out_file, %*s\version_id\: %d,\n, indent, , +field-version_id); +fprintf(out_file, %*s\field_exists\: %s,\n, indent, , +field-field_exists ? true : false); +fprintf(out_file, %*s\size\: %zu, indent, , field-size); +if (field-vmsd != NULL) { +fprintf(out_file, ,\n); +dump_vmstate_vmsd(out_file, field-vmsd, indent, false); +} +fprintf(out_file, \n%*s}, indent - 2, ); +} + +static void dump_vmstate_vmss(FILE *out_file, + const VMStateSubsection *subsection, + int indent) +{ +if (subsection-vmsd != NULL) { +dump_vmstate_vmsd(out_file, subsection-vmsd, indent, true); +} +} + +static void dump_vmstate_vmsd(FILE *out_file, + const VMStateDescription *vmsd, int indent, + bool is_subsection) +{ +if (is_subsection) { +fprintf(out_file, %*s{\n, indent, ); +} else { +fprintf(out_file, %*s\%s\: {\n, indent, , Description); +} +indent += 2; +fprintf(out_file, %*s\name\: \%s\,\n, indent, , vmsd-name); +fprintf(out_file, %*s\version_id\: %d,\n, indent, , +vmsd-version_id); +fprintf(out_file, %*s\minimum_version_id\: %d, indent, , +vmsd-minimum_version_id); +if (vmsd-fields != NULL) { +const VMStateField *field = vmsd-fields; +bool first; + +fprintf(out_file, ,\n%*s\Fields\: [\n, indent, ); +first = true; +while (field-name != NULL) { +if (field-flags VMS_MUST_EXIST) { +/* Ignore VMSTATE_VALIDATE bits; these don't get migrated */ +field++; +continue; +} +if (!first) { +fprintf(out_file, ,\n); +} +dump_vmstate_vmsf(out_file, field, indent + 2); +field++; +first = false; +} +fprintf(out_file, \n%*s], indent, ); +} +if (vmsd-subsections != NULL) { +const VMStateSubsection *subsection = vmsd-subsections; +bool first; + +fprintf(out_file, ,\n%*s\Subsections\: [\n, indent, ); +first = true; +while (subsection-vmsd != NULL) { +if (!first) { +fprintf(out_file, ,\n); +} +
[Qemu-devel] [PATCH v4 04/18] tests: vmstate static checker: incompat machine types
This commit modifies the dump2 data to flag incompatibilities in the machine types being compared. Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 44200fb..0a8b81d 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -1,6 +1,6 @@ { vmschkmachine: { -Name: pc-i440fx-2.1 +Name: pc-i440fx-2.2 }, fw_cfg: { Name: fw_cfg, -- 1.9.3
[Qemu-devel] [PATCH v4 17/18] tests: vmstate static checker: add substructure for usb-kbd for hid section
This shows how the script deals with substructures added to vmstate descriptions that don't change the on-wire format. Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 115 +++ 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index b5cb1aa..45cccaf 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -844,7 +844,7 @@ field: dev, version_id: 0, field_exists: false, - size: 4352, + size: 5832, Description: { name: USBDevice, version_id: 1, @@ -896,58 +896,71 @@ } }, { - field: kbd.keycodes, + field: hid, version_id: 0, field_exists: false, - size: 4 -}, -{ - field: head, - version_id: 0, - field_exists: false, - size: 4 -}, -{ - field: n, - version_id: 0, - field_exists: false, - size: 4 -}, -{ - field: kbd.modifiers, - version_id: 0, - field_exists: false, - size: 2 -}, -{ - field: kbd.leds, - version_id: 0, - field_exists: false, - size: 1 -}, -{ - field: kbd.key, - version_id: 0, - field_exists: false, - size: 1 -}, -{ - field: kbd.keys, - version_id: 0, - field_exists: false, - size: 4 -}, -{ - field: protocol, - version_id: 0, - field_exists: false, - size: 4 -}, -{ - field: idle, - version_id: 0, - field_exists: false, - size: 1 + size: 312, + Description: { +name: HIDKeyboardDevice, +version_id: 1, +minimum_version_id: 1, +Fields: [ + { +field: kbd.keycodes, +version_id: 0, +field_exists: false, +size: 4 + }, + { +field: head, +version_id: 0, +field_exists: false, +size: 4 + }, + { +field: n, +version_id: 0, +field_exists: false, +size: 4 + }, + { +field: kbd.modifiers, +version_id: 0, +field_exists: false, +size: 2 + }, + { +field: kbd.leds, +version_id: 0, +field_exists: false, +size: 1 + }, + { +field: kbd.key, +version_id: 0, +field_exists: false, +size: 1 + }, + { +field: kbd.keys, +version_id: 0, +field_exists: false, +size: 4 + }, + { +field: protocol, +version_id: 0, +field_exists: false, +size: 4 + }, + { +field: idle, +version_id: 0, +field_exists: false, +size: 1 + } +] + } } ] } -- 1.9.3
[Qemu-devel] [PATCH v4 06/18] tests: vmstate static checker: version mismatch inside a Description
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index f405534..36a9b4b 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -829,7 +829,7 @@ minimum_version_id: 2, Description: { name: fdc, - version_id: 2, + version_id: 1, minimum_version_id: 2, Fields: [ { -- 1.9.3
[Qemu-devel] [PATCH v4 10/18] tests: vmstate static checker: remove last field in a struct
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 6 -- 1 file changed, 6 deletions(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index f6b52d0..34bfbf6 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -637,12 +637,6 @@ version_id: 0, field_exists: false, size: 256 - }, - { -field: irq_state, -version_id: 2, -field_exists: false, -size: 16 } ] } -- 1.9.3
[Qemu-devel] [PATCH v4 18/18] tests: vmstate static checker: add size mismatch inside substructure
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 45cccaf..75719f5 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -909,7 +909,7 @@ field: kbd.keycodes, version_id: 0, field_exists: false, -size: 4 +size: 2 }, { field: head, -- 1.9.3
[Qemu-devel] [PATCH v4 05/18] tests: vmstate static checker: add version error in main section
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 0a8b81d..f405534 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -34,7 +34,7 @@ }, fusbh200-ehci-usb: { Name: fusbh200-ehci-usb, -version_id: 2, +version_id: 1, minimum_version_id: 1, Description: { name: ehci-sysbus, -- 1.9.3
[Qemu-devel] [PATCH v4 14/18] tests: vmstate static checker: remove Description inside Fields
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 27 +-- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 66ac3bd..05b8fce 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -212,32 +212,7 @@ field: pci, version_id: 0, field_exists: false, - size: 1944, - Description: { -name: PCIDevice, -version_id: 2, -minimum_version_id: 1, -Fields: [ - { -field: version_id, -version_id: 0, -field_exists: false, -size: 4 - }, - { -field: config, -version_id: 0, -field_exists: false, -size: 256 - }, - { -field: irq_state, -version_id: 2, -field_exists: false, -size: 16 - } -] - } + size: 1944 }, { field: g_ctl, -- 1.9.3
[Qemu-devel] [PATCH v4 08/18] tests: vmstate static checker: remove a section
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 36a9b4b..4ccfd67 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -2,7 +2,7 @@ vmschkmachine: { Name: pc-i440fx-2.2 }, - fw_cfg: { + fw_cfg2: { Name: fw_cfg, version_id: 2, minimum_version_id: 1, -- 1.9.3
[Qemu-devel] [PATCH v4 12/18] tests: vmstate static checker: remove Fields
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 114 +-- 1 file changed, 1 insertion(+), 113 deletions(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index f69966d..cc0aae3 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -196,119 +196,7 @@ Description: { name: pci-serial-multi, version_id: 1, - minimum_version_id: 1, - Fields: [ -{ - field: dev, - version_id: 0, - field_exists: false, - size: 1944, - Description: { -name: PCIDevice, -version_id: 2, -minimum_version_id: 1, -Fields: [ - { -field: version_id, -version_id: 0, -field_exists: false, -size: 4 - }, - { -field: config, -version_id: 0, -field_exists: false, -size: 256 - }, - { -field: irq_state, -version_id: 2, -field_exists: false, -size: 16 - } -] - } -}, -{ - field: state, - version_id: 0, - field_exists: false, - size: 368, - Description: { -name: serial, -version_id: 3, -minimum_version_id: 2, -Fields: [ - { -field: divider, -version_id: 2, -field_exists: false, -size: 2 - }, - { -field: rbr, -version_id: 0, -field_exists: false, -size: 1 - }, - { -field: ier, -version_id: 0, -field_exists: false, -size: 1 - }, - { -field: iir, -version_id: 0, -field_exists: false, -size: 1 - }, - { -field: lcr, -version_id: 0, -field_exists: false, -size: 1 - }, - { -field: mcr, -version_id: 0, -field_exists: false, -size: 1 - }, - { -field: lsr, -version_id: 0, -field_exists: false, -size: 1 - }, - { -field: msr, -version_id: 0, -field_exists: false, -size: 1 - }, - { -field: scr, -version_id: 0, -field_exists: false, -size: 1 - }, - { -field: fcr_vmstate, -version_id: 3, -field_exists: false, -size: 1 - } -] - } -}, -{ - field: level, - version_id: 0, - field_exists: false, - size: 4 -} - ] + minimum_version_id: 1 } }, intel-hda-generic: { -- 1.9.3
[Qemu-devel] [PATCH v4 16/18] tests: vmstate static checker: remove Subsections
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 15 --- 1 file changed, 15 deletions(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 6f8a617..b5cb1aa 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -558,21 +558,6 @@ field_exists: false, size: 4 } - ], - Subsections: [ -{ - name: PIIX3/rcr, - version_id: 1, - minimum_version_id: 1, - Fields: [ -{ - field: rcr, - version_id: 0, - field_exists: false, - size: 1 -} - ] -} ] } }, -- 1.9.3
[Qemu-devel] [PATCH v4 09/18] tests: vmstate static checker: remove a field
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 6 -- 1 file changed, 6 deletions(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 4ccfd67..f6b52d0 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -58,12 +58,6 @@ size: 4 }, { -field: usbsts, -version_id: 0, -field_exists: false, -size: 4 - }, - { field: usbsts_pending, version_id: 2, field_exists: false, -- 1.9.3
[Qemu-devel] [PATCH v4 15/18] tests: vmstate static checker: remove a subsection
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 13 - 1 file changed, 13 deletions(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 05b8fce..6f8a617 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -836,19 +836,6 @@ size: 1 } ] -}, -{ - name: fdrive/media_rate, - version_id: 1, - minimum_version_id: 1, - Fields: [ -{ - field: media_rate, - version_id: 0, - field_exists: false, - size: 1 -} - ] } ] } -- 1.9.3
[Qemu-devel] [PATCH v4 13/18] tests: vmstate static checker: remove Description
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 33 +--- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index cc0aae3..66ac3bd 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -462,38 +462,7 @@ cfi.pflash01: { Name: cfi.pflash01, version_id: 1, -minimum_version_id: 1, -Description: { - name: pflash_cfi01, - version_id: 1, - minimum_version_id: 1, - Fields: [ -{ - field: wcycle, - version_id: 0, - field_exists: false, - size: 1 -}, -{ - field: cmd, - version_id: 0, - field_exists: false, - size: 1 -}, -{ - field: status, - version_id: 0, - field_exists: false, - size: 1 -}, -{ - field: counter, - version_id: 0, - field_exists: false, - size: 8 -} - ] -} +minimum_version_id: 1 }, megasas: { Name: megasas, -- 1.9.3
Re: [Qemu-devel] [PATCH] libvixl: Add gcc format attribute
On 18 June 2014 05:45, Stefan Weil s...@weilnetz.de wrote: A 32 bit build on Ubuntu gcc-4.6.3-1ubuntu5 just finished and shows the same error messages, so really all of my builds show them (32 and 64 bit, Linux native and cross for Windows). Peter, I know that libvixl is external code, but posted this patch because I need help: I simply don't know why the compiler complains and whether these errors are really errors. It's easy to fix them by using PRId64, but would that be correct? Variable arguments usually are not converted to 64 bit values: if they are smaller than int, they are expanded to int, and larger values are passed as they are. But here obviously the compiler expands uint32_t to int64_t. Why? Unfortunately I don't know the answer... I was hoping RTH did. thanks -- PMM
[Qemu-devel] [PATCH v4 11/18] tests: vmstate static checker: change description name
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/vmstate-static-checker-data/dump2.json index 34bfbf6..f69966d 100644 --- a/tests/vmstate-static-checker-data/dump2.json +++ b/tests/vmstate-static-checker-data/dump2.json @@ -749,7 +749,7 @@ version_id: 1, minimum_version_id: 1, Description: { - name: tpci200, + name: tpci2002, version_id: 1, minimum_version_id: 1, Fields: [ -- 1.9.3
Re: [Qemu-devel] [RFC] Libqos virtio API
On Tue, Jun 17, 2014 at 11:02:48AM +0200, Marc Marí wrote: This is the draft for the libqos virtio API to create test cases for virtio devices. I'm looking forward to your comments. Signed-off-by: Marc Marí marc.mari.barc...@gmail.com --- tests/libqos/virtio.h | 148 + 1 file changed, 148 insertions(+) create mode 100644 tests/libqos/virtio.h diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h new file mode 100644 index 000..03f28dc --- /dev/null +++ b/tests/libqos/virtio.h @@ -0,0 +1,148 @@ +#define VIRTQUEUE_MAX_SIZE 1024 + +struct QVirtioBus +{ +/* Send a notification IRQ to the device */ +void (*notify)(QVirtioDevice *d, uint16_t vector); Guest-host notification is not an interrupt. It's a kick that's implemented by writing to a hardware register. The argument should be the virtqueue number. + +/* Get configuration of the device */ +void (*get_config)(QVirtioDevice *d, void *config); + +/* Set configuration of the device */ +void (*set_config)(QVirtioDevice *d, void *config); + +/* Get features of the device */ +uint32_t (*get_features)(QVirtioDevice *d); + +/* Get status of the device */ +uint8_t (*get_status)(QVirtioDevice *d); + +/* Set status of the device */ +void (*set_status)(QVirtioDevice *d, uint8_t val); + +/* Reset the device */ +void (*reset)(QVirtioDevice *d); + +/* Check pending IRQs */ +uint8_t (*query_isr)(QVirtioDevice *d); Does this also clear the ISR? + +/* Loop all devices, applying a function to all, or the one specified */ +void (*device_foreach)(QVirtioBus *bus, uint16_t device_id, +void (*func)(QVirtioDevice *dev, void *data), void *data); + +/* Find and return a device */ +QVirtioDevice *(*device_find)(uint16_t device_id, int index); +}; + +QVirtioBus *qvirtio_pci_init(); +QVirtioBus *qvirtio_mmio_init(); +QVirtioBus *qvirtio_ccw_init(); In C you should always give an arguments list. Use void if there are no arguments. In C++ fn() means fn(void) but in C it means legacy KR behavior which no one uses due to lack of type-safety. I don't think it's necessary to provide a function that instantiates a QVirtioBus. QVirtioBus is just a struct of function pointers. It can be declared static const: static const QVirtioBus virtio_pci_bus = { .reset = virtio_pci_reset, ... }; + +struct QVirtioDevice +{ +/* Index in all devices of the same type in the bus */ +int index; + +/* Device type */ +uint16_t device_id; + +/* VQs associated with the device */ +QVirtQueue *vq; +}; + +/* +I'm not sure what implementation of VirtQueue is better, QEMU's or Linux's. I +think QEMU implementation is better, because it will be easier to connect the +QEMU Virtqueue with the Libaos VirtQueue. + +The functions to use the VirtQueue are the ones I think necessary in Libqos, but +probably there are some missing and some others that are not necessary. +*/ Keep in mind that QEMU only cares about popping elements off the available ring and pushing them onto the used ring. The Linux guest driver implementation is the opposite. It pushes elements onto the available ring and pops them off the used ring. If in doubt, follow the Linux implementation because you are implementing the guest side of the interface, not the host side. pgpZBDTkyFI97.pgp Description: PGP signature
[Qemu-devel] [PATCH] linux-user: added fake open() for /proc/self/cmdline
From: Wim Vander Schelden w...@fixnum.org Signed-off-by: Wim Vander Schelden w...@fixnum.org --- linux-user/syscall.c | 46 ++ 1 file changed, 46 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c134c32..1be0f09 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4947,6 +4947,51 @@ int host_to_target_waitstatus(int status) return status; } +static int open_self_cmdline(void *cpu_env, int fd) +{ +int fd_orig = -1; +bool word_skipped = false; + +fd_orig = open(/proc/self/cmdline, O_RDONLY); +if (fd_orig 0) { +return fd_orig; +} + +while (true) { +ssize_t nb_read; +char buf[128]; +char *cp_buf = buf; + +nb_read = read(fd_orig, buf, sizeof(buf)); +if (nb_read 0) { +fd_orig = close(fd_orig); +return -1; +} else if (nb_read == 0) { +break; +} + +if (!word_skipped) { +/* Skip the first string, which is the path to qemu-*-static + instead of the actual command. */ +cp_buf = memchr(buf, 0, sizeof(buf)); +if (cp_buf) { +/* Null byte found, skip one string */ +cp_buf++; +nb_read -= cp_buf - buf; +word_skipped = true; +} +} + +if (word_skipped) { +if (write(fd, cp_buf, nb_read) != nb_read) { +return -1; +} +} +} + +return close(fd_orig); +} + static int open_self_maps(void *cpu_env, int fd) { #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32) @@ -5148,6 +5193,7 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode) { maps, open_self_maps, is_proc_myself }, { stat, open_self_stat, is_proc_myself }, { auxv, open_self_auxv, is_proc_myself }, +{ cmdline, open_self_cmdline, is_proc_myself }, #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) { /proc/net/route, open_net_route, is_proc }, #endif -- 1.9.1
Re: [Qemu-devel] [PATCH] linux-user: added fake open() for /proc/self/cmdline
Hi Eric, Thanks for your feedback. I've addressed the issues you mentioned and verified the patch with checkpatch.pl. The updated patch follows. Kind regards, Wim
[Qemu-devel] [PATCH v4 07/18] tests: vmstate static checker: minimum_version_id check
Signed-off-by: Amit Shah amit.s...@redhat.com --- tests/vmstate-static-checker-data/dump1.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vmstate-static-checker-data/dump1.json b/tests/vmstate-static-checker-data/dump1.json index 44200fb..786ca0b 100644 --- a/tests/vmstate-static-checker-data/dump1.json +++ b/tests/vmstate-static-checker-data/dump1.json @@ -698,7 +698,7 @@ minimum_version_id: 2, Description: { name: PIIX3, - version_id: 3, + version_id: 1, minimum_version_id: 2, Fields: [ { -- 1.9.3
Re: [Qemu-devel] [PATCH] pc: acpi-build: make linker RSDP tables dynamic
On Tue, 2014-06-17 at 23:19 +0300, Michael S. Tsirkin wrote: On Tue, Jun 17, 2014 at 10:14:01PM +0200, Igor Mammedov wrote: linker and RSDP tables are build only once, so if later during rebuild sizes of ACPI tables change pointers will be patched incorrectly due to wrong offsets. To fix it rebuild linker and RSDP tables along with the rest of ACPI tables so that they would have correct offsets. Signed-off-by: Igor Mammedov imamm...@redhat.com If you are adding a new blob you are breaking cross-version migration. Need to handle that depending on pc version as appropriate. Besides the above comment, Tested-by: Marcel Apfelbaum marce...@redhat.com Reviewed-by: Marcel Apfelbaum marce...@redhat.com Thanks, Marcel --- hw/i386/acpi-build.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index fab25ad..8301bb4 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1862,6 +1862,10 @@ struct AcpiBuildState { /* Copy of table in RAM (for patching). */ uint8_t *table_ram; uint32_t table_size; +uint8_t *linker_ram; +uint32_t linker_size; +uint8_t *rsdp_ram; +uint32_t rsdp_size; /* Is table patched? */ uint8_t patched; PcGuestInfo *guest_info; @@ -1998,6 +2002,10 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) assert(acpi_data_len(tables.table_data) == build_state-table_size); memcpy(build_state-table_ram, tables.table_data-data, build_state-table_size); +memcpy(build_state-linker_ram, tables.linker-data, + build_state-linker_size); +memcpy(build_state-rsdp_ram, tables.rsdp-data, + build_state-rsdp_size); acpi_build_tables_cleanup(tables, true); } @@ -2060,14 +2068,13 @@ void acpi_setup(PcGuestInfo *guest_info) ACPI_BUILD_TABLE_FILE); build_state-table_size = acpi_data_len(tables.table_data); -acpi_add_rom_blob(NULL, tables.linker, etc/table-loader); +build_state-linker_ram = acpi_add_rom_blob(build_state, tables.linker, +etc/table-loader); +build_state-linker_size = acpi_data_len(tables.linker); -/* - * RSDP is small so it's easy to keep it immutable, no need to - * bother with ROM blobs. - */ -fw_cfg_add_file(guest_info-fw_cfg, ACPI_BUILD_RSDP_FILE, -tables.rsdp-data, acpi_data_len(tables.rsdp)); +build_state-rsdp_ram = acpi_add_rom_blob(build_state, tables.rsdp, + ACPI_BUILD_RSDP_FILE); +build_state-rsdp_size = acpi_data_len(tables.rsdp); qemu_register_reset(acpi_build_reset, build_state); acpi_build_reset(build_state); -- 1.9.3
Re: [Qemu-devel] [PATCH] pc: acpi-build: make linker RSDP tables dynamic
On Wed, Jun 18, 2014 at 12:04:31PM +0300, Marcel Apfelbaum wrote: On Tue, 2014-06-17 at 23:19 +0300, Michael S. Tsirkin wrote: On Tue, Jun 17, 2014 at 10:14:01PM +0200, Igor Mammedov wrote: linker and RSDP tables are build only once, so if later during rebuild sizes of ACPI tables change pointers will be patched incorrectly due to wrong offsets. To fix it rebuild linker and RSDP tables along with the rest of ACPI tables so that they would have correct offsets. Signed-off-by: Igor Mammedov imamm...@redhat.com If you are adding a new blob you are breaking cross-version migration. Need to handle that depending on pc version as appropriate. Besides the above comment, Tested-by: Marcel Apfelbaum marce...@redhat.com Reviewed-by: Marcel Apfelbaum marce...@redhat.com Thanks, Marcel This will need a bit more motivation to go in than is provided here. --- hw/i386/acpi-build.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index fab25ad..8301bb4 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1862,6 +1862,10 @@ struct AcpiBuildState { /* Copy of table in RAM (for patching). */ uint8_t *table_ram; uint32_t table_size; +uint8_t *linker_ram; +uint32_t linker_size; +uint8_t *rsdp_ram; +uint32_t rsdp_size; /* Is table patched? */ uint8_t patched; PcGuestInfo *guest_info; @@ -1998,6 +2002,10 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) assert(acpi_data_len(tables.table_data) == build_state-table_size); memcpy(build_state-table_ram, tables.table_data-data, build_state-table_size); +memcpy(build_state-linker_ram, tables.linker-data, + build_state-linker_size); +memcpy(build_state-rsdp_ram, tables.rsdp-data, + build_state-rsdp_size); acpi_build_tables_cleanup(tables, true); } @@ -2060,14 +2068,13 @@ void acpi_setup(PcGuestInfo *guest_info) ACPI_BUILD_TABLE_FILE); build_state-table_size = acpi_data_len(tables.table_data); -acpi_add_rom_blob(NULL, tables.linker, etc/table-loader); +build_state-linker_ram = acpi_add_rom_blob(build_state, tables.linker, +etc/table-loader); +build_state-linker_size = acpi_data_len(tables.linker); -/* - * RSDP is small so it's easy to keep it immutable, no need to - * bother with ROM blobs. - */ -fw_cfg_add_file(guest_info-fw_cfg, ACPI_BUILD_RSDP_FILE, -tables.rsdp-data, acpi_data_len(tables.rsdp)); +build_state-rsdp_ram = acpi_add_rom_blob(build_state, tables.rsdp, + ACPI_BUILD_RSDP_FILE); +build_state-rsdp_size = acpi_data_len(tables.rsdp); qemu_register_reset(acpi_build_reset, build_state); acpi_build_reset(build_state); -- 1.9.3
[Qemu-devel] [PATCH] tests: disable vhost test temporarily
This test needs a bit more work: issues have been found on legacy systems, disable it for now to avoid false positives for people. Will re-enable after issues are addressed. Reported-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index d1c399c..1c40380 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -156,7 +156,7 @@ gcov-files-i386-y += hw/usb/hcd-ehci.c gcov-files-i386-y += hw/usb/hcd-uhci.c gcov-files-i386-y += hw/usb/dev-hid.c gcov-files-i386-y += hw/usb/dev-storage.c -check-qtest-i386-y += tests/vhost-user-test$(EXESUF) +#check-qtest-i386-y += tests/vhost-user-test$(EXESUF) check-qtest-x86_64-y = $(check-qtest-i386-y) gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) -- MST
Re: [Qemu-devel] [PULL 2/8] vscclient: use glib thread primitives not qemu
Il 17/06/2014 21:11, Ed Maste ha scritto: On 17 June 2014 13:15, Paolo Bonzini pbonz...@redhat.com wrote: Il 17/06/2014 19:10, Ed Maste ha scritto: This change breaks the build on FreeBSD: libcacard/vscclient.c: In function 'send_msg': libcacard/vscclient.c:111: warning: implicit declaration of function 'htonl' ... Can you prepare a patch yourself? I would be guessing the right header to include, sorry. I can get it to build by either restoring the #include of qemu/sockets.h, or explicitly #including sys/socket.h and netinet/in.h. The latter is better, this patch meant to remove most (though not yet all) dependencies of libcacard on include/qemu/. I'm happy to send a signed-off patch for either change, but it seems there must be more to the original change that I'm missing. What provides the declarations for socket(), htonl(), AF_INET etc. in the Linux build? netdb.h includes netinet/in.h, and netinet/in.h includes sys/socket.h. glibc is not particularly good at avoiding #includes within headers. :( Paolo
Re: [Qemu-devel] [PATCHv2] usb: Fix usb-bt-dongle initialization.
Il 18/06/2014 01:23, Hani Benhabiles ha scritto: Due to an incomplete initialization, adding a usb-bt-dongle device through HMP or QMP will cause a segmentation fault. Signed-off-by: Hani Benhabiles h...@linux.com Suggested-by: Paolo Bonzini pbonz...@redhat.com --- Compared to v1: * Remove duplicate code from usb_bt_init() and inline usb_create_simple() call. * usb_bt_initfn() check for s-hci. hw/usb/dev-bluetooth.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c index a9661d2..a76e581 100644 --- a/hw/usb/dev-bluetooth.c +++ b/hw/usb/dev-bluetooth.c @@ -19,6 +19,7 @@ */ #include qemu-common.h +#include qemu/error-report.h #include hw/usb.h #include hw/usb/desc.h #include sysemu/bt.h @@ -506,6 +507,14 @@ static int usb_bt_initfn(USBDevice *dev) usb_desc_create_serial(dev); usb_desc_init(dev); +s-dev.opaque = s; +if (!s-hci) { +s-hci = bt_new_hci(qemu_find_bt_vlan(0)); +} +s-hci-opaque = s; +s-hci-evt_recv = usb_bt_out_hci_packet_event; +s-hci-acl_recv = usb_bt_out_hci_packet_acl; +usb_bt_handle_reset(s-dev); s-intr = usb_ep_get(dev, USB_TOKEN_IN, USB_EVT_EP); return 0; @@ -516,6 +525,7 @@ static USBDevice *usb_bt_init(USBBus *bus, const char *cmdline) USBDevice *dev; struct USBBtState *s; HCIInfo *hci; +const char *name = usb-bt-dongle; if (*cmdline) { hci = hci_init(cmdline); @@ -525,19 +535,17 @@ static USBDevice *usb_bt_init(USBBus *bus, const char *cmdline) if (!hci) return NULL; -dev = usb_create_simple(bus, usb-bt-dongle); +dev = usb_create(bus, name); if (!dev) { +error_report(Failed to create USB device '%s', name); return NULL; } s = DO_UPCAST(struct USBBtState, dev, dev); -s-dev.opaque = s; - s-hci = hci; -s-hci-opaque = s; -s-hci-evt_recv = usb_bt_out_hci_packet_event; -s-hci-acl_recv = usb_bt_out_hci_packet_acl; - -usb_bt_handle_reset(s-dev); +if (qdev_init(dev-qdev) 0) { +error_report(Failed to initialize USB device '%s', name); +return NULL; +} return dev; } Perfect! My comment about inlining usb_create_simple was a bit cryptic, but you got what I meant. Thanks. :) Not really trivial, but you've CCed Gerd too. Reviewed-by: Paolo Bonzini pbonz...@redhat.com
[Qemu-devel] vhost-user: migration?
Just a query whether migration works for you guys with vhost-user and snabbswitch. vhost user code seems to have enough hooks in place to make it work, but was it tested in practice? -- MST
Re: [Qemu-devel] [PATCH v5 2/3] pc q35: Add new machine opt max-ram-below-4g
Hi, IMO xen should use a versioned machine type to make live migration more reliable. IIRC this was discussed anyway for other reasons (see xen-platform-pci discussions, picking pc-i440fx-1.6 IIRC). That is happening as far as I know and does not directly impact this patch set. That should also make qemu use the memory layout expected by old xen. Currently xen just ignores the memory layout that QEMU sets up and does it's own way. So no, this does not make QEMU use the memory layout expected by old xen. Why? -M pc-i440fx-1.6 will make qemu use the same memory layout it used to have before gbalign support was added. And that should match what old xen versions are setting up ... cheers, Gerd
Re: [Qemu-devel] [PATCH] tests: disable vhost test temporarily
On Wed, 18 Jun 2014 12:23:36 +0300 Michael S. Tsirkin m...@redhat.com wrote: This test needs a bit more work: issues have been found on legacy systems, disable it for now to avoid false positives for people. Will re-enable after issues are addressed. Reported-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com Reviewed-by: Igor Mammedov imamm...@redhat.com --- tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index d1c399c..1c40380 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -156,7 +156,7 @@ gcov-files-i386-y += hw/usb/hcd-ehci.c gcov-files-i386-y += hw/usb/hcd-uhci.c gcov-files-i386-y += hw/usb/dev-hid.c gcov-files-i386-y += hw/usb/dev-storage.c -check-qtest-i386-y += tests/vhost-user-test$(EXESUF) +#check-qtest-i386-y += tests/vhost-user-test$(EXESUF) check-qtest-x86_64-y = $(check-qtest-i386-y) gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
Re: [Qemu-devel] [PATCH] libqtest: escape strings in QMP commands, fix leak
Il 18/06/2014 09:41, Amos Kong ha scritto: - Fixed Andreas's mail address On Fri, Jun 13, 2014 at 10:15:00AM +0200, Paolo Bonzini wrote: libqtest is using g_strdup_printf to format QMP commands, but this does not work if the argument strings need to be escaped. Instead, use the fancy %-formatting functionality of QObject. The only change required in tests is that strings have to be formatted as %s, not '%s' or \%s\. Luckily this usage of parameterized QMP commands is not that frequent. I got this error when I apply this patch (it works without this patch): {error: {class: GenericError, desc: Parameter 'id' expects an identifier}} Code: |QDict *response; |int i, j; | |/* start with no network/block device, slots 3 to 0x1f are free */ |qtest_start(-net none); | |for (i = 3; i = 0x1f; i++) { |for (j = 7; j = 0; j--) { |response = qmp({ 'execute': 'blockdev-add', |'arguments': { | 'options': { |'driver': 'file', |'filename': '/dev/null', |'id': 'drv-%x.%x' ^ | } } }, i, j); |g_assert(response); |g_assert(!qdict_haskey(response, error)); |QDECREF(response); Then I have to fix it by : /* start with no network/block device, slots 3 to 0x1f are free */ qtest_start(-net none); for (i = 3; i = 0x1f; i++) { for (j = 7; j = 0; j--) { +sprintf(drive_id, drv-%x.%x, i, j); response = qmp({ 'execute': 'blockdev-add', 'arguments': { 'options': { 'driver': 'file', 'filename': '/dev/null', -'id': 'drv-%x.%x' - } } }, i, j); +'id': %s + } } }, drive_id); Is it the expected result? Thanks, Amos Thanks Amos. This is the right fix. Paolo
[Qemu-devel] [PATCH v4 0/9] virtio-blk: use alias properties in transport devices
v4: * Coding style: typedef struct { on a single line [Andreas] * Add dataplane: bail out on unsupported transport for s390-virtio [Cornelia] v3: * Split qdev_alias_all_properties() into its own patch [Peter Crosthwaite] * Do not dereference DEVICE_CLASS(class) inline [Peter Crosthwaite] v2: * Add qdev_alias_all_properties() instead of virtio-blk-specific function [Paolo] * Explain refcount handling in doc comment [Paolo] * Fix property duplicate typo [Peter Crosthwaite] * Add the same object or to clarify commit description [Igor] Thanks for the feedback on the RFC. This time around the alias property is implemented at the QOM property level instead of at the qdev property level. Note that this series only addresses virtio-blk. In later series we can convert virtio net, scsi, rng, and serial. The virtio transport/device split is broken as follows: 1. The virtio-blk device is never finalized because the transport devices (virtio-blk-pci and friends) leak the refcount. 2. If we fix the refcount leak then we double-free the 'serial' string property upon hot unplug since its char* is copied into the virtio-blk device which has an identical 'serial' qdev property. This series solves both of these problems as follows: 1. Introduce a QOM alias property that lets the transport device forward property accesses into the virtio device (the child). 2. Use alias properties in transport devices, instead of keeping a duplicate copy of the VirtIOBlkConf struct. 3. Fix the virtio-blk device refcount leak. It's now safe to do this since the double-free has been resolved. Tested that hotplug/hotunplug of virtio-blk-pci still works. Cornelia Huck (1): dataplane: bail out on unsupported transport Stefan Hajnoczi (8): qom: add object_property_add_alias() virtio-blk: avoid qdev property definition duplication virtio-blk: move x-data-plane qdev property to virtio-blk.h qdev: add qdev_alias_all_properties() virtio-blk: use aliases instead of duplicate qdev properties virtio-blk: drop virtio_blk_set_conf() virtio: fix virtio-blk child refcount in transports virtio-blk: move qdev properties into virtio-blk.c hw/block/dataplane/virtio-blk.c | 10 hw/block/virtio-blk.c | 18 +-- hw/core/qdev.c | 21 + hw/s390x/s390-virtio-bus.c | 10 ++-- hw/s390x/s390-virtio-bus.h | 1 - hw/s390x/virtio-ccw.c | 7 ++ hw/s390x/virtio-ccw.h | 1 - hw/virtio/virtio-pci.c | 7 ++ hw/virtio/virtio-pci.h | 1 - include/hw/qdev-properties.h| 2 ++ include/hw/virtio/virtio-blk.h | 19 --- include/qom/object.h| 20 qom/object.c| 51 + 13 files changed, 121 insertions(+), 47 deletions(-) -- 1.9.3
[Qemu-devel] [PATCH v4 1/9] qom: add object_property_add_alias()
Sometimes an object needs to present a property which is actually on another object, or it needs to provide an alias name for an existing property. Examples: a.foo - b.foo a.old_name - a.new_name The new object_property_add_alias() API allows objects to alias a property on the same object or another object. The source and target names can be different. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- v4: * Coding style: typedef struct { on a single line [Andreas] v2: * Explain refcount handling in doc comment [Paolo] * Fix property duplicate typo [Peter Crosthwaite] * Add the same object or to clarify commit description [Igor] --- include/qom/object.h | 20 qom/object.c | 51 +++ 2 files changed, 71 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index a641dcd..854a0d5 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1203,6 +1203,26 @@ void object_property_add_uint64_ptr(Object *obj, const char *name, const uint64_t *v, Error **Errp); /** + * object_property_add_alias: + * @obj: the object to add a property to + * @name: the name of the property + * @target_obj: the object to forward property access to + * @target_name: the name of the property on the forwarded object + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add an alias for a property on an object. This function will add a property + * of the same type as the forwarded property. + * + * The caller must ensure that code@target_obj/code stays alive as long as + * this property exists. In the case of a child object or an alias on the same + * object this will be the case. For aliases to other objects the caller is + * responsible for taking a reference. + */ +void object_property_add_alias(Object *obj, const char *name, + Object *target_obj, const char *target_name, + Error **errp); + +/** * object_child_foreach: * @obj: the object whose children will be navigated * @fn: the iterator function to be called diff --git a/qom/object.c b/qom/object.c index e42b254..b83c3a7 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1515,6 +1515,57 @@ void object_property_add_uint64_ptr(Object *obj, const char *name, NULL, NULL, (void *)v, errp); } +typedef struct { +Object *target_obj; +const char *target_name; +} AliasProperty; + +static void property_get_alias(Object *obj, struct Visitor *v, void *opaque, + const char *name, Error **errp) +{ +AliasProperty *prop = opaque; + +object_property_get(prop-target_obj, v, prop-target_name, errp); +} + +static void property_set_alias(Object *obj, struct Visitor *v, void *opaque, + const char *name, Error **errp) +{ +AliasProperty *prop = opaque; + +object_property_set(prop-target_obj, v, prop-target_name, errp); +} + +static void property_release_alias(Object *obj, const char *name, void *opaque) +{ +AliasProperty *prop = opaque; + +g_free(prop); +} + +void object_property_add_alias(Object *obj, const char *name, + Object *target_obj, const char *target_name, + Error **errp) +{ +AliasProperty *prop; +ObjectProperty *target_prop; + +target_prop = object_property_find(target_obj, target_name, errp); +if (!target_prop) { +return; +} + +prop = g_malloc(sizeof(*prop)); +prop-target_obj = target_obj; +prop-target_name = target_name; + +object_property_add(obj, name, target_prop-type, +property_get_alias, +property_set_alias, +property_release_alias, +prop, errp); +} + static void object_instance_init(Object *obj) { object_property_add_str(obj, type, qdev_get_type, NULL, NULL); -- 1.9.3
[Qemu-devel] [PATCH v4 2/9] virtio-blk: avoid qdev property definition duplication
It becomes unwiedly to duplicate all virtio-blk qdev property definitions due to an #ifdef. The C preprocessor syntax makes it a little hard to resolve this cleanly but we can extract the #ifdef and call a macro it defines later. Avoiding duplication is important since it will only get worse when we move the x-data-plane qdev property here too. We'd have a combinatorial explosion since x-data-plane has its own #ifdef. Suggested-by: Peter Crosthwaite peter.crosthwa...@xilinx.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- include/hw/virtio/virtio-blk.h | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 4bc9b54..7bafad5 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -137,21 +137,19 @@ typedef struct VirtIOBlock { DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) #ifdef __linux__ -#define DEFINE_VIRTIO_BLK_PROPERTIES(_state, _field) \ -DEFINE_BLOCK_PROPERTIES(_state, _field.conf), \ -DEFINE_BLOCK_CHS_PROPERTIES(_state, _field.conf), \ -DEFINE_PROP_STRING(serial, _state, _field.serial), \ -DEFINE_PROP_BIT(config-wce, _state, _field.config_wce, 0, true),\ -DEFINE_PROP_BIT(scsi, _state, _field.scsi, 0, true),\ -DEFINE_PROP_IOTHREAD(x-iothread, _state, _field.iothread) +#define DEFINE_VIRTIO_BLK_PROPERTIES_LINUX(_state, _field) \ +DEFINE_PROP_BIT(scsi, _state, _field.scsi, 0, true), #else +#define DEFINE_VIRTIO_BLK_PROPERTIES_LINUX(_state, _field) +#endif + #define DEFINE_VIRTIO_BLK_PROPERTIES(_state, _field) \ +DEFINE_VIRTIO_BLK_PROPERTIES_LINUX(_state, _field)\ DEFINE_BLOCK_PROPERTIES(_state, _field.conf), \ DEFINE_BLOCK_CHS_PROPERTIES(_state, _field.conf), \ DEFINE_PROP_STRING(serial, _state, _field.serial), \ DEFINE_PROP_BIT(config-wce, _state, _field.config_wce, 0, true),\ DEFINE_PROP_IOTHREAD(x-iothread, _state, _field.iothread) -#endif /* __linux__ */ void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk); -- 1.9.3
Re: [Qemu-devel] [PATCH] pc: acpi-build: make linker RSDP tables dynamic
On Wed, 18 Jun 2014 12:19:10 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Wed, Jun 18, 2014 at 12:04:31PM +0300, Marcel Apfelbaum wrote: On Tue, 2014-06-17 at 23:19 +0300, Michael S. Tsirkin wrote: On Tue, Jun 17, 2014 at 10:14:01PM +0200, Igor Mammedov wrote: linker and RSDP tables are build only once, so if later during rebuild sizes of ACPI tables change pointers will be patched incorrectly due to wrong offsets. To fix it rebuild linker and RSDP tables along with the rest of ACPI tables so that they would have correct offsets. Signed-off-by: Igor Mammedov imamm...@redhat.com If you are adding a new blob you are breaking cross-version migration. Need to handle that depending on pc version as appropriate. Besides the above comment, Tested-by: Marcel Apfelbaum marce...@redhat.com Reviewed-by: Marcel Apfelbaum marce...@redhat.com Thanks, Marcel This will need a bit more motivation to go in than is provided here. I'll address comment above and also will dig up example why it was needed in a month old dynamic ACPI tables series. --- hw/i386/acpi-build.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index fab25ad..8301bb4 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1862,6 +1862,10 @@ struct AcpiBuildState { /* Copy of table in RAM (for patching). */ uint8_t *table_ram; uint32_t table_size; +uint8_t *linker_ram; +uint32_t linker_size; +uint8_t *rsdp_ram; +uint32_t rsdp_size; /* Is table patched? */ uint8_t patched; PcGuestInfo *guest_info; @@ -1998,6 +2002,10 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) assert(acpi_data_len(tables.table_data) == build_state-table_size); memcpy(build_state-table_ram, tables.table_data-data, build_state-table_size); +memcpy(build_state-linker_ram, tables.linker-data, + build_state-linker_size); +memcpy(build_state-rsdp_ram, tables.rsdp-data, + build_state-rsdp_size); acpi_build_tables_cleanup(tables, true); } @@ -2060,14 +2068,13 @@ void acpi_setup(PcGuestInfo *guest_info) ACPI_BUILD_TABLE_FILE); build_state-table_size = acpi_data_len(tables.table_data); -acpi_add_rom_blob(NULL, tables.linker, etc/table-loader); +build_state-linker_ram = acpi_add_rom_blob(build_state, tables.linker, +etc/table-loader); +build_state-linker_size = acpi_data_len(tables.linker); -/* - * RSDP is small so it's easy to keep it immutable, no need to - * bother with ROM blobs. - */ -fw_cfg_add_file(guest_info-fw_cfg, ACPI_BUILD_RSDP_FILE, -tables.rsdp-data, acpi_data_len(tables.rsdp)); +build_state-rsdp_ram = acpi_add_rom_blob(build_state, tables.rsdp, + ACPI_BUILD_RSDP_FILE); +build_state-rsdp_size = acpi_data_len(tables.rsdp); qemu_register_reset(acpi_build_reset, build_state); acpi_build_reset(build_state); -- 1.9.3
[Qemu-devel] [PATCH v4 3/9] dataplane: bail out on unsupported transport
From: Cornelia Huck cornelia.h...@de.ibm.com If the virtio transport does not support notifiers (like s390-virtio), we can't use dataplane. Bail out early and let the user know what is wrong. Signed-off-by: Cornelia Huck cornelia.h...@de.ibm.com Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/block/dataplane/virtio-blk.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index c10b7b7..92ebb44 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -331,6 +331,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk, { VirtIOBlockDataPlane *s; Error *local_err = NULL; +BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); *dataplane = NULL; @@ -338,6 +340,14 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk, return; } +/* Don't try if transport does not support notifiers. */ +if (!k-set_guest_notifiers || !k-set_host_notifier) { +error_setg(errp, + device is incompatible with x-data-plane + (transport does not support notifiers)); +return; +} + /* If dataplane is (re-)enabled while the guest is running there could be * block jobs that can conflict. */ -- 1.9.3
[Qemu-devel] [PATCH v4 5/9] qdev: add qdev_alias_all_properties()
The qdev_alias_all_properties() function creates QOM alias properties for each qdev property on a DeviceState. This is useful for parent objects that wish to forward property accesses to their children. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- v3: * Split qdev_alias_all_properties() into its own patch [Peter Crosthwaite] * Do not dereference DEVICE_CLASS(class) inline [Peter Crosthwaite] --- hw/core/qdev.c | 21 + include/hw/qdev-properties.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e65a5aa..850cd9e 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -776,6 +776,27 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, } } +/* @qdev_alias_all_properties - Add alias properties to the source object for + * all qdev properties on the target DeviceState. + */ +void qdev_alias_all_properties(DeviceState *target, Object *source) +{ +ObjectClass *class; +Property *prop; + +class = object_get_class(OBJECT(target)); +do { +DeviceClass *dc = DEVICE_CLASS(class); + +for (prop = dc-props; prop prop-name; prop++) { +object_property_add_alias(source, prop-name, + OBJECT(target), prop-name, + error_abort); +} +class = object_class_get_parent(class); +} while (class != object_class_by_name(TYPE_DEVICE)); +} + static bool device_get_realized(Object *obj, Error **errp) { DeviceState *dev = DEVICE(obj); diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index c962b6b..3726bf3 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -193,6 +193,8 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, */ void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp); +void qdev_alias_all_properties(DeviceState *target, Object *source); + /** * @qdev_prop_set_after_realize: * @dev: device -- 1.9.3
[Qemu-devel] [PATCH v4 4/9] virtio-blk: move x-data-plane qdev property to virtio-blk.h
Move the x-data-plane property. Originally it was outside since not every transport may wish to support dataplane. But that makes little sense when we have a dedicated CONFIG_VIRTIO_BLK_DATA_PLANE ifdef already. This move makes it easier to switch to property aliases in the next patch. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/s390x/virtio-ccw.c | 3 --- hw/virtio/virtio-pci.c | 3 --- include/hw/virtio/virtio-blk.h | 8 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 05656a2..d7ff0a0 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1403,9 +1403,6 @@ static Property virtio_ccw_blk_properties[] = { DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE -DEFINE_PROP_BIT(x-data-plane, VirtIOBlkCcw, blk.data_plane, 0, false), -#endif DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index ce97514..0751a1e 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1067,9 +1067,6 @@ static Property virtio_blk_pci_properties[] = { DEFINE_PROP_BIT(ioeventfd, VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32(vectors, VirtIOPCIProxy, nvectors, 2), -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE -DEFINE_PROP_BIT(x-data-plane, VirtIOBlkPCI, blk.data_plane, 0, false), -#endif DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkPCI, blk), DEFINE_PROP_END_OF_LIST(), diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 7bafad5..56c98b1 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -143,8 +143,16 @@ typedef struct VirtIOBlock { #define DEFINE_VIRTIO_BLK_PROPERTIES_LINUX(_state, _field) #endif +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE +#define DEFINE_VIRTIO_BLK_PROPERTIES_DATA_PLANE(_state, _field) \ +DEFINE_PROP_BIT(x-data-plane, _state, _field.data_plane, 0, false), +#else +#define DEFINE_VIRTIO_BLK_PROPERTIES_DATA_PLANE(_state, _field) +#endif + #define DEFINE_VIRTIO_BLK_PROPERTIES(_state, _field) \ DEFINE_VIRTIO_BLK_PROPERTIES_LINUX(_state, _field)\ +DEFINE_VIRTIO_BLK_PROPERTIES_DATA_PLANE(_state, _field) \ DEFINE_BLOCK_PROPERTIES(_state, _field.conf), \ DEFINE_BLOCK_CHS_PROPERTIES(_state, _field.conf), \ DEFINE_PROP_STRING(serial, _state, _field.serial), \ -- 1.9.3
[Qemu-devel] [PATCH v4 7/9] virtio-blk: drop virtio_blk_set_conf()
This function is no longer used since parent objects now use child aliases to set the VirtIOBlkConf directly. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/block/virtio-blk.c | 6 -- include/hw/virtio/virtio-blk.h | 2 -- 2 files changed, 8 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 85aa871..cfb8fa3 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -655,12 +655,6 @@ static const BlockDevOps virtio_block_ops = { .resize_cb = virtio_blk_resize, }; -void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk) -{ -VirtIOBlock *s = VIRTIO_BLK(dev); -memcpy((s-blk), blk, sizeof(struct VirtIOBlkConf)); -} - #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE /* Disable dataplane thread during live migration since it does not * update the dirty memory bitmap yet. diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 56c98b1..59cf1f2 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -159,8 +159,6 @@ typedef struct VirtIOBlock { DEFINE_PROP_BIT(config-wce, _state, _field.config_wce, 0, true),\ DEFINE_PROP_IOTHREAD(x-iothread, _state, _field.iothread) -void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk); - int virtio_blk_handle_scsi_req(VirtIOBlock *blk, VirtQueueElement *elem); -- 1.9.3
[Qemu-devel] [PATCH v4 6/9] virtio-blk: use aliases instead of duplicate qdev properties
virtio-blk-pci, virtio-blk-s390, and virtio-blk-ccw all duplicate the qdev properties of their VirtIOBlock child. This approach does not work well with string or pointer properties since we must be careful about leaking or double-freeing them. Use the QOM alias property to forward property accesses to the VirtIOBlock child. This way no duplication is necessary. Remember to stop calling virtio_blk_set_conf() so that we don't clobber the values already set on the VirtIOBlock instance. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- v3: * Split qdev_alias_all_properties() into its own patch [Peter Crosthwaite] v2: * Add qdev_alias_all_properties() instead of virtio-blk-specific function [Paolo] --- hw/s390x/s390-virtio-bus.c | 9 + hw/s390x/s390-virtio-bus.h | 1 - hw/s390x/virtio-ccw.c | 3 +-- hw/s390x/virtio-ccw.h | 1 - hw/virtio/virtio-pci.c | 3 +-- hw/virtio/virtio-pci.h | 1 - 6 files changed, 3 insertions(+), 15 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 7c8c81b..38984ab 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -167,7 +167,6 @@ static int s390_virtio_blk_init(VirtIOS390Device *s390_dev) { VirtIOBlkS390 *dev = VIRTIO_BLK_S390(s390_dev); DeviceState *vdev = DEVICE(dev-vdev); -virtio_blk_set_conf(vdev, (dev-blk)); qdev_set_parent_bus(vdev, BUS(s390_dev-bus)); if (qdev_init(vdev) 0) { return -1; @@ -180,6 +179,7 @@ static void s390_virtio_blk_instance_init(Object *obj) VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_BLK); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static int s390_virtio_serial_init(VirtIOS390Device *s390_dev) @@ -513,18 +513,11 @@ static const TypeInfo s390_virtio_net = { .class_init= s390_virtio_net_class_init, }; -static Property s390_virtio_blk_properties[] = { -DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkS390, blk), -DEFINE_PROP_END_OF_LIST(), -}; - static void s390_virtio_blk_class_init(ObjectClass *klass, void *data) { -DeviceClass *dc = DEVICE_CLASS(klass); VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass); k-init = s390_virtio_blk_init; -dc-props = s390_virtio_blk_properties; } static const TypeInfo s390_virtio_blk = { diff --git a/hw/s390x/s390-virtio-bus.h b/hw/s390x/s390-virtio-bus.h index ac81bd8..ffd0df7 100644 --- a/hw/s390x/s390-virtio-bus.h +++ b/hw/s390x/s390-virtio-bus.h @@ -124,7 +124,6 @@ void s390_virtio_reset_idx(VirtIOS390Device *dev); typedef struct VirtIOBlkS390 { VirtIOS390Device parent_obj; VirtIOBlock vdev; -VirtIOBlkConf blk; } VirtIOBlkS390; /* virtio-scsi-s390 */ diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index d7ff0a0..9fa6f32 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -800,7 +800,6 @@ static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev) { VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev); DeviceState *vdev = DEVICE(dev-vdev); -virtio_blk_set_conf(vdev, (dev-blk)); qdev_set_parent_bus(vdev, BUS(ccw_dev-bus)); if (qdev_init(vdev) 0) { return -1; @@ -814,6 +813,7 @@ static void virtio_ccw_blk_instance_init(Object *obj) VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_BLK); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +qdev_alias_all_properties(DEVICE(dev-vdev), obj); } static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev) @@ -1400,7 +1400,6 @@ static const TypeInfo virtio_ccw_net = { static Property virtio_ccw_blk_properties[] = { DEFINE_PROP_STRING(devno, VirtioCcwDevice, bus_id), DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]), -DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk), DEFINE_PROP_BIT(ioeventfd, VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h index b8b8a8a..5a1f16e 100644 --- a/hw/s390x/virtio-ccw.h +++ b/hw/s390x/virtio-ccw.h @@ -144,7 +144,6 @@ typedef struct VHostSCSICcw { typedef struct VirtIOBlkCcw { VirtioCcwDevice parent_obj; VirtIOBlock vdev; -VirtIOBlkConf blk; } VirtIOBlkCcw; /* virtio-balloon-ccw */ diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 0751a1e..3bb782f 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1068,7 +1068,6 @@ static Property virtio_blk_pci_properties[] = { VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32(vectors, VirtIOPCIProxy, nvectors, 2), DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), -
[Qemu-devel] [PATCH v4 8/9] virtio: fix virtio-blk child refcount in transports
object_initialize() leaves the object with a refcount of 1. object_property_add_child() adds its own reference which is dropped again when the property is deleted. The upshot of this is that we always have a refcount = 1. Upon hot unplug the virtio-blk child is not finalized! Drop our reference after the child property has been added to the parent. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/s390x/s390-virtio-bus.c | 1 + hw/s390x/virtio-ccw.c | 1 + hw/virtio/virtio-pci.c | 1 + 3 files changed, 3 insertions(+) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 38984ab..3438a88 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -179,6 +179,7 @@ static void s390_virtio_blk_instance_init(Object *obj) VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_BLK); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 9fa6f32..0553fea 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -813,6 +813,7 @@ static void virtio_ccw_blk_instance_init(Object *obj) VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_BLK); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 3bb782f..abf05a9 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1102,6 +1102,7 @@ static void virtio_blk_pci_instance_init(Object *obj) VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(obj); object_initialize(dev-vdev, sizeof(dev-vdev), TYPE_VIRTIO_BLK); object_property_add_child(obj, virtio-backend, OBJECT(dev-vdev), NULL); +object_unref(OBJECT(dev-vdev)); qdev_alias_all_properties(DEVICE(dev-vdev), obj); } -- 1.9.3
[Qemu-devel] [PATCH v4 9/9] virtio-blk: move qdev properties into virtio-blk.c
There is no need to make DEFINE_VIRTIO_BLK_PROPERTIES() public. Inline it into virtio-blk.c so it cannot be used by mistake from other source files. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com --- hw/block/virtio-blk.c | 12 +++- include/hw/virtio/virtio-blk.h | 23 --- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index cfb8fa3..d36a3d4 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -762,7 +762,17 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp) } static Property virtio_blk_properties[] = { -DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlock, blk), +DEFINE_BLOCK_PROPERTIES(VirtIOBlock, blk.conf), +DEFINE_BLOCK_CHS_PROPERTIES(VirtIOBlock, blk.conf), +DEFINE_PROP_STRING(serial, VirtIOBlock, blk.serial), +DEFINE_PROP_BIT(config-wce, VirtIOBlock, blk.config_wce, 0, true), +DEFINE_PROP_IOTHREAD(x-iothread, VirtIOBlock, blk.iothread), +#ifdef __linux__ +DEFINE_PROP_BIT(scsi, VirtIOBlock, blk.scsi, 0, true), +#endif +#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE +DEFINE_PROP_BIT(x-data-plane, VirtIOBlock, blk.data_plane, 0, false), +#endif DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 59cf1f2..b3ed57a 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -136,29 +136,6 @@ typedef struct VirtIOBlock { #define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \ DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) -#ifdef __linux__ -#define DEFINE_VIRTIO_BLK_PROPERTIES_LINUX(_state, _field) \ -DEFINE_PROP_BIT(scsi, _state, _field.scsi, 0, true), -#else -#define DEFINE_VIRTIO_BLK_PROPERTIES_LINUX(_state, _field) -#endif - -#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE -#define DEFINE_VIRTIO_BLK_PROPERTIES_DATA_PLANE(_state, _field) \ -DEFINE_PROP_BIT(x-data-plane, _state, _field.data_plane, 0, false), -#else -#define DEFINE_VIRTIO_BLK_PROPERTIES_DATA_PLANE(_state, _field) -#endif - -#define DEFINE_VIRTIO_BLK_PROPERTIES(_state, _field) \ -DEFINE_VIRTIO_BLK_PROPERTIES_LINUX(_state, _field)\ -DEFINE_VIRTIO_BLK_PROPERTIES_DATA_PLANE(_state, _field) \ -DEFINE_BLOCK_PROPERTIES(_state, _field.conf), \ -DEFINE_BLOCK_CHS_PROPERTIES(_state, _field.conf), \ -DEFINE_PROP_STRING(serial, _state, _field.serial), \ -DEFINE_PROP_BIT(config-wce, _state, _field.config_wce, 0, true),\ -DEFINE_PROP_IOTHREAD(x-iothread, _state, _field.iothread) - int virtio_blk_handle_scsi_req(VirtIOBlock *blk, VirtQueueElement *elem); -- 1.9.3
Re: [Qemu-devel] qemu-img segfault on latest git
On Tue, Jun 17, 2014 at 11:08:48AM -0400, Milos Vyletel wrote: I hope this is the right place to report this. I've noticed that I can't run qemu-img convert on latest git version because it segfaults. I've bisected the code and identified that this was caused by Thanks for the bug report! commit 6f482f742dd841b45297fb0e5f3d2c81779253be Author: Chunyan Liu cy...@suse.com Date: Thu Jun 5 17:21:01 2014 +0800 raw-posix.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com Signed-off-by: Chunyan Liu cy...@suse.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com bisect log: git bisect start # bad: [af44da87e926ff64260b95f4350d338c4fc113ca] Merge remote-tracking branch 'remotes/agraf/tags/signed-ppc-for-upstream' into staging git bisect bad af44da87e926ff64260b95f4350d338c4fc113ca # good: [10f08a0a3435afea441db8d0981dbad49042c7cf] qemu-iotests: Test converting to streamOptimized from small cluster size git bisect good 10f08a0a3435afea441db8d0981dbad49042c7cf # good: [1673e89e93e08cbfee7c9b552008e5b39469ad0e] Merge remote-tracking branch 'remotes/kraxel/tags/pull-sdl-3' into staging git bisect good 1673e89e93e08cbfee7c9b552008e5b39469ad0e # good: [a491af471bf8f1188b2665f54d109065d4591e45] json-parser: drop superfluous assignment for token variable git bisect good a491af471bf8f1188b2665f54d109065d4591e45 # good: [10582ff832798813ba3a17f13f3ab46250388b47] spapr: Add ibm, chip-id property in device tree git bisect good 10582ff832798813ba3a17f13f3ab46250388b47 # good: [6a1eed3f49e0fc5ef94906c0eab5314bc32bc8ae] target-ppc: Make use of gen_spr_book3s_altivec() for POWER7/8 git bisect good 6a1eed3f49e0fc5ef94906c0eab5314bc32bc8ae # bad: [bd0cf596fd1200d162e5655adff9c06d40dbdd14] rbd.c: replace QEMUOptionParameter with QemuOpts git bisect bad bd0cf596fd1200d162e5655adff9c06d40dbdd14 # good: [8559e45e51edd22dd48d54cce8b0521e6339f3e9] QemuOpts: add conversion between QEMUOptionParameter to QemuOpts git bisect good 8559e45e51edd22dd48d54cce8b0521e6339f3e9 # good: [98c10b810a83a0f52b4b5a14a8a36ce0622cb01f] nfs.c: replace QEMUOptionParameter with QemuOpts git bisect good 98c10b810a83a0f52b4b5a14a8a36ce0622cb01f # good: [7ab74849a5724452b35982a6e7d658c25839f5e5] qed.c: replace QEMUOptionParameter with QemuOpts git bisect good 7ab74849a5724452b35982a6e7d658c25839f5e5 # bad: [ddef76999396d93b2c7ddfc7e95d5c4bcdeac55a] raw-win32.c: replace QEMUOptionParameter with QemuOpts git bisect bad ddef76999396d93b2c7ddfc7e95d5c4bcdeac55a # bad: [6f482f742dd841b45297fb0e5f3d2c81779253be] raw-posix.c: replace QEMUOptionParameter with QemuOpts git bisect bad 6f482f742dd841b45297fb0e5f3d2c81779253be test script: #!/bin/bash make -j 24 clean ./configure make -j 24 qemu-img ./qemu-img create -f raw ~/qemu-test.img 128M ./qemu-img convert -p -f raw ~/qemu-test.img -O vmdk \ -o adapter_type=lsilogic,subformat=streamOptimized,compat6 \ ~/qemu-test.vmdk [ -f ~/qemu-test.vmdk ] ret=0 || ret=1 rm -f ~/qemu-test.{img,vmdk} exit $ret Milos pgpMdYNKIoV5h.pgp Description: PGP signature
Re: [Qemu-devel] change of mac address at runtime
On Tue, Jun 17, 2014 at 04:48:43PM +0200, Anshul Makkar wrote: Just want to check this small piece of implementation detail in qemu. Is it possible to change the mac address of VM at runtime and does the same information is conveyed to host if we are using Virtio based transfers (approach). Yes, virtio-net supports changing MAC. Stefan pgpnJWx5iJR9h.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v1 0/3] e1000: link auto-negotiation fixes
On Mon, Jun 16, 2014 at 01:29:08PM -0400, Gabriel L. Somlo wrote: This series contains a few fixes and improvements in the emulation of link auto-negotiation: - use auto-negotiation when the link is bounced externally (e.g. via set_link foo down/up on the qemu monitor command line). - allow mii_tool on linux access to all the phy registers and flags it requires in order to report a successfully auto-negotiated link. - inject LSC interrupt upon successful link auto-negotiation (required by stock OS X e1000 driver). See additional prose following commit logs in 2/3 (making up excuses for checkpatch error) and 3/3 (further thoughts on OS X vs. Linux/Windows re. auto-negotiation and LSC injection). Thanks much, Gabriel Gabriel L. Somlo (3): e1000: emulate auto-negotiation during external link status change e1000: improve auto-negotiation reporting via mii-tool e1000: signal guest on successful link auto-negotiation hw/net/e1000.c | 24 +++- hw/net/e1000_regs.h | 3 +++ 2 files changed, 22 insertions(+), 5 deletions(-) From my limited e1000 understanding and some checking against the datasheet: Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Since Michael Tsirkin's attention has been drawn, I'll leave this series for him to review and merge. pgpUU4FI5Me4f.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH v4 01/18] migration: dump vmstate info as a json file for static analysis
Amit Shah amit.s...@redhat.com wrote: This commit adds a new command, '-dump-vmstate', that takes a filename as a parameter. When executed, QEMU will dump the vmstate information for the machine type it's invoked with to the file, and quit. The JSON-format output can then be used to compare the vmstate info for different QEMU versions, specifically to test whether live migration would break due to changes in the vmstate data. A Python script that compares the output of such JSON dumps is included in the following commit. Signed-off-by: Amit Shah amit.s...@redhat.com +static void dump_vmstate_vmsd(FILE *out_file, + const VMStateDescription *vmsd, int indent, + bool is_subsection) +{ +if (is_subsection) { +fprintf(out_file, %*s{\n, indent, ); +} else { +fprintf(out_file, %*s\%s\: {\n, indent, , Description); +} +indent += 2; +fprintf(out_file, %*s\name\: \%s\,\n, indent, , vmsd-name); +fprintf(out_file, %*s\version_id\: %d,\n, indent, , +vmsd-version_id); +fprintf(out_file, %*s\minimum_version_id\: %d, indent, , +vmsd-minimum_version_id); +if (vmsd-fields != NULL) { +const VMStateField *field = vmsd-fields; +bool first; + +fprintf(out_file, ,\n%*s\Fields\: [\n, indent, ); Remove last \n (*) +first = true; first can go now +while (field-name != NULL) { +if (field-flags VMS_MUST_EXIST) { +/* Ignore VMSTATE_VALIDATE bits; these don't get migrated */ +field++; +continue; +} +if (!first) { +fprintf(out_file, ,\n); You can print always \n now, right? Same for the other places? Or I am missing something. I will even go that itwould be better to just left the \n on the (*), and just add this \n at the end of writing a subsection. +fprintf(out_file, \n%*s}, indent - 2, ); And you remove it from here. full disclosure Yes, I have always hated pretty-printers /full-disclosure Rest of this, I fully agree. Later, Juan.
Re: [Qemu-devel] [PATCH v4 3/4] virtio-blk-test.c: add hotplug subtest
Am 18.06.2014 08:40, schrieb Amos Kong: On Tue, Jun 17, 2014 at 03:25:34PM +0200, Andreas Färber wrote: Am 06.06.2014 16:33, schrieb Amos Kong: This patch adds a new subtest, it hotplugs 29 * 8 = 232 virtio-blk devices to guest, and try to hot-unplug them. Note: the hot-unplug can't work without cooperation of guest OS. Signed-off-by: Amos Kong ak...@redhat.com Reviewed-by: Stefan Hajnoczi stefa...@redhat.com --- tests/virtio-blk-test.c | 31 +++ 1 file changed, 31 insertions(+) diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 0fdec01..7358203 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -7,11 +7,41 @@ * See the COPYING file in the top-level directory. */ +#include stdio.h #include glib.h #include string.h #include libqtest.h #include qemu/osdep.h +static void test_blk_hotplug(void) +{ +int i, j; + +/* start with no network/block device, slots 3~0x1f are free */ 3-0x1f or 3 to 0x1f? +qtest_start(-net none); + +for (i = 3; i = 0x1f; i++) { +for (j = 7; j = 0; j--) { +qmp_exec_hmp_cmd(OK\r\n, + drive_add 0 if=none,file=/dev/null,id=drv-%x.%x, + i, j); +qmp_exec_hmp_cmd(, + device_add virtio-blk-pci,id=dev-%x.%x,drive=drv-%x.%x, + addr=0x%x.%x,multifunction=on, i, j, i, j, i, j); Hi Andreas, Why are you using HMP-via-QMP here and not QMP directly? I referenced existed test code. +} +} + +/* hot-unplug doesn't work without cooperation of guest OS */ +for (i = 3; i = 0x1f; i++) { +for (j = 7; j = 0; j--) { While the function is still small, using a define or static const would be a small improvement. :) Could be a follow-up of course. Sorry I don't get it. You are adding two new loops that are supposed to match. My suggestion is to avoid the four magic numbers by using #define MIN_PCI_SLOT 3 or static const int max_pci_slot = 0x1f; etc. to enforce they always match and can more easily be tweaked once, e.g., another slot is taken by default. Just a cosmetic cleanup. Cheers, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v4 04/18] tests: vmstate static checker: incompat machine types
Amit Shah amit.s...@redhat.com wrote: This commit modifies the dump2 data to flag incompatibilities in the machine types being compared. Signed-off-by: Amit Shah amit.s...@redhat.com Acked-by: Juan Quintela quint...@redhat.com
Re: [Qemu-devel] [PATCH v4 03/18] tests: vmstate static checker: add dump1 and dump2 files
Amit Shah amit.s...@redhat.com wrote: These are stripped-down JSON data as obtained from the -dump-vmstate option. The two files are identical in this commit, and will be modified in the later commits to show what the script does with the data. Signed-off-by: Amit Shah amit.s...@redhat.com Acked-by: Juan Quintela quint...@redhat.com