Merge branch 'stable-2.5' into devel-2.5
[ganeti-local] / lib / daemon.py
index c26a176..3144727 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2008, 2010 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2010, 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@ from ganeti import errors
 from ganeti import netutils
 from ganeti import ssconf
 from ganeti import runtime
+from ganeti import compat
 
 
 class SchedulerBreakout(Exception):
@@ -434,6 +435,9 @@ class Mainloop(object):
     self._signal_wait = []
     self.scheduler = AsyncoreScheduler(time.time)
 
+    # Resolve uid/gids used
+    runtime.GetEnts()
+
   @utils.SignalHandled([signal.SIGCHLD])
   @utils.SignalHandled([signal.SIGTERM])
   @utils.SignalHandled([signal.SIGINT])
@@ -448,6 +452,7 @@ class Mainloop(object):
            len(signal_handlers) > 0, \
            "Broken SignalHandled decorator"
     running = True
+
     # Start actual main loop
     while running:
       if not self.scheduler.empty():
@@ -534,11 +539,24 @@ def _BeautifyError(err):
                                             err.errno)
     else:
       return str(err)
-  except Exception: # pylint: disable-msg=W0703
+  except Exception: # pylint: disable=W0703
     logging.exception("Error while handling existing error %s", err)
     return "%s" % str(err)
 
 
+def _HandleSigHup(reopen_fn, signum, frame): # pylint: disable=W0613
+  """Handler for SIGHUP.
+
+  @param reopen_fn: List of callback functions for reopening log files
+
+  """
+  logging.info("Reopening log files after receiving SIGHUP")
+
+  for fn in reopen_fn:
+    if fn:
+      fn()
+
+
 def GenericMain(daemon_name, optionparser,
                 check_fn, prepare_fn, exec_fn,
                 multithreaded=False, console_logging=False,
@@ -652,25 +670,36 @@ 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,
+                       debug=options.debug,
+                       stderr_logging=not options.fork,
+                       multithreaded=multithreaded,
+                       syslog=options.syslog,
+                       console_logging=console_logging)
+
+  # Reopen log file(s) on SIGHUP
+  signal.signal(signal.SIGHUP,
+                compat.partial(_HandleSigHup, [log_reopen_fn, stdio_reopen_fn]))
+
+  try:
+    utils.WritePidFile(utils.DaemonPidFileName(daemon_name))
+  except errors.PidFileLockError, err:
+    print >> sys.stderr, "Error while locking PID file:\n%s" % err
+    sys.exit(constants.EXIT_FAILURE)
 
-  utils.WritePidFile(utils.DaemonPidFileName(daemon_name))
   try:
     try:
-      utils.SetupLogging(logfile=constants.DAEMONS_LOGFILES[daemon_name],
-                         debug=options.debug,
-                         stderr_logging=not options.fork,
-                         multithreaded=multithreaded,
-                         program=daemon_name,
-                         syslog=options.syslog,
-                         console_logging=console_logging)
+      logging.info("%s daemon startup", daemon_name)
       if callable(prepare_fn):
         prep_results = prepare_fn(options, args)
       else:
         prep_results = None
-      logging.info("%s daemon startup", daemon_name)
     except Exception, err:
       utils.WriteErrorToFD(wpipe, _BeautifyError(err))
       raise