Revision 80adbbe1
b/src/Ganeti/Daemon.hs | ||
---|---|---|
45 | 45 |
, genericMain |
46 | 46 |
) where |
47 | 47 |
|
48 |
import Control.Concurrent |
|
48 | 49 |
import Control.Exception |
49 | 50 |
import Control.Monad |
50 | 51 |
import Data.Maybe (fromMaybe, listToMaybe) |
... | ... | |
53 | 54 |
import Network.BSD (getHostName) |
54 | 55 |
import qualified Network.Socket as Socket |
55 | 56 |
import System.Console.GetOpt |
57 |
import System.Directory |
|
56 | 58 |
import System.Exit |
57 | 59 |
import System.Environment |
58 | 60 |
import System.IO |
... | ... | |
235 | 237 |
_ <- createSession |
236 | 238 |
return () |
237 | 239 |
|
240 |
-- | Cleanup function, performing all the operations that need to be done prior |
|
241 |
-- to shutting down a daemon. |
|
242 |
finalCleanup :: FilePath -> IO () |
|
243 |
finalCleanup = removeFile |
|
244 |
|
|
245 |
-- | Signal handler for the termination signal. |
|
246 |
handleSigTerm :: ThreadId -> IO () |
|
247 |
handleSigTerm mainTID = |
|
248 |
-- Throw termination exception to the main thread, so that the daemon is |
|
249 |
-- actually stopped in the proper way, executing all the functions waiting on |
|
250 |
-- "finally" statement. |
|
251 |
Control.Exception.throwTo mainTID ExitSuccess |
|
252 |
|
|
238 | 253 |
-- | Signal handler for reopening log files. |
239 | 254 |
handleSigHup :: FilePath -> IO () |
240 | 255 |
handleSigHup path = do |
... | ... | |
418 | 433 |
-> SyslogUsage -- ^ Syslog mode |
419 | 434 |
-> a -- ^ Check results |
420 | 435 |
-> PrepFn a b -- ^ Prepare function |
421 |
-> IO b
|
|
436 |
-> IO (FilePath, b)
|
|
422 | 437 |
fullPrep daemon opts syslog check_result prep_fn = do |
423 | 438 |
logfile <- if optDaemonize opts |
424 | 439 |
then return Nothing |
... | ... | |
429 | 444 |
_ <- describeError "writing PID file; already locked?" |
430 | 445 |
Nothing (Just pidfile) $ writePidFile pidfile |
431 | 446 |
logNotice $ dname ++ " daemon startup" |
432 |
prep_fn opts check_result |
|
447 |
prep_res <- prep_fn opts check_result |
|
448 |
tid <- myThreadId |
|
449 |
_ <- installHandler sigTERM (Catch $ handleSigTerm tid) Nothing |
|
450 |
return (pidfile, prep_res) |
|
433 | 451 |
|
434 | 452 |
-- | Inner daemon function. |
435 | 453 |
-- |
... | ... | |
443 | 461 |
-> Maybe Fd -- ^ Error reporting function |
444 | 462 |
-> IO () |
445 | 463 |
innerMain daemon opts syslog check_result prep_fn exec_fn fd = do |
446 |
prep_result <- fullPrep daemon opts syslog check_result prep_fn
|
|
464 |
(pidFile, prep_result) <- fullPrep daemon opts syslog check_result prep_fn
|
|
447 | 465 |
`Control.Exception.catch` handlePrepErr True fd |
448 | 466 |
-- no error reported, we should now close the fd |
449 | 467 |
maybeCloseFd fd |
450 |
exec_fn opts check_result prep_result
|
|
468 |
finally (exec_fn opts check_result prep_result) (finalCleanup pidFile)
|
|
451 | 469 |
|
452 | 470 |
-- | Daemon prepare error handling function. |
453 | 471 |
handlePrepErr :: Bool -> Maybe Fd -> IOError -> IO a |
Also available in: Unified diff