All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1
@ 2014-06-18  6:43 Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 01/36] os-posix: include sys/time.h Paolo Bonzini
                   ` (38 more replies)
  0 siblings, 39 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

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                                     |  22 +-
 66 files changed, 1878 insertions(+), 1143 deletions(-)
 delete mode 100644 docs/qmp/qmp-events.txt
 create mode 100644 include/qapi/qmp-event.h
 create mode 100644 qapi-event.json
 create mode 100644 qapi/qmp-event.c
 create mode 100644 scripts/qapi-event.py
 delete mode 100644 stubs/mon-protocol-event.c
 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
 create mode 100644 tests/test-qmp-event.c

-- 
1.9.3

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 01/36] os-posix: include sys/time.h
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 02/36] qapi: Add includes from qapi/ as dependencies Paolo Bonzini
                   ` (37 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 02/36] qapi: Add includes from qapi/ as dependencies
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 01/36] os-posix: include sys/time.h Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 03/36] qapi: add event helper functions Paolo Bonzini
                   ` (36 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: Max Reitz, wenchaoqemu, lcapitulino

From: Max Reitz <mreitz@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 <mreitz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 03/36] qapi: add event helper functions
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 01/36] os-posix: include sys/time.h Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 02/36] qapi: Add includes from qapi/ as dependencies Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18 22:55   ` Wenchao Xia
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support Paolo Bonzini
                   ` (35 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

This file holds some functions that do not need to be generated.

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@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 0000000..8a8ffb5
--- /dev/null
+++ b/include/qapi/qmp-event.h
@@ -0,0 +1,27 @@
+/*
+ * QMP Event related
+ *
+ * Copyright (c) 2014 Wenchao Xia
+ *
+ * Authors:
+ *  Wenchao Xia   <wenchaoqemu@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 0000000..0d1ce0b
--- /dev/null
+++ b/qapi/qmp-event.c
@@ -0,0 +1,74 @@
+/*
+ * QMP Event related
+ *
+ * Copyright (c) 2014 Wenchao Xia
+ *
+ * Authors:
+ *  Wenchao Xia   <wenchaoqemu@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (2 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 03/36] qapi: add event helper functions Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19 12:06   ` Eric Blake
  2014-06-19 19:57   ` Eric Blake
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 05/36] test: add test cases for qapi event Paolo Bonzini
                   ` (34 subsequent siblings)
  38 siblings, 2 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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 0000000..3a1cd61
--- /dev/null
+++ b/scripts/qapi-event.py
@@ -0,0 +1,369 @@
+#
+# QAPI event generator
+#
+# Copyright (c) 2014 Wenchao Xia
+#
+# Authors:
+#  Wenchao Xia <wenchaoqemu@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
+import os
+import getopt
+import errno
+
+def _generate_event_api_name(event_name, params):
+    api_name = "void qapi_event_send_%s(" % c_fun(event_name).lower();
+    l = len(api_name)
+
+    if params:
+        for argname, argentry, optional, structured in parse_args(params):
+            if optional:
+                api_name += "bool has_%s,\n" % c_var(argname)
+                api_name += "".ljust(l)
+
+            if argentry == "str":
+                api_name += "const "
+            api_name += "%s %s,\n" % (c_type(argentry), c_var(argname))
+            api_name += "".ljust(l)
+
+    api_name += "Error **errp)"
+    return api_name;
+
+
+# Following are the core functions that generate C APIs to emit event.
+
+def generate_event_declaration(api_name):
+    return mcgen('''
+
+%(api_name)s;
+''',
+                 api_name = api_name)
+
+def generate_event_implement(api_name, event_name, params):
+    # step 1: declare any variables
+    ret = mcgen("""
+
+%(api_name)s
+{
+    QDict *qmp;
+    Error *local_err = NULL;
+    QMPEventFuncEmit emit;
+""",
+                api_name = api_name)
+
+    if params:
+        ret += mcgen("""
+    QmpOutputVisitor *qov;
+    Visitor *v;
+    QObject *obj;
+
+""")
+
+    # step 2: check emit function, create a dict
+    ret += mcgen("""
+    emit = qmp_event_get_func_emit();
+    if (!emit) {
+        return;
+    }
+
+    qmp = qmp_event_build_dict("%(event_name)s");
+
+""",
+                 event_name = event_name)
+
+    # step 3: visit the params if params != None
+    if params:
+        ret += mcgen("""
+    qov = qmp_output_visitor_new();
+    g_assert(qov);
+
+    v = qmp_output_get_visitor(qov);
+    g_assert(v);
+
+    /* Fake visit, as if all members are under a structure */
+    visit_start_struct(v, NULL, "", "%(event_name)s", 0, &local_err);
+    if (local_err) {
+        goto clean;
+    }
+
+""",
+                event_name = event_name)
+
+        for argname, argentry, optional, structured in parse_args(params):
+            if optional:
+                ret += mcgen("""
+    if (has_%(var)s) {
+""",
+                             var = c_var(argname))
+                push_indent()
+
+            if argentry == "str":
+                var_type = "(char **)"
+            else:
+                var_type = ""
+
+            ret += mcgen("""
+    visit_type_%(type)s(v, %(var_type)s&%(var)s, "%(name)s", &local_err);
+    if (local_err) {
+        goto clean;
+    }
+""",
+                         var_type = var_type,
+                         var = c_var(argname),
+                         type = type_name(argentry),
+                         name = argname)
+
+            if optional:
+                pop_indent()
+                ret += mcgen("""
+    }
+""")
+
+        ret += mcgen("""
+
+    visit_end_struct(v, &local_err);
+    if (local_err) {
+        goto clean;
+    }
+
+    obj = qmp_output_get_qobject(qov);
+    g_assert(obj != NULL);
+
+    qdict_put_obj(qmp, "data", obj);
+""")
+
+    # step 4: call qmp event api
+    ret += mcgen("""
+    emit(%(event_enum_value)s, qmp, &local_err);
+
+""",
+                 event_enum_value = event_enum_value)
+
+    # step 5: clean up
+    if params:
+        ret += mcgen("""
+ clean:
+    qmp_output_visitor_cleanup(qov);
+""")
+    ret += mcgen("""
+    error_propagate(errp, local_err);
+    QDECREF(qmp);
+}
+""")
+
+    return ret
+
+
+# Following are the functions that generate an enum type for all defined
+# events, similar to qapi-types.py. Here we already have enum name and
+# values which were generated before and recorded in event_enum_*. It also
+# works around the issue that "import qapi-types" can't work.
+
+def generate_event_enum_decl(event_enum_name, event_enum_values):
+    lookup_decl = mcgen('''
+
+extern const char *%(event_enum_name)s_lookup[];
+''',
+                        event_enum_name = event_enum_name)
+
+    enum_decl = mcgen('''
+typedef enum %(event_enum_name)s
+{
+''',
+                      event_enum_name = event_enum_name)
+
+    # append automatically generated _MAX value
+    enum_max_value = generate_enum_full_value(event_enum_name, "MAX")
+    enum_values = event_enum_values + [ enum_max_value ]
+
+    i = 0
+    for value in enum_values:
+        enum_decl += mcgen('''
+    %(value)s = %(i)d,
+''',
+                     value = value,
+                     i = i)
+        i += 1
+
+    enum_decl += mcgen('''
+} %(event_enum_name)s;
+''',
+                       event_enum_name = event_enum_name)
+
+    return lookup_decl + enum_decl
+
+def generate_event_enum_lookup(event_enum_name, event_enum_strings):
+    ret = mcgen('''
+
+const char *%(event_enum_name)s_lookup[] = {
+''',
+                event_enum_name = event_enum_name)
+
+    i = 0
+    for string in event_enum_strings:
+        ret += mcgen('''
+    "%(string)s",
+''',
+                     string = string)
+
+    ret += mcgen('''
+    NULL,
+};
+''')
+    return ret
+
+
+# Start the real job
+
+try:
+    opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
+                                   ["source", "header", "builtins", "prefix=",
+                                    "input-file=", "output-dir="])
+except getopt.GetoptError, err:
+    print str(err)
+    sys.exit(1)
+
+input_file = ""
+output_dir = ""
+prefix = ""
+c_file = 'qapi-event.c'
+h_file = 'qapi-event.h'
+
+do_c = False
+do_h = False
+do_builtins = False
+
+for o, a in opts:
+    if o in ("-p", "--prefix"):
+        prefix = a
+    elif o in ("-i", "--input-file"):
+        input_file = a
+    elif o in ("-o", "--output-dir"):
+        output_dir = a + "/"
+    elif o in ("-c", "--source"):
+        do_c = True
+    elif o in ("-h", "--header"):
+        do_h = True
+    elif o in ("-b", "--builtins"):
+        do_builtins = True
+
+if not do_c and not do_h:
+    do_c = True
+    do_h = True
+
+c_file = output_dir + prefix + c_file
+h_file = output_dir + prefix + h_file
+
+try:
+    os.makedirs(output_dir)
+except os.error, e:
+    if e.errno != errno.EEXIST:
+        raise
+
+def maybe_open(really, name, opt):
+    if really:
+        return open(name, opt)
+    else:
+        import StringIO
+        return StringIO.StringIO()
+
+fdef = maybe_open(do_c, c_file, 'w')
+fdecl = maybe_open(do_h, h_file, 'w')
+
+fdef.write(mcgen('''
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI event functions
+ *
+ * Copyright (c) 2014 Wenchao Xia
+ *
+ * Authors:
+ *  Wenchao Xia   <wenchaoqemu@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 "qemu-common.h"
+#include "%(header)s"
+#include "%(prefix)sqapi-visit.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qmp-event.h"
+
+''',
+                 prefix=prefix, header=basename(h_file)))
+
+fdecl.write(mcgen('''
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
+
+/*
+ * schema-defined QAPI event functions
+ *
+ * Copyright (c) 2014 Wenchao Xia
+ *
+ * Authors:
+ *  Wenchao Xia  <wenchaoqemu@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 %(guard)s
+#define %(guard)s
+
+#include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
+#include "%(prefix)sqapi-types.h"
+
+''',
+                  prefix=prefix, guard=guardname(h_file)))
+
+exprs = parse_schema(input_file)
+
+event_enum_name = prefix.upper().replace('-', '_') + "QAPIEvent"
+event_enum_values = []
+event_enum_strings = []
+
+for expr in exprs:
+    if expr.has_key('event'):
+        event_name = expr['event']
+        params = expr.get('data')
+        if params and len(params) == 0:
+            params = None
+
+        api_name = _generate_event_api_name(event_name, params)
+        ret = generate_event_declaration(api_name)
+        fdecl.write(ret)
+
+        # We need an enum value per event
+        event_enum_value = generate_enum_full_value(event_enum_name,
+                                                    event_name)
+        ret = generate_event_implement(api_name, event_name, params)
+        fdef.write(ret)
+
+        # Record it, and generate enum later
+        event_enum_values.append(event_enum_value)
+        event_enum_strings.append(event_name)
+
+ret = generate_event_enum_decl(event_enum_name, event_enum_values)
+fdecl.write(ret)
+ret = generate_event_enum_lookup(event_enum_name, event_enum_strings)
+fdef.write(ret)
+
+fdecl.write('''
+#endif
+''')
+
+fdecl.flush()
+fdecl.close()
+
+fdef.flush()
+fdef.close()
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 86e9608..9b488f2 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -248,6 +248,16 @@ def discriminator_find_enum_define(expr):
 
     return find_enum(discriminator_type)
 
+def check_event(expr, expr_info):
+    params = expr.get('data')
+    if params:
+        for argname, argentry, optional, structured in parse_args(params):
+            if structured:
+                raise QAPIExprError(expr_info,
+                                    "Nested structure define in event is not "
+                                    "supported now, event '%s', argname '%s'"
+                                    % (expr['event'], argname))
+
 def check_union(expr, expr_info):
     name = expr['union']
     base = expr.get('base')
@@ -311,6 +321,8 @@ def check_exprs(schema):
         expr = expr_elem['expr']
         if expr.has_key('union'):
             check_union(expr, expr_elem['info'])
+        if expr.has_key('event'):
+            check_event(expr, expr_elem['info'])
 
 def parse_schema(input_file):
     try:
diff --git a/tests/Makefile b/tests/Makefile
index 361bb7b..4bb63a6 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -198,7 +198,7 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
         include-simple.json include-relpath.json include-format-err.json \
         include-non-file.json include-no-file.json include-before-err.json \
         include-nested-err.json include-self-cycle.json include-cycle.json \
-        include-repetition.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
 
diff --git a/tests/qapi-schema/event-nest-struct.err b/tests/qapi-schema/event-nest-struct.err
new file mode 100644
index 0000000..e4a0faa
--- /dev/null
+++ b/tests/qapi-schema/event-nest-struct.err
@@ -0,0 +1 @@
+tests/qapi-schema/event-nest-struct.json:1: Nested structure define in event is not supported now, event 'EVENT_A', argname 'a'
diff --git a/tests/qapi-schema/event-nest-struct.exit b/tests/qapi-schema/event-nest-struct.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/event-nest-struct.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/event-nest-struct.json b/tests/qapi-schema/event-nest-struct.json
new file mode 100644
index 0000000..ee6f3ec
--- /dev/null
+++ b/tests/qapi-schema/event-nest-struct.json
@@ -0,0 +1,2 @@
+{ 'event': 'EVENT_A',
+  'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } }
diff --git a/tests/qapi-schema/event-nest-struct.out b/tests/qapi-schema/event-nest-struct.out
new file mode 100644
index 0000000..e69de29
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 05/36] test: add test cases for qapi event
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (3 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 06/36] qapi: adjust existing defines Paolo Bonzini
                   ` (33 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

These cases will verify whether the expected qdict is built.

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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'), ('*b', 'int')])), ('returns', 'int')]),
- OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
+ OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
+ OrderedDict([('type', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]),
+ OrderedDict([('event', 'EVENT_A')]),
+ OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]),
+ OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), ('*b', 'UserDefOne'), ('c', 'str')]))]),
+ OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
  {'enum_name': 'UserDefUnionKind', 'enum_values': None},
  {'enum_name': 'UserDefAnonUnionKind', 'enum_values': None},
@@ -28,4 +33,5 @@
  OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
  OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
  OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
- OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
+ OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
+ OrderedDict([('type', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))])]
diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
new file mode 100644
index 0000000..cb1e441
--- /dev/null
+++ b/tests/test-qmp-event.c
@@ -0,0 +1,265 @@
+/*
+ * qapi event unit-tests.
+ *
+ * Copyright (c) 2014 Wenchao Xia
+ *
+ * Authors:
+ *  Wenchao Xia   <wenchaoqemu@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 <glib.h>
+#include <stdarg.h>
+
+#include "qemu-common.h"
+#include "test-qapi-types.h"
+#include "test-qapi-visit.h"
+#include "test-qapi-event.h"
+#include "qapi/qmp/types.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qobject.h"
+#include "qapi/qmp-event.h"
+
+typedef struct TestEventData {
+    QDict *expect;
+} TestEventData;
+
+typedef struct QDictCmpData {
+    QDict *expect;
+    bool result;
+} QDictCmpData;
+
+TestEventData *test_event_data;
+static CompatGMutex test_event_lock;
+
+/* Only compares bool, int, string */
+static
+void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque)
+
+{
+    QObject *obj2;
+    QDictCmpData d_new, *d = opaque;
+
+    if (!d->result) {
+        return;
+    }
+
+    obj2 = qdict_get(d->expect, key);
+    if (!obj2) {
+        d->result = false;
+        return;
+    }
+
+    if (qobject_type(obj1) != qobject_type(obj2)) {
+        d->result = false;
+        return;
+    }
+
+    switch (qobject_type(obj1)) {
+    case QTYPE_QBOOL:
+        d->result = (qbool_get_int(qobject_to_qbool(obj1)) ==
+                     qbool_get_int(qobject_to_qbool(obj2)));
+        return;
+    case QTYPE_QINT:
+        d->result = (qint_get_int(qobject_to_qint(obj1)) ==
+                     qint_get_int(qobject_to_qint(obj2)));
+        return;
+    case QTYPE_QSTRING:
+        d->result = g_strcmp0(qstring_get_str(qobject_to_qstring(obj1)),
+                              qstring_get_str(qobject_to_qstring(obj2))) == 0;
+        return;
+    case QTYPE_QDICT:
+        d_new.expect = qobject_to_qdict(obj2);
+        d_new.result = true;
+        qdict_iter(qobject_to_qdict(obj1), qdict_cmp_do_simple, &d_new);
+        d->result = d_new.result;
+        return;
+    default:
+        abort();
+    }
+}
+
+static bool qdict_cmp_simple(QDict *a, QDict *b)
+{
+    QDictCmpData d;
+
+    d.expect = b;
+    d.result = true;
+    qdict_iter(a, qdict_cmp_do_simple, &d);
+    return d.result;
+}
+
+/* This function is hooked as final emit function, which can verify the
+   correctness. */
+static void event_test_emit(TEST_QAPIEvent event, QDict *d, Error **errp)
+{
+    QObject *obj;
+    QDict *t;
+    int64_t s, ms;
+
+    /* Verify that we have timestamp, then remove it to compare other fields */
+    obj = qdict_get(d, "timestamp");
+    g_assert(obj);
+    t = qobject_to_qdict(obj);
+    g_assert(t);
+    obj = qdict_get(t, "seconds");
+    g_assert(obj && qobject_type(obj) == QTYPE_QINT);
+    s = qint_get_int(qobject_to_qint(obj));
+    obj = qdict_get(t, "microseconds");
+    g_assert(obj && qobject_type(obj) == QTYPE_QINT);
+    ms = qint_get_int(qobject_to_qint(obj));
+    if (s == -1) {
+        g_assert(ms == -1);
+    } else {
+        g_assert(ms >= 0 && ms <= 999999);
+    }
+    g_assert(qdict_size(t) == 2);
+
+    qdict_del(d, "timestamp");
+
+    g_assert(qdict_cmp_simple(d, test_event_data->expect));
+
+}
+
+static void event_prepare(TestEventData *data,
+                          const void *unused)
+{
+    /* Global variable test_event_data was used to pass the expectation, so
+       test cases can't be executed at same time. */
+    g_mutex_lock(&test_event_lock);
+
+    data->expect = qdict_new();
+    test_event_data = data;
+}
+
+static void event_teardown(TestEventData *data,
+                           const void *unused)
+{
+    QDECREF(data->expect);
+    test_event_data = NULL;
+
+    g_mutex_unlock(&test_event_lock);
+}
+
+static void event_test_add(const char *testpath,
+                           void (*test_func)(TestEventData *data,
+                                             const void *user_data))
+{
+    g_test_add(testpath, TestEventData, NULL, event_prepare, test_func,
+               event_teardown);
+}
+
+
+/* Test cases */
+
+static void test_event_a(TestEventData *data,
+                         const void *unused)
+{
+    QDict *d;
+    d = data->expect;
+    qdict_put(d, "event", qstring_from_str("EVENT_A"));
+    qapi_event_send_event_a(&error_abort);
+}
+
+static void test_event_b(TestEventData *data,
+                         const void *unused)
+{
+    QDict *d;
+    d = data->expect;
+    qdict_put(d, "event", qstring_from_str("EVENT_B"));
+    qapi_event_send_event_b(&error_abort);
+}
+
+static void test_event_c(TestEventData *data,
+                         const void *unused)
+{
+    QDict *d, *d_data, *d_b;
+
+    UserDefOne b;
+    UserDefZero z;
+    z.integer = 2;
+    b.base = &z;
+    b.string = g_strdup("test1");
+    b.has_enum1 = false;
+
+    d_b = qdict_new();
+    qdict_put(d_b, "integer", qint_from_int(2));
+    qdict_put(d_b, "string", qstring_from_str("test1"));
+
+    d_data = qdict_new();
+    qdict_put(d_data, "a", qint_from_int(1));
+    qdict_put(d_data, "b", d_b);
+    qdict_put(d_data, "c", qstring_from_str("test2"));
+
+    d = data->expect;
+    qdict_put(d, "event", qstring_from_str("EVENT_C"));
+    qdict_put(d, "data", d_data);
+
+    qapi_event_send_event_c(true, 1, true, &b, "test2", &error_abort);
+
+    g_free(b.string);
+}
+
+/* Complex type */
+static void test_event_d(TestEventData *data,
+                         const void *unused)
+{
+    UserDefOne struct1;
+    EventStructOne a;
+    UserDefZero z;
+    QDict *d, *d_data, *d_a, *d_struct1;
+
+    z.integer = 2;
+    struct1.base = &z;
+    struct1.string = g_strdup("test1");
+    struct1.has_enum1 = true;
+    struct1.enum1 = ENUM_ONE_VALUE1;
+
+    a.struct1 = &struct1;
+    a.string = g_strdup("test2");
+    a.has_enum2 = true;
+    a.enum2 = ENUM_ONE_VALUE2;
+
+    d_struct1 = qdict_new();
+    qdict_put(d_struct1, "integer", qint_from_int(2));
+    qdict_put(d_struct1, "string", qstring_from_str("test1"));
+    qdict_put(d_struct1, "enum1", qstring_from_str("value1"));
+
+    d_a = qdict_new();
+    qdict_put(d_a, "struct1", d_struct1);
+    qdict_put(d_a, "string", qstring_from_str("test2"));
+    qdict_put(d_a, "enum2", qstring_from_str("value2"));
+
+    d_data = qdict_new();
+    qdict_put(d_data, "a", d_a);
+    qdict_put(d_data, "b", qstring_from_str("test3"));
+    qdict_put(d_data, "enum3", qstring_from_str("value3"));
+
+    d = data->expect;
+    qdict_put(d, "event", qstring_from_str("EVENT_D"));
+    qdict_put(d, "data", d_data);
+
+    qapi_event_send_event_d(&a, "test3", false, NULL, true, ENUM_ONE_VALUE3,
+                           &error_abort);
+
+    g_free(struct1.string);
+    g_free(a.string);
+}
+
+int main(int argc, char **argv)
+{
+    qmp_event_set_func_emit(event_test_emit);
+
+    g_test_init(&argc, &argv, NULL);
+
+    event_test_add("/event/event_a", test_event_a);
+    event_test_add("/event/event_b", test_event_b);
+    event_test_add("/event/event_c", test_event_c);
+    event_test_add("/event/event_d", test_event_d);
+    g_test_run();
+
+    return 0;
+}
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 06/36] qapi: adjust existing defines
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (4 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 05/36] test: add test cases for qapi event Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 07/36] monitor: add an implemention of qapi event emit method Paolo Bonzini
                   ` (32 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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,
                                        true, -ret);
