ftl: management framework

Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Kozlowski Mateusz <mateusz.kozlowski@intel.com>
Change-Id: I8261863e80a53a37183b0148d4a08fa97e208dda
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13289
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
This commit is contained in:
Artur Paszkiewicz 2022-06-22 12:11:47 +02:00 committed by Tomasz Zawadzki
parent 5140958837
commit 293cdc484b
11 changed files with 2015 additions and 2 deletions

View File

@ -11,9 +11,10 @@ SO_MINOR := 0
CFLAGS += -I.
FTL_SUBDIRS := utils
FTL_SUBDIRS := mngt utils
C_SRCS = ftl_core.c
C_SRCS += mngt/ftl_mngt.c
SPDK_MAP_FILE = $(abspath $(CURDIR)/spdk_ftl.map)

View File

@ -14,5 +14,6 @@
#include "ftl_core.h"
#include "ftl_internal.h"
#include "mngt/ftl_mngt.h"
SPDK_LOG_REGISTER_COMPONENT(ftl_core)

570
lib/ftl/mngt/ftl_mngt.c Normal file
View File

@ -0,0 +1,570 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) Intel Corporation.
* All rights reserved.
*/
#include "spdk/queue.h"
#include "spdk/assert.h"
#include "spdk/env.h"
#include "ftl_mngt.h"
#include "ftl_core.h"
struct ftl_mngt_step_status {
uint64_t start;
uint64_t stop;
int status;
int silent;
TAILQ_ENTRY(ftl_mngt_step) entry;
};
struct ftl_mngt_step {
void *ctx;
const struct ftl_mngt_step_desc *desc;
struct ftl_mngt_step_status action;
struct ftl_mngt_step_status rollback;
};
struct ftl_mngt_process {
struct spdk_ftl_dev *dev;
int status;
int silent;
bool rollback;
bool continuing;
struct {
ftl_mngt_fn cb;
void *cb_ctx;
struct spdk_thread *thread;
} caller;
void *ctx;
uint64_t tsc_start;
uint64_t tsc_stop;
const struct ftl_mngt_process_desc *desc;
TAILQ_HEAD(, ftl_mngt_step) action_queue_todo;
TAILQ_HEAD(, ftl_mngt_step) action_queue_done;
TAILQ_HEAD(, ftl_mngt_step) rollback_queue_todo;
TAILQ_HEAD(, ftl_mngt_step) rollback_queue_done;
struct {
struct ftl_mngt_step step;
struct ftl_mngt_step_desc desc;
} cleanup;
struct ftl_mng_tracer *tracer;
};
static void action_next(struct ftl_mngt_process *mngt);
static void action_msg(void *ctx);
static void action_execute(struct ftl_mngt_process *mngt);
static void action_done(struct ftl_mngt_process *mngt, int status);
static void rollback_next(struct ftl_mngt_process *mngt);
static void rollback_msg(void *ctx);
static void rollback_execute(struct ftl_mngt_process *mngt);
static void rollback_done(struct ftl_mngt_process *mngt, int status);
static inline struct ftl_mngt_step *
get_current_step(struct ftl_mngt_process *mngt)
{
if (!mngt->rollback) {
return TAILQ_FIRST(&mngt->action_queue_todo);
} else {
return TAILQ_FIRST(&mngt->rollback_queue_todo);
}
}
static int
init_step(struct ftl_mngt_process *mngt,
const struct ftl_mngt_step_desc *desc)
{
struct ftl_mngt_step *step;
step = calloc(1, sizeof(*step));
if (!step) {
return -ENOMEM;
}
/* Initialize the step's argument */
if (desc->ctx_size) {
step->ctx = calloc(1, desc->ctx_size);
if (!step->ctx) {
free(step);
return -ENOMEM;
}
}
step->desc = desc;
TAILQ_INSERT_TAIL(&mngt->action_queue_todo, step, action.entry);
return 0;
}
static void
free_mngt(struct ftl_mngt_process *mngt)
{
TAILQ_HEAD(, ftl_mngt_step) steps;
if (!mngt) {
return;
}
TAILQ_INIT(&steps);
TAILQ_CONCAT(&steps, &mngt->action_queue_todo, action.entry);
TAILQ_CONCAT(&steps, &mngt->action_queue_done, action.entry);
while (!TAILQ_EMPTY(&steps)) {
struct ftl_mngt_step *step = TAILQ_FIRST(&steps);
TAILQ_REMOVE(&steps, step, action.entry);
free(step->ctx);
free(step);
}
free(mngt->ctx);
free(mngt);
}
static struct ftl_mngt_process *
allocate_mngt(struct spdk_ftl_dev *dev,
const struct ftl_mngt_process_desc *pdesc,
ftl_mngt_fn cb, void *cb_ctx)
{
struct ftl_mngt_process *mngt;
/* Initialize management process */
mngt = calloc(1, sizeof(*mngt));
if (!mngt) {
goto error;
}
mngt->dev = dev;
mngt->caller.cb = cb;
mngt->caller.cb_ctx = cb_ctx;
mngt->caller.thread = spdk_get_thread();
/* Initialize process context */
if (pdesc->ctx_size) {
mngt->ctx = calloc(1, pdesc->ctx_size);
if (!mngt->ctx) {
goto error;
}
}
mngt->tsc_start = spdk_get_ticks();
mngt->desc = pdesc;
TAILQ_INIT(&mngt->action_queue_todo);
TAILQ_INIT(&mngt->action_queue_done);
TAILQ_INIT(&mngt->rollback_queue_todo);
TAILQ_INIT(&mngt->rollback_queue_done);
return mngt;
error:
free_mngt(mngt);
return NULL;
}
int
ftl_mngt_process_execute(struct spdk_ftl_dev *dev,
const struct ftl_mngt_process_desc *pdesc,
ftl_mngt_fn cb, void *cb_ctx)
{
const struct ftl_mngt_step_desc *sdesc;
struct ftl_mngt_process *mngt;
int rc = 0;
mngt = allocate_mngt(dev, pdesc, cb, cb_ctx);
if (!mngt) {
rc = -ENOMEM;
goto error;
}
if (pdesc->error_handler) {
/* Initialize a step for error handler */
mngt->cleanup.step.desc = &mngt->cleanup.desc;
mngt->cleanup.desc.name = "Handle ERROR";
mngt->cleanup.desc.cleanup = pdesc->error_handler;
/* Queue error handler to the rollback queue, it will be executed at the end */
TAILQ_INSERT_HEAD(&mngt->rollback_queue_todo, &mngt->cleanup.step,
rollback.entry);
}
/* Initialize steps */
sdesc = mngt->desc->steps;
while (sdesc->action) {
rc = init_step(mngt, sdesc);
if (rc) {
goto error;
}
sdesc++;
}
action_execute(mngt);
return 0;
error:
free_mngt(mngt);
return rc;
}
int
ftl_mngt_process_rollback(struct spdk_ftl_dev *dev,
const struct ftl_mngt_process_desc *pdesc,
ftl_mngt_fn cb, void *cb_ctx)
{
const struct ftl_mngt_step_desc *sdesc;
struct ftl_mngt_process *mngt;
int rc = 0;
mngt = allocate_mngt(dev, pdesc, cb, cb_ctx);
if (!mngt) {
rc = -ENOMEM;
goto error;
}
/* Initialize steps for rollback */
sdesc = mngt->desc->steps;
while (sdesc->action) {
if (!sdesc->cleanup) {
sdesc++;
continue;
}
rc = init_step(mngt, sdesc);
if (rc) {
goto error;
}
sdesc++;
}
/* Build rollback list */
struct ftl_mngt_step *step;
TAILQ_FOREACH(step, &mngt->action_queue_todo, action.entry) {
step->action.silent = true;
TAILQ_INSERT_HEAD(&mngt->rollback_queue_todo, step,
rollback.entry);
}
mngt->rollback = true;
rollback_execute(mngt);
return 0;
error:
free_mngt(mngt);
return rc;
}
struct spdk_ftl_dev *
ftl_mngt_get_dev(struct ftl_mngt_process *mngt)
{
return mngt->dev;
}
int
ftl_mngt_alloc_step_ctx(struct ftl_mngt_process *mngt, size_t size)
{
struct ftl_mngt_step *step = get_current_step(mngt);
void *arg = calloc(1, size);
if (!arg) {
return -ENOMEM;
}
free(step->ctx);
step->ctx = arg;
return 0;
}
void *
ftl_mngt_get_step_ctx(struct ftl_mngt_process *mngt)
{
return get_current_step(mngt)->ctx;
}
void *
ftl_mngt_get_process_ctx(struct ftl_mngt_process *mngt)
{
return mngt->ctx;
}
void *
ftl_mngt_get_caller_ctx(struct ftl_mngt_process *mngt)
{
return mngt->caller.cb_ctx;
}
int
ftl_mngt_get_status(struct ftl_mngt_process *mngt)
{
return mngt->status;
}
void
ftl_mngt_next_step(struct ftl_mngt_process *mngt)
{
if (false == mngt->rollback) {
action_next(mngt);
} else {
rollback_next(mngt);
}
}
void
ftl_mngt_skip_step(struct ftl_mngt_process *mngt)
{
if (mngt->rollback) {
get_current_step(mngt)->rollback.silent = true;
} else {
get_current_step(mngt)->action.silent = true;
}
ftl_mngt_next_step(mngt);
}
void
ftl_mngt_continue_step(struct ftl_mngt_process *mngt)
{
if (!mngt->continuing) {
if (false == mngt->rollback) {
action_execute(mngt);
} else {
rollback_execute(mngt);
}
}
mngt->continuing = true;
}
static void
child_cb(struct spdk_ftl_dev *dev, struct ftl_mngt_process *child)
{
int status = ftl_mngt_get_status(child);
struct ftl_mngt_process *parent = ftl_mngt_get_caller_ctx(child);
child->silent = true;
if (status) {
ftl_mngt_fail_step(parent);
} else {
ftl_mngt_next_step(parent);
}
}
void
ftl_mngt_call_process(struct ftl_mngt_process *mngt,
const struct ftl_mngt_process_desc *pdesc)
{
if (ftl_mngt_process_execute(mngt->dev, pdesc, child_cb, mngt)) {
ftl_mngt_fail_step(mngt);
} else {
if (mngt->rollback) {
get_current_step(mngt)->rollback.silent = true;
} else {
get_current_step(mngt)->action.silent = true;
}
}
}
void
ftl_mngt_call_process_rollback(struct ftl_mngt_process *mngt,
const struct ftl_mngt_process_desc *pdesc)
{
if (ftl_mngt_process_rollback(mngt->dev, pdesc, child_cb, mngt)) {
ftl_mngt_fail_step(mngt);
} else {
if (mngt->rollback) {
get_current_step(mngt)->rollback.silent = true;
} else {
get_current_step(mngt)->action.silent = true;
}
}
}
void
ftl_mngt_fail_step(struct ftl_mngt_process *mngt)
{
mngt->status = -1;
if (false == mngt->rollback) {
action_done(mngt, -1);
} else {
rollback_done(mngt, -1);
}
mngt->rollback = true;
rollback_execute(mngt);
}
static inline float
tsc_to_ms(uint64_t tsc)
{
float ms = tsc;
ms /= (float)spdk_get_ticks_hz();
ms *= 1000.0;
return ms;
}
static void
trace_step(struct spdk_ftl_dev *dev, struct ftl_mngt_step *step, bool rollback)
{
uint64_t duration;
const char *what = rollback ? "Rollback" : "Action";
int silent = rollback ? step->rollback.silent : step->action.silent;
if (silent) {
return;
}
FTL_NOTICELOG(dev, "%s\n", what);
FTL_NOTICELOG(dev, "\t name: %s\n", step->desc->name);
duration = step->action.stop - step->action.start;
FTL_NOTICELOG(dev, "\t duration: %.3f ms\n", tsc_to_ms(duration));
FTL_NOTICELOG(dev, "\t status: %d\n", step->action.status);
}
static void
process_summary(struct ftl_mngt_process *mngt)
{
uint64_t duration;
if (mngt->silent) {
return;
}
duration = mngt->tsc_stop - mngt->tsc_start;
FTL_NOTICELOG(mngt->dev, "Management process finished, "
"name '%s', duration = %.3f ms, result %d\n",
mngt->desc->name,
tsc_to_ms(duration),
mngt->status);
}
static void
finish_msg(void *ctx)
{
struct ftl_mngt_process *mngt = ctx;
mngt->caller.cb(mngt->dev, mngt);
process_summary(mngt);
free_mngt(mngt);
}
void
ftl_mngt_finish(struct ftl_mngt_process *mngt)
{
mngt->tsc_stop = spdk_get_ticks();
spdk_thread_send_msg(mngt->caller.thread, finish_msg, mngt);
}
/*
* Actions
*/
static void
action_next(struct ftl_mngt_process *mngt)
{
if (TAILQ_EMPTY(&mngt->action_queue_todo)) {
/* Nothing to do, finish the management process */
ftl_mngt_finish(mngt);
return;
} else {
action_done(mngt, 0);
action_execute(mngt);
}
}
static void
action_msg(void *ctx)
{
struct ftl_mngt_process *mngt = ctx;
struct ftl_mngt_step *step;
mngt->continuing = false;
if (TAILQ_EMPTY(&mngt->action_queue_todo)) {
ftl_mngt_finish(mngt);
return;
}
step = TAILQ_FIRST(&mngt->action_queue_todo);
if (!step->action.start) {
step->action.start = spdk_get_ticks();
}
step->desc->action(mngt->dev, mngt);
}
static void
action_execute(struct ftl_mngt_process *mngt)
{
spdk_thread_send_msg(mngt->dev->core_thread, action_msg, mngt);
}
static void
action_done(struct ftl_mngt_process *mngt, int status)
{
struct ftl_mngt_step *step;
assert(!TAILQ_EMPTY(&mngt->action_queue_todo));
step = TAILQ_FIRST(&mngt->action_queue_todo);
TAILQ_REMOVE(&mngt->action_queue_todo, step, action.entry);
TAILQ_INSERT_TAIL(&mngt->action_queue_done, step, action.entry);
if (step->desc->cleanup) {
TAILQ_INSERT_HEAD(&mngt->rollback_queue_todo, step,
rollback.entry);
}
step->action.stop = spdk_get_ticks();
step->action.status = status;
trace_step(mngt->dev, step, false);
}
/*
* Rollback
*/
static void
rollback_next(struct ftl_mngt_process *mngt)
{
if (TAILQ_EMPTY(&mngt->rollback_queue_todo)) {
/* Nothing to do, finish the management process */
ftl_mngt_finish(mngt);
return;
} else {
rollback_done(mngt, 0);
rollback_execute(mngt);
}
}
static void
rollback_msg(void *ctx)
{
struct ftl_mngt_process *mngt = ctx;
struct ftl_mngt_step *step;
mngt->continuing = false;
if (TAILQ_EMPTY(&mngt->rollback_queue_todo)) {
ftl_mngt_finish(mngt);
return;
}
step = TAILQ_FIRST(&mngt->rollback_queue_todo);
if (!step->rollback.start) {
step->rollback.start = spdk_get_ticks();
}
step->desc->cleanup(mngt->dev, mngt);
}
static void
rollback_execute(struct ftl_mngt_process *mngt)
{
spdk_thread_send_msg(mngt->dev->core_thread, rollback_msg, mngt);
}
void
rollback_done(struct ftl_mngt_process *mngt, int status)
{
struct ftl_mngt_step *step;
assert(!TAILQ_EMPTY(&mngt->rollback_queue_todo));
step = TAILQ_FIRST(&mngt->rollback_queue_todo);
TAILQ_REMOVE(&mngt->rollback_queue_todo, step, rollback.entry);
TAILQ_INSERT_TAIL(&mngt->rollback_queue_done, step, rollback.entry);
step->rollback.stop = spdk_get_ticks();
step->rollback.status = status;
trace_step(mngt->dev, step, true);
}

294
lib/ftl/mngt/ftl_mngt.h Normal file
View File

@ -0,0 +1,294 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) Intel Corporation.
* All rights reserved.
*/
#ifndef FTL_MNGT_H
#define FTL_MNGT_H
#include "spdk/stdinc.h"
#include "spdk/ftl.h"
struct spdk_ftl_dev;
struct ftl_mngt_process;
/**
* The FTL management callback function
*
* @param dev FTL device
* @param mngt FTL management handle
*/
typedef void (*ftl_mngt_fn)(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt);
/**
* The FTL management step descriptior
*/
struct ftl_mngt_step_desc {
/**
* Name of the step
*/
const char *name;
/**
* Size of the step argument (context)
*
* The step context will be allocated before execution of step's
* callback.
*
* @note The context can be reallocated (freed and newly allocated
* when calling ftl_mngt_alloc_step_ctx). The main usage is the ability
* to set this value to 0 and only allocate as needed if the step is
* going to be extremely similar - eg. recovery from shared memory and
* disk - in case of shm all the data is already available in memory, while
* recovery from disk needs extra context to be able to synchronize IO. This
* allows for saving a little bit of time on alloc/dealloc in the cases where
* execution time may be critical.
* @note It doesn't work like realloc
* @note The context can be retrieved within callback when calling
* ftl_mngt_get_step_ctx
*/
size_t ctx_size;
/**
* Step callback function
*/
ftl_mngt_fn action;
/**
* It the step requires cleanup this is right place to put your handler.
* When a FTL management process fails cleanup callbacks are executed
* in rollback procedure. Cleanup functions are executed in reverse
* order to actions already called.
*/
ftl_mngt_fn cleanup;
};
/**
* The FTL management process descriptor
*/
struct ftl_mngt_process_desc {
/**
* The name of the process
*/
const char *name;
/**
* Size of the process argument (context)
*
* The process context will be allocated before execution of the first
* step
*
* @note To get context of the process within FTL management callback,
* execute ftl_mngt_get_process_ctx
*/
size_t ctx_size;
/**
* Pointer to the additional error handler when the process fails
*/
ftl_mngt_fn error_handler;
/**
* The FTL process steps
*
* The process context will be allocated before execution of the first
* step
*
* @note The step array terminator shall end with action equals NULL
*/
struct ftl_mngt_step_desc steps[];
};
/**
* @brief Executes the FTL management process defined by the process descriptor
*
* In case of an error all already executed steps will have their rollback functions
* called in reverse order.
*
* @param dev FTL device
* @param process The descriptor of process to be executed
* @param cb Caller callback
* @param cb_ctx Caller context
*
* @return Result of invoking the operation
* @retval 0 - The FTL management process has been started
* @retval Non-zero An error occurred when starting The FTL management process
*/
int ftl_mngt_process_execute(struct spdk_ftl_dev *dev,
const struct ftl_mngt_process_desc *process,
ftl_mngt_fn cb, void *cb_ctx);
/**
* @brief Executes rollback on the FTL management process defined by the process
* descriptor
*
* All cleanup function from steps will be executed in reversed order
*
* @param dev FTL device
* @param process The descriptor of process to be rollback
* @param cb Caller callback
* @param cb_ctx Caller context
*
* @return Result of invoking the rollback operation
* @retval 0 - Rollback of the FTL management process has been started
* @retval Non-zero An error occurred when starting the rollback
*/
int ftl_mngt_process_rollback(struct spdk_ftl_dev *dev,
const struct ftl_mngt_process_desc *process,
ftl_mngt_fn cb, void *cb_ctx);
/*
* FTL management API for steps
*/
/**
* @brief Gets FTL device
*
* @param mngt FTL management handle
*
* @note This function can be invoked within step handler only
*
* @return FTL device
*/
struct spdk_ftl_dev *ftl_mngt_get_dev(struct ftl_mngt_process *mngt);
/**
* @brief Allocates a context for the management step
*
* @param mngt FTL management handle
* @param size Size of the step context
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @return Operation result
* @retval 0 Operation successful
* @retval Non-zero Operation failure
*/
int ftl_mngt_alloc_step_ctx(struct ftl_mngt_process *mngt, size_t size);
/**
* @brief Gets the management step context
*
* @param mngt FTL management handle
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @return Context of the step containing pointer to buffer and its size
*/
void *ftl_mngt_get_step_ctx(struct ftl_mngt_process *mngt);
/**
* @brief Gets the management process context
*
* @param mngt FTL management handle
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @return Context of the process containing pointer to buffer and its size
*/
void *ftl_mngt_get_process_ctx(struct ftl_mngt_process *mngt);
/**
* @brief Gets the caller context
*
* @param mngt FTL management handle
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @return Pointer to the caller context
*/
void *ftl_mngt_get_caller_ctx(struct ftl_mngt_process *mngt);
/**
* @brief Gets the status of executed management process
*
* @param mngt FTL management handle
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @return The operation result of the management process
* @retval 0 Operation successful
* @retval Non-zero Operation failure
*/
int ftl_mngt_get_status(struct ftl_mngt_process *mngt);
/**
* @brief Finishes the management process immediately
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @param mngt FTL management handle of process to be finished
*/
void ftl_mngt_finish(struct ftl_mngt_process *mngt);
/**
* @brief Completes the step currently in progress and jump to a next one
*
* If no more steps to be executed then the management process is finished and
* caller callback is invoked
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @param mngt FTL management handle
*/
void ftl_mngt_next_step(struct ftl_mngt_process *mngt);
/**
* @brief Skips the step currently in progress and jump to a next one
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @param mngt FTL management handle
*/
void ftl_mngt_skip_step(struct ftl_mngt_process *mngt);
/**
* @brief Continue the step currently in progress
*
* This causes invoking the same step handler in next iteration of the
* management process. This mechanism can be used by a job when polling for
* something.
*
* @note This function can be invoked within ftl_mngt_fn callback only
*
* @param mngt FTL management handle
*/
void ftl_mngt_continue_step(struct ftl_mngt_process *mngt);
/**
* @brief Fail the step currently in progress.
*
* It stops executing all steps and starts the rollback procedure (calling
* the cleanup functions of all already executed steps).
* If executed from a cleanup function, it will stop executing and the following
* cleanup functions (if any) will be executed.
*
* @param mngt FTL management handle
*/
void ftl_mngt_fail_step(struct ftl_mngt_process *mngt);
/**
* @brief Calls another management process
*
* Ends the current step and executes specified process and finally continues
* executing the the remaining steps
*
* @param mngt The management handle
* @param process The management process to be called
*/
void ftl_mngt_call_process(struct ftl_mngt_process *mngt,
const struct ftl_mngt_process_desc *process);
/**
* @brief Calls rollback steps of another management process
*
* Ends the current step and executes rollback steps of specified process
* and finally continues executing the remaining steps in the original process
*
* @param mngt The management handle
* @param process The management process to be called to execute rollback
*/
void ftl_mngt_call_process_rollback(struct ftl_mngt_process *mngt,
const struct ftl_mngt_process_desc *process);
#endif /* LIB_FTL_FTL_MNGT_H */

