diff --git a/Ganeti/HTools/ExtLoader.hs b/Ganeti/HTools/ExtLoader.hs
index 9db8f8114fd8919d0ccb767ec6a9ac8ada2d2e12..17726d10678eec21c2a5b1dd39e6be68cb274f21 100644
--- a/Ganeti/HTools/ExtLoader.hs
+++ b/Ganeti/HTools/ExtLoader.hs
@@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
 module Ganeti.HTools.ExtLoader
     ( loadExternalData
-    , Loader.commonSuffix
+    , commonSuffix
     ) where
 
 import Data.Maybe (isJust, fromJust)
@@ -46,10 +46,8 @@ import qualified Ganeti.HTools.Rapi as Rapi
 #endif
 import qualified Ganeti.HTools.Simu as Simu
 import qualified Ganeti.HTools.Text as Text
-import qualified Ganeti.HTools.Loader as Loader
-import qualified Ganeti.HTools.Instance as Instance
-import qualified Ganeti.HTools.Node as Node
-import qualified Ganeti.HTools.Group as Group
+import Ganeti.HTools.Loader (mergeData, checkData, ClusterData(..)
+                            , commonSuffix)
 
 import Ganeti.HTools.Types
 import Ganeti.HTools.CLI
@@ -75,7 +73,7 @@ parseUtilisation line =
 
 -- | External tool data loader from a variety of sources.
 loadExternalData :: Options
-                 -> IO (Group.List, Node.List, Instance.List, [String])
+                 -> IO ClusterData
 loadExternalData opts = do
   let mhost = optMaster opts
       lsock = optLuxi opts
@@ -120,8 +118,8 @@ loadExternalData opts = do
           | setFile -> wrapIO $ Text.loadData $ fromJust tfile
           | otherwise -> return $ Bad "No backend selected! Exiting."
 
-  let ldresult = input_data >>= Loader.mergeData util_data' exTags exInsts
-  (gl, loaded_nl, il, tags) <-
+  let ldresult = input_data >>= mergeData util_data' exTags exInsts
+  cdata <-
       (case ldresult of
          Ok x -> return x
          Bad s -> do
@@ -129,10 +127,10 @@ loadExternalData opts = do
                :: IO ()
            exitWith $ ExitFailure 1
       )
-  let (fix_msgs, fixed_nl) = Loader.checkData loaded_nl il
+  let (fix_msgs, nl) = checkData (cdNodes cdata) (cdInstances cdata)
 
   unless (null fix_msgs || optVerbose opts == 0) $ do
          hPutStrLn stderr "Warning: cluster has inconsistent data:"
          hPutStrLn stderr . unlines . map (printf "  - %s") $ fix_msgs
 
-  return (gl, fixed_nl, il, tags)
+  return cdata {cdNodes = nl}
diff --git a/Ganeti/HTools/IAlloc.hs b/Ganeti/HTools/IAlloc.hs
index 68a598f5bec0f86ba6194423f354f3b297cd98a7..e55d0e3bd7ec5732af8d0d697d40453161ccb791 100644
--- a/Ganeti/HTools/IAlloc.hs
+++ b/Ganeti/HTools/IAlloc.hs
@@ -130,7 +130,8 @@ parseData body = do
   let (kti, il) = assignIndices iobj
   -- cluster tags
   ctags <- fromObj "cluster_tags" obj
-  (map_g, map_n, map_i, ptags) <- mergeData [] [] [] (gl, nl, il, ctags)
+  cdata <- mergeData [] [] [] (gl, nl, il, ctags)
+  let map_n = cdNodes cdata
   optype <- fromObj "type" request
   rqtype <-
       case optype of
@@ -156,7 +157,7 @@ parseData body = do
               let ex_ndx = map Node.idx ex_nodes
               return $ Evacuate ex_ndx
         other -> fail ("Invalid request type '" ++ other ++ "'")
-  return $ Request rqtype (ClusterData map_g map_n map_i ptags)
+  return $ Request rqtype cdata
 
 -- | Format the result
 formatRVal :: RqType -> [Node.AllocElement] -> JSValue
diff --git a/Ganeti/HTools/Loader.hs b/Ganeti/HTools/Loader.hs
index 13c10d655bd1d8d1b7cbba486bcf1219d8b9f182..cddbd9f5083b23add8c4f5642727024f70933f18 100644
--- a/Ganeti/HTools/Loader.hs
+++ b/Ganeti/HTools/Loader.hs
@@ -185,7 +185,7 @@ mergeData :: [(String, DynUtil)]  -- ^ Instance utilisation data
           -> [String]             -- ^ Untouchable instances
           -> (Group.List, Node.List, Instance.List, [String])
           -- ^ Data from backends
-          -> Result (Group.List, Node.List, Instance.List, [String])
+          -> Result ClusterData
 mergeData um extags exinsts (gl, nl, il2, tags) =
   let il = Container.elems il2
       il3 = foldl' (\im (name, n_util) ->
@@ -209,7 +209,7 @@ mergeData um extags exinsts (gl, nl, il2, tags) =
   in if not $ all (`elem` all_inst_names) exinsts
      then Bad $ "Some of the excluded instances are unknown: " ++
           show (exinsts \\ all_inst_names)
