From d61cbe76c2be32c1131b7dd13718cf50d72a9ac6 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Fri, 20 Jun 2008 11:04:27 +0000
Subject: [PATCH] Add a rpc call for BlockDev.Close()

This patch adds rpc layer calls (in rpc.py and the equivalent in
ganeti-noded) to close a list of block devices, and the wrapper in
backend.py that takes a list of Disk objects, identifies them and
returns correctly formatted results.

The reason why this very basic call was missing until now from the rpc
layer is that we usually don't care about device closes (though we
should, and will do so in the future) as only drbd has a meaningful
Close() operation; right now we directly do Shutdown().

The patch is clean enough that it's actually independent of the live
migration implementation.

Reviewed-by: imsnah
---
 daemons/ganeti-noded |  8 ++++++++
 lib/backend.py       | 27 ++++++++++++++++++++++++++-
 lib/rpc.py           | 13 +++++++++++++
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded
index 115c51b48..b826724bd 100755
--- a/daemons/ganeti-noded
+++ b/daemons/ganeti-noded
@@ -220,6 +220,14 @@ class ServerObject(BaseHTTPServer.BaseHTTPRequestHandler):
     amount = params[1]
     return backend.GrowBlockDevice(cfbd, amount)
 
+  @staticmethod
+  def perspective_blockdev_close(params):
+    """Closes the given block devices.
+
+    """
+    disks = [objects.Disk.FromDict(cf) for cf in params]
+    return backend.CloseBlockDevices(disks)
+
   # export/import  --------------------------
 
   @staticmethod
diff --git a/lib/backend.py b/lib/backend.py
index 08e013f15..50bb6308f 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -1477,7 +1477,7 @@ def _TransformFileStorageDir(file_storage_dir):
 
   Args:
     file_storage_dir: string with path
-  
+
   Returns:
     normalized file_storage_dir (string) if valid, None otherwise
 
@@ -1592,6 +1592,31 @@ def RenameFileStorageDir(old_file_storage_dir, new_file_storage_dir):
   return result
 
 
+def CloseBlockDevices(disks):
+  """Closes the given block devices.
+
+  This means they will be switched to secondary mode (in case of DRBD).
+
+  """
+  bdevs = []
+  for cf in disks:
+    rd = _RecursiveFindBD(cf)
+    if rd is None:
+      return (False, "Can't find device %s" % cf)
+    bdevs.append(rd)
+
+  msg = []
+  for rd in bdevs:
+    try:
+      rd.Close()
+    except errors.BlockDeviceError, err:
+      msg.append(str(err))
+  if msg:
+    return (False, "Can't make devices secondary: %s" % ",".join(msg))
+  else:
+    return (True, "All devices secondary")
+
+
 class HooksRunner(object):
   """Hook runner.
 
diff --git a/lib/rpc.py b/lib/rpc.py
index 335d8885b..f2c85db11 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -512,6 +512,19 @@ def call_blockdev_find(node, disk):
   return c.getresult().get(node, False)
 
 
+def call_blockdev_close(node, disks):
+  """Closes the given block devices.
+
+  This is a single-node call.
+
+  """
+  params = [cf.ToDict() for cf in disks]
+  c = Client("blockdev_close", params)
+  c.connect(node)
+  c.run()
+  return c.getresult().get(node, False)
+
+
 def call_upload_file(node_list, file_name):
   """Upload a file.
 
-- 
GitLab