Patchwork Re: [PATCH][RESPIN] QMP: Emit asynchronous events on all QMP monitors

login
register
mail settings
Submitter Adam Litke
Date Jan. 15, 2010, 3:16 p.m.
Message ID <1263568563.3536.29.camel@aglitke>
Download mbox | patch
Permalink /patch/42970/
State New
Headers show

Comments

Adam Litke - Jan. 15, 2010, 3:16 p.m.
On Fri, 2010-01-15 at 13:00 -0200, Luiz Capitulino wrote:
>  The function will return on the first !QMP Monitor, the
> right QLIST_FOREACH() body is:
> 
> if (monitor_ctrl_mode(mon)) {
>  monitor_json_emitter(mon, QOBJECT(qmp));
> }
> 
>  I'll ACK the respin.

Ah right, of course.  Thanks and here it is.

When using a control/QMP monitor in tandem with a regular monitor, asynchronous
messages can get lost depending on the order of the QEMU program arguments.
QEMU events issued by monitor_protocol_event() always go to cur_mon.  If the
user monitor was specified on the command line first (or it has ,default), the
message will be directed to the user monitor (not the QMP monitor).
Additionally, only one QMP session is currently able to receive async messages.

To avoid this confusion, scan through the list of monitors and emit the message
on each QMP monitor.

Signed-off-by: Adam Litke <agl@us.ibm.com>
Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
Luiz Capitulino - Jan. 15, 2010, 3:23 p.m.
On Fri, 15 Jan 2010 09:16:03 -0600
Adam Litke <agl@us.ibm.com> wrote:

> On Fri, 2010-01-15 at 13:00 -0200, Luiz Capitulino wrote:
> >  The function will return on the first !QMP Monitor, the
> > right QLIST_FOREACH() body is:
> > 
> > if (monitor_ctrl_mode(mon)) {
> >  monitor_json_emitter(mon, QOBJECT(qmp));
> > }
> > 
> >  I'll ACK the respin.
> 
> Ah right, of course.  Thanks and here it is.
> 
> When using a control/QMP monitor in tandem with a regular monitor, asynchronous
> messages can get lost depending on the order of the QEMU program arguments.
> QEMU events issued by monitor_protocol_event() always go to cur_mon.  If the
> user monitor was specified on the command line first (or it has ,default), the
> message will be directed to the user monitor (not the QMP monitor).
> Additionally, only one QMP session is currently able to receive async messages.
> 
> To avoid this confusion, scan through the list of monitors and emit the message
> on each QMP monitor.
> 
> Signed-off-by: Adam Litke <agl@us.ibm.com>
> Acked-by: Luiz Capitulino <lcapitulino@redhat.com>

 Now it's good, hope Anthony's script can get a patch from a thread,
this is probably good for stable too.

 Btw, we have a lot of QMP tasks in case you're interested :-)

> 
> diff --git a/monitor.c b/monitor.c
> index 134ed15..6a2c7fb 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -334,13 +334,10 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
>  {
>      QDict *qmp;
>      const char *event_name;
> -    Monitor *mon = cur_mon;
> +    Monitor *mon;
>  
>      assert(event < QEVENT_MAX);
>  
> -    if (!monitor_ctrl_mode(mon))
> -        return;
> -
>      switch (event) {
>          case QEVENT_DEBUG:
>              event_name = "DEBUG";
> @@ -373,7 +370,11 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
>          qdict_put_obj(qmp, "data", data);
>      }
>  
> -    monitor_json_emitter(mon, QOBJECT(qmp));
> +    QLIST_FOREACH(mon, &mon_list, entry) {
> +        if (monitor_ctrl_mode(mon)) {
> +            monitor_json_emitter(mon, QOBJECT(qmp));
> +        }
> +    }
>      QDECREF(qmp);
>  }
>  
> 
>

Patch

diff --git a/monitor.c b/monitor.c
index 134ed15..6a2c7fb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -334,13 +334,10 @@  void monitor_protocol_event(MonitorEvent event, QObject *data)
 {
     QDict *qmp;
     const char *event_name;
-    Monitor *mon = cur_mon;
+    Monitor *mon;
 
     assert(event < QEVENT_MAX);
 
-    if (!monitor_ctrl_mode(mon))
-        return;
-
     switch (event) {
         case QEVENT_DEBUG:
             event_name = "DEBUG";
@@ -373,7 +370,11 @@  void monitor_protocol_event(MonitorEvent event, QObject *data)
         qdict_put_obj(qmp, "data", data);
     }
 
-    monitor_json_emitter(mon, QOBJECT(qmp));
+    QLIST_FOREACH(mon, &mon_list, entry) {
+        if (monitor_ctrl_mode(mon)) {
+            monitor_json_emitter(mon, QOBJECT(qmp));
+        }
+    }
     QDECREF(qmp);
 }