diff --git a/htools/Ganeti/Query/Node.hs b/htools/Ganeti/Query/Node.hs
index d324c39f6b254c3d192ba6725a6643b8cad78753..de6ea1a93d39f0ce9c68f8dece20cc47ff6fe791 100644
--- a/htools/Ganeti/Query/Node.hs
+++ b/htools/Ganeti/Query/Node.hs
@@ -223,4 +223,14 @@ maybeCollectLiveData False _ nodes =
 maybeCollectLiveData True cfg nodes = do
   let vgs = [clusterVolumeGroupName $ configCluster cfg]
       hvs = [getDefaultHypervisor cfg]
-  executeRpcCall nodes (RpcCallNodeInfo vgs hvs)
+      step n (bn, gn, em) =
+        let ndp' = getNodeNdParams cfg n
+        in case ndp' of
+             Just ndp -> (bn, n : gn,
+                          (nodeName n, ndpExclusiveStorage ndp) : em)
+             Nothing -> (n : bn, gn, em)
+      (bnodes, gnodes, emap) = foldr step ([], [], []) nodes
+  rpcres <- executeRpcCall gnodes (RpcCallNodeInfo vgs hvs (Map.fromList emap))
+  -- FIXME: The order of nodes in the result could be different from the input
+  return $ zip bnodes (repeat $ Left (RpcResultError "Broken configuration"))
+           ++ rpcres
diff --git a/htools/Ganeti/Rpc.hs b/htools/Ganeti/Rpc.hs
index c0d0cb6bbfe905bbb856b33c82e55c550bc99273..284bb5ef75667a60da1f7fb11e200ac3c978c69e 100644
--- a/htools/Ganeti/Rpc.hs
+++ b/htools/Ganeti/Rpc.hs
@@ -70,6 +70,8 @@ module Ganeti.Rpc
   ) where
 
 import Control.Arrow (second)
+import qualified Data.Map as Map
+import Data.Maybe (fromMaybe)
 import qualified Text.JSON as J
 import Text.JSON.Pretty (pp_value)
 
@@ -343,6 +345,7 @@ instance Rpc RpcCallInstanceList RpcResultInstanceList where
 $(buildObject "RpcCallNodeInfo" "rpcCallNodeInfo"
   [ simpleField "volume_groups" [t| [String] |]
   , simpleField "hypervisors" [t| [Hypervisor] |]
+  , simpleField "exclusive_storage" [t| Map.Map String Bool |]
   ])
 
 $(buildObject "VgInfo" "vgInfo"
@@ -371,10 +374,12 @@ instance RpcCall RpcCallNodeInfo where
   rpcCallName _          = "node_info"
   rpcCallTimeout _       = rpcTimeoutToRaw Urgent
   rpcCallAcceptOffline _ = False
-  rpcCallData _ call     = J.encode
+  rpcCallData n call     = J.encode
     ( rpcCallNodeInfoVolumeGroups call
     , rpcCallNodeInfoHypervisors call
-    , False
+    , fromMaybe (error $ "Programmer error: missing parameter for node named "
+                         ++ nodeName n)
+                $ Map.lookup (nodeName n) (rpcCallNodeInfoExclusiveStorage call)
     )
 
 instance Rpc RpcCallNodeInfo RpcResultNodeInfo where
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index eb9cb45717165aa81ec84283b18032ae745365a1..5b963c5fadd1a91ef3694e76e974e1b173a54a98 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -5288,8 +5288,9 @@ class _NodeQuery(_QueryBase):
       # filter out non-vm_capable nodes
       toquery_nodes = [name for name in nodenames if all_info[name].vm_capable]
 
+      es_flags = rpc.GetExclusiveStorageForNodeNames(lu.cfg, toquery_nodes)
       node_data = lu.rpc.call_node_info(toquery_nodes, [lu.cfg.GetVGName()],
-                                        [lu.cfg.GetHypervisorType()], False)
+                                        [lu.cfg.GetHypervisorType()], es_flags)
       live_data = dict((name, rpc.MakeLegacyNodeInfo(nresult.payload))
                        for (name, nresult) in node_data.items()
                        if not nresult.fail_msg and nresult.payload)
@@ -6888,7 +6889,8 @@ def _CheckNodesFreeDiskOnVG(lu, nodenames, vg, requested):
       or we cannot check the node
 
   """
-  nodeinfo = lu.rpc.call_node_info(nodenames, [vg], None, False)
+  es_flags = rpc.GetExclusiveStorageForNodeNames(lu.cfg, nodenames)
+  nodeinfo = lu.rpc.call_node_info(nodenames, [vg], None, es_flags)
   for node in nodenames:
     info = nodeinfo[node]
     info.Raise("Cannot get current information from node %s" % node,
diff --git a/lib/masterd/iallocator.py b/lib/masterd/iallocator.py
index 5f339b699ae0bd08b7c1c34ed809d98508e1ea9a..48cbd55ceef3c9b316f957477621ada1c5625217 100644
--- a/lib/masterd/iallocator.py
+++ b/lib/masterd/iallocator.py
@@ -430,8 +430,9 @@ class IAllocator(object):
       hypervisor_name = cluster_info.primary_hypervisor
       node_whitelist = None
 
+    es_flags = rpc.GetExclusiveStorageForNodeNames(cfg, node_list)
     node_data = self.rpc.call_node_info(node_list, [cfg.GetVGName()],
-                                        [hypervisor_name], False)
+                                        [hypervisor_name], es_flags)
     node_iinfo = \
       self.rpc.call_all_instances_info(node_list,
                                        cluster_info.enabled_hypervisors)
diff --git a/lib/rpc.py b/lib/rpc.py
index b72ac23e98bb911e1ca43651c2dd5bd6c02cff87..0c4bad0792c7117c1c17879392f540e02042aa6a 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -631,6 +631,31 @@ def AnnotateDiskParams(template, disks, disk_params):
   return [annotation_fn(disk.Copy(), ld_params) for disk in disks]
 
 
+def _GetESFlag(cfg, nodename):
+  ni = cfg.GetNodeInfo(nodename)
+  if ni is None:
+    raise errors.OpPrereqError("Invalid node name %s" % nodename,
+                               errors.ECODE_NOENT)
+  return cfg.GetNdParams(ni)[constants.ND_EXCLUSIVE_STORAGE]
+
+
+def GetExclusiveStorageForNodeNames(cfg, nodelist):
+  """Return the exclusive storage flag for all the given nodes.
+
+  @type cfg: L{config.ConfigWriter}
+  @param cfg: cluster configuration
+  @type nodelist: list or tuple
+  @param nodelist: node names for which to read the flag
+  @rtype: dict
+  @return: mapping from node names to exclusive storage flags
+  @raise errors.OpPrereqError: if any given node name has no corresponding node
+
+  """
+  getflag = lambda n: _GetESFlag(cfg, n)
+  flags = map(getflag, nodelist)
+  return dict(zip(nodelist, flags))
+
+
 #: Generic encoders
 _ENCODERS = {
   rpc_defs.ED_OBJECT_DICT: _ObjectToDict,