Commit 8c41f0d3 authored by Damiano Cipriani's avatar Damiano Cipriani Committed by Tomasz Zawadzki
Browse files

vbdev_lvol: add shallow copy status RPC



Add RPC interface to get info about a shallow copy operation,
like the total number of clusters to be copied, the
actual number of clusters copied and the result of the operation.

Change-Id: Ic242dced7e7d1a60fdf197f0211819d3188e2fb8
Signed-off-by: default avatarDamiano Cipriani <damiano.cipriani@suse.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/19252


Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
parent 9b3554b5
Loading
Loading
Loading
Loading
+52 −1
Original line number Diff line number Diff line
@@ -499,6 +499,7 @@ Example response:
    "bdev_lvol_rename_lvstore",
    "bdev_lvol_create_lvstore",
    "bdev_lvol_start_shallow_copy",
    "bdev_lvol_check_shallow_copy",
    "bdev_daos_delete",
    "bdev_daos_create",
    "bdev_daos_resize"
@@ -10653,7 +10654,8 @@ Must have:

#### Result

This RPC starts the operation and return an identifier.
This RPC starts the operation and return an identifier that can be used to query the status of the operation
with the RPC @ref rpc_bdev_lvol_check_shallow_copy.

#### Parameters

@@ -10690,6 +10692,55 @@ Example response:
}
~~~

### bdev_lvol_check_shallow_copy {#rpc_bdev_lvol_check_shallow_copy}

Get shallow copy status.

#### Result

Get info about the shallow copy operation identified by operation id.
It reports operation's status, which can be `in progress`, `complete` or `error`,
the actual number of copied clusters, the total number of clusters to copy and,
in case of error, a description.
Once the operation is ended and the result has been retrieved, the
operation is removed from the internal list of ended operation, so its
result cannot be accessed anymore.

#### Parameters

Name                    | Optional | Type        | Description
----------------------- | -------- | ----------- | -----------
operation_id            | Required | number      | operation identifier

#### Example

Example request:

~~~json
{
  "jsonrpc": "2.0",
  "method": "bdev_lvol_check_shallow_copy",
  "id": 1,
  "params": {
    "operation_id": 7
  }
}
~~~

Example response:

~~~json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "state": "in progress",
    "copied_clusters": 2,
    "total_clusters": 4
  }
}
~~~

## RAID

### bdev_raid_set_options {#rpc_bdev_raid_set_options}
+82 −0
Original line number Diff line number Diff line
@@ -1436,3 +1436,85 @@ cleanup:

SPDK_RPC_REGISTER("bdev_lvol_start_shallow_copy", rpc_bdev_lvol_start_shallow_copy,
		  SPDK_RPC_RUNTIME)

struct rpc_bdev_lvol_shallow_copy_status {
	char		*src_lvol_name;
	uint32_t	operation_id;
};

static void
free_rpc_bdev_lvol_shallow_copy_status(struct rpc_bdev_lvol_shallow_copy_status *req)
{
	free(req->src_lvol_name);
}

static const struct spdk_json_object_decoder rpc_bdev_lvol_shallow_copy_status_decoders[] = {
	{"operation_id", offsetof(struct rpc_bdev_lvol_shallow_copy_status, operation_id), spdk_json_decode_uint32},
};

