qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] block: Add support for Secure Shell (ssh) block


From: Stefan Hajnoczi
Subject: Re: [Qemu-devel] [PATCH] block: Add support for Secure Shell (ssh) block device.
Date: Thu, 21 Mar 2013 20:29:35 +0100

On Thu, Mar 21, 2013 at 4:39 PM, Richard W.M. Jones <address@hidden> wrote:
> On Thu, Mar 21, 2013 at 04:26:23PM +0100, Stefan Hajnoczi wrote:
>> On Thu, Mar 21, 2013 at 01:38:58PM +0000, Richard W.M. Jones wrote:
>> > From: "Richard W.M. Jones" <address@hidden>
>> >
>> >   qemu-system-x86_64 -drive file=ssh://hostname/some/image
>> >
>> > QEMU will ssh into 'hostname' and open '/some/image' which is made
>> > available as a standard block device.
>> >
>> > You can specify a username (ssh://address@hidden/...) and/or a port number
>> > (ssh://host:port/...).
>>
>> I can see this being handy for qemu-img since it gives you the ability
>> to work with remote image files.
>>
>> > Current limitations:
>> >
>> > - Authentication must be done without passwords or passphrases, using
>> >   ssh-agent.  Other authentication methods are not supported. (*)
>> >
>> > - Does not check host key. (*)
>> >
>> > - New remote files cannot be created. (*)
>>
>> Would be important to fix these limitations.  Authentication methods to
>> make this more usable.  Host key check for security.  File creation for
>> qemu-img.
>
> I agree.
>
>> > - Uses coroutine read/write, instead of true AIO.  (libssh2 supports
>> >   non-blocking access, so this could be fixed with some effort).
>>
>> This patch does not really use coroutines - the SSH I/O is blocking!
>>
>> Coroutines must submit the SSH I/O and then yield so the QEMU event loop
>> can get on with other work.  When SSH I/O finishes the request's
>> coroutine is re-entered and the request gets completed.
>
> Hmm OK.  Is there any documentation at all on how coroutines are
> supposed to work?  Or AIO for that matter?  For example, do coroutines
> really replace all the read/write syscalls deep inside a library
> (libssh2) so that these calls context switch, or am I missing the
> point of how this works entirely?

Before we go into coroutines, take a look at AIO since it may fit
libssh2's non-blocking mode of operation better.

Doing AIO means implementing .bdrv_aio_readv()/.bdrv_aio_writev().
These functions cannot block so you need to use non-blocking libssh2
interfaces and let QEMU's event loop notify us of
readability/writability (see qemu_aio_set_fd_handler()).

Look at block/iscsi.c:iscsi_aio_readv() for an example of how to
interface with an asynchronous library.

Back to coroutines.  Coroutines are just a primitive, like threads,
that your code can use.  They aren't a framework for how to do block
I/O.

If you want an example, take a look at block/sheepdog.c:

static coroutine_fn void do_co_req(void *opaque)
{
    int ret;
    Coroutine *co;
[...]
    co = qemu_coroutine_self();
    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, have_co_req, co);

    ret = send_co_req(sockfd, hdr, data, wlen);

Using qemu_aio_set_fd_handler() we tell the event loop to call
restart_co_req() when the file descriptor becomes writable.

Then we call send_co_req() which yields if send(2) returns EAGAIN.

This is an example of setting up an event handler, invoking a
non-blocking syscall, and yielding on EAGAIN.  Here is what
restart_co_req() looks like:

static void restart_co_req(void *opaque)
{
    Coroutine *co = opaque;

    qemu_coroutine_enter(co, NULL);
}

If you want to make the code clean and reusable it's best to put the
event handler, non-blocking I/O, and yield/re-enter into a function
that can be reused.  That way each callers don't duplicate this
low-level code.

Hope this gives you an idea of how to use coroutines for block drivers.

>> > This is implemented using libssh2 on the client side.  The server just
>> > requires a regular ssh daemon with sftp-server support.  Most ssh
>> > daemons on Unix/Linux systems will work out of the box.
>>
>> How much of a win over sshfs is this?
>>
>> sshfs can be mounted by unprivileged users and QEMU accesses it like a
>> regular file.  So the sshfs approach already works today.
>
> Sure, but compared to having to install and set up sshfs and FUSE,
> using this is a lot simpler.  It's also potentially faster since it
> cuts out FUSE and context switching to the sshfs process.
>
> BTW I looked into the implementation of sshfs before starting this,
> and what it does is to run an 'ssh' client subprocess, then implements
> the sftp protocol by hand on top.  So using libssh2 cuts out *two*
> external processes (plus FUSE).

I see.  Benchmarks would be interesting once AIO or coroutines is implemented.

Stefan



reply via email to

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