Commit 48ce9fd9 authored by Iustin Pop's avatar Iustin Pop
Browse files

Add checks for tcp/udp port collisions

In case the config file is manually modified, or in case of bugs, the
tcp/udp ports could be reused, which will create various problems
(instances not able to start, or drbd disks not able to communicate).

This patch extends the ConfigWriter.VerifyConfig() method (which is used
in cluster verify) to check for duplicates between:
  - the ports used for DRBD disks
  - the ports used for network console
  - the ports marked as free in the config file

Also, if the cluster parameter ‘highest_used_port’ is actually lower
than the computed highest used port, this is also flagged as an error.

The output from gnt-cluster verify will show (output manually wrapped):

node1 # gnt-cluster verify
* Verifying global settings
  - ERROR: tcp/udp port 11006 has duplicates: instance3.example.com/network port,
instance2.example.com/drbd disk sda
  - ERROR: tcp/udp port 11017 has duplicates: instance3.example.com/drbd disk sda,
instance3.example.com/drbd disk sdb, cluster/port marked as free
  - ERROR: Highest used port mismatch, saved 11010, computed 11017
* Gathering data (2 nodes)
...

Reviewed-by: ultrotter
parent b9f72b4e
......@@ -193,6 +193,7 @@ class ConfigWriter:
result = []
seen_macs = []
ports = {}
data = self._config_data
for instance_name in data.instances:
instance = data.instances[instance_name]
......@@ -209,6 +210,43 @@ class ConfigWriter:
(instance_name, idx, nic.mac))
else:
seen_macs.append(nic.mac)
# gather the drbd ports for duplicate checks
for dsk in instance.disks:
if dsk.dev_type in constants.LDS_DRBD:
tcp_port = dsk.logical_id[2]
if tcp_port not in ports:
ports[tcp_port] = []
ports[tcp_port].append((instance.name, "drbd disk %s" % dsk.iv_name))
# gather network port reservation
net_port = getattr(instance, "network_port", None)
if net_port is not None:
if net_port not in ports:
ports[net_port] = []
ports[net_port].append((instance.name, "network port"))
# cluster-wide pool of free ports
for free_port in self._config_data.cluster.tcpudp_port_pool:
if free_port not in ports:
ports[free_port] = []
ports[free_port].append(("cluster", "port marked as free"))
# compute tcp/udp duplicate ports
keys = ports.keys()
keys.sort()
for pnum in keys:
pdata = ports[pnum]
if len(pdata) > 1:
txt = ", ".join(["%s/%s" % val for val in pdata])
result.append("tcp/udp port %s has duplicates: %s" % (pnum, txt))
# highest used tcp port check
if keys:
if keys[-1] > self._config_data.cluster.highest_used_port:
result.append("Highest used port mismatch, saved %s, computed %s" %
(self._config_data.cluster.highest_used_port,
keys[-1]))
return result
def _UnlockedSetDiskID(self, disk, node_name):
......
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