From c62df7027e16adcb4f4b2d1f33f17ee61c99bb9b Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Wed, 16 Jan 2013 17:32:00 +0100
Subject: [PATCH] Start confd in notify mode if we can
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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 | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/Ganeti/Confd/Server.hs b/src/Ganeti/Confd/Server.hs
index 29204a4ef..cf0cebb01 100644
--- a/src/Ganeti/Confd/Server.hs
+++ b/src/Ganeti/Confd/Server.hs
@@ -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
-- 
GitLab