Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[experimental] ocf: rpc: Add runtime bdev flush support #34

Open
wants to merge 1 commit into
base: experimental
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions module/bdev/ocf/vbdev_ocf.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,15 @@ struct vbdev_ocf {

/* Management context */
struct vbdev_ocf_mngt_ctx mngt_ctx;

/* Cache conext */
struct vbdev_ocf_cache_ctx *cache_ctx;

struct {
bool in_progress;
int status;
} flush;

/* Exposed SPDK bdev. Registered in bdev layer */
struct spdk_bdev exp_bdev;

Expand Down
149 changes: 149 additions & 0 deletions module/bdev/ocf/vbdev_ocf_rpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,3 +442,152 @@ rpc_bdev_ocf_set_cache_mode(struct spdk_jsonrpc_request *request,
free_rpc_bdev_ocf_set_cache_mode(&req);
}
SPDK_RPC_REGISTER("bdev_ocf_set_cache_mode", rpc_bdev_ocf_set_cache_mode, SPDK_RPC_RUNTIME)

/* Structure to hold the parameters for this RPC method. */
struct rpc_bdev_ocf_start_flush {
char *name; /* main vbdev name */
};

static void
free_rpc_bdev_ocf_start_flush(struct rpc_bdev_ocf_start_flush *r)
{
free(r->name);
}

/* Structure to decode the input parameters for this RPC method. */
static const struct spdk_json_object_decoder rpc_bdev_ocf_start_flush_decoders[] = {
{"name", offsetof(struct rpc_bdev_ocf_set_cache_mode, name), spdk_json_decode_string},
};

struct get_ocf_start_flush_ctx {
struct spdk_jsonrpc_request *request;
struct vbdev_ocf *vbdev;
};

static void
rpc_bdev_ocf_start_flush_cmpl(ocf_cache_t cache, void *priv, int error)
{
struct get_ocf_start_flush_ctx *ctx = (struct get_ocf_stats_ctx *) priv;

ctx->vbdev->flush.in_progress = false;
ctx->vbdev->flush.status = error;

ocf_mngt_cache_read_unlock(cache);

free(ctx);
}

static void
rpc_bdev_ocf_start_flush_lock_cmpl(ocf_cache_t cache, void *priv, int error)
{
struct get_ocf_start_flush_ctx *ctx = (struct get_ocf_stats_ctx *) priv;

if (error) {
spdk_jsonrpc_send_error_response_fmt(ctx->request,
SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"Could not lock cache: %d", error);
free(ctx);
return;
}

ctx->vbdev->flush.in_progress = true;
ocf_mngt_cache_flush(cache, rpc_bdev_ocf_start_flush_cmpl, ctx);

spdk_jsonrpc_send_bool_response(ctx->request, true);
}

static void
rpc_bdev_ocf_start_flush(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_bdev_ocf_start_flush req = {NULL};
struct get_ocf_start_flush_ctx *ctx;
int status;

ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Not enough memory to process request");
goto end;
}

status = spdk_json_decode_object(params, rpc_bdev_ocf_start_flush_decoders,
SPDK_COUNTOF(rpc_bdev_ocf_start_flush_decoders),
&req);
if (status) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
free(ctx);
goto end;
}

ctx->vbdev = vbdev_ocf_get_by_name(req.name);
if (ctx->vbdev == NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
spdk_strerror(ENODEV));
free(ctx);
goto end;
}

ctx->request = request;
ocf_mngt_cache_read_lock(ctx->vbdev->ocf_cache, rpc_bdev_ocf_start_flush_lock_cmpl, ctx);

end:
free_rpc_bdev_ocf_start_flush(&req);
}
SPDK_RPC_REGISTER("bdev_ocf_start_flush", rpc_bdev_ocf_start_flush, SPDK_RPC_RUNTIME)

/* Structure to hold the parameters for this RPC method. */
struct rpc_bdev_ocf_get_flush_status {
char *name; /* main vbdev name */
};

static void
free_rpc_bdev_ocf_get_flush_status(struct rpc_bdev_ocf_get_flush_status *r)
{
free(r->name);
}

/* Structure to decode the input parameters for this RPC method. */
static const struct spdk_json_object_decoder rpc_bdev_ocf_get_flush_status_decoders[] = {
{"name", offsetof(struct rpc_bdev_ocf_set_cache_mode, name), spdk_json_decode_string},
};

static void
rpc_bdev_ocf_get_flush_status(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_bdev_ocf_get_flush_status req = {NULL};
struct spdk_json_write_ctx *w;
struct vbdev_ocf *vbdev;
int status;

status = spdk_json_decode_object(params, rpc_bdev_ocf_start_flush_decoders,
SPDK_COUNTOF(rpc_bdev_ocf_get_flush_status_decoders),
&req);
if (status) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid parameters");
goto end;
}

vbdev = vbdev_ocf_get_by_name(req.name);
if (vbdev == NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
spdk_strerror(ENODEV));
goto end;
}

w = spdk_jsonrpc_begin_result(request);

spdk_json_write_object_begin(w);
spdk_json_write_named_bool(w, "in_progress", vbdev->flush.in_progress);
if (!vbdev->flush.in_progress)
spdk_json_write_named_int32(w, "status", vbdev->flush.status);
spdk_json_write_object_end(w);

spdk_jsonrpc_end_result(request, w);
end:
free_rpc_bdev_ocf_start_flush(&req);
}
SPDK_RPC_REGISTER("bdev_ocf_get_flush_status", rpc_bdev_ocf_get_flush_status, SPDK_RPC_RUNTIME)
16 changes: 16 additions & 0 deletions scripts/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,22 @@ def bdev_ocf_set_cache_mode(args):
p.add_argument('mode', help='OCF cache mode', choices=['wb', 'wt', 'pt', 'wa', 'wi', 'wo'])
p.set_defaults(func=bdev_ocf_set_cache_mode)

def bdev_ocf_start_flush(args):
print_json(rpc.bdev.bdev_ocf_start_flush(args.client,
name=args.name))
p = subparsers.add_parser('bdev_ocf_start_flush',
help='Start flushing OCF block device')
p.add_argument('name', help='Name of OCF bdev')
p.set_defaults(func=bdev_ocf_start_flush)

def bdev_ocf_get_flush_status(args):
print_json(rpc.bdev.bdev_ocf_get_flush_status(args.client,
name=args.name))
p = subparsers.add_parser('bdev_ocf_get_flush_status',
help='Get flush status of OCF block device')
p.add_argument('name', help='Name of OCF bdev')
p.set_defaults(func=bdev_ocf_get_flush_status)

def bdev_malloc_create(args):
num_blocks = (args.total_size * 1024 * 1024) // args.block_size
print_json(rpc.bdev.bdev_malloc_create(args.client,
Expand Down
29 changes: 29 additions & 0 deletions scripts/rpc/bdev.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,35 @@ def bdev_ocf_set_cache_mode(client, name, mode):
return client.call('bdev_ocf_set_cache_mode', params)


def bdev_ocf_start_flush(client, name):
"""Start flushing OCF block device

Args:
name: name of OCF bdev
"""
params = {
'name': name,
}

return client.call('bdev_ocf_start_flush', params)


def bdev_ocf_get_flush_status(client, name):
"""Get flush status of OCF block device

Args:
name: name of OCF bdev

Returns:
Flush status
"""
params = {
'name': name,
}

return client.call('bdev_ocf_get_flush_status', params)


@deprecated_alias('construct_malloc_bdev')
def bdev_malloc_create(client, num_blocks, block_size, name=None, uuid=None):
"""Construct a malloc block device.
Expand Down