From a0c3fea1f56906ee5c21e09b44a4ff178f3dfd16 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Fri, 3 Aug 2007 12:35:59 +0000
Subject: [PATCH] Add instance name to LVM volume as a tag.

Reviewed-by: iustinp
---
 daemons/ganeti-noded |  9 ++-------
 lib/backend.py       |  5 ++++-
 lib/bdev.py          | 30 ++++++++++++++++++++++++++++++
 lib/cmdlib.py        | 35 +++++++++++++++++++++++------------
 lib/rpc.py           |  4 ++--
 5 files changed, 61 insertions(+), 22 deletions(-)

diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded
index f63000553..d403a1dde 100755
--- a/daemons/ganeti-noded
+++ b/daemons/ganeti-noded
@@ -80,19 +80,17 @@ class ServerObject(pb.Avatar):
   # the new block devices  --------------------------
 
   def perspective_blockdev_create(self, params):
-    bdev_s, size, on_primary = params
+    bdev_s, size, on_primary, info = params
     bdev = objects.ConfigObject.Loads(bdev_s)
     if bdev is None:
       raise ValueError("can't unserialize data!")
-    return backend.CreateBlockDevice(bdev, size, on_primary)
-
+    return backend.CreateBlockDevice(bdev, size, on_primary, info)
 
   def perspective_blockdev_remove(self, params):
     bdev_s = params[0]
     bdev = objects.ConfigObject.Loads(bdev_s)
     return backend.RemoveBlockDevice(bdev)
 
-
   def perspective_blockdev_assemble(self, params):
     bdev_s, on_primary = params
     bdev = objects.ConfigObject.Loads(bdev_s)
@@ -100,7 +98,6 @@ class ServerObject(pb.Avatar):
       raise ValueError("can't unserialize data!")
     return backend.AssembleBlockDevice(bdev, on_primary)
 
-
   def perspective_blockdev_shutdown(self, params):
     bdev_s = params[0]
     bdev = objects.ConfigObject.Loads(bdev_s)
@@ -108,7 +105,6 @@ class ServerObject(pb.Avatar):
       raise ValueError("can't unserialize data!")
     return backend.ShutdownBlockDevice(bdev)
 
-
   def perspective_blockdev_addchild(self, params):
     bdev_s, ndev_s = params
     bdev = objects.ConfigObject.Loads(bdev_s)
@@ -117,7 +113,6 @@ class ServerObject(pb.Avatar):
       raise ValueError("can't unserialize data!")
     return backend.MirrorAddChild(bdev, ndev)
 
-
   def perspective_blockdev_removechild(self, params):
     bdev_s, ndev_s = params
     bdev = objects.ConfigObject.Loads(bdev_s)
diff --git a/lib/backend.py b/lib/backend.py
index ea44897d5..996ae4e73 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -534,7 +534,7 @@ def ShutdownInstance(instance):
   return True
 
 
-def CreateBlockDevice(disk, size, on_primary):
+def CreateBlockDevice(disk, size, on_primary, info):
   """Creates a block device for an instance.
 
   Args:
@@ -578,6 +578,9 @@ def CreateBlockDevice(disk, size, on_primary):
     device.SetSyncSpeed(constants.SYNC_SPEED)
     if on_primary or disk.OpenOnSecondary():
       device.Open(force=True)
+
+  device.SetInfo(info)
+
   physical_id = device.unique_id
   return physical_id
 
diff --git a/lib/bdev.py b/lib/bdev.py
index 480c5ba3a..f7eef6e7b 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -258,6 +258,16 @@ class BlockDev(object):
     return min_percent, max_time, is_degraded
 
 
+  def SetInfo(self, text):
+    """Update metadata with info text.
+
+    Only supported for some device types.
+
+    """
+    for child in self._children:
+      child.SetInfo(text)
+
+
   def __repr__(self):
     return ("<%s: unique_id: %s, children: %s, %s:%s, %s>" %
             (self.__class__, self.unique_id, self._children,
@@ -477,6 +487,26 @@ class LogicalVolume(BlockDev):
     return snap_name
 
 
+  def SetInfo(self, text):
+    """Update metadata with info text.
+
+    """
+    BlockDev.SetInfo(self, text)
+
+    # Replace invalid characters
+    text = re.sub('^[^A-Za-z0-9_+.]', '_', text)
+    text = re.sub('[^-A-Za-z0-9_+.]', '_', text)
+
+    # Only up to 128 characters are allowed
+    text = text[:128]
+
+    result = utils.RunCmd(["lvchange", "--addtag", text,
+                           self.dev_path])
+    if result.failed:
+      raise errors.BlockDeviceError, ("Command: %s error: %s" %
+                                      (result.cmd, result.fail_reason))
+
+
 class MDRaid1(BlockDev):
   """raid1 device implemented via md.
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 5820bb93e..8f5216f5e 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2253,7 +2253,7 @@ class LUFailoverInstance(LogicalUnit):
                                (instance.name, target_node))
 
 
-def _CreateBlockDevOnPrimary(cfg, node, device):
+def _CreateBlockDevOnPrimary(cfg, node, device, info):
   """Create a tree of block devices on the primary node.
 
   This always creates all devices.
@@ -2261,11 +2261,11 @@ def _CreateBlockDevOnPrimary(cfg, node, device):
   """
   if device.children:
     for child in device.children:
-      if not _CreateBlockDevOnPrimary(cfg, node, child):
+      if not _CreateBlockDevOnPrimary(cfg, node, child, info):
         return False
 
   cfg.SetDiskID(device, node)
