@@ -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 = {
@@ -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");
+}
@@ -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*/
@@ -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);
+}
@@ -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_ */