-            if (action == BDRV_ACTION_STOP) {
+            if (action == BLOCK_ERROR_ACTION_STOP) {
                 n = 0;
                 continue;
             }
             if (error == 0) {
                 error = ret;
             }
-            if (action == BDRV_ACTION_REPORT) {
+            if (action == BLOCK_ERROR_ACTION_REPORT) {
                 break;
             }
         }
diff --git a/blockjob.c b/blockjob.c
index 7d84ca1..bc63d42 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -262,22 +262,23 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
 
     switch (on_err) {
     case BLOCKDEV_ON_ERROR_ENOSPC:
-        action = (error == ENOSPC) ? BDRV_ACTION_STOP : BDRV_ACTION_REPORT;
+        action = (error == ENOSPC) ?
+                 BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
         break;
     case BLOCKDEV_ON_ERROR_STOP:
-        action = BDRV_ACTION_STOP;
+        action = BLOCK_ERROR_ACTION_STOP;
         break;
     case BLOCKDEV_ON_ERROR_REPORT:
-        action = BDRV_ACTION_REPORT;
+        action = BLOCK_ERROR_ACTION_REPORT;
         break;
     case BLOCKDEV_ON_ERROR_IGNORE:
-        action = BDRV_ACTION_IGNORE;
+        action = BLOCK_ERROR_ACTION_IGNORE;
         break;
     default:
         abort();
     }
     bdrv_emit_qmp_error_event(job->bs, QEVENT_BLOCK_JOB_ERROR, action, is_read);
-    if (action == BDRV_ACTION_STOP) {
+    if (action == BLOCK_ERROR_ACTION_STOP) {
         block_job_pause(job);
         block_job_iostatus_set_err(job, error);
         if (bs != job->bs) {
diff --git a/hmp.c b/hmp.c
index ccc35d4..1174bab 100644
--- a/hmp.c
+++ b/hmp.c
@@ -463,7 +463,8 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
         for (client = info->clients; client; client = client->next) {
             monitor_printf(mon, "Client:\n");
             monitor_printf(mon, "     address: %s:%s\n",
-                           client->value->host, client->value->service);
+                           client->value->base->host,
+                           client->value->base->service);
             monitor_printf(mon, "  x509_dname: %s\n",
                            client->value->x509_dname ?
                            client->value->x509_dname : "none");
@@ -511,7 +512,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict)
         for (chan = info->channels; chan; chan = chan->next) {
             monitor_printf(mon, "Channel:\n");
             monitor_printf(mon, "     address: %s:%s%s\n",
-                           chan->value->host, chan->value->port,
+                           chan->value->base->host, chan->value->base->port,
                            chan->value->tls ? " [tls]" : "");
             monitor_printf(mon, "     session: %" PRId64 "\n",
                            chan->value->connection_id);
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 85aa871..08562ea 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -56,17 +56,17 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
     BlockErrorAction action = bdrv_get_error_action(req->dev->bs, is_read, error);
     VirtIOBlock *s = req->dev;
 
-    if (action == BDRV_ACTION_STOP) {
+    if (action == BLOCK_ERROR_ACTION_STOP) {
         req->next = s->rq;
         s->rq = req;
-    } else if (action == BDRV_ACTION_REPORT) {
+    } else if (action == BLOCK_ERROR_ACTION_REPORT) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
         bdrv_acct_done(s->bs, &req->acct);
         g_free(req);
     }
 
     bdrv_error_action(s->bs, action, is_read, error);
-    return action != BDRV_ACTION_IGNORE;
+    return action != BLOCK_ERROR_ACTION_IGNORE;
 }
 
 static void virtio_blk_rw_complete(void *opaque, int ret)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 1cac5f5..3a38f1e 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -596,10 +596,10 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
     bool is_read = (op & BM_STATUS_RETRY_READ) != 0;
     BlockErrorAction action = bdrv_get_error_action(s->bs, is_read, error);
 
-    if (action == BDRV_ACTION_STOP) {
+    if (action == BLOCK_ERROR_ACTION_STOP) {
         s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
         s->bus->error_status = op;
-    } else if (action == BDRV_ACTION_REPORT) {
+    } else if (action == BLOCK_ERROR_ACTION_REPORT) {
         if (op & BM_STATUS_DMA_RETRY) {
             dma_buf_commit(s);
             ide_dma_error(s);
@@ -608,7 +608,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
         }
     }
     bdrv_error_action(s->bs, action, is_read, error);
-    return action != BDRV_ACTION_IGNORE;
+    return action != BLOCK_ERROR_ACTION_IGNORE;
 }
 
 void ide_dma_cb(void *opaque, int ret)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index fc6e32a..15f7721 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -419,7 +419,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
     BlockErrorAction action = bdrv_get_error_action(s->qdev.conf.bs, is_read, error);
 
-    if (action == BDRV_ACTION_REPORT) {
+    if (action == BLOCK_ERROR_ACTION_REPORT) {
         switch (error) {
         case ENOMEDIUM:
             scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
@@ -439,10 +439,10 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
         }
     }
     bdrv_error_action(s->qdev.conf.bs, action, is_read, error);
-    if (action == BDRV_ACTION_STOP) {
+    if (action == BLOCK_ERROR_ACTION_STOP) {
         scsi_req_retry(&r->req);
     }
-    return action != BDRV_ACTION_IGNORE;
+    return action != BLOCK_ERROR_ACTION_IGNORE;
 }
 
 static void scsi_write_complete(void * opaque, int ret)
diff --git a/include/block/block.h b/include/block/block.h
index f15b99b..d0baf4f 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -150,10 +150,6 @@ typedef enum {
 #define BDRV_BLOCK_ALLOCATED    0x10
 #define BDRV_BLOCK_OFFSET_MASK  BDRV_SECTOR_MASK
 
-typedef enum {
-    BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
-} BlockErrorAction;
-
 typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
 
 typedef struct BDRVReopenState {
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 45588d7..af24669 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -29,6 +29,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
 #include "qemu/option.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qerror.h"
+#include "qapi-types.h"
 
 extern QemuOptsList socket_optslist;
 
@@ -61,6 +62,7 @@ int inet_nonblocking_connect(const char *str,
 
 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);
 int unix_listen(const char *path, char *ostr, int olen, Error **errp);
diff --git a/qapi-schema.json b/qapi-schema.json
index dc2abe4..3d23042 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -630,21 +630,59 @@
 { 'command': 'query-iothreads', 'returns': ['IOThreadInfo'] }
 
 ##
-# @VncClientInfo:
+# @NetworkAddressFamily
 #
-# Information about a connected VNC client.
+# The network address family
+#
+# @ipv4: IPV4 family
+#
+# @ipv6: IPV6 family
+#
+# @unix: unix socket
+#
+# @unknown: otherwise
+#
+# Since: 2.1
+##
+{ 'enum': 'NetworkAddressFamily',
+  'data': [ 'ipv4', 'ipv6', 'unix', 'unknown' ] }
+
+##
+# @VncBasicInfo
 #
-# @host: The host name of the client.  QEMU tries to resolve this to a DNS name
-#        when possible.
+# The basic information for vnc network connection
 #
-# @family: 'ipv6' if the client is connected via IPv6 and TCP
-#          'ipv4' if the client is connected via IPv4 and TCP
-#          'unix' if the client is connected via a unix domain socket
-#          'unknown' otherwise
+# @host: IP address
 #
-# @service: The service name of the client's port.  This may depends on the
-#           host system's service database so symbolic names should not be
-#           relied on.
+# @service: The service name of vnc port. This may depend on the host system's
+#           service database so symbolic names should not be relied on.
+#
+# @family: address family
+#
+# Since: 2.1
+##
+{ 'type': 'VncBasicInfo',
+  'data': { 'host': 'str',
+            'service': 'str',
+            'family': 'NetworkAddressFamily' } }
+
+##
+# @VncServerInfo
+#
+# The network connection information for server
+#
+# @auth: #optional, authentication method
+#
+# Since: 2.1
+##
+{ 'type': 'VncServerInfo',
+  'base': 'VncBasicInfo',
+  'data': { '*auth': 'str' } }
+
+##
+# @VncClientInfo:
+#
+# Information about a connected VNC client.
 #
 # @x509_dname: #optional If x509 authentication is in use, the Distinguished
 #              Name of the client.
@@ -655,8 +693,8 @@
 # Since: 0.14.0
 ##
 { 'type': 'VncClientInfo',
-  'data': {'host': 'str', 'family': 'str', 'service': 'str',
-           '*x509_dname': 'str', '*sasl_username': 'str'} }
+  'base': 'VncBasicInfo',
+  'data': { '*x509_dname'   : 'str', '*sasl_username': 'str' } }
 
 ##
 # @VncInfo:
@@ -695,7 +733,8 @@
 # Since: 0.14.0
 ##
 { 'type': 'VncInfo',
-  'data': {'enabled': 'bool', '*host': 'str', '*family': 'str',
+  'data': {'enabled': 'bool', '*host': 'str',
+           '*family': 'NetworkAddressFamily',
            '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }
 
 ##
@@ -710,19 +749,40 @@
 { 'command': 'query-vnc', 'returns': 'VncInfo' }
 
 ##
-# @SpiceChannel
+# @SpiceBasicInfo
 #
-# Information about a SPICE client channel.
+# The basic information for SPICE network connection
+#
+# @host: IP address
 #
-# @host: The host name of the client.  QEMU tries to resolve this to a DNS name
-#        when possible.
+# @port: port number
 #
-# @family: 'ipv6' if the client is connected via IPv6 and TCP
-#          'ipv4' if the client is connected via IPv4 and TCP
-#          'unix' if the client is connected via a unix domain socket
-#          'unknown' otherwise
+# @family: address family
 #
-# @port: The client's port number.
+# Since: 2.1
+##
+{ 'type': 'SpiceBasicInfo',
+  'data': { 'host': 'str',
+            'port': 'str',
+            'family': 'NetworkAddressFamily' } }
+
+##
+# @SpiceServerInfo
+#
+# Information about a SPICE server
+#
+# @auth: #optional, authentication method
+#
+# Since: 2.1
+##
+{ 'type': 'SpiceServerInfo',
+  'base': 'SpiceBasicInfo',
+  'data': { '*auth': 'str' } }
+
+##
+# @SpiceChannel
+#
+# Information about a SPICE client channel.
 #
 # @connection-id: SPICE connection id number.  All channels with the same id
 #                 belong to the same SPICE session.
@@ -740,8 +800,8 @@
 # Since: 0.14.0
 ##
 { 'type': 'SpiceChannel',
-  'data': {'host': 'str', 'family': 'str', 'port': 'str',
-           'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',
+  'base': 'SpiceBasicInfo',
+  'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',
            'tls': 'bool'} }
 
 ##
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 7215e48..b7f36c6 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1410,3 +1410,19 @@
 ##
 { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
 
+
+##
+# @BlockErrorAction
+#
+# An enumeration of action that has been taken when a DISK I/O occurs
+#
+# @ignore: error has been ignored
+#
+# @report: error has been reported to the device
+#
+# @stop: error caused VM to be stopped
+#
+# Since: 2.1
+##
+{ 'enum': 'BlockErrorAction',
+  'data': [ 'ignore', 'report', 'stop' ] }
diff --git a/ui/spice-core.c b/ui/spice-core.c
index d10818a..8d54fb3 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -391,15 +391,16 @@ static SpiceChannelList *qmp_query_spice_channels(void)
 
         chan = g_malloc0(sizeof(*chan));
         chan->value = g_malloc0(sizeof(*chan->value));
+        chan->value->base = g_malloc0(sizeof(*chan->value->base));
 
         paddr = (struct sockaddr *)&item->info->paddr_ext;
         plen = item->info->plen_ext;
         getnameinfo(paddr, plen,
                     host, sizeof(host), port, sizeof(port),
                     NI_NUMERICHOST | NI_NUMERICSERV);
-        chan->value->host = g_strdup(host);
-        chan->value->port = g_strdup(port);
-        chan->value->family = g_strdup(inet_strfamily(paddr->sa_family));
+        chan->value->base->host = g_strdup(host);
+        chan->value->base->port = g_strdup(port);
+        chan->value->base->family = inet_netfamily(paddr->sa_family);
 
         chan->value->connection_id = item->info->connection_id;
         chan->value->channel_type = item->info->type;
diff --git a/ui/vnc.c b/ui/vnc.c
index 1684206..95eee5a 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -321,9 +321,10 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client)
     }
 
     info = g_malloc0(sizeof(*info));
-    info->host = g_strdup(host);
-    info->service = g_strdup(serv);
-    info->family = g_strdup(inet_strfamily(sa.ss_family));
+    info->base = g_malloc0(sizeof(*info->base));
+    info->base->host = g_strdup(host);
+    info->base->service = g_strdup(serv);
+    info->base->family = inet_netfamily(sa.ss_family);
 
 #ifdef CONFIG_VNC_TLS
     if (client->tls.session && client->tls.dname) {
@@ -398,7 +399,7 @@ VncInfo *qmp_query_vnc(Error **errp)
         info->service = g_strdup(serv);
 
         info->has_family = true;
-        info->family = g_strdup(inet_strfamily(sa.ss_family));
+        info->family = inet_netfamily(sa.ss_family);
 
         info->has_auth = true;
         info->auth = g_strdup(vnc_auth_name(vnc_display));
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index a4a1e9d..447720f 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -102,6 +102,16 @@ const char *inet_strfamily(int family)
     return "unknown";
 }
 
+NetworkAddressFamily inet_netfamily(int family)
+{
+    switch (family) {
+    case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6;
+    case PF_INET:  return NETWORK_ADDRESS_FAMILY_IPV4;
+    case PF_UNIX:  return NETWORK_ADDRESS_FAMILY_UNIX;
+    }
+    return NETWORK_ADDRESS_FAMILY_UNKNOWN;
+}
+
 int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
 {
     struct addrinfo ai,*res,*e;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 07/36] monitor: add an implemention of qapi event emit method
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (5 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 06/36] qapi: adjust existing defines Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19  4:03   ` Eric Blake
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 08/36] qapi: add new schema file qapi-event.json Paolo Bonzini
                   ` (31 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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);
+    evstate->event = event;
+    evstate->rate = rate * SCALE_MS;
+    evstate->last = 0;
+    evstate->data = NULL;
+    evstate->timer = timer_new(QEMU_CLOCK_REALTIME,
+                               SCALE_MS,
+                               monitor_qapi_event_handler,
+                               evstate);
+}
+
+static void monitor_qapi_event_init(void)
+{
+    qmp_event_set_func_emit(monitor_qapi_event_queue);
+}
+
 
 /*
  * Emits the event to every monitor instance
@@ -588,7 +713,7 @@ static void monitor_protocol_event_handler(void *opaque)
  * more than 1 event will be emitted within @rate
  * milliseconds
  */
-static void
+static void __attribute__((__unused__))
 monitor_protocol_event_throttle(MonitorEvent event,
                                 int64_t rate)
 {
@@ -5350,6 +5475,7 @@ void monitor_init(CharDriverState *chr, int flags)
 
     if (is_first_init) {
         monitor_protocol_event_init();
+        monitor_qapi_event_init();
         sortcmdlist();
         is_first_init = 0;
     }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 08/36] qapi: add new schema file qapi-event.json
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (6 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 07/36] monitor: add an implemention of qapi event emit method Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19  4:04   ` Eric Blake
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 09/36] qapi event: convert SHUTDOWN Paolo Bonzini
                   ` (30 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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 0000000..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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 09/36] qapi event: convert SHUTDOWN
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (7 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 08/36] qapi: add new schema file qapi-event.json Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 10/36] qapi event: convert POWERDOWN Paolo Bonzini
                   ` (29 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

This patch also eliminates build time warning caused by
QAPI_EVENT_MAX = 0.

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 10/36] qapi event: convert POWERDOWN
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (8 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 09/36] qapi event: convert SHUTDOWN Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 11/36] qapi event: convert RESET Paolo Bonzini
                   ` (28 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 11/36] qapi event: convert RESET
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (9 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 10/36] qapi event: convert POWERDOWN Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 12/36] qapi event: convert STOP Paolo Bonzini
                   ` (27 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 12/36] qapi event: convert STOP
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (10 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 11/36] qapi event: convert RESET Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19 18:15   ` Luiz Capitulino
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 13/36] qapi event: convert RESUME Paolo Bonzini
                   ` (26 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 13/36] qapi event: convert RESUME
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (11 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 12/36] qapi event: convert STOP Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 14/36] qapi event: convert SUSPEND Paolo Bonzini
                   ` (25 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 14/36] qapi event: convert SUSPEND
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (12 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 13/36] qapi event: convert RESUME Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 15/36] qapi event: convert SUSPEND_DISK Paolo Bonzini
                   ` (24 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 15/36] qapi event: convert SUSPEND_DISK
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (13 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 14/36] qapi event: convert SUSPEND Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 16/36] qapi event: convert WAKEUP Paolo Bonzini
                   ` (23 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 16/36] qapi event: convert WAKEUP
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (14 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 15/36] qapi event: convert SUSPEND_DISK Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 17/36] qapi event: convert RTC_CHANGE Paolo Bonzini
                   ` (22 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 17/36] qapi event: convert RTC_CHANGE
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (15 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 16/36] qapi event: convert WAKEUP Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19  4:06   ` Eric Blake
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 18/36] qapi event: convert WATCHDOG Paolo Bonzini
                   ` (21 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

This patch also eliminates build time warning caused by no caller
of monitor_qapi_event_throttle().

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 18/36] qapi event: convert WATCHDOG
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (16 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 17/36] qapi event: convert RTC_CHANGE Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 19/36] qapi event: convert DEVICE_DELETED Paolo Bonzini
                   ` (20 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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_RESET        1	/* 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': 'WatchdogExpirationAction' } }
diff --git a/qapi-schema.json b/qapi-schema.json
index 26e0278..33d76bc 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3141,4 +3141,28 @@
               'rel'     : 'InputMoveEvent',
               'abs'     : 'InputMoveEvent' } }
 
+##
+# @WatchdogExpirationAction
+#
+# An enumeration of the actions taken when the watchdog device's timer is
+# expired
+#
+# @reset: system resets
+#
+# @shutdown: system shutdown, note that it is similar to @powerdown, which
+#            tries to set to system status and notify guest
+#
+# @poweroff: system poweroff, the emulator program exits
+#
+# @pause: system pauses, similar to @stop
+#
+# @debug: system enters debug state
+#
+# @none: nothing is done
+#
+# Since: 2.1
+##
+{ 'enum': 'WatchdogExpirationAction',
+  'data': [ 'reset', 'shutdown', 'poweroff', 'pause', 'debug', 'none' ] }
+
 { 'include': 'qapi-event.json' }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 19/36] qapi event: convert DEVICE_DELETED
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (17 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 18/36] qapi event: convert WATCHDOG Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 20/36] qapi event: convert DEVICE_TRAY_MOVED Paolo Bonzini
                   ` (19 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 20/36] qapi event: convert DEVICE_TRAY_MOVED
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (18 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 19/36] qapi event: convert DEVICE_DELETED Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR Paolo Bonzini
                   ` (18 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (19 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 20/36] qapi event: convert DEVICE_TRAY_MOVED Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-26 15:37   ` Markus Armbruster
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 22/36] qapi event: convert BLOCK_IMAGE_CORRUPTED Paolo Bonzini
                   ` (17 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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 and the job canceled
-    "stop": error caused job to be paused
-
-Example:
-
-{ "event": "BLOCK_JOB_ERROR",
-    "data": { "device": "ide0-hd1",
-              "operation": "write",
-              "action": "stop" },
-    "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
 BLOCK_JOB_READY
 ---------------
 
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 7aa2213..715c761 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -425,9 +425,6 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
 #ifdef _WIN32
 int is_windows_drive(const char *filename);
 #endif
-void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
-                               enum MonitorEvent ev,
-                               BlockErrorAction action, bool is_read);
 
 /**
  * stream_start:
diff --git a/qapi-schema.json b/qapi-schema.json
index 33d76bc..0a8df60 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3165,4 +3165,18 @@
 { 'enum': 'WatchdogExpirationAction',
   'data': [ 'reset', 'shutdown', 'poweroff', 'pause', 'debug', 'none' ] }
 
+##
+# @IoOperationType
+#
+# An enumeration of the I/O operation types
+#
+# @read: read operation
+#
+# @write: write operation
+#
+# Since: 2.1
+##
+{ 'enum': 'IoOperationType',
+  'data': [ 'read', 'write' ] }
+
 { 'include': 'qapi-event.json' }
diff --git a/qapi/block-core.json b/qapi/block-core.json
index b7f36c6..682864d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1426,3 +1426,42 @@
 ##
 { 'enum': 'BlockErrorAction',
   'data': [ 'ignore', 'report', 'stop' ] }
+
+
+##
+# @BLOCK_IO_ERROR
+#
+# Emitted when a disk I/O error occurs
+#
+# @device: device name
+#
+# @operation: I/O operation
+#
+# @action: action that has been taken
+#
+# Note: If action is "stop", a STOP event will eventually follow the
+# BLOCK_IO_ERROR event
+#
+# Since: 0.13.0
+##
+{ 'event': 'BLOCK_IO_ERROR',
+  'data': { 'device': 'str', 'operation': 'IoOperationType',
+            'action': 'BlockErrorAction' } }
+
+##
+# @BLOCK_JOB_ERROR
+#
+# Emitted when a block job encounters an error
+#
+# @device: device name
+#
+# @operation: I/O operation
+#
+# @action: action that has been taken
+#
+# Since: 1.3
+##
+{ 'event': 'BLOCK_JOB_ERROR',
+  'data': { 'device'   : 'str',
+            'operation': 'IoOperationType',
+            'action'   : 'BlockdevOnError' } }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 22/36] qapi event: convert BLOCK_IMAGE_CORRUPTED
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (20 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19  4:09   ` Eric Blake
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events Paolo Bonzini
                   ` (16 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (21 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 22/36] qapi event: convert BLOCK_IMAGE_CORRUPTED Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19  4:11   ` Eric Blake
  2014-06-26 14:08   ` Markus Armbruster
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 24/36] qapi event: convert NIC_RX_FILTER_CHANGED Paolo Bonzini
                   ` (15 subsequent siblings)
  38 siblings, 2 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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 progress value (json-int)
-              On success this is equal to len.
-              On failure this is less than len.
-- "speed":    Rate limit, bytes per second (json-int)
-
-Example:
-
-{ "event": "BLOCK_JOB_CANCELLED",
-     "data": { "type": "stream", "device": "virtio-disk0",
-               "len": 10737418240, "offset": 134217728,
-               "speed": 0 },
-     "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-BLOCK_JOB_COMPLETED
--------------------
-
-Emitted when a block job has completed.
-
-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 progress value (json-int)
-              On success this is equal to len.
-              On failure this is less than len.
-- "speed":    Rate limit, bytes per second (json-int)
-- "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 streaming
-              has failed and clients should not try to interpret the error
-              string.
-
-Example:
-
-{ "event": "BLOCK_JOB_COMPLETED",
-     "data": { "type": "stream", "device": "virtio-disk0",
-               "len": 10737418240, "offset": 10737418240,
-               "speed": 0 },
-     "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-BLOCK_JOB_READY
----------------
-
-Emitted when a block job is ready to complete.
-
-Data:
-
-- "device": device name (json-string)
-
-Example:
-
-{ "event": "BLOCK_JOB_READY",
-    "data": { "device": "ide0-hd1" },
-    "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-Note: The "ready to complete" status is always reset by a BLOCK_JOB_ERROR
-event.
-
 GUEST_PANICKED
 --------------
 
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index c0a7875..e443987 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -217,12 +217,21 @@ void block_job_pause(BlockJob *job);
 void block_job_resume(BlockJob *job);
 
 /**
- * qobject_from_block_job:
+ * block_job_event_cancle:
  * @job: The job whose information is requested.
  *
- * Return a QDict corresponding to @job's query-block-jobs entry.
+ * Send a BLOCK_JOB_CANCELLED event for the specified job.
  */
-QObject *qobject_from_block_job(BlockJob *job);
+void block_job_event_cancelled(BlockJob *job);
+
+/**
+ * block_job_ready:
+ * @job: The job which is now ready to complete.
+ * @msg: Error message. Only present on failure.
+ *
+ * Send a BLOCK_JOB_COMPLETED event for the specified job.
+ */
+void block_job_event_completed(BlockJob *job, const char *msg);
 
 /**
  * block_job_ready:
@@ -230,7 +239,7 @@ QObject *qobject_from_block_job(BlockJob *job);
  *
  * Send a BLOCK_JOB_READY event for the specified job.
  */
-void block_job_ready(BlockJob *job);
+void block_job_event_ready(BlockJob *job);
 
 /**
  * block_job_is_paused:
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 2dbac42..af6b436 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1473,6 +1473,62 @@
             'action': 'BlockErrorAction' } }
 
 ##
+# @BLOCK_JOB_COMPLETED
+#
+# Emitted when a block job has completed
+#
+# @type: job type
+#
+# @device: device name
+#
+# @len: maximum progress value
+#
+# @offset: current progress value. On success this is equal to len.
+#          On failure this is less than len
+#
+# @speed: rate limit, bytes per second
+#
+# @error: #optional, error message. Only present on failure. This field
+#         contains a human-readable error message. There are no semantics
+#         other than that streaming has failed and clients should not try to
+#         interpret the error string
+#
+# Since: 1.1
+##
+{ 'event': 'BLOCK_JOB_COMPLETED',
+  'data': { 'type'  : 'BlockJobType',
+            'device': 'str',
+            'len'   : 'int',
+            'offset': 'int',
+            'speed' : 'int',
+            '*error': 'str' } }
+
+##
+# @BLOCK_JOB_CANCELLED
+#
+# Emitted when a block job has been cancelled
+#
+# @type: job type
+#
+# @device: device name
+#
+# @len: maximum progress value
+#
+# @offset: current progress value. On success this is equal to len.
+#          On failure this is less than len
+#
+# @speed: rate limit, bytes per second
+#
+# Since: 1.1
+##
+{ 'event': 'BLOCK_JOB_CANCELLED',
+  'data': { 'type'  : 'BlockJobType',
+            'device': 'str',
+            'len'   : 'int',
+            'offset': 'int',
+            'speed' : 'int' } }
+
+##
 # @BLOCK_JOB_ERROR
 #
 # Emitted when a block job encounters an error
@@ -1489,3 +1545,18 @@
   'data': { 'device'   : 'str',
             'operation': 'IoOperationType',
             'action'   : 'BlockdevOnError' } }
+
+##
+# @BLOCK_JOB_READY
+#
+# Emitted when a block job is ready to complete
+#
+# @device: device name
+#
+# Note: The "ready to complete" status is always reset by a @BLOCK_JOB_ERROR
+# event
+#
+# Since: 1.3
+##
+{ 'event': 'BLOCK_JOB_READY',
+  'data': { 'device': 'str' } }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 24/36] qapi event: convert NIC_RX_FILTER_CHANGED
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (22 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 25/36] qapi event: convert VNC events Paolo Bonzini
                   ` (14 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Param name is declared as optional, since in code it is an optional
one.

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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_VERSION    11
 
@@ -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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 25/36] qapi event: convert VNC events
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (23 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 24/36] qapi event: convert NIC_RX_FILTER_CHANGED Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 26/36] qapi event: convert SPICE events Paolo Bonzini
                   ` (13 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Since VNC_CONNECTED, VNC_DISCONNECTED, VNC_INITIALIZED share some
common functions, convert them in one patch.

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -35,6 +35,7 @@
 #include "qmp-commands.h"
 #include "qemu/osdep.h"
 #include "ui/input.h"
+#include "qapi-event.h"
 
 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
 #define VNC_REFRESH_INTERVAL_INC  50
@@ -124,9 +125,10 @@ char *vnc_socket_remote_addr(const char *format, int fd) {
     return addr_to_string(format, &sa, salen);
 }
 
-static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa,
-                          socklen_t salen)
+static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
+                                        socklen_t salen)
 {
+    VncBasicInfo *info;
     char host[NI_MAXHOST];
     char serv[NI_MAXSERV];
     int err;
@@ -137,40 +139,40 @@ static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa,
                            NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
         VNC_DEBUG("Cannot resolve address %d: %s\n",
                   err, gai_strerror(err));
-        return -1;
+        return NULL;
     }
 
-    qdict_put(qdict, "host", qstring_from_str(host));
-    qdict_put(qdict, "service", qstring_from_str(serv));
-    qdict_put(qdict, "family",qstring_from_str(inet_strfamily(sa->ss_family)));
-
-    return 0;
+    info = g_malloc0(sizeof(VncBasicInfo));
+    info->host = g_strdup(host);
+    info->service = g_strdup(serv);
+    info->family = inet_netfamily(sa->ss_family);
+    return info;
 }
 
-static int vnc_server_addr_put(QDict *qdict, int fd)
+static VncBasicInfo *vnc_basic_info_get_from_server_addr(int fd)
 {
     struct sockaddr_storage sa;
     socklen_t salen;
 
     salen = sizeof(sa);
     if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
-        return -1;
+        return NULL;
     }
 
-    return put_addr_qdict(qdict, &sa, salen);
+    return vnc_basic_info_get(&sa, salen);
 }
 
-static int vnc_qdict_remote_addr(QDict *qdict, int fd)
+static VncBasicInfo *vnc_basic_info_get_from_remote_addr(int fd)
 {
     struct sockaddr_storage sa;
     socklen_t salen;
 
     salen = sizeof(sa);
     if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
-        return -1;
+        return NULL;
     }
 
-    return put_addr_qdict(qdict, &sa, salen);
+    return vnc_basic_info_get(&sa, salen);
 }
 
 static const char *vnc_auth_name(VncDisplay *vd) {
@@ -224,81 +226,82 @@ static const char *vnc_auth_name(VncDisplay *vd) {
     return "unknown";
 }
 
-static int vnc_server_info_put(QDict *qdict)
+static VncServerInfo *vnc_server_info_get(void)
 {
-    if (vnc_server_addr_put(qdict, vnc_display->lsock) < 0) {
-        return -1;
+    VncServerInfo *info;
+    VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vnc_display->lsock);
+    if (!bi) {
+        return NULL;
     }
 
-    qdict_put(qdict, "auth", qstring_from_str(vnc_auth_name(vnc_display)));
-    return 0;
+    info = g_malloc(sizeof(*info));
+    info->base = bi;
+    info->has_auth = true;
+    info->auth = g_strdup(vnc_auth_name(vnc_display));
+    return info;
 }
 
 static void vnc_client_cache_auth(VncState *client)
 {
-#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
-    QDict *qdict;
-#endif
-
     if (!client->info) {
         return;
     }
 
-#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
-    qdict = qobject_to_qdict(client->info);
-#endif
-
 #ifdef CONFIG_VNC_TLS
     if (client->tls.session &&
         client->tls.dname) {
-        qdict_put(qdict, "x509_dname", qstring_from_str(client->tls.dname));
+        client->info->has_x509_dname = true;
+        client->info->x509_dname = g_strdup(client->tls.dname);
     }
 #endif
 #ifdef CONFIG_VNC_SASL
     if (client->sasl.conn &&
         client->sasl.username) {
-        qdict_put(qdict, "sasl_username",
-                  qstring_from_str(client->sasl.username));
+        client->info->has_sasl_username = true;
+        client->info->sasl_username = g_strdup(client->sasl.username);
     }
 #endif
 }
 
 static void vnc_client_cache_addr(VncState *client)
 {
-    QDict *qdict;
+    VncBasicInfo *bi = vnc_basic_info_get_from_remote_addr(client->csock);
 
-    qdict = qdict_new();
-    if (vnc_qdict_remote_addr(qdict, client->csock) < 0) {
-        QDECREF(qdict);
-        /* XXX: how to report the error? */
-        return;
+    if (bi) {
+        client->info = g_malloc0(sizeof(*client->info));
+        client->info->base = bi;
     }
-
-    client->info = QOBJECT(qdict);
 }
 
