Start confd in notify mode if we can
authorIustin Pop <iustin@google.com>
Wed, 16 Jan 2013 16:32:00 +0000 (17:32 +0100)
committerIustin Pop <iustin@google.com>
Mon, 21 Jan 2013 11:57:50 +0000 (12:57 +0100)
This patch changes the default model—where confd is always started in
polling mode—to a model where if possible we enable inotify mode
before starting any of the background threads.

There are some tricky details here: if we enable inotify, we should
not modify the server state after wards, as inotify events could have
already fired and took ownership; therefore we presume that inotify
will work and set reloadModel=ReloadNotify, and only if we fail to
enable it we change it back to polling mode.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>

src/Ganeti/Confd/Server.hs

index 29204a4..cf0cebb 100644 (file)
@@ -33,7 +33,7 @@ module Ganeti.Confd.Server
 
 import Control.Concurrent
 import Control.Exception
-import Control.Monad (forever, liftM, when)
+import Control.Monad (forever, liftM, when, unless)
 import Data.IORef
 import Data.List
 import qualified Data.Map as M
@@ -112,6 +112,7 @@ initialPoll = ReloadPoll 0
 data ConfigReload = ConfigToDate    -- ^ No need to reload
                   | ConfigReloaded  -- ^ Configuration reloaded
                   | ConfigIOError   -- ^ Error during configuration reload
+                    deriving (Eq)
 
 -- | Unknown entry standard response.
 queryUnknownEntry :: StatusAnswer
@@ -522,19 +523,31 @@ prepMain _ (af_family, bindaddr) = do
 -- | Main function.
 main :: MainFn (S.Family, S.SockAddr) PrepResult
 main _ _ (s, query_data, cref) = do
+  -- Inotify setup
+  inotify <- initINotify
   -- try to load the configuration, if possible
   conf_file <- Path.clusterConfFile
-  (fstat, _) <- safeUpdateConfig conf_file nullFStat cref
+  (fstat, reloaded) <- safeUpdateConfig conf_file nullFStat cref
   ctime <- getCurrentTime
-  statemvar <- newMVar $ ServerState initialPoll ctime fstat
-  hmac <- getClusterHmac
-  -- Inotify setup
-  inotify <- initINotify
+  statemvar <- newMVar $ ServerState ReloadNotify ctime fstat
   let inotiaction = addNotifier inotify conf_file cref statemvar
+  has_inotify <- if reloaded == ConfigReloaded
+                   then inotiaction
+                   else return False
+  if has_inotify
+    then logInfo "Starting up in inotify mode"
+    else do
+      -- inotify was not enabled, we need to update the reload model
+      logInfo "Starting up in polling mode"
+      modifyMVar_ statemvar
+        (\state -> return state { reloadModel = initialPoll })
+  hmac <- getClusterHmac
   -- fork the timeout timer
   _ <- forkIO $ onTimeoutTimer inotiaction conf_file cref statemvar
   -- fork the polling timer
-  _ <- forkIO $ onReloadTimer inotiaction conf_file cref statemvar
+  unless has_inotify $ do
+    _ <- forkIO $ onReloadTimer inotiaction conf_file cref statemvar
+    return ()
   -- launch the queryd listener
   _ <- forkIO $ runQueryD query_data (configReader cref)
   -- and finally enter the responder loop