lib/bdev/ocf: add possibility to remove ocf instance
In current code there is no possibility to remove ocf instance permanently, even we call delete_ocf_bdev rpc command, on next examine this instance will be loaded. This patch introduces changes to delete_ocf_bdev rpc command. When we call this command via rpc, core related to particular vbdev will be removed from ocf cache before removing this cache instance. Thanks to that, on next examine we will not detect this core in cache metadata and therefore we will not create this instance on next load. However, in any other situation, we will not touch metadata, so in case of dirty shutdown/hot remove, on next load, we will recovery this instance. Signed-off-by: Marcin Dziegielewski <marcin.dziegielewski@intel.com> Change-Id: Iebef80989ea22ccea7f1b6ba4d734a40c1d5cc5d Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/465675 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
This commit is contained in:
parent
7ed0ec6832
commit
1ee2e81b30
@ -339,8 +339,8 @@ flush_vbdev(struct vbdev_ocf *vbdev)
|
||||
vbdev_ocf_mngt_poll(vbdev, flush_vbdev_poll);
|
||||
}
|
||||
|
||||
/* Procedures called during unregister */
|
||||
vbdev_ocf_mngt_fn unregister_path[] = {
|
||||
/* Procedures called during dirty unregister */
|
||||
vbdev_ocf_mngt_fn unregister_path_dirty[] = {
|
||||
flush_vbdev,
|
||||
wait_for_requests,
|
||||
stop_vbdev,
|
||||
@ -352,13 +352,30 @@ vbdev_ocf_mngt_fn unregister_path[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Procedures called during clean unregister */
|
||||
vbdev_ocf_mngt_fn unregister_path_clean[] = {
|
||||
flush_vbdev,
|
||||
wait_for_requests,
|
||||
detach_core,
|
||||
close_core_bdev,
|
||||
stop_vbdev,
|
||||
detach_cache,
|
||||
close_cache_bdev,
|
||||
unregister_finish,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Start asynchronous management operation using unregister_path */
|
||||
static void
|
||||
unregister_cb(void *opaque)
|
||||
{
|
||||
struct vbdev_ocf *vbdev = opaque;
|
||||
vbdev_ocf_mngt_fn *unregister_path;
|
||||
int rc;
|
||||
|
||||
unregister_path = vbdev->state.doing_clean_delete ?
|
||||
unregister_path_clean : unregister_path_dirty;
|
||||
|
||||
rc = vbdev_ocf_mngt_start(vbdev, unregister_path, NULL, NULL);
|
||||
if (rc) {
|
||||
SPDK_ERRLOG("Unable to unregister OCF bdev: %d\n", rc);
|
||||
@ -366,6 +383,38 @@ unregister_cb(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean remove case - remove core and then cache, this order
|
||||
* will remove instance permanently */
|
||||
static void
|
||||
_vbdev_ocf_destruct_clean(struct vbdev_ocf *vbdev)
|
||||
{
|
||||
if (vbdev->core.attached) {
|
||||
detach_core(vbdev);
|
||||
close_core_bdev(vbdev);
|
||||
}
|
||||
|
||||
if (vbdev->cache.attached) {
|
||||
detach_cache(vbdev);
|
||||
close_cache_bdev(vbdev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dirty shutdown/hot remove case - remove cache and then core, this order
|
||||
* will allow us to recover this instance in the future */
|
||||
static void
|
||||
_vbdev_ocf_destruct_dirty(struct vbdev_ocf *vbdev)
|
||||
{
|
||||
if (vbdev->cache.attached) {
|
||||
detach_cache(vbdev);
|
||||
close_cache_bdev(vbdev);
|
||||
}
|
||||
|
||||
if (vbdev->core.attached) {
|
||||
detach_core(vbdev);
|
||||
close_core_bdev(vbdev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unregister io device with callback to unregister_cb
|
||||
* This function is called during spdk_bdev_unregister */
|
||||
static int
|
||||
@ -391,13 +440,10 @@ vbdev_ocf_destruct(void *opaque)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vbdev->cache.attached) {
|
||||
detach_cache(vbdev);
|
||||
close_cache_bdev(vbdev);
|
||||
}
|
||||
if (vbdev->core.attached) {
|
||||
detach_core(vbdev);
|
||||
close_core_bdev(vbdev);
|
||||
if (vbdev->state.doing_clean_delete) {
|
||||
_vbdev_ocf_destruct_clean(vbdev);
|
||||
} else {
|
||||
_vbdev_ocf_destruct_dirty(vbdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -421,6 +467,17 @@ vbdev_ocf_delete(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Remove cores permanently and then stop OCF cache and unregister SPDK bdev */
|
||||
int
|
||||
vbdev_ocf_delete_clean(struct vbdev_ocf *vbdev, void (*cb)(void *, int),
|
||||
void *cb_arg)
|
||||
{
|
||||
vbdev->state.doing_clean_delete = true;
|
||||
|
||||
return vbdev_ocf_delete(vbdev, cb, cb_arg);
|
||||
}
|
||||
|
||||
|
||||
/* If vbdev is online, return its object */
|
||||
struct vbdev_ocf *
|
||||
vbdev_ocf_get_by_name(const char *name)
|
||||
|
@ -63,6 +63,8 @@ struct vbdev_ocf_qcxt {
|
||||
|
||||
/* Important states */
|
||||
struct vbdev_ocf_state {
|
||||
/* From the moment when clean delete started */
|
||||
bool doing_clean_delete;
|
||||
/* From the moment when finish started */
|
||||
bool doing_finish;
|
||||
/* From the moment when reset IO recieved, until it is completed */
|
||||
@ -200,6 +202,8 @@ struct vbdev_ocf_base *vbdev_ocf_get_base_by_name(const char *name);
|
||||
/* Stop OCF cache and unregister SPDK bdev */
|
||||
int vbdev_ocf_delete(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg);
|
||||
|
||||
int vbdev_ocf_delete_clean(struct vbdev_ocf *vbdev, void (*cb)(void *, int), 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 */
|
||||
|
@ -160,7 +160,7 @@ spdk_rpc_bdev_ocf_delete(struct spdk_jsonrpc_request *request,
|
||||
goto end;
|
||||
}
|
||||
|
||||
status = vbdev_ocf_delete(vbdev, delete_cb, request);
|
||||
status = vbdev_ocf_delete_clean(vbdev, delete_cb, request);
|
||||
if (status) {
|
||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||
"Could not delete OCF vbdev: %s",
|
||||
|
Loading…
Reference in New Issue
Block a user