/* * Copyright(c) 2012-2021 Intel Corporation * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __CAS_LIB_H__ #define __CAS_LIB_H__ #include #include #include #include #include #include #include #include #include #include #include "safeclib/safe_str_lib.h" #include #include #define CTRL_DEV_PATH "/dev/cas_ctrl" #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #define FAILURE 1 /**< default non-zero exit code. */ #define INTERRUPTED 2 /**< if command is interrupted */ #define SUCCESS 0 /**< 0 exit code from majority of our functions \ stands for success */ struct core_device { int id; int cache_id; char path[MAX_STR_LEN]; struct kcas_core_info info; }; struct cache_device { int id; int state; int expected_core_count; char device[MAX_STR_LEN]; int mode; int eviction_policy; int cleaning_policy; int promotion_policy; int dirty; int flushed; unsigned size; int core_count; struct core_device cores[]; }; struct cas_param { char *name; char *unit; char **value_names; uint32_t (*transform_value)(uint32_t value); uint32_t value; bool select; }; enum output_format_t { OUTPUT_FORMAT_INVALID = 0, OUTPUT_FORMAT_TABLE = 1, OUTPUT_FORMAT_CSV = 2, OUTPUT_FORMAT_DEFAULT = OUTPUT_FORMAT_TABLE }; #define STATS_FILTER_INVALID 0 #define STATS_FILTER_CONF (1 << 0) #define STATS_FILTER_USAGE (1 << 1) #define STATS_FILTER_REQ (1 << 2) #define STATS_FILTER_BLK (1 << 3) #define STATS_FILTER_ERR (1 << 4) #define STATS_FILTER_IOCLASS (1 << 5) #define STATS_FILTER_ALL (STATS_FILTER_CONF | \ STATS_FILTER_USAGE | \ STATS_FILTER_REQ | \ STATS_FILTER_BLK | \ STATS_FILTER_ERR) #define STATS_FILTER_DEFAULT STATS_FILTER_ALL #define STATS_FILTER_COUNTERS (STATS_FILTER_REQ | STATS_FILTER_BLK | STATS_FILTER_ERR) const char *cleaning_policy_to_name(uint8_t policy); const char *promotion_policy_to_name(uint8_t policy); const char *cache_mode_to_name(uint8_t cache_mode); const char *get_cache_state_name(int cache_state); const char *get_core_state_name(int core_state); const char *seq_cutoff_policy_to_name(uint8_t seq_cutoff_policy); __attribute__((format(printf, 2, 3))) typedef int (*cas_printf_t)(int log_level, const char *format, ...); extern cas_printf_t cas_printf; __attribute__((format(printf, 2, 3))) int caslog(int log_level, const char *template, ...); #define CAS_CLI_HELP_METADATA_VARIANTS \ CAS_METADATA_VARIANT_MAX"|" \ CAS_METADATA_VARIANT_MIX"|" \ CAS_METADATA_VARIANT_MIN /* for CLI commands arguments */ #define YES 1 #define NO 0 #define UNDEFINED -1 void metadata_memory_footprint(uint64_t size, float *footprint, const char **units); int start_cache(uint16_t cache_id, unsigned int cache_init, const char *cache_device, ocf_cache_mode_t cache_mode, ocf_cache_line_size_t line_size, int force); int stop_cache(uint16_t cache_id, int flush); #ifdef WI_AVAILABLE #define CAS_CLI_HELP_START_CACHE_MODES "wt|wb|wa|pt|wi|wo" #define CAS_CLI_HELP_SET_CACHE_MODES "wt|wb|wa|pt|wi|wo" #define CAS_CLI_HELP_SET_CACHE_MODES_FULL "Write-Through, Write-Back, Write-Around, Pass-Through, Write-Invalidate, Write-Only" #define CAS_CLI_HELP_START_CACHE_MODES_FULL "Write-Through, Write-Back, Write-Around, Pass-Through, Write-Invalidate, Write-Only" #else #define CAS_CLI_HELP_START_CACHE_MODES "wt|wb|wa|pt|wo" #define CAS_CLI_HELP_SET_CACHE_MODES "wt|wb|wa|pt|wo" #define CAS_CLI_HELP_START_CACHE_MODES_FULL "Write-Through, Write-Back, Write-Around, Pass-Through, Write-Only" #define CAS_CLI_HELP_SET_CACHE_MODES_FULL "Write-Through, Write-Back, Write-Around, Pass-Through, Write-Only" #endif /** * @brief handle set cache param command * @param cache_id id of cache device * @param params parameter array * @return exit code of successful completion is 0; * nonzero exit code means failure */ int cache_params_set(unsigned int cache_id, struct cas_param *params); /** * @brief get cache param value * @param cache_id id of cache device * @param param_id id of cache parameter to retrive * @param param variable to pass value to caller * @return exit code of successful completion is 0; * nonzero exit code means failure */ int cache_get_param(unsigned int cache_id, unsigned int param_id, struct cas_param *param); /** * @brief handle get cache param command * @param cache_id id of cache device * @param params parameter array * @return exit code of successful completion is 0; * nonzero exit code means failure */ int cache_params_get(unsigned int cache_id, struct cas_param *params, unsigned int output_format); /** * @brief handle set core param command * @param cache_id id of cache device * @param core_id id of core device * @param params parameter array * @return exit code of successful completion is 0; * nonzero exit code means failure */ int core_params_set(unsigned int cache_id, unsigned int core_id, struct cas_param *params); /** * @brief handle get core param command * @param cache_id id of cache device * @param core_id id of core device * @param params parameter array * @return exit code of successful completion is 0; * nonzero exit code means failure */ int core_params_get(unsigned int cache_id, unsigned int core_id, struct cas_param *params, unsigned int output_format); /** * @brief handle set cache mode (-Q) command * @param in cache mode identifier of cache mode (WRITE_BACK, WRITE_THROUGH etc...) * @param cache_id id of cache device * @param flush whenever we should flush cache during execution of command. Options: YES, NO, UNDEFINED. * (UNDEFINED is illegal when transitioning from Write-Back mode to any other mode) */ int set_cache_mode(unsigned int cache_state, unsigned int cache_id, int flush); /** * @brief add core device to a cache * * @param cache_id cache to which new core is being added * @param core_device path to a core device that is being added * @param iogroup_id id of iogroup (this parameter is not exposed in user CLI) * @param try_add try add core to earlier loaded cache or add to core pool * @param update_path try update path to core device * @return 0 upon successful core addition, 1 upon failure */ int add_core(unsigned int cache_id, unsigned int core_id, const char *core_device, int try_add, int update_path); int get_core_info(int fd, int cache_id, int core_id, struct kcas_core_info *info, bool by_id_path); int remove_core(unsigned int cache_id, unsigned int core_id, bool detach, bool force_no_flush); /** * @brief detach caching device from failover standby cache instance * * @param cache_id cache instance identifier * * @return 0 upon successful detach, 1 upon failure */ int failover_detach(int cache_id); /** * @brief activate failover standby cache instance * * @param cache_id cache instance identifier * @param cache_device cache device path * * @return 0 upon successful detach, 1 upon failure */ int failover_activate(int cache_id, const char *cache_device); /** * @brief remove inactive core device from a cache * * @param cache_id cache from which inactive core is being removed * @param cache_id inactive core which is being removed * @param force remove inactive force even if it has dirty cache lines assigned * @return 0 upon successful core removal, 1 upon failure */ int remove_inactive_core(unsigned int cache_id, unsigned int core_id, bool force); int core_pool_remove(const char *core_device); int get_core_pool_count(int fd); int reset_counters(unsigned int cache_id, unsigned int core_id); int purge_cache(unsigned int cache_id); int purge_core(unsigned int cache_id, unsigned int core_id); int flush_cache(unsigned int cache_id); 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_is_name_valid(const char *name); int cas_module_version(char *buff, int size); int disk_module_version(char *buff, int size); int list_caches(unsigned int list_format, bool by_id_path); int cache_status(unsigned int cache_id, unsigned int core_id, int io_class_id, unsigned int stats_filters, unsigned int stats_format, bool by_id_path); int get_inactive_core_count(const struct kcas_cache_info *cache_info); int open_ctrl_device_quiet(); int open_ctrl_device(); int *get_cache_ids(int *cache_count); struct cache_device *get_cache_device_by_id_fd(int cache_id, int fd, bool by_id_path); struct cache_device **get_cache_devices(int *caches_count, bool by_id_path); void free_cache_devices_list(struct cache_device **caches, int caches_count); int validate_dev(const char *dev_path); int validate_str_num(const char *source_str, const char *msg, long long int min, long long int max); int validate_str_num_sbd(const char *source_str, const char *msg, int min, int max); int validate_str_unum(const char *source_str, const char *msg, unsigned int min, unsigned int max); int validate_path(const char *path, int exist); int validate_str_cache_mode(const char *s); int validate_str_cln_policy(const char *s); int validate_str_promotion_policy(const char *s); int validate_str_stats_filters(const char* s); int validate_str_output_format(const char* s); /** * @brief clear metadata * * @param[in] cache_device device to which zeroing cache's metadata applies * @param[in] force enforce metadata erasure despite dirty data, metadata * mistmatch and/or dirty shutdown * @return 0 if succeed, 1 if failed */ int zero_md(const char *cache_device, bool force); /** * @brief calculate flush progress * * @param[in] dirty number of dirty blocks * @param[in] flush number of flushed blocks * @return flush progress or 0 if no flush is ongoing */ float calculate_flush_progress(unsigned dirty, unsigned flushed); /** * @brief calculate flush progress of given cache * * @param[in] cache_id cache to which calculation applies * @param[out] progress flush progress * @return 0 on success, nonzero on failure */ int get_flush_progress(int unsigned cache_id, float *progress); /** * @brief print error message corresponding with CAS extended error code. */ void print_err(int error_code); /** * @brief get special device file path (/dev/sdX) for disk. */ int get_dev_path(const char* disk, char* buf, size_t num); /** * @brief make sure device link is unique and write sanitized version to \a dest_path * * @param[in] src_path link to device * @param[in] src_len length of \a src_path * @param[in] dest_len max length of \a dest_path * @param[out] dest_path sanitized absolute path * @return 0 on success, nonzero on failure */ int set_device_path(char *dest_path, size_t dest_len, const char *src_path, size_t src_len); /** * @brief convert string to int */ bool str_to_int(const char* start, char** end, int *val); #endif