.. as it needs to be stored and reloaded if WConfd is restarted while
jobs are running.

Signed-off-by: Petr Pudlak <[email protected]>
---
 src/Ganeti/Path.hs                  |  5 +++++
 src/Ganeti/WConfd/Core.hs           |  3 +--
 src/Ganeti/WConfd/DeathDetection.hs |  3 ++-
 src/Ganeti/WConfd/Monad.hs          | 23 ++++++++++++++++++-----
 src/Ganeti/WConfd/Persistent.hs     | 14 +++++++++++++-
 src/Ganeti/WConfd/Server.hs         |  3 +++
 src/Ganeti/WConfd/TempRes.hs        |  4 ++--
 7 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/src/Ganeti/Path.hs b/src/Ganeti/Path.hs
index d6a1252..4638143 100644
--- a/src/Ganeti/Path.hs
+++ b/src/Ganeti/Path.hs
@@ -36,6 +36,7 @@ module Ganeti.Path
   , confdHmacKey
   , clusterConfFile
   , lockStatusFile
+  , tempResStatusFile
   , watcherPauseFile
   , nodedCertFile
   , nodedClientCertFile
@@ -125,6 +126,10 @@ clusterConfFile  = dataDirP "config.data"
 lockStatusFile :: IO FilePath
 lockStatusFile  = dataDirP "locks.data"
 
+-- | Path to the file representing the lock status.
+tempResStatusFile :: IO FilePath
+tempResStatusFile  = dataDirP "tempres.data"
+
 -- | Path to the watcher pause file.
 watcherPauseFile :: IO FilePath
 watcherPauseFile = dataDirP "watcher.pause"
diff --git a/src/Ganeti/WConfd/Core.hs b/src/Ganeti/WConfd/Core.hs
index 528fb27..b73a0fc 100644
--- a/src/Ganeti/WConfd/Core.hs
+++ b/src/Ganeti/WConfd/Core.hs
@@ -33,7 +33,6 @@ module Ganeti.WConfd.Core where
 
 import Control.Arrow ((&&&))
 import Control.Monad (liftM, unless, when)
-import Control.Monad.State (modify)
 import qualified Data.Map as M
 import qualified Data.Set as S
 import Language.Haskell.TH (Name)
@@ -123,7 +122,7 @@ flushConfig = forceConfigStateDistribution
 
 dropAllReservations :: ClientId -> WConfdMonad ()
 dropAllReservations cid =
-  modifyTempResState (const . modify $ T.dropAllReservations cid)
+  modifyTempResState (const $ T.dropAllReservations cid)
 
 -- *** DRBD
 
diff --git a/src/Ganeti/WConfd/DeathDetection.hs 
b/src/Ganeti/WConfd/DeathDetection.hs
index 0cecbe7..3b0e69c 100644
--- a/src/Ganeti/WConfd/DeathDetection.hs
+++ b/src/Ganeti/WConfd/DeathDetection.hs
@@ -62,8 +62,9 @@ cleanupLocksTask = forever . runResultT $ do
         let fpath = ciLockFile owner
         died <- liftIO (isDead fpath)
         when died $ do
-          logInfo $ show owner ++ " died, releasing locks"
+          logInfo $ show owner ++ " died, releasing locks and reservations"
           persCleanup persistentLocks owner
+          persCleanup persistentTempRes owner
           _ <- liftIO . E.try $ removeFile fpath
                :: WConfdMonad (Either IOError ())
           return ()
diff --git a/src/Ganeti/WConfd/Monad.hs b/src/Ganeti/WConfd/Monad.hs
index afc30ef..a1b863b 100644
--- a/src/Ganeti/WConfd/Monad.hs
+++ b/src/Ganeti/WConfd/Monad.hs
@@ -104,11 +104,13 @@ data DaemonHandle = DaemonHandle
   -- all IDs of threads that do asynchronous work should probably also go here
   , dhSaveConfigWorker :: AsyncWorker Any ()
   , dhSaveLocksWorker :: AsyncWorker () ()
+  , dhSaveTempResWorker :: AsyncWorker () ()
   }
 
 mkDaemonHandle :: FilePath
                -> ConfigState
                -> GanetiLockWaiting
+               -> TempResState
                -> (IO ConfigState -> [AsyncWorker () ()]
                                   -> ResultG (AsyncWorker Any ()))
                   -- ^ A function that creates a worker that asynchronously
@@ -122,11 +124,14 @@ mkDaemonHandle :: FilePath
                -> (IO GanetiLockWaiting -> ResultG (AsyncWorker () ()))
                   -- ^ A function that creates a worker that asynchronously
                   -- saves the lock allocation state.
+               -> (IO TempResState -> ResultG (AsyncWorker () ()))
+                  -- ^ A function that creates a worker that asynchronously
+                  -- saves the temporary reservations state.
                -> ResultG DaemonHandle
-mkDaemonHandle cpath cstat lstat
+mkDaemonHandle cpath cstat lstat trstat
                saveWorkerFn distMCsWorkerFn distSSConfWorkerFn
