From b2acdbdc5c3e3aca14a03c0aa93e70cba0091904 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Wed, 26 Oct 2011 13:49:47 +0200
Subject: [PATCH] Show RPC calls from config in lock monitor

With this patch all RPC calls at runtime of masterd will show up in the
lock monitor. There is a chicken-and-egg issue with initializing the
configuration with a context since the lock manager, containing the
monitor, requires the configuration. This is worked around by setting
the config's context only once the lock monitor is available.

Example:
rpc/node19.example.com/write_ssconf_files  Jq9/Job32/N_SET_PARAMjobqueue_update  Jq2/Job27/C_VERIFY_CONFIG

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
---
 lib/config.py         | 17 +++++++++++++++--
 lib/rpc.py            | 10 ++++++++--
 lib/server/masterd.py |  2 ++
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/lib/config.py b/lib/config.py
index ee9747c3c..1e8741809 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -164,8 +164,21 @@ class ConfigWriter:
     self._my_hostname = netutils.Hostname.GetSysName()
     self._last_cluster_serial = -1
     self._cfg_id = None
+    self._context = None
     self._OpenConfig(accept_foreign)
 
+  def _GetRpc(self, address_list):
+    """Returns RPC runner for configuration.
+
+    """
+    return rpc.ConfigRunner(self._context, address_list)
+
+  def SetContext(self, context):
+    """Sets Ganeti context.
+
+    """
+    self._context = context
+
   # this method needs to be static, so that we can call it on the class
   @staticmethod
   def IsCluster():
@@ -1749,7 +1762,7 @@ class ConfigWriter:
 
     # TODO: Use dedicated resolver talking to config writer for name resolution
     result = \
-      rpc.ConfigRunner(addr_list).call_upload_file(node_list, self._cfg_file)
+      self._GetRpc(addr_list).call_upload_file(node_list, self._cfg_file)
     for to_node, to_result in result.items():
       msg = to_result.fail_msg
       if msg:
@@ -1808,7 +1821,7 @@ class ConfigWriter:
     # Write ssconf files on all nodes (including locally)
     if self._last_cluster_serial < self._config_data.cluster.serial_no:
       if not self._offline:
-        result = rpc.ConfigRunner(None).call_write_ssconf_files(
+        result = self._GetRpc(None).call_write_ssconf_files(
           self._UnlockedGetOnlineNodeList(),
           self._UnlockedGetSsconfValues())
 
diff --git a/lib/rpc.py b/lib/rpc.py
index ca4847801..9626501c0 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -723,15 +723,21 @@ class ConfigRunner(_RpcClientBase, _generated_rpc.RpcClientConfig):
   """RPC wrappers for L{config}.
 
   """
-  def __init__(self, address_list):
+  def __init__(self, context, address_list):
     """Initializes this class.
 
     """
+    if context:
+      lock_monitor_cb = context.glm.AddToLockMonitor
+    else:
+      lock_monitor_cb = None
+
     if address_list is None:
       resolver = _SsconfResolver
     else:
       # Caller provided an address list
       resolver = _StaticResolver(address_list)
 
-    _RpcClientBase.__init__(self, resolver, _ENCODERS.get)
+    _RpcClientBase.__init__(self, resolver, _ENCODERS.get,
+                            lock_monitor_cb=lock_monitor_cb)
     _generated_rpc.RpcClientConfig.__init__(self)
diff --git a/lib/server/masterd.py b/lib/server/masterd.py
index 59563322d..a91c9d462 100644
--- a/lib/server/masterd.py
+++ b/lib/server/masterd.py
@@ -401,6 +401,8 @@ class GanetiContext(object):
                 self.cfg.GetNodeGroupList(),
                 self.cfg.GetInstanceList())
 
+    self.cfg.SetContext(self)
+
     # Job queue
     self.jobqueue = jqueue.JobQueue(self)
 
-- 
GitLab