[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 08/15] xen: Read and write the state of the VM in xenstore
From: Anthony PERARD <anthony.perard@xxxxxxxxxx> Introduce functions to read and write the state of the VM in xenstore. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> --- hw/xen_machine_fv.c | 9 ++++ target-xen/helper.c | 7 +++ target-xen/qemu-xen.h | 3 + target-xen/xenstore.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++ target-xen/xenstore.h | 6 ++ 5 files changed, 152 insertions(+), 0 deletions(-) diff --git a/hw/xen_machine_fv.c b/hw/xen_machine_fv.c index 12a7723..f0c3c03 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, @@ -149,6 +156,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 f8512c8..b6b722b 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) { @@ -61,3 +63,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 331b25f..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(); @@ -39,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_ */ -- 1.7.0.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |