From 48e175a2934fdb473466b2a7e52d16b91d5b87be Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Thu, 18 Oct 2012 17:59:56 +0200
Subject: [PATCH] Update blockdev's "info" at instance rename

Currently, we set "info" metadata on block devices at device creation
time, but we never update it, leading to stale data in case of
instance renames. This would not be a big problem in case of regular
renames (assuming this is a rare operation), but importing instances
into the cluster via the import/export feature usually is done with a
rename; this means that all imported instances have wrong information
in their block devices.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/backend.py      | 26 ++++++++++++++++++++++++++
 lib/cmdlib.py       |  9 +++++++++
 lib/rpc_defs.py     |  4 ++++
 lib/server/noded.py |  9 +++++++++
 4 files changed, 48 insertions(+)

diff --git a/lib/backend.py b/lib/backend.py
index 4c537b5b9..032547d22 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -2517,6 +2517,32 @@ def BlockdevSnapshot(disk):
           disk.unique_id, disk.dev_type)
 
 
+def BlockdevSetInfo(disk, info):
+  """Sets 'metadata' information on block devices.
+
+  This function sets 'info' metadata on block devices. Initial
+  information is set at device creation; this function should be used
+  for example after renames.
+
+  @type disk: L{objects.Disk}
+  @param disk: the disk to be grown
+  @type info: string
+  @param info: new 'info' metadata
+  @rtype: (status, result)
+  @return: a tuple with the status of the operation (True/False), and
+      the errors message if status is False
+
+  """
+  r_dev = _RecursiveFindBD(disk)
+  if r_dev is None:
+    _Fail("Cannot find block device %s", disk)
+
+  try:
+    r_dev.SetInfo(info)
+  except errors.BlockDeviceError, err:
+    _Fail("Failed to set information on block device: %s", err, exc=True)
+
+
 def FinalizeExport(instance, snap_disks):
   """Write out the export configuration information.
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index ba13cac86..6d998e4ce 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -7480,6 +7480,15 @@ class LUInstanceRename(LogicalUnit):
                     new_file_storage_dir))
 
     _StartInstanceDisks(self, inst, None)
+    # update info on disks
+    info = _GetInstanceInfoText(inst)
+    for (idx, disk) in enumerate(inst.disks):
+      for node in inst.all_nodes:
+        self.cfg.SetDiskID(disk, node)
+        result = self.rpc.call_blockdev_setinfo(node, disk, info)
+        if result.fail_msg:
+          self.LogWarning("Error setting info on node %s for disk %s: %s",
+                          node, idx, result.fail_msg)
     try:
       result = self.rpc.call_instance_run_rename(inst.primary_node, inst,
                                                  old_name, self.op.debug_level)
diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py
index c6ae9671a..15344b5eb 100644
--- a/lib/rpc_defs.py
+++ b/lib/rpc_defs.py
@@ -418,6 +418,10 @@ _BLOCKDEV_CALLS = [
     ], _BlockdevGetMirrorStatusMultiPreProc,
    _BlockdevGetMirrorStatusMultiPostProc,
     "Request status of (mirroring) devices from multiple nodes"),
+  ("blockdev_setinfo", SINGLE, None, constants.RPC_TMO_NORMAL, [
+    ("disk", ED_OBJECT_DICT, None),
+    ("info", None, None),
+    ], None, None, "Sets metadata information on a given block device"),
   ]
 
 _OS_CALLS = [
diff --git a/lib/server/noded.py b/lib/server/noded.py
index 203dc3cc1..2ff474c22 100644
--- a/lib/server/noded.py
+++ b/lib/server/noded.py
@@ -367,6 +367,15 @@ class NodeRequestHandler(http.server.HttpServerHandler):
     dest_node, dest_path, cluster_name = params[1:]
     return backend.BlockdevExport(disk, dest_node, dest_path, cluster_name)
 
+  @staticmethod
+  def perspective_blockdev_setinfo(params):
+    """Sets metadata information on the given block device.
+
+    """
+    (disk, info) = params
+    disk = objects.Disk.FromDict(disk)
+    return backend.BlockdevSetInfo(disk, info)
+
   # blockdev/drbd specific methods ----------
 
   @staticmethod
-- 
GitLab