249 lines
8.6 KiB
Python
249 lines
8.6 KiB
Python
#
|
|
# Copyright(c) 2019-2021 Intel Corporation
|
|
# Copyright(c) 2024-2025 Huawei Technologies Co., Ltd.
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
from datetime import timedelta
|
|
from typing import List
|
|
|
|
from api.cas import casadm
|
|
from api.cas.cache_config import (
|
|
CacheLineSize,
|
|
CleaningPolicy,
|
|
CacheStatus,
|
|
CacheMode,
|
|
FlushParametersAlru,
|
|
FlushParametersAcp,
|
|
SeqCutOffParameters,
|
|
SeqCutOffPolicy,
|
|
PromotionPolicy,
|
|
PromotionParametersNhit,
|
|
CacheConfig,
|
|
)
|
|
from api.cas.casadm_params import StatsFilter
|
|
from api.cas.casadm_parser import (get_cas_devices_dict, get_cores, get_flush_parameters_alru,
|
|
get_flush_parameters_acp, get_io_class_list)
|
|
from api.cas.core import Core
|
|
from api.cas.dmesg import get_metadata_size_on_device
|
|
from api.cas.statistics import CacheStats, CacheIoClassStats
|
|
from connection.utils.output import Output
|
|
from storage_devices.device import Device
|
|
from test_tools.os_tools import sync
|
|
from type_def.size import Size
|
|
|
|
|
|
class Cache:
|
|
def __init__(
|
|
self, cache_id: int, device: Device = None, cache_line_size: CacheLineSize = None
|
|
) -> None:
|
|
self.cache_id = cache_id
|
|
self.cache_device = device if device else self.__get_cache_device()
|
|
self.__cache_line_size = cache_line_size
|
|
|
|
def __get_cache_device(self) -> Device | None:
|
|
caches_dict = get_cas_devices_dict()["caches"]
|
|
cache = next(
|
|
iter([cache for cache in caches_dict.values() if cache["id"] == self.cache_id])
|
|
)
|
|
|
|
if not cache:
|
|
return None
|
|
|
|
if cache["device_path"] is "-":
|
|
return None
|
|
|
|
return Device(path=cache["device_path"])
|
|
|
|
def get_core_devices(self) -> list:
|
|
return get_cores(self.cache_id)
|
|
|
|
def get_cache_line_size(self) -> CacheLineSize:
|
|
if self.__cache_line_size is None:
|
|
stats = self.get_statistics()
|
|
stats_line_size = stats.config_stats.cache_line_size
|
|
self.__cache_line_size = CacheLineSize(stats_line_size)
|
|
return self.__cache_line_size
|
|
|
|
def get_cleaning_policy(self) -> CleaningPolicy:
|
|
stats = self.get_statistics()
|
|
cp = stats.config_stats.cleaning_policy
|
|
return CleaningPolicy[cp]
|
|
|
|
def get_metadata_size_in_ram(self) -> Size:
|
|
stats = self.get_statistics()
|
|
return stats.config_stats.metadata_memory_footprint
|
|
|
|
def get_metadata_size_on_disk(self) -> Size:
|
|
return get_metadata_size_on_device(cache_id=self.cache_id)
|
|
|
|
def get_occupancy(self):
|
|
return self.get_statistics().usage_stats.occupancy
|
|
|
|
def get_status(self) -> CacheStatus:
|
|
status = (
|
|
self.get_statistics(stat_filter=[StatsFilter.conf])
|
|
.config_stats.status.replace(" ", "_")
|
|
.lower()
|
|
)
|
|
return CacheStatus[status]
|
|
|
|
@property
|
|
def size(self) -> Size:
|
|
return self.get_statistics().config_stats.cache_size
|
|
|
|
def get_cache_mode(self) -> CacheMode:
|
|
return CacheMode[self.get_statistics().config_stats.write_policy.upper()]
|
|
|
|
def get_dirty_blocks(self) -> Size:
|
|
return self.get_statistics().usage_stats.dirty
|
|
|
|
def get_dirty_for(self) -> timedelta:
|
|
return self.get_statistics().config_stats.dirty_for
|
|
|
|
def get_clean_blocks(self) -> Size:
|
|
return self.get_statistics().usage_stats.clean
|
|
|
|
def get_flush_parameters_alru(self) -> FlushParametersAlru:
|
|
return get_flush_parameters_alru(self.cache_id)
|
|
|
|
def get_flush_parameters_acp(self) -> FlushParametersAcp:
|
|
return get_flush_parameters_acp(self.cache_id)
|
|
|
|
# Casadm methods:
|
|
|
|
def get_statistics(
|
|
self,
|
|
stat_filter: List[StatsFilter] = None,
|
|
percentage_val: bool = False,
|
|
) -> CacheStats:
|
|
return CacheStats(
|
|
cache_id=self.cache_id,
|
|
filter=stat_filter,
|
|
percentage_val=percentage_val,
|
|
)
|
|
|
|
def get_io_class_statistics(
|
|
self,
|
|
io_class_id: int = None,
|
|
stat_filter: List[StatsFilter] = None,
|
|
percentage_val: bool = False,
|
|
) -> CacheIoClassStats:
|
|
return CacheIoClassStats(
|
|
cache_id=self.cache_id,
|
|
filter=stat_filter,
|
|
io_class_id=io_class_id,
|
|
percentage_val=percentage_val,
|
|
)
|
|
|
|
def flush_cache(self) -> Output:
|
|
output = casadm.flush_cache(cache_id=self.cache_id)
|
|
sync()
|
|
return output
|
|
|
|
def purge_cache(self) -> Output:
|
|
output = casadm.purge_cache(cache_id=self.cache_id)
|
|
sync()
|
|
return output
|
|
|
|
def stop(self, no_data_flush: bool = False) -> Output:
|
|
return casadm.stop_cache(self.cache_id, no_data_flush)
|
|
|
|
def add_core(self, core_dev, core_id: int = None) -> Core:
|
|
return casadm.add_core(self, core_dev, core_id)
|
|
|
|
def remove_core(self, core_id: int, force: bool = False) -> Output:
|
|
return casadm.remove_core(self.cache_id, core_id, force)
|
|
|
|
def remove_inactive_core(self, core_id: int, force: bool = False) -> Output:
|
|
return casadm.remove_inactive(self.cache_id, core_id, force)
|
|
|
|
def reset_counters(self) -> Output:
|
|
return casadm.reset_counters(self.cache_id)
|
|
|
|
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 list_io_classes(self) -> list:
|
|
return get_io_class_list(self.cache_id)
|
|
|
|
def set_seq_cutoff_parameters(self, seq_cutoff_param: SeqCutOffParameters) -> Output:
|
|
return casadm.set_param_cutoff(
|
|
self.cache_id,
|
|
threshold=seq_cutoff_param.threshold,
|
|
policy=seq_cutoff_param.policy,
|
|
promotion_count=seq_cutoff_param.promotion_count,
|
|
)
|
|
|
|
def set_seq_cutoff_threshold(self, threshold: Size) -> Output:
|
|
return casadm.set_param_cutoff(self.cache_id, threshold=threshold, policy=None)
|
|
|
|
def set_seq_cutoff_policy(self, policy: SeqCutOffPolicy) -> Output:
|
|
return casadm.set_param_cutoff(self.cache_id, threshold=None, policy=policy)
|
|
|
|
def set_cleaning_policy(self, cleaning_policy: CleaningPolicy) -> Output:
|
|
return casadm.set_param_cleaning(self.cache_id, cleaning_policy)
|
|
|
|
def set_params_acp(self, acp_params: FlushParametersAcp) -> Output:
|
|
return casadm.set_param_cleaning_acp(
|
|
self.cache_id,
|
|
int(acp_params.wake_up_time.total_milliseconds()) if acp_params.wake_up_time else None,
|
|
int(acp_params.flush_max_buffers) if acp_params.flush_max_buffers else None,
|
|
)
|
|
|
|
def set_params_alru(self, alru_params: FlushParametersAlru) -> Output:
|
|
return casadm.set_param_cleaning_alru(
|
|
self.cache_id,
|
|
(int(alru_params.wake_up_time.total_seconds()) if alru_params.wake_up_time else None),
|
|
(
|
|
int(alru_params.staleness_time.total_seconds())
|
|
if alru_params.staleness_time
|
|
else None
|
|
),
|
|
(alru_params.flush_max_buffers if alru_params.flush_max_buffers else None),
|
|
(
|
|
int(alru_params.activity_threshold.total_milliseconds())
|
|
if alru_params.activity_threshold
|
|
else None
|
|
),
|
|
)
|
|
|
|
def set_promotion_policy(self, policy: PromotionPolicy) -> Output:
|
|
return casadm.set_param_promotion(self.cache_id, policy)
|
|
|
|
def set_params_nhit(self, promotion_params_nhit: PromotionParametersNhit) -> Output:
|
|
return casadm.set_param_promotion_nhit(
|
|
self.cache_id,
|
|
threshold=promotion_params_nhit.threshold,
|
|
trigger=promotion_params_nhit.trigger,
|
|
)
|
|
|
|
def get_cache_config(self) -> CacheConfig:
|
|
return CacheConfig(
|
|
self.get_cache_line_size(),
|
|
self.get_cache_mode(),
|
|
self.get_cleaning_policy(),
|
|
)
|
|
|
|
def standby_detach(self, shortcut: bool = False) -> Output:
|
|
return casadm.standby_detach_cache(cache_id=self.cache_id, shortcut=shortcut)
|
|
|
|
def standby_activate(self, device: Device, shortcut: bool = False) -> Output:
|
|
return casadm.standby_activate_cache(
|
|
cache_id=self.cache_id, cache_dev=device, shortcut=shortcut
|
|
)
|
|
|
|
def attach(self, device: Device, force: bool = False) -> Output:
|
|
cmd_output = casadm.attach_cache(cache_id=self.cache_id, device=device, force=force)
|
|
return cmd_output
|
|
|
|
def detach(self) -> Output:
|
|
cmd_output = casadm.detach_cache(cache_id=self.cache_id)
|
|
return cmd_output
|
|
|
|
def has_volatile_metadata(self) -> bool:
|
|
return self.get_metadata_size_on_disk() == Size.zero()
|