View File

@ -60,7 +60,7 @@ DEPDIRS-blobfs := log thread blob trace util
DEPDIRS-event := log util thread $(JSON_LIBS) trace init
DEPDIRS-init := jsonrpc json log rpc thread util
DEPDIRS-ftl := log
DEPDIRS-ftl := log thread
DEPDIRS-nbd := log util thread $(JSON_LIBS) bdev
DEPDIRS-nvmf := accel log sock util nvme thread $(JSON_LIBS) trace bdev
ifeq ($(CONFIG_RDMA),y)

View File

@ -12,6 +12,7 @@ DIRS-$(CONFIG_IDXD) += idxd
DIRS-$(CONFIG_REDUCE) += reduce
ifeq ($(OS),Linux)
DIRS-$(CONFIG_VHOST) += vhost
DIRS-y += ftl
endif
.PHONY: all clean $(DIRS-y)

View File

@ -0,0 +1,16 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Intel Corporation.
# All rights reserved.
#
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
DIRS-y = ftl_mngt
.PHONY: all clean $(DIRS-y)
all: $(DIRS-y)
clean: $(DIRS-y)
include $(SPDK_ROOT_DIR)/mk/spdk.subdirs.mk

1
test/unit/lib/ftl/ftl_mngt/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
ftl_mngt_ut

View File

@ -0,0 +1,12 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Intel Corporation.
# All rights reserved.
#
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../../..)
TEST_FILE = ftl_mngt_ut.c
include $(SPDK_ROOT_DIR)/mk/spdk.unittest.mk
CFLAGS += -I$(SPDK_ROOT_DIR)/lib/ftl

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,10 @@ function unittest_event() {
$valgrind $testdir/lib/event/reactor.c/reactor_ut
}
function unittest_ftl() {
$valgrind $testdir/lib/ftl/ftl_mngt/ftl_mngt_ut
}
function unittest_iscsi() {
$valgrind $testdir/lib/iscsi/conn.c/conn_ut
$valgrind $testdir/lib/iscsi/param.c/param_ut
@ -206,6 +210,9 @@ fi
run_test "unittest_blob_blobfs" unittest_blob
run_test "unittest_event" unittest_event
if [ $(uname -s) = Linux ]; then
run_test "unittest_ftl" unittest_ftl
fi
run_test "unittest_accel" $valgrind $testdir/lib/accel/accel.c/accel_engine_ut
run_test "unittest_ioat" $valgrind $testdir/lib/ioat/ioat.c/ioat_ut