-static void vnc_qmp_event(VncState *vs, MonitorEvent event)
+static void vnc_qmp_event(VncState *vs, QAPIEvent event)
 {
-    QDict *server;
-    QObject *data;
+    VncServerInfo *si;
 
     if (!vs->info) {
         return;
     }
+    g_assert(vs->info->base);
 
-    server = qdict_new();
-    if (vnc_server_info_put(server) < 0) {
-        QDECREF(server);
+    si = vnc_server_info_get();
+    if (!si) {
         return;
     }
 
-    data = qobject_from_jsonf("{ 'client': %p, 'server': %p }",
-                              vs->info, QOBJECT(server));
-
-    monitor_protocol_event(event, data);
+    switch (event) {
+    case QAPI_EVENT_VNC_CONNECTED:
+        qapi_event_send_vnc_connected(si, vs->info->base, &error_abort);
+        break;
+    case QAPI_EVENT_VNC_INITIALIZED:
+        qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
+        break;
+    case QAPI_EVENT_VNC_DISCONNECTED:
+        qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
+        break;
+    default:
+        break;
+    }
 
-    qobject_incref(vs->info);
-    qobject_decref(data);
+    qapi_free_VncServerInfo(si);
 }
 
 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
@@ -1037,7 +1040,7 @@ void vnc_disconnect_finish(VncState *vs)
     vnc_jobs_join(vs); /* Wait encoding jobs */
 
     vnc_lock_output(vs);
-    vnc_qmp_event(vs, QEVENT_VNC_DISCONNECTED);
+    vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
 
     buffer_free(&vs->input);
     buffer_free(&vs->output);
@@ -1046,7 +1049,7 @@ void vnc_disconnect_finish(VncState *vs)
     buffer_free(&vs->ws_output);
 #endif /* CONFIG_VNC_WS */
 
-    qobject_decref(vs->info);
+    qapi_free_VncClientInfo(vs->info);
 
     vnc_zlib_clear(vs);
     vnc_tight_clear(vs);
@@ -2321,7 +2324,7 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
     vnc_flush(vs);
 
     vnc_client_cache_auth(vs);
-    vnc_qmp_event(vs, QEVENT_VNC_INITIALIZED);
+    vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
 
     vnc_read_when(vs, protocol_client_msg, 1);
 
@@ -2844,7 +2847,7 @@ static void vnc_connect(VncDisplay *vd, int csock,
     }
 
     vnc_client_cache_addr(vs);
-    vnc_qmp_event(vs, QEVENT_VNC_CONNECTED);
+    vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
     vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
 
     vs->vd = vd;
diff --git a/ui/vnc.h b/ui/vnc.h
index 8da81b8..07af9f7 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -31,7 +31,6 @@
 #include "qemu/queue.h"
 #include "qemu/thread.h"
 #include "ui/console.h"
-#include "monitor/monitor.h"
 #include "audio/audio.h"
 #include "qemu/bitmap.h"
 #include <zlib.h>
@@ -40,6 +39,7 @@
 #include "keymaps.h"
 #include "vnc-palette.h"
 #include "vnc-enc-zrle.h"
+#include "qapi-types.h"
 
 // #define _VNC_DEBUG 1
 
@@ -292,7 +292,7 @@ struct VncState
     bool websocket;
 #endif /* CONFIG_VNC_WS */
 
-    QObject *info;
+    VncClientInfo *info;
 
     Buffer output;
     Buffer input;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 26/36] qapi event: convert SPICE events
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (24 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 25/36] qapi event: convert VNC events Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 27/36] qapi event: convert BALLOON_CHANGE Paolo Bonzini
                   ` (12 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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': { 'server': 'SpiceBasicInfo',
+            'client': 'SpiceBasicInfo' } }
+
+##
+# @SPICE_MIGRATE_COMPLETED
+#
+# Emitted when SPICE migration has completed
+#
+# Since: 1.3
+##
+{ 'event': 'SPICE_MIGRATE_COMPLETED' }
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 8d54fb3..70df446 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -35,9 +35,9 @@
 #include "qapi/qmp/qjson.h"
 #include "qemu/notify.h"
 #include "migration/migration.h"
-#include "monitor/monitor.h"
 #include "hw/hw.h"
 #include "ui/spice-display.h"
+#include "qapi-event.h"
 
 /* core bits */
 
@@ -174,39 +174,34 @@ static void channel_list_del(SpiceChannelEventInfo *info)
     }
 }
 
-static void add_addr_info(QDict *dict, struct sockaddr *addr, int len)
+static void add_addr_info(SpiceBasicInfo *info, struct sockaddr *addr, int len)
 {
     char host[NI_MAXHOST], port[NI_MAXSERV];
-    const char *family;
 
     getnameinfo(addr, len, host, sizeof(host), port, sizeof(port),
                 NI_NUMERICHOST | NI_NUMERICSERV);
-    family = inet_strfamily(addr->sa_family);
 
-    qdict_put(dict, "host", qstring_from_str(host));
-    qdict_put(dict, "port", qstring_from_str(port));
-    qdict_put(dict, "family", qstring_from_str(family));
+    info->host = g_strdup(host);
+    info->port = g_strdup(port);
+    info->family = inet_netfamily(addr->sa_family);
 }
 
-static void add_channel_info(QDict *dict, SpiceChannelEventInfo *info)
+static void add_channel_info(SpiceChannel *sc, SpiceChannelEventInfo *info)
 {
     int tls = info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS;
 
-    qdict_put(dict, "connection-id", qint_from_int(info->connection_id));
-    qdict_put(dict, "channel-type", qint_from_int(info->type));
-    qdict_put(dict, "channel-id", qint_from_int(info->id));
-    qdict_put(dict, "tls", qbool_from_int(tls));
+    sc->connection_id = info->connection_id;
+    sc->channel_type = info->type;
+    sc->channel_id = info->id;
+    sc->tls = !!tls;
 }
 
 static void channel_event(int event, SpiceChannelEventInfo *info)
 {
-    static const int qevent[] = {
-        [ SPICE_CHANNEL_EVENT_CONNECTED    ] = QEVENT_SPICE_CONNECTED,
-        [ SPICE_CHANNEL_EVENT_INITIALIZED  ] = QEVENT_SPICE_INITIALIZED,
-        [ SPICE_CHANNEL_EVENT_DISCONNECTED ] = QEVENT_SPICE_DISCONNECTED,
-    };
-    QDict *server, *client;
-    QObject *data;
+    SpiceServerInfo *server = g_malloc0(sizeof(*server));
+    SpiceChannel *client = g_malloc0(sizeof(*client));
+    server->base = g_malloc0(sizeof(*server->base));
+    client->base = g_malloc0(sizeof(*client->base));
 
     /*
      * Spice server might have called us from spice worker thread
@@ -222,36 +217,43 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
         qemu_mutex_lock_iothread();
     }
 
-    client = qdict_new();
-    server = qdict_new();
-
     if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
-        add_addr_info(client, (struct sockaddr *)&info->paddr_ext,
+        add_addr_info(client->base, (struct sockaddr *)&info->paddr_ext,
                       info->plen_ext);
-        add_addr_info(server, (struct sockaddr *)&info->laddr_ext,
+        add_addr_info(server->base, (struct sockaddr *)&info->laddr_ext,
                       info->llen_ext);
     } else {
         error_report("spice: %s, extended address is expected",
                      __func__);
     }
 
-    if (event == SPICE_CHANNEL_EVENT_INITIALIZED) {
-        qdict_put(server, "auth", qstring_from_str(auth));
+    switch (event) {
+    case SPICE_CHANNEL_EVENT_CONNECTED:
+        qapi_event_send_spice_connected(server->base, client->base, &error_abort);
+        break;
+    case SPICE_CHANNEL_EVENT_INITIALIZED:
+        if (auth) {
+            server->has_auth = true;
+            server->auth = g_strdup(auth);
+        }
         add_channel_info(client, info);
         channel_list_add(info);
-    }
-    if (event == SPICE_CHANNEL_EVENT_DISCONNECTED) {
+        qapi_event_send_spice_initialized(server, client, &error_abort);
+        break;
+    case SPICE_CHANNEL_EVENT_DISCONNECTED:
         channel_list_del(info);
+        qapi_event_send_spice_disconnected(server->base, client->base, &error_abort);
+        break;
+    default:
+        break;
     }
 
-    data = qobject_from_jsonf("{ 'client': %p, 'server': %p }",
-                              QOBJECT(client), QOBJECT(server));
-    monitor_protocol_event(qevent[event], data);
-    qobject_decref(data);
-
     if (need_lock) {
         qemu_mutex_unlock_iothread();
     }
+
+    qapi_free_SpiceServerInfo(server);
+    qapi_free_SpiceChannel(client);
 }
 
 static SpiceCoreInterface core_interface = {
@@ -305,7 +307,7 @@ static void migrate_connect_complete_cb(SpiceMigrateInstance *sin)
 
 static void migrate_end_complete_cb(SpiceMigrateInstance *sin)
 {
-    monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL);
+    qapi_event_send_spice_migrate_completed(&error_abort);
     spice_migration_completed = true;
 }
 
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 447720f..74cf078 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -92,16 +92,6 @@ static void inet_setport(struct addrinfo *e, int port)
     }
 }
 
-const char *inet_strfamily(int family)
-{
-    switch (family) {
-    case PF_INET6: return "ipv6";
-    case PF_INET:  return "ipv4";
-    case PF_UNIX:  return "unix";
-    }
-    return "unknown";
-}
-
 NetworkAddressFamily inet_netfamily(int family)
 {
     switch (family) {
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 27/36] qapi event: convert BALLOON_CHANGE
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (25 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 26/36] qapi event: convert SPICE events Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 28/36] qapi event: convert GUEST_PANICKED Paolo Bonzini
                   ` (11 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 28/36] qapi event: convert GUEST_PANICKED
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (26 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 27/36] qapi event: convert BALLOON_CHANGE Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 29/36] qapi event: convert QUORUM events Paolo Bonzini
                   ` (10 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 29/36] qapi event: convert QUORUM events
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (27 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 28/36] qapi event: convert GUEST_PANICKED Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19  4:14   ` Eric Blake
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up Paolo Bonzini
                   ` (9 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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..0000000
--- 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 d07da39..fbdda48 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -266,3 +266,41 @@
 ##
 { 'event': 'GUEST_PANICKED',
   'data': { 'action': 'GuestPanicAction' } }
+
+##
+# @QUORUM_FAILURE
+#
+# Emitted by the Quorum block driver if it fails to establish a quorum
+#
+# @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
+#
+# Since: 2.0
+##
+{ 'event': 'QUORUM_FAILURE',
+  'data': { 'reference': 'str', 'sector-num': 'int', 'sector-count': 'int' } }
+
+##
+# @QUORUM_REPORT_BAD
+#
+# Emitted to report a corruption of a Quorum file
+#
+# @error: #optional, error message. 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
+#
+# Since: 2.0
+##
+{ 'event': 'QUORUM_REPORT_BAD',
+  'data': { '*error': 'str', 'node-name': 'str',
+            'sector-num': 'int', 'sector-count': 'int' } }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (28 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 29/36] qapi event: convert QUORUM events Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19  4:17   ` Eric Blake
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 32/36] qemu-char: do not call chr_write directly Paolo Bonzini
                   ` (8 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

From: Wenchao Xia <wenchaoqemu@gmail.com>

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@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
  * milliseconds
  */
-static void __attribute__((__unused__))
+static void
 monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
 {
     MonitorQAPIEventState *evstate;
@@ -624,158 +565,6 @@ static void monitor_qapi_event_init(void)
     qmp_event_set_func_emit(monitor_qapi_event_queue);
 }
 
-
-/*
- * Emits the event to every monitor instance
- */
-static void
-monitor_protocol_event_emit(MonitorEvent 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_protocol_event_queue(MonitorEvent event,
-                             QObject *data)
-{
-    MonitorEventState *evstate;
-    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-    assert(event < QEVENT_MAX);
-
-    evstate = &(monitor_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_protocol_event_emit(event, 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 = data;
-            qobject_incref(evstate->data);
-        } else {
-            monitor_protocol_event_emit(event, data);
-            evstate->last = now;
-        }
-    }
-}
-
-
-/*
- * The callback invoked by QemuTimer when a delayed
- * event is ready to be emitted
- */
-static void monitor_protocol_event_handler(void *opaque)
-{
-    MonitorEventState *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_protocol_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_protocol_event_throttle(MonitorEvent event,
-                                int64_t rate)
-{
-    MonitorEventState *evstate;
-    assert(event < QEVENT_MAX);
-
-    evstate = &(monitor_event_state[event]);
-
-    trace_monitor_protocol_event_throttle(event, rate);
-    evstate->event = event;
-    evstate->rate = rate * SCALE_MS;
-    evstate->timer = timer_new(QEMU_CLOCK_REALTIME,
-                                    SCALE_MS,
-                                    monitor_protocol_event_handler,
-                                    evstate);
-    evstate->last = 0;
-    evstate->data = NULL;
-}
-
-
-/* Global, one-time initializer to configure the rate limiting
- * and initialize state */
-static void monitor_protocol_event_init(void)
-{
-}
-
-/**
- * monitor_protocol_event(): Generate a Monitor event
- *
- * Event-specific data can be emitted through the (optional) 'data' parameter.
- */
-void monitor_protocol_event(MonitorEvent event, QObject *data)
-{
-    QDict *qmp;
-    const char *event_name;
-
-    assert(event < QEVENT_MAX);
-
-    event_name = monitor_event_names[event];
-    assert(event_name != NULL);
-
-    qmp = qdict_new();
-    timestamp_put(qmp);
-    qdict_put(qmp, "event", qstring_from_str(event_name));
-    if (data) {
-        qobject_incref(data);
-        qdict_put_obj(qmp, "data", data);
-    }
-
-    trace_monitor_protocol_event(event, event_name, qmp);
-    monitor_protocol_event_queue(event, QOBJECT(qmp));
-    QDECREF(qmp);
-}
-
 static int do_qmp_capabilities(Monitor *mon, const QDict *params,
                                QObject **ret_data)
 {
@@ -1170,10 +959,10 @@ CommandInfoList *qmp_query_commands(Error **errp)
 EventInfoList *qmp_query_events(Error **errp)
 {
     EventInfoList *info, *ev_list = NULL;
-    MonitorEvent e;
+    QAPIEvent e;
 
-    for (e = 0 ; e < QEVENT_MAX ; e++) {
-        const char *event_name = monitor_event_names[e];
+    for (e = 0 ; e < QAPI_EVENT_MAX ; e++) {
+        const char *event_name = QAPIEvent_lookup[e];
         assert(event_name != NULL);
         info = g_malloc0(sizeof(*info));
         info->value = g_malloc0(sizeof(*info->value));
@@ -5475,7 +5264,6 @@ void monitor_init(CharDriverState *chr, int flags)
     Monitor *mon;
 
     if (is_first_init) {
-        monitor_protocol_event_init();
         monitor_qapi_event_init();
         sortcmdlist();
         is_first_init = 0;
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index d99e2b9..60de407 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -14,7 +14,6 @@ stub-obj-y += iothread-lock.o
 stub-obj-y += migr-blocker.o
 stub-obj-y += mon-is-qmp.o
 stub-obj-y += mon-printf.o
-stub-obj-y += mon-protocol-event.o
 stub-obj-y += mon-set-error.o
 stub-obj-y += pci-drive-hot-add.o
 stub-obj-y += qtest.o
diff --git a/stubs/mon-protocol-event.c b/stubs/mon-protocol-event.c
deleted file mode 100644
index 0946e94..0000000
--- a/stubs/mon-protocol-event.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "qemu-common.h"
-#include "monitor/monitor.h"
-
-void monitor_protocol_event(MonitorEvent event, QObject *data)
-{
-}
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 32/36] qemu-char: do not call chr_write directly
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (29 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-19 14:47   ` Eric Blake
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 33/36] qemu-char: move pty_chr_update_read_handler around Paolo Bonzini
                   ` (7 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

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 <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 33/36] qemu-char: move pty_chr_update_read_handler around
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (30 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 32/36] qemu-char: do not call chr_write directly Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe Paolo Bonzini
                   ` (6 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (31 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 33/36] qemu-char: move pty_chr_update_read_handler around Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-25  6:06   ` Stefan Weil
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 35/36] monitor: protect outbuf and mux_out with mutex Paolo Bonzini
                   ` (5 subsequent siblings)
  38 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

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 <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@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);
 
 static gboolean pty_chr_timer(gpointer opaque)
