All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
@ 2014-06-05 12:21 Wenchao Xia
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 01/29] os-posix: include sys/time.h Wenchao Xia
                   ` (29 more replies)
  0 siblings, 30 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 8202 bytes --]

This series add support for tag/keyword 'event' in qapi-schema.
A new file was created to store some helper functions in patch 2, patch 4 is
the test case, patch 5 is a convert example.

The implemention is done by generate API and a batch of parameters for each
event define, it doesn't generate a struture and visit function in the
background for every event, so it doesn't support nested structure in the
define to avoid trouble. A callback layer is added to control the behavior.
More detail can be found in patch 3's message and incode comments.

v2:
  Address Luiz's comments:
  patch 3: rename *err to *local_err, do not initialize *qmp = NULL, create
a new function qmp_build_evet_dict().
  Other change:
  reorgnized script in patch 3, it have a clear three steps, see patch 3's
incode comments.

v3:
  Address Luiz's comments:
  2/5: use -1 when fail to get host timestamp.
  3/5: typo fix and better incode comments. all unchanged functions are moved
into qmp-event.c, from generated file. To do so without include issue, 'int'
was used intead of 'enum' in function prototype declaration, since the 'enum'
define is a generated type.
  Address Eric's comments:
  2/5: use -1 when fail to get host timestamp.
  3/5: typo fix, add docs/qapi-code-gen.txt.
  4/5: typo fix, verify no other fields in member 'timestamp'.
  5/5: add doc in qapi-schema.json.
  fix license, all script using GPL2, all C code use LGPL, just as other
similar files in upstream.

v4:
  Address Eric's comments:
  2/5: typo fix, add copyright declaration, use a static function pointer
instead of a struct in C file, assign -1 in two line of codes to avoid issue
when tv_sec and tv_usec are not in same data width, fix indention.
  3/5: typo fix, add copyright declaration.
  4/5: add copyright declaration, simplify string compare with
 "d->result = g_strcmp0(...) == 0;", add check for tv_usec's range and value.
  Other:
  3/5: all error check code was moved from qapi-event.py to qapi.py, and it
reports better message with line number info. Added related test case.
  Note:
  Benoit's series which track input file better seems not the final version,
so I didn't rebase this series ontop for now, will do it once Benoit's ones
get ACKed.

v5:
  Address Eric and Markus's comments:
  2/28: use uint64_t for both sec and usec, to avoid type cast issue in printf.
  Other:
  Remove RFC, add full coversion by patch 5-28.
  3/28: add prefix for event enum type name, to avoid double define of
QAPIEvent in test code.

v6:
  Address Eric's comments:
  3/29: employ modularization mechnism of schema file of Lluís series, remove
error_is_set() usage.
  4/29: Makefile change for Lluís series.
  5/29: separate patch for refactoring the existing schema defines, improve doc
for @service in VncBasicInfo.
  7/29-28/29: define and convert event caller one by one.
  Other change:
  6/29: new way to add event emit implemention. In v5 it breaks old event
mechnism, in v6 it touch nothing of old event mechnism but add a new set of
functions for new event mechnism.
  7/29: Add new file qapi-event.json to store event defines, and all type
defines goes into qapi-schema.json.
  29/29: related clean up change.
  Note:
  I have no way to verify target-s390x/kvm.c touched by patch 27/29, and
block/quorum.c touched by patch 28/29, need a confirm from whom has the test
env.

Wenchao Xia (29):
  1 os-posix: include sys/time.h
  2 qapi: add event helper functions
  3 qapi script: add event support
  4 test: add test cases for qapi event
  5 qapi: adjust existing defines
  6 monitor: add an implemention as qapi event emit method
  7 qapi: add new schema file qapi-event.json
  8 qapi event: convert SHUTDOWN
  9 qapi event: convert POWERDOWN
  10 qapi event: convert RESET
  11 qapi event: convert STOP
  12 qapi event: convert RESUME
  13 qapi event: convert SUSPEND
  14 qapi event: convert SUSPEND_DISK
  15 qapi event: convert WAKEUP
  16 qapi event: convert RTC_CHANGE
  17 qapi event: convert WATCHDOG
  18 qapi event: convert DEVICE_DELETED
  19 qapi event: convert DEVICE_TRAY_MOVED
  20 qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  21 qapi event: convert BLOCK_IMAGE_CORRUPTED
  22 qapi event: convert other BLOCK_JOB events
  23 qapi event: convert NIC_RX_FILTER_CHANGED
  24 qapi event: convert VNC events
  25 qapi event: convert SPICE events
  26 qapi event: convert BALLOON_CHANGE
  27 qapi event: convert GUEST_PANICKED
  28 qapi event: convert QUORUM events
  29 qapi event: clean up

 Makefile                                 |   21 +-
 Makefile.objs                            |    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/os-posix.h                |    2 +
 include/sysemu/sysemu.h                  |    2 -
 monitor.c                                |  185 +++--------
 qapi-event.json                          |  452 +++++++++++++++++++++++++
 qapi-schema.json                         |  178 +++++++++--
 qapi/Makefile.objs                       |    1 +
 qapi/qmp-event.c                         |   74 ++++
 scripts/qapi-event.py                    |  369 ++++++++++++++++++++
 scripts/qapi.py                          |   12 +
 stubs/Makefile.objs                      |    1 -
 stubs/mon-protocol-event.c               |    6 -
 target-s390x/kvm.c                       |    8 +-
 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/qapi-schema-test.json  |   12 +
 tests/qapi-schema/qapi-schema-test.out   |   10 +-
 tests/test-qmp-event.c                   |  265 +++++++++++++++
 trace-events                             |    4 +
 ui/spice-core.c                          |   77 +++--
 ui/vnc.c                                 |  120 ++++----
 ui/vnc.h                                 |    4 +-
 util/qemu-sockets.c                      |   10 +-
 vl.c                                     |   22 +-
 58 files changed, 1732 insertions(+), 1087 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] 77+ messages in thread

* [Qemu-devel] [PATCH V6 01/29] os-posix: include sys/time.h
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
@ 2014-06-05 12:21 ` Wenchao Xia
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 02/29] qapi: add event helper functions Wenchao Xia
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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>
---
 include/sysemu/os-posix.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

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.7.1

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

* [Qemu-devel] [PATCH V6 02/29] qapi: add event helper functions
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 01/29] os-posix: include sys/time.h Wenchao Xia
@ 2014-06-05 12:21 ` Wenchao Xia
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 03/29] qapi script: add event support Wenchao Xia
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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>
---
 include/qapi/qmp-event.h |   27 +++++++++++++++++
 qapi/Makefile.objs       |    1 +
 qapi/qmp-event.c         |   74 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+), 0 deletions(-)
 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..02b6ce5
--- /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)(int event_kind, 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.7.1

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

* [Qemu-devel] [PATCH V6 03/29] qapi script: add event support
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 01/29] os-posix: include sys/time.h Wenchao Xia
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 02/29] qapi: add event helper functions Wenchao Xia
@ 2014-06-05 12:21 ` Wenchao Xia
  2014-06-13 16:47   ` Eric Blake
                     ` (3 more replies)
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 04/29] test: add test cases for qapi event Wenchao Xia
                   ` (26 subsequent siblings)
  29 siblings, 4 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

qapi-event.py will parse the schema and generate qapi-event.c, then
the API in qapi-event.c can be used to handle event 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>
---
 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 +
 9 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 d830483..237657e 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)'
@@ -256,6 +256,11 @@ $(SRC_PATH)/qapi-schema.json $(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 :\
+$(SRC_PATH)/qapi-schema.json $(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 :\
 $(SRC_PATH)/qapi-schema.json $(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 key word 'event'.  When 'data' is also specified,
+additional info will be carried on.  Finally there will be C API generated
+in qapi-event.h, and 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..e1dcc43
--- /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 and 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 member 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 6b294a7..287455f 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.7.1

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

* [Qemu-devel] [PATCH V6 04/29] test: add test cases for qapi event
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (2 preceding siblings ...)
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 03/29] qapi script: add event support Wenchao Xia
@ 2014-06-05 12:21 ` Wenchao Xia
  2014-06-13 17:05   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 05/29] qapi: adjust existing defines Wenchao Xia
                   ` (25 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

These cases will verify whether the expected qdict is built.

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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 287455f..f07a916 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..c967d35
--- /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 GStaticMutex test_event_lock = G_STATIC_MUTEX_INIT;
+
+/* 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(int event_kind, QDict *d, Error **errp)
+{
+    QObject *obj;
+    QDict *t;
+    int64_t s, ms;
+
+    /* Verify that we have timestamp, then remove it to compare other field */
+    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_static_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_static_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(NULL);
+}
+
+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(NULL);
+}
+
+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", NULL);
+
+    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,
+                           NULL);
+
+    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.7.1

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

* [Qemu-devel] [PATCH V6 05/29] qapi: adjust existing defines
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (3 preceding siblings ...)
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 04/29] test: add test cases for qapi event Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 17:32   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 06/29] monitor: add an implemention as qapi event emit method Wenchao Xia
                   ` (24 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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.

One thing not perfect is that, VncInfo should be foldered but may break
API stability.

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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       |  126 ++++++++++++++++++++++++++++++++++++++----------
 ui/spice-core.c        |    7 ++-
 ui/vnc.c               |    9 ++--
 util/qemu-sockets.c    |   10 ++++
 15 files changed, 156 insertions(+), 66 deletions(-)

diff --git a/block.c b/block.c
index 310ea89..84ad945 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:
@@ -3599,13 +3599,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();
     }
@@ -3620,7 +3621,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 8a568e5..62ac610 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -57,17 +57,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 4bcef55..f35229b 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 faee3aa..a677baf 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 7bc33ea..115d8d0 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1163,21 +1163,59 @@
 { 'command': 'query-blockstats', 'returns': ['BlockStats'] }
 
 ##
-# @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.
@@ -1188,8 +1226,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:
@@ -1228,7 +1266,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']} }
 
 ##
@@ -1243,19 +1282,40 @@
 { 'command': 'query-vnc', 'returns': 'VncInfo' }
 
 ##
-# @SpiceChannel
+# @SpiceBasicInfo
 #
-# Information about a SPICE client channel.
+# The basic information for SPICE network connection
+#
+# @host: IP address
+#
+# @port: port number
 #
-# @host: The host name of the client.  QEMU tries to resolve this to a DNS name
-#        when possible.
+# @family: address family
 #
-# @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
+# 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
 #
-# @port: The client's port number.
+# Information about a SPICE client channel.
 #
 # @connection-id: SPICE connection id number.  All channels with the same id
 #                 belong to the same SPICE session.
@@ -1273,8 +1333,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'} }
 
 ##
@@ -4722,3 +4782,19 @@
               'btn'     : 'InputBtnEvent',
               'rel'     : 'InputMoveEvent',
               'abs'     : 'InputMoveEvent' } }
+
+##
+# @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 61b1f93..469852a 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 627e609..7f558bb 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -104,6 +104,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.7.1

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

* [Qemu-devel] [PATCH V6 06/29] monitor: add an implemention as qapi event emit method
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (4 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 05/29] qapi: adjust existing defines Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 19:04   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 07/29] qapi: add new schema file qapi-event.json Wenchao Xia
                   ` (23 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Now monitor has been hooked on the new event mechanism, so the patches
later 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>
---
 monitor.c    |  128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 trace-events |    4 ++
 2 files changed, 131 insertions(+), 1 deletions(-)

diff --git a/monitor.c b/monitor.c
index 593679a..e122381 100644
--- a/monitor.c
+++ b/monitor.c
@@ -69,6 +69,8 @@
 #include "qmp-commands.h"
 #include "hmp.h"
 #include "qemu/thread.h"
+#include "qapi/qmp-event.h"
+#include "qapi-event.h"
 
 /* for pic/irq_info */
 #if defined(TARGET_SPARC)
@@ -185,6 +187,14 @@ typedef struct MonitorEventState {
     QObject *data;      /* Event pending delayed dispatch */
 } MonitorEventState;
 
+typedef struct MonitorQAPIEventState {
+    QAPIEvent 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 */
+} MonitorQAPIEventState;
+
 struct Monitor {
     CharDriverState *chr;
     int mux_out;
@@ -489,6 +499,122 @@ 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_qapi_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(int event_kind, QDict *data, Error **errp)
+{
+    MonitorQAPIEventState *evstate;
+    assert(event_kind < QAPI_EVENT_MAX);
+    QAPIEvent event = (QAPIEvent)event_kind;
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+
+    evstate = &(monitor_qapi_event_state[event]);
+    trace_monitor_qapi_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_qapi_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 monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
+{
+    MonitorQAPIEventState *evstate;
+    assert(event < QAPI_EVENT_MAX);
+
+    evstate = &(monitor_qapi_event_state[event]);
+
+    trace_monitor_qapi_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
@@ -507,7 +633,6 @@ monitor_protocol_event_emit(MonitorEvent event,
     }
 }
 
-
 /*
  * Queue a new event for emission to Monitor instances,
  * applying any rate limiting if required.
@@ -5169,6 +5294,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;
     }
diff --git a/trace-events b/trace-events
index ffe6e62..f4b8dbb 100644
--- a/trace-events
+++ b/trace-events
@@ -932,6 +932,10 @@ monitor_protocol_event_handler(uint32_t event, void *data, uint64_t last, uint64
 monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
 monitor_protocol_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
 monitor_protocol_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
+monitor_qapi_event_emit(uint32_t event, void *data) "event=%d data=%p"
+monitor_qapi_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
+monitor_qapi_event_handler(uint32_t event, void *data, uint64_t last, uint64_t now) "event=%d data=%p last=%" PRId64 " now=%" PRId64
+monitor_qapi_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
 
 # hw/net/opencores_eth.c
 open_eth_mii_write(unsigned idx, uint16_t v) "MII[%02x] <- %04x"
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 07/29] qapi: add new schema file qapi-event.json
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (5 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 06/29] monitor: add an implemention as qapi event emit method Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 19:25   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 08/29] qapi event: convert SHUTDOWN Wenchao Xia
                   ` (22 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
---
 Makefile         |   12 ++++++++----
 qapi-schema.json |    2 ++
 2 files changed, 10 insertions(+), 4 deletions(-)
 create mode 100644 qapi-event.json

diff --git a/Makefile b/Makefile
index 237657e..554fb2d 100644
--- a/Makefile
+++ b/Makefile
@@ -247,22 +247,26 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
 		"  GEN   $@")
 
 qapi-types.c qapi-types.h :\
-$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
+$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
+$(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)
+$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
+$(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 :\
-$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
+$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
+$(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 :\
-$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
+$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
+$(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   $@")
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 115d8d0..d04514a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4798,3 +4798,5 @@
 ##
 { 'enum': 'BlockErrorAction',
   'data': [ 'ignore', 'report', 'stop' ] }
+
+{ 'include': 'qapi-event.json' }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 08/29] qapi event: convert SHUTDOWN
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (6 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 07/29] qapi: add new schema file qapi-event.json Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 19:57   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 09/29] qapi event: convert POWERDOWN Wenchao Xia
                   ` (21 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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..b2a943f 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -0,0 +1,12 @@
+##
+# @SHUTDOWN
+#
+# Emitted when the virtual machine shutdown, qemu terminated the emulation and
+# is 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: 2.1
+##
+{ 'event': 'SHUTDOWN' }
diff --git a/vl.c b/vl.c
index 0c15608..273d237 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(NULL);
         if (no_shutdown) {
             vm_stop(RUN_STATE_SHUTDOWN);
         } else {
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 09/29] qapi event: convert POWERDOWN
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (7 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 08/29] qapi event: convert SHUTDOWN Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 20:02   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 10/29] qapi event: convert RESET Wenchao Xia
                   ` (20 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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>
---
 qapi-event.json |   10 ++++++++++
 vl.c            |    2 +-
 2 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/qapi-event.json b/qapi-event.json
index b2a943f..fbdbc7c 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -10,3 +10,13 @@
 # Since: 2.1
 ##
 { 'event': 'SHUTDOWN' }
+
+##
+# @POWERDOWN
+#
+# Emitted when the virtual machine is powered down through the power control
+# system, such as via ACPI.
+#
+# Since: 2.1
+##
+{ 'event': 'POWERDOWN' }
diff --git a/vl.c b/vl.c
index 273d237..69ad0e9 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(NULL);
     notifier_list_notify(&powerdown_notifiers, NULL);
 }
 
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 10/29] qapi event: convert RESET
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (8 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 09/29] qapi event: convert POWERDOWN Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 11/29] qapi event: convert STOP Wenchao Xia
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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 fbdbc7c..6f27555 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -20,3 +20,12 @@
 # Since: 2.1
 ##
 { 'event': 'POWERDOWN' }
+
+##
+# @RESET
+#
+# Emitted when the virtual machine is reset
+#
+# Since: 2.1
+##
+{ 'event': 'RESET' }
diff --git a/vl.c b/vl.c
index 69ad0e9..b95fc5e 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(NULL);
     }
     cpu_synchronize_all_post_reset();
 }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 11/29] qapi event: convert STOP
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (9 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 10/29] qapi event: convert RESET Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 20:29   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 12/29] qapi event: convert RESUME Wenchao Xia
                   ` (18 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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..28abb11 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(NULL);
     }
 
     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 6f27555..af5a18c 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -29,3 +29,12 @@
 # Since: 2.1
 ##
 { 'event': 'RESET' }
+
+##
+# @STOP
+#
+# Emitted when the virtual machine is stopped
+#
+# Since: 2.1
+##
+{ 'event': 'STOP' }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 12/29] qapi event: convert RESUME
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (10 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 11/29] qapi event: convert STOP Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 20:33   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 13/29] qapi event: convert SUSPEND Wenchao Xia
                   ` (17 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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 af5a18c..3485985 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -38,3 +38,12 @@
 # Since: 2.1
 ##
 { 'event': 'STOP' }
+
+##
+# @RESUME
+#
+# Emitted when the virtual machine resumes execution
+#
+# Since: 2.1
+##
+{ 'event': 'RESUME' }
diff --git a/vl.c b/vl.c
index b95fc5e..d195e50 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(NULL);
     }
 }
 
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 13/29] qapi event: convert SUSPEND
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (11 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 12/29] qapi event: convert RESUME Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 20:40   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 14/29] qapi event: convert SUSPEND_DISK Wenchao Xia
                   ` (16 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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 3485985..83c4ea2 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -47,3 +47,13 @@
 # Since: 2.1
 ##
 { 'event': 'RESUME' }
+
+##
+# @SUSPEND
+#
+# Emitted when guest enters a hardware suspension state, for example, S3 state,
+# which is sometimes called standby state
+#
+# Since: 2.1
+##
+{ 'event': 'SUSPEND' }
diff --git a/vl.c b/vl.c
index d195e50..c6cb2c1 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(NULL);
 }
 
 void qemu_system_suspend_request(void)
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 14/29] qapi event: convert SUSPEND_DISK
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (12 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 13/29] qapi event: convert SUSPEND Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 20:42   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 15/29] qapi event: convert WAKEUP Wenchao Xia
                   ` (15 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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..ace6438 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(NULL);
                 qemu_system_shutdown_request();
             }
             break;
diff --git a/qapi-event.json b/qapi-event.json
index 83c4ea2..c68edfd 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -57,3 +57,15 @@
 # Since: 2.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: 2.1