-  new_id = rpc.call_blockdev_create(node, device, device.size, True)
+  new_id = rpc.call_blockdev_create(node, device, device.size, True, info)
   if not new_id:
     return False
   if device.physical_id is None:
@@ -2273,7 +2273,7 @@ def _CreateBlockDevOnPrimary(cfg, node, device):
   return True
 
 
-def _CreateBlockDevOnSecondary(cfg, node, device, force):
+def _CreateBlockDevOnSecondary(cfg, node, device, force, info):
   """Create a tree of block devices on a secondary node.
 
   If this device type has to be created on secondaries, create it and
@@ -2286,13 +2286,13 @@ def _CreateBlockDevOnSecondary(cfg, node, device, force):
     force = True
   if device.children:
     for child in device.children:
-      if not _CreateBlockDevOnSecondary(cfg, node, child, force):
+      if not _CreateBlockDevOnSecondary(cfg, node, child, force, info):
         return False
 
   if not force:
     return True
   cfg.SetDiskID(device, node)
-  new_id = rpc.call_blockdev_create(node, device, device.size, False)
+  new_id = rpc.call_blockdev_create(node, device, device.size, False, info)
   if not new_id:
     return False
   if device.physical_id is None:
@@ -2394,6 +2394,10 @@ def _GenerateDiskTemplate(cfg, template_name,
   return disks
 
 
+def _GetInstanceInfoText(instance):
+  return "originstname+%s" % instance.name
+
+
 def _CreateDisks(cfg, instance):
   """Create all disks for an instance.
 
@@ -2406,17 +2410,20 @@ def _CreateDisks(cfg, instance):
     True or False showing the success of the creation process
 
   """
+  info = _GetInstanceInfoText(instance)
+
   for device in instance.disks:
     logger.Info("creating volume %s for instance %s" %
               (device.iv_name, instance.name))
     #HARDCODE
     for secondary_node in instance.secondary_nodes:
-      if not _CreateBlockDevOnSecondary(cfg, secondary_node, device, False):
+      if not _CreateBlockDevOnSecondary(cfg, secondary_node, device, False,
+                                        info):
         logger.Error("failed to create volume %s (%s) on secondary node %s!" %
                      (device.iv_name, device, secondary_node))
         return False
     #HARDCODE
-    if not _CreateBlockDevOnPrimary(cfg, instance.primary_node, device):
+    if not _CreateBlockDevOnPrimary(cfg, instance.primary_node, device, info):
       logger.Error("failed to create volume %s on primary!" %
                    device.iv_name)
       return False
@@ -2854,13 +2861,15 @@ class LUAddMDDRBDComponent(LogicalUnit):
 
     logger.Info("adding new mirror component on secondary")
     #HARDCODE
-    if not _CreateBlockDevOnSecondary(self.cfg, remote_node, new_drbd, False):
+    if not _CreateBlockDevOnSecondary(self.cfg, remote_node, new_drbd, False,
+                                      _GetInstanceInfoText(instance)):
       raise errors.OpExecError, ("Failed to create new component on secondary"
                                  " node %s" % remote_node)
 
     logger.Info("adding new mirror component on primary")
     #HARDCODE
-    if not _CreateBlockDevOnPrimary(self.cfg, instance.primary_node, new_drbd):
+    if not _CreateBlockDevOnPrimary(self.cfg, instance.primary_node, new_drbd,
+                                    _GetInstanceInfoText(instance)):
       # remove secondary dev
       self.cfg.SetDiskID(new_drbd, remote_node)
       rpc.call_blockdev_remove(remote_node, new_drbd)
@@ -3053,7 +3062,8 @@ class LUReplaceDisks(LogicalUnit):
       logger.Info("adding new mirror component on secondary for %s" %
                   dev.iv_name)
       #HARDCODE
-      if not _CreateBlockDevOnSecondary(cfg, remote_node, new_drbd, False):
+      if not _CreateBlockDevOnSecondary(cfg, remote_node, new_drbd, False,
+                                        _GetInstanceInfoText(instance)):
         raise errors.OpExecError, ("Failed to create new component on"
                                    " secondary node %s\n"
                                    "Full abort, cleanup manually!" %
@@ -3061,7 +3071,8 @@ class LUReplaceDisks(LogicalUnit):
 
       logger.Info("adding new mirror component on primary")
       #HARDCODE
-      if not _CreateBlockDevOnPrimary(cfg, instance.primary_node, new_drbd):
+      if not _CreateBlockDevOnPrimary(cfg, instance.primary_node, new_drbd,
+                                      _GetInstanceInfoText(instance)):
         # remove secondary dev
         cfg.SetDiskID(new_drbd, remote_node)
         rpc.call_blockdev_remove(remote_node, new_drbd)
diff --git a/lib/rpc.py b/lib/rpc.py
index 061eead4d..bcec427fd 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -452,13 +452,13 @@ def call_version(node_list):
   return c.getresult()
 
 
-def call_blockdev_create(node, bdev, size, on_primary):
+def call_blockdev_create(node, bdev, size, on_primary, info):
   """Request creation of a given block device.
 
   This is a single-node call.
 
   """
-  params = [bdev.Dumps(), size, on_primary]
+  params = [bdev.Dumps(), size, on_primary, info]
   c = Client("blockdev_create", params)
   c.connect(node)
   c.run()
-- 
GitLab