@@ -1031,14 +1043,17 @@ static gboolean pty_chr_timer(gpointer opaque)
     struct CharDriverState *chr = opaque;
     PtyCharDriver *s = chr->opaque;
 
+    qemu_mutex_lock(&chr->chr_write_lock);
     s->timer_tag = 0;
     if (!s->connected) {
         /* Next poll ... */
-        pty_chr_update_read_handler(chr);
+        pty_chr_update_read_handler_locked(chr);
     }
+    qemu_mutex_unlock(&chr->chr_write_lock);
     return FALSE;
 }
 
+/* Called with chr_write_lock held.  */
 static void pty_chr_rearm_timer(CharDriverState *chr, int ms)
 {
     PtyCharDriver *s = chr->opaque;
@@ -1055,7 +1070,8 @@ static void pty_chr_rearm_timer(CharDriverState *chr, int ms)
     }
 }
 
-static void pty_chr_update_read_handler(CharDriverState *chr)
+/* Called with chr_write_lock held.  */
+static void pty_chr_update_read_handler_locked(CharDriverState *chr)
 {
     PtyCharDriver *s = chr->opaque;
     GPollFD pfd;
@@ -1071,13 +1087,21 @@ static void pty_chr_update_read_handler(CharDriverState *chr)
     }
 }
 
