diff --git a/Makefile.am b/Makefile.am
index 3c7820a194a394ef5037b211406d362eee109719..5a6e137a0f5e05ec2e304f41dc2661d48a17184a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -429,6 +429,7 @@ HS_LIB_SRCS = \
 	htools/Ganeti/Luxi.hs \
 	htools/Ganeti/Objects.hs \
 	htools/Ganeti/OpCodes.hs \
+	htools/Ganeti/Path.hs \
 	htools/Ganeti/Query/Common.hs \
 	htools/Ganeti/Query/Filter.hs \
 	htools/Ganeti/Query/Language.hs \
diff --git a/autotools/convert-constants b/autotools/convert-constants
index e051821e6c4e0294d6752fb36f5eaeaa9cddc5a7..b08f6f33eebf0d3475afc93182c20325c902e30c 100755
--- a/autotools/convert-constants
+++ b/autotools/convert-constants
@@ -29,6 +29,8 @@ from ganeti import compat
 from ganeti import constants
 from ganeti import luxi
 from ganeti import qlang
+from ganeti import _autoconf
+
 
 #: Constant name regex
 CONSTANT_RE = re.compile("^[A-Z][A-Z0-9_-]+$")
@@ -46,6 +48,7 @@ RE_TYPE = type(CONSTANT_RE)
 # have strings instead of easily looked-up names.
 IGNORED_DECL_NAMES = ["DEFAULT_ENABLED_HYPERVISOR"]
 
