qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [RFC][PATCH v1 08/12] qemu-char: add qmp_proxy chardev


From: Michael Roth
Subject: [Qemu-devel] Re: [RFC][PATCH v1 08/12] qemu-char: add qmp_proxy chardev
Date: Tue, 29 Mar 2011 13:54:57 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9

On 03/28/2011 12:45 PM, Anthony Liguori wrote:
On 03/25/2011 05:11 PM, Michael Roth wrote:
Why are these options required?


The qmp_proxy_new() constructor expects a path to a socket it can
connect() to. Not sure about telnet, but the other options are
required for this. Well...server=on at least, wait=off needs to be set
as well because that's the only way to have the socket chardev set the
listening socket to non-block, since qmp_proxy_new() calls connect()
on it before we return to the main I/O loop.

Although, we probably shouldn't just silently switch out explicitly
set options; an error would probably be more appropriate here.

You ought to make qmp_proxy_new() return a CharDriverState such that you
can do:

qemu -device virtio-serial,chardev=foo -chardev guest-agent,id=foo


That's what the current invocation looks like, but with regard to not relying on an intermediate socket between QmpProxy and individual qmp sessions, I think the main issue is:

- We expose the proxy via a call such a qmp_proxy_send_request(QDict request) - This request can be arbitrarily large (not atm, but in the future perhaps with RPCs sent as qmp_send_file() they may potential by large)

So if we do this directly via a new char state rather than intermediate sock, we'd either:

1) Send the request in full via, say, qmp_proxy_send_request()->qemu_chr_read()->virtio_serial_write(), and assume the port/device can actually buffer it all in one shot. Or,

2) Send it in smaller chunks, via something that amounts to:

    can_read_bytes = virtio_serial_guest_ready()):
    virtio_serial_write(port, request, can_read_bytes)

If anything is left over, we need to add something QEMU's main loop to handle some of the remaining bytes in the next main loop iteration. (With the intermediate socket, we achieve this by registering a write handler that selects on the intermediate socket and writes in small chunks until the buffer is empty, the socket chardev does all the work of checking for the backend device to be ready and not writing more than it should)

So, if we do 2), which I think is the only "correct" approach out of the 2, to take the intermediate socket fd out of the equation, we either need to add a custom handler to QEMU's main loop, or register deferred work via something like qemu_bh_schedule_idle().

So I think that's the trade-off...we can:

- do what the patches currently do and complicate the plumbing by adding an intermediate socket (or perhaps even just a pipe), and simplify the logic of handling backlogged work via a select()-driven write handler, or

- remove the intermediate socket to simplify the plumbing, but complicate the back-end logic involved in sending requests to the guest by using a BH to clear our host->guest TX buffer

If using a BH to handle this work seems reasonable, then I'd be fine with attempting to implement this. If using a BH seems nasty, then I think the current intermediate socket/fd approach is the best alternative.

Regards,

Anthony Liguori





reply via email to

[Prev in Thread] Current Thread [Next in Thread]