+##
+{ 'event': 'SUSPEND_DISK' }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 15/29] qapi event: convert WAKEUP
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (13 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 14/29] qapi event: convert SUSPEND_DISK Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 20:57   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE Wenchao Xia
                   ` (14 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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 c68edfd..32ac571 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -69,3 +69,12 @@
 # Since: 2.1
 ##
 { 'event': 'SUSPEND_DISK' }
+
+##
+# @WAKEUP
+#
+# Emitted when the guest has woken up from suspend state and is running
+#
+# Since: 2.1
+##
+{ 'event': 'WAKEUP' }
diff --git a/vl.c b/vl.c
index c6cb2c1..b8ad1df 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(NULL);
     }
     if (qemu_powerdown_requested()) {
         qemu_system_powerdown();
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (14 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 15/29] qapi event: convert WAKEUP Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 21:27   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG Wenchao Xia
                   ` (13 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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..7e4cffe 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), NULL);
     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 df54546..9bb3708 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), NULL);
 }
 
 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 e122381..e6d32c2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -612,6 +612,9 @@ static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
 
 static void monitor_qapi_event_init(void)
 {
+    /* Limit RTC & BALLOON events to 1 per second */
+    monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000);
+
     qmp_event_set_func_emit(monitor_qapi_event_queue);
 }
 
@@ -737,7 +740,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 32ac571..dc20bb4 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -78,3 +78,16 @@
 # Since: 2.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: 2.1
+##
+{ 'event': 'RTC_CHANGE',
+  'data': { 'offset': 'int' } }
diff --git a/vl.c b/vl.c
index b8ad1df..cb56714 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.7.1

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

* [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (15 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-13 21:47   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 18/29] qapi event: convert DEVICE_DELETED Wenchao Xia
                   ` (12 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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..9284d3f 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, NULL);
         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, NULL);
         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, NULL);
         exit(0);
 
     case WDT_PAUSE:             /* same as 'stop' command in monitor */
-        watchdog_mon_event("pause");
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_PAUSE, NULL);
         vm_stop(RUN_STATE_WATCHDOG);
         break;
 
     case WDT_DEBUG:
-        watchdog_mon_event("debug");
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_DEBUG, NULL);
         fprintf(stderr, "watchdog: timer fired\n");
         break;
 
     case WDT_NONE:
-        watchdog_mon_event("none");
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_NONE, NULL);
         break;
     }
 }
diff --git a/monitor.c b/monitor.c
index e6d32c2..cae60ab 100644
--- a/monitor.c
+++ b/monitor.c
@@ -614,6 +614,7 @@ static void monitor_qapi_event_init(void)
 {
     /* Limit RTC & BALLOON 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);
 }
@@ -741,7 +742,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 dc20bb4..640f841 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: 2.1
+##
+{ 'event': 'WATCHDOG',
+  'data': { 'action': 'WatchdogExpirationAction' } }
diff --git a/qapi-schema.json b/qapi-schema.json
index d04514a..a14504d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4799,4 +4799,28 @@
 { 'enum': 'BlockErrorAction',
   'data': [ 'ignore', 'report', 'stop' ] }
 
+##
+# @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.7.1

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

* [Qemu-devel] [PATCH V6 18/29] qapi event: convert DEVICE_DELETED
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (16 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 19/29] qapi event: convert DEVICE_TRAY_MOVED Wenchao Xia
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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..a6c62b2 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, NULL);
         g_free(path);
     }
 }
diff --git a/qapi-event.json b/qapi-event.json
index 640f841..fc83fed 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: 2.1
+##
+{ 'event': 'DEVICE_DELETED',
+  'data': { '*device': 'str', 'path': 'str' } }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 19/29] qapi event: convert DEVICE_TRAY_MOVED
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (17 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 18/29] qapi event: convert DEVICE_DELETED Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 20/29] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR Wenchao Xia
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
---
 block.c                 |   21 +++++++--------------
 docs/qmp/qmp-events.txt |   18 ------------------
 qapi-event.json         |   15 +++++++++++++++
 3 files changed, 22 insertions(+), 32 deletions(-)

diff --git a/block.c b/block.c
index 84ad945..52f4580 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, NULL);
         }
         if (load) {
             /* tray close */
-            bdrv_emit_qmp_eject_event(bs, false);
+            qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
+                                              false, NULL);
         }
     }
 }
@@ -5173,7 +5165,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, NULL);
     }
 }
 
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-event.json b/qapi-event.json
index fc83fed..c2c65f9 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -122,3 +122,18 @@
 ##
 { 'event': 'DEVICE_DELETED',
   'data': { '*device': 'str', 'path': 'str' } }
+
+##
+# @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: 2.1
+##
+{ 'event': 'DEVICE_TRAY_MOVED',
+  'data': { 'device': 'str', 'tray-open': 'bool' } }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 20/29] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (18 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 19/29] qapi event: convert DEVICE_TRAY_MOVED Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 21/29] qapi event: convert BLOCK_IMAGE_CORRUPTED Wenchao Xia
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
---
 block.c                   |   36 +++------------------------------
 blockjob.c                |    6 ++++-
 docs/qmp/qmp-events.txt   |   47 ---------------------------------------------
 include/block/block_int.h |    3 --
 qapi-event.json           |   38 ++++++++++++++++++++++++++++++++++++
 qapi-schema.json          |   14 +++++++++++++
 6 files changed, 61 insertions(+), 83 deletions(-)

diff --git a/block.c b/block.c
index 52f4580..1ebbce6 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) {
@@ -3612,7 +3581,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, NULL);
     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..43f971d 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, NULL);
     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 f2e753f..0995316 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -399,9 +399,6 @@ AioContext *bdrv_get_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-event.json b/qapi-event.json
index c2c65f9..c889dbf 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -137,3 +137,41 @@
 ##
 { 'event': 'DEVICE_TRAY_MOVED',
   'data': { 'device': 'str', 'tray-open': 'bool' } }
+
+##
+# @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: 2.1
+##
+{ '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: 2.1
+##
+{ 'event': 'BLOCK_JOB_ERROR',
+  'data': { 'device'   : 'str',
+            'operation': 'IoOperationType',
+            'action'   : 'BlockdevOnError' } }
diff --git a/qapi-schema.json b/qapi-schema.json
index a14504d..23be2bf 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4823,4 +4823,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' }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 21/29] qapi event: convert BLOCK_IMAGE_CORRUPTED
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (19 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 20/29] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-16 22:53   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 22/29] qapi event: convert other BLOCK_JOB events Wenchao Xia
                   ` (8 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
---
 block/qcow2-refcount.c  |   14 ++++++++------
 docs/qmp/qmp-events.txt |   22 ----------------------
 qapi-event.json         |   22 ++++++++++++++++++++++
 3 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 9507aef..2fca5a1 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,
+                                              NULL);
         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-event.json b/qapi-event.json
index c889dbf..640eaa0 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -159,6 +159,28 @@
             'action': 'BlockErrorAction' } }
 
 ##
+# @BLOCK_IMAGE_CORRUPTED
+#
+# Emitted when a disk image is being marked corrupt
+#
+# @device: device name
+#
+# @msg: informative message, for example, reason for the corruption
+#
+# @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: 2.1
+##
+{ 'event': 'BLOCK_IMAGE_CORRUPTED',
+  'data': { 'device' : 'str',
+            'msg'    : 'str',
+            '*offset': 'int',
+            '*size'  : 'int' } }
+
+##
 # @BLOCK_JOB_ERROR
 #
 # Emitted when a block job encounters an error
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 22/29] qapi event: convert other BLOCK_JOB events
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (20 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 21/29] qapi event: convert BLOCK_IMAGE_CORRUPTED Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-16 22:57   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 23/29] qapi event: convert NIC_RX_FILTER_CHANGED Wenchao Xia
                   ` (7 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Since BLOCK_JOB_COMPLETED, BLOCK_JOB_CANCELLED, BLOCK_JOB_READY are
related, converts 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>
---
 block/mirror.c           |    2 +-
 blockdev.c               |   12 +++----
 blockjob.c               |   36 +++++++++++++----------
 docs/qmp/qmp-events.txt  |   71 ----------------------------------------------
 include/block/blockjob.h |   17 ++++++++--
 qapi-event.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 9b5261b..9cc2c0c 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1851,23 +1851,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 43f971d..d21f51e 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,
+                                        NULL);
+}
 
-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,
+                                        NULL);
 }
 
-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), NULL);
 }
 
 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-event.json b/qapi-event.json
index 640eaa0..bc47104 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -181,6 +181,62 @@
             '*size'  : 'int' } }
 
 ##
+# @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: 2.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: 2.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
@@ -197,3 +253,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: 2.1
+##
+{ 'event': 'BLOCK_JOB_READY',
+  'data': { 'device': 'str' } }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 23/29] qapi event: convert NIC_RX_FILTER_CHANGED
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (21 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 22/29] qapi event: convert other BLOCK_JOB events Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 24/29] qapi event: convert VNC events Wenchao Xia
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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..f6d3447 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, NULL);
         g_free(path);
 
         /* disable event notification to avoid events flooding */
diff --git a/qapi-event.json b/qapi-event.json
index bc47104..0f840e4 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -268,3 +268,18 @@
 ##
 { 'event': 'BLOCK_JOB_READY',
   'data': { 'device': '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: 2.1
+##
+{ 'event': 'NIC_RX_FILTER_CHANGED',
+  'data': { '*name': 'str', 'path': 'str' } }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 24/29] qapi event: convert VNC events
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (22 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 23/29] qapi event: convert NIC_RX_FILTER_CHANGED Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-16 23:01   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 25/29] qapi event: convert SPICE events Wenchao Xia
                   ` (5 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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 0f840e4..e4cb2d0 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -283,3 +283,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: 2.1
+##
+{ '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: 2.1
+##
+{ 'event': 'VNC_INITIALIZED',
+  'data': { 'server': 'VncServerInfo',
+            'client': 'VncClientInfo' } }
+
+##
+# @VNC_DISCONNECTED
+#
+# Emitted when the connection is closed
+#
+# @server: server information
+#
+# @client: client information
+#
+# Since: 2.1
+##
+{ 'event': 'VNC_DISCONNECTED',
+  'data': { 'server': 'VncServerInfo',
+            'client': 'VncClientInfo' } }
diff --git a/ui/vnc.c b/ui/vnc.c
index 469852a..989dc3f 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, NULL);
+        break;
+    case QAPI_EVENT_VNC_INITIALIZED:
+        qapi_event_send_vnc_initialized(si, vs->info, NULL);
+        break;
+    case QAPI_EVENT_VNC_DISCONNECTED:
+        qapi_event_send_vnc_disconnected(si, vs->info, NULL);
+        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);
@@ -2319,7 +2322,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);
 
@@ -2842,7 +2845,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.7.1

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

* [Qemu-devel] [PATCH V6 25/29] qapi event: convert SPICE events
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (23 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 24/29] qapi event: convert VNC events Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-16 23:05   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 26/29] qapi event: convert BALLOON_CHANGE Wenchao Xia
                   ` (4 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

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
more caller exist now.

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>
---
 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 e4cb2d0..0849584 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -332,3 +332,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: 2.1
+##
+{ '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: 2.1
+##
+{ 'event': 'SPICE_INITIALIZED',
+  'data': { 'server': 'SpiceServerInfo',
+            'client': 'SpiceChannel' } }
+
+##
+# @SPICE_DISCONNECTED
+#
+# Emitted when the SPICE connection is closed
+#
+# @server: server information
+#
+# @client: client information
+#
+# Since: 2.1
+##
+{ 'event': 'SPICE_DISCONNECTED',
+  'data': { 'server': 'SpiceBasicInfo',
+            'client': 'SpiceBasicInfo' } }
+
+##
+# @SPICE_MIGRATE_COMPLETED
+#
+# Emitted when SPICE migration has completed
+#
+# Since: 2.1
+##
+{ 'event': 'SPICE_MIGRATE_COMPLETED' }
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 8d54fb3..4605f80 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, NULL);
+        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, NULL);
+        break;
+    case SPICE_CHANNEL_EVENT_DISCONNECTED:
         channel_list_del(info);
+        qapi_event_send_spice_disconnected(server->base, client->base, NULL);
+        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(NULL);
     spice_migration_completed = true;
 }
 
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 7f558bb..c930876 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -94,16 +94,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.7.1

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

* [Qemu-devel] [PATCH V6 26/29] qapi event: convert BALLOON_CHANGE
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (24 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 25/29] qapi event: convert SPICE events Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 27/29] qapi event: convert GUEST_PANICKED Wenchao Xia
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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 bf2b588..75d24b2 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>
@@ -294,8 +295,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),
+                        NULL);
     }
 }
 
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 cae60ab..b0a54cf 100644
--- a/monitor.c
+++ b/monitor.c
@@ -615,6 +615,7 @@ static void monitor_qapi_event_init(void)
     /* Limit RTC & BALLOON 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);
 }
@@ -740,8 +741,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 0849584..93f9eeb 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -387,3 +387,16 @@
 # Since: 2.1
 ##
 { '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: 2.1
+##
+{ 'event': 'BALLOON_CHANGE',
+  'data': { 'actual': 'int' } }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 27/29] qapi event: convert GUEST_PANICKED
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (25 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 26/29] qapi event: convert BALLOON_CHANGE Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-16 14:08   ` Eric Blake
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 28/29] qapi event: convert QUORUM events Wenchao Xia
                   ` (2 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

'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>
---
 docs/qmp/qmp-events.txt |   14 --------------
 hw/misc/pvpanic.c       |   13 ++-----------
 qapi-event.json         |   12 ++++++++++++
 qapi-schema.json        |   12 ++++++++++++
 target-s390x/kvm.c      |    8 +++-----
 5 files changed, 29 insertions(+), 30 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..d396b74 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_PANICK_ACTION_PAUSE, NULL);
         vm_stop(RUN_STATE_GUEST_PANICKED);
         return;
     }
diff --git a/qapi-event.json b/qapi-event.json
index 93f9eeb..6bfc2a7 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -400,3 +400,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: 2.1
+##
+{ 'event': 'GUEST_PANICKED',
+  'data': { 'action': 'GuestPanickAction' } }
diff --git a/qapi-schema.json b/qapi-schema.json
index 23be2bf..badc1bf 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4837,4 +4837,16 @@
 { 'enum': 'IoOperationType',
   'data': [ 'read', 'write' ] }
 
+##
+# @GuestPanickAction
+#
+# An enumeration of the actions taken when guest OS panic is detected
+#
+# @pause: system pauses
+#
+# Since: 2.1
+##
+{ 'enum': 'GuestPanickAction',
+  'data': [ 'pause' ] }
+
 { 'include': 'qapi-event.json' }
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 7a07f9d..2212583 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -38,6 +38,7 @@
 #include "monitor/monitor.h"
 #include "exec/gdbstub.h"
 #include "trace.h"
+#include "qapi-event.h"
 
 /* #define DEBUG_KVM */
 
@@ -891,11 +892,8 @@ static int handle_intercept(S390CPU *cpu)
                 if (is_special_wait_psw(cs)) {
                     qemu_system_shutdown_request();
                 } else {
-                    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_PANICK_ACTION_PAUSE,
+                                                   NULL);
                     vm_stop(RUN_STATE_GUEST_PANICKED);
                 }
             }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 28/29] qapi event: convert QUORUM events
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (26 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 27/29] qapi event: convert GUEST_PANICKED Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 29/29] qapi event: clean up Wenchao Xia
  2014-06-10  5:48 ` [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Paolo Bonzini
  29 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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 ecec3a5..5d1c3dc 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, NULL);
 }
 
 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, NULL);
 }
 
 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 b0a54cf..aaf6f9d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -616,6 +616,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);
 }
@@ -741,9 +744,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 6bfc2a7..395a143 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -412,3 +412,41 @@
 ##
 { 'event': 'GUEST_PANICKED',
   'data': { 'action': 'GuestPanickAction' } }
+
+##
+# @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.1
+##
+{ '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.1
+##
+{ 'event': 'QUORUM_REPORT_BAD',
+  'data': { '*error': 'str', 'node-name': 'str',
+            'sector-num': 'int', 'sector-count': 'int' } }
-- 
1.7.1

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

* [Qemu-devel] [PATCH V6 29/29] qapi event: clean up
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (27 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 28/29] qapi event: convert QUORUM events Wenchao Xia
@ 2014-06-05 12:22 ` Wenchao Xia
  2014-06-16 14:09   ` Eric Blake
  2014-06-10  5:48 ` [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Paolo Bonzini
  29 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-05 12:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: mdroth, armbru, Wenchao Xia, lcapitulino

Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
---
 include/monitor/monitor.h  |   40 --------
 monitor.c                  |  216 +-------------------------------------------
 stubs/Makefile.objs        |    1 -
 stubs/mon-protocol-event.c |    6 --
 4 files changed, 3 insertions(+), 260 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 aaf6f9d..9f920f3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -179,14 +179,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;       /* Period over which to throttle. 0 to disable */
@@ -447,58 +439,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];
 
 /*
@@ -624,156 +565,6 @@ static void monitor_qapi_event_init(void)
 }
 
 
-/*
- * 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
-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)
 {
@@ -1168,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));
@@ -5294,7 +5085,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.7.1

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

* Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
  2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
                   ` (28 preceding siblings ...)
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 29/29] qapi event: clean up Wenchao Xia
@ 2014-06-10  5:48 ` Paolo Bonzini
  2014-06-15  0:52   ` Wenchao Xia
  29 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-10  5:48 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