-               saveLockWorkerFn = do
-  ds <- newIORef $ DaemonState cstat lstat emptyTempResState
+               saveLockWorkerFn saveTempResWorkerFn = do
+  ds <- newIORef $ DaemonState cstat lstat trstat
   let readConfigIO = dsConfigState `liftM` readIORef ds :: IO ConfigState
 
   ssconfWorker <- distSSConfWorkerFn readConfigIO
@@ -136,7 +141,9 @@ mkDaemonHandle cpath cstat lstat
 
   saveLockWorker <- saveLockWorkerFn $ dsLockWaiting `liftM` readIORef ds
 
-  return $ DaemonHandle ds cpath saveWorker saveLockWorker
+  saveTempResWorker <- saveTempResWorkerFn $ dsTempRes `liftM` readIORef ds
+
+  return $ DaemonHandle ds cpath saveWorker saveLockWorker saveTempResWorker
 
 -- * The monad and its instances
 
@@ -244,7 +251,13 @@ modifyTempResStateErr f = do
   let f' ds = traverseOf2 dsTempResL
               (runStateT (f (csConfigData . dsConfigState $ ds))) ds
   dh <- daemonHandle
-  toErrorBase $ atomicModifyIORefErr (dhDaemonState dh) (liftM swap . f')
+  r <- toErrorBase $ atomicModifyIORefErr (dhDaemonState dh)
+                                          (liftM swap . f')
+  -- logDebug $ "Current temporary reservations: " ++ J.encode tr
+  logDebug "Triggering temporary reservations write"
+  liftBase . triggerAndWait_ . dhSaveTempResWorker $ dh
+  logDebug "Temporary reservations write finished"
+  return r
 
 -- | Atomically modifies the state of temporary reservations in
 -- WConfdMonad.
diff --git a/src/Ganeti/WConfd/Persistent.hs b/src/Ganeti/WConfd/Persistent.hs
index 1ff3ded..3d01a0a 100644
--- a/src/Ganeti/WConfd/Persistent.hs
+++ b/src/Ganeti/WConfd/Persistent.hs
@@ -34,6 +34,7 @@ module Ganeti.WConfd.Persistent
   , writePersistentAsyncTask
   , readPersistent
   , persistentLocks
+  , persistentTempRes
   ) where
 
 import Control.Monad.Error
@@ -47,8 +48,9 @@ import Ganeti.Locking.Waiting (emptyWaiting)
 import Ganeti.Locking.Locks (ClientId(..), GanetiLockWaiting)
 import Ganeti.Logging
 import qualified Ganeti.Path as Path
-import Ganeti.WConfd.Core (freeLocks)
+import Ganeti.WConfd.Core (freeLocks, dropAllReservations)
 import Ganeti.WConfd.Monad
+import Ganeti.WConfd.TempRes (TempResState, emptyTempResState)
 import Ganeti.Utils.Atomic
 import Ganeti.Utils.AsyncWorker
 
@@ -112,3 +114,13 @@ persistentLocks = Persistent
   , persEmpty = emptyWaiting
   , persCleanup = freeLocks
   }
+
+-- ** Temporary reservations
+
+persistentTempRes :: Persistent TempResState
+persistentTempRes = Persistent
+  { persName = "temporary reservations"
+  , persPath = Path.tempResStatusFile
+  , persEmpty = emptyTempResState
+  , persCleanup = dropAllReservations
+  }
diff --git a/src/Ganeti/WConfd/Server.hs b/src/Ganeti/WConfd/Server.hs
index 375e237..67d8e05 100644
--- a/src/Ganeti/WConfd/Server.hs
+++ b/src/Ganeti/WConfd/Server.hs
@@ -83,13 +83,16 @@ prepMain _ _ = do
     (cdata, cstat) <- loadConfigFromFile conf_file
     verifyConfigErr cdata
     lock <- readPersistent persistentLocks
+    tempres <- readPersistent persistentTempRes
     mkDaemonHandle conf_file
                    (mkConfigState cdata)
                    lock
+                   tempres
                    (saveConfigAsyncTask conf_file cstat)
                    (distMCsAsyncTask ents conf_file)
                    distSSConfAsyncTask
                    (writePersistentAsyncTask persistentLocks)
+                   (writePersistentAsyncTask persistentTempRes)
 
   return (s, dh)
 
diff --git a/src/Ganeti/WConfd/TempRes.hs b/src/Ganeti/WConfd/TempRes.hs
index 110d5e3..effde60 100644
--- a/src/Ganeti/WConfd/TempRes.hs
+++ b/src/Ganeti/WConfd/TempRes.hs
@@ -245,8 +245,8 @@ generateRand rgen jobid existing genfn tr =
 -- | Removes all resources reserved by a given job.
 --
 -- If a new reservation resource type is added, it must be added here as well.
-dropAllReservations :: ClientId -> TempResState -> TempResState
-dropAllReservations jobId =
+dropAllReservations :: ClientId -> State TempResState ()
+dropAllReservations jobId = modify $
     (trsMACsL %~ dropReservationsFor jobId)
   . (trsDRBDSecretsL %~ dropReservationsFor jobId)
   . (trsLVsL %~ dropReservationsFor jobId)
-- 
2.0.0.526.g5318336

Reply via email to