commit
21a44d54a4
@ -68,7 +68,7 @@ static const char *cache_states_name[ocf_cache_state_max + 1] = {
|
|||||||
[ocf_cache_state_stopping] = "Stopping",
|
[ocf_cache_state_stopping] = "Stopping",
|
||||||
[ocf_cache_state_initializing] = "Initializing",
|
[ocf_cache_state_initializing] = "Initializing",
|
||||||
[ocf_cache_state_incomplete] = "Incomplete",
|
[ocf_cache_state_incomplete] = "Incomplete",
|
||||||
[ocf_cache_state_passive] = "Passive",
|
[ocf_cache_state_standby] = "Standby",
|
||||||
[ocf_cache_state_max] = "Unknown",
|
[ocf_cache_state_max] = "Unknown",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -573,7 +573,9 @@ static bool is_dev_link_whitelisted(const char* path)
|
|||||||
"/dev/cas[0-9]\\+-[0-9]\\+p[0-9]\\+$",
|
"/dev/cas[0-9]\\+-[0-9]\\+p[0-9]\\+$",
|
||||||
"/dev/ram[0-9]\\+$",
|
"/dev/ram[0-9]\\+$",
|
||||||
"/dev/ram[0-9]\\+p[0-9]\\+$",
|
"/dev/ram[0-9]\\+p[0-9]\\+$",
|
||||||
"/dev/nullb[0-9]\\+$"
|
"/dev/nullb[0-9]\\+$",
|
||||||
|
"/dev/drbd[0-9]\\+$",
|
||||||
|
"/dev/drbd[0-9]\\+p[0-9]\\+$",
|
||||||
};
|
};
|
||||||
static const unsigned count = ARRAY_SIZE(whitelist);
|
static const unsigned count = ARRAY_SIZE(whitelist);
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -782,6 +784,9 @@ struct cache_device *get_cache_device(const struct kcas_cache_info *info, bool b
|
|||||||
cache->id = cache_id;
|
cache->id = cache_id;
|
||||||
cache->state = info->info.state;
|
cache->state = info->info.state;
|
||||||
|
|
||||||
|
if (info->info.failover_detached)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (strncpy_s(cache->device, sizeof(cache->device),
|
if (strncpy_s(cache->device, sizeof(cache->device),
|
||||||
info->cache_path_name,
|
info->cache_path_name,
|
||||||
sizeof(info->cache_path_name))) {
|
sizeof(info->cache_path_name))) {
|
||||||
@ -2776,7 +2781,7 @@ int list_caches(unsigned int list_format, bool by_id_path)
|
|||||||
cache_mode_to_name(curr_cache->mode));
|
cache_mode_to_name(curr_cache->mode));
|
||||||
} else {
|
} else {
|
||||||
tmp_status = get_cache_state_name(curr_cache->state);
|
tmp_status = get_cache_state_name(curr_cache->state);
|
||||||
if (curr_cache->state & (1 << ocf_cache_state_passive)) {
|
if (curr_cache->state & (1 << ocf_cache_state_standby)) {
|
||||||
strncpy(mode_string, "-", sizeof(mode_string));
|
strncpy(mode_string, "-", sizeof(mode_string));
|
||||||
} else {
|
} else {
|
||||||
snprintf(mode_string, sizeof(mode_string), "%s",
|
snprintf(mode_string, sizeof(mode_string), "%s",
|
||||||
@ -2973,3 +2978,39 @@ int zero_md(const char *cache_device, bool force)
|
|||||||
cas_printf(LOG_INFO, "OpenCAS's metadata wiped succesfully from device '%s'.\n", cache_device);
|
cas_printf(LOG_INFO, "OpenCAS's metadata wiped succesfully from device '%s'.\n", cache_device);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cas_ioctl(int id, void *data)
|
||||||
|
{
|
||||||
|
int fd, result;
|
||||||
|
|
||||||
|
fd = open_ctrl_device();
|
||||||
|
if (fd == -1)
|
||||||
|
return FAILURE;
|
||||||
|
|
||||||
|
result = run_ioctl(fd, id, data);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return result < 0 ? FAILURE : SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int failover_detach(int cache_id)
|
||||||
|
{
|
||||||
|
struct kcas_failover_detach data = {.cache_id = cache_id};
|
||||||
|
|
||||||
|
return cas_ioctl(KCAS_IOCTL_FAILOVER_DETACH, &data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int failover_activate(int cache_id, const char *cache_device)
|
||||||
|
{
|
||||||
|
struct kcas_failover_activate data = {.cache_id = cache_id};
|
||||||
|
|
||||||
|
if (cache_device) {
|
||||||
|
if (set_device_path(data.cache_path, sizeof(data.cache_path),
|
||||||
|
cache_device, MAX_STR_LEN) != SUCCESS) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cas_ioctl(KCAS_IOCTL_FAILOVER_ACTIVATE, &data);
|
||||||
|
}
|
||||||
|
@ -204,6 +204,25 @@ 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,
|
int remove_core(unsigned int cache_id, unsigned int core_id,
|
||||||
bool detach, bool force_no_flush);
|
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
|
* @brief remove inactive core device from a cache
|
||||||
*
|
*
|
||||||
|
@ -198,10 +198,8 @@ int start_cache_command_handle_option(char *opt, const char **arg)
|
|||||||
command_args_values.cache_id = atoi(arg[0]);
|
command_args_values.cache_id = atoi(arg[0]);
|
||||||
} else if (!strcmp(opt, "load")) {
|
} else if (!strcmp(opt, "load")) {
|
||||||
command_args_values.state = CACHE_INIT_LOAD;
|
command_args_values.state = CACHE_INIT_LOAD;
|
||||||
} else if (!strcmp(opt, "bind")) {
|
} else if (!strcmp(opt, "failover-standby")) {
|
||||||
command_args_values.state = CACHE_INIT_BIND;
|
command_args_values.state = CACHE_INIT_STANDBY;
|
||||||
} else if (!strcmp(opt, "activate")) {
|
|
||||||
command_args_values.state = CACHE_INIT_ACTIVATE;
|
|
||||||
} else if (!strcmp(opt, "cache-device")) {
|
} else if (!strcmp(opt, "cache-device")) {
|
||||||
if(validate_device_name(arg[0]) == FAILURE)
|
if(validate_device_name(arg[0]) == FAILURE)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
@ -247,8 +245,7 @@ static cli_option start_options[] = {
|
|||||||
{'d', "cache-device", CACHE_DEVICE_DESC, 1, "DEVICE", CLI_OPTION_REQUIRED},
|
{'d', "cache-device", CACHE_DEVICE_DESC, 1, "DEVICE", CLI_OPTION_REQUIRED},
|
||||||
{'i', "cache-id", CACHE_ID_DESC_LONG, 1, "ID", 0},
|
{'i', "cache-id", CACHE_ID_DESC_LONG, 1, "ID", 0},
|
||||||
{'l', "load", "Load cache metadata from caching device (DANGEROUS - see manual or Admin Guide for details)"},
|
{'l', "load", "Load cache metadata from caching device (DANGEROUS - see manual or Admin Guide for details)"},
|
||||||
{'b', "bind", "Bind caching device (DANGEROUS - see manual or Admin Guide for details)"},
|
{'s', "failover-standby", "Start cache in standby mode for failover purpose (DANGEROUS - see manual or Admin Guide for details)"},
|
||||||
{'a', "activate", "Activate caching device after bind"},
|
|
||||||
{'f', "force", "Force the creation of cache instance"},
|
{'f', "force", "Force the creation of cache instance"},
|
||||||
{'c', "cache-mode", "Set cache mode from available: {"CAS_CLI_HELP_START_CACHE_MODES"} "CAS_CLI_HELP_START_CACHE_MODES_FULL"; without this parameter Write-Through will be set by default", 1, "NAME"},
|
{'c', "cache-mode", "Set cache mode from available: {"CAS_CLI_HELP_START_CACHE_MODES"} "CAS_CLI_HELP_START_CACHE_MODES_FULL"; without this parameter Write-Through will be set by default", 1, "NAME"},
|
||||||
{'x', "cache-line-size", "Set cache line size in kibibytes: {4,8,16,32,64}[KiB] (default: %d)", 1, "NUMBER", CLI_OPTION_DEFAULT_INT, 0, 0, ocf_cache_line_size_default / KiB},
|
{'x', "cache-line-size", "Set cache line size in kibibytes: {4,8,16,32,64}[KiB] (default: %d)", 1, "NUMBER", CLI_OPTION_DEFAULT_INT, 0, 0, ocf_cache_line_size_default / KiB},
|
||||||
@ -288,45 +285,34 @@ static int check_fs(const char* device)
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_start()
|
int validate_cache_path(const char* path)
|
||||||
{
|
{
|
||||||
int cache_device = 0;
|
int cache_device;
|
||||||
int status;
|
|
||||||
struct stat device_info;
|
struct stat device_info;
|
||||||
|
|
||||||
if (command_args_values.state == CACHE_INIT_LOAD && command_args_values.force) {
|
|
||||||
cas_printf(LOG_ERR, "Use of 'load' and 'force' simultaneously is forbidden.\n");
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command_args_values.state == CACHE_INIT_BIND && command_args_values.force) {
|
cache_device = open(path, O_RDONLY);
|
||||||
cas_printf(LOG_ERR, "Use of 'bind' and 'force' simultaneously is forbidden.\n");
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_device = open(command_args_values.cache_device, O_RDONLY);
|
|
||||||
|
|
||||||
if (cache_device < 0) {
|
if (cache_device < 0) {
|
||||||
cas_printf(LOG_ERR, "Couldn't open cache device %s.\n",
|
cas_printf(LOG_ERR, "Couldn't open cache device %s.\n", path);
|
||||||
command_args_values.cache_device);
|
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(cache_device, &device_info)) {
|
if (fstat(cache_device, &device_info)) {
|
||||||
close(cache_device);
|
close(cache_device);
|
||||||
cas_printf(LOG_ERR, "Could not stat target device:%s!\n",
|
cas_printf(LOG_ERR, "Could not stat target device:%s!\n",
|
||||||
command_args_values.cache_device);
|
path);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISBLK(device_info.st_mode)) {
|
if (!S_ISBLK(device_info.st_mode)) {
|
||||||
close(cache_device);
|
close(cache_device);
|
||||||
cas_printf(LOG_ERR, WRONG_DEVICE_ERROR NOT_BLOCK_ERROR,
|
cas_printf(LOG_ERR, WRONG_DEVICE_ERROR NOT_BLOCK_ERROR,
|
||||||
command_args_values.cache_device);
|
path);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_fs(command_args_values.cache_device)) {
|
if (check_fs(path)) {
|
||||||
close(cache_device);
|
close(cache_device);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
@ -336,6 +322,26 @@ int handle_start()
|
|||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_start()
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (command_args_values.state == CACHE_INIT_LOAD && command_args_values.force) {
|
||||||
|
cas_printf(LOG_ERR, "Use of 'load' and 'force' simultaneously is forbidden.\n");
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command_args_values.state == CACHE_INIT_STANDBY && command_args_values.force) {
|
||||||
|
cas_printf(LOG_ERR, "Use of 'failover-standby' and 'force' simultaneously is forbidden.\n");
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validate_cache_path(command_args_values.cache_device) == FAILURE)
|
||||||
|
return FAILURE;
|
||||||
|
|
||||||
status = start_cache(command_args_values.cache_id,
|
status = start_cache(command_args_values.cache_id,
|
||||||
command_args_values.state,
|
command_args_values.state,
|
||||||
command_args_values.cache_device,
|
command_args_values.cache_device,
|
||||||
@ -1449,6 +1455,18 @@ int io_class_handle() {
|
|||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static cli_option failover_detach_options[] = {
|
||||||
|
{'i', "cache-id", CACHE_ID_DESC, 1, "ID", CLI_OPTION_REQUIRED},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static cli_option failover_activate_options[] = {
|
||||||
|
{'i', "cache-id", CACHE_ID_DESC, 1, "ID", CLI_OPTION_REQUIRED},
|
||||||
|
{'d', "cache-device", CACHE_DEVICE_DESC, 1, "DEVICE"},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Script Commands
|
* Script Commands
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -1684,6 +1702,17 @@ int script_command_is_valid() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int handle_failover_detach()
|
||||||
|
{
|
||||||
|
return failover_detach(command_args_values.cache_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_failover_activate()
|
||||||
|
{
|
||||||
|
return failover_activate(command_args_values.cache_id,
|
||||||
|
command_args_values.cache_device);
|
||||||
|
}
|
||||||
|
|
||||||
int script_handle() {
|
int script_handle() {
|
||||||
if (script_cmd_unknown == command_args_values.script_subcmd) {
|
if (script_cmd_unknown == command_args_values.script_subcmd) {
|
||||||
cas_printf(LOG_ERR, "Invalid or missing first sub-command parameter\n");
|
cas_printf(LOG_ERR, "Invalid or missing first sub-command parameter\n");
|
||||||
@ -2094,6 +2123,30 @@ static cli_command cas_commands[] = {
|
|||||||
.flags = CLI_SU_REQUIRED,
|
.flags = CLI_SU_REQUIRED,
|
||||||
.help = NULL
|
.help = NULL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "failover-detach",
|
||||||
|
.desc = "Detach cache device from standby cache instance",
|
||||||
|
.long_desc = "Detach cache device from standby cache instance. "
|
||||||
|
"Cache continues to run in failover standby mode, "
|
||||||
|
"awaiting activation on a new drive.",
|
||||||
|
.options = failover_detach_options,
|
||||||
|
.command_handle_opts = command_handle_option,
|
||||||
|
.handle = handle_failover_detach,
|
||||||
|
.flags = CLI_SU_REQUIRED,
|
||||||
|
.help = NULL,
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "failover-activate",
|
||||||
|
.desc = "Activate standby cache instance",
|
||||||
|
.long_desc = NULL,
|
||||||
|
.options = failover_activate_options,
|
||||||
|
.command_handle_opts = command_handle_option,
|
||||||
|
.handle = handle_failover_activate,
|
||||||
|
.flags = CLI_SU_REQUIRED,
|
||||||
|
.help = NULL,
|
||||||
|
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "script",
|
.name = "script",
|
||||||
.options = script_params_options,
|
.options = script_params_options,
|
||||||
|
@ -538,10 +538,13 @@ int cache_stats_conf(int ctrl_fd, const struct kcas_cache_info *cache_info,
|
|||||||
char dev_path[MAX_STR_LEN];
|
char dev_path[MAX_STR_LEN];
|
||||||
int inactive_cores;
|
int inactive_cores;
|
||||||
|
|
||||||
if (!by_id_path && get_dev_path(cache_info->cache_path_name, dev_path, sizeof(dev_path)) == SUCCESS)
|
if (strnlen(cache_info->cache_path_name, sizeof(cache_info->cache_path_name)) == 0) {
|
||||||
|
cache_path = "-";
|
||||||
|
} else if (!by_id_path && get_dev_path(cache_info->cache_path_name, dev_path, sizeof(dev_path)) == SUCCESS) {
|
||||||
cache_path = dev_path;
|
cache_path = dev_path;
|
||||||
else
|
} else {
|
||||||
cache_path = cache_info->cache_path_name;
|
cache_path = cache_info->cache_path_name;
|
||||||
|
}
|
||||||
|
|
||||||
flush_progress = calculate_flush_progress(cache_info->info.dirty,
|
flush_progress = calculate_flush_progress(cache_info->info.dirty,
|
||||||
cache_info->info.flushed);
|
cache_info->info.flushed);
|
||||||
|
@ -58,6 +58,7 @@ struct cache_priv {
|
|||||||
atomic_t flush_interrupt_enabled;
|
atomic_t flush_interrupt_enabled;
|
||||||
ocf_queue_t mngt_queue;
|
ocf_queue_t mngt_queue;
|
||||||
void *attach_context;
|
void *attach_context;
|
||||||
|
bool cache_exp_obj_initialized;
|
||||||
ocf_queue_t io_queues[];
|
ocf_queue_t io_queues[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -576,7 +576,7 @@ static int exit_instance_finish(void *data)
|
|||||||
else
|
else
|
||||||
result = ctx->error;
|
result = ctx->error;
|
||||||
|
|
||||||
if (!ocf_cache_is_passive(ctx->cache))
|
if (!ocf_cache_is_standby(ctx->cache))
|
||||||
cas_cls_deinit(ctx->cache);
|
cas_cls_deinit(ctx->cache);
|
||||||
|
|
||||||
vfree(cache_priv);
|
vfree(cache_priv);
|
||||||
@ -595,7 +595,8 @@ static int exit_instance_finish(void *data)
|
|||||||
|
|
||||||
struct _cache_mngt_attach_context {
|
struct _cache_mngt_attach_context {
|
||||||
struct _cache_mngt_async_context async;
|
struct _cache_mngt_async_context async;
|
||||||
struct kcas_start_cache *cmd;
|
char cache_elevator[MAX_ELEVATOR_NAME];
|
||||||
|
uint64_t min_free_ram;
|
||||||
struct ocf_mngt_cache_device_config *device_cfg;
|
struct ocf_mngt_cache_device_config *device_cfg;
|
||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
int ocf_start_error;
|
int ocf_start_error;
|
||||||
@ -1284,7 +1285,7 @@ static void _cache_mngt_add_core_complete(ocf_cache_t cache,
|
|||||||
complete(&context->cmpl);
|
complete(&context->cmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _cache_mngt_remove_core_complete(void *priv, int error);
|
static void _cache_mngt_generic_complete(void *priv, int error);
|
||||||
|
|
||||||
int cache_mngt_add_core_to_cache(const char *cache_name, size_t name_len,
|
int cache_mngt_add_core_to_cache(const char *cache_name, size_t name_len,
|
||||||
struct ocf_mngt_core_config *cfg,
|
struct ocf_mngt_core_config *cfg,
|
||||||
@ -1372,7 +1373,7 @@ error_after_create_exported_object:
|
|||||||
error_after_add_core:
|
error_after_add_core:
|
||||||
init_completion(&remove_context.cmpl);
|
init_completion(&remove_context.cmpl);
|
||||||
remove_context.result = &remove_core_result;
|
remove_context.result = &remove_core_result;
|
||||||
ocf_mngt_cache_remove_core(core, _cache_mngt_remove_core_complete,
|
ocf_mngt_cache_remove_core(core, _cache_mngt_generic_complete,
|
||||||
&remove_context);
|
&remove_context);
|
||||||
wait_for_completion(&remove_context.cmpl);
|
wait_for_completion(&remove_context.cmpl);
|
||||||
|
|
||||||
@ -1429,7 +1430,7 @@ put:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _cache_mngt_remove_core_complete(void *priv, int error)
|
static void _cache_mngt_generic_complete(void *priv, int error)
|
||||||
{
|
{
|
||||||
struct _cache_mngt_sync_context *context = priv;
|
struct _cache_mngt_sync_context *context = priv;
|
||||||
|
|
||||||
@ -1450,7 +1451,7 @@ static void _cache_mngt_remove_core_fallback(ocf_cache_t cache, ocf_core_t core)
|
|||||||
context.result = &result;
|
context.result = &result;
|
||||||
|
|
||||||
ocf_mngt_cache_detach_core(core,
|
ocf_mngt_cache_detach_core(core,
|
||||||
_cache_mngt_remove_core_complete, &context);
|
_cache_mngt_generic_complete, &context);
|
||||||
|
|
||||||
wait_for_completion(&context.cmpl);
|
wait_for_completion(&context.cmpl);
|
||||||
|
|
||||||
@ -1523,10 +1524,10 @@ int cache_mngt_remove_core_from_cache(struct kcas_remove_core *cmd)
|
|||||||
|
|
||||||
if (cmd->detach) {
|
if (cmd->detach) {
|
||||||
ocf_mngt_cache_detach_core(core,
|
ocf_mngt_cache_detach_core(core,
|
||||||
_cache_mngt_remove_core_complete, &context);
|
_cache_mngt_generic_complete, &context);
|
||||||
} else {
|
} else {
|
||||||
ocf_mngt_cache_remove_core(core,
|
ocf_mngt_cache_remove_core(core,
|
||||||
_cache_mngt_remove_core_complete, &context);
|
_cache_mngt_generic_complete, &context);
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_for_completion(&context.cmpl);
|
wait_for_completion(&context.cmpl);
|
||||||
@ -1584,7 +1585,7 @@ int cache_mngt_remove_inactive_core(struct kcas_remove_inactive *cmd)
|
|||||||
init_completion(&context.cmpl);
|
init_completion(&context.cmpl);
|
||||||
context.result = &result;
|
context.result = &result;
|
||||||
|
|
||||||
ocf_mngt_cache_remove_core(core, _cache_mngt_remove_core_complete,
|
ocf_mngt_cache_remove_core(core, _cache_mngt_generic_complete,
|
||||||
&context);
|
&context);
|
||||||
|
|
||||||
wait_for_completion(&context.cmpl);
|
wait_for_completion(&context.cmpl);
|
||||||
@ -1755,16 +1756,29 @@ static int cache_mngt_initialize_core_exported_objects(ocf_cache_t cache)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cache_mngt_destroy_cache_exp_obj(ocf_cache_t cache)
|
static int cache_mngt_destroy_cache_exp_obj(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
if (kcas_cache_destroy_exported_object(cache)) {
|
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!cache_priv->cache_exp_obj_initialized)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = kcas_cache_destroy_exported_object(cache);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
printk(KERN_ERR "Cannot destroy %s exported object\n",
|
printk(KERN_ERR "Cannot destroy %s exported object\n",
|
||||||
ocf_cache_get_name(cache));
|
ocf_cache_get_name(cache));
|
||||||
|
} else {
|
||||||
|
cache_priv->cache_exp_obj_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cache_mngt_initialize_cache_exported_object(ocf_cache_t cache)
|
static int cache_mngt_initialize_cache_exported_object(ocf_cache_t cache)
|
||||||
{
|
{
|
||||||
|
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = kcas_cache_create_exported_object(cache);
|
result = kcas_cache_create_exported_object(cache);
|
||||||
@ -1777,11 +1791,42 @@ static int cache_mngt_initialize_cache_exported_object(ocf_cache_t cache)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache_priv->cache_exp_obj_initialized = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cache_mngt_prepare_cache_device_cfg(struct ocf_mngt_cache_device_config *cfg,
|
||||||
|
char *cache_path)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
memset(cfg, 0, sizeof(*cfg));
|
||||||
|
|
||||||
|
if (strnlen(cache_path, MAX_STR_LEN) == MAX_STR_LEN)
|
||||||
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
|
cfg->uuid.data = cache_path;
|
||||||
|
cfg->uuid.size = strnlen(cfg->uuid.data, MAX_STR_LEN) + 1;
|
||||||
|
cfg->perform_test = false;
|
||||||
|
|
||||||
|
if (cfg->uuid.size == 1) {
|
||||||
|
// empty string means empty uuid
|
||||||
|
cfg->uuid.size = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg->uuid.size > 1) {
|
||||||
|
result = cas_blk_identify_type(cfg->uuid.data,
|
||||||
|
&cfg->volume_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
||||||
struct ocf_mngt_cache_device_config *device_cfg,
|
struct ocf_mngt_cache_attach_config *attach_cfg,
|
||||||
struct kcas_start_cache *cmd)
|
struct kcas_start_cache *cmd)
|
||||||
{
|
{
|
||||||
int init_cache, result;
|
int init_cache, result;
|
||||||
@ -1791,9 +1836,6 @@ int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
|||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
if (strnlen(cmd->cache_path_name, MAX_STR_LEN) >= MAX_STR_LEN)
|
|
||||||
return -OCF_ERR_INVAL;
|
|
||||||
|
|
||||||
if (cmd->cache_id == OCF_CACHE_ID_INVALID) {
|
if (cmd->cache_id == OCF_CACHE_ID_INVALID) {
|
||||||
cache_id = find_free_cache_id(cas_ctx);
|
cache_id = find_free_cache_id(cas_ctx);
|
||||||
if (cache_id == OCF_CACHE_ID_INVALID)
|
if (cache_id == OCF_CACHE_ID_INVALID)
|
||||||
@ -1805,7 +1847,15 @@ int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
|||||||
cache_name_from_id(cache_name, cmd->cache_id);
|
cache_name_from_id(cache_name, cmd->cache_id);
|
||||||
|
|
||||||
memset(cfg, 0, sizeof(*cfg));
|
memset(cfg, 0, sizeof(*cfg));
|
||||||
memset(device_cfg, 0, sizeof(*device_cfg));
|
memset(attach_cfg, 0, sizeof(*attach_cfg));
|
||||||
|
|
||||||
|
result = cache_mngt_prepare_cache_device_cfg(&attach_cfg->device,
|
||||||
|
cmd->cache_path_name);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (attach_cfg->device.uuid.size <= 1)
|
||||||
|
return -OCF_ERR_INVAL;
|
||||||
|
|
||||||
strncpy(cfg->name, cache_name, OCF_CACHE_NAME_SIZE - 1);
|
strncpy(cfg->name, cache_name, OCF_CACHE_NAME_SIZE - 1);
|
||||||
cfg->cache_mode = cmd->caching_mode;
|
cfg->cache_mode = cmd->caching_mode;
|
||||||
@ -1820,31 +1870,22 @@ int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
|||||||
|
|
||||||
cfg->backfill.max_queue_size = max_writeback_queue_size;
|
cfg->backfill.max_queue_size = max_writeback_queue_size;
|
||||||
cfg->backfill.queue_unblock_size = writeback_queue_unblock_size;
|
cfg->backfill.queue_unblock_size = writeback_queue_unblock_size;
|
||||||
|
attach_cfg->cache_line_size = cmd->line_size;
|
||||||
device_cfg->uuid.data = cmd->cache_path_name;
|
attach_cfg->force = cmd->force;
|
||||||
device_cfg->uuid.size = strnlen(device_cfg->uuid.data, MAX_STR_LEN) + 1;
|
attach_cfg->discard_on_start = true;
|
||||||
device_cfg->cache_line_size = cmd->line_size;
|
|
||||||
device_cfg->force = cmd->force;
|
|
||||||
device_cfg->discard_on_start = true;
|
|
||||||
device_cfg->perform_test = false;
|
|
||||||
|
|
||||||
init_cache = cmd->init_cache;
|
init_cache = cmd->init_cache;
|
||||||
|
|
||||||
switch (init_cache) {
|
switch (init_cache) {
|
||||||
case CACHE_INIT_LOAD:
|
case CACHE_INIT_LOAD:
|
||||||
case CACHE_INIT_ACTIVATE:
|
attach_cfg->open_cores = true;
|
||||||
device_cfg->open_cores = true;
|
|
||||||
case CACHE_INIT_NEW:
|
case CACHE_INIT_NEW:
|
||||||
case CACHE_INIT_BIND:
|
case CACHE_INIT_STANDBY:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -OCF_ERR_INVAL;
|
return -OCF_ERR_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = cas_blk_identify_type(device_cfg->uuid.data,
|
|
||||||
&device_cfg->volume_type);
|
|
||||||
if (result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1935,9 +1976,8 @@ static void init_instance_complete(struct _cache_mngt_attach_context *ctx,
|
|||||||
/* Set other back information */
|
/* Set other back information */
|
||||||
name = block_dev_get_elevator_name(
|
name = block_dev_get_elevator_name(
|
||||||
casdsk_disk_get_queue(bd_cache_obj->dsk));
|
casdsk_disk_get_queue(bd_cache_obj->dsk));
|
||||||
if (name && ctx->cmd)
|
if (name)
|
||||||
strlcpy(ctx->cmd->cache_elevator,
|
strlcpy(ctx->cache_elevator, name, MAX_ELEVATOR_NAME);
|
||||||
name, MAX_ELEVATOR_NAME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _cache_mngt_start_complete(ocf_cache_t cache, void *priv, int error)
|
static void _cache_mngt_start_complete(ocf_cache_t cache, void *priv, int error)
|
||||||
@ -1945,9 +1985,9 @@ static void _cache_mngt_start_complete(ocf_cache_t cache, void *priv, int error)
|
|||||||
struct _cache_mngt_attach_context *ctx = priv;
|
struct _cache_mngt_attach_context *ctx = priv;
|
||||||
int caller_status;
|
int caller_status;
|
||||||
|
|
||||||
if (error == -OCF_ERR_NO_FREE_RAM && ctx->cmd) {
|
if (error == -OCF_ERR_NO_FREE_RAM) {
|
||||||
ocf_mngt_get_ram_needed(cache, ctx->device_cfg,
|
ocf_mngt_get_ram_needed(cache, ctx->device_cfg,
|
||||||
&ctx->cmd->min_free_ram);
|
&ctx->min_free_ram);
|
||||||
}
|
}
|
||||||
|
|
||||||
caller_status =_cache_mngt_async_callee_set_result(&ctx->async, error);
|
caller_status =_cache_mngt_async_callee_set_result(&ctx->async, error);
|
||||||
@ -2051,8 +2091,8 @@ out_bdev:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _cache_start_finalize(ocf_cache_t cache,
|
static int _cache_start_finalize(ocf_cache_t cache, int init_mode,
|
||||||
struct kcas_start_cache *cmd)
|
bool activate)
|
||||||
{
|
{
|
||||||
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
|
||||||
struct _cache_mngt_attach_context *ctx = cache_priv->attach_context;
|
struct _cache_mngt_attach_context *ctx = cache_priv->attach_context;
|
||||||
@ -2060,7 +2100,7 @@ static int _cache_start_finalize(ocf_cache_t cache,
|
|||||||
|
|
||||||
_cache_mngt_log_cache_device_path(cache, ctx->device_cfg);
|
_cache_mngt_log_cache_device_path(cache, ctx->device_cfg);
|
||||||
|
|
||||||
if (cmd->init_cache != CACHE_INIT_BIND) {
|
if (activate || init_mode != CACHE_INIT_STANDBY) {
|
||||||
result = cas_cls_init(cache);
|
result = cas_cls_init(cache);
|
||||||
if (result) {
|
if (result) {
|
||||||
ctx->ocf_start_error = result;
|
ctx->ocf_start_error = result;
|
||||||
@ -2069,10 +2109,14 @@ static int _cache_start_finalize(ocf_cache_t cache,
|
|||||||
ctx->cls_inited = true;
|
ctx->cls_inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(cmd->init_cache) {
|
if (activate)
|
||||||
case CACHE_INIT_ACTIVATE:
|
|
||||||
cache_mngt_destroy_cache_exp_obj(cache);
|
cache_mngt_destroy_cache_exp_obj(cache);
|
||||||
/* fall through */
|
|
||||||
|
/* after destroying exported object activate should follow
|
||||||
|
* load path */
|
||||||
|
init_mode = activate ? CACHE_INIT_LOAD : init_mode;
|
||||||
|
|
||||||
|
switch(init_mode) {
|
||||||
case CACHE_INIT_LOAD:
|
case CACHE_INIT_LOAD:
|
||||||
result = cache_mngt_initialize_core_exported_objects(cache);
|
result = cache_mngt_initialize_core_exported_objects(cache);
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -2082,7 +2126,7 @@ static int _cache_start_finalize(ocf_cache_t cache,
|
|||||||
ocf_core_visit(cache, _cache_mngt_core_device_loaded_visitor,
|
ocf_core_visit(cache, _cache_mngt_core_device_loaded_visitor,
|
||||||
NULL, false);
|
NULL, false);
|
||||||
break;
|
break;
|
||||||
case CACHE_INIT_BIND:
|
case CACHE_INIT_STANDBY:
|
||||||
result = cache_mngt_initialize_cache_exported_object(cache);
|
result = cache_mngt_initialize_cache_exported_object(cache);
|
||||||
if (result) {
|
if (result) {
|
||||||
ctx->ocf_start_error = result;
|
ctx->ocf_start_error = result;
|
||||||
@ -2100,7 +2144,8 @@ static int _cache_start_finalize(ocf_cache_t cache,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cache_mngt_check_bdev(struct ocf_mngt_cache_device_config *device_cfg)
|
int cache_mngt_check_bdev(struct ocf_mngt_cache_device_config *device_cfg,
|
||||||
|
bool force)
|
||||||
{
|
{
|
||||||
char holder[] = "CAS START\n";
|
char holder[] = "CAS START\n";
|
||||||
struct block_device *bdev;
|
struct block_device *bdev;
|
||||||
@ -2119,15 +2164,68 @@ int cache_mngt_check_bdev(struct ocf_mngt_cache_device_config *device_cfg)
|
|||||||
part_count = cas_blk_get_part_count(bdev);
|
part_count = cas_blk_get_part_count(bdev);
|
||||||
blkdev_put(bdev, (FMODE_EXCL|FMODE_READ));
|
blkdev_put(bdev, (FMODE_EXCL|FMODE_READ));
|
||||||
|
|
||||||
if (!is_part && part_count > 1 && !device_cfg->force)
|
if (!is_part && part_count > 1 && !force)
|
||||||
return -KCAS_ERR_CONTAINS_PART;
|
return -KCAS_ERR_CONTAINS_PART;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cache_mngt_init_instance_activate(struct ocf_mngt_cache_config *cfg,
|
int cache_mngt_failover_detach(struct kcas_failover_detach *cmd)
|
||||||
struct ocf_mngt_cache_device_config *device_cfg,
|
{
|
||||||
struct kcas_start_cache *cmd)
|
ocf_cache_t cache;
|
||||||
|
struct cache_priv *cache_priv;
|
||||||
|
char cache_name[OCF_CACHE_NAME_SIZE];
|
||||||
|
int result = 0;
|
||||||
|
struct _cache_mngt_sync_context context = {
|
||||||
|
.result = &result
|
||||||
|
};
|
||||||
|
|
||||||
|
init_completion(&context.cmpl);
|
||||||
|
|
||||||
|
if (!try_module_get(THIS_MODULE))
|
||||||
|
return -KCAS_ERR_SYSTEM;
|
||||||
|
|
||||||
|
cache_name_from_id(cache_name, cmd->cache_id);
|
||||||
|
|
||||||
|
result = ocf_mngt_cache_get_by_name(cas_ctx, cache_name,
|
||||||
|
OCF_CACHE_NAME_SIZE, &cache);
|
||||||
|
if (result)
|
||||||
|
goto out_module_put;
|
||||||
|
|
||||||
|
if (!ocf_cache_is_standby(cache)) {
|
||||||
|
result = -OCF_ERR_CACHE_EXIST;
|
||||||
|
goto out_cache_put;
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_priv = ocf_cache_get_priv(cache);
|
||||||
|
if (!cache_priv->cache_exp_obj_initialized) {
|
||||||
|
result = -KCAS_ERR_DETACHED;
|
||||||
|
goto out_cache_put;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = cache_mngt_destroy_cache_exp_obj(cache);
|
||||||
|
if (result)
|
||||||
|
goto out_cache_put;
|
||||||
|
|
||||||
|
result = _cache_mngt_lock_sync(cache);
|
||||||
|
if (result)
|
||||||
|
goto out_cache_put;
|
||||||
|
|
||||||
|
ocf_mngt_cache_failover_detach(cache, _cache_mngt_generic_complete,
|
||||||
|
&context);
|
||||||
|
|
||||||
|
wait_for_completion(&context.cmpl);
|
||||||
|
ocf_mngt_cache_unlock(cache);
|
||||||
|
|
||||||
|
out_cache_put:
|
||||||
|
ocf_mngt_cache_put(cache);
|
||||||
|
out_module_put:
|
||||||
|
module_put(THIS_MODULE);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cache_mngt_activate(struct ocf_mngt_cache_device_config *cfg,
|
||||||
|
struct kcas_failover_activate *cmd)
|
||||||
{
|
{
|
||||||
struct _cache_mngt_attach_context *context;
|
struct _cache_mngt_attach_context *context;
|
||||||
ocf_cache_t cache;
|
ocf_cache_t cache;
|
||||||
@ -2147,7 +2245,7 @@ int cache_mngt_init_instance_activate(struct ocf_mngt_cache_config *cfg,
|
|||||||
if (result)
|
if (result)
|
||||||
goto out_module_put;
|
goto out_module_put;
|
||||||
|
|
||||||
if (!ocf_cache_is_passive(cache)) {
|
if (!ocf_cache_is_standby(cache)) {
|
||||||
result = -OCF_ERR_CACHE_EXIST;
|
result = -OCF_ERR_CACHE_EXIST;
|
||||||
goto out_cache_put;
|
goto out_cache_put;
|
||||||
}
|
}
|
||||||
@ -2156,12 +2254,16 @@ int cache_mngt_init_instance_activate(struct ocf_mngt_cache_config *cfg,
|
|||||||
if (result)
|
if (result)
|
||||||
goto out_cache_put;
|
goto out_cache_put;
|
||||||
|
|
||||||
cache_volume = ocf_cache_get_volume(cache);
|
if (strnlen(cmd->cache_path, MAX_STR_LEN) > 0) {
|
||||||
cache_uuid = ocf_volume_get_uuid(cache_volume);
|
cache_volume = ocf_cache_get_volume(cache);
|
||||||
if (strcmp(device_cfg->uuid.data, cache_uuid->data) != 0) {
|
cache_uuid = ocf_volume_get_uuid(cache_volume);
|
||||||
result = cache_mngt_check_bdev(device_cfg);
|
if (cache_uuid->size > 0 &&
|
||||||
if (result)
|
strcmp(cfg->uuid.data, cache_uuid->data)
|
||||||
goto out_cache_unlock;
|
!= 0) {
|
||||||
|
result = cache_mngt_check_bdev(cfg, false);
|
||||||
|
if (result)
|
||||||
|
goto out_cache_unlock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context = kzalloc(sizeof(*context), GFP_KERNEL);
|
context = kzalloc(sizeof(*context), GFP_KERNEL);
|
||||||
@ -2170,8 +2272,10 @@ int cache_mngt_init_instance_activate(struct ocf_mngt_cache_config *cfg,
|
|||||||
goto out_cache_unlock;
|
goto out_cache_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->device_cfg = device_cfg;
|
/* TODO: doesn't this need to be copied to avoid use-after-free
|
||||||
context->cmd = cmd;
|
* in case where calle is interrupted and returns???
|
||||||
|
*/
|
||||||
|
context->device_cfg = cfg;
|
||||||
context->cache = cache;
|
context->cache = cache;
|
||||||
|
|
||||||
cache_priv = ocf_cache_get_priv(cache);
|
cache_priv = ocf_cache_get_priv(cache);
|
||||||
@ -2185,8 +2289,8 @@ int cache_mngt_init_instance_activate(struct ocf_mngt_cache_config *cfg,
|
|||||||
}
|
}
|
||||||
_cache_mngt_async_context_init(&context->async);
|
_cache_mngt_async_context_init(&context->async);
|
||||||
|
|
||||||
ocf_mngt_cache_activate(cache, device_cfg,
|
ocf_mngt_cache_activate(cache, cfg, _cache_mngt_start_complete,
|
||||||
_cache_mngt_start_complete, context);
|
context);
|
||||||
result = wait_for_completion_interruptible(&context->async.cmpl);
|
result = wait_for_completion_interruptible(&context->async.cmpl);
|
||||||
|
|
||||||
result = _cache_mngt_async_caller_set_result(&context->async, result);
|
result = _cache_mngt_async_caller_set_result(&context->async, result);
|
||||||
@ -2198,7 +2302,7 @@ int cache_mngt_init_instance_activate(struct ocf_mngt_cache_config *cfg,
|
|||||||
if (result)
|
if (result)
|
||||||
goto err_free_context;
|
goto err_free_context;
|
||||||
|
|
||||||
result = _cache_start_finalize(cache, cmd);
|
result = _cache_start_finalize(cache, -1, true);
|
||||||
|
|
||||||
err_free_context:
|
err_free_context:
|
||||||
kfree(context);
|
kfree(context);
|
||||||
@ -2214,7 +2318,7 @@ out_module_put:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
||||||
struct ocf_mngt_cache_device_config *device_cfg,
|
struct ocf_mngt_cache_attach_config *attach_cfg,
|
||||||
struct kcas_start_cache *cmd)
|
struct kcas_start_cache *cmd)
|
||||||
{
|
{
|
||||||
struct _cache_mngt_attach_context *context;
|
struct _cache_mngt_attach_context *context;
|
||||||
@ -2222,13 +2326,10 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
|||||||
struct cache_priv *cache_priv;
|
struct cache_priv *cache_priv;
|
||||||
int result = 0, rollback_result = 0;
|
int result = 0, rollback_result = 0;
|
||||||
|
|
||||||
if (cmd->init_cache == CACHE_INIT_ACTIVATE)
|
|
||||||
return cache_mngt_init_instance_activate(cfg, device_cfg, cmd);
|
|
||||||
|
|
||||||
if (!try_module_get(THIS_MODULE))
|
if (!try_module_get(THIS_MODULE))
|
||||||
return -KCAS_ERR_SYSTEM;
|
return -KCAS_ERR_SYSTEM;
|
||||||
|
|
||||||
result = cache_mngt_check_bdev(device_cfg);
|
result = cache_mngt_check_bdev(&attach_cfg->device, attach_cfg->force);
|
||||||
if (result) {
|
if (result) {
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
return result;
|
return result;
|
||||||
@ -2256,8 +2357,7 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->device_cfg = device_cfg;
|
context->device_cfg = &attach_cfg->device;
|
||||||
context->cmd = cmd;
|
|
||||||
_cache_mngt_async_context_init(&context->async);
|
_cache_mngt_async_context_init(&context->async);
|
||||||
|
|
||||||
/* Start cache. Returned cache instance will be locked as it was set
|
/* Start cache. Returned cache instance will be locked as it was set
|
||||||
@ -2286,15 +2386,15 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
|||||||
|
|
||||||
switch (cmd->init_cache) {
|
switch (cmd->init_cache) {
|
||||||
case CACHE_INIT_NEW:
|
case CACHE_INIT_NEW:
|
||||||
ocf_mngt_cache_attach(cache, device_cfg,
|
ocf_mngt_cache_attach(cache, attach_cfg,
|
||||||
_cache_mngt_start_complete, context);
|
_cache_mngt_start_complete, context);
|
||||||
break;
|
break;
|
||||||
case CACHE_INIT_LOAD:
|
case CACHE_INIT_LOAD:
|
||||||
ocf_mngt_cache_load(cache, device_cfg,
|
ocf_mngt_cache_load(cache, attach_cfg,
|
||||||
_cache_mngt_start_complete, context);
|
_cache_mngt_start_complete, context);
|
||||||
break;
|
break;
|
||||||
case CACHE_INIT_BIND:
|
case CACHE_INIT_STANDBY:
|
||||||
ocf_mngt_cache_bind(cache, device_cfg,
|
ocf_mngt_cache_standby(cache, attach_cfg,
|
||||||
_cache_mngt_start_complete, context);
|
_cache_mngt_start_complete, context);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2310,7 +2410,11 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
|||||||
if (result)
|
if (result)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
result = _cache_start_finalize(cache, cmd);
|
strlcpy(cmd->cache_elevator, context->cache_elevator,
|
||||||
|
MAX_ELEVATOR_NAME);
|
||||||
|
cmd->min_free_ram = context->min_free_ram;
|
||||||
|
|
||||||
|
result = _cache_start_finalize(cache, cmd->init_cache, false);
|
||||||
if (result)
|
if (result)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -2827,11 +2931,13 @@ int cache_mngt_get_info(struct kcas_cache_info *info)
|
|||||||
if (result)
|
if (result)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
if (info->info.attached) {
|
if (info->info.attached && !info->info.failover_detached) {
|
||||||
uuid = ocf_cache_get_uuid(cache);
|
uuid = ocf_cache_get_uuid(cache);
|
||||||
BUG_ON(!uuid);
|
BUG_ON(!uuid);
|
||||||
strlcpy(info->cache_path_name, uuid->data,
|
strlcpy(info->cache_path_name, uuid->data,
|
||||||
min(sizeof(info->cache_path_name), uuid->size));
|
min(sizeof(info->cache_path_name), uuid->size));
|
||||||
|
} else {
|
||||||
|
memset(info->cache_path_name, 0, sizeof(info->cache_path_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Collect cores IDs */
|
/* Collect cores IDs */
|
||||||
|
@ -45,8 +45,11 @@ int cache_mngt_set_partitions(const char *cache_name, size_t name_len,
|
|||||||
int cache_mngt_exit_instance(const char *cache_name, size_t name_len,
|
int cache_mngt_exit_instance(const char *cache_name, size_t name_len,
|
||||||
int flush);
|
int flush);
|
||||||
|
|
||||||
|
int cache_mngt_prepare_cache_device_cfg(struct ocf_mngt_cache_device_config *cfg,
|
||||||
|
char *cache_path);
|
||||||
|
|
||||||
int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
int cache_mngt_prepare_cache_cfg(struct ocf_mngt_cache_config *cfg,
|
||||||
struct ocf_mngt_cache_device_config *device_cfg,
|
struct ocf_mngt_cache_attach_config *attach_cfg,
|
||||||
struct kcas_start_cache *cmd);
|
struct kcas_start_cache *cmd);
|
||||||
|
|
||||||
int cache_mngt_core_pool_get_paths(struct kcas_core_pool_path *cmd_info);
|
int cache_mngt_core_pool_get_paths(struct kcas_core_pool_path *cmd_info);
|
||||||
@ -59,9 +62,12 @@ int cache_mngt_prepare_core_cfg(struct ocf_mngt_core_config *cfg,
|
|||||||
struct kcas_insert_core *cmd_info);
|
struct kcas_insert_core *cmd_info);
|
||||||
|
|
||||||
int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
|
||||||
struct ocf_mngt_cache_device_config *device_cfg,
|
struct ocf_mngt_cache_attach_config *attach_cfg,
|
||||||
struct kcas_start_cache *cmd);
|
struct kcas_start_cache *cmd);
|
||||||
|
|
||||||
|
int cache_mngt_activate(struct ocf_mngt_cache_device_config *cfg,
|
||||||
|
struct kcas_failover_activate *cmd);
|
||||||
|
|
||||||
int cache_mngt_set_seq_cutoff_threshold(ocf_cache_t cache, ocf_core_t core,
|
int cache_mngt_set_seq_cutoff_threshold(ocf_cache_t cache, ocf_core_t core,
|
||||||
uint32_t thresh);
|
uint32_t thresh);
|
||||||
|
|
||||||
@ -108,4 +114,9 @@ int cache_mngt_set_cache_params(struct kcas_set_cache_param *info);
|
|||||||
|
|
||||||
int cache_mngt_get_cache_params(struct kcas_get_cache_param *info);
|
int cache_mngt_get_cache_params(struct kcas_get_cache_param *info);
|
||||||
|
|
||||||
|
int cache_mngt_failover_detach(struct kcas_failover_detach *cmd);
|
||||||
|
|
||||||
|
int cache_mngt_activate(struct ocf_mngt_cache_device_config *cfg,
|
||||||
|
struct kcas_failover_activate *cmd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,15 +50,15 @@ long cas_service_ioctl_ctrl(struct file *filp, unsigned int cmd,
|
|||||||
case KCAS_IOCTL_START_CACHE: {
|
case KCAS_IOCTL_START_CACHE: {
|
||||||
struct kcas_start_cache *cmd_info;
|
struct kcas_start_cache *cmd_info;
|
||||||
struct ocf_mngt_cache_config cfg;
|
struct ocf_mngt_cache_config cfg;
|
||||||
struct ocf_mngt_cache_device_config device_cfg;
|
struct ocf_mngt_cache_attach_config attach_cfg;
|
||||||
|
|
||||||
GET_CMD_INFO(cmd_info, arg);
|
GET_CMD_INFO(cmd_info, arg);
|
||||||
|
|
||||||
retval = cache_mngt_prepare_cache_cfg(&cfg, &device_cfg, cmd_info);
|
retval = cache_mngt_prepare_cache_cfg(&cfg, &attach_cfg, cmd_info);
|
||||||
if (retval)
|
if (retval)
|
||||||
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
||||||
|
|
||||||
retval = cache_mngt_init_instance(&cfg, &device_cfg, cmd_info);
|
retval = cache_mngt_init_instance(&cfg, &attach_cfg, cmd_info);
|
||||||
|
|
||||||
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
||||||
}
|
}
|
||||||
@ -378,7 +378,30 @@ long cas_service_ioctl_ctrl(struct file *filp, unsigned int cmd,
|
|||||||
|
|
||||||
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
||||||
}
|
}
|
||||||
|
case KCAS_IOCTL_FAILOVER_DETACH: {
|
||||||
|
struct kcas_failover_detach *cmd_info;
|
||||||
|
|
||||||
|
GET_CMD_INFO(cmd_info, arg);
|
||||||
|
|
||||||
|
retval = cache_mngt_failover_detach(cmd_info);
|
||||||
|
|
||||||
|
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
||||||
|
}
|
||||||
|
case KCAS_IOCTL_FAILOVER_ACTIVATE: {
|
||||||
|
struct kcas_failover_activate *cmd_info;
|
||||||
|
struct ocf_mngt_cache_device_config cfg;
|
||||||
|
|
||||||
|
GET_CMD_INFO(cmd_info, arg);
|
||||||
|
|
||||||
|
retval = cache_mngt_prepare_cache_device_cfg(&cfg,
|
||||||
|
cmd_info->cache_path);
|
||||||
|
if (retval)
|
||||||
|
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
||||||
|
|
||||||
|
retval = cache_mngt_activate(&cfg, cmd_info);
|
||||||
|
|
||||||
|
RETURN_CMD_RESULT(cmd_info, arg, retval);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,7 @@
|
|||||||
|
|
||||||
#define CACHE_INIT_NEW 0 /**< initialize new metadata from fresh start */
|
#define CACHE_INIT_NEW 0 /**< initialize new metadata from fresh start */
|
||||||
#define CACHE_INIT_LOAD 1 /**< load existing metadata */
|
#define CACHE_INIT_LOAD 1 /**< load existing metadata */
|
||||||
#define CACHE_INIT_BIND 2 /**< bind existing metadata */
|
#define CACHE_INIT_STANDBY 2 /**< initialize failover standby cache */
|
||||||
#define CACHE_INIT_ACTIVATE 3 /**< activate cache after bind */
|
|
||||||
|
|
||||||
struct kcas_start_cache {
|
struct kcas_start_cache {
|
||||||
/**
|
/**
|
||||||
@ -353,6 +352,21 @@ struct kcas_get_cache_param {
|
|||||||
int ext_err_code;
|
int ext_err_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct kcas_failover_detach
|
||||||
|
{
|
||||||
|
uint16_t cache_id;
|
||||||
|
|
||||||
|
int ext_err_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kcas_failover_activate
|
||||||
|
{
|
||||||
|
uint16_t cache_id;
|
||||||
|
char cache_path[MAX_STR_LEN]; /**< path to an ssd*/
|
||||||
|
|
||||||
|
int ext_err_code;
|
||||||
|
};
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* CODE * NAME * STATUS *
|
* CODE * NAME * STATUS *
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
@ -483,6 +497,12 @@ struct kcas_get_cache_param {
|
|||||||
/** Remove inactive core object from an running cache instance */
|
/** Remove inactive core object from an running cache instance */
|
||||||
#define KCAS_IOCTL_REMOVE_INACTIVE _IOWR(KCAS_IOCTL_MAGIC, 37, struct kcas_remove_inactive)
|
#define KCAS_IOCTL_REMOVE_INACTIVE _IOWR(KCAS_IOCTL_MAGIC, 37, struct kcas_remove_inactive)
|
||||||
|
|
||||||
|
/** Detach caching drive from failover standby cache instance */
|
||||||
|
#define KCAS_IOCTL_FAILOVER_DETACH _IOWR(KCAS_IOCTL_MAGIC, 38, struct kcas_failover_detach)
|
||||||
|
|
||||||
|
/** Activate standby failover cache instance */
|
||||||
|
#define KCAS_IOCTL_FAILOVER_ACTIVATE _IOWR(KCAS_IOCTL_MAGIC, 39, struct kcas_failover_activate)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extended kernel CAS error codes
|
* Extended kernel CAS error codes
|
||||||
*/
|
*/
|
||||||
|
2
ocf
2
ocf
@ -1 +1 @@
|
|||||||
Subproject commit 886c8d4e31e160f36d5ca3d0698a79811c8c0eca
|
Subproject commit 7b120162a573868221a3f66366ecbf2e1f4b90be
|
Loading…
Reference in New Issue
Block a user