diff --git a/casadm/cas_lib.c b/casadm/cas_lib.c index e5224bc..fb10139 100644 --- a/casadm/cas_lib.c +++ b/casadm/cas_lib.c @@ -1937,7 +1937,8 @@ int remove_core(unsigned int cache_id, unsigned int core_id, return SUCCESS; } -int remove_inactive_core(unsigned int cache_id, unsigned int core_id) +int remove_inactive_core(unsigned int cache_id, unsigned int core_id, + bool force) { int fd = 0; struct kcas_remove_inactive cmd; @@ -1954,6 +1955,7 @@ int remove_inactive_core(unsigned int cache_id, unsigned int core_id) memset(&cmd, 0, sizeof(cmd)); cmd.cache_id = cache_id; cmd.core_id = core_id; + cmd.force = force; if (run_ioctl(fd, KCAS_IOCTL_REMOVE_INACTIVE, &cmd) < 0) { close(fd); diff --git a/casadm/cas_lib.h b/casadm/cas_lib.h index 020365e..ac217d2 100644 --- a/casadm/cas_lib.h +++ b/casadm/cas_lib.h @@ -220,9 +220,10 @@ int remove_core(unsigned int cache_id, unsigned int core_id, * * @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); +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); @@ -311,7 +312,7 @@ 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 diff --git a/casadm/cas_main.c b/casadm/cas_main.c index d7278cb..c34fb2a 100644 --- a/casadm/cas_main.c +++ b/casadm/cas_main.c @@ -180,23 +180,6 @@ int remove_core_command_handle_option(char *opt, const char **arg) return 0; } -int remove_inactive_core_command_handle_option(char *opt, const char **arg) -{ - if (!strcmp(opt, "cache-id")){ - if (validate_str_num(arg[0], "cache id", OCF_CACHE_ID_MIN, OCF_CACHE_ID_MAX) == FAILURE) - return FAILURE; - - command_args_values.cache_id = atoi(arg[0]); - } else if (!strcmp(opt, "core-id")){ - if (validate_str_num(arg[0], "core id", 0, OCF_CORE_ID_MAX) == FAILURE) - return FAILURE; - - command_args_values.core_id = atoi(arg[0]); - } - - return 0; -} - int core_pool_remove_command_handle_option(char *opt, const char **arg) { if (!strcmp(opt, "device")) { @@ -1143,13 +1126,14 @@ int handle_remove() static cli_option remove_inactive_options[] = { {'i', "cache-id", CACHE_ID_DESC, 1, "ID", CLI_OPTION_REQUIRED}, {'j', "core-id", CORE_ID_DESC, 1, "ID", CLI_OPTION_REQUIRED}, + {'f', "force", "Force dirty inactive core removal"}, {0} }; int handle_remove_inactive() { return remove_inactive_core(command_args_values.cache_id, - command_args_values.core_id); + command_args_values.core_id, command_args_values.force); } static cli_option core_pool_remove_options[] = { @@ -2005,7 +1989,7 @@ static cli_command cas_commands[] = { .desc = "Remove inactive core device from cache instance", .long_desc = NULL, .options = remove_inactive_options, - .command_handle_opts = remove_inactive_core_command_handle_option, + .command_handle_opts = remove_core_command_handle_option, .handle = handle_remove_inactive, .flags = CLI_SU_REQUIRED, .help = NULL, diff --git a/casadm/extended_err_msg.c b/casadm/extended_err_msg.c index fcad5f3..4f9e14e 100644 --- a/casadm/extended_err_msg.c +++ b/casadm/extended_err_msg.c @@ -258,7 +258,11 @@ struct { KCAS_ERR_CORE_IN_ACTIVE_STATE, "Core device is in active state" }, - + { + KCAS_ERR_INACTIVE_CORE_IS_DIRTY, + "The cache contains dirty data assigned to the core. If you want to " + "continue, please use --force option.\nWarning: the data will be lost" + }, }; const char *cas_strerr(int cas_error_code) diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index 2848485..7f893d5 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -1517,6 +1517,11 @@ int cache_mngt_remove_inactive_core(struct kcas_remove_inactive *cmd) goto unlock; } + if (ocf_mngt_core_is_dirty(core) && !cmd->force) { + result = -KCAS_ERR_INACTIVE_CORE_IS_DIRTY; + goto unlock; + } + /* * Destroy exported object - in case of error during destruction of * exported object, instead of trying rolling this back we rather diff --git a/modules/include/cas_ioctl_codes.h b/modules/include/cas_ioctl_codes.h index 87d65bc..d0cc73c 100644 --- a/modules/include/cas_ioctl_codes.h +++ b/modules/include/cas_ioctl_codes.h @@ -126,6 +126,7 @@ struct kcas_remove_core { struct kcas_remove_inactive { uint16_t cache_id; /**< id of an running cache */ uint16_t core_id; /**< id core object to be removed */ + bool force; /**< remove inactive core without flushing */ int ext_err_code; }; @@ -599,7 +600,10 @@ enum kcas_error { KCAS_ERR_WAITING_INTERRUPTED, /** Core device is in active state */ - KCAS_ERR_CORE_IN_ACTIVE_STATE + KCAS_ERR_CORE_IN_ACTIVE_STATE, + + /** Inactive core has dirty data assigned */ + KCAS_ERR_INACTIVE_CORE_IS_DIRTY }; #endif