From b3a389fdfc3a1fe19fd7094b0180e97d49c186dd Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 12 Feb 2008 10:57:49 +0000 Subject: device-dm: Use SIGHUP before SIGKILL Make qemu unblock SIGHUP and make sure the default handler is in place. Have the domain killer send SIGHUP to the device-model script, allow the script 10s to clean up, and if still not dead, send SIGKILL. Signed-off-by: Samuel Thibault --- tools/ioemu/vl.c | 6 ++++-- tools/python/xen/xend/image.py | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index 01dfef8555..452bfcc555 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -7928,11 +7928,13 @@ int main(int argc, char **argv) } #endif - /* Unblock SIGTERM, which may have been blocked by the caller */ + /* Unblock SIGTERM and SIGHUP, which may have been blocked by the caller */ + signal(SIGHUP, SIG_DFL); sigemptyset(&set); sigaddset(&set, SIGTERM); + sigaddset(&set, SIGHUP); if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) - fprintf(stderr, "Failed to unblock SIGTERM\n"); + fprintf(stderr, "Failed to unblock SIGTERM and SIGHUP\n"); main_loop(); quit_timers(); diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 4ceb36194f..069cde7dbe 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -335,16 +335,27 @@ class ImageHandler: return if self.pid: try: - os.kill(self.pid, signal.SIGKILL) + os.kill(self.pid, signal.SIGHUP) except OSError, exn: log.exception(exn) try: - os.waitpid(self.pid, 0) + # Try to reap the child every 100ms for 10s. Then SIGKILL it. + for i in xrange(100): + (p, rv) = os.waitpid(self.pid, os.WNOHANG) + if p == self.pid: + break + time.sleep(0.1) + else: + log.warning("DeviceModel %d took more than 10s " + "to terminate: sending SIGKILL" % self.pid) + os.kill(self.pid, signal.SIGKILL) + os.waitpid(self.pid, 0) except OSError, exn: # This is expected if Xend has been restarted within the # life of this domain. In this case, we can kill the process, # but we can't wait for it because it's not our child. - pass + # We just make really sure it's going away (SIGKILL) first. + os.kill(self.pid, signal.SIGKILL) self.pid = None state = xstransact.Remove("/local/domain/0/device-model/%i" % self.vm.getDomid()) -- cgit v1.2.3