Merge branch 'stable-2.13' into stable-2.14
[ganeti-github.git] / src / Ganeti / WConfd / Core.hs
index c538d94..8c0306c 100644 (file)
@@ -2,15 +2,16 @@
 
 {-| The Ganeti WConfd core functions.
 
-As TemplateHaskell require that splices be defined in a separate
-module, we combine all the TemplateHaskell functionality that HTools
-needs in this module (except the one for unittests).
+This module defines all the functions that WConfD exports for
+RPC calls. They are in a separate module so that in a later
+stage, TemplateHaskell can generate, e.g., the python interface
+for those.
 
 -}
 
 {-
 
-Copyright (C) 2013 Google Inc.
+Copyright (C) 2013, 2014 Google Inc.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -68,6 +69,7 @@ import Ganeti.WConfd.DeathDetection (cleanupLocks)
 import Ganeti.WConfd.Language
 import Ganeti.WConfd.Monad
 import qualified Ganeti.WConfd.TempRes as T
+import qualified Ganeti.WConfd.ConfigModifications as CM
 import qualified Ganeti.WConfd.ConfigWriter as CW
 
 -- * Functions available to the RPC module
@@ -137,6 +139,22 @@ unlockConfig
   :: ClientId -> WConfdMonad ()
 unlockConfig cid = freeLocksLevel cid LevelConfig
 
+-- | Write the configuration, if the config lock is held exclusively,
+-- and release the config lock. It the caller does not have the config
+-- lock, return False.
+writeConfigAndUnlock :: ClientId -> ConfigData -> WConfdMonad Bool
+writeConfigAndUnlock cid cdata = do
+  la <- readLockAllocation
+  if L.holdsLock cid ConfigLock L.OwnExclusive la
+    then do
+      CW.writeConfig cdata
+      unlockConfig cid
+      return True
+    else do
+      logWarning $ show cid ++ " tried writeConfigAndUnlock without owning"
+                   ++ " the config lock"
+      return False
+
 -- | Force the distribution of configuration without actually modifying it.
 -- It is not necessary to hold a lock for this operation.
 flushConfig :: WConfdMonad ()
@@ -156,22 +174,22 @@ computeDRBDMap = uncurry T.computeDRBDMap =<< readTempResState
 -- Allocate a drbd minor.
 --
 -- The free minor will be automatically computed from the existing devices.
--- A node can be given multiple times in order to allocate multiple minors.
+-- A node can not be given multiple times.
 -- The result is the list of minors, in the same order as the passed nodes.
 allocateDRBDMinor
-  :: T.InstanceUUID -> [T.NodeUUID] -> WConfdMonad [T.DRBDMinor]
-allocateDRBDMinor inst nodes =
-  modifyTempResStateErr (\cfg -> T.allocateDRBDMinor cfg inst nodes)
+  :: T.DiskUUID -> [T.NodeUUID] -> WConfdMonad [T.DRBDMinor]
+allocateDRBDMinor disk nodes =
+  modifyTempResStateErr (\cfg -> T.allocateDRBDMinor cfg disk nodes)
 
--- Release temporary drbd minors allocated for a given instance using
+-- Release temporary drbd minors allocated for a given disk using
 -- 'allocateDRBDMinor'.
 --
 -- This should be called on the error paths, on the success paths
 -- it's automatically called by the ConfigWriter add and update
 -- functions.
 releaseDRBDMinors
-  :: T.InstanceUUID -> WConfdMonad ()
-releaseDRBDMinors inst = modifyTempResState (const $ T.releaseDRBDMinors inst)
+  :: T.DiskUUID -> WConfdMonad ()
+releaseDRBDMinors disk = modifyTempResState (const $ T.releaseDRBDMinors disk)
 
 -- *** MACs
 
@@ -370,6 +388,7 @@ exportedFunctions = [ 'echo
                     , 'verifyConfig
                     , 'lockConfig
                     , 'unlockConfig
+                    , 'writeConfigAndUnlock
                     , 'flushConfig
                     -- temporary reservations (common)
                     , 'dropAllReservations
@@ -406,3 +425,4 @@ exportedFunctions = [ 'echo
                     , 'guardedOpportunisticLockUnion
                     , 'hasPendingRequest
                     ]
+                    ++ CM.exportedFunctions