On Wed, Jun 4, 2014 at 3:57 PM, Dimitris Bliablias <[email protected]>
wrote:

> Introduce a new RPC call named 'blockdev_convert'. This method uses the
> 'backend.BlockdevConvert' function which takes as arguments the source
> and target disks between which we will perform the actual data copy of
> their contents.
>
> This method first gets the export and import commands from the source
> and target devices respectively, and then concatenates them to a unified
> command using a pipe ("|"), following a similar approach with the impexp
> daemon. Finally, the unified command is executed by this method.
>
> Signed-off-by: Dimitris Bliablias <[email protected]>
> ---
>  lib/backend.py      |   37 +++++++++++++++++++++++++++++++++++++
>  lib/rpc_defs.py     |    5 +++++
>  lib/server/noded.py |   10 ++++++++++
>  3 files changed, 52 insertions(+)
>
> diff --git a/lib/backend.py b/lib/backend.py
> index 0e23c12..4fc89ce 100644
> --- a/lib/backend.py
> +++ b/lib/backend.py
> @@ -2373,6 +2373,43 @@ def _DownloadAndDumpDevice(source_url, target_path,
> size):
>    target_file.close()
>
>
> +def BlockdevConvert(src_disk, target_disk):
> +  """Copies data from source block device to target.
> +
> +  This function gets the export and import commands from the source and
> +  target devices respectively, and then concatenates them to a single
> +  command using a pipe ("|"). Finally, executes the unified command that
> +  will transfer the data between the devices during the disk template
> +  conversion operation.
> +
> +  @type src_disk: L{objects.Disk}
> +  @param src_disk: the disk object we want to copy from
> +  @type target_disk: L{objects.Disk}
> +  @param target_disk: the disk object we want to copy to
> +
> +  @rtype: NoneType
> +  @return: None
> +  @raise RPCFail: in case of failure
> +
> +  """
> +  src_dev = _RecursiveFindBD(src_disk)
> +  if src_dev is None:
> +    _Fail("Cannot copy from device '%s': device not found", src_disk.uuid)
> +
> +  dest_dev = _RecursiveFindBD(target_disk)
> +  if dest_dev is None:
> +    _Fail("Cannot copy to device '%s': device not found",
> target_disk.uuid)
> +
> +  src_cmd = src_dev.Export()
> +  dest_cmd = dest_dev.Import()
> +  command = "%s | %s" % (src_cmd, dest_cmd)
>

As mentioned before, this is dangerous. Instead, src_cmd and dest_cmd
should be lists of strings, and we should do something like

command = "%s | %s" % (utils_text.ShellQuoteArgs(src_cmd),
utils_text.ShellQuoteArgs((dest_cmd))


> +
> +  result = utils.RunCmd(command)
> +  if result.failed:
> +    _Fail("Disk conversion command '%s' exited with error: %s; output:
> %s",
> +          result.cmd, result.fail_reason, result.output)
> +
> +
>  def BlockdevWipe(disk, offset, size):
>    """Wipes a block device.
>
> diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py
> index 7eb53f0..c575c37 100644
> --- a/lib/rpc_defs.py
> +++ b/lib/rpc_defs.py
> @@ -361,6 +361,11 @@ _BLOCKDEV_CALLS = [
>      ("info", None, None),
>      ("exclusive_storage", None, None),
>      ], None, None, "Request creation of a given block device"),
> +  ("blockdev_convert", SINGLE, None, constants.RPC_TMO_SLOW, [
> +    ("bdev_src", ED_SINGLE_DISK_DICT_DP, None),
> +    ("bdev_dest", ED_SINGLE_DISK_DICT_DP, None),
> +    ], None, None,
> +    "Request the copy of the source block device to the destination one"),
>    ("blockdev_image", SINGLE, None, constants.RPC_TMO_SLOW, [
>      ("bdev", ED_SINGLE_DISK_DICT_DP, None),
>      ("image", None, None),
> diff --git a/lib/server/noded.py b/lib/server/noded.py
> index 7c11b5a..b36e5d8 100644
> --- a/lib/server/noded.py
> +++ b/lib/server/noded.py
> @@ -215,6 +215,16 @@ class
> NodeRequestHandler(http.server.HttpServerHandler):
>                                    excl_stor)
>
>    @staticmethod
> +  def perspective_blockdev_convert(params):
> +    """Copy data from source block device to target.
> +
> +    """
> +    disk_src, disk_dest = params
> +    bdev_src = objects.Disk.FromDict(disk_src)
> +    bdev_dest = objects.Disk.FromDict(disk_dest)
> +    return backend.BlockdevConvert(bdev_src, bdev_dest)
> +
> +  @staticmethod
>    def perspective_blockdev_pause_resume_sync(params):
>      """Pause/resume sync of a block device.
>
> --
> 1.7.10.4
>
>
Rest LGTM

Reply via email to