From patchwork Thu Aug 12 14:09:55 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 61609 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 99C5AB70B8 for ; Fri, 13 Aug 2010 00:24:37 +1000 (EST) Received: from localhost ([127.0.0.1]:60446 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OjYhu-0000Xz-Am for incoming@patchwork.ozlabs.org; Thu, 12 Aug 2010 10:24:34 -0400 Received: from [140.186.70.92] (port=59966 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OjYUc-00034t-SR for qemu-devel@nongnu.org; Thu, 12 Aug 2010 10:11:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OjYU6-0000zS-22 for qemu-devel@nongnu.org; Thu, 12 Aug 2010 10:10:20 -0400 Received: from smtp02.citrix.com ([66.165.176.63]:51011) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OjYU5-0000vb-Nm for qemu-devel@nongnu.org; Thu, 12 Aug 2010 10:10:18 -0400 X-IronPort-AV: E=Sophos;i="4.55,358,1278302400"; d="scan'208";a="109436866" Received: from ftlpexchmx01.citrite.net ([10.9.154.126]) by FTLPIPO02.CITRIX.COM with ESMTP; 12 Aug 2010 10:10:17 -0400 Received: from smtp01.ad.xensource.com ([10.219.128.104]) by FTLPEXCHMX01.citrite.net with Microsoft SMTPSVC(6.0.3790.4675); Thu, 12 Aug 2010 10:10:17 -0400 Received: from localhost.localdomain (kaball.uk.xensource.com [10.80.2.59]) by smtp01.ad.xensource.com (8.13.1/8.13.1) with ESMTP id o7CEA014020767; Thu, 12 Aug 2010 07:10:15 -0700 From: stefano.stabellini@eu.citrix.com To: qemu-devel@nongnu.org Date: Thu, 12 Aug 2010 15:09:55 +0100 Message-Id: <1281622202-3453-8-git-send-email-stefano.stabellini@eu.citrix.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: References: X-OriginalArrivalTime: 12 Aug 2010 14:10:17.0833 (UTC) FILETIME=[178BC590:01CB3A28] X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Anthony.Perard@citrix.com, Anthony PERARD , xen-devel@lists.xensource.com, Stefano Stabellini Subject: [Qemu-devel] [PATCH 08/15] xen: Read and write the state of the VM in xenstore X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Anthony PERARD Introduce functions to read and write the state of the VM in xenstore. 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_ */