Il 05/06/2014 14:21, Wenchao Xia ha scritto:
> This series add support for tag/keyword 'event' in qapi-schema.
> A new file was created to store some helper functions in patch 2, patch 4 is
> the test case, patch 5 is a convert example.
>
> The implemention is done by generate API and a batch of parameters for each
> event define, it doesn't generate a struture and visit function in the
> background for every event, so it doesn't support nested structure in the
> define to avoid trouble. A callback layer is added to control the behavior.
> More detail can be found in patch 3's message and incode comments.
>
> v2:
>   Address Luiz's comments:
>   patch 3: rename *err to *local_err, do not initialize *qmp = NULL, create
> a new function qmp_build_evet_dict().
>   Other change:
>   reorgnized script in patch 3, it have a clear three steps, see patch 3's
> incode comments.
>
> v3:
>   Address Luiz's comments:
>   2/5: use -1 when fail to get host timestamp.
>   3/5: typo fix and better incode comments. all unchanged functions are moved
> into qmp-event.c, from generated file. To do so without include issue, 'int'
> was used intead of 'enum' in function prototype declaration, since the 'enum'
> define is a generated type.
>   Address Eric's comments:
>   2/5: use -1 when fail to get host timestamp.
>   3/5: typo fix, add docs/qapi-code-gen.txt.
>   4/5: typo fix, verify no other fields in member 'timestamp'.
>   5/5: add doc in qapi-schema.json.
>   fix license, all script using GPL2, all C code use LGPL, just as other
> similar files in upstream.
>
> v4:
>   Address Eric's comments:
>   2/5: typo fix, add copyright declaration, use a static function pointer
> instead of a struct in C file, assign -1 in two line of codes to avoid issue
> when tv_sec and tv_usec are not in same data width, fix indention.
>   3/5: typo fix, add copyright declaration.
>   4/5: add copyright declaration, simplify string compare with
>  "d->result = g_strcmp0(...) == 0;", add check for tv_usec's range and value.
>   Other:
>   3/5: all error check code was moved from qapi-event.py to qapi.py, and it
> reports better message with line number info. Added related test case.
>   Note:
>   Benoit's series which track input file better seems not the final version,
> so I didn't rebase this series ontop for now, will do it once Benoit's ones
> get ACKed.
>
> v5:
>   Address Eric and Markus's comments:
>   2/28: use uint64_t for both sec and usec, to avoid type cast issue in printf.
>   Other:
>   Remove RFC, add full coversion by patch 5-28.
>   3/28: add prefix for event enum type name, to avoid double define of
> QAPIEvent in test code.
>
> v6:
>   Address Eric's comments:
>   3/29: employ modularization mechnism of schema file of Lluís series, remove
> error_is_set() usage.
>   4/29: Makefile change for Lluís series.
>   5/29: separate patch for refactoring the existing schema defines, improve doc
> for @service in VncBasicInfo.
>   7/29-28/29: define and convert event caller one by one.
>   Other change:
>   6/29: new way to add event emit implemention. In v5 it breaks old event
> mechnism, in v6 it touch nothing of old event mechnism but add a new set of
> functions for new event mechnism.
>   7/29: Add new file qapi-event.json to store event defines, and all type
> defines goes into qapi-schema.json.
>   29/29: related clean up change.
>   Note:
>   I have no way to verify target-s390x/kvm.c touched by patch 27/29, and
> block/quorum.c touched by patch 28/29, need a confirm from whom has the test
> env.
>
> Wenchao Xia (29):
>   1 os-posix: include sys/time.h
>   2 qapi: add event helper functions
>   3 qapi script: add event support
>   4 test: add test cases for qapi event
>   5 qapi: adjust existing defines
>   6 monitor: add an implemention as qapi event emit method
>   7 qapi: add new schema file qapi-event.json
>   8 qapi event: convert SHUTDOWN
>   9 qapi event: convert POWERDOWN
>   10 qapi event: convert RESET
>   11 qapi event: convert STOP
>   12 qapi event: convert RESUME
>   13 qapi event: convert SUSPEND
>   14 qapi event: convert SUSPEND_DISK
>   15 qapi event: convert WAKEUP
>   16 qapi event: convert RTC_CHANGE
>   17 qapi event: convert WATCHDOG
>   18 qapi event: convert DEVICE_DELETED
>   19 qapi event: convert DEVICE_TRAY_MOVED
>   20 qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
>   21 qapi event: convert BLOCK_IMAGE_CORRUPTED
>   22 qapi event: convert other BLOCK_JOB events
>   23 qapi event: convert NIC_RX_FILTER_CHANGED
>   24 qapi event: convert VNC events
>   25 qapi event: convert SPICE events
>   26 qapi event: convert BALLOON_CHANGE
>   27 qapi event: convert GUEST_PANICKED
>   28 qapi event: convert QUORUM events
>   29 qapi event: clean up
>
>  Makefile                                 |   21 +-
>  Makefile.objs                            |    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/os-posix.h                |    2 +
>  include/sysemu/sysemu.h                  |    2 -
>  monitor.c                                |  185 +++--------
>  qapi-event.json                          |  452 +++++++++++++++++++++++++
>  qapi-schema.json                         |  178 +++++++++--
>  qapi/Makefile.objs                       |    1 +
>  qapi/qmp-event.c                         |   74 ++++
>  scripts/qapi-event.py                    |  369 ++++++++++++++++++++
>  scripts/qapi.py                          |   12 +
>  stubs/Makefile.objs                      |    1 -
>  stubs/mon-protocol-event.c               |    6 -
>  target-s390x/kvm.c                       |    8 +-
>  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/qapi-schema-test.json  |   12 +
>  tests/qapi-schema/qapi-schema-test.out   |   10 +-
>  tests/test-qmp-event.c                   |  265 +++++++++++++++
>  trace-events                             |    4 +
>  ui/spice-core.c                          |   77 +++--
>  ui/vnc.c                                 |  120 ++++----
>  ui/vnc.h                                 |    4 +-
>  util/qemu-sockets.c                      |   10 +-
>  vl.c                                     |   22 +-
>  58 files changed, 1732 insertions(+), 1087 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
>
>
>

Tested-by: Paolo Bonzini <pbonzini@redhat.com>

Unfortunately, this already does not apply anymore.

I've placed the rebase on branch qapi-event of my github repository. 
The resolutions are trivial, so perhaps Luiz or Michael can pull from there?

Paolo

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

* Re: [Qemu-devel] [PATCH V6 03/29] qapi script: add event support
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 03/29] qapi script: add event support Wenchao Xia
@ 2014-06-13 16:47   ` Eric Blake
  2014-06-13 21:28   ` Eric Blake
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 16:47 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:21 AM, Wenchao Xia wrote:
> qapi-event.py will parse the schema and generate qapi-event.c, then
> the API in qapi-event.c can be used to handle event in qemu code.

s/event in/events in/

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

My python is weak, but I did apply this patch (or rather, used Paolo's
rebase of this patch) to test the generated files.

At this point, I'm interested in seeing the series go in sooner rather
than later, and my findings below are minor enough that I'm okay fixing
them in a followup patch rather than waiting for a respin of the whole
series.

Your patch fails to update .gitignore for the new generated files:

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	qapi-event.c
	qapi-event.h

>  
> +=== Events ===
> +
> +Events are defined with key word 'event'.  When 'data' is also specified,
> +additional info will be carried on.  Finally there will be C API generated

s/carried on/included in the event/

> +++ b/scripts/qapi-event.py
> +
> +def _generate_event_api_name(event_name, params):
> +    api_name = "void qapi_event_send_%s(" % c_fun(event_name).lower();

As of this commit, no events using qapi_event_send are generated yet.
I'm trusting that this code works, but I reserve the right to revisit
this patch later once I look at later patches and see what the generated
code is doing there.  But for now, the generated code has merely:

const char *QAPIEvent_lookup[] = {
    NULL,
};

which looks correct, even if a bit sparse :)

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

s/ now// - we don't EVER want to support nested structures in events
(for that matter, I've been arguing in other threads that we want to
completely ditch support for nested structures to simplify the generator
code-base and make it possible to cleanly support argument defaults).

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

Of course, if you tweak the message above, you'll also have to tweak
this test.  But thanks for adding a test!

Since I'm okay saving the cleanups mentioned above for a followup-patch,
and assuming I don't revisit this file:

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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 04/29] test: add test cases for qapi event
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 04/29] test: add test cases for qapi event Wenchao Xia
@ 2014-06-13 17:05   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 17:05 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:21 AM, Wenchao Xia wrote:
> These cases will verify whether the expected qdict is built.
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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
> 


> +
> +    /* Verify that we have timestamp, then remove it to compare other field */

s/field/fields/

Minor enough to include that as part of your followup patch to the whole
series.

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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 05/29] qapi: adjust existing defines
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 05/29] qapi: adjust existing defines Wenchao Xia
@ 2014-06-13 17:32   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 17:32 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> 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.

If you were to respin this, I'd split it into two - one part moving
BlockErrorAction from block.h into the schema, and the other tweaking
spice and vnc schema members.  But at this point, I'm more interested in
getting it into the tree than worrying about another round of delays for
a respin.

> 
> One thing not perfect is that, VncInfo should be foldered but may break

s/that,/that/

"foldered" is not a word, but off-hand I have no idea what you meant. [1]

> API stability.
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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       |  126 ++++++++++++++++++++++++++++++++++++++----------

Of course, some of this is in qapi/block-core.json now; but Paolo's
rebased series picked up on that.

>  ui/spice-core.c        |    7 ++-
>  ui/vnc.c               |    9 ++--
>  util/qemu-sockets.c    |   10 ++++
>  15 files changed, 156 insertions(+), 66 deletions(-)
> 

> +++ b/qapi-schema.json
> @@ -1163,21 +1163,59 @@
>  { 'command': 'query-blockstats', 'returns': ['BlockStats'] }
>  
>  ##
> -# @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' ] }

Nice. Conversion of 'str' to 'NetworkAddressFamily' has no impact to the
on-the-wire format, but makes us have better type safety.

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

s/of/of the/

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

I wonder if this parameter should eventually be converted to an enum
rather than open-coded str, but that doesn't need to happen right away.

> +#
> +# 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.
> @@ -1188,8 +1226,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' } }

Spurious addition of spaces; s/   :/:/ in your cleanup patch.

>  
>  ##
>  # @VncInfo:
> @@ -1228,7 +1266,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']} }

[1] Okay, I think I see what you meant in your commit message.  You did
NOT convert 'VncInfo' to use 'VncBasicInfo' as a base class, because you
were worried about whether it would break things.  And your worry is
justified - VncBasicInfo marks 'host', 'family', and 'service' as
manadatory, while 'VncInfo' marks them as optional.

If VncInfo is only used on the output side of commands (which indeed
appears to be the case - it is only used as the return of 'query-vnc'),
then converting from optional to mandatory is fine from the
backwards-compatibility aspect; the only question is whether the
existing code for query-vnc has sane defaults for those three fields in
the case where it was previously omitting them.  If you choose to make
that change, do it as a followup patch.  This patch is fine.  And now
that I understand your concern, I'd rewrite that paragraph in the commit
message to this (and either Paolo can rebase it back into his github
tree, or whoever applies the patches can make the tweak when adding my R-b):

At this point, VncInfo is not made a child of VncBasicInfo, due to the
difference in mandatory vs. optional parameters.

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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 06/29] monitor: add an implemention as qapi event emit method
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 06/29] monitor: add an implemention as qapi event emit method Wenchao Xia
@ 2014-06-13 19:04   ` Eric Blake
  2014-06-15  0:27     ` Wenchao Xia
  0 siblings, 1 reply; 77+ messages in thread
From: Eric Blake @ 2014-06-13 19:04 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:

In the subject: s/as/of/

> Now monitor has been hooked on the new event mechanism, so the patches

s/Now/The/

> later can convert event callers one by one. Most code are copied from

s/the patches later/that later patches/

s/are/is/

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

I only got one of those two warnings, about the unused function.  What
compiler and options are you using to get a warning about
QAPI_EVENT_MAX?.  Furthermore, since the default 'configure' turns
warnings into errors, this would be a build-breaker that hurts 'git
bisect'.  I think it's easy enough to avoid, if you would please squash
this in:

diff --git i/monitor.c w/monitor.c
index 952e1cb..a593d17 100644
--- i/monitor.c
+++ w/monitor.c
@@ -594,6 +594,7 @@ static void monitor_qapi_event_handler(void *opaque)
  * more than 1 event will be emitted within @rate
  * milliseconds
  */
+__attribute__((unused)) /* FIXME remove once in use */
 static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
 {
     MonitorQAPIEventState *evstate;


You can then remove that attribute later in 29/29 when you delete
everything else about the older implementation.

At this point, I think we're racking up enough fixes to be worth a v7
respin (particularly since avoiding 'git bisect' breakage cannot be done
as a followup patch, but has to be done in-place in the series).

> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  monitor.c    |  128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  trace-events |    4 ++
>  2 files changed, 131 insertions(+), 1 deletions(-)
> 

>  
> +typedef struct MonitorQAPIEventState {
> +    QAPIEvent 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 */

in what unit? [1]...

> +    QEMUTimer *timer;   /* Timer for handling delayed events */
> +    QObject *data;        /* Event pending delayed dispatch */

Any reason the comments aren't aligned?

> +} MonitorQAPIEventState;
> +
>  struct Monitor {
>      CharDriverState *chr;
>      int mux_out;
> @@ -489,6 +499,122 @@ 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];

If you are still seeing a compiler warning about allocating an array of
size 0, you could likewise try this hack:

/* FIXME Hack a minimum array size until we have events */
static MonitorQAPIEventState monitor_qapi_event_state[QAPI_EVENT_MAX +
!QAPI_EVENT_MAX];

and likewise clean that up in 29/29

> +static void
> +monitor_qapi_event_queue(int event_kind, QDict *data, Error **errp)

This is not the usual formatting in qemu.

> +{
> +    MonitorQAPIEventState *evstate;
> +    assert(event_kind < QAPI_EVENT_MAX);

This doesn't filter out negative values for event_kind.  Is it worth the
extra paranoia to either make event_kind unsigned, or to assert that
event_kind >= 0?

> +    QAPIEvent event = (QAPIEvent)event_kind;

Why are we casting here?  Would it not make more sense to change the
signature in patch 2/29 to use the enum type from the get-go?

typedef void (*QMPEventFuncEmit)(QAPIEvent event_kind, QDict *dict,
Error **errp);

and adjust the signature of this function to match

> +    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);

...[1] okay, it looks like 'rate' and 'last' are specified in
nanoseconds.  Worth documenting in their declaration above.
Particularly since [1]...

> +static void monitor_qapi_event_handler(void *opaque)
> +{
> +    MonitorQAPIEventState *evstate = opaque;
> +    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
> +
> +
> +    trace_monitor_qapi_event_handler(evstate->event,

Why the double blank line?

> +
> +/*
> + * @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 monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)

...[1] this function is documented in milliseconds, not nanoseconds, and
you are scaling internally.

> +{
> +    MonitorQAPIEventState *evstate;
> +    assert(event < QAPI_EVENT_MAX);
> +
> +    evstate = &(monitor_qapi_event_state[event]);
> +
> +    trace_monitor_qapi_event_throttle(event, rate);
> +    evstate->event = event;
> +    evstate->rate = rate * SCALE_MS;

This value can overflow if a user passes in an insanely large rate. Do
we care?

> +    evstate->last = 0;
> +    evstate->data = NULL;
> +    evstate->timer = timer_new(QEMU_CLOCK_REALTIME,
> +                               SCALE_MS,
> +                               monitor_qapi_event_handler,
> +                               evstate);

> @@ -507,7 +633,6 @@ monitor_protocol_event_emit(MonitorEvent event,
>      }
>  }
>  
> -
>  /*

Why the spurious line deletion?

> +++ b/trace-events
> @@ -932,6 +932,10 @@ monitor_protocol_event_handler(uint32_t event, void *data, uint64_t last, uint64
>  monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
>  monitor_protocol_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
>  monitor_protocol_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
> +monitor_qapi_event_emit(uint32_t event, void *data) "event=%d data=%p"
> +monitor_qapi_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
> +monitor_qapi_event_handler(uint32_t event, void *data, uint64_t last, uint64_t now) "event=%d data=%p last=%" PRId64 " now=%" PRId64
> +monitor_qapi_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64

Any reason you wanted to invent four new trace names, even though the
existing 4 traces have the same signatures?  I'm wondering whether it
would have just been better to use the old trace names.

-- 
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 related	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 07/29] qapi: add new schema file qapi-event.json
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 07/29] qapi: add new schema file qapi-event.json Wenchao Xia
@ 2014-06-13 19:25   ` Eric Blake
  2014-06-13 19:45     ` Eric Blake
  0 siblings, 1 reply; 77+ messages in thread
From: Eric Blake @ 2014-06-13 19:25 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, Max Reitz, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  Makefile         |   12 ++++++++----
>  qapi-schema.json |    2 ++
>  2 files changed, 10 insertions(+), 4 deletions(-)
>  create mode 100644 qapi-event.json
> 
> diff --git a/Makefile b/Makefile
> index 237657e..554fb2d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -247,22 +247,26 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
>  		"  GEN   $@")
>  
>  qapi-types.c qapi-types.h :\
> -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
> +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
> +$(SRC_PATH)/scripts/qapi-types.py $(qapi-py)

Please rebase this on top of Max's fix to add $(qapi-modules):
https://lists.gnu.org/archive/html/qemu-devel/2014-06/msg01838.html

> diff --git a/qapi-event.json b/qapi-event.json
> new file mode 100644
> index 0000000..e69de29

Probably better to name this file qapi/event.json, to go alongside the
other sub-files we have already created.

> diff --git a/qapi-schema.json b/qapi-schema.json
> index 115d8d0..d04514a 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -4798,3 +4798,5 @@
>  ##
>  { 'enum': 'BlockErrorAction',
>    'data': [ 'ignore', 'report', 'stop' ] }
> +
> +{ 'include': 'qapi-event.json' }

Rather than putting this at the bottom of the file, would it make sense
to put it at the top next to the other 'include' directives?

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 07/29] qapi: add new schema file qapi-event.json
  2014-06-13 19:25   ` Eric Blake
@ 2014-06-13 19:45     ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 19:45 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: armbru, lcapitulino, mdroth, Max Reitz

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

On 06/13/2014 01:25 PM, Eric Blake wrote:
> On 06/05/2014 06:22 AM, Wenchao Xia wrote:
>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
>> ---
>>  Makefile         |   12 ++++++++----
>>  qapi-schema.json |    2 ++
>>  2 files changed, 10 insertions(+), 4 deletions(-)
>>  create mode 100644 qapi-event.json
>>

>> diff --git a/qapi-event.json b/qapi-event.json
>> new file mode 100644
>> index 0000000..e69de29
> 
> Probably better to name this file qapi/event.json, to go alongside the
> other sub-files we have already created.

Also, I forgot to mention - adding an empty file to qemu.git is unusual.
When you respin, make the file non-empty by at least giving it a decent
comment at the top stating the purpose of the file.  You could even add
in a copyright/license comment, if we had any agreement on what to use
(but that's already a different thread, since I already pointed out on
Benoit's work to split out several .json files that we don't have any
example to choose from).

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 08/29] qapi event: convert SHUTDOWN
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 08/29] qapi event: convert SHUTDOWN Wenchao Xia
@ 2014-06-13 19:57   ` Eric Blake
  2014-06-15  0:32     ` Wenchao Xia
  0 siblings, 1 reply; 77+ messages in thread
From: Eric Blake @ 2014-06-13 19:57 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> This patch also eliminates build time warning caused by
> QAPI_EVENT_MAX = 0.

I still don't know why I wasn't seeing a warning for that, but agree
this cleans it up (or whichever event gets converted first, as there
aren't really any dependency restrictions in the order in which you do
conversions).  If you do follow my suggestion of adding a workaround in
6/29 to avoid build warnings, then don't undo it here, but save it until
29/29; that way, no one individual conversion is doing more work than
any other.

> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  docs/qmp/qmp-events.txt |   15 ---------------
>  qapi-event.json         |   12 ++++++++++++
>  vl.c                    |    3 ++-
>  3 files changed, 14 insertions(+), 16 deletions(-)

Yay - I finally have enough to see what code gets generated in 3/29.
The qapi-event.h header now has:

void qapi_event_send_shutdown(Error **errp);

extern const char *QAPIEvent_lookup[];
typedef enum QAPIEvent
{
    QAPI_EVENT_SHUTDOWN = 0,
    QAPI_EVENT_MAX = 1,
} QAPIEvent;


and the .c file has:

void qapi_event_send_shutdown(Error **errp)
{
    QDict *qmp;
    Error *local_err = NULL;
    QMPEventFuncEmit emit;
    emit = qmp_event_get_func_emit();
    if (!emit) {
        return;
    }

    qmp = qmp_event_build_dict("SHUTDOWN");

    emit(QAPI_EVENT_SHUTDOWN, qmp, &local_err);

    error_propagate(errp, local_err);
    QDECREF(qmp);
}


Looks good, for a data-free event (I guess I'll have to wait till later
in the series to see what gets generated for an event with data).  Hmm,
I wonder if patch 3/29 should have also modified docs/qapi-code-gen.txt
to show a sample generated function.

> 
> -
> -Emitted when the Virtual Machine is powered down.

> +++ b/qapi-event.json
> @@ -0,0 +1,12 @@
> +##
> +# @SHUTDOWN
> +#
> +# Emitted when the virtual machine shutdown, qemu terminated the emulation and
> +# is about to exit.

Different wording than the text it replaces, and the grammar is a bit
unusual.  Maybe:

Emitted when the virtual machine has shut down, indicating that qemu is
about to exit.

>      if (qemu_shutdown_requested()) {
>          qemu_kill_report();
> -        monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
> +        qapi_event_send_shutdown(NULL);

Note that the two NULLs serve different purposes.  In the old code, NULL
meant there was no additional data.  In the new code, NULL indicates
that we are ignoring the possibility for error.  I wonder if it would be
better to pass &error_abort instead of NULL?  For that matter, I just
re-read 6/29 - the one implementation we have of an emit function
(monitor_qapi_event_queue) never sets errp.  Is it better to just
consider events as best-effort, and completely ditch the errp parameter
from the emit callback typedef in 2/29, since it looks like you intend
to pass NULL for all clients of the callback?

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 09/29] qapi event: convert POWERDOWN
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 09/29] qapi event: convert POWERDOWN Wenchao Xia
@ 2014-06-13 20:02   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 20:02 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> There is no existing comments for POWERDOWN in doc/qmp/qmp-events.txt,
> so no change on it like other conversion patch.

Oddly enough, POWERDOWN _is_ documented in docs/qmp/qmp-spec.txt, but
that reference doesn't need updating with this conversion.

> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  qapi-event.json |   10 ++++++++++
>  vl.c            |    2 +-
>  2 files changed, 11 insertions(+), 1 deletions(-)

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

Modulo my comment in 8/29 on whether we even need an errp argument,

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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 11/29] qapi event: convert STOP
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 11/29] qapi event: convert STOP Wenchao Xia
@ 2014-06-13 20:29   ` Eric Blake
  2014-06-17  9:17     ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Eric Blake @ 2014-06-13 20:29 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  cpus.c                  |    5 +++--
>  docs/qmp/qmp-events.txt |   12 ------------
>  qapi-event.json         |    9 +++++++++
>  3 files changed, 12 insertions(+), 14 deletions(-)
> 

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

Same comments from earlier about not needing errp argument

> +++ b/qapi-event.json
> @@ -29,3 +29,12 @@
>  # Since: 2.1
>  ##
>  { 'event': 'RESET' }
> +
> +##
> +# @STOP
> +#
> +# Emitted when the virtual machine is stopped
> +#
> +# Since: 2.1

0.14.0

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 12/29] qapi event: convert RESUME
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 12/29] qapi event: convert RESUME Wenchao Xia
@ 2014-06-13 20:33   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 20:33 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  docs/qmp/qmp-events.txt |   12 ------------
>  qapi-event.json         |    9 +++++++++
>  vl.c                    |    2 +-
>  3 files changed, 10 insertions(+), 13 deletions(-)
> 

> +##
> +# @RESUME
> +#
> +# Emitted when the virtual machine resumes execution
> +#
> +# Since: 2.1

0.14.0

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 13/29] qapi event: convert SUSPEND
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 13/29] qapi event: convert SUSPEND Wenchao Xia
@ 2014-06-13 20:40   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 20:40 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  docs/qmp/qmp-events.txt |   12 ------------
>  qapi-event.json         |   10 ++++++++++
>  vl.c                    |    2 +-
>  3 files changed, 11 insertions(+), 13 deletions(-)
> 

> +##
> +# @SUSPEND
> +#
> +# Emitted when guest enters a hardware suspension state, for example, S3 state,
> +# which is sometimes called standby state
> +#
> +# Since: 2.1

1.1

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 14/29] qapi event: convert SUSPEND_DISK
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 14/29] qapi event: convert SUSPEND_DISK Wenchao Xia
@ 2014-06-13 20:42   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 20:42 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  docs/qmp/qmp-events.txt |   14 --------------
>  hw/acpi/core.c          |    4 ++--
>  qapi-event.json         |   12 ++++++++++++
>  3 files changed, 14 insertions(+), 16 deletions(-)
> 

> +++ b/qapi-event.json
> @@ -57,3 +57,15 @@
>  # Since: 2.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: 2.1

1.2

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 15/29] qapi event: convert WAKEUP
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 15/29] qapi event: convert WAKEUP Wenchao Xia
@ 2014-06-13 20:57   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 20:57 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  docs/qmp/qmp-events.txt |   12 ------------
>  qapi-event.json         |    9 +++++++++
>  vl.c                    |    2 +-
>  3 files changed, 10 insertions(+), 13 deletions(-)
> 

> +##
> +# @WAKEUP
> +#
> +# Emitted when the guest has woken up from suspend state and is running
> +#
> +# Since: 2.1

1.1

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE Wenchao Xia
@ 2014-06-13 21:27   ` Eric Blake
  2014-06-15  0:38     ` Wenchao Xia
                       ` (2 more replies)
  0 siblings, 3 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 21:27 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> This patch also eliminates build time warning caused by no caller
> of monitor_qapi_event_throttle().

Again, my suggestion on 6/29 could avoid that warning; if you use that
workaround, don't clean it until 29/29, but you can drop this paragraph
of this commit.

> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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(-)
> 

Yay - the first event with data, so I get to see what the generator does.

The .h file shows this signature:

>> void qapi_event_send_rtc_change(int64_t offset,
>>                                 Error **errp);

and the .c has this code:

>> void qapi_event_send_rtc_change(int64_t offset,
>>                                 Error **errp)
>> {
>>     QDict *qmp;
>>     Error *local_err = NULL;
>>     QMPEventFuncEmit emit;
>>     QmpOutputVisitor *qov;
>>     Visitor *v;
>>     QObject *obj;
>> 
>>     emit = qmp_event_get_func_emit();
>>     if (!emit) {
>>         return;
>>     }
>> 
>>     qmp = qmp_event_build_dict("RTC_CHANGE");
>> 
>>     qov = qmp_output_visitor_new();
>>     g_assert(qov);
>> 
>>     v = qmp_output_get_visitor(qov);
>>     g_assert(v);
>> 
>>     /* Fake visit, as if all member are under a structure */

Grammar error; guess I have more comments on 3/29.

>>     visit_start_struct(v, NULL, "", "RTC_CHANGE", 0, &local_err);
>>     if (local_err) {
>>         goto clean;
>>     }

Hmm, qmp_output_start_struct() never sets errp.

>> 
>>     visit_type_int(v, &offset, "offset", &local_err);
>>     if (local_err) {
>>         goto clean;
>>     }

Likewise, qmp_output_type_int never sets errp.

>> 
>>     visit_end_struct(v, &local_err);
>>     if (local_err) {
>>         goto clean;
>>     }

And neither does qmp_end_struct.

>> 
>>     obj = qmp_output_get_qobject(qov);
>>     g_assert(obj != NULL);
>> 
>>     qdict_put_obj(qmp, "data", obj);
>>     emit(QAPI_EVENT_RTC_CHANGE, qmp, &local_err);

And I already mentioned earlier that the only implementation of the
emit() callback never sets local_err (and probably doesn't even need it
as a parameter).

>> 
>>  clean:
>>     qmp_output_visitor_cleanup(qov);
>>     error_propagate(errp, local_err);
>>     QDECREF(qmp);
>> }

If you change the earlier 3 instances to just use visit_...(,
&error_abort), you can completely ditch the local_err variable, drop the
clean: label, and overall have a much shorter generated function.


> @@ -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), NULL);
>      spapr->rtc_offset = qemu_timedate_diff(&tm);

