From: Jean Guyader Date: Mon, 15 Jun 2009 13:51:20 +0000 (+0100) Subject: Backport a patch from xenserver. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=a73840f13ce18c1534cf5f76baf2434b918627b8;p=xenclient%2Fioemu-pq.git Backport a patch from xenserver. xenvm send a SIGUSR1 to save the qemu context. --- diff --git a/master/series b/master/series index a7b238d..39cd30b 100644 --- a/master/series +++ b/master/series @@ -2,6 +2,7 @@ ioemu-compil add-config-audio xenstore-watch-callbacks dm-ready +suspend-by-signal battery-management oem-features diff --git a/master/suspend-by-signal b/master/suspend-by-signal new file mode 100644 index 0000000..632a006 --- /dev/null +++ b/master/suspend-by-signal @@ -0,0 +1,92 @@ +diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c +index 969241f..681bd86 100644 +--- a/i386-dm/helper2.c ++++ b/i386-dm/helper2.c +@@ -566,7 +566,7 @@ int main_loop(void) + qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL); + + while (1) { +- while (!(vm_running && xen_pause_requested)) ++ while (!(vm_running && (xen_pause_requested || suspend_requested))) + /* Wait up to 10 msec. */ + main_loop_wait(10); + +@@ -582,6 +582,9 @@ int main_loop(void) + do_savevm(qemu_file); + free(qemu_file); + ++ if (suspend_requested) ++ return 0; ++ + xenstore_record_dm_state("paused"); + + /* Wait to be allowed to continue */ +diff --git a/qemu-xen.h b/qemu-xen.h +index c45bf9f..395b7c9 100644 +--- a/qemu-xen.h ++++ b/qemu-xen.h +@@ -34,6 +34,8 @@ void qemu_invalidate_map_cache(void); + #define mapcache_lock() ((void)0) + #define mapcache_unlock() ((void)0) + ++extern int suspend_requested; ++ + /* helper2.c */ + extern long time_offset; + void timeoffset_get(void); +diff --git a/vl.c b/vl.c +index b273c75..5c437e0 100644 +--- a/vl.c ++++ b/vl.c +@@ -3369,6 +3369,15 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) + + #endif /* !CONFIG_DM */ + ++void suspend(int sig) ++{ ++ fprintf(stderr, "suspend sig handler called with requested=%d!\n", ++ suspend_requested); ++ if (sig != SIGUSR1) ++ fprintf(stderr, "suspend signal dismatch, get sig=%d!\n", sig); ++ suspend_requested = 1; ++} ++ + void qemu_service_io(void) + { + CPUState *env = cpu_single_env; +@@ -3611,6 +3620,7 @@ static QEMUResetEntry *first_reset_entry; + static int reset_requested; + static int shutdown_requested; + static int powerdown_requested; ++int suspend_requested = 0; + + int qemu_shutdown_requested(void) + { +@@ -6049,6 +6059,27 @@ int main(int argc, char **argv, char **envp) + + xenstore_dm_finished_startup(); + ++#ifndef CONFIG_STUBDOM ++ /* register signal for the suspend request when save */ ++ { ++ struct sigaction act; ++ sigset_t set; ++ act.sa_handler = suspend; ++ act.sa_flags = SA_RESTART; ++ sigemptyset(&act.sa_mask); ++ ++ sigaction(SIGUSR1, &act, NULL); ++ ++ /* control panel mask some signals when spawn qemu, need unmask here*/ ++ sigemptyset(&set); ++ sigaddset(&set, SIGUSR1); ++ sigaddset(&set, SIGTERM); ++ if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) ++ fprintf(stderr, "unblock signal fail, possible issue for HVM save!\n"); ++ ++ } ++#endif ++ + main_loop(); + quit_timers(); + net_cleanup();