Skip to content
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
3 changes: 2 additions & 1 deletion casadm/cas_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2524,7 +2524,7 @@ int partition_set_config(struct kcas_io_classes *cnfg)
return result;
}

int partition_setup(unsigned int cache_id, const char *file)
int partition_setup(unsigned int cache_id, bool reclassify, const char *file)
{
int result = 0;
CSVFILE *in;
Expand Down Expand Up @@ -2556,6 +2556,7 @@ int partition_setup(unsigned int cache_id, const char *file)
}

if (0 == partition_get_config(in, cnfg, cache_id)) {
cnfg->repart_all = reclassify;
result = partition_set_config(cnfg);
} else {
result = FAILURE;
Expand Down
4 changes: 2 additions & 2 deletions casadm/cas_lib.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright(c) 2012-2022 Intel Corporation
* Copyright(c) 2024 Huawei Technologies
* Copyright(c) 2024-2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand Down Expand Up @@ -279,7 +279,7 @@ int flush_core(unsigned int cache_id, unsigned int core_id);
int check_cache_device(const char *device_path);

int partition_list(unsigned int cache_id, unsigned int output_format);
int partition_setup(unsigned int cache_id, const char *file);
int partition_setup(unsigned int cache_id, bool reclassify, const char *file);
int partition_is_name_valid(const char *name);

int cas_module_version(char *buff, int size);
Expand Down
21 changes: 18 additions & 3 deletions casadm/cas_main.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright(c) 2012-2022 Intel Corporation
* Copyright(c) 2024 Huawei Technologies
* Copyright(c) 2024-2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand Down Expand Up @@ -1312,6 +1312,7 @@ enum {

io_class_opt_cache_id,
io_class_opt_cache_file_load,
io_class_opt_keep_classification,
io_class_opt_output_format,

io_class_opt_io_class_id,
Expand Down Expand Up @@ -1369,6 +1370,14 @@ static cli_option io_class_params_options[] = {
.priv = (1 << io_class_opt_subcmd_configure)
| (1 << io_class_opt_flag_required)
},
[io_class_opt_keep_classification] = {
.short_name = 'k',
.long_name = "keep-classification",
.desc = "Prevents reclassification of data in IO classes with IDs matching previous configuration",
.args_count = 0,
.arg = NULL,
.priv = (1 << io_class_opt_subcmd_configure)
},
[io_class_opt_output_format] = {
.short_name = 'o',
.long_name = "output-format",
Expand Down Expand Up @@ -1434,6 +1443,7 @@ struct {
int io_class_id;
int cache_mode;
int io_class_prio;
bool reclassify;
int output_format;
uint32_t min;
uint32_t max;
Expand All @@ -1443,6 +1453,7 @@ struct {
.subcmd = io_class_opt_subcmd_unknown,
.cache_id = 0,
.file = "",
.reclassify = true,
.output_format = OUTPUT_FORMAT_DEFAULT
};

Expand Down Expand Up @@ -1479,6 +1490,10 @@ int io_class_handle_option(char *opt, const char **arg)
return FAILURE;

io_class_params_options[io_class_opt_output_format].priv |= (1 << io_class_opt_flag_set);
} else if (!strcmp(opt, "keep-classification")) {
io_class_params.reclassify = false;

io_class_params_options[io_class_opt_keep_classification].priv |= (1 << io_class_opt_flag_set);
}

return 0;
Expand Down Expand Up @@ -1534,8 +1549,8 @@ int io_class_handle() {

switch (io_class_params.subcmd) {
case io_class_opt_subcmd_configure:
return partition_setup(io_class_params.cache_id,
io_class_params.file);
return partition_setup(io_class_params.cache_id,
io_class_params.reclassify, io_class_params.file);
case io_class_opt_subcmd_list:
return partition_list(io_class_params.cache_id,
io_class_params.output_format);
Expand Down
5 changes: 4 additions & 1 deletion modules/cas_cache/layer_cache_management.c
Original file line number Diff line number Diff line change
Expand Up @@ -1746,7 +1746,7 @@ int cache_mngt_set_partitions(const char *cache_name, size_t name_len,
result = ocf_mngt_cache_io_classes_configure(cache, io_class_cfg);
if (result == -OCF_ERR_IO_CLASS_NOT_EXIST)
result = 0;
if(result)
if (result)
goto out_configure;

result = _cache_mngt_save_sync(cache);
Expand All @@ -1762,6 +1762,9 @@ int cache_mngt_set_partitions(const char *cache_name, size_t name_len,
if (result) {
while (class_id--)
cas_cls_rule_destroy(cache, cls_rule[class_id]);
} else {
/* repartition without management lock */
ocf_repart_to_default(cache, io_class_cfg, cfg->repart_all);
}
out_not_running:
ocf_mngt_cache_put(cache);
Expand Down
3 changes: 2 additions & 1 deletion modules/include/cas_ioctl_codes.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright(c) 2012-2022 Intel Corporation
* Copyright(c) 2024 Huawei Technologies
* Copyright(c) 2024-2025 Huawei Technologies
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand Down Expand Up @@ -250,6 +250,7 @@ struct kcas_io_class {
struct kcas_io_classes {
/** Cache ID */
uint16_t cache_id;
bool repart_all;

int ext_err_code;

Expand Down
4 changes: 2 additions & 2 deletions test/functional/api/cas/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ def reset_counters(self) -> Output:
def set_cache_mode(self, cache_mode: CacheMode, flush=None) -> Output:
return casadm.set_cache_mode(cache_mode, self.cache_id, flush)

def load_io_class(self, file_path: str) -> Output:
return casadm.load_io_classes(self.cache_id, file_path)
def load_io_class(self, file_path: str, keep_classification: bool = False) -> Output:
return casadm.load_io_classes(self.cache_id, file_path, keep_classification)

def list_io_classes(self) -> list:
return get_io_class_list(self.cache_id)
Expand Down
4 changes: 2 additions & 2 deletions test/functional/api/cas/casadm.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,9 @@ def flush_core(cache_id: int, core_id: int, shortcut: bool = False) -> Output:
return output


def load_io_classes(cache_id: int, file: str, shortcut: bool = False) -> Output:
def load_io_classes(cache_id: int, file: str, keep_classification: bool = False, shortcut: bool = False) -> Output:
output = TestRun.executor.run(
load_io_classes_cmd(cache_id=str(cache_id), file=file, shortcut=shortcut)
load_io_classes_cmd(cache_id=str(cache_id), file=file, keep_classification=keep_classification, shortcut=shortcut)
)
if output.exit_code != 0:
raise CmdException("Load IO class command failed.", output)
Expand Down
6 changes: 4 additions & 2 deletions test/functional/api/cas/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# Copyright(c) 2019-2022 Intel Corporation
# Copyright(c) 2024 Huawei Technologies Co., Ltd.
# Copyright(c) 2024-2025 Huawei Technologies Co., Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#

Expand Down Expand Up @@ -338,10 +338,12 @@ def flush_core_cmd(cache_id: str, core_id: str, shortcut: bool = False) -> str:
return casadm_bin + command


def load_io_classes_cmd(cache_id: str, file: str, shortcut: bool = False) -> str:
def load_io_classes_cmd(cache_id: str, file: str, keep_classification: bool = False, shortcut: bool = False) -> str:
command = " -C -C" if shortcut else " --io-class --load-config"
command += (" -i " if shortcut else " --cache-id ") + cache_id
command += (" -f " if shortcut else " --file ") + file
if keep_classification:
command += (" -k" if shortcut else " --keep-classification")
return casadm_bin + command


Expand Down
1 change: 1 addition & 0 deletions test/functional/api/cas/cli_help_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@
r"Options that are valid with --load-config \(-C\) are:",
r"-i --cache-id \<ID\> Identifier of cache instance \<1-16384\>",
r"-f --file \<FILE\> Configuration file containing IO class definition",
r"-k --keep-classification Prevents reclassification of data in IO classes with IDs matching previous configuration",
r"Lists currently configured IO classes:",
r"Usage: casadm --io-class --list --cache-id \<ID\> \[option\.\.\.\]",
r"Options that are valid with --list \(-L\) are:",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#
# Copyright(c) 2025 Huawei Technologies Co., Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#

import pytest

from api.cas.cache_config import (
CacheMode,
CacheLineSize,
CleaningPolicy,
UnalignedIo,
KernelParameters,
UseIoScheduler,
)
from api.cas.cli import load_io_classes_cmd
from core.test_run import TestRun
from storage_devices.disk import DiskType, DiskTypeSet, DiskTypeLowerThan
from test_tools.peach_fuzzer.peach_fuzzer import PeachFuzzer
from tests.security.fuzzy.kernel.common.common import (
prepare_cas_instance,
get_fuzz_config,
run_cmd_and_validate,
)
from tests.security.fuzzy.kernel.fuzzy_with_io.common.common import (
get_basic_workload,
mount_point,
)


@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand]))
@pytest.mark.require_disk("core", DiskTypeLowerThan("cache"))
@pytest.mark.parametrizex("cache_mode", CacheMode)
@pytest.mark.parametrizex("cache_line_size", CacheLineSize)
@pytest.mark.parametrizex("cleaning_policy", CleaningPolicy)
@pytest.mark.parametrizex("unaligned_io", UnalignedIo)
@pytest.mark.parametrizex("use_io_scheduler", UseIoScheduler)
def test_fuzzy_io_class_load_config_flags(
cache_mode, cache_line_size, cleaning_policy, unaligned_io, use_io_scheduler
):
"""
title: Fuzzy test for casadm 'load IO class configuration' command – flags.
description: |
Using Peach Fuzzer check Open CAS ability of handling wrong flags in
'load IO class configuration' command.
pass_criteria:
- System did not crash
- Open CAS still works.
"""
with TestRun.step(
"Start cache with configuration and add core device, make filesystem and mount it"
):
cache_disk = TestRun.disks["cache"]
core_disk = TestRun.disks["core"]
cache, core = prepare_cas_instance(
cache_device=cache_disk,
core_device=core_disk,
cache_mode=cache_mode,
cache_line_size=cache_line_size,
kernel_params=KernelParameters(unaligned_io, use_io_scheduler),
cleaning_policy=cleaning_policy,
mount_point=mount_point,
)

with TestRun.step("Run fio in background"):
fio = get_basic_workload(mount_point)
fio_pid = fio.run_in_background()
if not TestRun.executor.check_if_process_exists(fio_pid):
raise Exception("Fio is not running.")

with TestRun.step("Prepare PeachFuzzer"):
valid_values = ["", "-k", "--keep-classification"]
valid_values = [v.encode("ascii") for v in valid_values]
PeachFuzzer.generate_config(get_fuzz_config("flags.yml"))
base_cmd = load_io_classes_cmd(cache_id=str(cache.cache_id), file="/etc/opencas/ioclass-config.csv") + " {param}"
commands = PeachFuzzer.get_fuzzed_command(
command_template=base_cmd, count=TestRun.usr.fuzzy_iter_count
)

for index, cmd in TestRun.iteration(
enumerate(commands), f"Run command {TestRun.usr.fuzzy_iter_count} times"
):
with TestRun.step(f"Iteration {index + 1}"):
if not TestRun.executor.check_if_process_exists(fio_pid):
raise Exception("Fio is not running.")

run_cmd_and_validate(
cmd=cmd,
value_name="Flag",
is_valid=cmd.param in valid_values,
)