From 2be7273ccdad115169ab0f8765f3fe66d0aeff47 Mon Sep 17 00:00:00 2001 From: Apollon Oikonomopoulos <apollon@noc.grnet.gr> Date: Fri, 4 Mar 2011 16:28:58 +0200 Subject: [PATCH] Add bdev_sizes RPC call 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 | 38 ++++++++++++++++++++++++++++++++++++++ lib/rpc.py | 9 +++++++++ lib/server/noded.py | 9 +++++++++ 3 files changed, 56 insertions(+) diff --git a/lib/backend.py b/lib/backend.py index 391bb7a0a..44e5b7e74 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -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. diff --git a/lib/rpc.py b/lib/rpc.py index 4e2693e55..2eeec0628 100644 --- a/lib/rpc.py +++ b/lib/rpc.py @@ -589,6 +589,15 @@ class RpcRunner(object): # Begin RPC calls # + @_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. diff --git a/lib/server/noded.py b/lib/server/noded.py index decc87449..0090efb7d 100644 --- a/lib/server/noded.py +++ b/lib/server/noded.py @@ -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 -- GitLab