diff --git a/casadm/cas_lib.c b/casadm/cas_lib.c index 043fedc..88dbbeb 100644 --- a/casadm/cas_lib.c +++ b/casadm/cas_lib.c @@ -1931,6 +1931,43 @@ 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 fd = 0; + struct kcas_remove_inactive cmd; + + /* don't even attempt ioctl if filesystem is mounted */ + if (SUCCESS != check_if_mounted(cache_id, core_id)) { + return FAILURE; + } + + fd = open_ctrl_device(); + if (fd == -1) + return FAILURE; + + memset(&cmd, 0, sizeof(cmd)); + cmd.cache_id = cache_id; + cmd.core_id = core_id; + + if (run_ioctl(fd, KCAS_IOCTL_REMOVE_INACTIVE, &cmd) < 0) { + close(fd); + if (cmd.ext_err_code == KCAS_ERR_CORE_IN_ACTIVE_STATE) { + cas_printf(LOG_ERR, "Core is active. " + "To manage the active core use " + "'--remove-core' command.\n"); + } else { + cas_printf(LOG_ERR, "Error while removing inactive " + "core device %d from cache instance " + "%d\n", core_id, cache_id); + print_err(cmd.ext_err_code); + } + return FAILURE; + } + close(fd); + + return SUCCESS; +} + int core_pool_remove(const char *core_device) { struct kcas_core_pool_remove cmd; diff --git a/casadm/cas_lib.h b/casadm/cas_lib.h index 5bf3d34..020365e 100644 --- a/casadm/cas_lib.h +++ b/casadm/cas_lib.h @@ -215,6 +215,15 @@ int get_core_info(int fd, int cache_id, int core_id, struct kcas_core_info *info int remove_core(unsigned int cache_id, unsigned int core_id, bool detach, bool force_no_flush); +/** + * @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 + * @return 0 upon successful core removal, 1 upon failure + */ +int remove_inactive_core(unsigned int cache_id, unsigned int core_id); + int core_pool_remove(const char *core_device); int get_core_pool_count(int fd); diff --git a/casadm/cas_main.c b/casadm/cas_main.c index 6093906..208ec3d 100644 --- a/casadm/cas_main.c +++ b/casadm/cas_main.c @@ -180,6 +180,23 @@ 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")) { @@ -1121,6 +1138,18 @@ int handle_remove() command_args_values.force); } +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}, + {0} +}; + +int handle_remove_inactive() +{ + return remove_inactive_core(command_args_values.cache_id, + command_args_values.core_id); +} + static cli_option core_pool_remove_options[] = { {'d', "device", CORE_DEVICE_DESC, 1, "DEVICE", CLI_OPTION_REQUIRED}, {0} @@ -1969,6 +1998,16 @@ static cli_command cas_commands[] = { .flags = CLI_SU_REQUIRED, .help = NULL, }, + { + .name = "remove-inactive", + .desc = "Remove inactive core device from cache instance", + .long_desc = NULL, + .options = remove_inactive_options, + .command_handle_opts = remove_inactive_core_command_handle_option, + .handle = handle_remove_inactive, + .flags = CLI_SU_REQUIRED, + .help = NULL, + }, { .name = "remove-detached", .desc = "Remove core device from core pool",