Commit 6d2e83d5 authored by Iustin Pop's avatar Iustin Pop
Browse files

Make cluster-verify check the drbd minors space

This patch adds support for verification of drbd minors space in cluster
verify: minors which belong to running instances and should be online
but are not, and minors which do not belong to any instace but are in
use.

The patch requires exposing some methods from bdev.DRBD8 and
config.ConfigWriter which were until now private methods.

Reviewed-by: ultrotter
parent 2f907a8c
......@@ -432,6 +432,14 @@ def VerifyNode(what, cluster_name):
hyper = hypervisor.GetHypervisor(what[constants.NV_HVINFO])
result[constants.NV_HVINFO] = hyper.GetNodeInfo()
if constants.NV_DRBDLIST in what:
try:
used_minors = bdev.DRBD8.GetUsedDevs().keys()
except errors.BlockDeviceErrors:
logging.warning("Can't get used minors list", exc_info=True)
used_minors = []
result[constants.NV_DRBDLIST] = used_minors
return result
......
......@@ -692,7 +692,7 @@ class BaseDRBD(BlockDev):
return "/dev/drbd%d" % minor
@classmethod
def _GetUsedDevs(cls):
def GetUsedDevs(cls):
"""Compute the list of used DRBD devices.
"""
......@@ -1343,7 +1343,7 @@ class DRBD8(BaseDRBD):
/proc).
"""
used_devs = self._GetUsedDevs()
used_devs = self.GetUsedDevs()
if self._aminor in used_devs:
minor = self._aminor
else:
......
......@@ -613,7 +613,8 @@ class LUVerifyCluster(LogicalUnit):
self.share_locks = dict(((i, 1) for i in locking.LEVELS))
def _VerifyNode(self, nodeinfo, file_list, local_cksum,
node_result, feedback_fn, master_files):
node_result, feedback_fn, master_files,
drbd_map):
"""Run multiple tests against a node.
Test list:
......@@ -630,6 +631,9 @@ class LUVerifyCluster(LogicalUnit):
@param node_result: the results from the node
@param feedback_fn: function used to accumulate results
@param master_files: list of files that only masters should have
@param drbd_map: the useddrbd minors for this node, in
form of minor: (instance, must_exist) which correspond to instances
and their running status
"""
node = nodeinfo.name
......@@ -724,6 +728,19 @@ class LUVerifyCluster(LogicalUnit):
if hv_result is not None:
feedback_fn(" - ERROR: hypervisor %s verify failure: '%s'" %
(hv_name, hv_result))
# check used drbd list
used_minors = node_result.get(constants.NV_DRBDLIST, [])
for minor, (iname, must_exist) in drbd_map.items():
if minor not in used_minors and must_exist:
feedback_fn(" - ERROR: drbd minor %d of instance %s is not active" %
(minor, iname))
bad = True
for minor in used_minors:
if minor not in drbd_map:
feedback_fn(" - ERROR: unallocated drbd minor %d is in use" % minor)
bad = True
return bad
def _VerifyInstance(self, instance, instanceconfig, node_vol_is,
......@@ -867,6 +884,8 @@ class LUVerifyCluster(LogicalUnit):
nodelist = utils.NiceSort(self.cfg.GetNodeList())
nodeinfo = [self.cfg.GetNodeInfo(nname) for nname in nodelist]
instancelist = utils.NiceSort(self.cfg.GetInstanceList())
instanceinfo = dict((iname, self.cfg.GetInstanceInfo(iname))
for iname in instancelist)
i_non_redundant = [] # Non redundant instances
i_non_a_balanced = [] # Non auto-balanced instances
n_offline = [] # List of offline nodes
......@@ -900,12 +919,15 @@ class LUVerifyCluster(LogicalUnit):
constants.NV_VGLIST: None,
constants.NV_VERSION: None,
constants.NV_HVINFO: self.cfg.GetHypervisorType(),
constants.NV_DRBDLIST: None,
}
all_nvinfo = self.rpc.call_node_verify(nodelist, node_verify_param,
self.cfg.GetClusterName())
cluster = self.cfg.GetClusterInfo()
master_node = self.cfg.GetMasterNode()
all_drbd_map = self.cfg.ComputeDRBDMap()
for node_i in nodeinfo:
node = node_i.name
nresult = all_nvinfo[node].data
......@@ -928,8 +950,13 @@ class LUVerifyCluster(LogicalUnit):
bad = True
continue
node_drbd = {}
for minor, instance in all_drbd_map[node].items():
instance = instanceinfo[instance]
node_drbd[minor] = (instance.name, instance.status == "up")
result = self._VerifyNode(node_i, file_names, local_checksums,
nresult, feedback_fn, master_files)
nresult, feedback_fn, master_files,
node_drbd)
bad = bad or result
lvdata = nresult.get(constants.NV_LVLIST, "Missing LV data")
......@@ -985,7 +1012,7 @@ class LUVerifyCluster(LogicalUnit):
for instance in instancelist:
feedback_fn("* Verifying instance %s" % instance)
inst_config = self.cfg.GetInstanceInfo(instance)
inst_config = instanceinfo[instance]
result = self._VerifyInstance(instance, inst_config, node_volume,
node_instance, feedback_fn, n_offline)
bad = bad or result
......
......@@ -389,7 +389,7 @@ class ConfigWriter:
self._WriteConfig()
return port
def _ComputeDRBDMap(self, instance):
def _UnlockedComputeDRBDMap(self):
"""Compute the used DRBD minor/nodes.
@return: dictionary of node_name: dict of minor: instance_name;
......@@ -421,6 +421,19 @@ class ConfigWriter:
_AppendUsedPorts(instance.name, disk, my_dict)
return my_dict
@locking.ssynchronized(_config_lock)
def ComputeDRBDMap(self):
"""Compute the used DRBD minor/nodes.
This is just a wrapper over L{_UnlockedComputeDRBDMap}.
@return: dictionary of node_name: dict of minor: instance_name;
the returned dict will have all the nodes in it (even if with
an empty list).
"""
return self._UnlockedComputeDRBDMap()
@locking.ssynchronized(_config_lock)
def AllocateDRBDMinor(self, nodes, instance):
"""Allocate a drbd minor.
......@@ -431,7 +444,7 @@ class ConfigWriter:
order as the passed nodes.
"""
d_map = self._ComputeDRBDMap(instance)
d_map = self._UnlockedComputeDRBDMap()
result = []
for nname in nodes:
ndata = d_map[nname]
......
......@@ -351,6 +351,7 @@ NV_NODELIST = "nodelist"
NV_NODENETTEST = "node-net-test"
NV_VERSION = "version"
NV_VGLIST = "vglist"
NV_DRBDLIST = "drbd-list"
# Allocator framework constants
IALLOCATOR_DIR_IN = "in"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment