ocf/rpc: Add bdev_ocf_set_cache_mode method

This method allows to dynamically switch cache mode on OCF bdev

Signed-off-by: Rafal Stefanowski <rafal.stefanowski@intel.com>
Change-Id: I933273e35bb9f29528657f8f6800c6b52dde32e5
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6547
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Rafal Stefanowski 2021-02-21 05:25:32 +01:00 committed by Tomasz Zawadzki
parent 1b837766f0
commit 5bdaec6322
8 changed files with 200 additions and 0 deletions

View File

@ -2232,6 +2232,47 @@ Example response:
}
~~~
## bdev_ocf_set_cache_mode {#rpc_bdev_ocf_set_cache_mode}
Set new cache mode on OCF bdev.
### Parameters
Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
name | Required | string | Bdev name
mode | Required | string | OCF cache mode: wb, wt, pt, wa, wi, wo
### Response
New cache mode name.
### Example
Example request:
~~~
{
"params": {
"name": "ocf0",
"mode": "pt",
},
"jsonrpc": "2.0",
"method": "bdev_ocf_set_cache_mode",
"id": 1
}
~~~
Example response:
~~~
{
"jsonrpc": "2.0",
"id": 1,
"result": "pt"
}
~~~
## bdev_malloc_create {#rpc_bdev_malloc_create}
Construct @ref bdev_config_malloc

View File

@ -1479,6 +1479,31 @@ vbdev_ocf_construct(const char *vbdev_name,
}
}
/* Set new cache mode on OCF cache */
void
vbdev_ocf_set_cache_mode(struct vbdev_ocf *vbdev,
const char *cache_mode_name,
void (*cb)(int, struct vbdev_ocf *, void *),
void *cb_arg)
{
ocf_cache_t cache;
ocf_cache_mode_t cache_mode;
int rc;
cache = vbdev->ocf_cache;
cache_mode = ocf_get_cache_mode(cache_mode_name);
rc = ocf_mngt_cache_trylock(cache);
if (rc) {
cb(rc, vbdev, cb_arg);
return;
}
rc = ocf_mngt_cache_set_mode(cache, cache_mode);
ocf_mngt_cache_unlock(cache);
cb(rc, vbdev, cb_arg);
}
/* This called if new device is created in SPDK application
* If that device named as one of base bdevs of OCF vbdev,
* claim and open them */

View File

