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
|