[libvirt] [PATCH] virDomainMemoryPeek - peek into guest memory
Daniel P. Berrange
berrange at redhat.com
Fri Jun 6 10:25:41 UTC 2008
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 :|
More information about the libvir-list
mailing list