+static void pty_chr_update_read_handler(CharDriverState *chr)
+{
+    qemu_mutex_lock(&chr->chr_write_lock);
+    pty_chr_update_read_handler_locked(chr);
+    qemu_mutex_unlock(&chr->chr_write_lock);
+}
+
+/* Called with chr_write_lock held.  */
 static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
     PtyCharDriver *s = chr->opaque;
 
     if (!s->connected) {
         /* guest sends data, check for (re-)connect */
-        pty_chr_update_read_handler(chr);
+        pty_chr_update_read_handler_locked(chr);
         return 0;
     }
     return io_channel_send(s->fd, buf, len);
@@ -1123,6 +1147,7 @@ static gboolean pty_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
     return TRUE;
 }
 
+/* Called with chr_write_lock held.  */
 static void pty_chr_state(CharDriverState *chr, int connected)
 {
     PtyCharDriver *s = chr->opaque;
@@ -1613,9 +1638,12 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd)
 typedef struct {
     int max_size;
     HANDLE hcom, hrecv, hsend;
-    OVERLAPPED orecv, osend;
+    OVERLAPPED orecv;
     BOOL fpipe;
     DWORD len;
+
+    /* Protected by the CharDriverState chr_write_lock.  */
+    OVERLAPPED osend;
 } WinCharState;
 
 typedef struct {
@@ -1725,6 +1753,7 @@ static int win_chr_init(CharDriverState *chr, const char *filename)
     return -1;
 }
 
+/* Called with chr_write_lock held.  */
 static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
 {
     WinCharState *s = chr->opaque;
@@ -2167,6 +2196,7 @@ typedef struct {
     int max_size;
 } NetCharDriver;
 
+/* Called with chr_write_lock held.  */
 static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
     NetCharDriver *s = chr->opaque;
@@ -2307,6 +2337,7 @@ typedef struct {
 
 static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque);
 
+/* Called with chr_write_lock held.  */
 static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
     TCPCharDriver *s = chr->opaque;
@@ -2788,6 +2819,7 @@ static size_t ringbuf_count(const CharDriverState *chr)
     return d->prod - d->cons;
 }
 
+/* Called with chr_write_lock held.  */
 static int ringbuf_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
     RingBufCharDriver *d = chr->opaque;
@@ -2812,9 +2844,11 @@ static int ringbuf_chr_read(CharDriverState *chr, uint8_t *buf, int len)
     RingBufCharDriver *d = chr->opaque;
     int i;
 
+    qemu_mutex_lock(&chr->chr_write_lock);
     for (i = 0; i < len && d->cons != d->prod; i++) {
         buf[i] = d->cbuf[d->cons++ & (d->size - 1)];
     }
+    qemu_mutex_unlock(&chr->chr_write_lock);
 
     return i;
 }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 35/36] monitor: protect outbuf and mux_out with mutex
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (32 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe Paolo Bonzini
@ 2014-06-18  6:43 ` Paolo Bonzini
  2014-06-18  6:44 ` [Qemu-devel] [PATCH 2.1 36/36] monitor: protect event emission Paolo Bonzini
                   ` (4 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

This lets the block layer emit QMP events from outside the I/O thread.

Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 2.1 36/36] monitor: protect event emission
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (33 preceding siblings ...)
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 35/36] monitor: protect outbuf and mux_out with mutex Paolo Bonzini
@ 2014-06-18  6:44 ` Paolo Bonzini
       [not found] ` <1403073840-32603-32-git-send-email-pbonzini@redhat.com>
                   ` (3 subsequent siblings)
  38 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: wenchaoqemu, lcapitulino

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 <lcapitulino@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@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

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 03/36] qapi: add event helper functions
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 03/36] qapi: add event helper functions Paolo Bonzini
@ 2014-06-18 22:55   ` Wenchao Xia
  0 siblings, 0 replies; 68+ messages in thread
From: Wenchao Xia @ 2014-06-18 22:55 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: lcapitulino

于 2014/6/18 14:43, Paolo Bonzini 写道:
> From: Wenchao Xia <wenchaoqemu@gmail.com>
> 
> This file holds some functions that do not need to be generated.
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@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 0000000..8a8ffb5
> --- /dev/null
> +++ b/include/qapi/qmp-event.h
> @@ -0,0 +1,27 @@
> +/*
> + * QMP Event related
> + *
> + * Copyright (c) 2014 Wenchao Xia
> + *
> + * Authors:
> + *  Wenchao Xia   <wenchaoqemu@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);
> +

  Using unsigned instead of QAPIEvent works around the include issue,
and also fix the type cast issue in implemention function that Eric
mentioned. It is nice to me, +1.

> +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 0000000..0d1ce0b
> --- /dev/null
> +++ b/qapi/qmp-event.c
> @@ -0,0 +1,74 @@
> +/*
> + * QMP Event related
> + *
> + * Copyright (c) 2014 Wenchao Xia
> + *
> + * Authors:
> + *  Wenchao Xia   <wenchaoqemu@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;
> +}
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 07/36] monitor: add an implemention of qapi event emit method
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 07/36] monitor: add an implemention of qapi event emit method Paolo Bonzini
@ 2014-06-19  4:03   ` Eric Blake
  0 siblings, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19  4:03 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 1305 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@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.

This comment is now stale, given...

> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  monitor.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 127 insertions(+), 1 deletion(-)

> + * milliseconds
> + */
> +static void __attribute__((__unused__))
> +monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)

>   */
> -static void
> +static void __attribute__((__unused__))
>  monitor_protocol_event_throttle(MonitorEvent event,
>                                  int64_t rate)

...these workarounds.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 08/36] qapi: add new schema file qapi-event.json
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 08/36] qapi: add new schema file qapi-event.json Paolo Bonzini
@ 2014-06-19  4:04   ` Eric Blake
  0 siblings, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19  4:04 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 1387 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@gmail.com>
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@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 0000000..e69de29
> diff --git a/qapi-schema.json b/qapi-schema.json

Still didn't pick up on my suggestion of at least having a comment in
the new file; but I can live with it.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 17/36] qapi event: convert RTC_CHANGE
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 17/36] qapi event: convert RTC_CHANGE Paolo Bonzini
@ 2014-06-19  4:06   ` Eric Blake
  0 siblings, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19  4:06 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 548 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@gmail.com>
> 
> This patch also eliminates build time warning caused by no caller
> of monitor_qapi_event_throttle().

Stale comment, given that earlier in the series we added a workaround to
avoid the warning in the first place.

> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 22/36] qapi event: convert BLOCK_IMAGE_CORRUPTED
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 22/36] qapi event: convert BLOCK_IMAGE_CORRUPTED Paolo Bonzini
@ 2014-06-19  4:09   ` Eric Blake
  0 siblings, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19  4:09 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 783 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@gmail.com>
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---

> +# @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

Not quite as strong as wording in other locations about not parsing the
value because it is allowed to change; but you could change that in a
followup if desired. I'm okay with this commit going in as written.


-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events Paolo Bonzini
@ 2014-06-19  4:11   ` Eric Blake
  2014-06-26 14:08   ` Markus Armbruster
  1 sibling, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19  4:11 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 877 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---

> +++ b/include/block/blockjob.h
> @@ -217,12 +217,21 @@ void block_job_pause(BlockJob *job);
>  void block_job_resume(BlockJob *job);
>  
>  /**
> - * qobject_from_block_job:
> + * block_job_event_cancle:

s/cancle/cancel/

At this point, if you need to clean it up in a followup patch instead of
delaying the series, I can live with it.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 29/36] qapi event: convert QUORUM events
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 29/36] qapi event: convert QUORUM events Paolo Bonzini
@ 2014-06-19  4:14   ` Eric Blake
  0 siblings, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19  4:14 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 905 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@gmail.com>
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---

> +++ 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);

You could drop this comment; the one several lines earlier states pretty
much the same thing.  But saving it for a followup is okay with me.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up Paolo Bonzini
@ 2014-06-19  4:17   ` Eric Blake
  2014-06-19  8:00     ` Paolo Bonzini
  0 siblings, 1 reply; 68+ messages in thread
From: Eric Blake @ 2014-06-19  4:17 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 970 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@gmail.com>
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@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

For patches 1-30:

Reviewed-by: Eric Blake <eblake@redhat.com>

I'll resume my review tomorrow on Paolo's thread-safety patches, but if
Luiz is ready to pull these into his staging tree, then other patches
that are pending on the qapi events (such as Igor's proposal to add
ACPI_DEVICE_OST) will have something to rebase on.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up
  2014-06-19  4:17   ` Eric Blake
@ 2014-06-19  8:00     ` Paolo Bonzini
  2014-06-19 14:51       ` Luiz Capitulino
  0 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-19  8:00 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: wenchaoqemu, lcapitulino

Il 19/06/2014 06:17, Eric Blake ha scritto:
> I'll resume my review tomorrow on Paolo's thread-safety patches, but if
> Luiz is ready to pull these into his staging tree, then other patches
> that are pending on the qapi events (such as Igor's proposal to add
> ACPI_DEVICE_OST) will have something to rebase on.
>
> -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization
> library http://libvirt.org

Yes, please. :)

Wenchao, can you submit a follow-up patch with the fixes that Eric 
requested?  Thanks for the through review.

Paolo

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 31/36] qemu-char: introduce qemu_chr_alloc
       [not found] ` <1403073840-32603-32-git-send-email-pbonzini@redhat.com>
@ 2014-06-19 12:03   ` Eric Blake
  2014-06-19 12:52     ` Paolo Bonzini
  0 siblings, 1 reply; 68+ messages in thread
From: Eric Blake @ 2014-06-19 12:03 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 1034 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> The next patch will modify this function to initialize state that is
> common to all backends.
> 
> Reviewed-by: Fam Zheng <famz@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  backends/baum.c       |  2 +-
>  backends/msmouse.c    |  2 +-
>  include/sysemu/char.h |  9 +++++++++
>  qemu-char.c           | 32 +++++++++++++++++++-------------
>  spice-qemu-char.c     |  2 +-
>  ui/console.c          |  2 +-
>  6 files changed, 32 insertions(+), 17 deletions(-)

Missing hw/misc/ivshmem.c:

static int pci_ivshmem_init(PCIDevice *dev)
{
...
        s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *));

        qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive,
ivshmem_read,
                     ivshmem_event, s);


Is that going to matter?  If not,

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support Paolo Bonzini
@ 2014-06-19 12:06   ` Eric Blake
  2014-06-19 19:57   ` Eric Blake
  1 sibling, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19 12:06 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 1392 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---

> +++ b/scripts/qapi-event.py
> @@ -0,0 +1,369 @@
> +#
> +# QAPI event generator
> +#
> +# Copyright (c) 2014 Wenchao Xia
> +#
> +# Authors:
> +#  Wenchao Xia <wenchaoqemu@gmail.com>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2.
> +# See the COPYING file in the top-level directory.

As mentioned in another thread, Wenchao was okay relaxing this to GPLv2+
- but do that as a followup rather than holding up this series.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 31/36] qemu-char: introduce qemu_chr_alloc
  2014-06-19 12:03   ` [Qemu-devel] [PATCH 2.1 31/36] qemu-char: introduce qemu_chr_alloc Eric Blake
@ 2014-06-19 12:52     ` Paolo Bonzini
  0 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-19 12:52 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: wenchaoqemu, lcapitulino

