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

Re: [Libvir] Preliminary patch to support remote driver / libvirtd

On Tue, Jan 30, 2007 at 05:42:21PM +0000, Richard W.M. Jones wrote:
> This patch is just for discussion.  It's not in a state to be applied, 
> even if it were accepted (which is a long-shot at present anyway).
> When looking at the patch, a good starting point is to search for 
> "Architecture and notes" and read from there.
> Supports:
>  * remote driver (just does the "open", "close", "type" and
>    "version" calls at present as a proof of concept)
>  * TLS transport (built using GnuTLS)
>  * SSH transport (forks external ssh process)
>  * TCP transport (unencrypted - just for testing)
>  * Unix domain socket transport
>  * arbitrary external program / shell script transport
>  * IPv6-ready on client & server
> I've tested all the transports, and in limited tests they all
> seem to work.  ie. You really can do:
>   virsh -c remote:tls:server version

I don't think that's valid URI syntax - although we've got the historical
cruft of a simple 'xen' connect string, we're trying to get the rest of
the backends to use sane URIs. We need to be able to express the actual
backend driver in this URI, so that its possible to pass it into the
virConnectOpen method on the server side.

Current drivers have prefixes like


We could make use of the host/port number component to signify that the
driver should use the libvirtd.  So 'test:///default' would be procssed
by the driver locally, while 'test://example.com/default' would get
picked up by the 'remote' driver which would strip the host/port bit
and pass 'test:///default' to the virConnectOpen method on the remote

> Shortcomings in this version:
>  * in "open" call, name must be non-NULL (this is just a bug)
>  * doesn't actually invoke libvirt on the server side; just
>    prints out messages and returns dummy values
>  * "ssh" not recognised as a service name by getaddrinfo, so
>    you must always give a port number, ie. remote:ssh:server:22

That's a little odd - do other named services get recognised corectly ?

>  * /tmp/socket should be cleaned up when the server exits

Two scenarios I imagine:

 1. A privileged daemon started from the init scripts. The init
    script would do the PID file based locking preventing 2
    instances being started. Thus could simply unlink() the socket
    upon startup before bind()ing to it
 2. Or just use sockets in the abstract namespace which don't hit
     the filesystem at all & thus are auto-cleaned up.

I prefer the latter really.

>  * SunRPC is stateless so we need to hand out a cookie to
>    represent the virConnectPtr handle on the server side.
>    However if the client dies without explicitly calling
>    close, we have no way to know, and so the cookie/handle
>    on the server side lives forever.

I think you can get a handle to the socket representing the client
connection from without the remote impl of the methods, by using the
svc_getcaller() API, and thus associated state with the client socket.
Since we have to replace svc_run() with a hand crafted mainloop
we can then detect when a client socket is removed from the server
and trigger cleanup of any resources.
>  * There's some confusion about the level of abstraction.  At
>    the moment I'm abstracting at the driver level, but that may
>    be wrong and possibly I should be abstracting at the level
>    of vir* calls.  On the other hand, there's not a huge amount
>    of difference.

The only interesting difference is probably in the virConnectOpen
method where we iterate over the drivers figuring out which one to
activate. Once you have an activated driver, then it doesn't matter
really whether you call the public, or driver APIs. I think I'd
probably start off at the vir* call level.

>  * Security:
>      Is it safe for libvirt to be connecting to arbitrary TCP
>      sockets?

Well the app always has to pass an explicit URI into virConnectOpen
before we'll do any of the remote connection stuff, so I'd assume
that if they're giving us an explicit request to connect to port
XXX then they know what they're doing.

>      Is it safe for libvirt to be able to run arbitrary programs?

I'm not such a fan of libraries which spawn arbitrary programs on
my behalf. But as long as it didn't actually spawn stuff unless ther
was some explicit request based on the URI it should be ok - that 
way we can document that specific URI formats will result in the
spawning of /usr/bin/ssh.

> +  if (strncasecmp (name, "remote:", 7) != 0)
> +    return -1;			/* Not for me. */
> +
> +  /* Split the name at whitespace and parse it. */
> +  const char *p;
> +  for (p = name; *p;) {
> +    // NB. All versioning is done by SunRPC so we don't need to worry
> +    // that we are connected to an incompatible daemon.
> +    break;
> +  }

We can use libxml's existing routines for parsing URIs

#include <libxml/uri.h>

xmlURIPtr uri = xmlParseURI(connectstr)

> +
> +  case proto_unix: {
> +    // 108 is hard-coded into the header files as well.
> +#define UNIX_PATH_MAX 108

Can't we use  sizeof(addr.sun_path) because this may be hardcoded
to a different value on non-Linux systems.

> +program LIBVIRTREMOTE {
> +  version LIBVIRTREMOTE_VERS1 {
> +    /* XXX The open interface should return a cookie to represent
> +     * the virConnectPtr on the server side.  Note also that SunRPC
> +     * is stateless so it's unclear when cookies can be garbage
> +     * collected.
> +     */
> +    int remote_rpc_open (string) = 1;

Do we actually need any to have any cookie for this - just assume 1 socket
connetion == virConnectPtr  object and thus only allow remote_rpc_open to
be called a single time per connection. 

|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

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