+
 def NameRules(name):
   """Converts the upper-cased Python name to Haskell camelCase.
 
@@ -289,6 +292,7 @@ def main():
   print Convert(constants, "")
   print Convert(luxi, "luxi")
   print Convert(qlang, "qlang")
+  print Convert(_autoconf, "autoconf")
 
 
 if __name__ == "__main__":
diff --git a/htools/Ganeti/Confd/Server.hs b/htools/Ganeti/Confd/Server.hs
index 6bedee94a7af92d59d90d914268691b630a33a2b..b14eb43534829a9276859878ce5b742bcc2204ac 100644
--- a/htools/Ganeti/Confd/Server.hs
+++ b/htools/Ganeti/Confd/Server.hs
@@ -55,6 +55,7 @@ import Ganeti.Config
 import Ganeti.Hash
 import Ganeti.Logging
 import qualified Ganeti.Constants as C
+import qualified Ganeti.Path as Path
 import Ganeti.Query.Server (runQueryD)
 
 -- * Types and constants definitions
@@ -503,11 +504,11 @@ main opts = do
   hmac <- getClusterHmac
   -- Inotify setup
   inotify <- initINotify
-  let inotiaction = addNotifier inotify C.clusterConfFile cref statemvar
+  let inotiaction = addNotifier inotify Path.clusterConfFile cref statemvar
   -- fork the timeout timer
-  _ <- forkIO $ onTimeoutTimer inotiaction C.clusterConfFile cref statemvar
+  _ <- forkIO $ onTimeoutTimer inotiaction Path.clusterConfFile cref statemvar
   -- fork the polling timer
-  _ <- forkIO $ onReloadTimer inotiaction C.clusterConfFile cref statemvar
+  _ <- forkIO $ onReloadTimer inotiaction Path.clusterConfFile cref statemvar
   -- launch the queryd listener
   _ <- forkIO $ runQueryD Nothing (configReader cref)
   -- and finally enter the responder loop
diff --git a/htools/Ganeti/Confd/Utils.hs b/htools/Ganeti/Confd/Utils.hs
index 180e327255821edf8a5bfb4857056dd7912bd735..043ded07b3b8a467b306340ebabaf616e98214e0 100644
--- a/htools/Ganeti/Confd/Utils.hs
+++ b/htools/Ganeti/Confd/Utils.hs
@@ -40,12 +40,13 @@ import Ganeti.BasicTypes
 import Ganeti.Confd
 import Ganeti.Hash
 import qualified Ganeti.Constants as C
+import qualified Ganeti.Path as Path
 import Ganeti.JSON
 import Ganeti.HTools.Utils
 
 -- | Returns the HMAC key.
 getClusterHmac :: IO HashKey
-getClusterHmac = fmap B.unpack $ B.readFile C.confdHmacKey
+getClusterHmac = fmap B.unpack $ B.readFile Path.confdHmacKey
 
 -- | Parses a signed request.
 parseRequest :: HashKey -> String -> Result (String, String, ConfdRequest)
diff --git a/htools/Ganeti/HTools/CLI.hs b/htools/Ganeti/HTools/CLI.hs
index 056149035f9dd04eda295961166964bd41b24b2b..e4580136d5d2703477ac9a055d670345440002ee 100644
--- a/htools/Ganeti/HTools/CLI.hs
+++ b/htools/Ganeti/HTools/CLI.hs
@@ -36,7 +36,6 @@ module Ganeti.HTools.CLI
   , parseYesNo
   , parseISpecString
   , shTemplate
-  , defaultLuxiSocket
   , maybePrintNodes
   , maybePrintInsts
   , maybeShowWarnings
@@ -92,20 +91,12 @@ import Text.Printf (printf)
 
 import qualified Ganeti.HTools.Container as Container
 import qualified Ganeti.HTools.Node as Node
-import qualified Ganeti.Constants as C
+import qualified Ganeti.Path as Path
 import Ganeti.HTools.Types
 import Ganeti.HTools.Utils
 import Ganeti.BasicTypes
 import Ganeti.Common as Common
 
--- * Constants
-
--- | The default value for the luxi socket.
---
--- This is re-exported from the "Ganeti.Constants" module.
-defaultLuxiSocket :: FilePath
-defaultLuxiSocket = C.masterSocket
-
 -- * Data types
 
 -- | Command line options structure.
@@ -301,7 +292,7 @@ oIAllocSrc = Option "I" ["ialloc-src"]
 oLuxiSocket :: OptType
 oLuxiSocket = Option "L" ["luxi"]
               (OptArg ((\ f opts -> Ok opts { optLuxi = Just f }) .
-                       fromMaybe defaultLuxiSocket) "SOCKET")
+                       fromMaybe Path.defaultLuxiSocket) "SOCKET")
               "collect data via Luxi, optionally using the given SOCKET path"
 
 oMachineReadable :: OptType
diff --git a/htools/Ganeti/HTools/Program/Hscan.hs b/htools/Ganeti/HTools/Program/Hscan.hs
index 5c89de90a0f57133fd4faedd5c58408d16a225e3..b83cc57fc622358c735763aa87f7bae79400d535 100644
--- a/htools/Ganeti/HTools/Program/Hscan.hs
+++ b/htools/Ganeti/HTools/Program/Hscan.hs
@@ -39,6 +39,7 @@ import qualified Ganeti.HTools.Node as Node
 import qualified Ganeti.HTools.Instance as Instance
 import qualified Ganeti.HTools.Rapi as Rapi
 import qualified Ganeti.HTools.Luxi as Luxi
+import qualified Ganeti.Path as Path
 import Ganeti.HTools.Loader (checkData, mergeData, ClusterData(..))
 import Ganeti.HTools.Text (serializeCluster)
 
@@ -138,7 +139,7 @@ main opts clusters = do
                 "t_disk" "f_disk" "Score"
 
   when (null clusters) $ do
-         let lsock = fromMaybe defaultLuxiSocket (optLuxi opts)
+         let lsock = fromMaybe Path.defaultLuxiSocket (optLuxi opts)
          let name = local
          input_data <- Luxi.loadData lsock
          result <- writeData nlen name opts input_data
diff --git a/htools/Ganeti/Path.hs b/htools/Ganeti/Path.hs
new file mode 100644
index 0000000000000000000000000000000000000000..5f439dd365a6815cd8e04c61d824a89a4bee5c18
--- /dev/null
+++ b/htools/Ganeti/Path.hs
@@ -0,0 +1,70 @@
+{-| Path-related helper functions.
+
+-}
+
+{-
+
+Copyright (C) 2012 Google Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+-}
+
+module Ganeti.Path
+  ( defaultLuxiSocket
+  , defaultQuerySocket
+  , dataDir
+  , logDir
+  , runDir
+  , confdHmacKey
+  , clusterConfFile
+  ) where
+
+import qualified Ganeti.Constants as C
+import System.FilePath
+
+
+-- | Directory for data
+dataDir :: FilePath
+dataDir = C.autoconfLocalstatedir </> "lib" </> "ganeti"
+
+-- | Directory for runtime files
+runDir :: FilePath
+runDir = C.autoconfLocalstatedir </> "run" </> "ganeti"
+
+-- | Directory for log files
+logDir :: FilePath
+logDir = C.autoconfLocalstatedir </> "log" </> "ganeti"
+
+-- | Directory for Unix sockets
+socketDir :: FilePath
+socketDir = runDir </> "socket"
+
+-- | The default LUXI socket path.
+defaultLuxiSocket :: FilePath
+defaultLuxiSocket = socketDir </> "ganeti-master"
+
+-- | The default LUXI socket for queries.
+defaultQuerySocket :: FilePath
+defaultQuerySocket = socketDir </> "ganeti-query"
+
+-- | Path to file containing confd's HMAC key
+confdHmacKey :: FilePath
+confdHmacKey = dataDir </> "hmac.key"
+
+-- | Path to cluster configuration file
+clusterConfFile :: FilePath
+clusterConfFile  = dataDir </> "config.data"
diff --git a/htools/Ganeti/Query/Server.hs b/htools/Ganeti/Query/Server.hs
index 80be42c0bb355f26c6ecf74e5bab368ac440880b..876aba04e1f920f77cc1f1790782c517620f1914 100644
--- a/htools/Ganeti/Query/Server.hs
+++ b/htools/Ganeti/Query/Server.hs
@@ -42,6 +42,7 @@ import Text.JSON.Pretty (pp_value)
 import System.Info (arch)
 
 import qualified Ganeti.Constants as C
+import qualified Ganeti.Path as Path
 import Ganeti.Daemon
 import Ganeti.Objects
 import qualified Ganeti.Config as Config
@@ -197,7 +198,7 @@ mainLoop creader socket = do
 -- only one exposed from this module.
 runQueryD :: Maybe FilePath -> ConfigReader -> IO ()
 runQueryD fpath creader = do
-  let socket_path = fromMaybe C.querySocket fpath
+  let socket_path = fromMaybe Path.defaultQuerySocket fpath
   cleanupSocket socket_path
   bracket
     (getServer socket_path)
diff --git a/htools/Ganeti/Runtime.hs b/htools/Ganeti/Runtime.hs
index 7a8acca2b132f7a90a0b7fb1ee34f7912be45e06..82957369dfd60eedfb68ff8b370476408a903d17 100644
--- a/htools/Ganeti/Runtime.hs
+++ b/htools/Ganeti/Runtime.hs
@@ -49,6 +49,7 @@ import System.Posix.User
 import Text.Printf
 
 import qualified Ganeti.Constants as C
+import qualified Ganeti.Path as Path
 import Ganeti.BasicTypes
 
 data GanetiDaemon = GanetiMasterd
@@ -92,11 +93,11 @@ daemonGroup (ExtraGroup  AdminGroup)    = C.adminGroup
 
 -- | Returns the log file for a daemon.
 daemonLogFile :: GanetiDaemon -> FilePath
-daemonLogFile daemon = C.logDir </> daemonName daemon <.> "log"
+daemonLogFile daemon = Path.logDir </> daemonName daemon <.> "log"
 
 -- | Returns the pid file name for a daemon.
 daemonPidFile :: GanetiDaemon -> FilePath
-daemonPidFile daemon = C.runDir </> daemonName daemon <.> "pid"
+daemonPidFile daemon = Path.runDir </> daemonName daemon <.> "pid"
 
 -- | All groups list. A bit hacking, as we can't enforce it's complete
 -- at compile time.
diff --git a/htools/Ganeti/Ssconf.hs b/htools/Ganeti/Ssconf.hs
index cc3639561b4602b1915536dc8891d5c809866372..47a2e04ced158258601184f90ce75987113f9a47 100644
--- a/htools/Ganeti/Ssconf.hs
+++ b/htools/Ganeti/Ssconf.hs
@@ -46,6 +46,7 @@ import System.FilePath ((</>))
 import System.IO.Error (isDoesNotExistError)
 
 import qualified Ganeti.Constants as C
+import qualified Ganeti.Path as Path
 import Ganeti.BasicTypes
 import Ganeti.HTools.Utils
 
@@ -86,7 +87,7 @@ $(declareSADT "SSKey"
 keyToFilename :: Maybe FilePath     -- ^ Optional config path override
               -> SSKey              -- ^ ssconf key
               -> FilePath
-keyToFilename optpath key = fromMaybe C.dataDir optpath </>
+keyToFilename optpath key = fromMaybe Path.dataDir optpath </>
                             sSFilePrefix ++ sSKeyToRaw key
 
 -- | Runs an IO action while transforming any error into 'Bad'