From: Anthony Liguori <anthony@codemonkey.ws>
To: Luiz Capitulino <lcapitulino@redhat.com>
Cc: Avi Kivity <avi@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] RFC: Monitor high-level design
Date: Wed, 22 Sep 2010 10:39:44 -0500 [thread overview]
Message-ID: <4C9A2340.4030207@codemonkey.ws> (raw)
In-Reply-To: <20100922120347.3a98ebdd@doriath>
On 09/22/2010 10:03 AM, Luiz Capitulino wrote:
> On Wed, 22 Sep 2010 08:18:10 -0500
> Anthony Liguori<anthony@codemonkey.ws> wrote:
>
>
>> On 09/22/2010 07:32 AM, Markus Armbruster wrote:
>>
> [...]
>
>
>>> I can't see why we must have a dogmatic "thou shalt not use anything but
>>> QMP to implement HMP commands, ever" rule.
>>>
> I based most of my ideas on what Anthony has described at:
>
> http://wiki.qemu.org/Features/QMP_0.14
>
> But that's more like a start point, of course that we shouldn't be dogmatic,
> specially when we have better ideas.
>
>
>> FWIW, print/sum can be easily implemented in terms of QMP commands.
>>
> Yes, but I think the point is when/if we should do it.
>
>
>> It's not really necessary for every possibly HMP command to be
>> implemented in terms of QMP. However, unless you can do everything in
>> QMP that you can do in HMP, then people will be inclined to use HMP as a
>> management interface.
>>
> s/use HMP/use QMP
>
>
>> So, the only real rule we should try to adopt is that QMP is at least as
>> powerful as HMP. That should be our goal.
>>
> Agreed.
>
>
>>>> - HMP can't be moved outside of QEMU, if we want that we'd have to
>>>> write a new Monitor client (potentially in a different language,
>>>> which is actually good)
>>>>
>>>>
>>> I'd rather not worry about that now.
>>>
>>>
>>>
>>>> - Not sure if HMP features like command completion will perfectly fit
>>>>
>>>>
>>> Maybe I'm naive, but I figure that as long as the human monitor controls
>>> its character device and knows enough about its own commands, it can do
>>> completion pretty much the same way it does now.
>>>
> Yes, that's right.
>
>
>>> Let's have a closer look at the human monitor:
>>>
>>> +---------------+ reads/writes
>>> | human monitor |<---------------> character device
>>> +---------------+ ^
>>> | |
>>> | calls |
>>> | |
>>> v |
>>> +---------------+ writes |
>>> | hmon handlers | -------------------------+
>>> +---------------+
>>>
>>> The "human monitor" box actually has identifiable sub-boxes:
>>>
>>> * Command table: human monitor command description
>>>
>>> * Several argument types: methods to parse, check, complete, ...
>>>
>>> * Reader: read a line of input from character device
>>>
>>> - Readline, uses table for completion
>>>
>>> * Parser: parse a line of input, uses table to parse arguments
>>>
>>> * Executor: call the appropriate handler, uses table
>>>
>>> The machine monitor (short: qmon) is pretty similar, actually.
>>>
> That's the 'is pretty similar' part I was referring to when I said (by IRC
> I guess) that qmon and hmon can share the device handling code.
>
>
>>> Differences:
>>>
>>> * We read and parse JSON objects, not lines.
>>>
>>> * We don't bother to set up completion.
>>>
>>> * The qmon handlers don't write to the character device. They return
>>> objects instead, to be written by the qmon executor.
>>>
>>> Remember that we want qmon handlers to use proper internal interfaces to
>>> do the real work. In other words, qmon handlers should be fairly
>>> trivial.
>>>
>>> I can think of three ways to write a human monitor handler:
>>>
>>> 1. Call a qmon handler, print the object it returns, suitably formatted.
>>>
>>> 2. Call the internal interfaces, just like qmon handlers do. Print the
>>> results.
>>>
>>> This cut out the qmon handler middle-man. Since the qmon handler is
>>> supposed to be trivial, this isn't a big deal.
>>>
>>> 3. Just do it. I think that's fine for some commands that make sense
>>> only human monitor, like print. Also fine for legacy commands
>>> scheduled for removal; we got more useful things to do than
>>> beautifying those. The ones we want to keep we should convert to
>>> 1. or 2. Doing that early may be advisable to get the internal
>>> interfaces used, but it's not like "need to convert everything before
>>> anything works".
>>>
>>> You see hmon doesn't use all of qmon, only qmon handlers, and even that
>>> only with 1. Can't see a layering issue there.
>>>
> Yes and note that we have 1 and 3 today already.
>
>
>> Yeah, I think what you describe makes perfect sense. As long as QMP is
>> a thin wrapper around an API, and HMP also calls the API, then it's
>> pretty clear that QMP is at least as powerful as HMP.
>>
> Ok, let me get into two details:
>
> 1. The BufferCharDriverState is only going to be used for human monitor
> passthrough, right?
>
Well, I think the pointer Markus raised is that there are two ways to
implement HMP in terms of QMP. One of them is to do:
static void do_commit(Monitor *mon, const char *device)
{
QObject *res;
res = qmp_command("commit", "{'device': %s}", device);
if (qobject_is_qerror(res)) {
monitor_printf(mon, "commit: %s\n",
qerror_to_str(qobject_to_qerror(res)));
return;
}
}
And the second way is:
static void do_commit(Monitor *mon, const char *device)
{
Error *err = NULL;
qpi_commit(device, &err);
if (err) {
monitor_printf(mon, "commit: %s\n", error_to_str(err);
error_free(err);
}
}
Which takes advantage of the notion that all QMP commands are expressed
as proper C interfaces internally. Under the covers, qpi_commit() could
be a direct API call or it could even be a QMP client RPC interface. As
long as qpi_commit(...) maps directly to qmp_command("commit", ...) it's
all equivalent.
There's definitely an elegance to the second approach.
Regards,
Anthony Liguori
> 2. As Markus described above, QMP and HMP perform similar internal steps,
> so what about having them behind a common interface, like this:
>
> struct monitor_ops {
> const char *name;
> int (*init)(void *opaque);
> void (*exit)(void *opaque);
> int (*can_read)(void *opaque);
> void (*read)(void *opaque, const uint8_t *buf, int size);
> void (*event)(void *opaque, int event);
> void (*async_message)(void *opaque, MonitorEvent, QObject *data);
> };
>
> Then monitor.c code would register itself with the chardev layer, calling
> each monitor's monitor_ops.
>
> Note that we already have a feature request to be able to create new monitors
> on demand. I believe such design will help.
>
> Is this overkill? Does anyone have better ideas on how both modules (QMP/HMP)
> should be designed/separated?
>
> Sketches are welcome.
>
prev parent reply other threads:[~2010-09-22 15:40 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-21 18:46 [Qemu-devel] RFC: Monitor high-level design Luiz Capitulino
2010-09-21 19:08 ` [Qemu-devel] " Anthony Liguori
2010-09-22 12:32 ` [Qemu-devel] " Markus Armbruster
2010-09-22 13:18 ` Anthony Liguori
2010-09-22 15:03 ` Luiz Capitulino
2010-09-22 15:39 ` Anthony Liguori [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C9A2340.4030207@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=armbru@redhat.com \
--cc=avi@redhat.com \
--cc=lcapitulino@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).