Commit 1a865afe authored by Iustin Pop's avatar Iustin Pop
Browse files

Properly log errors when setting up daemon FDs



While writing the pipe-based reporting and trying various ways to
break the startup, I fought for a while trying to understand why error
reporting was _different_ when running the daemon as a user (with no
rights). It turns out that setupDaemonFDs wants to open the log file
in append mode way before, so we are not protected by the 'prepare'
phase.

This patch explicitly runs the 'setupDaemonFDs' function under the
same handler as the prepare phase, with the only change that here we
instruct handlePrepErr to not log the message via log*, since logging
is not yet set up.
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarMichael Hanselmann <hansmi@google.com>
parent 8ee2994a
......@@ -309,12 +309,14 @@ daemonize logfile action = do
_ <- forkProcess $ do
-- in the child
closeFd rpipe
let wpipe' = Just wpipe
setupDaemonEnv "/" (unionFileModes groupModes otherModes)
setupDaemonFDs $ Just logfile
setupDaemonFDs (Just logfile) `Control.Exception.catch`
handlePrepErr False wpipe'
_ <- installHandler lostConnection (Catch (handleSigHup logfile)) Nothing
-- second fork, launches the actual child code; standard
-- double-fork technique
_ <- forkProcess (action (Just wpipe))
_ <- forkProcess (action wpipe')
exitImmediately ExitSuccess
closeFd wpipe
hndl <- fdToHandle rpipe
......@@ -397,21 +399,21 @@ innerMain :: GanetiDaemon -- ^ The daemon we're running
-> IO ()
innerMain daemon opts syslog check_result prep_fn exec_fn fd = do
prep_result <- fullPrep daemon opts syslog check_result prep_fn
`Control.Exception.catch` handlePrepErr fd
`Control.Exception.catch` handlePrepErr True fd
-- no error reported, we should now close the fd
maybeCloseFd fd
exec_fn opts check_result prep_result
-- | Daemon prepare error handling function.
handlePrepErr :: Maybe Fd -> IOError -> IO a
handlePrepErr fd err = do
handlePrepErr :: Bool -> Maybe Fd -> IOError -> IO a
handlePrepErr logging_setup fd err = do
let msg = show err
case fd of
-- explicitly writing to the fd directly, since when forking it's
-- better (safer) than trying to convert this into a full handle
Just fd' -> fdWrite fd' msg >> return ()
Nothing -> hPutStrLn stderr (daemonStartupErr msg)
logError msg
when logging_setup $ logError msg
exitWith $ ExitFailure 1
-- | Close a file descriptor.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment