From f59dce3e94f67493b7767dd9e1d2924094692bfa Mon Sep 17 00:00:00 2001
From: Guido Trotter <ultrotter@google.com>
Date: Fri, 21 May 2010 11:24:54 +0100
Subject: [PATCH] Mainloop: handle SIGINT as well (and terminate)

This is needed if daemons are in the foreground, and get ctrl+c-ed by
the user. Also add unittests to make sure the correct signals terminate
the mainloop.

Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 lib/daemon.py                  |  3 ++-
 test/ganeti.daemon_unittest.py | 10 ++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/lib/daemon.py b/lib/daemon.py
index c843f0a0f..06cd70c2c 100644
--- a/lib/daemon.py
+++ b/lib/daemon.py
@@ -168,6 +168,7 @@ class Mainloop(object):
 
   @utils.SignalHandled([signal.SIGCHLD])
   @utils.SignalHandled([signal.SIGTERM])
+  @utils.SignalHandled([signal.SIGINT])
   def Run(self, signal_handlers=None):
     """Runs the mainloop.
 
@@ -194,7 +195,7 @@ class Mainloop(object):
         handler = signal_handlers[sig]
         if handler.called:
           self._CallSignalWaiters(sig)
-          running = (sig != signal.SIGTERM)
+          running = sig not in (signal.SIGTERM, signal.SIGINT)
           handler.Clear()
 
   def _CallSignalWaiters(self, signum):
diff --git a/test/ganeti.daemon_unittest.py b/test/ganeti.daemon_unittest.py
index ad5a12852..81912ee18 100755
--- a/test/ganeti.daemon_unittest.py
+++ b/test/ganeti.daemon_unittest.py
@@ -56,6 +56,16 @@ class TestMainloop(testutils.GanetiTestCase):
     self.mainloop.Run() # terminates by _SendSig being scheduled
     self.assertEquals(self.sendsig_events, [signal.SIGTERM])
 
+  def testTerminatingSignals(self):
+    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGCHLD])
+    self.mainloop.scheduler.enter(0.2, 1, self._SendSig, [signal.SIGINT])
+    self.mainloop.Run()
+    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGINT])
+    self.mainloop.scheduler.enter(0.1, 1, self._SendSig, [signal.SIGTERM])
+    self.mainloop.Run()
+    self.assertEquals(self.sendsig_events, [signal.SIGCHLD, signal.SIGINT,
+                                            signal.SIGTERM])
+
   def testSchedulerCancel(self):
     handle = self.mainloop.scheduler.enter(0.1, 1, self._SendSig,
                                            [signal.SIGTERM])
-- 
GitLab