Il 19/06/2014 14:03, Eric Blake ha scritto:
> On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
>> The next patch will modify this function to initialize state that is
>> common to all backends.
>>
>> Reviewed-by: Fam Zheng <famz@redhat.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  backends/baum.c       |  2 +-
>>  backends/msmouse.c    |  2 +-
>>  include/sysemu/char.h |  9 +++++++++
>>  qemu-char.c           | 32 +++++++++++++++++++-------------
>>  spice-qemu-char.c     |  2 +-
>>  ui/console.c          |  2 +-
>>  6 files changed, 32 insertions(+), 17 deletions(-)
>
> Missing hw/misc/ivshmem.c:
>
> static int pci_ivshmem_init(PCIDevice *dev)
> {
> ...
>         s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *));
>
>         qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive,
> ivshmem_read,
>                      ivshmem_event, s);
>
>
> Is that going to matter?  If not,

Heh, I did the same wrong grep when writing the patch. :)

This is allocating a vector of _pointers_ to CharDriverState.  The 
pointers are initialized separately using create_eventfd_chr_device 
(that uses qemu_chr_open_eventfd and hence qemu_chr_alloc).

Paolo

> Reviewed-by: Eric Blake <eblake@redhat.com>
>

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 32/36] qemu-char: do not call chr_write directly
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 32/36] qemu-char: do not call chr_write directly Paolo Bonzini
@ 2014-06-19 14:47   ` Eric Blake
  0 siblings, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19 14:47 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 1605 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> 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 <famz@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  qemu-char.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

> @@ -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);

Worth fixing the spacing around + while at it?

> @@ -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;

The break is dead code; you could clean it up while in the area.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up
  2014-06-19  8:00     ` Paolo Bonzini
@ 2014-06-19 14:51       ` Luiz Capitulino
  0 siblings, 0 replies; 68+ messages in thread
From: Luiz Capitulino @ 2014-06-19 14:51 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, wenchaoqemu

On Thu, 19 Jun 2014 10:00:18 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 19/06/2014 06:17, Eric Blake ha scritto:
> > I'll resume my review tomorrow on Paolo's thread-safety patches, but if
> > Luiz is ready to pull these into his staging tree, then other patches
> > that are pending on the qapi events (such as Igor's proposal to add
> > ACPI_DEVICE_OST) will have something to rebase on.
> >
> > -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization
> > library http://libvirt.org
> 
> Yes, please. :)

I'll do it.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 12/36] qapi event: convert STOP
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 12/36] qapi event: convert STOP Paolo Bonzini
@ 2014-06-19 18:15   ` Luiz Capitulino
  0 siblings, 0 replies; 68+ messages in thread
From: Luiz Capitulino @ 2014-06-19 18:15 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, wenchaoqemu

On Wed, 18 Jun 2014 08:43:36 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> From: Wenchao Xia <wenchaoqemu@gmail.com>
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@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"

Dropping monitor.h breaks the build with the following error:

"""
/home/lcapitulino/work/src/upstream/qmp-unstable/cpus.c: In function ‘qmp_inject_nmi’:
/home/lcapitulino/work/src/upstream/qmp-unstable/cpus.c:1490:9: error: implicit declaration of function ‘monitor_get_cpu_index’ [-Werror=implicit-function-declaration]
         if (cpu->env.cpu_num == monitor_get_cpu_index()) {
         ^
/home/lcapitulino/work/src/upstream/qmp-unstable/cpus.c:1490:9: error: nested extern declaration of ‘monitor_get_cpu_index’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
make[1]: *** [cpus.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [subdir-s390x-softmmu] Error 2
"""

I've added it back then.

> +#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' }

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (35 preceding siblings ...)
       [not found] ` <1403073840-32603-32-git-send-email-pbonzini@redhat.com>
@ 2014-06-19 18:40 ` Luiz Capitulino
  2014-06-20 15:44 ` Eric Blake
  2014-06-26 15:50 ` Markus Armbruster
  38 siblings, 0 replies; 68+ messages in thread
From: Luiz Capitulino @ 2014-06-19 18:40 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, wenchaoqemu

On Wed, 18 Jun 2014 08:43:24 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> This includes:
> 
> - Max's dependency fixes for QAPI scripts
> 
> - Wenchao's QAPI event series
> 
> - my thread-safety fixes, rebased onto QAPI events
> 
> Paolo

Applied to the qmp branch, thanks.

> 
> 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                                     |  22 +-
>  66 files changed, 1878 insertions(+), 1143 deletions(-)
>  delete mode 100644 docs/qmp/qmp-events.txt
>  create mode 100644 include/qapi/qmp-event.h
>  create mode 100644 qapi-event.json
>  create mode 100644 qapi/qmp-event.c
>  create mode 100644 scripts/qapi-event.py
>  delete mode 100644 stubs/mon-protocol-event.c
>  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
>  create mode 100644 tests/test-qmp-event.c
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support Paolo Bonzini
  2014-06-19 12:06   ` Eric Blake
@ 2014-06-19 19:57   ` Eric Blake
  1 sibling, 0 replies; 68+ messages in thread
From: Eric Blake @ 2014-06-19 19:57 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 1089 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> From: Wenchao Xia <wenchaoqemu@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".
> 

> +    if params:
> +        for argname, argentry, optional, structured in parse_args(params):
> +            if optional:
> +                api_name += "bool has_%s,\n" % c_var(argname)
> +                api_name += "".ljust(l)
> +
> +            if argentry == "str":
> +                api_name += "const "
> +            api_name += "%s %s,\n" % (c_type(argentry), c_var(argname))

Wenchao, when you write your followup cleanups to this series, rewrite
this to use c_type(argentry, is_param=True) instead of pre-pending
"const " yourself (basically, take advantage of Amos' "qapi: add const
prefix to 'char *' insider c_type()" which is now in the tree ahead of
your patches).

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (36 preceding siblings ...)
  2014-06-19 18:40 ` [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Luiz Capitulino
@ 2014-06-20 15:44 ` Eric Blake
  2014-06-20 23:34   ` Wenchao Xia
  2014-06-26 15:50 ` Markus Armbruster
  38 siblings, 1 reply; 68+ messages in thread
From: Eric Blake @ 2014-06-20 15:44 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

[-- Attachment #1: Type: text/plain, Size: 941 bytes --]

On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
> This includes:
> 
> - Max's dependency fixes for QAPI scripts
> 
> - Wenchao's QAPI event series
> 
> - my thread-safety fixes, rebased onto QAPI events
> 
> Paolo
> 

>  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 +++++

Wenchao, as part of your followups to this series, I'd really like to
move qapi-event.json into qapi/event.json, so that all of our subset
.json files live in the same directory.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1
  2014-06-20 15:44 ` Eric Blake
@ 2014-06-20 23:34   ` Wenchao Xia
  0 siblings, 0 replies; 68+ messages in thread
From: Wenchao Xia @ 2014-06-20 23:34 UTC (permalink / raw)
  To: Eric Blake, Paolo Bonzini, qemu-devel; +Cc: lcapitulino

于 2014/6/20 23:44, Eric Blake 写道:
> On 06/18/2014 12:43 AM, Paolo Bonzini wrote:
>> This includes:
>>
>> - Max's dependency fixes for QAPI scripts
>>
>> - Wenchao's QAPI event series
>>
>> - my thread-safety fixes, rebased onto QAPI events
>>
>> Paolo
>>
>
>>   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 +++++
>
> Wenchao, as part of your followups to this series, I'd really like to
> move qapi-event.json into qapi/event.json, so that all of our subset
> .json files live in the same directory.
>
   I'll send the clean up patch onece the Paolo's series get merged.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe Paolo Bonzini
@ 2014-06-25  6:06   ` Stefan Weil
  2014-06-25  7:03     ` Paolo Bonzini
  0 siblings, 1 reply; 68+ messages in thread
From: Stefan Weil @ 2014-06-25  6:06 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: wenchaoqemu, lcapitulino

Am 18.06.2014 08:43, schrieb Paolo Bonzini:
> 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 <famz@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/sysemu/char.h | 11 ++++++----
>  qemu-char.c           | 58 ++++++++++++++++++++++++++++++++++++++++-----------
>  2 files changed, 53 insertions(+), 16 deletions(-)
> 

Latest QEMU is broken for w64. This command no longer starts the GTK gui:

wine64 x86_64-softmmu/qemu-system-x86_64 -L pc-bios

Wine reports a dead lock:

err:ntdll:RtlpWaitForCriticalSection section 0x964f0 "?" wait timed out
in thread 0009, blocked by 0000, retrying (60 sec)

git bisect finds this commit which introduced that regression:

9005b2a7589540a3733b3abdcfbccfe7746cd1a1 is the first bad commit
commit 9005b2a7589540a3733b3abdcfbccfe7746cd1a1
Author: Paolo Bonzini <pbonzini@redhat.com>
Date:   Wed Jun 18 08:43:58 2014 +0200

    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 <famz@redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>

:040000 040000 0a8837feb639c89178d4d9fbdfa10e26dd702b40
5be463e0d46eb49e65a2b3e11deb494b63975906 M	include
:100644 100644 9961b02ce607764a3d8ea2d70353036b95f955f2
a9025e642e779c2b2ad0c462ae863d761365b35d M	qemu-char.c

I did not run tests with 32 bit versions, nor did I run a native test on
Windows.

Regards
Stefan

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe
  2014-06-25  6:06   ` Stefan Weil
@ 2014-06-25  7:03     ` Paolo Bonzini
  0 siblings, 0 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-25  7:03 UTC (permalink / raw)
  To: Stefan Weil, qemu-devel; +Cc: wenchaoqemu, lcapitulino

Il 25/06/2014 08:06, Stefan Weil ha scritto:
> Am 18.06.2014 08:43, schrieb Paolo Bonzini:
>> 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 <famz@redhat.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  include/sysemu/char.h | 11 ++++++----
>>  qemu-char.c           | 58 ++++++++++++++++++++++++++++++++++++++++-----------
>>  2 files changed, 53 insertions(+), 16 deletions(-)
>>
>
> Latest QEMU is broken for w64. This command no longer starts the GTK gui:
>
> wine64 x86_64-softmmu/qemu-system-x86_64 -L pc-bios
>
> Wine reports a dead lock:
>
> err:ntdll:RtlpWaitForCriticalSection section 0x964f0 "?" wait timed out
> in thread 0009, blocked by 0000, retrying (60 sec)

Actually this message is more likely to be a missing qemu_mutex_init, 
and in fact that's what it is.  I'm sorry, I'll send a patch right away.

Paolo

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events Paolo Bonzini
  2014-06-19  4:11   ` Eric Blake
@ 2014-06-26 14:08   ` Markus Armbruster
  2014-06-26 14:19     ` Paolo Bonzini
  1 sibling, 1 reply; 68+ messages in thread
From: Markus Armbruster @ 2014-06-26 14:08 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Kevin Wolf, lcapitulino, qemu-devel, wenchaoqemu

Paolo Bonzini <pbonzini@redhat.com> writes:

> From: Wenchao Xia <wenchaoqemu@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 <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

This broke tests/qemu-iotests/040.  Apparently, the BLOCK_JOB_READY
event changed from

    {'timestamp': {'seconds': 1403791120, 'microseconds': 539716},
     'data': {'device': 'drive0',
               'type': 'commit',
               'speed': 0,
               'len': 1048576,
               'offset': 1048576},
     'event': 'BLOCK_JOB_READY'}

to just

    {'timestamp': {'seconds': 1403790920, 'microseconds': 123232},
     'data': {'device': 'drive0'},
     'event': 'BLOCK_JOB_READY'}

breaking qemu-iotests/040's tests of data/type and data/len.

Documentation of BLOCK_JOB_READY shows only data/device, before and
after this patch.

Suggests that

* Before this patch, code disagreed with docs, and qemu-iotests/040
  matched the code.

* After this patch, code matches docs, and qemu-iotests/040 matches
  neither.

Please advise.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events
  2014-06-26 14:08   ` Markus Armbruster
@ 2014-06-26 14:19     ` Paolo Bonzini
  2014-06-26 14:24       ` Luiz Capitulino
  0 siblings, 1 reply; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-26 14:19 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: Kevin Wolf, lcapitulino, qemu-devel, wenchaoqemu

Il 26/06/2014 16:08, Markus Armbruster ha scritto:
>
> Suggests that
>
> * Before this patch, code disagreed with docs, and qemu-iotests/040
>   matched the code.
>
> * After this patch, code matches docs, and qemu-iotests/040 matches
>   neither.
>
> Please advise.

Code is always right. :)

Paolo

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events
  2014-06-26 14:19     ` Paolo Bonzini
@ 2014-06-26 14:24       ` Luiz Capitulino
  0 siblings, 0 replies; 68+ messages in thread
From: Luiz Capitulino @ 2014-06-26 14:24 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Kevin Wolf, Markus Armbruster, wenchaoqemu, qemu-devel

On Thu, 26 Jun 2014 16:19:39 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 26/06/2014 16:08, Markus Armbruster ha scritto:
> >
> > Suggests that
> >
> > * Before this patch, code disagreed with docs, and qemu-iotests/040
> >   matched the code.
> >
> > * After this patch, code matches docs, and qemu-iotests/040 matches
> >   neither.
> >
> > Please advise.
> 
> Code is always right. :)

Agreed. We have to fix everything to match the code prior to the
conversion.

Are you going to take a stab at it yourself?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR Paolo Bonzini
@ 2014-06-26 15:37   ` Markus Armbruster
  2014-06-26 15:40     ` Paolo Bonzini
  0 siblings, 1 reply; 68+ messages in thread
From: Markus Armbruster @ 2014-06-26 15:37 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lcapitulino, qemu-devel, wenchaoqemu

Paolo Bonzini <pbonzini@redhat.com> writes:

> From: Wenchao Xia <wenchaoqemu@gmail.com>
>
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

This broke tests/qemu-iotests/041.  Apparently, the BLOCK_JOB_ERROR
event changed from

    {'timestamp': {'seconds': 1403796871, 'microseconds': 446502},
     'data': {'device': 'drive0',
              'action': 'ignore',
              'operation': 'write'},
     'event': 'BLOCK_JOB_ERROR'}

to

    {'timestamp': {'seconds': 1403796674, 'microseconds': 63271},
     'data': {'device': '',
              'action': 'report',
              'operation': 'write'},
     'event': 'BLOCK_JOB_ERROR'}

losing the value of device, which breaks qemu-iotests/041's tests of
data/device.

