[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] Re: [PATCH 08/15] xen: Read and write the state of the VM in xenstore



On 08/12/2010 09:09 AM, stefano.stabellini@xxxxxxxxxxxxx wrote:
From: Anthony PERARD<anthony.perard@xxxxxxxxxx>

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<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 |  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_ */


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.