From 110f49efa32793aaa17d565025c33b71c40eaa5a Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Mon, 25 Jul 2011 14:35:51 +0200
Subject: [PATCH] Reopen daemon's stdio on SIGHUP

Before this patch daemons would continue to refer to an old logfile for
their standard I/O if they had been asked to reopen the log (SIGHUP).

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 lib/daemon.py        | 18 +++++++++++-------
 lib/utils/process.py | 14 ++++++++++----
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/lib/daemon.py b/lib/daemon.py
index 974c8d87c..7f5e9efcf 100644
--- a/lib/daemon.py
+++ b/lib/daemon.py
@@ -544,15 +544,17 @@ def _BeautifyError(err):
     return "%s" % str(err)
 
 
-def _HandleSigHup(reopen_cb, signum, frame): # pylint: disable-msg=W0613
+def _HandleSigHup(reopen_fn, signum, frame): # pylint: disable-msg=W0613
   """Handler for SIGHUP.
 
-  @param reopen_cb: Callback function for reopening log files
+  @param reopen_fn: List of callback functions for reopening log files
 
   """
-  assert callable(reopen_cb)
   logging.info("Reopening log files after receiving SIGHUP")
-  reopen_cb()
+
+  for fn in reopen_fn:
+    if fn:
+      fn()
 
 
 def GenericMain(daemon_name, optionparser,
@@ -668,9 +670,10 @@ def GenericMain(daemon_name, optionparser,
 
   if options.fork:
     utils.CloseFDs()
-    wpipe = utils.Daemonize(logfile=constants.DAEMONS_LOGFILES[daemon_name])
+    (wpipe, stdio_reopen_fn) = \
+      utils.Daemonize(logfile=constants.DAEMONS_LOGFILES[daemon_name])
   else:
-    wpipe = None
+    (wpipe, stdio_reopen_fn) = (None, None)
 
   log_reopen_fn = \
     utils.SetupLogging(constants.DAEMONS_LOGFILES[daemon_name], daemon_name,
@@ -681,7 +684,8 @@ def GenericMain(daemon_name, optionparser,
                        console_logging=console_logging)
 
   # Reopen log file(s) on SIGHUP
-  signal.signal(signal.SIGHUP, compat.partial(_HandleSigHup, log_reopen_fn))
+  signal.signal(signal.SIGHUP,
+                compat.partial(_HandleSigHup, [log_reopen_fn, stdio_reopen_fn]))
 
   utils.WritePidFile(utils.DaemonPidFileName(daemon_name))
   try:
diff --git a/lib/utils/process.py b/lib/utils/process.py
index 2e015de7f..9047429dd 100644
--- a/lib/utils/process.py
+++ b/lib/utils/process.py
@@ -36,6 +36,7 @@ from cStringIO import StringIO
 
 from ganeti import errors
 from ganeti import constants
+from ganeti import compat
 
 from ganeti.utils import retry as utils_retry
 from ganeti.utils import wrapper as utils_wrapper
@@ -835,8 +836,9 @@ def Daemonize(logfile):
 
   @type logfile: str
   @param logfile: the logfile to which we should redirect stdout/stderr
-  @rtype: int
-  @return: the value zero
+  @rtype: tuple; (int, callable)
+  @return: File descriptor of pipe(2) which must be closed to notify parent
+    process and a callable to reopen log files
 
   """
   # pylint: disable-msg=W0212
@@ -872,8 +874,12 @@ def Daemonize(logfile):
       rcode = 0
     os._exit(rcode) # Exit parent of the first child.
 
-  SetupDaemonFDs(logfile, None)
-  return wpipe
+  reopen_fn = compat.partial(SetupDaemonFDs, logfile, None)
+
+  # Open logs for the first time
+  reopen_fn()
+
+  return (wpipe, reopen_fn)
 
 
 def KillProcess(pid, signal_=signal.SIGTERM, timeout=30,
-- 
GitLab