qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC][PATCH v6 00/23] virtagent: host/guest RPC communi


From: Michael Roth
Subject: Re: [Qemu-devel] [RFC][PATCH v6 00/23] virtagent: host/guest RPC communication agent
Date: Tue, 01 Feb 2011 16:18:32 -0600
User-agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7

On 01/31/2011 08:41 AM, Michael Roth wrote:
On 01/18/2011 08:13 AM, Anthony Liguori wrote:
On 01/18/2011 08:02 AM, Gerd Hoffmann wrote:
On 01/17/11 15:53, Michael Roth wrote:
On 01/17/2011 07:53 AM, Gerd Hoffmann wrote:
What is your plan to handle system-level queries+actions (such as
reboot) vs. per-user stuff (such as cut+paste)?

One option would be to have two virtio-serial channels, one for the
system and one for the user stuff. gdm could grant the desktop user
access to the user channel like it does with sound devices and simliar
stuff, so the user agent has access to it.

Another option is to have some socket where the user agent can talk to
the system agent and have it relay the requests.

I think this is the best approach. One requirement we've been working
with is that all actions from guest agents are logged. This is to give
an administrator confidence that the hypervisor isn't doing anything
stupid. If you route all of the user traffic through a privileged
daemon, you can log everything to syslog or an appropriate log file.


A brain-dump on how we're planning to do this. I tried to keep it
concise, but that only went so far :)

We extend qemu-va, the virtagent guest agent, to be able to create a
unix socket in the guest that listens for connections.

We also extend qemu-va so that it can run as a user-level daemon that
can connect to the aforementioned socket.

root: qemu-va -c virtio-serial -p /dev/virtio-ports/org.qemu.virtagent
--user-socket=/var/run/virtagent.user.sock

user: qemu-va -c unix-connect -p /var/run/virtagent.user.sock
[--username=user] --user-daemon

The user-level daemon will drop priviledges to specified username if
necessary, or run as the invoking user. User->daemon mappings will be
determined by the system-level agent using getsockopt on new connections.

The user-level daemon operates in the same manner as the system-level
daemon: it can execute RPCs in the host, and the host can execute RPCs
it implements. This should theoretically make it capable of vdagent-like
functionality by adding the appropriate host/guest-side RPCs. We would
have to incorporate the X11 fd into the main select() for events and
such, but that should be fairly straight-forward.

User-specific host->guest RPCs will add an http header,
"X-Virtagent-Username", specifying the intended recipient. If that
recipient has no associated running user-level daemon, an error will be
returned by the system-level daemon. An RPC may be provided so the host
can query the system-level agent for connected users.

User-generated guest->host RPCs will be routed directly to the host,
with the same "X-Virtagent-Username" http header inserted by the
system-level agent. The host will re-insert this header field in it's
responses so the system-level agent can route the responses back to the
user.

We will only allow one daemon per user at a time, and enforce this with
a pid/lock file. If this is circumvented somehow (or we allow a
user-specifiable pid file), a new connection specifying a user that's
already been mapped to a user-level daemon will overwrite the existing
mapping, and the old connection will be closed by the system-level
daemon if it is still active.

Some caveats to consider however:

1) There may be user-level RPCs that are generally desirable...such as
being able to execute a script as an unpriveledged user, or access a
file in the same way. So it makes sense to invoke user-level agent
startup with a login script. But for X-related things like Spice, an
.xsession hook makes more sense. If we do both, the .xsession-spawned
daemon will "take over", but any existing stateful interactions with
that user will be effectively reset. This may be undesirable. One option
is to XOpenDisplay() "on demand", rather than at startup. We won't know
what $env{DISPLAY} is then, however, and there could be multiple
displays for that user. I'm not sure if there's a reliable way to query
such a thing, but assuming you can...we could implement stateful RPCs so
establish a connection later: There could be multiple displays as well.
My first inclination would be to have something like:

on host:
query_displays(user)
connect_display(user, display_name)
query_screens(user, display_name)
etc..

This requires either the host to poll for displays, or for the guest
agent to do it and then notify the host, however. The only way I see
around this is to only start the user-level daemon via .xsession or
similar.

Any thoughts on this?

I'd like to move forward with this approach, but with the goal here being that we have one agent to rule them all, I'd like to know whether those of you involved with the spice vdagent work think this is a reasonable approach.

One thing that would be really useful is if we could outline the basic host->guest calls, and guest->host calls, and see how they fit into the proposed architecture. I've been looking at vdagent to get an idea, but due to the limitations noted above there are some changes that would to made in how we identify, and be notified of, new X displays if we have a single per-user daemon that is started *before* the X display, and persists after the X display is shut down. I can take an initial stab at this, but have some questions:

Can spice do anything useful with more than 1 display per user?

If so, should the agent report new displays to the host? Or should the host query for available displays for a particular user, then instruct the agent about what display it wants the agent to connect to? What about when a display is closed?

Thanks,

Mike



reply via email to

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