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

[Xen-devel] [RFC][PATCH 12/13] Kemari: use signal to save qemu state for Kemari



This patch implements signal handler for saving QEMU status quickly.  It also
includes a feature borrowed from KVM-17, which saves QEMU status quickly
without repositioning file offset by fseek.

Signed-off-by: Yoshisato Yanagisawa <yanagisawa.yoshisato@xxxxxxxxxxxxx>
Signed-off-by: Yoshi Tamura <tamura.yoshiaki@xxxxxxxxxxxxx>
---
 vl.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 93 insertions(+), 1 deletion(-)

commit 3050ae2f8fffc2238a9e763b2534f3778b1bb372
Author: Yoshisato YANAGISAWA <yanagisawa@xxxxxxxx>
Date:   Thu Feb 26 14:25:40 2009 +0900

    Add features required for Kemari.

diff --git a/vl.c b/vl.c
index 4d62006..8ef5168 100644
--- a/vl.c
+++ b/vl.c
@@ -258,6 +258,7 @@ struct drive_opt {
 static CPUState *cur_cpu;
 static CPUState *next_cpu;
 static int event_pending = 1;
+volatile int kemari_enabled = 0;

 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)

@@ -6152,6 +6153,36 @@ int register_savevm(const char *idstr,

 #define QEMU_VM_FILE_MAGIC   0x5145564d
 #define QEMU_VM_FILE_VERSION 0x00000002
+#define QEMU_VM_FILE_KEMARI  0x80000000
+
+static int qemu_savevm_state_kemari(QEMUFile *f)
+{
+    SaveStateEntry *se;
+    int len, ret;
+
+    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
+    qemu_put_be32(f, (QEMU_VM_FILE_VERSION | QEMU_VM_FILE_KEMARI));
+
+    for(se = first_se; se != NULL; se = se->next) {
+        /* ignore vga because it is too large. */
+        if (strstr(se->idstr, "vga"))
+            continue;
+
+        len = strlen(se->idstr);
+
+        qemu_put_byte(f, len);
+        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
+        qemu_put_be32(f, se->instance_id);
+        qemu_put_be32(f, se->version_id);
+
+        se->save_state(f, se->opaque);
+    }
+
+    qemu_put_byte(f, 0);
+
+    ret = 0;
+    return ret;
+}

 static int qemu_savevm_state(QEMUFile *f)
 {
@@ -6210,6 +6241,40 @@ static SaveStateEntry *find_se(const char *idstr, int 
instance_id)
     return NULL;
 }

+static int qemu_loadvm_state_kemari(QEMUFile *f)
+{
+    SaveStateEntry *se;
+    int len, ret, instance_id, version_id;
+    unsigned int v;
+    char idstr[256];
+
+    fprintf(stderr, "qemu: loading VM in Kemari mode.\n");
+    for (;;) {
+        len = qemu_get_byte(f);
+        if (len == 0)
+            break;
+        qemu_get_buffer(f, (uint8_t *)idstr, len);
+        idstr[len] = '\0';
+        instance_id = qemu_get_be32(f);
+        version_id = qemu_get_be32(f);
+        se = find_se(idstr, instance_id);
+        if (!se) {
+            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not 
present in current VM\n",
+                    instance_id, idstr);
+        } else {
+            ret = se->load_state(f, se->opaque, version_id);
+            if (ret < 0) {
+                fprintf(stderr, "qemu: warning: error while loading state for 
instance 0x%x of device '%s'\n",
+                        instance_id, idstr);
+            }
+        }
+    }
+    ret = 0;
+
+ the_end:
+    return ret;
+}
+
 static int qemu_loadvm_state(QEMUFile *f)
 {
     SaveStateEntry *se;
@@ -6223,6 +6288,10 @@ static int qemu_loadvm_state(QEMUFile *f)
         goto fail;
     v = qemu_get_be32(f);
     if (v != QEMU_VM_FILE_VERSION) {
+        if (v == (QEMU_VM_FILE_VERSION | QEMU_VM_FILE_KEMARI)) {
+            ret = qemu_loadvm_state_kemari(f);
+            goto the_end;
+        }
     fail:
         ret = -1;
         goto the_end;
@@ -6386,7 +6455,10 @@ void do_savevm(const char *name)
         term_printf("Could not open VM state file\n");
         goto the_end;
     }
-    ret = qemu_savevm_state(f);
+    if (kemari_enabled)
+        ret = qemu_savevm_state_kemari(f);
+    else
+        ret = qemu_savevm_state(f);
     sn->vm_state_size = qemu_ftell(f);
     qemu_fclose(f);
     if (ret < 0) {
@@ -7893,6 +7965,15 @@ static BOOL WINAPI qemu_ctrl_handler(DWORD type)
 }
 #endif

+#ifndef _WIN32
+void xenstore_process_logdirty_event(void);
+static void kemari_handler(int dummy)
+{
+    kemari_enabled = 1; /* QEMU will run in kemari mode */
+    xenstore_process_logdirty_event();
+}
+#endif /* !_WIN32 */
+
 #define MAX_NET_CLIENTS 32

 int main(int argc, char **argv)
@@ -7969,6 +8050,17 @@ int main(int argc, char **argv)
         act.sa_handler = SIG_IGN;
         sigaction(SIGPIPE, &act, NULL);
     }
+    {
+        struct sigaction act;
+        sigfillset(&act.sa_mask);
+        act.sa_handler = kemari_handler;
+#ifdef  CONFIG_DM
+        act.sa_flags = SA_RESTART;
+#else /* !CONFIG_DM */
+        act.sa_flags = 0;
+#endif /* CONFIG_DM */
+        sigaction(SIGUSR1, &act, NULL);
+    }
 #else
     SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
     /* Note: cpu_interrupt() is currently not SMP safe, so we force




_______________________________________________
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®.