Merge pull request #47 from mmichal10/task-cache-mode-per-io-class
Mutators for all io classes at once
This commit is contained in:
commit
21012df2f8
@ -57,15 +57,15 @@ struct ocf_io_class_info {
|
||||
* function meant to retrieve information pertaining to particular IO class,
|
||||
* specifically to fill ocf_io_class_info structure based on input parameters.
|
||||
*
|
||||
* @param[in] cache cache id, to which specified request pertains.
|
||||
* @param[in] cache cache handle, to which specified request pertains.
|
||||
* @param[in] io_class id of an io class which shall be retreived.
|
||||
* @param[out] info io class info structure to be filled as a
|
||||
* @param[out] info io class info structures to be filled as a
|
||||
* result of this function call.
|
||||
*
|
||||
* @return function returns 0 upon successful completion; appropriate error
|
||||
* code is returned otherwise
|
||||
*/
|
||||
int ocf_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
|
||||
int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
|
||||
struct ocf_io_class_info *info);
|
||||
|
||||
/**
|
||||
|
@ -543,8 +543,12 @@ struct ocf_mngt_io_class_config {
|
||||
uint32_t max_size;
|
||||
};
|
||||
|
||||
struct ocf_mngt_io_classes_config {
|
||||
struct ocf_mngt_io_class_config config[OCF_IO_CLASS_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configure IO class in given cache
|
||||
* @brief Configure IO classes in given cache
|
||||
*
|
||||
* @param[in] cache Cache handle
|
||||
* @param[in] cfg IO class configuration
|
||||
@ -552,8 +556,8 @@ struct ocf_mngt_io_class_config {
|
||||
* @retval 0 Configuration have been set successfully
|
||||
* @retval Non-zero Error occurred and configuration not been set
|
||||
*/
|
||||
int ocf_mngt_io_class_configure(ocf_cache_t cache,
|
||||
const struct ocf_mngt_io_class_config *cfg);
|
||||
int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache,
|
||||
const struct ocf_mngt_io_classes_config *cfg);
|
||||
|
||||
/**
|
||||
* @brief Set core sequential cutoff threshold
|
||||
|
@ -173,18 +173,19 @@ void ocf_core_stats_initialize(ocf_core_t core);
|
||||
void ocf_core_stats_initialize_all(ocf_cache_t cache);
|
||||
|
||||
/**
|
||||
* @brief ocf_io_class_get_stats retrieve cache statistics
|
||||
* @brief ocf_core_io_class_get_stats retrieve io class statistics
|
||||
* for given core
|
||||
*
|
||||
* Retrieve buffer of cache statistics for given cache instance.
|
||||
*
|
||||
* @param[in] core core ID to which request pertains
|
||||
* @param[in] io_class IO class, stats of which are requested
|
||||
* @param[out] stats statistics structure that shall be filled as
|
||||
* @param[in] core core handle to which request pertains
|
||||
* @param[in] part_id IO class, stats of which are requested
|
||||
* @param[out] stats statistic structure that shall be filled as
|
||||
* a result of this function invocation.
|
||||
*
|
||||
* @result zero upon successful completion; error code otherwise
|
||||
*/
|
||||
int ocf_io_class_get_stats(ocf_core_t core, uint32_t io_class,
|
||||
int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id,
|
||||
struct ocf_stats_io_class *stats);
|
||||
|
||||
/**
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../engine/engine_common.h"
|
||||
#include "../concurrency/ocf_cache_concurrency.h"
|
||||
#include "cleaning_priv.h"
|
||||
#include "../utils/utils_core.h"
|
||||
|
||||
#define OCF_ACP_DEBUG 0
|
||||
|
||||
@ -184,10 +185,6 @@ static struct acp_chunk_info *_acp_get_chunk(struct ocf_cache *cache,
|
||||
return &acp->chunk_info[core_line.core_id][chunk_id];
|
||||
}
|
||||
|
||||
#define for_each_core(cache, iter) \
|
||||
for (iter = 0; iter < OCF_CORE_MAX; iter++) \
|
||||
if (cache->core_conf_meta[iter].added)
|
||||
|
||||
static void _acp_remove_cores(struct ocf_cache *cache)
|
||||
{
|
||||
int i;
|
||||
|
@ -1847,7 +1847,6 @@ int ocf_mngt_cache_detach(ocf_cache_t cache)
|
||||
{
|
||||
int i, j, no;
|
||||
int result;
|
||||
ocf_cache_mode_t mode;
|
||||
|
||||
OCF_CHECK_NULL(cache);
|
||||
|
||||
@ -1856,9 +1855,10 @@ int ocf_mngt_cache_detach(ocf_cache_t cache)
|
||||
if (!env_atomic_read(&cache->attached))
|
||||
return -EINVAL;
|
||||
|
||||
/* temporarily switch to PT */
|
||||
mode = cache->conf_meta->cache_mode;
|
||||
result = _cache_mng_set_cache_mode(cache, ocf_cache_mode_pt, true);
|
||||
/* prevent dirty io */
|
||||
env_atomic_inc(&cache->flush_started);
|
||||
|
||||
result = ocf_mngt_cache_flush(cache, true);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
@ -1867,10 +1867,7 @@ int ocf_mngt_cache_detach(ocf_cache_t cache)
|
||||
env_waitqueue_wait(cache->pending_cache_wq,
|
||||
!env_atomic_read(&cache->pending_cache_requests));
|
||||
|
||||
/* Restore original mode in metadata - it will be used when new
|
||||
cache device is attached. By this tume all requests are served
|
||||
in direct-to-core mode. */
|
||||
cache->conf_meta->cache_mode = mode;
|
||||
ENV_BUG_ON(env_atomic_dec_return(&cache->flush_started) < 0);
|
||||
|
||||
/* remove cacheline metadata and cleaning policy meta for all cores */
|
||||
for (i = 0, j = 0; j < no && i < OCF_CORE_MAX; i++) {
|
||||
|
@ -18,7 +18,7 @@ static inline void _ocf_mngt_begin_flush(struct ocf_cache *cache)
|
||||
{
|
||||
env_mutex_lock(&cache->flush_mutex);
|
||||
|
||||
env_atomic_set(&cache->flush_started, 1);
|
||||
env_atomic_inc(&cache->flush_started);
|
||||
|
||||
env_waitqueue_wait(cache->pending_dirty_wq,
|
||||
!env_atomic_read(&cache->pending_dirty_requests));
|
||||
@ -26,7 +26,7 @@ static inline void _ocf_mngt_begin_flush(struct ocf_cache *cache)
|
||||
|
||||
static inline void _ocf_mngt_end_flush(struct ocf_cache *cache)
|
||||
{
|
||||
env_atomic_set(&cache->flush_started, 0);
|
||||
ENV_BUG_ON(env_atomic_dec_return(&cache->flush_started) < 0);
|
||||
|
||||
env_mutex_unlock(&cache->flush_mutex);
|
||||
}
|
||||
|
@ -109,67 +109,49 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache,
|
||||
|
||||
OCF_CHECK_NULL(cache->device);
|
||||
|
||||
OCF_METADATA_LOCK_WR();
|
||||
|
||||
dest_part = &cache->user_parts[part_id];
|
||||
|
||||
if (!ocf_part_is_added(dest_part)) {
|
||||
ocf_cache_log(cache, log_info, "Setting IO class, id: %u, "
|
||||
"name: '%s' [ ERROR ]\n", part_id, dest_part->config->name);
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
return -OCF_ERR_INVAL;
|
||||
}
|
||||
|
||||
if (!name || !name[0])
|
||||
return -OCF_ERR_IO_CLASS_NOT_EXIST;
|
||||
|
||||
if (part_id == PARTITION_DEFAULT) {
|
||||
/* Special behavior for default partition */
|
||||
|
||||
if (!name[0]) {
|
||||
/* Removing of default partition is not allowed */
|
||||
ocf_cache_log(cache, log_info,
|
||||
"Cannot remove unclassified IO class, "
|
||||
"id: %u [ ERROR ]\n", part_id);
|
||||
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try set partition size */
|
||||
if (_ocf_mngt_set_partition_size(cache, part_id, min, max)) {
|
||||
ocf_cache_log(cache, log_info,
|
||||
"Setting IO class size, id: %u, name: '%s' "
|
||||
"[ ERROR ]\n", part_id, dest_part->config->name);
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
return -OCF_ERR_INVAL;
|
||||
}
|
||||
ocf_part_set_prio(cache, dest_part, prio);
|
||||
ocf_part_sort(cache);
|
||||
dest_part->config->cache_mode = cache_mode;
|
||||
|
||||
ocf_cache_log(cache, log_info,
|
||||
"Updating Unclassified IO class, id: "
|
||||
"%u [ OK ]\n", part_id);
|
||||
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (name[0]) {
|
||||
/* Setting */
|
||||
result = env_strncpy(dest_part->config->name, sizeof(dest_part->config->name), name,
|
||||
result = env_strncpy(dest_part->config->name,
|
||||
sizeof(dest_part->config->name), name,
|
||||
sizeof(dest_part->config->name));
|
||||
if (result) {
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Try set partition size */
|
||||
if (_ocf_mngt_set_partition_size(cache, part_id, min, max)) {
|
||||
ocf_cache_log(cache, log_info,
|
||||
"Setting IO class size, id: %u, name: '%s' "
|
||||
"[ ERROR ]\n", part_id, dest_part->config->name);
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
return -OCF_ERR_INVAL;
|
||||
}
|
||||
|
||||
@ -178,7 +160,6 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache,
|
||||
ocf_cache_log(cache, log_info, "Updating existing IO "
|
||||
"class, id: %u, name: '%s' [ OK ]\n",
|
||||
part_id, dest_part->config->name);
|
||||
|
||||
} else {
|
||||
/* Adding new */
|
||||
ocf_part_set_valid(cache, part_id, true);
|
||||
@ -191,13 +172,28 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache,
|
||||
ocf_part_set_prio(cache, dest_part, prio);
|
||||
dest_part->config->cache_mode = cache_mode;
|
||||
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Clearing */
|
||||
static int _ocf_mngt_io_class_remove(ocf_cache_t cache,
|
||||
const struct ocf_mngt_io_class_config *cfg)
|
||||
{
|
||||
struct ocf_user_part *dest_part;
|
||||
ocf_part_id_t part_id = cfg->class_id;
|
||||
int result;
|
||||
|
||||
dest_part = &cache->user_parts[part_id];
|
||||
|
||||
OCF_CHECK_NULL(cache->device);
|
||||
|
||||
if (part_id == PARTITION_DEFAULT) {
|
||||
ocf_cache_log(cache, log_info,
|
||||
"Cannot remove unclassified IO class, "
|
||||
"id: %u [ ERROR ]\n", part_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ocf_part_is_valid(dest_part)) {
|
||||
/* Removing */
|
||||
|
||||
result = 0;
|
||||
|
||||
@ -211,11 +207,20 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache,
|
||||
/* Does not exist */
|
||||
result = -OCF_ERR_IO_CLASS_NOT_EXIST;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ocf_part_sort(cache);
|
||||
static int _ocf_mngt_io_class_edit(ocf_cache_t cache,
|
||||
const struct ocf_mngt_io_class_config *cfg)
|
||||
{
|
||||
int result;
|
||||
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
if (cfg->name) {
|
||||
result = _ocf_mngt_io_class_configure(cache, cfg);
|
||||
} else {
|
||||
result = _ocf_mngt_io_class_remove(cache, cfg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -226,6 +231,10 @@ static int _ocf_mngt_io_class_validate_cfg(ocf_cache_t cache,
|
||||
if (cfg->class_id >= OCF_IO_CLASS_MAX)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
/* Name set to null means particular io_class should be removed */
|
||||
if (!cfg->name)
|
||||
return 0;
|
||||
|
||||
/* TODO(r.baldyga): ocf_cache_mode_max is allowed for compatibility
|
||||
* with OCF 3.1 kernel adapter (upgrade in flight) and casadm.
|
||||
* Forbid ocf_cache_mode_max after fixing these problems.
|
||||
@ -250,17 +259,60 @@ static int _ocf_mngt_io_class_validate_cfg(ocf_cache_t cache,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ocf_mngt_io_class_configure(ocf_cache_t cache,
|
||||
const struct ocf_mngt_io_class_config *cfg)
|
||||
int ocf_mngt_cache_io_classes_configure(ocf_cache_t cache,
|
||||
const struct ocf_mngt_io_classes_config *cfg)
|
||||
{
|
||||
struct ocf_user_part *old_config;
|
||||
int result;
|
||||
int i;
|
||||
|
||||
OCF_CHECK_NULL(cache);
|
||||
OCF_CHECK_NULL(cfg);
|
||||
|
||||
result = _ocf_mngt_io_class_validate_cfg(cache, cfg);
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
|
||||
result = _ocf_mngt_io_class_validate_cfg(cache, &cfg->config[i]);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return _ocf_mngt_io_class_configure(cache, cfg);
|
||||
}
|
||||
|
||||
old_config = env_malloc(sizeof(cache->user_parts), ENV_MEM_NORMAL);
|
||||
if (!old_config)
|
||||
return -OCF_ERR_NO_MEM;
|
||||
|
||||
OCF_METADATA_LOCK_WR();
|
||||
|
||||
result = env_memcpy(old_config, sizeof(&cache->user_parts),
|
||||
cache->user_parts, sizeof(&cache->user_parts));
|
||||
if (result) {
|
||||
env_free(old_config);
|
||||
return result;
|
||||
}
|
||||
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
|
||||
result = _ocf_mngt_io_class_edit(cache, &cfg->config[i]);
|
||||
if (result && result != -OCF_ERR_IO_CLASS_NOT_EXIST) {
|
||||
ocf_cache_log(cache, log_err,
|
||||
"Failed to set new io class config\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
}
|
||||
|
||||
ocf_part_sort(cache);
|
||||
|
||||
if (ocf_metadata_flush_superblock(cache)) {
|
||||
ocf_cache_log(cache, log_err, "Failed to store new io class config\n");
|
||||
result = -OCF_ERR_WRITE_CACHE;
|
||||
}
|
||||
|
||||
err:
|
||||
if (result) {
|
||||
ENV_BUG_ON(env_memcpy(cache->user_parts, sizeof(&cache->user_parts),
|
||||
old_config, sizeof(&cache->user_parts)));
|
||||
}
|
||||
|
||||
OCF_METADATA_UNLOCK_WR();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -194,6 +194,8 @@ struct ocf_cache {
|
||||
struct ocf_core_meta_runtime *core_runtime_meta;
|
||||
|
||||
env_atomic flush_in_progress;
|
||||
|
||||
/* Prevent dirty requests. May be incremented recursively */
|
||||
env_atomic flush_started;
|
||||
|
||||
/* 1 if cache device attached, 0 otherwise */
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "engine/cache_engine.h"
|
||||
#include "utils/utils_part.h"
|
||||
|
||||
int ocf_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
|
||||
int ocf_cache_io_class_get_info(ocf_cache_t cache, uint32_t io_class,
|
||||
struct ocf_io_class_info *info)
|
||||
{
|
||||
ocf_part_id_t part_id = io_class;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "engine/cache_engine.h"
|
||||
#include "utils/utils_part.h"
|
||||
#include "utils/utils_cache_line.h"
|
||||
#include "utils/utils_core.h"
|
||||
|
||||
#ifdef OCF_DEBUG_STATS
|
||||
static void ocf_stats_debug_init(struct ocf_counters_debug *stats)
|
||||
@ -160,39 +161,30 @@ static void copy_debug_stats(struct ocf_stats_core_debug *dest,
|
||||
}
|
||||
#endif
|
||||
|
||||
int ocf_io_class_get_stats(ocf_core_t core, uint32_t io_class,
|
||||
int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id,
|
||||
struct ocf_stats_io_class *stats)
|
||||
{
|
||||
ocf_part_id_t part_id = io_class;
|
||||
ocf_cache_t cache;
|
||||
uint32_t i;
|
||||
uint32_t cache_occupancy_total = 0;
|
||||
struct ocf_counters_part *part_stat;
|
||||
ocf_core_id_t core_id;
|
||||
ocf_cache_t cache;
|
||||
|
||||
OCF_CHECK_NULL(core);
|
||||
OCF_CHECK_NULL(stats);
|
||||
|
||||
if (part_id < OCF_IO_CLASS_ID_MIN || part_id > OCF_IO_CLASS_ID_MAX)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
core_id = ocf_core_get_id(core);
|
||||
cache = ocf_core_get_cache(core);
|
||||
|
||||
if (!stats)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
if (io_class >= OCF_IO_CLASS_MAX)
|
||||
return -OCF_ERR_INVAL;
|
||||
|
||||
if (!ocf_part_is_valid(&cache->user_parts[part_id])) {
|
||||
/* Partition does not exist */
|
||||
if (!ocf_part_is_valid(&cache->user_parts[part_id]))
|
||||
return -OCF_ERR_IO_CLASS_NOT_EXIST;
|
||||
}
|
||||
|
||||
for (i = 0; i != OCF_CORE_MAX; ++i) {
|
||||
if (!env_bit_test(i, cache->conf_meta->
|
||||
valid_object_bitmap)) {
|
||||
continue;
|
||||
}
|
||||
cache_occupancy_total += env_atomic_read(&cache->
|
||||
core_runtime_meta[i].cached_clines);
|
||||
for_each_core(cache, i) {
|
||||
cache_occupancy_total += env_atomic_read(
|
||||
&cache->core_runtime_meta[i].cached_clines);
|
||||
}
|
||||
|
||||
part_stat = &core->counters->part_counters[part_id];
|
||||
|
13
src/utils/utils_core.h
Normal file
13
src/utils/utils_core.h
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#ifndef __UTILS_CORE_H__
|
||||
#define __UTILS_CORE_H__
|
||||
|
||||
#define for_each_core(cache, iter) \
|
||||
for (iter = 0; iter < OCF_CORE_MAX; iter++) \
|
||||
if (cache->core_conf_meta[iter].added)
|
||||
|
||||
#endif /* __UTILS_CORE_H__ */
|
@ -48,6 +48,9 @@ class TestGenerator(object):
|
||||
buf += self.get_empty_test_function()
|
||||
buf += self.get_test_main()
|
||||
|
||||
with open(dst_path, "w") as f:
|
||||
f.writelines(buf)
|
||||
|
||||
print dst_path + " generated successfully!"
|
||||
|
||||
def get_markups(self):
|
||||
|
274
tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c
Normal file
274
tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2018 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
/*
|
||||
* <tested_file_path>src/mngt/ocf_mngt_io_class.c</tested_file_path>
|
||||
* <tested_function>ocf_mngt_cache_io_classes_configure</tested_function>
|
||||
* <functions_to_leave>
|
||||
* INSERT HERE LIST OF FUNCTIONS YOU WANT TO LEAVE
|
||||
* ONE FUNCTION PER LINE
|
||||
* _ocf_mngt_io_class_edit
|
||||
* _ocf_mngt_io_class_configure
|
||||
* _ocf_mngt_io_class_remove
|
||||
* </functions_to_leave>
|
||||
*/
|
||||
|
||||
#undef static
|
||||
|
||||
#undef inline
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
#include "print_desc.h"
|
||||
|
||||
#include "ocf/ocf.h"
|
||||
#include "ocf_mngt_common.h"
|
||||
#include "../ocf_priv.h"
|
||||
#include "../metadata/metadata.h"
|
||||
#include "../engine/cache_engine.h"
|
||||
#include "../utils/utils_part.h"
|
||||
#include "../eviction/ops.h"
|
||||
#include "ocf_env.h"
|
||||
|
||||
/* Mocks reqired for compilation */
|
||||
int __wrap_ocf_log_raw(const struct ocf_logger *logger, ocf_logger_lvl_t lvl,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
|
||||
ocf_ctx_t __wrap_ocf_cache_get_ctx(ocf_cache_t cache)
|
||||
{
|
||||
}
|
||||
|
||||
char *__wrap_ocf_cache_get_name(ocf_cache_t cache)
|
||||
{
|
||||
}
|
||||
|
||||
int __wrap_ocf_mngt_cache_lock(ocf_cache_t cache)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __wrap_ocf_mngt_cache_unlock(ocf_cache_t cache)
|
||||
{
|
||||
}
|
||||
|
||||
void __wrap_ocf_metadata_lock(struct ocf_cache *cache, int rw)
|
||||
{
|
||||
}
|
||||
|
||||
void __wrap_ocf_metadata_unlock(struct ocf_cache *cache, int rw)
|
||||
{
|
||||
}
|
||||
|
||||
/* Functions mocked for testing purposes */
|
||||
bool __wrap_ocf_part_is_added(struct ocf_user_part *part)
|
||||
{
|
||||
function_called();
|
||||
return mock();
|
||||
}
|
||||
|
||||
int __wrap__ocf_mngt_set_partition_size(struct ocf_cache *cache,
|
||||
ocf_part_id_t part_id, uint32_t min, uint32_t max)
|
||||
{
|
||||
function_called();
|
||||
return mock();
|
||||
}
|
||||
|
||||
void __wrap_ocf_part_set_prio(struct ocf_cache *cache,
|
||||
struct ocf_user_part *part, int16_t prio)
|
||||
{
|
||||
function_called();
|
||||
}
|
||||
|
||||
bool __wrap_ocf_part_is_valid(struct ocf_user_part *part)
|
||||
{
|
||||
function_called();
|
||||
return mock();
|
||||
}
|
||||
|
||||
|
||||
void __wrap_ocf_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
|
||||
bool valid)
|
||||
{
|
||||
function_called();
|
||||
check_expected(valid);
|
||||
check_expected(id);
|
||||
}
|
||||
|
||||
int __wrap__ocf_mngt_io_class_validate_cfg(ocf_cache_t cache,
|
||||
const struct ocf_mngt_io_class_config *cfg)
|
||||
{
|
||||
function_called();
|
||||
return mock();
|
||||
}
|
||||
|
||||
void __wrap_ocf_part_sort(struct ocf_cache *cache)
|
||||
{
|
||||
function_called();
|
||||
}
|
||||
|
||||
int __wrap_ocf_metadata_flush_superblock(struct ocf_cache *cache)
|
||||
{
|
||||
function_called();
|
||||
return mock();
|
||||
}
|
||||
|
||||
/* Helper function for test prepration */
|
||||
static inline void setup_valid_config(struct ocf_mngt_io_class_config *cfg,
|
||||
bool remove)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
|
||||
cfg[i].class_id = i;
|
||||
cfg[i].name = remove ? NULL : "test_io_class_name" ;
|
||||
cfg[i].prio = i;
|
||||
cfg[i].cache_mode = ocf_cache_mode_pt;
|
||||
cfg[i].min_size = 2*i;
|
||||
cfg[i].max_size = 20*i;
|
||||
}
|
||||
}
|
||||
|
||||
static void ocf_mngt_io_classes_configure_test03(void **state)
|
||||
{
|
||||
struct ocf_cache cache = {0};
|
||||
struct ocf_mngt_io_classes_config cfg = {0};
|
||||
int result, i;
|
||||
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
|
||||
cache.user_parts[i].config =
|
||||
test_malloc(sizeof(struct ocf_user_part_config));
|
||||
}
|
||||
cache.device = 1;
|
||||
|
||||
setup_valid_config(cfg.config, true);
|
||||
|
||||
print_test_description("Remove all io classes");
|
||||
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
|
||||
expect_function_call(__wrap__ocf_mngt_io_class_validate_cfg);
|
||||
will_return(__wrap__ocf_mngt_io_class_validate_cfg, 0);
|
||||
}
|
||||
|
||||
/* Removing default io_class is not allowed */
|
||||
for (i = 1; i < OCF_IO_CLASS_MAX; i++) {
|
||||
expect_function_call(__wrap_ocf_part_is_valid);
|
||||
will_return(__wrap_ocf_part_is_valid, 1);
|
||||
|
||||
expect_function_call(__wrap_ocf_part_set_valid);
|
||||
/* Test assumes default partition has id equal 0 */
|
||||
expect_in_range(__wrap_ocf_part_set_valid, id, OCF_IO_CLASS_ID_MIN + 1,
|
||||
OCF_IO_CLASS_ID_MAX);
|
||||
expect_value(__wrap_ocf_part_set_valid, valid, false);
|
||||
}
|
||||
|
||||
expect_function_call(__wrap_ocf_part_sort);
|
||||
|
||||
expect_function_call(__wrap_ocf_metadata_flush_superblock);
|
||||
will_return(__wrap_ocf_metadata_flush_superblock, 0);
|
||||
|
||||
result = ocf_mngt_cache_io_classes_configure(&cache, &cfg);
|
||||
|
||||
assert_int_equal(result, 0);
|
||||
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++)
|
||||
test_free(cache.user_parts[i].config);
|
||||
}
|
||||
|
||||
static void ocf_mngt_io_classes_configure_test02(void **state)
|
||||
{
|
||||
struct ocf_cache cache = {0};
|
||||
struct ocf_mngt_io_classes_config cfg = {0};
|
||||
int result, i;
|
||||
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
|
||||
cache.user_parts[i].config =
|
||||
test_malloc(sizeof(struct ocf_user_part_config));
|
||||
}
|
||||
cache.device = 1;
|
||||
|
||||
setup_valid_config(cfg.config, false);
|
||||
|
||||
print_test_description("Configure all possible io classes");
|
||||
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++) {
|
||||
expect_function_call(__wrap__ocf_mngt_io_class_validate_cfg);
|
||||
will_return(__wrap__ocf_mngt_io_class_validate_cfg, 0);
|
||||
}
|
||||
|
||||
/* Configure default io_class */
|
||||
expect_function_call(__wrap_ocf_part_is_added);
|
||||
will_return(__wrap_ocf_part_is_added, 1);
|
||||
|
||||
expect_function_call(__wrap__ocf_mngt_set_partition_size);
|
||||
will_return(__wrap__ocf_mngt_set_partition_size, 0);
|
||||
|
||||
expect_function_call(__wrap_ocf_part_set_prio);
|
||||
|
||||
/* Configure custom io_classes */
|
||||
for (i = 1; i < OCF_IO_CLASS_MAX; i++) {
|
||||
expect_function_call(__wrap_ocf_part_is_added);
|
||||
will_return(__wrap_ocf_part_is_added, 1);
|
||||
|
||||
expect_function_call(__wrap__ocf_mngt_set_partition_size);
|
||||
will_return(__wrap__ocf_mngt_set_partition_size, 0);
|
||||
|
||||
expect_function_call(__wrap_ocf_part_is_valid);
|
||||
will_return(__wrap_ocf_part_is_valid, 0);
|
||||
|
||||
expect_function_call(__wrap_ocf_part_set_valid);
|
||||
expect_in_range(__wrap_ocf_part_set_valid, id, OCF_IO_CLASS_ID_MIN,
|
||||
OCF_IO_CLASS_ID_MAX);
|
||||
expect_value(__wrap_ocf_part_set_valid, valid, true);
|
||||
|
||||
expect_function_call(__wrap_ocf_part_set_prio);
|
||||
}
|
||||
|
||||
expect_function_call(__wrap_ocf_part_sort);
|
||||
|
||||
expect_function_call(__wrap_ocf_metadata_flush_superblock);
|
||||
will_return(__wrap_ocf_metadata_flush_superblock, 0);
|
||||
|
||||
result = ocf_mngt_cache_io_classes_configure(&cache, &cfg);
|
||||
|
||||
assert_int_equal(result, 0);
|
||||
|
||||
for (i = 0; i < OCF_IO_CLASS_MAX; i++)
|
||||
test_free(cache.user_parts[i].config);
|
||||
}
|
||||
|
||||
static void ocf_mngt_io_classes_configure_test01(void **state)
|
||||
{
|
||||
struct ocf_cache cache;
|
||||
struct ocf_mngt_io_classes_config cfg[OCF_IO_CLASS_MAX];
|
||||
int error_code = -OCF_ERR_INVAL;
|
||||
int result;
|
||||
|
||||
print_test_description("Invalid config - "
|
||||
"termination with error");
|
||||
|
||||
expect_function_call(__wrap__ocf_mngt_io_class_validate_cfg);
|
||||
will_return(__wrap__ocf_mngt_io_class_validate_cfg, error_code);
|
||||
|
||||
result = ocf_mngt_cache_io_classes_configure(&cache, &cfg);
|
||||
|
||||
assert_int_equal(result, error_code);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(ocf_mngt_io_classes_configure_test01),
|
||||
cmocka_unit_test(ocf_mngt_io_classes_configure_test02),
|
||||
cmocka_unit_test(ocf_mngt_io_classes_configure_test03)
|
||||
};
|
||||
|
||||
print_message("Unit test of src/mngt/ocf_mngt_io_class.c");
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
Loading…
Reference in New Issue
Block a user