Eww. This makes me worry whether grabbing qemu_timedate_diff() two times
in a row may cause a different value to be reported than what is stored
locally.  Please grab it only once into a local variable, then copy that
value into both locations.

Once again, all callers of qapi_event_send_rtc_change() are passing a
NULL errp to silently ignore errors; and I just audited that no errors
happen anyways.

> +++ b/monitor.c
> @@ -612,6 +612,9 @@ static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>  
>  static void monitor_qapi_event_init(void)
>  {
> +    /* Limit RTC & BALLOON events to 1 per second */

Comment is a bit misleading until a later patch converts balloon events,...

> +    monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000);
> +
>      qmp_event_set_func_emit(monitor_qapi_event_queue);
>  }
>  
> @@ -737,7 +740,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);

...furthermore, the OLD comment was wrong (it forgot about the watchdog
event).  You could get around that by rewording the comment to just say
'limit guest-triggerable events to 1 per second' without calling out
what those events are.

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

0.14.0

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 03/29] qapi script: add event support
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 03/29] qapi script: add event support Wenchao Xia
  2014-06-13 16:47   ` Eric Blake
@ 2014-06-13 21:28   ` Eric Blake
  2014-06-18  3:33   ` Eric Blake
  2014-06-18  3:50   ` Eric Blake
  3 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 21:28 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:21 AM, Wenchao Xia wrote:
> qapi-event.py will parse the schema and generate qapi-event.c, then
> the API in qapi-event.c can be used to handle event in qemu code.
> All API have prefix "qapi_event".
> 

As promised, a revisit of the generator code now that I've looked at
more of it in use.  And since I've identified enough elsewhere that
warrants a series respin to v7, you should squash in fixes for these issues:

> +++ b/scripts/qapi-event.py

> +
> +def generate_event_implement(api_name, event_name, params):
> +    # step 1: declare and variables

s/and/any/


> +
> +    /* Fake visit, as if all member are under a structure */

s/member/members/

See also my comments on 16/29 - what if you change the generator to use
&error_abort instead of futzing around with local_error?  After all, the
qmp_output_visitor doesn't ever set errp; and all of your callers
silently ignore errp even if it were to be set.  Which makes sense,
since events are best-effort anyways (it's not like you are building up
a reply to a synchronous command, so you really don't have anyone to
inform about the failed event short of sending yet another event - but
if the first event failed, then your attempt to send another event to
inform about the failure is probably doomed).

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG Wenchao Xia
@ 2014-06-13 21:47   ` Eric Blake
  2014-06-13 22:05     ` Eric Blake
  2014-06-17  9:23     ` Paolo Bonzini
  0 siblings, 2 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-13 21:47 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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(-)
> 

> @@ -117,31 +108,31 @@ void watchdog_perform_action(void)
>  {
>      switch(watchdog_action) {

Worth fixing the missing space after switch while touching this area of
code?

>      case WDT_RESET:             /* same as 'system_reset' in monitor */
> -        watchdog_mon_event("reset");
> +        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_RESET, NULL);

More instances of ignoring the errp argument, where eliminating it might
be nicer.

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

0.14.0

> +  'data': { 'action': 'WatchdogExpirationAction' } }

Hmm.  You've managed to create error.json in such a manner that it is
not self-sufficient.  If some other file includes error.json, it must
also define WatchdogExpirationAction or it will fail the generators.

> +++ b/qapi-schema.json

> +##
> +# @WatchdogExpirationAction

I think you will be better off to ensure that error.json is
self-sufficient, perhaps by sticking any data type it references
directly into common.json rather than qapi-schema.json, and having
error.json include common.json.  (This is the first instance of
referencing an external type, but other events later in the series have
the same issue).

> +# Since: 2.1
> +##
> +{ 'enum': 'WatchdogExpirationAction',
> +  'data': [ 'reset', 'shutdown', 'poweroff', 'pause', 'debug', 'none' ] }

Nice conversion of open-coded string to an enum.  While I've been asking
for the earliest QMP version for Since fields on event objects proper,
here, I think you're okay keeping the 'since 2.1' indication.  Why?
Because we already have other examples in the code base of converting
open-coded strings to an enum, where the QMP wire format is the same,
but where the version claimed on those enums was the qemu version that
did the conversion rather than the age of the command being converted.
(Maybe we could audit all of those conversions and retroactively update
their Since field, or even come up with a notation for wire-stability
release vs. QAPI introspection release - but that sounds like more pain
than necessary with no obvious benefit)

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG
  2014-06-13 21:47   ` Eric Blake
@ 2014-06-13 22:05     ` Eric Blake
  2014-06-15  0:45       ` Wenchao Xia
  2014-06-17  9:23     ` Paolo Bonzini
  1 sibling, 1 reply; 77+ messages in thread
From: Eric Blake @ 2014-06-13 22:05 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

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

On 06/13/2014 03:47 PM, Eric Blake wrote:
> On 06/05/2014 06:22 AM, Wenchao Xia wrote:
>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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(-)
>>

> 
>> +  'data': { 'action': 'WatchdogExpirationAction' } }
> 
> Hmm.  You've managed to create error.json in such a manner that it is
> not self-sufficient.  If some other file includes error.json, it must
> also define WatchdogExpirationAction or it will fail the generators.

s/error.json/qapi-event.json/

> 
>> +++ b/qapi-schema.json
> 
>> +##
>> +# @WatchdogExpirationAction
> 
> I think you will be better off to ensure that error.json is

and again qapi-event.json (not sure why I typed error.json).

> self-sufficient, perhaps by sticking any data type it references
> directly into common.json rather than qapi-schema.json, and having
> error.json include common.json.  (This is the first instance of
> referencing an external type, but other events later in the series have
> the same issue).

Oh weird! I've managed to run all four of
scripts/qapi-{visit,types,commands,event}.py directly on
qapi-event.json, and didn't get any complaints from the generator.  BUT,
the generated code is definitely different:

-void qapi_event_send_watchdog(WatchdogExpirationAction action,
+void qapi_event_send_watchdog(WatchdogExpirationAction * action,
                               Error **errp)

That is, when the enum type is known (because the parse was done on
qapi-schema.json), the WatchdogExpirationAction argument is treated as
an integer enum value; but when the enum type is unknown (because the
parse was done directly on an incomplete qapi-event.json), the generator
tries to treat it as a pointer to an otherwise unknown structure.
(Never mind the odd formatting of the space after the '*' - I believe
this pending patch fixes it:
https://lists.gnu.org/archive/html/qemu-devel/2014-06/msg02385.html).

This little exercise raises red flags for me - we probably ought to
enhance the code generators to error out instead of blindly act as if
unknown types are pointers.  But save it for another day - no need to
stall this series just to wait for a robustness improvement to the
generators.

Meanwhile, my suggestion of making qapi-event.json to be self-sufficient
is going to be a bit harder to test, but is still probably worth trying
(just moving common types into a common shared include).

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 06/29] monitor: add an implemention as qapi event emit method
  2014-06-13 19:04   ` Eric Blake
@ 2014-06-15  0:27     ` Wenchao Xia
  0 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-15  0:27 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: mdroth, armbru, lcapitulino

于 2014/6/14 3:04, Eric Blake 写道:
> On 06/05/2014 06:22 AM, Wenchao Xia wrote:
>
> In the subject: s/as/of/
>
>> Now monitor has been hooked on the new event mechanism, so the patches
>
> s/Now/The/
>
>> later can convert event callers one by one. Most code are copied from
>
> s/the patches later/that later patches/
>
> s/are/is/
>
>> 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.
>
> I only got one of those two warnings, about the unused function.  What
> compiler and options are you using to get a warning about
> QAPI_EVENT_MAX?.  Furthermore, since the default 'configure' turns
> warnings into errors, this would be a build-breaker that hurts 'git
> bisect'.  I think it's easy enough to avoid, if you would please squash
> this in:
>

   The QAPI_EVENT_MAX = 0 cause a warning for code:

monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
{
     ....
     assert(event < QAPI_EVENT_MAX);
}

which is always false now. Perhaps change it as

assert((int)event < QAPI_EVENT_MAX);

?


> diff --git i/monitor.c w/monitor.c
> index 952e1cb..a593d17 100644
> --- i/monitor.c
> +++ w/monitor.c
> @@ -594,6 +594,7 @@ static void monitor_qapi_event_handler(void *opaque)
>    * more than 1 event will be emitted within @rate
>    * milliseconds
>    */
> +__attribute__((unused)) /* FIXME remove once in use */
>   static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>   {
>       MonitorQAPIEventState *evstate;
>
>
> You can then remove that attribute later in 29/29 when you delete
> everything else about the older implementation.
>
> At this point, I think we're racking up enough fixes to be worth a v7
> respin (particularly since avoiding 'git bisect' breakage cannot be done
> as a followup patch, but has to be done in-place in the series).
>

   Thanks for tipping, it is a good way to go.


>>
>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
>> ---
>>   monitor.c    |  128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>   trace-events |    4 ++
>>   2 files changed, 131 insertions(+), 1 deletions(-)
>>
>
>>
>> +typedef struct MonitorQAPIEventState {
>> +    QAPIEvent 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 */
>
> in what unit? [1]...
>
>> +    QEMUTimer *timer;   /* Timer for handling delayed events */
>> +    QObject *data;        /* Event pending delayed dispatch */
>
> Any reason the comments aren't aligned?

   Will fix.

>
>> +} MonitorQAPIEventState;
>> +
>>   struct Monitor {
>>       CharDriverState *chr;
>>       int mux_out;
>> @@ -489,6 +499,122 @@ 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];
>
> If you are still seeing a compiler warning about allocating an array of
> size 0, you could likewise try this hack:
>
> /* FIXME Hack a minimum array size until we have events */
> static MonitorQAPIEventState monitor_qapi_event_state[QAPI_EVENT_MAX +
> !QAPI_EVENT_MAX];
>
> and likewise clean that up in 29/29
>
>> +static void
>> +monitor_qapi_event_queue(int event_kind, QDict *data, Error **errp)
>
> This is not the usual formatting in qemu.

   Fixing it.

>
>> +{
>> +    MonitorQAPIEventState *evstate;
>> +    assert(event_kind < QAPI_EVENT_MAX);
>
> This doesn't filter out negative values for event_kind.  Is it worth the
> extra paranoia to either make event_kind unsigned, or to assert that
> event_kind >= 0?
>

   Build waring will be raised for QAPI_EVENT_MAX = 0, same as above,
any better way to solve?

>> +    QAPIEvent event = (QAPIEvent)event_kind;
>
> Why are we casting here?  Would it not make more sense to change the
> signature in patch 2/29 to use the enum type from the get-go?
>
> typedef void (*QMPEventFuncEmit)(QAPIEvent event_kind, QDict *dict,
> Error **errp);
>
> and adjust the signature of this function to match
>

   Since QAPIEvent is generated by qapi-event.py, and they are
different in qemu code and test code, so there will be conflict
in test code which include qmp-event.h:
in qemu:
qmp-event.h include qapi-event.h
in test:
qmp-event.h include test-qapi-event.h
For simple I just used int type instead of QAPIEvent type.

   To use QAPIEvent in declaration, I think there would be some
tricks in test, and doc that using qapi-event.h define in
qmp-event.c may break test code, the encapsulation is not very goood.


>> +    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>
> ...[1] okay, it looks like 'rate' and 'last' are specified in
> nanoseconds.  Worth documenting in their declaration above.
> Particularly since [1]...
>
>> +static void monitor_qapi_event_handler(void *opaque)
>> +{
>> +    MonitorQAPIEventState *evstate = opaque;
>> +    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
>> +
>> +
>> +    trace_monitor_qapi_event_handler(evstate->event,
>
> Why the double blank line?
>

   Copied code, will fix.

>> +
>> +/*
>> + * @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 monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>
> ...[1] this function is documented in milliseconds, not nanoseconds, and
> you are scaling internally.
>
>> +{
>> +    MonitorQAPIEventState *evstate;
>> +    assert(event < QAPI_EVENT_MAX);
>> +
>> +    evstate = &(monitor_qapi_event_state[event]);
>> +
>> +    trace_monitor_qapi_event_throttle(event, rate);
>> +    evstate->event = event;
>> +    evstate->rate = rate * SCALE_MS;
>
> This value can overflow if a user passes in an insanely large rate. Do
> we care?
>

   There is not much existing caller, maybe we can change it as
nonoseconds.

>> +    evstate->last = 0;
>> +    evstate->data = NULL;
>> +    evstate->timer = timer_new(QEMU_CLOCK_REALTIME,
>> +                               SCALE_MS,
>> +                               monitor_qapi_event_handler,
>> +                               evstate);
>
>> @@ -507,7 +633,6 @@ monitor_protocol_event_emit(MonitorEvent event,
>>       }
>>   }
>>
>> -
>>   /*
>
> Why the spurious line deletion?
>
   Will remove.

>> +++ b/trace-events
>> @@ -932,6 +932,10 @@ monitor_protocol_event_handler(uint32_t event, void *data, uint64_t last, uint64
>>   monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
>>   monitor_protocol_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
>>   monitor_protocol_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
>> +monitor_qapi_event_emit(uint32_t event, void *data) "event=%d data=%p"
>> +monitor_qapi_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
>> +monitor_qapi_event_handler(uint32_t event, void *data, uint64_t last, uint64_t now) "event=%d data=%p last=%" PRId64 " now=%" PRId64
>> +monitor_qapi_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
>
> Any reason you wanted to invent four new trace names, even though the
> existing 4 traces have the same signatures?  I'm wondering whether it
> would have just been better to use the old trace names.
>

   The old trace functions are still in use of old event code,
so I added fource new ones. The old ones should be removed in
cleanup patch.

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

* Re: [Qemu-devel] [PATCH V6 08/29] qapi event: convert SHUTDOWN
  2014-06-13 19:57   ` Eric Blake
