Message ID | 1264108180-3666-9-git-send-email-lcapitulino@redhat.com |
---|---|
State | New |
Headers | show |
On 01/21/2010 03:09 PM, Luiz Capitulino wrote: > This commit disables asynchronous messages by default and > introduces two new QMP commands: async_msg_enable and > async_msg_disable. > > Each QMP Monitor has its own set of asynchronous messages, > so for example, if QEMU is run with two QMP Monitors async > messages setup in one of them doesn't affect the other. > > To implement this design a bitmap is introduced to the > Monitor struct, each async message is represented by one bit. > > Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com> > Ah, I see I was a little confused. I'd suggest making async message masking an independent mechanism. Capabilities should strictly deal with protocol changes, not feature details. For instance, protocol timestamps are something would reasonable considered a capability. Extended data types would be a capability. Another way to look at it, is that if you're writing a client library, the capability negotiation should be entirely invisible to the end API user. Regards, Anthony Liguori
On Fri, 22 Jan 2010 12:05:19 -0600 Anthony Liguori <anthony@codemonkey.ws> wrote: > On 01/21/2010 03:09 PM, Luiz Capitulino wrote: > > This commit disables asynchronous messages by default and > > introduces two new QMP commands: async_msg_enable and > > async_msg_disable. > > > > Each QMP Monitor has its own set of asynchronous messages, > > so for example, if QEMU is run with two QMP Monitors async > > messages setup in one of them doesn't affect the other. > > > > To implement this design a bitmap is introduced to the > > Monitor struct, each async message is represented by one bit. > > > > Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com> > > > > Ah, I see I was a little confused. > > I'd suggest making async message masking an independent mechanism. > Capabilities should strictly deal with protocol changes, not feature > details. To summarize (after a IRC talk): async messages are considered a capability and should be enabled during the negotiation phase but the masking of particular messages are not and can be done at any time after the negotiation phase. I'm ok with that, Markus?
On 01/22/2010 02:09 PM, Luiz Capitulino wrote: > On Fri, 22 Jan 2010 12:05:19 -0600 > Anthony Liguori<anthony@codemonkey.ws> wrote: > > >> On 01/21/2010 03:09 PM, Luiz Capitulino wrote: >> >>> This commit disables asynchronous messages by default and >>> introduces two new QMP commands: async_msg_enable and >>> async_msg_disable. >>> >>> Each QMP Monitor has its own set of asynchronous messages, >>> so for example, if QEMU is run with two QMP Monitors async >>> messages setup in one of them doesn't affect the other. >>> >>> To implement this design a bitmap is introduced to the >>> Monitor struct, each async message is represented by one bit. >>> >>> Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com> >>> >>> >> Ah, I see I was a little confused. >> >> I'd suggest making async message masking an independent mechanism. >> Capabilities should strictly deal with protocol changes, not feature >> details. >> > To summarize (after a IRC talk): async messages are considered a > capability and should be enabled during the negotiation phase but > the masking of particular messages are not and can be done at > any time after the negotiation phase. > Just to further clarify, the mental model I have of capabilities is that they are things that affect the protocol itself. Additional features (new command options, new commands, new async messages) are things that are enabled/discovered in a different way. Async messages themselves are a capability since it changes the protocol. Timestamps would be another capability and a new data type (like an uint64 type) would be a new capability. > I'm ok with that, Markus? > Regards, Anthony Liguori
On 01/22/2010 08:05 PM, Anthony Liguori wrote: > On 01/21/2010 03:09 PM, Luiz Capitulino wrote: >> This commit disables asynchronous messages by default and >> introduces two new QMP commands: async_msg_enable and >> async_msg_disable. >> >> Each QMP Monitor has its own set of asynchronous messages, >> so for example, if QEMU is run with two QMP Monitors async >> messages setup in one of them doesn't affect the other. >> >> To implement this design a bitmap is introduced to the >> Monitor struct, each async message is represented by one bit. >> >> Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com> > > Ah, I see I was a little confused. > > I'd suggest making async message masking an independent mechanism. > Capabilities should strictly deal with protocol changes, not feature > details. > > For instance, protocol timestamps are something would reasonable > considered a capability. Extended data types would be a capability. > > Another way to look at it, is that if you're writing a client library, > the capability negotiation should be entirely invisible to the end API > user. > I agree with that, but we can look at async messages as a baseline protocol capability (thus no negotiation required), and the new command only enabled individual messages.
On 01/21/2010 11:09 PM, Luiz Capitulino wrote: > This commit disables asynchronous messages by default and > introduces two new QMP commands: async_msg_enable and > async_msg_disable. > > Each QMP Monitor has its own set of asynchronous messages, > so for example, if QEMU is run with two QMP Monitors async > messages setup in one of them doesn't affect the other. > > To implement this design a bitmap is introduced to the > Monitor struct, each async message is represented by one bit. > > A bitmap is an overkill here, an array of booleans should suffice. > > +#define EVENTS_BITMAP_SIZE (QEVENT_MAX / 8) > Doesn't that underflow if QEVENT_MAX is not a multiple of 8?
Avi Kivity wrote: > On 01/22/2010 08:05 PM, Anthony Liguori wrote: > >On 01/21/2010 03:09 PM, Luiz Capitulino wrote: > >>This commit disables asynchronous messages by default and > >>introduces two new QMP commands: async_msg_enable and > >>async_msg_disable. > >> > >>Each QMP Monitor has its own set of asynchronous messages, > >>so for example, if QEMU is run with two QMP Monitors async > >>messages setup in one of them doesn't affect the other. > >> > >>To implement this design a bitmap is introduced to the > >>Monitor struct, each async message is represented by one bit. > >> > >>Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com> > > > >Ah, I see I was a little confused. > > > >I'd suggest making async message masking an independent mechanism. > >Capabilities should strictly deal with protocol changes, not feature > >details. > > > >For instance, protocol timestamps are something would reasonable > >considered a capability. Extended data types would be a capability. > > > >Another way to look at it, is that if you're writing a client library, > >the capability negotiation should be entirely invisible to the end API > >user. > > I agree with that, but we can look at async messages as a baseline > protocol capability (thus no negotiation required), and the new command > only enabled individual messages. I'd like to be able to connect and be sure not to receive any async messages, from simple scripts with simple output parsing. If async messages can only be received as a result of commands which trigger individual messages, that will be achieved. But it would be a nice little bonus if disabling async messages caused all slow commands to be synchronous - that is, the async result message becomes the command's synchronous result. -- Jamie
On 01/24/2010 04:34 AM, Avi Kivity wrote: > On 01/22/2010 08:05 PM, Anthony Liguori wrote: >> On 01/21/2010 03:09 PM, Luiz Capitulino wrote: >>> This commit disables asynchronous messages by default and >>> introduces two new QMP commands: async_msg_enable and >>> async_msg_disable. >>> >>> Each QMP Monitor has its own set of asynchronous messages, >>> so for example, if QEMU is run with two QMP Monitors async >>> messages setup in one of them doesn't affect the other. >>> >>> To implement this design a bitmap is introduced to the >>> Monitor struct, each async message is represented by one bit. >>> >>> Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com> >> >> Ah, I see I was a little confused. >> >> I'd suggest making async message masking an independent mechanism. >> Capabilities should strictly deal with protocol changes, not feature >> details. >> >> For instance, protocol timestamps are something would reasonable >> considered a capability. Extended data types would be a capability. >> >> Another way to look at it, is that if you're writing a client >> library, the capability negotiation should be entirely invisible to >> the end API user. >> > > I agree with that, but we can look at async messages as a baseline > protocol capability (thus no negotiation required), and the new > command only enabled individual messages. To be honest, I don't think there's really a need to mask individual messages. A client can always ignore messages it doesn't care about. There is no side effect of receiving a message so there is no functional implication of receiving messages you don't care about. The only time it would matter is if we had a really high volume of messages. I'd suggest waiting until a message is introduced that could potentially have a high rate and then implement a mechanism to mask it. For now, it just adds unnecessary complexity. Regards, Anthony Liguori
On 01/24/2010 04:04 PM, Anthony Liguori wrote: >> I agree with that, but we can look at async messages as a baseline >> protocol capability (thus no negotiation required), and the new >> command only enabled individual messages. > > > To be honest, I don't think there's really a need to mask individual > messages. A client can always ignore messages it doesn't care about. > There is no side effect of receiving a message so there is no > functional implication of receiving messages you don't care about. > > The only time it would matter is if we had a really high volume of > messages. I'd suggest waiting until a message is introduced that > could potentially have a high rate and then implement a mechanism to > mask it. For now, it just adds unnecessary complexity. Fair enough. But then, why can't all clients do that? Dropping an async notification is maybe one line of code.
On 01/24/2010 08:17 AM, Avi Kivity wrote: > On 01/24/2010 04:04 PM, Anthony Liguori wrote: >>> I agree with that, but we can look at async messages as a baseline >>> protocol capability (thus no negotiation required), and the new >>> command only enabled individual messages. >> >> >> To be honest, I don't think there's really a need to mask individual >> messages. A client can always ignore messages it doesn't care >> about. There is no side effect of receiving a message so there is no >> functional implication of receiving messages you don't care about. >> >> The only time it would matter is if we had a really high volume of >> messages. I'd suggest waiting until a message is introduced that >> could potentially have a high rate and then implement a mechanism to >> mask it. For now, it just adds unnecessary complexity. > > Fair enough. But then, why can't all clients do that? Dropping an > async notification is maybe one line of code. I agree. The only argument I can imagine for masking is if we had a really, really high volume event that caused bandwidth issues. I don't think that's an appropriate use of async messages though so I don't think this will ever happen. Regards, Anthony Liguori
On 01/24/2010 05:07 AM, Jamie Lokier wrote: > Avi Kivity wrote: > >> On 01/22/2010 08:05 PM, Anthony Liguori wrote: >> >>> On 01/21/2010 03:09 PM, Luiz Capitulino wrote: >>> >>>> This commit disables asynchronous messages by default and >>>> introduces two new QMP commands: async_msg_enable and >>>> async_msg_disable. >>>> >>>> Each QMP Monitor has its own set of asynchronous messages, >>>> so for example, if QEMU is run with two QMP Monitors async >>>> messages setup in one of them doesn't affect the other. >>>> >>>> To implement this design a bitmap is introduced to the >>>> Monitor struct, each async message is represented by one bit. >>>> >>>> Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com> >>>> >>> Ah, I see I was a little confused. >>> >>> I'd suggest making async message masking an independent mechanism. >>> Capabilities should strictly deal with protocol changes, not feature >>> details. >>> >>> For instance, protocol timestamps are something would reasonable >>> considered a capability. Extended data types would be a capability. >>> >>> Another way to look at it, is that if you're writing a client library, >>> the capability negotiation should be entirely invisible to the end API >>> user. >>> >> I agree with that, but we can look at async messages as a baseline >> protocol capability (thus no negotiation required), and the new command >> only enabled individual messages. >> > I'd like to be able to connect and be sure not to receive any async > messages, from simple scripts with simple output parsing. > You can't have simple output parsing with QMP. You need a full JSON stack. The simplest script would be a python script that uses the builtin json support. Having async messages means that you'll have to loop on recv in order make sure that the response is a command response vs. an async message. It's just a few lines more of code so I have a hard time believing it's really a problem. But what you probably want is a python QMP library and that would mean you wouldn't need the few more lines of code. > If async messages can only be received as a result of commands which > trigger individual messages, that will be achieved. > > But it would be a nice little bonus if disabling async messages caused > all slow commands to be synchronous - that is, the async result > message becomes the command's synchronous result. > I know what you're getting at but I think it's the wrong target for QMP. The goal is not to allow simple, hacky clients, but to provide a robust management API. It should not be difficult to use, but parsing it in a shell with awk is not a requirement in my mind :-) Regards, Anthony Liguori
Anthony Liguori wrote: > >I'd like to be able to connect and be sure not to receive any async > >messages, from simple scripts with simple output parsing. > > You can't have simple output parsing with QMP. You need a full JSON > stack. The simplest script would be a python script that uses the > builtin json support. Having async messages means that you'll have to > loop on recv in order make sure that the response is a command response > vs. an async message. It's just a few lines more of code so I have a > hard time believing it's really a problem. > > But what you probably want is a python QMP library and that would mean > you wouldn't need the few more lines of code. You're right. To be honest, parsing JSON can be done in a single Perl regexp; a "full JSON stack" isn't much. On that note, it'd be good if the end of a QMP message is framed with something that can't appear inside the JSON value, without having to parse the JSON incrementally on each partial read(). There are plenty of short character sequences to choose from that can't appear. Some JSON parsers expect a whole well-formed expression or throw a parse error - it's what people do over HTTP after all. So you wait until you think you've read a whole one, then pass it to the JSON parser. > >If async messages can only be received as a result of commands which > >trigger individual messages, that will be achieved. > > > >But it would be a nice little bonus if disabling async messages caused > >all slow commands to be synchronous - that is, the async result > >message becomes the command's synchronous result. > > I know what you're getting at but I think it's the wrong target for > QMP. The goal is not to allow simple, hacky clients, but to provide a > robust management API. It should not be difficult to use, but parsing > it in a shell with awk is not a requirement in my mind :-) I agree - not a requirement. Just seemed nice if that turned out to be a natural thing to do anyway. -- Jamie
On Sun, 24 Jan 2010 18:35:14 +0000 Jamie Lokier <jamie@shareable.org> wrote: > Anthony Liguori wrote: > > >I'd like to be able to connect and be sure not to receive any async > > >messages, from simple scripts with simple output parsing. > > > > You can't have simple output parsing with QMP. You need a full JSON > > stack. The simplest script would be a python script that uses the > > builtin json support. Having async messages means that you'll have to > > loop on recv in order make sure that the response is a command response > > vs. an async message. It's just a few lines more of code so I have a > > hard time believing it's really a problem. > > > > But what you probably want is a python QMP library and that would mean > > you wouldn't need the few more lines of code. > > You're right. To be honest, parsing JSON can be done in a single Perl > regexp; a "full JSON stack" isn't much. > > On that note, it'd be good if the end of a QMP message is framed with > something that can't appear inside the JSON value, without having to > parse the JSON incrementally on each partial read(). There are plenty > of short character sequences to choose from that can't appear. Some > JSON parsers expect a whole well-formed expression or throw a parse > error - it's what people do over HTTP after all. So you wait until > you think you've read a whole one, then pass it to the JSON parser. The Monitor sends a CRLF sequence at the end of each line and I have maintained that behaivor for QMP, but it's hard to _guarantee_ that this sequence won't appear inside a json-string. In practice it doesn't, afaik.
On Sun, 24 Jan 2010 08:19:53 -0600 Anthony Liguori <anthony@codemonkey.ws> wrote: > On 01/24/2010 08:17 AM, Avi Kivity wrote: > > On 01/24/2010 04:04 PM, Anthony Liguori wrote: > >>> I agree with that, but we can look at async messages as a baseline > >>> protocol capability (thus no negotiation required), and the new > >>> command only enabled individual messages. > >> > >> > >> To be honest, I don't think there's really a need to mask individual > >> messages. A client can always ignore messages it doesn't care > >> about. There is no side effect of receiving a message so there is no > >> functional implication of receiving messages you don't care about. > >> > >> The only time it would matter is if we had a really high volume of > >> messages. I'd suggest waiting until a message is introduced that > >> could potentially have a high rate and then implement a mechanism to > >> mask it. For now, it just adds unnecessary complexity. > > > > Fair enough. But then, why can't all clients do that? Dropping an > > async notification is maybe one line of code. > > I agree. The only argument I can imagine for masking is if we had a > really, really high volume event that caused bandwidth issues. I don't > think that's an appropriate use of async messages though so I don't > think this will ever happen. The only real client writer we have thought it would be a good idea to disable them by default. If we don't this now and add a masking command later, then clients that don't want certain messages will have to deal with them between the window of qmp_swicth_mode and masking. I don't have strong opinions here though.
On Sun, 24 Jan 2010 12:36:39 +0200 Avi Kivity <avi@redhat.com> wrote: > On 01/21/2010 11:09 PM, Luiz Capitulino wrote: > > This commit disables asynchronous messages by default and > > introduces two new QMP commands: async_msg_enable and > > async_msg_disable. > > > > Each QMP Monitor has its own set of asynchronous messages, > > so for example, if QEMU is run with two QMP Monitors async > > messages setup in one of them doesn't affect the other. > > > > To implement this design a bitmap is introduced to the > > Monitor struct, each async message is represented by one bit. > > > > > > A bitmap is an overkill here, an array of booleans should suffice. Ok. > > +#define EVENTS_BITMAP_SIZE (QEVENT_MAX / 8) > > > > Doesn't that underflow if QEVENT_MAX is not a multiple of 8? Yes.
Luiz Capitulino <lcapitulino@redhat.com> writes: > On Sun, 24 Jan 2010 18:35:14 +0000 > Jamie Lokier <jamie@shareable.org> wrote: > >> Anthony Liguori wrote: >> > >I'd like to be able to connect and be sure not to receive any async >> > >messages, from simple scripts with simple output parsing. >> > >> > You can't have simple output parsing with QMP. You need a full JSON >> > stack. The simplest script would be a python script that uses the >> > builtin json support. Having async messages means that you'll have to >> > loop on recv in order make sure that the response is a command response >> > vs. an async message. It's just a few lines more of code so I have a >> > hard time believing it's really a problem. >> > >> > But what you probably want is a python QMP library and that would mean >> > you wouldn't need the few more lines of code. >> >> You're right. To be honest, parsing JSON can be done in a single Perl >> regexp; a "full JSON stack" isn't much. >> >> On that note, it'd be good if the end of a QMP message is framed with >> something that can't appear inside the JSON value, without having to >> parse the JSON incrementally on each partial read(). There are plenty >> of short character sequences to choose from that can't appear. Some >> JSON parsers expect a whole well-formed expression or throw a parse >> error - it's what people do over HTTP after all. So you wait until >> you think you've read a whole one, then pass it to the JSON parser. > > The Monitor sends a CRLF sequence at the end of each line and I have > maintained that behaivor for QMP, but it's hard to _guarantee_ that this > sequence won't appear inside a json-string. JSON requires control characters in strings to be escaped. RFC 4627 section 2.5: A string begins and ends with quotation marks. All Unicode characters may be placed within the quotation marks except for the characters that must be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F). > In practice it doesn't, afaik. If it doesn't, then it's not proper JSON, is it?
On Mon, 25 Jan 2010 15:15:59 +0100 Markus Armbruster <armbru@redhat.com> wrote: > Luiz Capitulino <lcapitulino@redhat.com> writes: > > > On Sun, 24 Jan 2010 18:35:14 +0000 > > Jamie Lokier <jamie@shareable.org> wrote: > > > >> Anthony Liguori wrote: > >> > >I'd like to be able to connect and be sure not to receive any async > >> > >messages, from simple scripts with simple output parsing. > >> > > >> > You can't have simple output parsing with QMP. You need a full JSON > >> > stack. The simplest script would be a python script that uses the > >> > builtin json support. Having async messages means that you'll have to > >> > loop on recv in order make sure that the response is a command response > >> > vs. an async message. It's just a few lines more of code so I have a > >> > hard time believing it's really a problem. > >> > > >> > But what you probably want is a python QMP library and that would mean > >> > you wouldn't need the few more lines of code. > >> > >> You're right. To be honest, parsing JSON can be done in a single Perl > >> regexp; a "full JSON stack" isn't much. > >> > >> On that note, it'd be good if the end of a QMP message is framed with > >> something that can't appear inside the JSON value, without having to > >> parse the JSON incrementally on each partial read(). There are plenty > >> of short character sequences to choose from that can't appear. Some > >> JSON parsers expect a whole well-formed expression or throw a parse > >> error - it's what people do over HTTP after all. So you wait until > >> you think you've read a whole one, then pass it to the JSON parser. > > > > The Monitor sends a CRLF sequence at the end of each line and I have > > maintained that behaivor for QMP, but it's hard to _guarantee_ that this > > sequence won't appear inside a json-string. > > JSON requires control characters in strings to be escaped. RFC 4627 > section 2.5: Excellent. > > In practice it doesn't, afaik. > > If it doesn't, then it's not proper JSON, is it? My 'doesn\'t' meant: no JSON string we currently generate has CR or LF in them, as far as I can remember. But even if it happens it's not a problem, as you clarified.
Luiz Capitulino <lcapitulino@redhat.com> writes: > On Fri, 22 Jan 2010 12:05:19 -0600 > Anthony Liguori <anthony@codemonkey.ws> wrote: > >> On 01/21/2010 03:09 PM, Luiz Capitulino wrote: >> > This commit disables asynchronous messages by default and >> > introduces two new QMP commands: async_msg_enable and >> > async_msg_disable. >> > >> > Each QMP Monitor has its own set of asynchronous messages, >> > so for example, if QEMU is run with two QMP Monitors async >> > messages setup in one of them doesn't affect the other. >> > >> > To implement this design a bitmap is introduced to the >> > Monitor struct, each async message is represented by one bit. >> > >> > Signed-off-by: Luiz Capitulino<lcapitulino@redhat.com> >> > >> >> Ah, I see I was a little confused. >> >> I'd suggest making async message masking an independent mechanism. >> Capabilities should strictly deal with protocol changes, not feature >> details. > > To summarize (after a IRC talk): async messages are considered a > capability and should be enabled during the negotiation phase but > the masking of particular messages are not and can be done at > any time after the negotiation phase. > > I'm ok with that, Markus? I agree with Anthony that async message masking doesn't really affect the protocol proper. We could pretend it does so we can let protocol capability negotiation (which we need anyway) cover it. But I'm certainly fine with keeping it separate. Whether we call it protocol or not, the question whether we should permit changing the masks at any time is valid, I think. Permitting it adds a bit of conceptual complexity, as a command disabling reporting of an event can race with the event. But that's just giving clients some more rope. I'm fine with that.
On 01/25/2010 04:29 PM, Markus Armbruster wrote: > > I agree with Anthony that async message masking doesn't really affect > the protocol proper. We could pretend it does so we can let protocol > capability negotiation (which we need anyway) cover it. But I'm > certainly fine with keeping it separate. > > Whether we call it protocol or not, the question whether we should > permit changing the masks at any time is valid, I think. Permitting it > adds a bit of conceptual complexity, as a command disabling reporting of > an event can race with the event. But that's just giving clients some > more rope. I'm fine with that. > Without disagreeing with the rest (which means I'm just nit-picking), there's no race. Once the command that disables an event report returns to the caller, the event can no longer be reported.
On Mon, 25 Jan 2010 16:33:02 +0200 Avi Kivity <avi@redhat.com> wrote: > On 01/25/2010 04:29 PM, Markus Armbruster wrote: > > > > I agree with Anthony that async message masking doesn't really affect > > the protocol proper. We could pretend it does so we can let protocol > > capability negotiation (which we need anyway) cover it. But I'm > > certainly fine with keeping it separate. > > > > Whether we call it protocol or not, the question whether we should > > permit changing the masks at any time is valid, I think. Permitting it > > adds a bit of conceptual complexity, as a command disabling reporting of > > an event can race with the event. But that's just giving clients some > > more rope. I'm fine with that. > > > > Without disagreeing with the rest (which means I'm just nit-picking), > there's no race. Once the command that disables an event report returns > to the caller, the event can no longer be reported. I wouldn't call it a race, but if you don't want an event you'll have to deal with it between mode change and masking. Not a big deal, only confirms that clients are required to know how to ignore events, even if masking is available (which I'm not going to introduce).
diff --git a/monitor.c b/monitor.c index 61c0273..321bc3a 100644 --- a/monitor.c +++ b/monitor.c @@ -108,11 +108,14 @@ typedef enum QMPMode { QMODE_HANDSHAKE, } QMPMode; +#define EVENTS_BITMAP_SIZE (QEVENT_MAX / 8) + typedef struct MonitorControl { QObject *id; QMPMode mode; int print_enabled; JSONMessageParser parser; + uint8_t events_bitmap[EVENTS_BITMAP_SIZE]; } MonitorControl; struct Monitor { @@ -318,6 +321,23 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data) QDECREF(qmp); } +static void qevent_set(const Monitor *mon, int64_t event) +{ + assert(event >= 0 && event < QEVENT_MAX); + mon->mc->events_bitmap[event / 8] |= (1 << (event % 8)); +} + +static void qevent_unset(const Monitor *mon, int64_t event) +{ + assert(event >= 0 && event < QEVENT_MAX); + mon->mc->events_bitmap[event / 8] &= ~(1 << (event % 8)); +} + +static int qevent_enabled(const Monitor *mon, int64_t event) +{ + return (mon->mc->events_bitmap[event / 8] & (1 << (event % 8))); +} + static void timestamp_put(QDict *qdict) { int err; @@ -389,7 +409,8 @@ void monitor_protocol_event(MonitorEvent event, QObject *data) } QLIST_FOREACH(mon, &mon_list, entry) { - if (monitor_ctrl_mode(mon)) { + if (monitor_ctrl_mode(mon) && + qevent_enabled(mon, event)) { monitor_json_emitter(mon, QOBJECT(qmp)); } } @@ -465,6 +486,32 @@ static void do_commit(Monitor *mon, const QDict *qdict) } } +static void qevent_set_value(Monitor *mon, const QDict *qdict, int value) +{ + int i; + const char *name = qdict_get_str(qdict, "name"); + + for (i = 0; monitor_events_names[i].name != NULL; i++) { + if (!strcmp(monitor_events_names[i].name, name)) { + return (value ? qevent_set(mon, i) : qevent_unset(mon, i)); + } + } + + qemu_error_new(QERR_ASYNC_MSG_NOT_FOUND, name); +} + +static void do_async_msg_enable(Monitor *mon, const QDict *qdict, + QObject **ret_data) +{ + qevent_set_value(mon, qdict, 1); +} + +static void do_async_msg_disable(Monitor *mon, const QDict *qdict, + QObject **ret_data) +{ + qevent_set_value(mon, qdict, 0); +} + static void do_info(Monitor *mon, const QDict *qdict, QObject **ret_data) { const mon_cmd_t *cmd; diff --git a/qemu-monitor.hx b/qemu-monitor.hx index eebea09..0f3dfde 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1077,6 +1077,36 @@ STEXI Switch QMP to @var{mode} ETEXI + { + .name = "async_msg_enable", + .args_type = "name:s", + .params = "async_msg_enable name", + .help = "enable an asynchronous message", + .flags = HANDLER_HANDSHAKE_ONLY, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_async_msg_enable, + }, + +STEXI +@item async_msg_enable @var{name} +Enable the asynchronous message @var{name} +ETEXI + + { + .name = "async_msg_disable", + .args_type = "name:s", + .params = "async_msg_disable name", + .help = "disable an asynchronous message", + .flags = HANDLER_HANDSHAKE_ONLY, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_async_msg_disable, + }, + +STEXI +@item async_msg_disable @var{name} +Disable the asynchronous message @var{name} +ETEXI + STEXI @end table ETEXI
This commit disables asynchronous messages by default and introduces two new QMP commands: async_msg_enable and async_msg_disable. Each QMP Monitor has its own set of asynchronous messages, so for example, if QEMU is run with two QMP Monitors async messages setup in one of them doesn't affect the other. To implement this design a bitmap is introduced to the Monitor struct, each async message is represented by one bit. Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> --- monitor.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- qemu-monitor.hx | 30 ++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletions(-)