From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=35136 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OjzNN-0000yz-2K for qemu-devel@nongnu.org; Fri, 13 Aug 2010 14:53:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OjzNL-0002Mq-MR for qemu-devel@nongnu.org; Fri, 13 Aug 2010 14:53:08 -0400 Received: from mail-yx0-f173.google.com ([209.85.213.173]:34502) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OjzNL-0002Mf-Ho for qemu-devel@nongnu.org; Fri, 13 Aug 2010 14:53:07 -0400 Received: by yxn35 with SMTP id 35so1166981yxn.4 for ; Fri, 13 Aug 2010 11:53:07 -0700 (PDT) Message-ID: <4C65948C.8030707@codemonkey.ws> Date: Fri, 13 Aug 2010 13:53:00 -0500 From: Anthony Liguori MIME-Version: 1.0 References: <1281622202-3453-8-git-send-email-stefano.stabellini@eu.citrix.com> In-Reply-To: <1281622202-3453-8-git-send-email-stefano.stabellini@eu.citrix.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] Re: [PATCH 08/15] xen: Read and write the state of the VM in xenstore List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: stefano.stabellini@eu.citrix.com Cc: Anthony.Perard@citrix.com, xen-devel@lists.xensource.com, qemu-devel@nongnu.org On 08/12/2010 09:09 AM, stefano.stabellini@eu.citrix.com wrote: > From: Anthony PERARD > > Introduce functions to read and write the state of the VM in xenstore. > This basically creates a new management interface for QEMU via the xenstore. Our management interface is QMP. If you want to maintain compatibility, you'll need to write a QMP -> xenstore daemon that maps events appropriately. Regards, Anthony Liguori > Signed-off-by: Anthony PERARD > Signed-off-by: Stefano Stabellini > --- > hw/xen_machine_fv.c | 9 ++++ > target-xen/helper.c | 7 +++ > target-xen/qemu-xen.h | 3 + > target-xen/xenstore.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++ > target-xen/xenstore.h | 6 ++ > 5 files changed, 153 insertions(+), 0 deletions(-) > > diff --git a/hw/xen_machine_fv.c b/hw/xen_machine_fv.c > index ec826e7..a6e778a 100644 > --- a/hw/xen_machine_fv.c > +++ b/hw/xen_machine_fv.c > @@ -36,10 +36,17 @@ > #include "xen_backend.h" > #include "xenstore.h" > #include "xen_platform.h" > +#include "qemu-xen.h" > #include "xen/hvm/hvm_info_table.h" > > #define MAX_IDE_BUS 2 > > +static void xen_vm_change_state_handler(void *opaque, int running, int reason) > +{ > + if (running) > + xen_main_loop_prepare(); > +} > + > static void xen_init_fv(ram_addr_t ram_size, > const char *boot_device, > const char *kernel_filename, > @@ -150,6 +157,8 @@ static void xen_init_fv(ram_addr_t ram_size, > } > > pc_pci_device_init(pci_bus); > + > + qemu_add_vm_change_state_handler(xen_vm_change_state_handler, NULL); > } > > static QEMUMachine xenfv_machine = { > diff --git a/target-xen/helper.c b/target-xen/helper.c > index d588e64..8cb7771 100644 > --- a/target-xen/helper.c > +++ b/target-xen/helper.c > @@ -19,6 +19,8 @@ > */ > > #include "cpu.h" > +#include "qemu-xen.h" > +#include "xenstore.h" > > CPUXenState *cpu_xen_init(const char *cpu_model) > { > @@ -67,3 +69,8 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) > { > return addr; > } > + > +void xen_main_loop_prepare(void) > +{ > + xenstore_record_dm_state("running"); > +} > diff --git a/target-xen/qemu-xen.h b/target-xen/qemu-xen.h > index d1910d6..091ae07 100644 > --- a/target-xen/qemu-xen.h > +++ b/target-xen/qemu-xen.h > @@ -27,4 +27,7 @@ int cpu_register_io_memory_fixed(int io_index, > CPUWriteMemoryFunc * const *mem_write, > void *opaque); > > +/* target-xen/helper.c */ > +void xen_main_loop_prepare(void); > + > #endif /*QEMU_XEN_H*/ > diff --git a/target-xen/xenstore.c b/target-xen/xenstore.c > index 9f2e1ea..6eb6a30 100644 > --- a/target-xen/xenstore.c > +++ b/target-xen/xenstore.c > @@ -13,6 +13,60 @@ static void xenstore_process_event(void *opaque) > free(vec); > } > > +static const char *xenstore_get_guest_uuid(void) > +{ > + static char *already_computed = NULL; > + > + char *domain_path = NULL, *vm_path = NULL, *vm_value = NULL, *p = NULL; > + unsigned int len; > + > + if (already_computed) > + return already_computed; > + > + if (xen_xc == NULL) > + return NULL; > + > + domain_path = xs_get_domain_path(xenstore, xen_domid); > + if (domain_path == NULL) { > + fprintf(stderr, "xs_get_domain_path() error. domid %d.\n", xen_domid); > + goto out; > + } > + > + if (asprintf(&vm_path, "%s/vm", domain_path) == -1) { > + fprintf(stderr, "xenstore_get_guest_uuid(): out of memory.\n"); > + goto out; > + } > + vm_value = xs_read(xenstore, XBT_NULL, vm_path,&len); > + if (vm_value == NULL) { > + fprintf(stderr, "xs_read(): uuid get error. %s.\n", vm_path); > + goto out; > + } > + > + if (strtok(vm_value, "/") == NULL) { > + fprintf(stderr, "failed to parse guest uuid\n"); > + goto out; > + } > + p = strtok(NULL, "/"); > + if (p == NULL) { > + fprintf(stderr, "failed to parse guest uuid\n"); > + goto out; > + } > + > + if (asprintf(&already_computed, "%s", p) == -1) { > + fprintf(stderr, "xenstore_get_guest_uuid(): out of memory.\n"); > + goto out; > + } > + > + fprintf(stderr, "Guest uuid = %s\n", already_computed); > + > +out: > + free(domain_path); > + free(vm_path); > + free(vm_value); > + > + return already_computed; > +} > + > int xen_dm_init(void) > { > xenstore = xs_daemon_open(); > @@ -29,6 +83,7 @@ int xen_dm_init(void) > xen_be_printf(NULL, 0, "can't open xen interface\n"); > goto err; > } > + > return 0; > > err: > @@ -38,3 +93,76 @@ err: > > return -1; > } > + > +static char *xenstore_vm_key_path(int domid, const char *key) { > + const char *uuid; > + char *buf = NULL; > + > + if (xenstore == NULL) > + return NULL; > + > + uuid = xenstore_get_guest_uuid(); > + if (!uuid) > + return NULL; > + > + if (asprintf(&buf, "/vm/%s/%s", uuid, key) == -1) > + return NULL; > + > + return buf; > +} > + > +char *xenstore_vm_read(int domid, const char *key, unsigned int *len) > +{ > + char *path = NULL, *value = NULL; > + > + path = xenstore_vm_key_path(domid, key); > + if (!path) > + return NULL; > + > + value = xs_read(xenstore, XBT_NULL, path, len); > + if (value == NULL) { > + fprintf(stderr, "xs_read(%s): read error\n", path); > + } > + > + free(path); > + return value; > +} > + > +int xenstore_vm_write(int domid, const char *key, const char *value) > +{ > + char *path = NULL; > + int rc = -1; > + > + path = xenstore_vm_key_path(domid, key); > + if (!path) > + return 0; > + > + rc = xs_write(xenstore, XBT_NULL, path, value, strlen(value)); > + if (rc == 0) { > + fprintf(stderr, "xs_write(%s, %s): write error\n", path, key); > + } > + > + free(path); > + return rc; > +} > + > +void xenstore_record_dm(const char *subpath, const char *state) > +{ > + char *path = NULL; > + > + if (asprintf(&path, > + "/local/domain/0/device-model/%u/%s", xen_domid, subpath) == -1) { > + fprintf(stderr, "out of memory recording dm\n"); > + goto out; > + } > + if (!xs_write(xenstore, XBT_NULL, path, state, strlen(state))) > + fprintf(stderr, "error recording dm\n"); > + > +out: > + free(path); > +} > + > +void xenstore_record_dm_state(const char *state) > +{ > + xenstore_record_dm("state", state); > +} > diff --git a/target-xen/xenstore.h b/target-xen/xenstore.h > index 90baf79..c8144ea 100644 > --- a/target-xen/xenstore.h > +++ b/target-xen/xenstore.h > @@ -3,4 +3,10 @@ > > int xen_dm_init(void); > > +char *xenstore_vm_read(int domid, const char *key, unsigned int *len); > +int xenstore_vm_write(int domid, const char *key, const char *value); > + > +void xenstore_record_dm(const char *subpath, const char *state); > +void xenstore_record_dm_state(const char *state); > + > #endif /* !XENSTORE_H_ */ > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anthony Liguori Subject: Re: [PATCH 08/15] xen: Read and write the state of the VM in xenstore Date: Fri, 13 Aug 2010 13:53:00 -0500 Message-ID: <4C65948C.8030707@codemonkey.ws> References: <1281622202-3453-8-git-send-email-stefano.stabellini@eu.citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1281622202-3453-8-git-send-email-stefano.stabellini@eu.citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: stefano.stabellini@eu.citrix.com Cc: Anthony.Perard@citrix.com, xen-devel@lists.xensource.com, qemu-devel@nongnu.org List-Id: xen-devel@lists.xenproject.org On 08/12/2010 09:09 AM, stefano.stabellini@eu.citrix.com wrote: > From: Anthony PERARD > > Introduce functions to read and write the state of the VM in xenstore. > This basically creates a new management interface for QEMU via the xenstore. Our management interface is QMP. If you want to maintain compatibility, you'll need to write a QMP -> xenstore daemon that maps events appropriately. Regards, Anthony Liguori > Signed-off-by: Anthony PERARD > Signed-off-by: Stefano Stabellini > --- > hw/xen_machine_fv.c | 9 ++++ > target-xen/helper.c | 7 +++ > target-xen/qemu-xen.h | 3 + > target-xen/xenstore.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++ > target-xen/xenstore.h | 6 ++ > 5 files changed, 153 insertions(+), 0 deletions(-) > > diff --git a/hw/xen_machine_fv.c b/hw/xen_machine_fv.c > index ec826e7..a6e778a 100644 > --- a/hw/xen_machine_fv.c > +++ b/hw/xen_machine_fv.c > @@ -36,10 +36,17 @@ > #include "xen_backend.h" > #include "xenstore.h" > #include "xen_platform.h" > +#include "qemu-xen.h" > #include "xen/hvm/hvm_info_table.h" > > #define MAX_IDE_BUS 2 > > +static void xen_vm_change_state_handler(void *opaque, int running, int reason) > +{ > + if (running) > + xen_main_loop_prepare(); > +} > + > static void xen_init_fv(ram_addr_t ram_size, > const char *boot_device, > const char *kernel_filename, > @@ -150,6 +157,8 @@ static void xen_init_fv(ram_addr_t ram_size, > } > > pc_pci_device_init(pci_bus); > + > + qemu_add_vm_change_state_handler(xen_vm_change_state_handler, NULL); > } > > static QEMUMachine xenfv_machine = { > diff --git a/target-xen/helper.c b/target-xen/helper.c > index d588e64..8cb7771 100644 > --- a/target-xen/helper.c > +++ b/target-xen/helper.c > @@ -19,6 +19,8 @@ > */ > > #include "cpu.h" > +#include "qemu-xen.h" > +#include "xenstore.h" > > CPUXenState *cpu_xen_init(const char *cpu_model) > { > @@ -67,3 +69,8 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) > { > return addr; > } > + > +void xen_main_loop_prepare(void) > +{ > + xenstore_record_dm_state("running"); > +} > diff --git a/target-xen/qemu-xen.h b/target-xen/qemu-xen.h > index d1910d6..091ae07 100644 > --- a/target-xen/qemu-xen.h > +++ b/target-xen/qemu-xen.h > @@ -27,4 +27,7 @@ int cpu_register_io_memory_fixed(int io_index, > CPUWriteMemoryFunc * const *mem_write, > void *opaque); > > +/* target-xen/helper.c */ > +void xen_main_loop_prepare(void); > + > #endif /*QEMU_XEN_H*/ > diff --git a/target-xen/xenstore.c b/target-xen/xenstore.c > index 9f2e1ea..6eb6a30 100644 > --- a/target-xen/xenstore.c > +++ b/target-xen/xenstore.c > @@ -13,6 +13,60 @@ static void xenstore_process_event(void *opaque) > free(vec); > } > > +static const char *xenstore_get_guest_uuid(void) > +{ > + static char *already_computed = NULL; > + > + char *domain_path = NULL, *vm_path = NULL, *vm_value = NULL, *p = NULL; > + unsigned int len; > + > + if (already_computed) > + return already_computed; > + > + if (xen_xc == NULL) > + return NULL; > + > + domain_path = xs_get_domain_path(xenstore, xen_domid); > + if (domain_path == NULL) { > + fprintf(stderr, "xs_get_domain_path() error. domid %d.\n", xen_domid); > + goto out; > + } > + > + if (asprintf(&vm_path, "%s/vm", domain_path) == -1) { > + fprintf(stderr, "xenstore_get_guest_uuid(): out of memory.\n"); > + goto out; > + } > + vm_value = xs_read(xenstore, XBT_NULL, vm_path,&len); > + if (vm_value == NULL) { > + fprintf(stderr, "xs_read(): uuid get error. %s.\n", vm_path); > + goto out; > + } > + > + if (strtok(vm_value, "/") == NULL) { > + fprintf(stderr, "failed to parse guest uuid\n"); > + goto out; > + } > + p = strtok(NULL, "/"); > + if (p == NULL) { > + fprintf(stderr, "failed to parse guest uuid\n"); > + goto out; > + } > + > + if (asprintf(&already_computed, "%s", p) == -1) { > + fprintf(stderr, "xenstore_get_guest_uuid(): out of memory.\n"); > + goto out; > + } > + > + fprintf(stderr, "Guest uuid = %s\n", already_computed); > + > +out: > + free(domain_path); > + free(vm_path); > + free(vm_value); > + > + return already_computed; > +} > + > int xen_dm_init(void) > { > xenstore = xs_daemon_open(); > @@ -29,6 +83,7 @@ int xen_dm_init(void) > xen_be_printf(NULL, 0, "can't open xen interface\n"); > goto err; > } > + > return 0; > > err: > @@ -38,3 +93,76 @@ err: > > return -1; > } > + > +static char *xenstore_vm_key_path(int domid, const char *key) { > + const char *uuid; > + char *buf = NULL; > + > + if (xenstore == NULL) > + return NULL; > + > + uuid = xenstore_get_guest_uuid(); > + if (!uuid) > + return NULL; > + > + if (asprintf(&buf, "/vm/%s/%s", uuid, key) == -1) > + return NULL; > + > + return buf; > +} > + > +char *xenstore_vm_read(int domid, const char *key, unsigned int *len) > +{ > + char *path = NULL, *value = NULL; > + > + path = xenstore_vm_key_path(domid, key); > + if (!path) > + return NULL; > + > + value = xs_read(xenstore, XBT_NULL, path, len); > + if (value == NULL) { > + fprintf(stderr, "xs_read(%s): read error\n", path); > + } > + > + free(path); > + return value; > +} > + > +int xenstore_vm_write(int domid, const char *key, const char *value) > +{ > + char *path = NULL; > + int rc = -1; > + > + path = xenstore_vm_key_path(domid, key); > + if (!path) > + return 0; > + > + rc = xs_write(xenstore, XBT_NULL, path, value, strlen(value)); > + if (rc == 0) { > + fprintf(stderr, "xs_write(%s, %s): write error\n", path, key); > + } > + > + free(path); > + return rc; > +} > + > +void xenstore_record_dm(const char *subpath, const char *state) > +{ > + char *path = NULL; > + > + if (asprintf(&path, > + "/local/domain/0/device-model/%u/%s", xen_domid, subpath) == -1) { > + fprintf(stderr, "out of memory recording dm\n"); > + goto out; > + } > + if (!xs_write(xenstore, XBT_NULL, path, state, strlen(state))) > + fprintf(stderr, "error recording dm\n"); > + > +out: > + free(path); > +} > + > +void xenstore_record_dm_state(const char *state) > +{ > + xenstore_record_dm("state", state); > +} > diff --git a/target-xen/xenstore.h b/target-xen/xenstore.h > index 90baf79..c8144ea 100644 > --- a/target-xen/xenstore.h > +++ b/target-xen/xenstore.h > @@ -3,4 +3,10 @@ > > int xen_dm_init(void); > > +char *xenstore_vm_read(int domid, const char *key, unsigned int *len); > +int xenstore_vm_write(int domid, const char *key, const char *value); > + > +void xenstore_record_dm(const char *subpath, const char *state); > +void xenstore_record_dm_state(const char *state); > + > #endif /* !XENSTORE_H_ */ >