Please fix.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  2014-06-26 15:37   ` Markus Armbruster
@ 2014-06-26 15:40     ` Paolo Bonzini
  2014-06-26 15:44       ` Luiz Capitulino
  2014-06-26 15:58       ` Markus Armbruster
  0 siblings, 2 replies; 68+ messages in thread
From: Paolo Bonzini @ 2014-06-26 15:40 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, wenchaoqemu, lcapitulino

Il 26/06/2014 17:37, Markus Armbruster ha scritto:
> Paolo Bonzini <pbonzini@redhat.com> writes:
> 
>> From: Wenchao Xia <wenchaoqemu@gmail.com>
>>
>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> 
> This broke tests/qemu-iotests/041.  Apparently, the BLOCK_JOB_ERROR
> event changed from
> 
>     {'timestamp': {'seconds': 1403796871, 'microseconds': 446502},
>      'data': {'device': 'drive0',

-    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),

Should have been job->bs.

>               'action': 'ignore',
>               'operation': 'write'},
>      'event': 'BLOCK_JOB_ERROR'}
> 
> to
> 
>     {'timestamp': {'seconds': 1403796674, 'microseconds': 63271},
>      'data': {'device': '',
>               'action': 'report',

I suppose ignore vs. report is just from pasting two different sections?

Paolo

>               'operation': 'write'},
>      'event': 'BLOCK_JOB_ERROR'}
> 
> losing the value of device, which breaks qemu-iotests/041's tests of
> data/device.
> 
> Please fix.
> 
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  2014-06-26 15:40     ` Paolo Bonzini
@ 2014-06-26 15:44       ` Luiz Capitulino
  2014-06-26 15:58       ` Markus Armbruster
  1 sibling, 0 replies; 68+ messages in thread
From: Luiz Capitulino @ 2014-06-26 15:44 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Markus Armbruster, wenchaoqemu, qemu-devel

On Thu, 26 Jun 2014 17:40:57 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 26/06/2014 17:37, Markus Armbruster ha scritto:
> > Paolo Bonzini <pbonzini@redhat.com> writes:
> > 
> >> From: Wenchao Xia <wenchaoqemu@gmail.com>
> >>
> >> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> >> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > 
> > This broke tests/qemu-iotests/041.  Apparently, the BLOCK_JOB_ERROR
> > event changed from
> > 
> >     {'timestamp': {'seconds': 1403796871, 'microseconds': 446502},
> >      'data': {'device': 'drive0',
> 
> -    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),
> 
> Should have been job->bs.

Yeah, patch is underway.

> 
> >               'action': 'ignore',
> >               'operation': 'write'},
> >      'event': 'BLOCK_JOB_ERROR'}
> > 
> > to
> > 
> >     {'timestamp': {'seconds': 1403796674, 'microseconds': 63271},
> >      'data': {'device': '',
> >               'action': 'report',
> 
> I suppose ignore vs. report is just from pasting two different sections?
> 
> Paolo
> 
> >               'operation': 'write'},
> >      'event': 'BLOCK_JOB_ERROR'}
> > 
> > losing the value of device, which breaks qemu-iotests/041's tests of
> > data/device.
> > 
> > Please fix.
> > 
> > 
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1
  2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
                   ` (37 preceding siblings ...)
  2014-06-20 15:44 ` Eric Blake
@ 2014-06-26 15:50 ` Markus Armbruster
  2014-06-26 15:56   ` Luiz Capitulino
  38 siblings, 1 reply; 68+ messages in thread
From: Markus Armbruster @ 2014-06-26 15:50 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lcapitulino, qemu-devel, wenchaoqemu

Paolo Bonzini <pbonzini@redhat.com> writes:

> This includes:
>
> - Max's dependency fixes for QAPI scripts
>
> - Wenchao's QAPI event series
>
> - my thread-safety fixes, rebased onto QAPI events

The QAPI event series messed up two out of three event types tested in
qemu-iotests, if I count them correctly.

How can we gain confidence that we're not breaking half of the events
not tested there, too?

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1
  2014-06-26 15:50 ` Markus Armbruster
@ 2014-06-26 15:56   ` Luiz Capitulino
  0 siblings, 0 replies; 68+ messages in thread
From: Luiz Capitulino @ 2014-06-26 15:56 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: Paolo Bonzini, qemu-devel, wenchaoqemu

On Thu, 26 Jun 2014 17:50:08 +0200
Markus Armbruster <armbru@redhat.com> wrote:

> Paolo Bonzini <pbonzini@redhat.com> writes:
> 
> > This includes:
> >
> > - Max's dependency fixes for QAPI scripts
> >
> > - Wenchao's QAPI event series
> >
> > - my thread-safety fixes, rebased onto QAPI events
> 
> The QAPI event series messed up two out of three event types tested in
> qemu-iotests, if I count them correctly.

Let's fix 'em.

> 
> How can we gain confidence that we're not breaking half of the events
> not tested there, too?

Let's test 'em. It would be superb to add tests for them.

I tested most of them myself before applying the series, but it was a
manual test. I didn't check/test every single field of every single event.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  2014-06-26 15:40     ` Paolo Bonzini
  2014-06-26 15:44       ` Luiz Capitulino
@ 2014-06-26 15:58       ` Markus Armbruster
  2014-06-26 16:00         ` Luiz Capitulino
  2014-06-27 12:21         ` Markus Armbruster
  1 sibling, 2 replies; 68+ messages in thread
From: Markus Armbruster @ 2014-06-26 15:58 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lcapitulino, qemu-devel, wenchaoqemu

Paolo Bonzini <pbonzini@redhat.com> writes:

> Il 26/06/2014 17:37, Markus Armbruster ha scritto:
>> Paolo Bonzini <pbonzini@redhat.com> writes:
>> 
>>> From: Wenchao Xia <wenchaoqemu@gmail.com>
>>>
>>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
>>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> 
>> This broke tests/qemu-iotests/041.  Apparently, the BLOCK_JOB_ERROR
>> event changed from
>> 
>>     {'timestamp': {'seconds': 1403796871, 'microseconds': 446502},
>>      'data': {'device': 'drive0',
>
> - 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),
>
> Should have been job->bs.

Will you post a patch, or would you like me to do that?

>>               'action': 'ignore',
>>               'operation': 'write'},
>>      'event': 'BLOCK_JOB_ERROR'}
>> 
>> to
>> 
>>     {'timestamp': {'seconds': 1403796674, 'microseconds': 63271},
>>      'data': {'device': '',
>>               'action': 'report',
>
> I suppose ignore vs. report is just from pasting two different sections?

Could well be; it's almost time for Fußball & Bier ;)

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  2014-06-26 15:58       ` Markus Armbruster
@ 2014-06-26 16:00         ` Luiz Capitulino
  2014-06-27 12:21         ` Markus Armbruster
  1 sibling, 0 replies; 68+ messages in thread
From: Luiz Capitulino @ 2014-06-26 16:00 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: Paolo Bonzini, qemu-devel, wenchaoqemu

On Thu, 26 Jun 2014 17:58:21 +0200
Markus Armbruster <armbru@redhat.com> wrote:

> Paolo Bonzini <pbonzini@redhat.com> writes:
> 
> > Il 26/06/2014 17:37, Markus Armbruster ha scritto:
> >> Paolo Bonzini <pbonzini@redhat.com> writes:
> >> 
> >>> From: Wenchao Xia <wenchaoqemu@gmail.com>
> >>>
> >>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> >>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> >> 
> >> This broke tests/qemu-iotests/041.  Apparently, the BLOCK_JOB_ERROR
> >> event changed from
> >> 
> >>     {'timestamp': {'seconds': 1403796871, 'microseconds': 446502},
> >>      'data': {'device': 'drive0',
> >
> > - 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),
> >
> > Should have been job->bs.
> 
> Will you post a patch, or would you like me to do that?

I was going to do it myself, but it would be great if you could do that.

> 
> >>               'action': 'ignore',
> >>               'operation': 'write'},
> >>      'event': 'BLOCK_JOB_ERROR'}
> >> 
> >> to
> >> 
> >>     {'timestamp': {'seconds': 1403796674, 'microseconds': 63271},
> >>      'data': {'device': '',
> >>               'action': 'report',
> >
> > I suppose ignore vs. report is just from pasting two different sections?
> 
> Could well be; it's almost time for Fußball & Bier ;)
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  2014-06-26 15:58       ` Markus Armbruster
  2014-06-26 16:00         ` Luiz Capitulino
@ 2014-06-27 12:21         ` Markus Armbruster
  1 sibling, 0 replies; 68+ messages in thread
From: Markus Armbruster @ 2014-06-27 12:21 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: lcapitulino, qemu-devel, wenchaoqemu

Markus Armbruster <armbru@redhat.com> writes:

> Paolo Bonzini <pbonzini@redhat.com> writes:
>
>> Il 26/06/2014 17:37, Markus Armbruster ha scritto:
>>> Paolo Bonzini <pbonzini@redhat.com> writes:
>>> 
>>>> From: Wenchao Xia <wenchaoqemu@gmail.com>
>>>>
>>>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
>>>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>>> 
>>> This broke tests/qemu-iotests/041.  Apparently, the BLOCK_JOB_ERROR
>>> event changed from
>>> 
>>>     {'timestamp': {'seconds': 1403796871, 'microseconds': 446502},
>>>      'data': {'device': 'drive0',
>>
>> - 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),
>>
>> Should have been job->bs.
>
> Will you post a patch, or would you like me to do that?
>
>>>               'action': 'ignore',
>>>               'operation': 'write'},
>>>      'event': 'BLOCK_JOB_ERROR'}
>>> 
>>> to
>>> 
>>>     {'timestamp': {'seconds': 1403796674, 'microseconds': 63271},
>>>      'data': {'device': '',
>>>               'action': 'report',
>>
>> I suppose ignore vs. report is just from pasting two different sections?
>
> Could well be; it's almost time for Fußball & Bier ;)

Nope, it's a genuine error in the patch.  Working on a fix.

^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2014-06-27 12:22 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-18  6:43 [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 01/36] os-posix: include sys/time.h Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 02/36] qapi: Add includes from qapi/ as dependencies Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 03/36] qapi: add event helper functions Paolo Bonzini
2014-06-18 22:55   ` Wenchao Xia
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 04/36] qapi script: add event support Paolo Bonzini
2014-06-19 12:06   ` Eric Blake
2014-06-19 19:57   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 05/36] test: add test cases for qapi event Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 06/36] qapi: adjust existing defines Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 07/36] monitor: add an implemention of qapi event emit method Paolo Bonzini
2014-06-19  4:03   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 08/36] qapi: add new schema file qapi-event.json Paolo Bonzini
2014-06-19  4:04   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 09/36] qapi event: convert SHUTDOWN Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 10/36] qapi event: convert POWERDOWN Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 11/36] qapi event: convert RESET Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 12/36] qapi event: convert STOP Paolo Bonzini
2014-06-19 18:15   ` Luiz Capitulino
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 13/36] qapi event: convert RESUME Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 14/36] qapi event: convert SUSPEND Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 15/36] qapi event: convert SUSPEND_DISK Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 16/36] qapi event: convert WAKEUP Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 17/36] qapi event: convert RTC_CHANGE Paolo Bonzini
2014-06-19  4:06   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 18/36] qapi event: convert WATCHDOG Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 19/36] qapi event: convert DEVICE_DELETED Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 20/36] qapi event: convert DEVICE_TRAY_MOVED Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 21/36] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR Paolo Bonzini
2014-06-26 15:37   ` Markus Armbruster
2014-06-26 15:40     ` Paolo Bonzini
2014-06-26 15:44       ` Luiz Capitulino
2014-06-26 15:58       ` Markus Armbruster
2014-06-26 16:00         ` Luiz Capitulino
2014-06-27 12:21         ` Markus Armbruster
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 22/36] qapi event: convert BLOCK_IMAGE_CORRUPTED Paolo Bonzini
2014-06-19  4:09   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 23/36] qapi event: convert other BLOCK_JOB events Paolo Bonzini
2014-06-19  4:11   ` Eric Blake
2014-06-26 14:08   ` Markus Armbruster
2014-06-26 14:19     ` Paolo Bonzini
2014-06-26 14:24       ` Luiz Capitulino
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 24/36] qapi event: convert NIC_RX_FILTER_CHANGED Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 25/36] qapi event: convert VNC events Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 26/36] qapi event: convert SPICE events Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 27/36] qapi event: convert BALLOON_CHANGE Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 28/36] qapi event: convert GUEST_PANICKED Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 29/36] qapi event: convert QUORUM events Paolo Bonzini
2014-06-19  4:14   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 30/36] qapi event: clean up Paolo Bonzini
2014-06-19  4:17   ` Eric Blake
2014-06-19  8:00     ` Paolo Bonzini
2014-06-19 14:51       ` Luiz Capitulino
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 32/36] qemu-char: do not call chr_write directly Paolo Bonzini
2014-06-19 14:47   ` Eric Blake
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 33/36] qemu-char: move pty_chr_update_read_handler around Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 34/36] qemu-char: make writes thread-safe Paolo Bonzini
2014-06-25  6:06   ` Stefan Weil
2014-06-25  7:03     ` Paolo Bonzini
2014-06-18  6:43 ` [Qemu-devel] [PATCH 2.1 35/36] monitor: protect outbuf and mux_out with mutex Paolo Bonzini
2014-06-18  6:44 ` [Qemu-devel] [PATCH 2.1 36/36] monitor: protect event emission Paolo Bonzini
     [not found] ` <1403073840-32603-32-git-send-email-pbonzini@redhat.com>
2014-06-19 12:03   ` [Qemu-devel] [PATCH 2.1 31/36] qemu-char: introduce qemu_chr_alloc Eric Blake
2014-06-19 12:52     ` Paolo Bonzini
2014-06-19 18:40 ` [Qemu-devel] [PATCH 2.1 00/36] Pending monitor patches for 2.1 Luiz Capitulino
2014-06-20 15:44 ` Eric Blake
2014-06-20 23:34   ` Wenchao Xia
2014-06-26 15:50 ` Markus Armbruster
2014-06-26 15:56   ` Luiz Capitulino

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.