-     else Ok (gl, snl, sil, tags)
+     else Ok (ClusterData gl snl sil tags)
 
 -- | Checks the cluster data for consistency.
 checkData :: Node.List -> Instance.List
diff --git a/Ganeti/HTools/QC.hs b/Ganeti/HTools/QC.hs
index 536d1bf2dc2449e479259910adfc80e836cbdf3c..d574bb0e906634bd429d2b77f02c84bbbc9e1d9e 100644
--- a/Ganeti/HTools/QC.hs
+++ b/Ganeti/HTools/QC.hs
@@ -852,7 +852,7 @@ prop_Loader_mergeData ns =
   in case Loader.mergeData [] [] []
          (Container.empty, na, Container.empty, []) of
     Types.Bad _ -> False
-    Types.Ok (_, nl, il, _) ->
+    Types.Ok (Loader.ClusterData _ nl il _) ->
       let nodes = Container.elems nl
           instances = Container.elems il
       in (sum . map (length . Node.pList)) nodes == 0 &&
diff --git a/hail.hs b/hail.hs
index ed67005718f348f2c47551aa3cdcdf83108cef54..78eb8e11a281593b7ba650c0fcbe16b022c9c85f 100644
--- a/hail.hs
+++ b/hail.hs
@@ -89,9 +89,9 @@ readRequest opts args = do
           Ok rq -> return rq
   r2 <- if isJust (optDataFile opts) ||  (not . null . optNodeSim) opts
         then  do
-          (gl, nl, il, ctags) <- loadExternalData opts
+          cdata <- loadExternalData opts
           let Request rqt _ = r1
-          return $ Request rqt (ClusterData gl nl il ctags)
+          return $ Request rqt cdata
         else return r1
   return r2
 
diff --git a/hbal.hs b/hbal.hs
index 455a751ccd978d5aa51e09ad1248acefd2f7060b..7db7b601f1ba3bec2f799953a1a9d54db3791662 100644
--- a/hbal.hs
+++ b/hbal.hs
@@ -49,6 +49,7 @@ import Ganeti.HTools.CLI
 import Ganeti.HTools.ExtLoader
 import Ganeti.HTools.Utils
 import Ganeti.HTools.Types
+import Ganeti.HTools.Loader (ClusterData(..))
 
 import Ganeti.HTools.Text (serializeCluster)
 
@@ -235,7 +236,7 @@ main = do
       verbose = optVerbose opts
       shownodes = optShowNodes opts
 
-  (gl, fixed_nl, ilf, ctags) <- loadExternalData opts
+  (ClusterData gl fixed_nl ilf ctags) <- loadExternalData opts
 
   let offline_names = optOffline opts
       all_nodes = Container.elems fixed_nl
diff --git a/hscan.hs b/hscan.hs
index e99efebfd8b5ab4e5dc1c8e1fc911f36669505ba..3c58769635e489b834b47bc41061a6727f8dda00 100644
--- a/hscan.hs
+++ b/hscan.hs
@@ -45,7 +45,7 @@ import qualified Ganeti.HTools.Instance as Instance
 import qualified Ganeti.HTools.Rapi as Rapi
 #endif
 import qualified Ganeti.HTools.Luxi as Luxi
-import qualified Ganeti.HTools.Loader as Loader
+import Ganeti.HTools.Loader (checkData, mergeData, ClusterData(..))
 import Ganeti.HTools.Text (serializeCluster)
 
 import Ganeti.HTools.CLI
@@ -93,8 +93,8 @@ fixSlash = map (\x -> if x == '/' then '_' else x)
 processData :: Result (Group.List, Node.List, Instance.List, [String])
             -> Result (Group.List, Node.List, Instance.List, String)
 processData input_data = do
-  (gl, nl, il, ctags) <- input_data >>= Loader.mergeData [] [] []
-  let (_, fix_nl) = Loader.checkData nl il
+  (ClusterData gl nl il ctags) <- input_data >>= mergeData [] [] []
+  let (_, fix_nl) = checkData nl il
       adata = serializeCluster gl nl il ctags
   return (gl, fix_nl, il, adata)
 
diff --git a/hspace.hs b/hspace.hs
index 2678c9dae80d0f0c7b4b4ff3c57b3f0fafd31d28..434a77c5a94071d63ed29645d1ee071b756c5d32 100644
--- a/hspace.hs
+++ b/hspace.hs
@@ -47,6 +47,7 @@ import Ganeti.HTools.Types
 import Ganeti.HTools.CLI
 import Ganeti.HTools.ExtLoader
 import Ganeti.HTools.Text (serializeCluster)
+import Ganeti.HTools.Loader (ClusterData(..))
 
 -- | Options list and functions
 options :: [OptType]
@@ -206,7 +207,7 @@ main = do
       ispec = optISpec opts
       shownodes = optShowNodes opts
 
-  (gl, fixed_nl, il, ctags) <- loadExternalData opts
+  (ClusterData gl fixed_nl il ctags) <- loadExternalData opts
 
   printKeys $ map (\(a, fn) -> ("SPEC_" ++ a, fn ispec)) specData
   printKeys [ ("SPEC_RQN", printf "%d" (optINodes opts)) ]