static void
rpc_bdev_lvol_check_shallow_copy(struct spdk_jsonrpc_request *request,
				 const struct spdk_json_val *params)
{
	struct rpc_bdev_lvol_shallow_copy_status req = {};
	struct rpc_shallow_copy_status *status;
	struct spdk_json_write_ctx *w;
	uint64_t copied_clusters, total_clusters;
	int result;

	SPDK_INFOLOG(lvol_rpc, "Shallow copy check\n");

	if (spdk_json_decode_object(params, rpc_bdev_lvol_shallow_copy_status_decoders,
				    SPDK_COUNTOF(rpc_bdev_lvol_shallow_copy_status_decoders),
				    &req)) {
		SPDK_INFOLOG(lvol_rpc, "spdk_json_decode_object failed\n");
		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
						 "spdk_json_decode_object failed");
		goto cleanup;
	}

	LIST_FOREACH(status, &g_shallow_copy_status_list, link) {
		if (status->operation_id == req.operation_id) {
			break;
		}
	}

	if (!status) {
		SPDK_ERRLOG("operation id '%d' does not exist\n", req.operation_id);
		spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
		goto cleanup;
	}

	copied_clusters = status->copied_clusters;
	total_clusters = status->total_clusters;
	result = status->result;

	w = spdk_jsonrpc_begin_result(request);

	spdk_json_write_object_begin(w);

	spdk_json_write_named_uint64(w, "copied_clusters", copied_clusters);
	spdk_json_write_named_uint64(w, "total_clusters", total_clusters);
	if (copied_clusters < total_clusters && result == 0) {
		spdk_json_write_named_string(w, "state", "in progress");
	} else if (copied_clusters == total_clusters && result == 0) {
		spdk_json_write_named_string(w, "state", "complete");
		LIST_REMOVE(status, link);
		free(status);
	} else {
		spdk_json_write_named_string(w, "state", "error");
		spdk_json_write_named_string(w, "error", spdk_strerror(-result));
		LIST_REMOVE(status, link);
		free(status);
	}

	spdk_json_write_object_end(w);

	spdk_jsonrpc_end_result(request, w);

cleanup:
	free_rpc_bdev_lvol_shallow_copy_status(&req);
}

SPDK_RPC_REGISTER("bdev_lvol_check_shallow_copy", rpc_bdev_lvol_check_shallow_copy,
		  SPDK_RPC_RUNTIME)
+14 −1
Original line number Diff line number Diff line
@@ -224,7 +224,8 @@ def bdev_lvol_decouple_parent(client, name):


def bdev_lvol_start_shallow_copy(client, src_lvol_name, dst_bdev_name):
    """Start a shallow copy of an lvol over a given bdev
    """Start a shallow copy of an lvol over a given bdev. The status of the operation
    can be obtained with bdev_lvol_check_shallow_copy

    Args:
        src_lvol_name: name of lvol to create a copy from
@@ -237,6 +238,18 @@ def bdev_lvol_start_shallow_copy(client, src_lvol_name, dst_bdev_name):
    return client.call('bdev_lvol_start_shallow_copy', params)


def bdev_lvol_check_shallow_copy(client, operation_id):
    """Get shallow copy status

    Args:
        operation_id: operation identifier
    """
    params = {
        'operation_id': operation_id
    }
    return client.call('bdev_lvol_check_shallow_copy', params)


def bdev_lvol_delete_lvstore(client, uuid=None, lvs_name=None):
    """Destroy a logical volume store.

+11 −1
Original line number Diff line number Diff line
@@ -2138,11 +2138,21 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
                                                         src_lvol_name=args.src_lvol_name,
                                                         dst_bdev_name=args.dst_bdev_name))

    p = subparsers.add_parser('bdev_lvol_start_shallow_copy', help='Start a shallow copy of an lvol over a given bdev')
    p = subparsers.add_parser('bdev_lvol_start_shallow_copy',
                              help="""Start a shallow copy of an lvol over a given bdev.  The status of the operation
    can be obtained with bdev_lvol_check_shallow_copy""")
    p.add_argument('src_lvol_name', help='source lvol name')
    p.add_argument('dst_bdev_name', help='destination bdev name')
    p.set_defaults(func=bdev_lvol_start_shallow_copy)

    def bdev_lvol_check_shallow_copy(args):
        print_json(rpc.lvol.bdev_lvol_check_shallow_copy(args.client,
                                                         operation_id=args.operation_id))

    p = subparsers.add_parser('bdev_lvol_check_shallow_copy', help='Get shallow copy status')
    p.add_argument('operation_id', help='operation identifier', type=int)
    p.set_defaults(func=bdev_lvol_check_shallow_copy)

    def bdev_lvol_delete_lvstore(args):
        rpc.lvol.bdev_lvol_delete_lvstore(args.client,
                                          uuid=args.uuid,