@ -203,6 +203,13 @@ int vbdev_ocf_delete(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_
int vbdev_ocf_delete_clean(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg);
/* Set new cache mode on OCF cache */
void vbdev_ocf_set_cache_mode(
struct vbdev_ocf *vbdev,
const char *cache_mode_name,
void (*cb)(int, struct vbdev_ocf *, void *),
void *cb_arg);
typedef void (*vbdev_ocf_foreach_fn)(struct vbdev_ocf *, void *);
/* Execute fn for each OCF device that is online or waits for base devices */

View File

@ -33,6 +33,7 @@
#include "vbdev_ocf.h"
#include "stats.h"
#include "utils.h"
#include "spdk/log.h"
#include "spdk/rpc.h"
#include "spdk/string.h"
@ -359,3 +360,71 @@ end:
}
SPDK_RPC_REGISTER("bdev_ocf_get_bdevs", rpc_bdev_ocf_get_bdevs, SPDK_RPC_RUNTIME)
SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_ocf_get_bdevs, get_ocf_bdevs)
/* Structure to hold the parameters for this RPC method. */
struct rpc_bdev_ocf_set_cache_mode {
char *name; /* main vbdev name */
char *mode; /* OCF cache mode to switch to */
};
static void
free_rpc_bdev_ocf_set_cache_mode(struct rpc_bdev_ocf_set_cache_mode *r)
{
free(r->name);
free(r->mode);
}
/* Structure to decode the input parameters for this RPC method. */
static const struct spdk_json_object_decoder rpc_bdev_ocf_set_cache_mode_decoders[] = {
{"name", offsetof(struct rpc_bdev_ocf_set_cache_mode, name), spdk_json_decode_string},
{"mode", offsetof(struct rpc_bdev_ocf_set_cache_mode, mode), spdk_json_decode_string},
};
static void
cache_mode_cb(int status, struct vbdev_ocf *vbdev, void *cb_arg)
{
struct spdk_jsonrpc_request *request = cb_arg;
struct spdk_json_write_ctx *w;
if (status) {
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"Could not change OCF vbdev cache mode: %d",
status);
} else {
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_string(w, ocf_get_cache_modename(
ocf_cache_get_mode(vbdev->ocf_cache)));
spdk_jsonrpc_end_result(request, w);
}
}
static void
rpc_bdev_ocf_set_cache_mode(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_bdev_ocf_set_cache_mode req = {NULL};
struct vbdev_ocf *vbdev;
int status;
status = spdk_json_decode_object(params, rpc_bdev_ocf_set_cache_mode_decoders,
SPDK_COUNTOF(rpc_bdev_ocf_set_cache_mode_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;
}
vbdev_ocf_set_cache_mode(vbdev, req.mode, cache_mode_cb, request);
end:
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)

View File

@ -325,6 +325,16 @@ if __name__ == "__main__":
p.add_argument('name', nargs='?', default=None, help='name of OCF vbdev or name of cache device or name of core device (optional)')
p.set_defaults(func=bdev_ocf_get_bdevs)
def bdev_ocf_set_cache_mode(args):
print_json(rpc.bdev.bdev_ocf_set_cache_mode(args.client,
name=args.name,
mode=args.mode))
p = subparsers.add_parser('bdev_ocf_set_cache_mode',
help='Set cache mode of OCF block device')
p.add_argument('name', help='Name of OCF bdev')
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_malloc_create(args):
num_blocks = (args.total_size * 1024 * 1024) // args.block_size
print_json(rpc.bdev.bdev_malloc_create(args.client,

View File

@ -204,6 +204,24 @@ def bdev_ocf_get_bdevs(client, name=None):
return client.call('bdev_ocf_get_bdevs', params)
def bdev_ocf_set_cache_mode(client, name, mode):
"""Set cache mode of OCF block device
Args:
name: name of OCF bdev
mode: OCF cache mode: {'wb', 'wt', 'pt', 'wa', 'wi', 'wo'}
Returns:
New cache mode name
"""
params = {
'name': name,
'mode': mode,
}
return client.call('bdev_ocf_set_cache_mode', params)
@deprecated_alias('construct_malloc_bdev')
def bdev_malloc_create(client, num_blocks, block_size, name=None, uuid=None):
"""Construct a malloc block device.

View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
curdir=$(dirname $(readlink -f "${BASH_SOURCE[0]}"))
rootdir=$(readlink -f $curdir/../../..)
source $rootdir/test/common/autotest_common.sh
rpc_py=$rootdir/scripts/rpc.py
cache_modes=(wt wb pt wa wi wo)
$SPDK_BIN_DIR/iscsi_tgt &
spdk_pid=$!
waitforlisten $spdk_pid
# Prepare OCF cache
$rpc_py bdev_malloc_create 101 512 -b Malloc0
$rpc_py bdev_malloc_create 101 512 -b Malloc1
$rpc_py bdev_ocf_create Cache wt Malloc0 Malloc1
$rpc_py bdev_ocf_get_bdevs | jq -e \
'.[0] | .started and .cache.attached and .core.attached'
# Change cache mode
for cache_mode in "${cache_modes[@]}"; do
$rpc_py bdev_ocf_set_cache_mode Cache $cache_mode
done
trap - SIGINT SIGTERM EXIT
killprocess $spdk_pid

View File

@ -12,3 +12,4 @@ run_test "ocf_create_destruct" "$testdir/management/create-destruct.sh"
run_test "ocf_multicore" "$testdir/management/multicore.sh"
run_test "ocf_persistent_metadata" "$testdir/management/persistent-metadata.sh"
run_test "ocf_remove" "$testdir/management/remove.sh"
run_test "ocf_configuration_change" "$testdir/management/configuration-change.sh"