@ 2014-06-15  0:32     ` Wenchao Xia
  0 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-15  0:32 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: mdroth, armbru, lcapitulino

于 2014/6/14 3:57, Eric Blake 写道:
> On 06/05/2014 06:22 AM, Wenchao Xia wrote:
>> This patch also eliminates build time warning caused by
>> QAPI_EVENT_MAX = 0.
>
> I still don't know why I wasn't seeing a warning for that, but agree
> this cleans it up (or whichever event gets converted first, as there
> aren't really any dependency restrictions in the order in which you do
> conversions).  If you do follow my suggestion of adding a workaround in
> 6/29 to avoid build warnings, then don't undo it here, but save it until
> 29/29; that way, no one individual conversion is doing more work than
> any other.
>
>>
>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
>> ---
>>   docs/qmp/qmp-events.txt |   15 ---------------
>>   qapi-event.json         |   12 ++++++++++++
>>   vl.c                    |    3 ++-
>>   3 files changed, 14 insertions(+), 16 deletions(-)
>
> Yay - I finally have enough to see what code gets generated in 3/29.
> The qapi-event.h header now has:
>
> void qapi_event_send_shutdown(Error **errp);
>
> extern const char *QAPIEvent_lookup[];
> typedef enum QAPIEvent
> {
>      QAPI_EVENT_SHUTDOWN = 0,
>      QAPI_EVENT_MAX = 1,
> } QAPIEvent;
>
>
> and the .c file has:
>
> void qapi_event_send_shutdown(Error **errp)
> {
>      QDict *qmp;
>      Error *local_err = NULL;
>      QMPEventFuncEmit emit;
>      emit = qmp_event_get_func_emit();
>      if (!emit) {
>          return;
>      }
>
>      qmp = qmp_event_build_dict("SHUTDOWN");
>
>      emit(QAPI_EVENT_SHUTDOWN, qmp, &local_err);
>
>      error_propagate(errp, local_err);
>      QDECREF(qmp);
> }
>
>
> Looks good, for a data-free event (I guess I'll have to wait till later
> in the series to see what gets generated for an event with data).  Hmm,
> I wonder if patch 3/29 should have also modified docs/qapi-code-gen.txt
> to show a sample generated function.
>
   Will add doc part.


>>
>> -
>> -Emitted when the Virtual Machine is powered down.
>
>> +++ b/qapi-event.json
>> @@ -0,0 +1,12 @@
>> +##
>> +# @SHUTDOWN
>> +#
>> +# Emitted when the virtual machine shutdown, qemu terminated the emulation and
>> +# is about to exit.
>
> Different wording than the text it replaces, and the grammar is a bit
> unusual.  Maybe:
>
> Emitted when the virtual machine has shut down, indicating that qemu is
> about to exit.
>
>>       if (qemu_shutdown_requested()) {
>>           qemu_kill_report();
>> -        monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
>> +        qapi_event_send_shutdown(NULL);
>
> Note that the two NULLs serve different purposes.  In the old code, NULL
> meant there was no additional data.  In the new code, NULL indicates
> that we are ignoring the possibility for error.  I wonder if it would be
> better to pass &error_abort instead of NULL?  For that matter, I just
> re-read 6/29 - the one implementation we have of an emit function
> (monitor_qapi_event_queue) never sets errp.  Is it better to just
> consider events as best-effort, and completely ditch the errp parameter
> from the emit callback typedef in 2/29, since it looks like you intend
> to pass NULL for all clients of the callback?
>
   It make things simple, I will remove &errp in next version.

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

* Re: [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE
  2014-06-13 21:27   ` Eric Blake
@ 2014-06-15  0:38     ` Wenchao Xia
  2014-06-15 14:01       ` Paolo Bonzini
  2014-06-15 14:00     ` Paolo Bonzini
  2014-06-17  9:21     ` Paolo Bonzini
  2 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-15  0:38 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: mdroth, armbru, lcapitulino

于 2014/6/14 5:27, Eric Blake 写道:
> On 06/05/2014 06:22 AM, Wenchao Xia wrote:
>> This patch also eliminates build time warning caused by no caller
>> of monitor_qapi_event_throttle().
>
> Again, my suggestion on 6/29 could avoid that warning; if you use that
> workaround, don't clean it until 29/29, but you can drop this paragraph
> of this commit.
>
>>
>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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(-)
>>
>
> Yay - the first event with data, so I get to see what the generator does.
>
> The .h file shows this signature:
>
>>> void qapi_event_send_rtc_change(int64_t offset,
>>>                                  Error **errp);
>
> and the .c has this code:
>
>>> void qapi_event_send_rtc_change(int64_t offset,
>>>                                  Error **errp)
>>> {
>>>      QDict *qmp;
>>>      Error *local_err = NULL;
>>>      QMPEventFuncEmit emit;
>>>      QmpOutputVisitor *qov;
>>>      Visitor *v;
>>>      QObject *obj;
>>>
>>>      emit = qmp_event_get_func_emit();
>>>      if (!emit) {
>>>          return;
>>>      }
>>>
>>>      qmp = qmp_event_build_dict("RTC_CHANGE");
>>>
>>>      qov = qmp_output_visitor_new();
>>>      g_assert(qov);
>>>
>>>      v = qmp_output_get_visitor(qov);
>>>      g_assert(v);
>>>
>>>      /* Fake visit, as if all member are under a structure */
>
> Grammar error; guess I have more comments on 3/29.
>
>>>      visit_start_struct(v, NULL, "", "RTC_CHANGE", 0, &local_err);
>>>      if (local_err) {
>>>          goto clean;
>>>      }
>
> Hmm, qmp_output_start_struct() never sets errp.
>
>>>
>>>      visit_type_int(v, &offset, "offset", &local_err);
>>>      if (local_err) {
>>>          goto clean;
>>>      }
>
> Likewise, qmp_output_type_int never sets errp.
>
>>>
>>>      visit_end_struct(v, &local_err);
>>>      if (local_err) {
>>>          goto clean;
>>>      }
>
> And neither does qmp_end_struct.
>
>>>
>>>      obj = qmp_output_get_qobject(qov);
>>>      g_assert(obj != NULL);
>>>
>>>      qdict_put_obj(qmp, "data", obj);
>>>      emit(QAPI_EVENT_RTC_CHANGE, qmp, &local_err);
>
> And I already mentioned earlier that the only implementation of the
> emit() callback never sets local_err (and probably doesn't even need it
> as a parameter).
>
>>>
>>>   clean:
>>>      qmp_output_visitor_cleanup(qov);
>>>      error_propagate(errp, local_err);
>>>      QDECREF(qmp);
>>> }
>
> If you change the earlier 3 instances to just use visit_...(,
> &error_abort), you can completely ditch the local_err variable, drop the
> clean: label, and overall have a much shorter generated function.
>
>
>> @@ -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), NULL);
>>       spapr->rtc_offset = qemu_timedate_diff(&tm);
>
> Eww. This makes me worry whether grabbing qemu_timedate_diff() two times
> in a row may cause a different value to be reported than what is stored
> locally.  Please grab it only once into a local variable, then copy that
> value into both locations.
>
> Once again, all callers of qapi_event_send_rtc_change() are passing a
> NULL errp to silently ignore errors; and I just audited that no errors
> happen anyways.
>

   Fixing it.

>> +++ b/monitor.c
>> @@ -612,6 +612,9 @@ static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>>
>>   static void monitor_qapi_event_init(void)
>>   {
>> +    /* Limit RTC & BALLOON events to 1 per second */
>
> Comment is a bit misleading until a later patch converts balloon events,...
>

   Oops, good catch, will fix it.

>> +    monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000);
>> +
>>       qmp_event_set_func_emit(monitor_qapi_event_queue);
>>   }
>>
>> @@ -737,7 +740,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);
>
> ...furthermore, the OLD comment was wrong (it forgot about the watchdog
> event).  You could get around that by rewording the comment to just say
> 'limit guest-triggerable events to 1 per second' without calling out
> what those events are.
>
>> +# @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: 2.1
>
> 0.14.0
>

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

* Re: [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG
  2014-06-13 22:05     ` Eric Blake
@ 2014-06-15  0:45       ` Wenchao Xia
  0 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-15  0:45 UTC (permalink / raw)
  To: Eric Blake, qemu-devel; +Cc: lcapitulino, mdroth, armbru

于 2014/6/14 6:05, Eric Blake 写道:
> On 06/13/2014 03:47 PM, Eric Blake wrote:
>> On 06/05/2014 06:22 AM, Wenchao Xia wrote:
>>> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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(-)
>>>
>
>>
>>> +  'data': { 'action': 'WatchdogExpirationAction' } }
>>
>> Hmm.  You've managed to create error.json in such a manner that it is
>> not self-sufficient.  If some other file includes error.json, it must
>> also define WatchdogExpirationAction or it will fail the generators.
>
> s/error.json/qapi-event.json/
>
>>
>>> +++ b/qapi-schema.json
>>
>>> +##
>>> +# @WatchdogExpirationAction
>>
>> I think you will be better off to ensure that error.json is
>
> and again qapi-event.json (not sure why I typed error.json).
>
>> self-sufficient, perhaps by sticking any data type it references
>> directly into common.json rather than qapi-schema.json, and having
>> error.json include common.json.  (This is the first instance of
>> referencing an external type, but other events later in the series have
>> the same issue).
>
> Oh weird! I've managed to run all four of
> scripts/qapi-{visit,types,commands,event}.py directly on
> qapi-event.json, and didn't get any complaints from the generator.  BUT,
> the generated code is definitely different:
>
> -void qapi_event_send_watchdog(WatchdogExpirationAction action,
> +void qapi_event_send_watchdog(WatchdogExpirationAction * action,
>                                 Error **errp)
>
> That is, when the enum type is known (because the parse was done on
> qapi-schema.json), the WatchdogExpirationAction argument is treated as
> an integer enum value; but when the enum type is unknown (because the
> parse was done directly on an incomplete qapi-event.json), the generator
> tries to treat it as a pointer to an otherwise unknown structure.
> (Never mind the odd formatting of the space after the '*' - I believe
> this pending patch fixes it:
> https://lists.gnu.org/archive/html/qemu-devel/2014-06/msg02385.html).
>
> This little exercise raises red flags for me - we probably ought to
> enhance the code generators to error out instead of blindly act as if
> unknown types are pointers.  But save it for another day - no need to
> stall this series just to wait for a robustness improvement to the
> generators.
>


> Meanwhile, my suggestion of making qapi-event.json to be self-sufficient
> is going to be a bit harder to test, but is still probably worth trying
> (just moving common types into a common shared include).
>

   I think it is a issue about how to orgnize the .json files. There are
some common type defines needed for different .json files, in my series
they are needed both in qapi-schema.json and qapi-event.json. So to
make qapi-event.json self-sufficient, qapi-schema.json will be
insufficient. I considered this before, and thought it is better
to reorgnize .json files as:

       qapi-types.json
       |             |
qapi-cmd.json    qapi-event.json

   It is an adjusting work for existing code, So I didn't do that in my
series.

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

* Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
  2014-06-10  5:48 ` [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Paolo Bonzini
@ 2014-06-15  0:52   ` Wenchao Xia
  2014-06-17 10:57     ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Wenchao Xia @ 2014-06-15  0:52 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: lcapitulino, mdroth, armbru

于 2014/6/10 13:48, Paolo Bonzini 写道:
> Il 05/06/2014 14:21, Wenchao Xia ha scritto:
>> This series add support for tag/keyword 'event' in qapi-schema.
>> A new file was created to store some helper functions in patch 2,
>> patch 4 is
>> the test case, patch 5 is a convert example.
>>
>> The implemention is done by generate API and a batch of parameters for
>> each
>> event define, it doesn't generate a struture and visit function in the
>> background for every event, so it doesn't support nested structure in the
>> define to avoid trouble. A callback layer is added to control the
>> behavior.
>> More detail can be found in patch 3's message and incode comments.
>>
>> v2:
>>   Address Luiz's comments:
>>   patch 3: rename *err to *local_err, do not initialize *qmp = NULL,
>> create
>> a new function qmp_build_evet_dict().
>>   Other change:
>>   reorgnized script in patch 3, it have a clear three steps, see patch
>> 3's
>> incode comments.
>>
>> v3:
>>   Address Luiz's comments:
>>   2/5: use -1 when fail to get host timestamp.
>>   3/5: typo fix and better incode comments. all unchanged functions
>> are moved
>> into qmp-event.c, from generated file. To do so without include issue,
>> 'int'
>> was used intead of 'enum' in function prototype declaration, since the
>> 'enum'
>> define is a generated type.
>>   Address Eric's comments:
>>   2/5: use -1 when fail to get host timestamp.
>>   3/5: typo fix, add docs/qapi-code-gen.txt.
>>   4/5: typo fix, verify no other fields in member 'timestamp'.
>>   5/5: add doc in qapi-schema.json.
>>   fix license, all script using GPL2, all C code use LGPL, just as other
>> similar files in upstream.
>>
>> v4:
>>   Address Eric's comments:
>>   2/5: typo fix, add copyright declaration, use a static function pointer
>> instead of a struct in C file, assign -1 in two line of codes to avoid
>> issue
>> when tv_sec and tv_usec are not in same data width, fix indention.
>>   3/5: typo fix, add copyright declaration.
>>   4/5: add copyright declaration, simplify string compare with
>>  "d->result = g_strcmp0(...) == 0;", add check for tv_usec's range and
>> value.
>>   Other:
>>   3/5: all error check code was moved from qapi-event.py to qapi.py,
>> and it
>> reports better message with line number info. Added related test case.
>>   Note:
>>   Benoit's series which track input file better seems not the final
>> version,
>> so I didn't rebase this series ontop for now, will do it once Benoit's
>> ones
>> get ACKed.
>>
>> v5:
>>   Address Eric and Markus's comments:
>>   2/28: use uint64_t for both sec and usec, to avoid type cast issue
>> in printf.
>>   Other:
>>   Remove RFC, add full coversion by patch 5-28.
>>   3/28: add prefix for event enum type name, to avoid double define of
>> QAPIEvent in test code.
>>
>> v6:
>>   Address Eric's comments:
>>   3/29: employ modularization mechnism of schema file of Lluís
>> series, remove
>> error_is_set() usage.
>>   4/29: Makefile change for Lluís series.
>>   5/29: separate patch for refactoring the existing schema defines,
>> improve doc
>> for @service in VncBasicInfo.
>>   7/29-28/29: define and convert event caller one by one.
>>   Other change:
>>   6/29: new way to add event emit implemention. In v5 it breaks old event
>> mechnism, in v6 it touch nothing of old event mechnism but add a new
>> set of
>> functions for new event mechnism.
>>   7/29: Add new file qapi-event.json to store event defines, and all type
>> defines goes into qapi-schema.json.
>>   29/29: related clean up change.
>>   Note:
>>   I have no way to verify target-s390x/kvm.c touched by patch 27/29, and
>> block/quorum.c touched by patch 28/29, need a confirm from whom has
>> the test
>> env.
>>
>> Wenchao Xia (29):
>>   1 os-posix: include sys/time.h
>>   2 qapi: add event helper functions
>>   3 qapi script: add event support
>>   4 test: add test cases for qapi event
>>   5 qapi: adjust existing defines
>>   6 monitor: add an implemention as qapi event emit method
>>   7 qapi: add new schema file qapi-event.json
>>   8 qapi event: convert SHUTDOWN
>>   9 qapi event: convert POWERDOWN
>>   10 qapi event: convert RESET
>>   11 qapi event: convert STOP
>>   12 qapi event: convert RESUME
>>   13 qapi event: convert SUSPEND
>>   14 qapi event: convert SUSPEND_DISK
>>   15 qapi event: convert WAKEUP
>>   16 qapi event: convert RTC_CHANGE
>>   17 qapi event: convert WATCHDOG
>>   18 qapi event: convert DEVICE_DELETED
>>   19 qapi event: convert DEVICE_TRAY_MOVED
>>   20 qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR
>>   21 qapi event: convert BLOCK_IMAGE_CORRUPTED
>>   22 qapi event: convert other BLOCK_JOB events
>>   23 qapi event: convert NIC_RX_FILTER_CHANGED
>>   24 qapi event: convert VNC events
>>   25 qapi event: convert SPICE events
>>   26 qapi event: convert BALLOON_CHANGE
>>   27 qapi event: convert GUEST_PANICKED
>>   28 qapi event: convert QUORUM events
>>   29 qapi event: clean up
>>
>>  Makefile                                 |   21 +-
>>  Makefile.objs                            |    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/os-posix.h                |    2 +
>>  include/sysemu/sysemu.h                  |    2 -
>>  monitor.c                                |  185 +++--------
>>  qapi-event.json                          |  452
>> +++++++++++++++++++++++++
>>  qapi-schema.json                         |  178 +++++++++--
>>  qapi/Makefile.objs                       |    1 +
>>  qapi/qmp-event.c                         |   74 ++++
>>  scripts/qapi-event.py                    |  369 ++++++++++++++++++++
>>  scripts/qapi.py                          |   12 +
>>  stubs/Makefile.objs                      |    1 -
>>  stubs/mon-protocol-event.c               |    6 -
>>  target-s390x/kvm.c                       |    8 +-
>>  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/qapi-schema-test.json  |   12 +
>>  tests/qapi-schema/qapi-schema-test.out   |   10 +-
>>  tests/test-qmp-event.c                   |  265 +++++++++++++++
>>  trace-events                             |    4 +
>>  ui/spice-core.c                          |   77 +++--
>>  ui/vnc.c                                 |  120 ++++----
>>  ui/vnc.h                                 |    4 +-
>>  util/qemu-sockets.c                      |   10 +-
>>  vl.c                                     |   22 +-
>>  58 files changed, 1732 insertions(+), 1087 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
>>
>>
>>
>
> Tested-by: Paolo Bonzini <pbonzini@redhat.com>
>
> Unfortunately, this already does not apply anymore.
>
> I've placed the rebase on branch qapi-event of my github repository. The
> resolutions are trivial, so perhaps Luiz or Michael can pull from there?
>
> Paolo


   Thanks for testing my work:)
   Eric:
   I have looked the comments, most fix will arrive in my V7 next week,
but still I have two issues without decision:
   1. Whether to use QAPIEvent in callback function type declartion,
See my feedback in 6/29.
   2. Whether to make qapi-event.json self sufficent, see my comments
in 17/29.

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

* Re: [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE
  2014-06-13 21:27   ` Eric Blake
  2014-06-15  0:38     ` Wenchao Xia
@ 2014-06-15 14:00     ` Paolo Bonzini
  2014-06-17  9:21     ` Paolo Bonzini
  2 siblings, 0 replies; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-15 14:00 UTC (permalink / raw)
  To: Eric Blake, Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

Il 13/06/2014 23:27, Eric Blake ha scritto:
>>> >>     visit_start_struct(v, NULL, "", "RTC_CHANGE", 0, &local_err);
>>> >>     if (local_err) {
>>> >>         goto clean;
>>> >>     }
> Hmm, qmp_output_start_struct() never sets errp.
>
>>> >>
>>> >>     visit_type_int(v, &offset, "offset", &local_err);
>>> >>     if (local_err) {
>>> >>         goto clean;
>>> >>     }
> Likewise, qmp_output_type_int never sets errp.
>

I think it is better to produce correct error propagation even if it is 
unused.  We could add range-checking of enums, for example.

I guess all the NULLs for errp could become &error_abort, but it can be 
done after the merge.

Paolo

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

* Re: [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE
  2014-06-15  0:38     ` Wenchao Xia
@ 2014-06-15 14:01       ` Paolo Bonzini
  0 siblings, 0 replies; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-15 14:01 UTC (permalink / raw)
  To: Wenchao Xia, Eric Blake, qemu-devel; +Cc: lcapitulino, mdroth, armbru

Il 15/06/2014 02:38, Wenchao Xia ha scritto:
>>
>> Once again, all callers of qapi_event_send_rtc_change() are passing a
>> NULL errp to silently ignore errors; and I just audited that no errors
>> happen anyways.
>>
>
>   Fixing it.

No, please don't.  I prefer the way you did it in v6.

Paolo

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

* Re: [Qemu-devel] [PATCH V6 27/29] qapi event: convert GUEST_PANICKED
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 27/29] qapi event: convert GUEST_PANICKED Wenchao Xia
@ 2014-06-16 14:08   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-16 14:08 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> '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>
> ---
>  docs/qmp/qmp-events.txt |   14 --------------
>  hw/misc/pvpanic.c       |   13 ++-----------
>  qapi-event.json         |   12 ++++++++++++
>  qapi-schema.json        |   12 ++++++++++++
>  target-s390x/kvm.c      |    8 +++-----
>  5 files changed, 29 insertions(+), 30 deletions(-)
> 

> @@ -50,7 +41,7 @@ static void handle_event(int event)
>      }
>  
>      if (event & PVPANIC_PANICKED) {
> -        panicked_mon_event("pause");
> +        qapi_event_send_guest_panicked(GUEST_PANICK_ACTION_PAUSE, NULL);

s/PANICK/PANIC/

>          vm_stop(RUN_STATE_GUEST_PANICKED);
>          return;
>      }
> diff --git a/qapi-event.json b/qapi-event.json
> index 93f9eeb..6bfc2a7 100644
> --- a/qapi-event.json
> +++ b/qapi-event.json
> @@ -400,3 +400,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: 2.1
> +##
> +{ 'event': 'GUEST_PANICKED',
> +  'data': { 'action': 'GuestPanickAction' } }

s/GuestPanickAction/GuestPanicAction/

> diff --git a/qapi-schema.json b/qapi-schema.json
> index 23be2bf..badc1bf 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -4837,4 +4837,16 @@
>  { 'enum': 'IoOperationType',
>    'data': [ 'read', 'write' ] }
>  
> +##
> +# @GuestPanickAction

And again. The English word is 'panic'; the only time you add a 'k' is
in situations where you are trying to avoid the hard ending 'c' looking
like a soft sound because it is followed by an 'e' or 'i'.


-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 29/29] qapi event: clean up
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 29/29] qapi event: clean up Wenchao Xia
@ 2014-06-16 14:09   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-16 14:09 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  include/monitor/monitor.h  |   40 --------
>  monitor.c                  |  216 +-------------------------------------------
>  stubs/Makefile.objs        |    1 -
>  stubs/mon-protocol-event.c |    6 --
>  4 files changed, 3 insertions(+), 260 deletions(-)
>  delete mode 100644 stubs/mon-protocol-event.c

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

