Add bdev_sizes RPC call
authorApollon Oikonomopoulos <apollon@noc.grnet.gr>
Fri, 4 Mar 2011 14:28:58 +0000 (16:28 +0200)
committerIustin Pop <iustin@google.com>
Tue, 8 Mar 2011 12:00:38 +0000 (13:00 +0100)
The bdev_sizes multi-node RPC call returns the sizes of the requested
block devices on the desired nodes. Its intended use is to verify the
existence of a block device on a given node for shared block storage
support.

Block device paths are expected to lie under constants.BLOCKDEV_DIR
("/dev/disk" by default), where persistent symlinks for block devices
are assumed to exist.

Signed-off-by: Apollon Oikonomopoulos <apollon@noc.grnet.gr>
[iustin@google.com: small changes in backend.py]
Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>

lib/backend.py
lib/rpc.py
lib/server/noded.py

index 391bb7a..44e5b7e 100644 (file)
@@ -647,6 +647,44 @@ def VerifyNode(what, cluster_name):
   return result
 
 
+def GetBlockDevSizes(devices):
+  """Return the size of the given block devices
+
+  @type devices: list
+  @param devices: list of block device nodes to query
+  @rtype: dict
+  @return:
+    dictionary of all block devices under /dev (key). The value is their
+    size in MiB.
+
+    {'/dev/disk/by-uuid/123456-12321231-312312-312': 124}
+
+  """
+  DEV_PREFIX = "/dev/"
+  blockdevs = {}
+
+  for devpath in devices:
+    if os.path.commonprefix([DEV_PREFIX, devpath]) != DEV_PREFIX:
+      continue
+
+    try:
+      st = os.stat(devpath)
+    except EnvironmentError, err:
+      logging.warning("Error stat()'ing device %s: %s", devpath, str(err))
+      continue
+
+    if stat.S_ISBLK(st.st_mode):
+      result = utils.RunCmd(["blockdev", "--getsize64", devpath])
+      if result.failed:
+        # We don't want to fail, just do not list this device as available
+        logging.warning("Cannot get size for block device %s", devpath)
+        continue
+
+      size = int(result.stdout) / (1024 * 1024)
+      blockdevs[devpath] = size
+  return blockdevs
+
+
 def GetVolumeList(vg_names):
   """Compute list of logical volumes and their size.
 
index 4e2693e..2eeec06 100644 (file)
@@ -590,6 +590,15 @@ class RpcRunner(object):
   #
 
   @_RpcTimeout(_TMO_URGENT)
+  def call_bdev_sizes(self, node_list, devices):
+    """Gets the sizes of requested block devices present on a node
+
+    This is a multi-node call.
+
+    """
+    return self._MultiNodeCall(node_list, "bdev_sizes", [devices])
+
+  @_RpcTimeout(_TMO_URGENT)
   def call_lv_list(self, node_list, vg_name):
     """Gets the logical volumes present in a given volume group.
 
index decc874..0090efb 100644 (file)
@@ -457,6 +457,15 @@ class NodeHttpServer(http.server.HttpServer):
     export = params[0]
     return backend.RemoveExport(export)
 
+  # block device ---------------------
+  @staticmethod
+  def perspective_bdev_sizes(params):
+    """Query the list of block devices
+
+    """
+    devices = params[0]
+    return backend.GetBlockDevSizes(devices)
+
   # volume  --------------------------
 
   @staticmethod