From 4b98ac2932e6a530a02f499dc18eaf3cd471cf54 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Thu, 12 Feb 2009 07:31:04 +0000
Subject: [PATCH] ConfigWriter: add checks for duplicate disk IDs

This patch adds a safety check for duplicate disk logical/physical IDs,
in order to prevent possible software bugs.

Reviewed-by: imsnah
---
 lib/config.py | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/lib/config.py b/lib/config.py
index a6f3d6905..dbb008387 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -227,6 +227,34 @@ class ConfigWriter:
 
     return result
 
+  def _CheckDiskIDs(self, disk, l_ids, p_ids):
+    """Compute duplicate disk IDs
+
+    @type disk: L{objects.Disk}
+    @param disk: the disk at which to start searching
+    @type l_ids: list
+    @param l_ids: list of current logical ids
+    @type p_ids: list
+    @param p_ids: list of current physical ids
+    @rtype: list
+    @return: a list of error messages
+
+    """
+    result = []
+    if disk.logical_id in l_ids:
+      result.append("duplicate logical id %s" % str(disk.logical_id))
+    else:
+      l_ids.append(disk.logical_id)
+    if disk.physical_id in p_ids:
+      result.append("duplicate physical id %s" % str(disk.physical_id))
+    else:
+      p_ids.append(disk.physical_id)
+
+    if disk.children:
+      for child in disk.children:
+        result.extend(self._CheckDiskIDs(child, l_ids, p_ids))
+    return result
+
   def _UnlockedVerifyConfig(self):
     """Verify function.
 
@@ -239,6 +267,8 @@ class ConfigWriter:
     seen_macs = []
     ports = {}
     data = self._config_data
+    seen_lids = []
+    seen_pids = []
     for instance_name in data.instances:
       instance = data.instances[instance_name]
       if instance.primary_node not in data.nodes:
@@ -273,6 +303,7 @@ class ConfigWriter:
       for idx, disk in enumerate(instance.disks):
         result.extend(["instance '%s' disk %d error: %s" %
                        (instance.name, idx, msg) for msg in disk.Verify()])
+        result.extend(self._CheckDiskIDs(disk, seen_lids, seen_pids))
 
     # cluster-wide pool of free ports
     for free_port in data.cluster.tcpudp_port_pool:
-- 
GitLab