Looking forward to v7.

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 21/29] qapi event: convert BLOCK_IMAGE_CORRUPTED
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 21/29] qapi event: convert BLOCK_IMAGE_CORRUPTED Wenchao Xia
@ 2014-06-16 22:53   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-16 22:53 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  block/qcow2-refcount.c  |   14 ++++++++------
>  docs/qmp/qmp-events.txt |   22 ----------------------
>  qapi-event.json         |   22 ++++++++++++++++++++++
>  3 files changed, 30 insertions(+), 28 deletions(-)
> 

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

The old docs didn't make it clear...

> +#
> +# @msg: informative message, for example, reason for the corruption

...but the new docs should mention that msg is for human consumption and
should not be parsed by machine as it is not guaranteed to be stable

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 22/29] qapi event: convert other BLOCK_JOB events
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 22/29] qapi event: convert other BLOCK_JOB events Wenchao Xia
@ 2014-06-16 22:57   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-16 22:57 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Since BLOCK_JOB_COMPLETED, BLOCK_JOB_CANCELLED, BLOCK_JOB_READY are
> related, converts them in one patch. The block_job_event_* functions

s/converts/convert/

> are used to keep encapsulation of BlockJob structure.
> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com>
> ---
>  block/mirror.c           |    2 +-
>  blockdev.c               |   12 +++----
>  blockjob.c               |   36 +++++++++++++----------
>  docs/qmp/qmp-events.txt  |   71 ----------------------------------------------
>  include/block/blockjob.h |   17 ++++++++--
>  qapi-event.json          |   71 ++++++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 110 insertions(+), 99 deletions(-)
> 

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

This sort of disclaimer is what I'm looking for in 21/29.

>  /**
> - * qobject_from_block_job:
> + * block_job_event_cancle:

s/cancle/cancelled/

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 24/29] qapi event: convert VNC events
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 24/29] qapi event: convert VNC events Wenchao Xia
@ 2014-06-16 23:01   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-16 23:01 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> Since VNC_CONNECTED, VNC_DISCONNECTED, VNC_INITIALIZED share some
> common functions, converts them in one patch.

s/converts/convert/

> 
> Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.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(-)
> 

> +##
> +{ 'event': 'VNC_INITIALIZED',
> +  'data': { 'server': 'VncServerInfo',
> +            'client': 'VncClientInfo' } }

Those types from the earlier commit make this nice :)

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 25/29] qapi event: convert SPICE events
  2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 25/29] qapi event: convert SPICE events Wenchao Xia
@ 2014-06-16 23:05   ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-16 23:05 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:22 AM, Wenchao Xia wrote:
> 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
> more caller exist now.

s/caller/callers/

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

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 11/29] qapi event: convert STOP
  2014-06-13 20:29   ` Eric Blake
@ 2014-06-17  9:17     ` Paolo Bonzini
  2014-06-17 13:18       ` Eric Blake
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-17  9:17 UTC (permalink / raw)
  To: Eric Blake, Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

Il 13/06/2014 22:29, Eric Blake ha scritto:
>> > +#
>> > +# Emitted when the virtual machine is stopped
>> > +#
>> > +# Since: 2.1
> 0.14.0

0.12.0, actually:

$ git describe --contains b1a15e7eaafba8f26e2263b1a9b6e6d40e585e72
v0.12.0-rc0~187

Paolo

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

* Re: [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE
  2014-06-13 21:27   ` Eric Blake
  2014-06-15  0:38     ` Wenchao Xia
  2014-06-15 14:00     ` Paolo Bonzini
@ 2014-06-17  9:21     ` Paolo Bonzini
  2014-06-17 13:19       ` Eric Blake
  2 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-17  9:21 UTC (permalink / raw)
  To: Eric Blake, Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

Il 13/06/2014 23:27, Eric Blake ha scritto:
>> > +# @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: 2.1
> 0.14.0

0.13.0 :)

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

* Re: [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG
  2014-06-13 21:47   ` Eric Blake
  2014-06-13 22:05     ` Eric Blake
@ 2014-06-17  9:23     ` Paolo Bonzini
  2014-06-17 13:21       ` Eric Blake
  1 sibling, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-17  9:23 UTC (permalink / raw)
  To: Eric Blake, Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

Il 13/06/2014 23:47, Eric Blake ha scritto:
>> +##
>> > +# @WatchdogExpirationAction
> I think you will be better off to ensure that error.json is
> self-sufficient, perhaps by sticking any data type it references
> directly into common.json rather than qapi-schema.json, and having
> error.json include common.json.  (This is the first instance of
> referencing an external type, but other events later in the series have
> the same issue).
>

Can be done later though, I think?

Paolo

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

* Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
  2014-06-15  0:52   ` Wenchao Xia
@ 2014-06-17 10:57     ` Paolo Bonzini
  2014-06-17 16:05       ` Eric Blake
  2014-06-18  4:00       ` Eric Blake
  0 siblings, 2 replies; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-17 10:57 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: armbru, mdroth, lcapitulino

Il 15/06/2014 02:52, Wenchao Xia ha scritto:
>> Unfortunately, this already does not apply anymore.
>>
>> I've placed the rebase on branch qapi-event of my github repository. The
>> resolutions are trivial, so perhaps Luiz or Michael can pull from there?
>>
>> Paolo
> 
> 
>   Thanks for testing my work:)
>   Eric:
>   I have looked the comments, most fix will arrive in my V7 next week,
> but still I have two issues without decision:
>   1. Whether to use QAPIEvent in callback function type declartion,
> See my feedback in 6/29.
>   2. Whether to make qapi-event.json self sufficent, see my comments
> in 17/29.

I am afraid that this will miss 2.1 (and so will dataplane 
rerror/werror that depends on it), so I went ahead and done all fixes in 
my qapi-event branch.

I have not yet applied Reviewed-by tags from Eric since some patches
are different and I want him to look at the interdiff first.

Regarding error handling, I have left the code in but switched all
callers to &error_abort.

The interdiff is here.  I ensured that the result is 
bisectable, and the intermediate changes are responsible
for the "spurious" hunks of the interdiff:

diff --git a/Makefile b/Makefile
index 3e65525..f473cf5 100644
--- a/Makefile
+++ b/Makefile
@@ -246,8 +246,7 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
 		$(gen-out-type) -o "." -b -i $<, \
 		"  GEN   $@")
 qapi-event.c qapi-event.h :\
-$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
-$(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
+$(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   $@")
diff --git a/block.c b/block.c
index 2885db4..041f17a 100644
--- a/block.c
+++ b/block.c
@@ -2140,12 +2140,12 @@ static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
         if (tray_was_closed) {
             /* tray open */
             qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
-                                              true, NULL);
+                                              true, &error_abort);
         }
         if (load) {
             /* tray close */
             qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
-                                              false, NULL);
+                                              false, &error_abort);
         }
     }
 }
@@ -3591,7 +3591,7 @@ void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
     qapi_event_send_block_io_error(bdrv_get_device_name(bs),
                                    is_read ? IO_OPERATION_TYPE_READ :
                                    IO_OPERATION_TYPE_WRITE,
-                                   action, NULL);
+                                   action, &error_abort);
     if (action == BLOCK_ERROR_ACTION_STOP) {
         vm_stop(RUN_STATE_IO_ERROR);
         bdrv_iostatus_set_err(bs, error);
@@ -5165,7 +5165,7 @@ void bdrv_eject(BlockDriverState *bs, bool eject_flag)
 
     if (bs->device_name[0] != '\0') {
         qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
-                                          eject_flag, NULL);
+                                          eject_flag, &error_abort);
     }
 }
 
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 2fca5a1..cc6cf74 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1822,7 +1822,7 @@ int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
                                               offset,
                                               true,
                                               size,
-                                              NULL);
+                                              &error_abort);
         g_free(message);
 
         qcow2_mark_corrupt(bs);
diff --git a/block/quorum.c b/block/quorum.c
index 7f0f1bd..86802d3 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -204,7 +204,7 @@ static void quorum_report_bad(QuorumAIOCB *acb, char *node_name, int ret)
         msg = strerror(-ret);
     }
     qapi_event_send_quorum_report_bad(!!msg, msg, node_name,
-                                      acb->sector_num, acb->nb_sectors, NULL);
+                                      acb->sector_num, acb->nb_sectors, &error_abort);
 }
 
 static void quorum_report_failure(QuorumAIOCB *acb)
@@ -214,7 +214,7 @@ static void quorum_report_failure(QuorumAIOCB *acb)
                             acb->common.bs->node_name;
 
     qapi_event_send_quorum_failure(reference, acb->sector_num,
-                                   acb->nb_sectors, NULL);
+                                   acb->nb_sectors, &error_abort);
 }
 
 static int quorum_vote_error(QuorumAIOCB *acb);
diff --git a/blockjob.c b/blockjob.c
index d21f51e..4da86cd 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -239,7 +239,7 @@ void block_job_event_cancelled(BlockJob *job)
                                         job->len,
                                         job->offset,
                                         job->speed,
-                                        NULL);
+                                        &error_abort);
 }
 
 void block_job_event_completed(BlockJob *job, const char *msg)
@@ -251,12 +251,12 @@ void block_job_event_completed(BlockJob *job, const char *msg)
                                         job->speed,
                                         !!msg,
                                         msg,
-                                        NULL);
+                                        &error_abort);
 }
 
 void block_job_event_ready(BlockJob *job)
 {
-    qapi_event_send_block_job_ready(bdrv_get_device_name(job->bs), NULL);
+    qapi_event_send_block_job_ready(bdrv_get_device_name(job->bs), &error_abort);
 }
 
 BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
@@ -285,7 +285,7 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
     qapi_event_send_block_job_error(bdrv_get_device_name(bs),
                                     is_read ? IO_OPERATION_TYPE_READ :
                                     IO_OPERATION_TYPE_WRITE,
-                                    action, NULL);
+                                    action, &error_abort);
     if (action == BLOCK_ERROR_ACTION_STOP) {
         block_job_pause(job);
         block_job_iostatus_set_err(job, error);
diff --git a/cpus.c b/cpus.c
index 28abb11..87ac99f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -531,7 +531,7 @@ static int do_vm_stop(RunState state)
         pause_all_vcpus();
         runstate_set(state);
         vm_state_notify(0, state);
-        qapi_event_send_stop(NULL);
+        qapi_event_send_stop(&error_abort);
     }
 
     bdrv_drain_all();
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index ace6438..a7368fb 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -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 */
-                qapi_event_send_suspend_disk(NULL);
+                qapi_event_send_suspend_disk(&error_abort);
                 qemu_system_shutdown_request();
             }
             break;
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index a6c62b2..cbe8bdd 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -958,7 +958,7 @@ static void device_unparent(Object *obj)
     if (have_realized) {
         gchar *path = object_get_canonical_path(OBJECT(dev));
 
-        qapi_event_send_device_deleted(!!dev->id, dev->id, path, NULL);
+        qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
         g_free(path);
     }
 }
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index d396b74..994f8af 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -41,7 +41,7 @@ static void handle_event(int event)
     }
 
     if (event & PVPANIC_PANICKED) {
-        qapi_event_send_guest_panicked(GUEST_PANICK_ACTION_PAUSE, NULL);
+        qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
         vm_stop(RUN_STATE_GUEST_PANICKED);
         return;
     }
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index f6d3447..a423a7b 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -201,7 +201,7 @@ static void rxfilter_notify(NetClientState *nc)
     if (nc->rxfilter_notify_enabled) {
         gchar *path = object_get_canonical_path(OBJECT(n->qdev));
         qapi_event_send_nic_rx_filter_changed(!!n->netclient_name,
-                                              n->netclient_name, path, NULL);
+                                              n->netclient_name, path, &error_abort);
         g_free(path);
 
         /* disable event notification to avoid events flooding */
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 7e4cffe..8d08539 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -94,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 */
-    qapi_event_send_rtc_change(qemu_timedate_diff(&tm), NULL);
+    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 bb91853..05002bf 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -531,7 +531,7 @@ static void rtc_set_time(RTCState *s)
     s->base_rtc = mktimegm(&tm);
     s->last_update = qemu_clock_get_ns(rtc_clock);
 
-    qapi_event_send_rtc_change(qemu_timedate_diff(&tm), NULL);
+    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/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index c65c6eb..2a2e58a 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -292,7 +292,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
     if (dev->actual != oldactual) {
         qapi_event_send_balloon_change(ram_size -
                         ((ram_addr_t) dev->actual << VIRTIO_BALLOON_PFN_SHIFT),
-                        NULL);
+                        &error_abort);
     }
 }
 
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index 9284d3f..4aebd34 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -108,31 +108,31 @@ void watchdog_perform_action(void)
 {
     switch(watchdog_action) {
     case WDT_RESET:             /* same as 'system_reset' in monitor */
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_RESET, NULL);
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_RESET, &error_abort);
         qemu_system_reset_request();
         break;
 
     case WDT_SHUTDOWN:          /* same as 'system_powerdown' in monitor */
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_SHUTDOWN, NULL);
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_SHUTDOWN, &error_abort);
         qemu_system_powerdown_request();
         break;
 
     case WDT_POWEROFF:          /* same as 'quit' command in monitor */
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_POWEROFF, NULL);
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_POWEROFF, &error_abort);
         exit(0);
 
     case WDT_PAUSE:             /* same as 'stop' command in monitor */
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_PAUSE, NULL);
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_PAUSE, &error_abort);
         vm_stop(RUN_STATE_WATCHDOG);
         break;
 
     case WDT_DEBUG:
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_DEBUG, NULL);
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_DEBUG, &error_abort);
         fprintf(stderr, "watchdog: timer fired\n");
         break;
 
     case WDT_NONE:
-        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_NONE, NULL);
+        qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_NONE, &error_abort);
         break;
     }
 }
diff --git a/include/qapi/qmp-event.h b/include/qapi/qmp-event.h
index 02b6ce5..8a8ffb5 100644
--- a/include/qapi/qmp-event.h
+++ b/include/qapi/qmp-event.h
@@ -17,7 +17,7 @@
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 
-typedef void (*QMPEventFuncEmit)(int event_kind, QDict *dict, Error **errp);
+typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp);
 
 void qmp_event_set_func_emit(QMPEventFuncEmit emit);
 
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index f131521..25d0b2a 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -26,8 +26,6 @@
 #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);
diff --git a/monitor.c b/monitor.c
index 6b693ee..66a1db7 100644
--- a/monitor.c
+++ b/monitor.c
@@ -183,10 +183,10 @@ typedef struct MonitorControl {
  */
 typedef struct MonitorQAPIEventState {
     QAPIEvent 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 */
+    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 */
+    QObject *data;      /* Event pending delayed dispatch */
 } MonitorQAPIEventState;
 
 struct Monitor {
@@ -451,7 +451,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, QObject *data)
 {
     Monitor *mon;
 
-    trace_monitor_qapi_event_emit(event, data);
+    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);
@@ -464,19 +464,18 @@ static void monitor_qapi_event_emit(QAPIEvent event, QObject *data)
  * applying any rate limiting if required.
  */
 static void
-monitor_qapi_event_queue(int event_kind, QDict *data, Error **errp)
+monitor_qapi_event_queue(QAPIEvent event, QDict *data, Error **errp)
 {
     MonitorQAPIEventState *evstate;
-    assert(event_kind < QAPI_EVENT_MAX);
-    QAPIEvent event = (QAPIEvent)event_kind;
+    assert(event < QAPI_EVENT_MAX);
     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
 
     evstate = &(monitor_qapi_event_state[event]);
-    trace_monitor_qapi_event_queue(event,
-                                   data,
-                                   evstate->rate,
-                                   evstate->last,
-                                   now);
+    trace_monitor_protocol_event_queue(event,
+                                       data,
+                                       evstate->rate,
+                                       evstate->last,
+                                       now);
 
     /* Rate limit of 0 indicates no throttling */
     if (!evstate->rate) {
@@ -514,11 +513,10 @@ static void monitor_qapi_event_handler(void *opaque)
     MonitorQAPIEventState *evstate = opaque;
     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
 
-
-    trace_monitor_qapi_event_handler(evstate->event,
-                                     evstate->data,
-                                     evstate->last,
-                                     now);
+    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);
@@ -535,14 +533,15 @@ static void monitor_qapi_event_handler(void *opaque)
  * more than 1 event will be emitted within @rate
  * milliseconds
  */
-static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
+static void
+monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
 {
     MonitorQAPIEventState *evstate;
     assert(event < QAPI_EVENT_MAX);
 
     evstate = &(monitor_qapi_event_state[event]);
 
-    trace_monitor_qapi_event_throttle(event, rate);
+    trace_monitor_protocol_event_throttle(event, rate);
     evstate->event = event;
     evstate->rate = rate * SCALE_MS;
     evstate->last = 0;
@@ -555,7 +554,7 @@ static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
 
 static void monitor_qapi_event_init(void)
 {
-    /* Limit RTC & BALLOON events to 1 per second */
+    /* 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);
@@ -566,7 +565,6 @@ static void monitor_qapi_event_init(void)
     qmp_event_set_func_emit(monitor_qapi_event_queue);
 }
 
-
 static int do_qmp_capabilities(Monitor *mon, const QDict *params,
                                QObject **ret_data)
 {
diff --git a/qapi-event.json b/qapi-event.json
index 805a5a3..fbdda48 100644
--- a/qapi-event.json
+++ b/qapi-event.json
@@ -1,13 +1,13 @@
 ##
 # @SHUTDOWN
 #
-# Emitted when the virtual machine shutdown, qemu terminated the emulation and
-# is about to exit.
+# 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: 2.1
+# Since: 0.12.0
 ##
 { 'event': 'SHUTDOWN' }
 
@@ -17,7 +17,7 @@
 # Emitted when the virtual machine is powered down through the power control
 # system, such as via ACPI.
 #
-# Since: 2.1
+# Since: 0.12.0
 ##
 { 'event': 'POWERDOWN' }
 
@@ -26,7 +26,7 @@
 #
 # Emitted when the virtual machine is reset
 #
-# Since: 2.1
+# Since: 0.12.0
 ##
 { 'event': 'RESET' }
 
@@ -35,7 +35,7 @@
 #
 # Emitted when the virtual machine is stopped
 #
-# Since: 2.1
+# Since: 0.12.0
 ##
 { 'event': 'STOP' }
 
@@ -44,7 +44,7 @@
 #
 # Emitted when the virtual machine resumes execution
 #
-# Since: 2.1
+# Since: 0.12.0
 ##
 { 'event': 'RESUME' }
 
@@ -54,7 +54,7 @@
 # Emitted when guest enters a hardware suspension state, for example, S3 state,
 # which is sometimes called standby state
 #
-# Since: 2.1
+# Since: 1.1
 ##
 { 'event': 'SUSPEND' }
 
@@ -66,7 +66,7 @@
 #
 # Note: QEMU shuts down (similar to event @SHUTDOWN) when entering this state
 #
-# Since: 2.1
+# Since: 1.2
 ##
 { 'event': 'SUSPEND_DISK' }
 
@@ -75,7 +75,7 @@
 #
 # Emitted when the guest has woken up from suspend state and is running
 #
-# Since: 2.1
+# Since: 1.1
 ##
 { 'event': 'WAKEUP' }
 
@@ -87,7 +87,7 @@
 # @offset: offset between base RTC clock (as specified by -rtc base), and
 #          new RTC clock value
 #
-# Since: 2.1
+# Since: 0.13.0
 ##
 { 'event': 'RTC_CHANGE',
   'data': { 'offset': 'int' } }
@@ -102,7 +102,7 @@
 # Note: If action is "reset", "shutdown", or "pause" the WATCHDOG event is
 # followed respectively by the RESET, SHUTDOWN, or STOP events
 #
-# Since: 2.1
+# Since: 0.13.0
 ##
 { 'event': 'WATCHDOG',
   'data': { 'action': 'WatchdogExpirationAction' } }
@@ -118,7 +118,7 @@
 #
 # @path: device path
 #
-# Since: 2.1
+# Since: 1.5
 ##
 { 'event': 'DEVICE_DELETED',
   'data': { '*device': 'str', 'path': 'str' } }
@@ -133,7 +133,7 @@
 #
 # @path: device path
 #
-# Since: 2.1
+# Since: 1.6
 ##
 { 'event': 'NIC_RX_FILTER_CHANGED',
   'data': { '*name': 'str', 'path': 'str' } }
@@ -150,7 +150,7 @@
 # Note: This event is emitted before any authentication takes place, thus
 # the authentication ID is not provided
 #
-# Since: 2.1
+# Since: 0.13.0
 ##
 { 'event': 'VNC_CONNECTED',
   'data': { 'server': 'VncServerInfo',
@@ -166,7 +166,7 @@
 #
 # @client: client information
 #
-# Since: 2.1
+# Since: 0.13.0
 ##
 { 'event': 'VNC_INITIALIZED',
   'data': { 'server': 'VncServerInfo',
@@ -181,7 +181,7 @@
 #
 # @client: client information
 #
-# Since: 2.1
+# Since: 0.13.0
 ##
 { 'event': 'VNC_DISCONNECTED',
   'data': { 'server': 'VncServerInfo',
@@ -196,7 +196,7 @@
 #
 # @client: client information
 #
-# Since: 2.1
+# Since: 0.14.0
 ##
 { 'event': 'SPICE_CONNECTED',
   'data': { 'server': 'SpiceBasicInfo',
@@ -212,7 +212,7 @@
 #
 # @client: client information
 #
-# Since: 2.1
+# Since: 0.14.0
 ##
 { 'event': 'SPICE_INITIALIZED',
   'data': { 'server': 'SpiceServerInfo',
@@ -227,7 +227,7 @@
 #
 # @client: client information
 #
-# Since: 2.1
+# Since: 0.14.0
 ##
 { 'event': 'SPICE_DISCONNECTED',
   'data': { 'server': 'SpiceBasicInfo',
@@ -238,7 +238,7 @@
 #
 # Emitted when SPICE migration has completed
 #
-# Since: 2.1
+# Since: 1.3
 ##
 { 'event': 'SPICE_MIGRATE_COMPLETED' }
 
@@ -250,7 +250,7 @@
 #
 # @actual: actual level of the guest memory balloon in bytes
 #
-# Since: 2.1
+# Since: 1.2
 ##
 { 'event': 'BALLOON_CHANGE',
   'data': { 'actual': 'int' } }
@@ -262,10 +262,10 @@
 #
 # @action: action that has been taken, currently always "pause"
 #
-# Since: 2.1
+# Since: 1.5
 ##
 { 'event': 'GUEST_PANICKED',
-  'data': { 'action': 'GuestPanickAction' } }
+  'data': { 'action': 'GuestPanicAction' } }
 
 ##
 # @QUORUM_FAILURE
@@ -278,7 +278,7 @@
 #
 # @sector-count: failed read operation sector count
 #
-# Since: 2.1
+# Since: 2.0
 ##
 { 'event': 'QUORUM_FAILURE',
   'data': { 'reference': 'str', 'sector-num': 'int', 'sector-count': 'int' } }
@@ -299,7 +299,7 @@
 #
 # @sector-count: failed read operation sector count
 #
-# Since: 2.1
+# Since: 2.0
 ##
 { 'event': 'QUORUM_REPORT_BAD',
   'data': { '*error': 'str', 'node-name': 'str',
diff --git a/qapi-schema.json b/qapi-schema.json
index 96426c3..d62bb7d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3180,7 +3180,7 @@
   'data': [ 'read', 'write' ] }
 
 ##
-# @GuestPanickAction
+# @GuestPanicAction
 #
 # An enumeration of the actions taken when guest OS panic is detected
 #
@@ -3188,7 +3188,7 @@
 #
 # Since: 2.1
 ##
-{ 'enum': 'GuestPanickAction',
+{ 'enum': 'GuestPanicAction',
   'data': [ 'pause' ] }
 
 { 'include': 'qapi-event.json' }
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 2b258e5..af6b436 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1435,14 +1435,16 @@
 #
 # @device: device name
 #
-# @msg: informative message, for example, reason for the corruption
+# @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: 2.1
+# Since: 1.7
 ##
 { 'event': 'BLOCK_IMAGE_CORRUPTED',
   'data': { 'device' : 'str',
@@ -1464,7 +1466,7 @@
 # Note: If action is "stop", a STOP event will eventually follow the
 # BLOCK_IO_ERROR event
 #
-# Since: 2.1
+# Since: 0.13.0
 ##
 { 'event': 'BLOCK_IO_ERROR',
   'data': { 'device': 'str', 'operation': 'IoOperationType',
@@ -1491,7 +1493,7 @@
 #         other than that streaming has failed and clients should not try to
 #         interpret the error string
 #
-# Since: 2.1
+# Since: 1.1
 ##
 { 'event': 'BLOCK_JOB_COMPLETED',
   'data': { 'type'  : 'BlockJobType',
@@ -1517,7 +1519,7 @@
 #
 # @speed: rate limit, bytes per second
 #
-# Since: 2.1
+# Since: 1.1
 ##
 { 'event': 'BLOCK_JOB_CANCELLED',
   'data': { 'type'  : 'BlockJobType',
@@ -1537,7 +1539,7 @@
 #
 # @action: action that has been taken
 #
-# Since: 2.1
+# Since: 1.3
 ##
 { 'event': 'BLOCK_JOB_ERROR',
   'data': { 'device'   : 'str',
@@ -1554,7 +1556,7 @@
 # Note: The "ready to complete" status is always reset by a @BLOCK_JOB_ERROR
 # event
 #
-# Since: 2.1
+# Since: 1.3
 ##
 { 'event': 'BLOCK_JOB_READY',
   'data': { 'device': 'str' } }
diff --git a/qapi/block.json b/qapi/block.json
index 1bdcba5..e313465 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -174,7 +174,7 @@
 #
 # @tray-open: true if the tray has been opened or false if it has been closed
 #
-# Since: 2.1
+# Since: 1.1
 ##
 { 'event': 'DEVICE_TRAY_MOVED',
   'data': { 'device': 'str', 'tray-open': 'bool' } }
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index e1dcc43..3a1cd61 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -45,7 +45,7 @@ def generate_event_declaration(api_name):
                  api_name = api_name)
 
 def generate_event_implement(api_name, event_name, params):
-    # step 1: declare and variables
+    # step 1: declare any variables
     ret = mcgen("""
 
 %(api_name)s
@@ -85,7 +85,7 @@ def generate_event_implement(api_name, event_name, params):
     v = qmp_output_get_visitor(qov);
     g_assert(v);
 
-    /* Fake visit, as if all member are under a structure */
+    /* 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;
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index e57350f..a6e587b 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -1030,8 +1030,8 @@ static bool is_special_wait_psw(CPUState *cs)
 
 static void guest_panicked(void)
 {
-    qapi_event_send_guest_panicked(GUEST_PANICK_ACTION_PAUSE,
-                                   NULL);
+    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
+                                   &error_abort);
     vm_stop(RUN_STATE_GUEST_PANICKED);
 }
 
diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
index c967d35..cb1e441 100644
--- a/tests/test-qmp-event.c
+++ b/tests/test-qmp-event.c
@@ -33,7 +33,7 @@ typedef struct QDictCmpData {
 } QDictCmpData;
 
 TestEventData *test_event_data;
-static GStaticMutex test_event_lock = G_STATIC_MUTEX_INIT;
+static CompatGMutex test_event_lock;
 
 /* Only compares bool, int, string */
 static
@@ -94,13 +94,13 @@ static bool qdict_cmp_simple(QDict *a, QDict *b)
 
 /* This function is hooked as final emit function, which can verify the
    correctness. */
-static void event_test_emit(int event_kind, QDict *d, Error **errp)
+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 field */
+    /* 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);
@@ -129,7 +129,7 @@ static void event_prepare(TestEventData *data,
 {
     /* Global variable test_event_data was used to pass the expectation, so
        test cases can't be executed at same time. */
-    g_static_mutex_lock(&test_event_lock);
+    g_mutex_lock(&test_event_lock);
 
     data->expect = qdict_new();
     test_event_data = data;
@@ -141,7 +141,7 @@ static void event_teardown(TestEventData *data,
     QDECREF(data->expect);
     test_event_data = NULL;
 
-    g_static_mutex_unlock(&test_event_lock);
+    g_mutex_unlock(&test_event_lock);
 }
 
 static void event_test_add(const char *testpath,
@@ -161,7 +161,7 @@ static void test_event_a(TestEventData *data,
     QDict *d;
     d = data->expect;
     qdict_put(d, "event", qstring_from_str("EVENT_A"));
-    qapi_event_send_event_a(NULL);
+    qapi_event_send_event_a(&error_abort);
 }
 
 static void test_event_b(TestEventData *data,
@@ -170,7 +170,7 @@ static void test_event_b(TestEventData *data,
     QDict *d;
     d = data->expect;
     qdict_put(d, "event", qstring_from_str("EVENT_B"));
-    qapi_event_send_event_b(NULL);
+    qapi_event_send_event_b(&error_abort);
 }
 
 static void test_event_c(TestEventData *data,
@@ -198,7 +198,7 @@ static void test_event_c(TestEventData *data,
     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", NULL);
+    qapi_event_send_event_c(true, 1, true, &b, "test2", &error_abort);
 
     g_free(b.string);
 }
@@ -243,7 +243,7 @@ static void test_event_d(TestEventData *data,
     qdict_put(d, "data", d_data);
 
     qapi_event_send_event_d(&a, "test3", false, NULL, true, ENUM_ONE_VALUE3,
-                           NULL);
+                           &error_abort);
 
     g_free(struct1.string);
     g_free(a.string);
diff --git a/trace-events b/trace-events
index 06fe330..f8dff48 100644
--- a/trace-events
+++ b/trace-events
@@ -932,10 +932,6 @@ monitor_protocol_event_handler(uint32_t event, void *data, uint64_t last, uint64
 monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
 monitor_protocol_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
 monitor_protocol_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
-monitor_qapi_event_emit(uint32_t event, void *data) "event=%d data=%p"
-monitor_qapi_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64
-monitor_qapi_event_handler(uint32_t event, void *data, uint64_t last, uint64_t now) "event=%d data=%p last=%" PRId64 " now=%" PRId64
-monitor_qapi_event_throttle(uint32_t event, uint64_t rate) "event=%d rate=%" PRId64
 
 # hw/net/opencores_eth.c
 open_eth_mii_write(unsigned idx, uint16_t v) "MII[%02x] <- %04x"
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 4605f80..70df446 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -229,7 +229,7 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
 
     switch (event) {
     case SPICE_CHANNEL_EVENT_CONNECTED:
-        qapi_event_send_spice_connected(server->base, client->base, NULL);
+        qapi_event_send_spice_connected(server->base, client->base, &error_abort);
         break;
     case SPICE_CHANNEL_EVENT_INITIALIZED:
         if (auth) {
@@ -238,11 +238,11 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
         }
         add_channel_info(client, info);
         channel_list_add(info);
-        qapi_event_send_spice_initialized(server, client, NULL);
+        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, NULL);
+        qapi_event_send_spice_disconnected(server->base, client->base, &error_abort);
         break;
     default:
         break;
@@ -307,7 +307,7 @@ static void migrate_connect_complete_cb(SpiceMigrateInstance *sin)
 
 static void migrate_end_complete_cb(SpiceMigrateInstance *sin)
 {
-    qapi_event_send_spice_migrate_completed(NULL);
+    qapi_event_send_spice_migrate_completed(&error_abort);
     spice_migration_completed = true;
 }
 
diff --git a/ui/vnc.c b/ui/vnc.c
index 67447c6..9ccd5e3 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -289,13 +289,13 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
 
     switch (event) {
     case QAPI_EVENT_VNC_CONNECTED:
-        qapi_event_send_vnc_connected(si, vs->info->base, NULL);
+        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, NULL);
+        qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
         break;
     case QAPI_EVENT_VNC_DISCONNECTED:
-        qapi_event_send_vnc_disconnected(si, vs->info, NULL);
+        qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
         break;
     default:
         break;
diff --git a/vl.c b/vl.c
index 6ede799..198c77a 100644
--- a/vl.c
+++ b/vl.c
@@ -1746,7 +1746,7 @@ void vm_start(void)
         runstate_set(RUN_STATE_RUNNING);
         vm_state_notify(1, RUN_STATE_RUNNING);
         resume_all_vcpus();
-        qapi_event_send_resume(NULL);
+        qapi_event_send_resume(&error_abort);
     }
 }
 
@@ -1898,7 +1898,7 @@ void qemu_system_reset(bool report)
         qemu_devices_reset();
     }
     if (report) {
-        qapi_event_send_reset(NULL);
+        qapi_event_send_reset(&error_abort);
     }
     cpu_synchronize_all_post_reset();
 }
@@ -1919,7 +1919,7 @@ static void qemu_system_suspend(void)
     pause_all_vcpus();
     notifier_list_notify(&suspend_notifiers, NULL);
     runstate_set(RUN_STATE_SUSPENDED);
-    qapi_event_send_suspend(NULL);
+    qapi_event_send_suspend(&error_abort);
 }
 
 void qemu_system_suspend_request(void)
@@ -1982,7 +1982,7 @@ void qemu_system_shutdown_request(void)
 
 static void qemu_system_powerdown(void)
 {
-    qapi_event_send_powerdown(NULL);
+    qapi_event_send_powerdown(&error_abort);
     notifier_list_notify(&powerdown_notifiers, NULL);
 }
 
@@ -2020,7 +2020,7 @@ static bool main_loop_should_exit(void)
     }
     if (qemu_shutdown_requested()) {
         qemu_kill_report();
-        qapi_event_send_shutdown(NULL);
+        qapi_event_send_shutdown(&error_abort);
         if (no_shutdown) {
             vm_stop(RUN_STATE_SHUTDOWN);
         } else {
@@ -2043,7 +2043,7 @@ static bool main_loop_should_exit(void)
         notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
         wakeup_reason = QEMU_WAKEUP_REASON_NONE;
         resume_all_vcpus();
-        qapi_event_send_wakeup(NULL);
+        qapi_event_send_wakeup(&error_abort);
     }
     if (qemu_powerdown_requested()) {
         qemu_system_powerdown();

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

* Re: [Qemu-devel] [PATCH V6 11/29] qapi event: convert STOP
  2014-06-17  9:17     ` Paolo Bonzini
@ 2014-06-17 13:18       ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-17 13:18 UTC (permalink / raw)
  To: Paolo Bonzini, Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

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

On 06/17/2014 03:17 AM, Paolo Bonzini wrote:
> Il 13/06/2014 22:29, Eric Blake ha scritto:
>>> > +#
>>> > +# Emitted when the virtual machine is stopped
>>> > +#
>>> > +# Since: 2.1
>> 0.14.0
> 
> 0.12.0, actually:
> 
> $ git describe --contains b1a15e7eaafba8f26e2263b1a9b6e6d40e585e72
> v0.12.0-rc0~187

But nothing else in qapi-schema.json mentions anything earlier than
0.14.  True, QMP was first started in the 0.12 timeframe, but upstream
libvirt refuses to use QMP for anything earlier than qemu 0.15, unless
libvirt was able to probe that enough additional functionality of QMP
was backported to make it useful (thus it supports RHEL 6's qemu 0.12+).

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE
  2014-06-17  9:21     ` Paolo Bonzini
@ 2014-06-17 13:19       ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-17 13:19 UTC (permalink / raw)
  To: Paolo Bonzini, Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

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

On 06/17/2014 03:21 AM, Paolo Bonzini wrote:
> Il 13/06/2014 23:27, Eric Blake ha scritto:
>>> > +# @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: 2.1
>> 0.14.0
> 
> 0.13.0 :)

Again, since nothing else in QAPI documents anything earlier than 0.14,
I'm not sure it's worth caring about whether 0.13 supported a particular
event.

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG
  2014-06-17  9:23     ` Paolo Bonzini
@ 2014-06-17 13:21       ` Eric Blake
  0 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-17 13:21 UTC (permalink / raw)
  To: Paolo Bonzini, Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

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

On 06/17/2014 03:23 AM, Paolo Bonzini wrote:
> Il 13/06/2014 23:47, Eric Blake ha scritto:
>>> +##
>>> > +# @WatchdogExpirationAction
>> I think you will be better off to ensure that error.json is
>> self-sufficient, perhaps by sticking any data type it references
>> directly into common.json rather than qapi-schema.json, and having
>> error.json include common.json.  (This is the first instance of
>> referencing an external type, but other events later in the series have
>> the same issue).
>>
> 
> Can be done later though, I think?

Yes; as I mentioned in my other mail:
https://lists.gnu.org/archive/html/qemu-devel/2014-06/msg03208.html


This little exercise raises red flags for me - we probably ought to
enhance the code generators to error out instead of blindly act as if
unknown types are pointers.  But save it for another day - no need to
stall this series just to wait for a robustness improvement to the
generators.


-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
  2014-06-17 10:57     ` Paolo Bonzini
@ 2014-06-17 16:05       ` Eric Blake
  2014-06-17 16:30         ` Paolo Bonzini
  2014-06-18  4:00       ` Eric Blake
  1 sibling, 1 reply; 77+ messages in thread
From: Eric Blake @ 2014-06-17 16:05 UTC (permalink / raw)
  To: Paolo Bonzini, Wenchao Xia, qemu-devel; +Cc: lcapitulino, armbru, mdroth

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

On 06/17/2014 04:57 AM, Paolo Bonzini wrote:
> Il 15/06/2014 02:52, Wenchao Xia ha scritto:
>>> Unfortunately, this already does not apply anymore.
>>>
>>> I've placed the rebase on branch qapi-event of my github repository. The
>>> resolutions are trivial, so perhaps Luiz or Michael can pull from there?
>>>
>>> Paolo
>>
>>
>>   Thanks for testing my work:)
>>   Eric:
>>   I have looked the comments, most fix will arrive in my V7 next week,
>> but still I have two issues without decision:
>>   1. Whether to use QAPIEvent in callback function type declartion,
>> See my feedback in 6/29.
>>   2. Whether to make qapi-event.json self sufficent, see my comments
>> in 17/29.
> 
> I am afraid that this will miss 2.1 (and so will dataplane 
> rerror/werror that depends on it), so I went ahead and done all fixes in 
> my qapi-event branch.
> 
> I have not yet applied Reviewed-by tags from Eric since some patches
> are different and I want him to look at the interdiff first.

Here's my first glance through your interdiff; I will also respond once
I've looked at the commits leading to
8910d4c0f568d1eb46934ef16e9a275d97749973 (your current qapi-event branch
head at git://github.com/bonzini/qemu.git).

> 
> Regarding error handling, I have left the code in but switched all
> callers to &error_abort.

Works for me to use &error_abort.

> 
> The interdiff is here.  I ensured that the result is 
> bisectable, and the intermediate changes are responsible
> for the "spurious" hunks of the interdiff:
> 
> diff --git a/Makefile b/Makefile
> index 3e65525..f473cf5 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -246,8 +246,7 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
>  		$(gen-out-type) -o "." -b -i $<, \
>  		"  GEN   $@")
>  qapi-event.c qapi-event.h :\
> -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
> -$(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)

Where's the change that adds qapi/event.json to $(qapi-modules)?  (Maybe
the interdiff doesn't show it?)


> +++ b/include/sysemu/os-posix.h
> @@ -26,8 +26,6 @@
>  #ifndef QEMU_OS_POSIX_H
>  #define QEMU_OS_POSIX_H
>  
> -#include <sys/time.h>
> -
>  void os_set_line_buffering(void);

Why this hunk? Did you accidentally forget to include Wenchao's 1/29 in
your series?

>  void os_set_proc_name(const char *s);
>  void os_setup_signal_handling(void);
> diff --git a/monitor.c b/monitor.c
> index 6b693ee..66a1db7 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -183,10 +183,10 @@ typedef struct MonitorControl {
>   */
>  typedef struct MonitorQAPIEventState {
>      QAPIEvent 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 */
> +    int64_t rate;       /* Minimum time (in ns) between two events */
> +    int64_t last;       /* QEMU_CLOCK_REALTIME value at last emission */

I still like the "0 to disable" comment; but I see that you dropped it
to keep line length manageable.  So I guess I can live with this change.

> @@ -535,14 +533,15 @@ static void monitor_qapi_event_handler(void *opaque)
>   * more than 1 event will be emitted within @rate
>   * milliseconds
>   */
> -static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
> +static void
> +monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>  {

Not the usual qemu formatting style.

Overall the interdiff looks like it resolves most of my concerns on v6.
 Now for me to read the actual commits in your git repo...

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
  2014-06-17 16:05       ` Eric Blake
@ 2014-06-17 16:30         ` Paolo Bonzini
  2014-06-17 22:10           ` Wenchao Xia
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-17 16:30 UTC (permalink / raw)
  To: Eric Blake, Wenchao Xia, qemu-devel; +Cc: lcapitulino, armbru, mdroth

Il 17/06/2014 18:05, Eric Blake ha scritto:
>> diff --git a/Makefile b/Makefile
>> index 3e65525..f473cf5 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -246,8 +246,7 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
>>  		$(gen-out-type) -o "." -b -i $<, \
>>  		"  GEN   $@")
>>  qapi-event.c qapi-event.h :\
>> -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
>> -$(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
>> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
>
> Where's the change that adds qapi/event.json to $(qapi-modules)?  (Maybe
> the interdiff doesn't show it?)

Oops, it's not there.

>> +++ b/include/sysemu/os-posix.h
>> @@ -26,8 +26,6 @@
>>  #ifndef QEMU_OS_POSIX_H
>>  #define QEMU_OS_POSIX_H
>>
>> -#include <sys/time.h>
>> -
>>  void os_set_line_buffering(void);
>
> Why this hunk? Did you accidentally forget to include Wenchao's 1/29 in
> your series?

Yes, fixing now.

>> @@ -535,14 +533,15 @@ static void monitor_qapi_event_handler(void *opaque)
>>   * more than 1 event will be emitted within @rate
>>   * milliseconds
>>   */
>> -static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>> +static void
>> +monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>>  {
>
> Not the usual qemu formatting style.

Yeah, this happened because of __attribute__((__unused__)) and matches 
other monitor_qapi_ functions.  I kind of like the 
return-type-then-newline too. :)

> Overall the interdiff looks like it resolves most of my concerns on v6.
>  Now for me to read the actual commits in your git repo...

Will fix in a moment.

Paolo

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

* Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
  2014-06-17 16:30         ` Paolo Bonzini
@ 2014-06-17 22:10           ` Wenchao Xia
  0 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-17 22:10 UTC (permalink / raw)
  To: Paolo Bonzini, Eric Blake, qemu-devel; +Cc: lcapitulino, armbru, mdroth

于 2014/6/18 0:30, Paolo Bonzini 写道:
> Il 17/06/2014 18:05, Eric Blake ha scritto:
>>> diff --git a/Makefile b/Makefile
>>> index 3e65525..f473cf5 100644
>>> --- a/Makefile
>>> +++ b/Makefile
>>> @@ -246,8 +246,7 @@ $(SRC_PATH)/qga/qapi-schema.json
>>> $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
>>>          $(gen-out-type) -o "." -b -i $<, \
>>>          "  GEN   $@")
>>>  qapi-event.c qapi-event.h :\
>>> -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi-event.json \
>>> -$(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
>>> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
>>
>> Where's the change that adds qapi/event.json to $(qapi-modules)?  (Maybe
>> the interdiff doesn't show it?)
>
> Oops, it's not there.
>
>>> +++ b/include/sysemu/os-posix.h
>>> @@ -26,8 +26,6 @@
>>>  #ifndef QEMU_OS_POSIX_H
>>>  #define QEMU_OS_POSIX_H
>>>
>>> -#include <sys/time.h>
>>> -
>>>  void os_set_line_buffering(void);
>>
>> Why this hunk? Did you accidentally forget to include Wenchao's 1/29 in
>> your series?
>
> Yes, fixing now.
>
>>> @@ -535,14 +533,15 @@ static void monitor_qapi_event_handler(void
>>> *opaque)
>>>   * more than 1 event will be emitted within @rate
>>>   * milliseconds
>>>   */
>>> -static void monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>>> +static void
>>> +monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
>>>  {
>>
>> Not the usual qemu formatting style.
>
> Yeah, this happened because of __attribute__((__unused__)) and matches
> other monitor_qapi_ functions.  I kind of like the
> return-type-then-newline too. :)
>
>> Overall the interdiff looks like it resolves most of my concerns on v6.
>>  Now for me to read the actual commits in your git repo...
>
> Will fix in a moment.
>
> Paolo
   If you and Eric think v6 is OK to catch up 2.1, I can send a clean up
patch fixing the typo/doc issues after merge.

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

* Re: [Qemu-devel] [PATCH V6 03/29] qapi script: add event support
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 03/29] qapi script: add event support Wenchao Xia
  2014-06-13 16:47   ` Eric Blake
  2014-06-13 21:28   ` Eric Blake
@ 2014-06-18  3:33   ` Eric Blake
  2014-06-18  6:06     ` Paolo Bonzini
  2014-06-18  3:50   ` Eric Blake
  3 siblings, 1 reply; 77+ messages in thread
From: Eric Blake @ 2014-06-18  3:33 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:21 AM, Wenchao Xia wrote:
> qapi-event.py will parse the schema and generate qapi-event.c, then
> the API in qapi-event.c can be used to handle event 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.
> 

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

Any reason this can't be GPLv2+ instead of GPLv2-only?

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 03/29] qapi script: add event support
  2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 03/29] qapi script: add event support Wenchao Xia
                     ` (2 preceding siblings ...)
  2014-06-18  3:33   ` Eric Blake
@ 2014-06-18  3:50   ` Eric Blake
  3 siblings, 0 replies; 77+ messages in thread
From: Eric Blake @ 2014-06-18  3:50 UTC (permalink / raw)
  To: Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

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

On 06/05/2014 06:21 AM, Wenchao Xia wrote:
> qapi-event.py will parse the schema and generate qapi-event.c, then
> the API in qapi-event.c can be used to handle event 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.
> 

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

This may need to be rebased or have a followup patch based on Amos' work:
https://lists.gnu.org/archive/html/qemu-devel/2014-06/msg02387.html

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
  2014-06-17 10:57     ` Paolo Bonzini
  2014-06-17 16:05       ` Eric Blake
@ 2014-06-18  4:00       ` Eric Blake
  2014-06-18  6:07         ` Paolo Bonzini
  1 sibling, 1 reply; 77+ messages in thread
From: Eric Blake @ 2014-06-18  4:00 UTC (permalink / raw)
  To: Paolo Bonzini, Wenchao Xia, qemu-devel; +Cc: lcapitulino, armbru, mdroth

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

On 06/17/2014 04:57 AM, Paolo Bonzini wrote:
> Il 15/06/2014 02:52, Wenchao Xia ha scritto:
>>> Unfortunately, this already does not apply anymore.
>>>
>>> I've placed the rebase on branch qapi-event of my github repository. The
>>> resolutions are trivial, so perhaps Luiz or Michael can pull from there?
>>>
>>> Paolo
>>

I'm still reviewing your git tree; I raised a couple comments on 3/29
(see my replies there).  Also:

> +++ b/include/qapi/qmp-event.h
> @@ -17,7 +17,7 @@
>  #include "qapi/error.h"
>  #include "qapi/qmp/qdict.h"
>  
> -typedef void (*QMPEventFuncEmit)(int event_kind, QDict *dict, Error **errp);
> +typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp);

It looks like you have some churn on this definition; patch 4/29 in your
qapi-event branch did:

-enum QAPIEvent;
-typedef void (*QMPEventFuncEmit)(enum QAPIEvent event, QDict *dict,
Error **errp);
+typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error
**errp);

Can you hoist the use of 'unsigned' directly into 2/29 to minimize the
churn?

-- 
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] 77+ messages in thread

* Re: [Qemu-devel] [PATCH V6 03/29] qapi script: add event support
  2014-06-18  3:33   ` Eric Blake
@ 2014-06-18  6:06     ` Paolo Bonzini
  2014-06-18 22:45       ` Wenchao Xia
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:06 UTC (permalink / raw)
  To: Eric Blake, Wenchao Xia, qemu-devel; +Cc: lcapitulino, mdroth, armbru

Il 18/06/2014 05:33, Eric Blake ha scritto:
>> > +# This work is licensed under the terms of the GNU GPL, version 2.
>> > +# See the COPYING file in the top-level directory.
> Any reason this can't be GPLv2+ instead of GPLv2-only?

I suppose because it copies parts of other qapi-* scripts. :(

Paolo

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

* Re: [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema
  2014-06-18  4:00       ` Eric Blake
@ 2014-06-18  6:07         ` Paolo Bonzini
  0 siblings, 0 replies; 77+ messages in thread
From: Paolo Bonzini @ 2014-06-18  6:07 UTC (permalink / raw)
  To: Eric Blake, Wenchao Xia, qemu-devel; +Cc: mdroth, armbru, lcapitulino

Il 18/06/2014 06:00, Eric Blake ha scritto:
>> > -typedef void (*QMPEventFuncEmit)(int event_kind, QDict *dict, Error **errp);
>> > +typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error **errp);
> It looks like you have some churn on this definition; patch 4/29 in your
> qapi-event branch did:
>
> -enum QAPIEvent;
> -typedef void (*QMPEventFuncEmit)(enum QAPIEvent event, QDict *dict,
> Error **errp);
> +typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict, Error
> **errp);
>
> Can you hoist the use of 'unsigned' directly into 2/29 to minimize the
> churn?

Yes, will fix in a couple of hours.

Paolo

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

* Re: [Qemu-devel] [PATCH V6 03/29] qapi script: add event support
  2014-06-18  6:06     ` Paolo Bonzini
@ 2014-06-18 22:45       ` Wenchao Xia
  0 siblings, 0 replies; 77+ messages in thread
From: Wenchao Xia @ 2014-06-18 22:45 UTC (permalink / raw)
  To: Paolo Bonzini, Eric Blake, qemu-devel; +Cc: lcapitulino, mdroth, armbru

于 2014/6/18 14:06, Paolo Bonzini 写道:
> Il 18/06/2014 05:33, Eric Blake ha scritto:
>>> > +# This work is licensed under the terms of the GNU GPL, version 2.
>>> > +# See the COPYING file in the top-level directory.
>> Any reason this can't be GPLv2+ instead of GPLv2-only?
>
> I suppose because it copies parts of other qapi-* scripts. :(
>
> Paolo

   Yes, feel free to change the license.

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

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

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-05 12:21 [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Wenchao Xia
2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 01/29] os-posix: include sys/time.h Wenchao Xia
2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 02/29] qapi: add event helper functions Wenchao Xia
2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 03/29] qapi script: add event support Wenchao Xia
2014-06-13 16:47   ` Eric Blake
2014-06-13 21:28   ` Eric Blake
2014-06-18  3:33   ` Eric Blake
2014-06-18  6:06     ` Paolo Bonzini
2014-06-18 22:45       ` Wenchao Xia
2014-06-18  3:50   ` Eric Blake
2014-06-05 12:21 ` [Qemu-devel] [PATCH V6 04/29] test: add test cases for qapi event Wenchao Xia
2014-06-13 17:05   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 05/29] qapi: adjust existing defines Wenchao Xia
2014-06-13 17:32   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 06/29] monitor: add an implemention as qapi event emit method Wenchao Xia
2014-06-13 19:04   ` Eric Blake
2014-06-15  0:27     ` Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 07/29] qapi: add new schema file qapi-event.json Wenchao Xia
2014-06-13 19:25   ` Eric Blake
2014-06-13 19:45     ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 08/29] qapi event: convert SHUTDOWN Wenchao Xia
2014-06-13 19:57   ` Eric Blake
2014-06-15  0:32     ` Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 09/29] qapi event: convert POWERDOWN Wenchao Xia
2014-06-13 20:02   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 10/29] qapi event: convert RESET Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 11/29] qapi event: convert STOP Wenchao Xia
2014-06-13 20:29   ` Eric Blake
2014-06-17  9:17     ` Paolo Bonzini
2014-06-17 13:18       ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 12/29] qapi event: convert RESUME Wenchao Xia
2014-06-13 20:33   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 13/29] qapi event: convert SUSPEND Wenchao Xia
2014-06-13 20:40   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 14/29] qapi event: convert SUSPEND_DISK Wenchao Xia
2014-06-13 20:42   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 15/29] qapi event: convert WAKEUP Wenchao Xia
2014-06-13 20:57   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 16/29] qapi event: convert RTC_CHANGE Wenchao Xia
2014-06-13 21:27   ` Eric Blake
2014-06-15  0:38     ` Wenchao Xia
2014-06-15 14:01       ` Paolo Bonzini
2014-06-15 14:00     ` Paolo Bonzini
2014-06-17  9:21     ` Paolo Bonzini
2014-06-17 13:19       ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 17/29] qapi event: convert WATCHDOG Wenchao Xia
2014-06-13 21:47   ` Eric Blake
2014-06-13 22:05     ` Eric Blake
2014-06-15  0:45       ` Wenchao Xia
2014-06-17  9:23     ` Paolo Bonzini
2014-06-17 13:21       ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 18/29] qapi event: convert DEVICE_DELETED Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 19/29] qapi event: convert DEVICE_TRAY_MOVED Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 20/29] qapi event: convert BLOCK_IO_ERROR and BLOCK_JOB_ERROR Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 21/29] qapi event: convert BLOCK_IMAGE_CORRUPTED Wenchao Xia
2014-06-16 22:53   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 22/29] qapi event: convert other BLOCK_JOB events Wenchao Xia
2014-06-16 22:57   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 23/29] qapi event: convert NIC_RX_FILTER_CHANGED Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 24/29] qapi event: convert VNC events Wenchao Xia
2014-06-16 23:01   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 25/29] qapi event: convert SPICE events Wenchao Xia
2014-06-16 23:05   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 26/29] qapi event: convert BALLOON_CHANGE Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 27/29] qapi event: convert GUEST_PANICKED Wenchao Xia
2014-06-16 14:08   ` Eric Blake
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 28/29] qapi event: convert QUORUM events Wenchao Xia
2014-06-05 12:22 ` [Qemu-devel] [PATCH V6 29/29] qapi event: clean up Wenchao Xia
2014-06-16 14:09   ` Eric Blake
2014-06-10  5:48 ` [Qemu-devel] [PATCH V6 00/29] add direct support of event in qapi schema Paolo Bonzini
2014-06-15  0:52   ` Wenchao Xia
2014-06-17 10:57     ` Paolo Bonzini
2014-06-17 16:05       ` Eric Blake
2014-06-17 16:30         ` Paolo Bonzini
2014-06-17 22:10           ` Wenchao Xia
2014-06-18  4:00       ` Eric Blake
2014-06-18  6:07         ` Paolo Bonzini

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.