]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
KCC: Create Graphviz dot files showing network topology
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Fri, 27 Feb 2015 05:21:19 +0000 (18:21 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 28 May 2015 05:25:08 +0000 (07:25 +0200)
This tries to record some information about what the graph is (e.g
which partition), though it is not very readable.

Pair-programmed-with: Garming Sam <garming@catalyst.net.nz>
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/kcc_utils.py
source4/scripting/bin/samba_kcc

index 9980c6cb40d1120bc08b9d2717e07e8a45478bd3..3e0845ee03b05b97dd26ef244aa490c87935d150 100644 (file)
@@ -2358,3 +2358,18 @@ def combine_repl_info(info_a, info_b, info_c):
         info_c.cost = MAX_DWORD
 
     return True
+
+def write_dot_file(basename, edge_list, label=None, destdir=None):
+    from tempfile import NamedTemporaryFile
+    if label:
+        basename += '_' + label.translate(None, ', ') #fix DN, guid labels
+    f = NamedTemporaryFile(suffix='.dot', prefix=basename + '_', delete=False, dir=destdir)
+    graphname = ''.join(x for x in basename if x.isalnum())
+    print >>f, 'graph %s {' % graphname
+    print >>f, 'label="%s",' % (label or graphname)
+    for a, b in edge_list:
+        print >>f, '"%s" -- "%s"' % (a, b)
+    print >>f, '}'
+
+
+    f.close()
index d1e9b1c6f38c4f3a0f55dcffa9e721d553c69cd0..2adb9f628727f58126ff05134411166e6ae239ad 100755 (executable)
@@ -36,6 +36,8 @@ sys.path.insert(0, "bin/python")
 
 import optparse
 import logging
+import itertools
+import heapq
 
 from samba import (
     getopt as options,
@@ -50,8 +52,6 @@ from samba.samdb import SamDB
 from samba.dcerpc import drsuapi
 from samba.kcc_utils import *
 
-import heapq
-
 class KCC(object):
     """The Knowledge Consistency Checker class.
 
@@ -1515,7 +1515,7 @@ class KCC(object):
         if my_vertex.is_white():
             return all_connected, found_failed
 
-        edge_list, component_count = self.get_spanning_tree_edges(graph)
+        edge_list, component_count = self.get_spanning_tree_edges(graph, label=part.partstr)
 
         logger.debug("%s Number of components: %d" % (part.nc_dnstr, component_count))
         if component_count > 1:
@@ -1639,7 +1639,7 @@ class KCC(object):
 
         return all_connected
 
-    def get_spanning_tree_edges(self, graph):
+    def get_spanning_tree_edges(self, graph, label=None):
         # Phase 1: Run Dijkstra's to get a list of internal edges, which are
         # just the shortest-paths connecting colored vertices
 
@@ -1656,6 +1656,12 @@ class KCC(object):
                 for v in e.vertices:
                     v.edges.append(e)
 
+            write_dot_file('edgeset_%s' % (edgeType,),
+                           ((a.site.site_dnstr, b.site.site_dnstr)
+                            for a, b in itertools.chain(*(itertools.combinations(edge.vertices, 2)
+                                                          for edge in e_set.edges))),
+                           label=label)
+
             # Run dijkstra's algorithm with just the red vertices as seeds
             # Seed from the full replicas
             dijkstra(graph, edgeType, False)
@@ -1674,6 +1680,9 @@ class KCC(object):
         setup_vertices(graph)
         process_edge_set(graph, None, internal_edges)
 
+        write_dot_file('prekruskal', [(e.v1.site.site_dnstr, e.v2.site.site_dnstr)
+                                       for e in internal_edges])
+
         # Phase 2: Run Kruskal's on the internal edges
         output_edges, components = kruskal(graph, internal_edges)
 
@@ -1687,6 +1696,8 @@ class KCC(object):
             else:
                 v.dist_to_red = v.repl_info.cost
 
+        write_dot_file('postkruskal', ((e.v1.site.site_dnstr, e.v2.site.site_dnstr) for e in internal_edges))
+
         # count the components
         return self.copy_output_edges(graph, output_edges), components
 
@@ -2228,6 +2239,14 @@ class KCC(object):
 
             # Step 7
             self.update_rodc_connection()
+
+            dot_edges = []
+            for site in self.site_table.values():
+                for dsa in site.dsa_table.values():
+                    for con in dsa.connect_table.values():
+                        dot_edges.append((dsa.dsa_dnstr, con.from_dnstr))
+
+            write_dot_file('dsa_final', dot_edges)
         except:
             raise