The code is still in rough shape, but while we're on the topic of guest agents I wanted to put out a working example of how exec functionality can be added to qemu-ga to provide a mechansim for building arbitrarilly high-level interfaces.
The hope is that by allowing qemu-ga to execute commands in the guest, paired with file read/write access, we can instrument a guest "on the fly" to support any type of hyperviser functionality, and do so without dramatically enlarging the role qemu-ga plays as a small, QEMU-specific agent that is tightly integrated with QEMU/QMP/libvirt. These patches add the following interfaces: guest-file-open-pipe guest-exec guest-exec-status The guest-file-open-pipe interface is analagous to the existing guest-file-open interface (it might be best to roll it into it actually): it returns a handle that can be handled via the existing guest-file-{read,write,flush,close} interface. Internally it creates a FIFO pair that we can use to associate handles to the stdin/stdout/stderr of a guest-exec spawned process. We can also also use them to redirect output into other processes, giving us the basic tools to build a basic shell (or a full-blown one if we add TTY support) using a single qemu-ga. Theoretically we can even deploy other agents, including session-level agents, and communicate with them via these same handles. Thus, ovirt could deploy and run an agent via qemu-ga, Spice could deploy vdagent, etc. Since the interface is somewhat tedious, I'm working on a wrapper script to try out some of these scenarios, but a basic use case using the raw QMP interface is included below. Any thoughts/comments on this approach are appreciated. EXAMPLE USAGE (execute `top -b -n1`): {'execute': 'guest-file-open-pipe'} {'return': 6} {'execute': 'guest-exec', \ 'arguments': {'detach': True, \ 'handle_stdout': 6, \ 'params': [{'param': '-b'}, \ {'param': '-n1'}], \ 'path': 'top'}} {'return': {'exit-code': 0, \ 'exited': False, \ 'handle_stderr': -1, \ 'handle_stdin': -1, \ 'handle_stdout': 6, \ 'pid': 14267}} {'execute': 'guest-file-read', \ 'arguments': {'count': 65536, \ 'handle': 6}} {'return': {'buf-b64': '', \ 'count': 0, \ 'eof': False}} {'execute': 'guest-file-read', \ 'arguments': {'count': 65536, \ 'handle': 6}} {'return': {'buf-b64': 'dG9wIC0gMjI6N...', \ 'count': 11064, \ 'eof': True}} /* top - 22:41:49 up 1 day, 4:30, 3 users, load average: 0.00, 0.00, 0.00 Tasks: 114 total, 1 running, 113 sleeping, 0 stopped, 0 zombie Cpu(s): 0.2%us, 0.2%sy, 0.0%ni, 99.6%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 504848k total, 445664k used, 59184k free, 49100k buffers Swap: 323580k total, 224k used, 323356k free, 256392k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 14267 root 20 0 19272 1248 924 R 2 0.2 0:00.02 top 1 root 20 0 24008 2048 1280 S 0 0.4 0:00.85 init 2 root 20 0 0 0 0 S 0 0.0 0:00.30 kthreadd 3 root 20 0 0 0 0 S 0 0.0 0:01.09 ksoftirqd/0 ... */ {'execute': 'guest-exec-status', \ 'arguments': {'pid': 14267}} {'return': {'exit-code': 0, \ 'exited': True, \ 'handle_stderr': -1, \ 'handle_stdin': -1, \ 'handle_stdout': 6, \ 'pid': 14267}} {'execute': 'guest-file-close'} \ 'arguments': {'handle': 6}} {'return': {}} Michael Roth (2): guest agent: add guest-file-open-pipe guest agent: add guest-exec and guest-exec-status interfaces qapi-schema-guest.json | 79 +++++++- qga/guest-agent-commands.c | 478 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 531 insertions(+), 26 deletions(-) -- 1.7.4.1