[libvirt] [PATCH] virDomainMemoryPeek - peek into guest memory

This patch implements virDomainMemoryPeek, which allows callers to peek into guest (virtual) memory. Currently the patch contains a QEMU driver and remote support. There's also a big comment in the source describing how to do Xen. Obviously the use case for this is virt-mem: http://et.redhat.com/~rjones/virt-mem/ Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones Read my OCaml programming blog: http://camltastic.blogspot.com/ Fedora now supports 59 OCaml packages (the OPEN alternative to F#) http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora

This patch removes a file descriptor leak. I've now tested this patch with virt-mem and it appears to work. Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into Xen guests. http://et.redhat.com/~rjones/virt-p2v

On Thu, Jun 05, 2008 at 10:30:55PM +0100, Richard W.M. Jones wrote:
+/* Memory peeking flags. */ +typedef enum { + VIR_MEMORY_VIRTUAL = 1, /* addresses are virtual addresses */ +} virDomainMemoryFlags;
Since there is only one flag, and it is compulsory I'm rather inclined to say that virtual memory addressing should be the default with a flags value of 0. Unless there is another mode, not yet implemented, that you think would be a better default in the future ? Obviously keep the flags arg for expansion regardless though.
diff -u -p -r1.36 remote.c --- qemud/remote.c 5 Jun 2008 21:12:26 -0000 1.36 +++ qemud/remote.c 5 Jun 2008 21:26:29 -0000 @@ -938,6 +938,52 @@ remoteDispatchDomainBlockPeek (struct qe }
static int +remoteDispatchDomainMemoryPeek (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client, + remote_message_header *req, + remote_domain_memory_peek_args *args, + remote_domain_memory_peek_ret *ret) +{ + virDomainPtr dom; + unsigned long long offset; + size_t size; + unsigned int flags; + CHECK_CONN (client); + + dom = get_nonnull_domain (client->conn, args->dom); + if (dom == NULL) { + remoteDispatchError (client, req, "%s", _("domain not found")); + return -2; + } + offset = args->offset; + size = args->size; + flags = args->flags; + + if (size > REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX) { + remoteDispatchError (client, req, + "%s", _("size > maximum buffer size")); + return -2; + } + + ret->buffer.buffer_len = size; + ret->buffer.buffer_val = malloc (size); + if (!ret->buffer.buffer_val) { + remoteDispatchError (client, req, "%s", strerror (errno)); + return -2; + }
The 'dom' object is leaking in the 2 error paths here & it'd be better to use VIR_ALLOC_N(ret->buffer.buffer_val, size) here.
diff -u -p -r1.14 remote_protocol.x --- qemud/remote_protocol.x 5 Jun 2008 21:12:27 -0000 1.14 +++ qemud/remote_protocol.x 5 Jun 2008 21:26:29 -0000 @@ -340,6 +340,17 @@ struct remote_domain_block_peek_ret { opaque buffer<REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX>; };
+struct remote_domain_memory_peek_args { + remote_nonnull_domain dom; + unsigned hyper offset; + unsigned size; + unsigned flags; +}; + +struct remote_domain_memory_peek_ret { + opaque buffer<REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX>; +};
Is it worth having a separate constant for the max memory size, independant of the block peek size.
+/** + * virDomainMemoryPeek: + * @dom: pointer to the domain object + * @start: start of memory to peek + * @size: size of memory to peek + * @buffer: return buffer (must be at least size bytes) + * @flags: flags, see below + * + * This function allows you to read the contents of a domain's + * memory. + * + * The memory which is read is controlled by the 'start', 'size' + * and 'flags' parameters. + * + * If 'flags' is VIR_MEMORY_VIRTUAL then the 'start' and 'size' + * parameters are interpreted as virtual memory addresses for + * whichever task happens to be running on the domain at the + * moment. Although this sounds haphazard it is in fact what + * you want in order to read Linux kernel state, because it + * ensures that pointers in the kernel image can be interpreted + * coherently. + * + * 'buffer' is the return buffer and must be at least 'size' bytes. + * 'size' may be 0 to test if the call would succeed.
Should we document and enforce a maximum value for size. The remote driver at least has a maximum limit,, so perhaps we should enforce that in the main API dispatcher here in virDomainMemoryPeek() impl
+int +static int +qemudDomainMemoryPeek (virDomainPtr dom, + unsigned long long offset, size_t size, + void *buffer, + unsigned int flags) +{ + struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData; + struct qemud_vm *vm = qemudFindVMByID (driver, dom->id); + char cmd[256], *info; + char tmp[] = "/tmp/qemumemXXXXXX";
It'd make the SELinux policy easier if we avoided the generic /tmp and put the files in somewhere like /var/spool/libvirt/qemu/. Wouldn't even need to use mkstemp() then - just have it named VMNAME.mem since it'd be in a safe controlled directory Regards, Daniel. -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Fri, Jun 06, 2008 at 11:25:41AM +0100, Daniel P. Berrange wrote:
On Thu, Jun 05, 2008 at 10:30:55PM +0100, Richard W.M. Jones wrote:
+/* Memory peeking flags. */ +typedef enum { + VIR_MEMORY_VIRTUAL = 1, /* addresses are virtual addresses */ +} virDomainMemoryFlags;
Since there is only one flag, and it is compulsory I'm rather inclined to say that virtual memory addressing should be the default with a flags value of 0. Unless there is another mode, not yet implemented, that you think would be a better default in the future ? Obviously keep the flags arg for expansion regardless though.
The reason I wanted this flag is because I think this behaviour is unexpected, so it's worth remarking on it. I would (naively) have expected a memory-peek call to peek physical memory, even though that isn't very useful behaviour if you want to actually analyze the memory. So the flag makes sure people realize that the peeking does a virtual to physical address mapping. I fully expect that we would add a VIR_MEMORY_PHYSICAL flag at some point. Thanks for looking at the rest of the patch. I'll make an updated version soon with those things fixed. Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/

Here's a patch which should address all concerns raised, although I left the VIR_MEMORY_VIRTUAL flag because I still think it's important to have it. Please note to whomever is maintaining libvirt in Fedora that there is a change to the specfile. Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into Xen guests. http://et.redhat.com/~rjones/virt-p2v

On Mon, Jun 09, 2008 at 01:47:09PM +0100, Richard W.M. Jones wrote: [...]
@@ -49,6 +49,7 @@ #endif
#include "internal.h" +#include "memory.h" #include "qemud.h" #include "memory.h"
Oops - ignore that fragment. I think an intervening 'cvs update' pulled in an extra part from Dan's patch. Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into Xen guests. http://et.redhat.com/~rjones/virt-p2v

On Mon, Jun 09, 2008 at 01:47:09PM +0100, Richard W.M. Jones wrote:
+struct remote_domain_memory_peek_ret { + opaque buffer<REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX>; +};
Aargh, and this should be REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX instead. Not going well today! Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones Read my OCaml programming blog: http://camltastic.blogspot.com/ Fedora now supports 59 OCaml packages (the OPEN alternative to F#) http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora

On Mon, Jun 09, 2008 at 01:47:09PM +0100, Richard W.M. Jones wrote:
Here's a patch which should address all concerns raised, although I left the VIR_MEMORY_VIRTUAL flag because I still think it's important to have it.
Please note to whomever is maintaining libvirt in Fedora that there is a change to the specfile.
Any comments on this patch? Rich. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones Read my OCaml programming blog: http://camltastic.blogspot.com/ Fedora now supports 59 OCaml packages (the OPEN alternative to F#) http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora

On Tue, Jun 10, 2008 at 09:39:44AM +0100, Richard W.M. Jones wrote:
On Mon, Jun 09, 2008 at 01:47:09PM +0100, Richard W.M. Jones wrote:
Here's a patch which should address all concerns raised, although I left the VIR_MEMORY_VIRTUAL flag because I still think it's important to have it.
Please note to whomever is maintaining libvirt in Fedora that there is a change to the specfile.
Any comments on this patch?
Looks ok to me now. Daniel. -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Tue, Jun 10, 2008 at 09:39:44AM +0100, Richard W.M. Jones wrote:
On Mon, Jun 09, 2008 at 01:47:09PM +0100, Richard W.M. Jones wrote:
Here's a patch which should address all concerns raised, although I left the VIR_MEMORY_VIRTUAL flag because I still think it's important to have it.
Please note to whomever is maintaining libvirt in Fedora that there is a change to the specfile.
Any comments on this patch?
Looks fine to me ! Daniel -- Red Hat Virtualization group http://redhat.com/virtualization/ Daniel Veillard | virtualization library http://libvirt.org/ veillard@redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/

"Richard W.M. Jones" <rjones@redhat.com> wrote:
On Mon, Jun 09, 2008 at 01:47:09PM +0100, Richard W.M. Jones wrote:
Here's a patch which should address all concerns raised, although I left the VIR_MEMORY_VIRTUAL flag because I still think it's important to have it.
Please note to whomever is maintaining libvirt in Fedora that there is a change to the specfile.
Any comments on this patch?
Looks fine!
participants (4)
-
Daniel P. Berrange
-
Daniel Veillard
-
Jim Meyering
-
Richard W.M. Jones