Merge pull request #1057 from jfckm/standby-load-config

Standby load config
This commit is contained in:
Robert Baldyga 2022-02-11 10:12:02 +01:00 committed by GitHub
commit 1742841ee3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 273 additions and 108 deletions

View File

@ -967,9 +967,8 @@ int start_cache(uint16_t cache_id, unsigned int cache_init,
{ {
int fd = 0; int fd = 0;
struct kcas_start_cache cmd; struct kcas_start_cache cmd;
struct cache_device **caches;
struct cache_device *cache; struct cache_device *cache;
int i, status, caches_count; int i, status;
double min_free_ram_gb; double min_free_ram_gb;
/* check if cache device given exists */ /* check if cache device given exists */
@ -984,21 +983,6 @@ int start_cache(uint16_t cache_id, unsigned int cache_init,
if (fd == -1) if (fd == -1)
return FAILURE; return FAILURE;
if (cache_id == 0) {
cache_id = 1;
caches = get_cache_devices(&caches_count, false);
if (caches != NULL) {
psort(caches, caches_count, sizeof(struct cache_device*), caches_compare);
for (i = 0; i < caches_count; ++i) {
if (caches[i]->id == cache_id) {
cache_id += 1;
}
}
free_cache_devices_list(caches, caches_count);
}
}
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.cache_id = cache_id; cmd.cache_id = cache_id;
@ -1014,9 +998,12 @@ int start_cache(uint16_t cache_id, unsigned int cache_init,
cmd.line_size = line_size; cmd.line_size = line_size;
cmd.force = (uint8_t)force; cmd.force = (uint8_t)force;
if (run_ioctl_interruptible_retry(fd, KCAS_IOCTL_START_CACHE, &cmd, status = run_ioctl_interruptible_retry(fd, KCAS_IOCTL_START_CACHE, &cmd,
"Starting cache", cache_id, OCF_CORE_ID_INVALID) < 0) { "Starting cache", cache_id, OCF_CORE_ID_INVALID);
cache_id = cmd.cache_id;
if (status < 0) {
close(fd); close(fd);
if (cmd.ext_err_code == OCF_ERR_NO_FREE_RAM) { if (cmd.ext_err_code == OCF_ERR_NO_FREE_RAM) {
min_free_ram_gb = cmd.min_free_ram; min_free_ram_gb = cmd.min_free_ram;
min_free_ram_gb /= GiB; min_free_ram_gb /= GiB;
@ -3014,7 +3001,7 @@ int standby_load(int cache_id, ocf_cache_line_size_t line_size,
return start_cache(cache_id, return start_cache(cache_id,
CACHE_INIT_STANDBY_LOAD, CACHE_INIT_STANDBY_LOAD,
cache_device, cache_device,
ocf_cache_mode_default, ocf_cache_mode_none,
line_size, line_size,
0); 0);
} }

View File

@ -406,17 +406,24 @@ int handle_start()
{ {
int status; int status;
if (command_args_values.state == CACHE_INIT_LOAD && command_args_values.force) { if (command_args_values.state == CACHE_INIT_LOAD) {
cas_printf(LOG_ERR, "Use of 'load' and 'force' simultaneously is forbidden.\n"); if (command_args_values.force ||
return FAILURE; command_args_values.line_size != ocf_cache_line_size_none ||
} command_args_values.cache_mode != ocf_cache_mode_none ||
command_args_values.cache_id != OCF_CACHE_ID_INVALID) {
cas_printf(LOG_ERR, "Use of 'load' with 'force', 'cache-id',"
" 'cache-mode' or 'cache-line-size'"
" simultaneously is forbidden.\n");
return FAILURE;
}
} else {
if (command_args_values.line_size == ocf_cache_line_size_none) {
command_args_values.line_size = ocf_cache_line_size_default;
}
if (command_args_values.line_size == ocf_cache_line_size_none) { if (command_args_values.cache_mode == ocf_cache_mode_none) {
command_args_values.line_size = ocf_cache_line_size_default; command_args_values.cache_mode = ocf_cache_mode_default;
} }
if (command_args_values.cache_mode == ocf_cache_mode_none) {
command_args_values.cache_mode = ocf_cache_mode_default;
} }
if (validate_cache_path(command_args_values.cache_device) == FAILURE) if (validate_cache_path(command_args_values.cache_device) == FAILURE)
@ -1473,7 +1480,7 @@ int io_class_is_missing() {
/* Option is set, check if this option is allowed */ /* Option is set, check if this option is allowed */
mask = (1 << io_class_params.subcmd); mask = (1 << io_class_params.subcmd);
if (0 == (mask & iter->priv)) { if (0 == (mask & iter->priv)) {
cas_printf(LOG_INFO, "Option '%s' is not allowed\n", option_name); cas_printf(LOG_ERR, "Option '%s' is not allowed\n", option_name);
result = -1; result = -1;
} }
@ -1481,7 +1488,7 @@ int io_class_is_missing() {
/* Option is missing, check if it is required for this sub-command*/ /* Option is missing, check if it is required for this sub-command*/
mask = (1 << io_class_params.subcmd) | (1 << io_class_opt_flag_required); mask = (1 << io_class_params.subcmd) | (1 << io_class_opt_flag_required);
if (mask == (iter->priv & mask)) { if (mask == (iter->priv & mask)) {
cas_printf(LOG_INFO, "Option '%s' is missing\n", option_name); cas_printf(LOG_ERR, "Option '%s' is missing\n", option_name);
result = -1; result = -1;
} }
} }
@ -1741,12 +1748,12 @@ int script_command_is_valid() {
if (option_is_set) { if (option_is_set) {
if (!is_option_allowed(option_id)) { if (!is_option_allowed(option_id)) {
cas_printf(LOG_INFO, "Option '%s' is not allowed\n", option_name); cas_printf(LOG_ERR, "Option '%s' is not allowed\n", option_name);
result = FAILURE; result = FAILURE;
} }
} else { } else {
if (is_option_required(option_id)) { if (is_option_required(option_id)) {
cas_printf(LOG_INFO, "Option '%s' is missing\n", option_name); cas_printf(LOG_ERR, "Option '%s' is missing\n", option_name);
result = FAILURE; result = FAILURE;
} }
} }
@ -1926,7 +1933,6 @@ static cli_option standby_params_options[] = {
.args_count = 1, .args_count = 1,
.arg = "ID", .arg = "ID",
.priv = (1 << standby_opt_subcmd_init) .priv = (1 << standby_opt_subcmd_init)
| (1 << standby_opt_subcmd_load)
| (1 << standby_opt_subcmd_detach) | (1 << standby_opt_subcmd_detach)
| (1 << standby_opt_subcmd_activate) | (1 << standby_opt_subcmd_activate)
| (1 << standby_opt_flag_required), | (1 << standby_opt_flag_required),
@ -1941,7 +1947,6 @@ static cli_option standby_params_options[] = {
.args_count = 1, .args_count = 1,
.arg = "NUMBER", .arg = "NUMBER",
.priv = (1 << standby_opt_subcmd_init) .priv = (1 << standby_opt_subcmd_init)
| (1 << standby_opt_subcmd_load)
| (1 << standby_opt_flag_required), | (1 << standby_opt_flag_required),
.flags = CLI_OPTION_DEFAULT_INT, .flags = CLI_OPTION_DEFAULT_INT,
.default_value = ocf_cache_line_size_default / KiB, .default_value = ocf_cache_line_size_default / KiB,
@ -2053,7 +2058,7 @@ int standby_is_missing() {
/* Option is set, check if this option is allowed */ /* Option is set, check if this option is allowed */
mask = (1 << standby_params.subcmd); mask = (1 << standby_params.subcmd);
if (0 == (mask & iter->priv)) { if (0 == (mask & iter->priv)) {
cas_printf(LOG_INFO, "Option '%s' is not allowed\n", option_name); cas_printf(LOG_ERR, "Option '%s' is not allowed\n", option_name);
result = -1; result = -1;
} }
@ -2061,7 +2066,7 @@ int standby_is_missing() {
/* Option is missing, check if it is required for this sub-command*/ /* Option is missing, check if it is required for this sub-command*/
mask = (1 << standby_params.subcmd) | (1 << standby_opt_flag_required); mask = (1 << standby_params.subcmd) | (1 << standby_opt_flag_required);
if (mask == (iter->priv & mask)) { if (mask == (iter->priv & mask)) {
cas_printf(LOG_INFO, "Option '%s' is missing\n", option_name); cas_printf(LOG_ERR, "Option '%s' is missing\n", option_name);
result = -1; result = -1;
} }
} }
@ -2078,6 +2083,16 @@ int standby_handle() {
return FAILURE; return FAILURE;
} }
if (standby_params.subcmd == standby_opt_subcmd_load &&
(standby_params.force ||
standby_params.line_size != ocf_cache_line_size_none ||
standby_params.cache_id != OCF_CACHE_ID_INVALID)) {
cas_printf(LOG_ERR, "Use of 'load' with 'force', 'cache-id'"
" or 'cache-line-size' simultaneously is"
" forbidden.\n");
return FAILURE;
}
/* Check if all required options are set */ /* Check if all required options are set */
if (standby_is_missing()) { if (standby_is_missing()) {
return FAILURE; return FAILURE;

View File

@ -1839,7 +1839,6 @@ int cache_mngt_prepare_cache_device_cfg(struct ocf_mngt_cache_device_config *cfg
&cfg->volume_type); &cfg->volume_type);
} }
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_attach_config *attach_cfg, struct ocf_mngt_cache_attach_config *attach_cfg,
struct kcas_start_cache *cmd) struct kcas_start_cache *cmd)
@ -1851,7 +1850,25 @@ 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 (cmd->cache_id == OCF_CACHE_ID_INVALID) { if (cmd->init_cache == CACHE_INIT_LOAD ||
cmd->init_cache == CACHE_INIT_STANDBY_LOAD) {
if (cmd->cache_id != OCF_CACHE_ID_INVALID) {
printk(KERN_WARNING "Specifying cache id while loading "
"cache is forbidden\n");
return -OCF_ERR_INVAL;
}
if (cmd->line_size != ocf_cache_line_size_none) {
printk(KERN_WARNING "Specifying cache line size while "
"loading cache is forbidden\n");
return -OCF_ERR_INVAL;
}
if (cmd->caching_mode != ocf_cache_mode_none) {
printk(KERN_WARNING "Specifying cache mode while "
"loading cache is forbidden\n");
return -OCF_ERR_INVAL;
}
} else 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)
return -OCF_ERR_INVAL; return -OCF_ERR_INVAL;
@ -2043,39 +2060,47 @@ static int _cache_mngt_cache_priv_init(ocf_cache_t cache)
return 0; return 0;
} }
struct cache_mngt_check_metadata_context { struct cache_mngt_probe_metadata_context {
struct completion cmpl; struct completion cmpl;
char *cache_name; char *cache_name;
int *result; int *result;
char *cache_name_meta;
ocf_cache_mode_t *cache_mode_meta;
ocf_cache_line_size_t *cache_line_size_meta;
}; };
static void cache_mngt_check_metadata_end(void *priv, int error, static void cache_mngt_probe_metadata_end(void *priv, int error,
struct ocf_metadata_probe_status *status) struct ocf_metadata_probe_status *status)
{ {
struct cache_mngt_check_metadata_context *context = priv; struct cache_mngt_probe_metadata_context *context = priv;
*context->result = error; *context->result = error;
if (error == -OCF_ERR_NO_METADATA) { if (error == -OCF_ERR_NO_METADATA) {
printk(KERN_ERR "No cache metadata found!\n"); printk(KERN_ERR "No cache metadata found!\n");
goto err;
} else if (error == -OCF_ERR_METADATA_VER) { } else if (error == -OCF_ERR_METADATA_VER) {
printk(KERN_ERR "Cache metadata version mismatch\n"); printk(KERN_ERR "Cache metadata version mismatch\n");
goto err;
} else if (error) { } else if (error) {
printk(KERN_ERR "Failed to load cache metadata!\n"); printk(KERN_ERR "Failed to load cache metadata!\n");
} else if (strncmp(status->cache_name, context->cache_name, goto err;
OCF_CACHE_NAME_SIZE)) {
*context->result = -OCF_ERR_CACHE_NAME_MISMATCH;
printk(KERN_ERR "Loaded cache name is invalid: %s!\n",
status->cache_name);
} }
strlcpy(context->cache_name_meta, status->cache_name,
OCF_CACHE_NAME_SIZE);
*(context->cache_mode_meta) = status->cache_mode;
*(context->cache_line_size_meta) = status->cache_line_size;
err:
complete(&context->cmpl); complete(&context->cmpl);
} }
static int _cache_mngt_check_metadata(struct ocf_mngt_cache_config *cfg, static int _cache_mngt_probe_metadata(char *cache_path_name,
char *cache_path_name) char *cache_name_meta, ocf_cache_mode_t *cache_mode_meta,
ocf_cache_line_size_t *cache_line_size_meta)
{ {
struct cache_mngt_check_metadata_context context; struct cache_mngt_probe_metadata_context context;
struct block_device *bdev; struct block_device *bdev;
ocf_volume_t volume; ocf_volume_t volume;
char holder[] = "CAS CHECK METADATA\n"; char holder[] = "CAS CHECK METADATA\n";
@ -2094,10 +2119,12 @@ static int _cache_mngt_check_metadata(struct ocf_mngt_cache_config *cfg,
goto out_bdev; goto out_bdev;
init_completion(&context.cmpl); init_completion(&context.cmpl);
context.cache_name = cfg->name;
context.result = &result; context.result = &result;
context.cache_name_meta = cache_name_meta;
context.cache_mode_meta = cache_mode_meta;
context.cache_line_size_meta = cache_line_size_meta;
ocf_metadata_probe(cas_ctx, volume, cache_mngt_check_metadata_end, ocf_metadata_probe(cas_ctx, volume, cache_mngt_probe_metadata_end,
&context); &context);
wait_for_completion(&context.cmpl); wait_for_completion(&context.cmpl);
@ -2351,9 +2378,12 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
struct kcas_start_cache *cmd) struct kcas_start_cache *cmd)
{ {
struct _cache_mngt_attach_context *context; struct _cache_mngt_attach_context *context;
ocf_cache_t cache; ocf_cache_t cache, tmp_cache = NULL;
char cache_name_meta[OCF_CACHE_NAME_SIZE];
struct cache_priv *cache_priv; struct cache_priv *cache_priv;
int result = 0, rollback_result = 0; int result = 0, rollback_result = 0;
ocf_cache_mode_t cache_mode_meta;
ocf_cache_line_size_t cache_line_size_meta;
if (!try_module_get(THIS_MODULE)) if (!try_module_get(THIS_MODULE))
return -KCAS_ERR_SYSTEM; return -KCAS_ERR_SYSTEM;
@ -2367,11 +2397,40 @@ int cache_mngt_init_instance(struct ocf_mngt_cache_config *cfg,
switch (cmd->init_cache) { switch (cmd->init_cache) {
case CACHE_INIT_LOAD: case CACHE_INIT_LOAD:
case CACHE_INIT_STANDBY_LOAD: case CACHE_INIT_STANDBY_LOAD:
result = _cache_mngt_check_metadata(cfg, cmd->cache_path_name); result = _cache_mngt_probe_metadata(cmd->cache_path_name,
cache_name_meta, &cache_mode_meta,
&cache_line_size_meta);
if (result) { if (result) {
module_put(THIS_MODULE); module_put(THIS_MODULE);
return result; return result;
} }
/* Need to return name from metadata now for caller to properly
* communicate the error to user */
if (cache_id_from_name(&cmd->cache_id, cache_name_meta)) {
printk(KERN_ERR "Improper cache name format on %s.\n",
cmd->cache_path_name);
module_put(THIS_MODULE);
return -OCF_ERR_START_CACHE_FAIL;
}
result = ocf_mngt_cache_get_by_name(cas_ctx, cache_name_meta,
OCF_CACHE_NAME_SIZE, &tmp_cache);
if (result != -OCF_ERR_CACHE_NOT_EXIST) {
printk(KERN_ERR "Can't load %s. Cache using that name "
"already exists.\n", cache_name_meta);
ocf_mngt_cache_put(tmp_cache);
module_put(THIS_MODULE);
return -OCF_ERR_CACHE_EXIST;
}
result = 0;
strlcpy(cfg->name, cache_name_meta, OCF_CACHE_NAME_SIZE);
cfg->cache_mode = cache_mode_meta;
cfg->cache_line_size = cache_line_size_meta;
default: default:
break; break;
} }

View File

@ -81,7 +81,8 @@ stop_cache_mounted_core = [
] ]
load_and_force = [ load_and_force = [
r"Use of \'load\' and \'force\' simultaneously is forbidden\." (r"Use of \'load\' and \'force\', \'cache-id\', \'cache-mode\' or \'cache-line-size\'",
r" simultaneously is forbidden.")
] ]
try_add_core_sector_size_mismatch = [ try_add_core_sector_size_mismatch = [

View File

@ -30,8 +30,11 @@ restore_config() {
start_cache() { start_cache() {
check_options ${FUNCNAME[0]} check_options ${FUNCNAME[0]}
local COMMAND="$CAS --start-cache --cache-device $CACHE_DEVICE_OPTION --cache-id $CACHE_ID_OPTION" local COMMAND="$CAS --start-cache --cache-device $CACHE_DEVICE_OPTION"
if [ -n "$CACHE_ID_OPTION" ] ; then
COMMAND="$COMMAND --cache-id $CACHE_ID_OPTION"
fi
if [ -n "$CACHE_FORCE_OPTION" ] ; then if [ -n "$CACHE_FORCE_OPTION" ] ; then
COMMAND="$COMMAND --force" COMMAND="$COMMAND --force"
fi fi

View File

@ -33,7 +33,7 @@ export ALL_OPTIONS="
# Specify ONLY required options here. The name of the variable should start with # Specify ONLY required options here. The name of the variable should start with
# uppercase function's name + "_REQUIRED_OPTIONS". # uppercase function's name + "_REQUIRED_OPTIONS".
export START_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION CACHE_DEVICE_OPTION" export START_CACHE_REQUIRED_OPTIONS="CACHE_DEVICE_OPTION"
export STOP_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION" export STOP_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION"
export ADD_CORE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_DEVICE_OPTION" export ADD_CORE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_DEVICE_OPTION"
export TRY_ADD_CORE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_ID_OPTION CORE_DEVICE_OPTION" export TRY_ADD_CORE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_ID_OPTION CORE_DEVICE_OPTION"
@ -67,7 +67,6 @@ export TURN_ON_NVME_DEVICE_REQUIRED_OPTIONS="CACHE_DEVICE_OPTION"
export START_DUAL_LEVEL_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION CACHE_DEVICE_OPTION" export START_DUAL_LEVEL_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION CACHE_DEVICE_OPTION"
export START_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION CACHE_DEVICE_OPTION"
export IO_CLASS_LIST_REQUIRED_OPTIONS="CACHE_ID_OPTION" export IO_CLASS_LIST_REQUIRED_OPTIONS="CACHE_ID_OPTION"
export IO_CLASS_LOAD_REQUIRED_OPTIONS="CACHE_ID_OPTION CSV_FILE" export IO_CLASS_LOAD_REQUIRED_OPTIONS="CACHE_ID_OPTION CSV_FILE"

View File

@ -57,7 +57,7 @@ DEVICE_ID_OPTION="${CORE_DEVICE}-part3" DEMANDED_STATE_OPTION="Detached" check_d
# Try to load cache device, check if it is running and if all cores status is appropirate # Try to load cache device, check if it is running and if all cores status is appropirate
CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" CACHE_LOAD_METADATA_OPTION="y" start_cache CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" CACHE_LOAD_METADATA_OPTION="y" start_cache
DEVICE_ID_OPTION="${CACHE_DEVICE}-part1" DEMANDED_STATE_OPTION="Running" check_device_state DEVICE_ID_OPTION="${CACHE_DEVICE}-part1" DEMANDED_STATE_OPTION="Running" check_device_state
DEVICE_ID_OPTION="${DEVICE_NAME}1-1" DEMANDED_STATE_OPTION="Active" check_device_state DEVICE_ID_OPTION="${DEVICE_NAME}1-1" DEMANDED_STATE_OPTION="Active" check_device_state
DEVICE_ID_OPTION="${DEVICE_NAME}1-2" DEMANDED_STATE_OPTION="Active" check_device_state DEVICE_ID_OPTION="${DEVICE_NAME}1-2" DEMANDED_STATE_OPTION="Active" check_device_state

View File

@ -48,7 +48,7 @@ TARGET_DEVICE_OPTION="$CORE_DEVICE" PARTITION_SIZE_OPTION="4000M" PARTITION_IDS_
sleep 1 sleep 1
# Load cache, then add cores and check if chache is running # Load cache, then add cores and check if chache is running
# Try to load cache device, check its state and cores state # Try to load cache device, check its state and cores state
CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" CACHE_LOAD_METADATA_OPTION="y" start_cache CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" CACHE_LOAD_METADATA_OPTION="y" start_cache
DEVICE_ID_OPTION="${CACHE_DEVICE}-part1" DEMANDED_STATE_OPTION="Incomplete" check_device_state DEVICE_ID_OPTION="${CACHE_DEVICE}-part1" DEMANDED_STATE_OPTION="Incomplete" check_device_state
DEVICE_ID_OPTION="${DEVICE_NAME}1-1" DEMANDED_STATE_OPTION="Active" check_device_state DEVICE_ID_OPTION="${DEVICE_NAME}1-1" DEMANDED_STATE_OPTION="Active" check_device_state
DEVICE_ID_OPTION="${DEVICE_NAME}1-2" DEMANDED_STATE_OPTION="Active" check_device_state DEVICE_ID_OPTION="${DEVICE_NAME}1-2" DEMANDED_STATE_OPTION="Active" check_device_state
@ -66,7 +66,7 @@ DEVICE_ID_OPTION="${CORE_DEVICE}-part1" DEMANDED_STATE_OPTION="Detached" check_d
DEVICE_ID_OPTION="${CORE_DEVICE}-part2" DEMANDED_STATE_OPTION="Detached" check_device_state DEVICE_ID_OPTION="${CORE_DEVICE}-part2" DEMANDED_STATE_OPTION="Detached" check_device_state
DEVICE_ID_OPTION="${CORE_DEVICE}-part3" DEMANDED_STATE_OPTION="Detached" check_device_state DEVICE_ID_OPTION="${CORE_DEVICE}-part3" DEMANDED_STATE_OPTION="Detached" check_device_state
CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" CACHE_LOAD_METADATA_OPTION="y" start_cache CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" CACHE_LOAD_METADATA_OPTION="y" start_cache
DEVICE_ID_OPTION="${CACHE_DEVICE}-part1" DEMANDED_STATE_OPTION="Running" check_device_state DEVICE_ID_OPTION="${CACHE_DEVICE}-part1" DEMANDED_STATE_OPTION="Running" check_device_state
DEVICE_ID_OPTION="${DEVICE_NAME}1-1" DEMANDED_STATE_OPTION="Active" check_device_state DEVICE_ID_OPTION="${DEVICE_NAME}1-1" DEMANDED_STATE_OPTION="Active" check_device_state

View File

@ -114,7 +114,7 @@ do
fi fi
# Start again with load option, this should fail, metadata is corrupted. # Start again with load option, this should fail, metadata is corrupted.
NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="1" CACHE_LOAD_METADATA_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" start_cache NEGATIVE_TEST_OPTION="1" CACHE_LOAD_METADATA_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" start_cache
done done

View File

@ -91,7 +91,7 @@ do
fi fi
# Start again with load option, this should fail, metadata is corrupted. # Start again with load option, this should fail, metadata is corrupted.
NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="1" CACHE_LOAD_METADATA_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" start_cache NEGATIVE_TEST_OPTION="1" CACHE_LOAD_METADATA_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" start_cache
done done
test_log_stop test_log_stop

View File

@ -108,7 +108,7 @@ CACHE_ID_OPTION="1" PROMO_POL_NS_OPTION="promotion-nhit" THRESHOLD_OPTION="451"
CACHE_ID_OPTION="1" PROMO_POL_NS_OPTION="promotion-nhit" THRESHOLD_OPTION="812" TRIGGER_OPTION="49" set_promotion_params CACHE_ID_OPTION="1" PROMO_POL_NS_OPTION="promotion-nhit" THRESHOLD_OPTION="812" TRIGGER_OPTION="49" set_promotion_params
CACHE_ID_OPTION="1" PROMO_POL_OPTION="nhit" set_promotion_policy CACHE_ID_OPTION="1" PROMO_POL_OPTION="nhit" set_promotion_policy
CACHE_ID_OPTION="1" stop_cache CACHE_ID_OPTION="1" stop_cache
CACHE_MODE_OPTION="wt" CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" CACHE_LOAD_METADATA_OPTION="1" start_cache CACHE_MODE_OPTION="wt" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part1" CACHE_LOAD_METADATA_OPTION="1" start_cache
CACHE_ID_OPTION="1" PROMO_POL_OPTION="nhit" check_promotion_policy CACHE_ID_OPTION="1" PROMO_POL_OPTION="nhit" check_promotion_policy
CACHE_ID_OPTION="1" PROMO_POL_NS_OPTION="promotion-nhit" THRESHOLD_OPTION="812" TRIGGER_OPTION="49" check_promotion_params CACHE_ID_OPTION="1" PROMO_POL_NS_OPTION="promotion-nhit" THRESHOLD_OPTION="812" TRIGGER_OPTION="49" check_promotion_params

View File

@ -72,7 +72,7 @@ done
CACHE_DEVICE_OPTION="${SHORT_LINK}" turn_on_device CACHE_DEVICE_OPTION="${SHORT_LINK}" turn_on_device
for ID in 1 2 3 ; do for ID in 1 2 3 ; do
CACHE_ID_OPTION="$ID" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part${ID}" CACHE_LOAD_METADATA_OPTION="y" CACHE_MODE_OPTION="wb" start_cache CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part${ID}" CACHE_LOAD_METADATA_OPTION="y" start_cache
CACHE_ID_OPTION="$ID" stop_cache CACHE_ID_OPTION="$ID" stop_cache
run_cmd "mount ${CORE_DEVICE}-part${ID} ${MOUNTPOINT}-${ID}-1" run_cmd "mount ${CORE_DEVICE}-part${ID} ${MOUNTPOINT}-${ID}-1"
done done

View File

@ -72,7 +72,7 @@ done
CACHE_DEVICE_OPTION="${SHORT_LINK}" turn_on_device CACHE_DEVICE_OPTION="${SHORT_LINK}" turn_on_device
for ID in 1 2 3 ; do for ID in 1 2 3 ; do
CACHE_ID_OPTION="$ID" CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part${ID}" CACHE_LOAD_METADATA_OPTION="y" CACHE_MODE_OPTION="wb" start_cache CACHE_DEVICE_OPTION="${CACHE_DEVICE}-part${ID}" CACHE_LOAD_METADATA_OPTION="y" start_cache
CACHE_ID_OPTION="$ID" CORE_ID_OPTION="1" mount_cache CACHE_ID_OPTION="$ID" CORE_ID_OPTION="1" mount_cache
done done

View File

@ -316,7 +316,7 @@ def test_cas_config_get_by_id_path_not_found(mock_listdir, mock_realpath):
"2 /dev/dummy0n2 pt ioclass_file=mango.csv", "2 /dev/dummy0n2 pt ioclass_file=mango.csv",
"3 /dev/dummy0n3 WA cache_line_size=16", "3 /dev/dummy0n3 WA cache_line_size=16",
("4 /dev/dummyc wb cache_line_size=16," ("4 /dev/dummyc wb cache_line_size=16,"
"ioclass_file=mango.csv,cleaning_policy=nop"), "ioclass_file=mango.csv,cleaning_policy=nop,target_failover_state=standby"),
], ],
[], [],
), ),

View File

@ -187,8 +187,10 @@ def test_cache_config_from_line_missing_ioclass_file(
"ioclass_file=ioclass.csv,ioclass_file=ioclass.csv", "ioclass_file=ioclass.csv,ioclass_file=ioclass.csv",
"cleaning_policy=nop,cleaning_policy=acp", "cleaning_policy=nop,cleaning_policy=acp",
"cleaning_policy=", "cleaning_policy=",
"clining_polisi=nop",
"cleaning_policy=INVALID", "cleaning_policy=INVALID",
"ioclass_file=ioclass.csv, cleaning_policy=nop", "ioclass_file=ioclass.csv, cleaning_policy=nop",
"ioclas_file=ioclass.csv",
"cache_line_size=4,cache_line_size=8", "cache_line_size=4,cache_line_size=8",
"cache_line_size=", "cache_line_size=",
"cache_line_size=0", "cache_line_size=0",
@ -198,14 +200,20 @@ def test_cache_config_from_line_missing_ioclass_file(
"cache_line_size=-1", "cache_line_size=-1",
"cache_line_size=four", "cache_line_size=four",
"cache_line_size=128", "cache_line_size=128",
"cach_lin_siz=4",
"promotion_policy=111111", "promotion_policy=111111",
"promotion_policy=", "promotion_policy=",
"promotion_policy=dinosaurs", "promotion_policy=dinosaurs",
"promotion_policy=Robert'); DROP TABLE Students;--", "promotion_policy=Robert'); DROP TABLE Students;--",
"promotion_policy=awlays", "promotion_policy=awlays",
"promotion_policy=nnhit", "promotion_policy=nnhit",
"demolition_policy=nhit",
"lazy_startup=yes", "lazy_startup=yes",
"lazy_startup=absolutely", "lazy_startup=absolutely",
"hasty_startup=true",
"target_failover_state=no",
"target_failover_state=maybe",
"target_failrover_state=standby",
], ],
) )
@mock.patch("os.path.exists") @mock.patch("os.path.exists")
@ -242,10 +250,12 @@ def test_cache_config_from_line_parameter_validation_01(
"ioclass_file=ioclass.csv,cache_line_size=4,cleaning_policy=nop", "ioclass_file=ioclass.csv,cache_line_size=4,cleaning_policy=nop",
"promotion_policy=nhit", "promotion_policy=nhit",
"promotion_policy=always", "promotion_policy=always",
"target_failover_state=standby",
"target_failover_state=active",
"lazy_startup=true", "lazy_startup=true",
"lazy_startup=false", "lazy_startup=false",
("ioclass_file=ioclass.csv,cache_line_size=4,cleaning_policy=nop,promotion_policy=always," ("ioclass_file=ioclass.csv,cache_line_size=4,cleaning_policy=nop,promotion_policy=always,"
"lazy_startup=true"), "lazy_startup=true,target_failover_state=active"),
], ],
) )
@mock.patch("os.path.exists") @mock.patch("os.path.exists")
@ -416,6 +426,7 @@ def test_cache_config_from_line_cache_id_validation_02(
"cache_mode": "wo", "cache_mode": "wo",
"promotion_policy": "always", "promotion_policy": "always",
"cache_line_size": "16", "cache_line_size": "16",
"lazy_startup": "true"
}, },
{ {
"cache_id": "1", "cache_id": "1",
@ -423,6 +434,7 @@ def test_cache_config_from_line_cache_id_validation_02(
"cache_mode": "wo", "cache_mode": "wo",
"promotion_policy": "nhit", "promotion_policy": "nhit",
"cache_line_size": "16", "cache_line_size": "16",
"target_failover_state": "active",
}, },
], ],
) )

View File

@ -6,6 +6,7 @@
import pytest import pytest
from unittest.mock import patch, Mock from unittest.mock import patch, Mock
import time import time
import subprocess
import opencas import opencas
@ -74,7 +75,7 @@ def test_cas_settle_cores_didnt_start_02(mock_add, mock_exists, mock_run, mock_l
"type": "cache", "type": "cache",
"id": "1", "id": "1",
"disk": "/dev/dummy_cache", "disk": "/dev/dummy_cache",
"status": "Active", "status": "Standby",
"write policy": "wt", "write policy": "wt",
"device": "-", "device": "-",
} }
@ -303,7 +304,11 @@ def test_cas_settle_caches_didnt_start_01(
mock_config.return_value = Mock( mock_config.return_value = Mock(
spec_set=opencas.cas_config(), spec_set=opencas.cas_config(),
cores=[], cores=[],
caches={42: opencas.cas_config.cache_config(42, "/dev/dummy", "wt")}, caches={
42: opencas.cas_config.cache_config(
42, "/dev/dummy", "wt", target_failover_state="standby"
)
},
) )
result = opencas.wait_for_startup(timeout=0, interval=0) result = opencas.wait_for_startup(timeout=0, interval=0)
@ -345,7 +350,7 @@ def test_cas_settle_caches_didnt_start_02(
result = opencas.wait_for_startup(timeout=0, interval=0) result = opencas.wait_for_startup(timeout=0, interval=0)
assert len(result) == 1, "didn't return uninitialized core" assert len(result) == 1, "didn't return uninitialized cache"
@patch("opencas.cas_config.from_file") @patch("opencas.cas_config.from_file")
@ -416,7 +421,7 @@ def test_cas_settle_caches_didnt_start_03(
result = opencas.wait_for_startup(timeout=0, interval=0) result = opencas.wait_for_startup(timeout=0, interval=0)
assert len(result) == 2, "didn't return uninitialized cores" assert len(result) == 2, "didn't return uninitialized caches"
@patch("opencas.cas_config.from_file") @patch("opencas.cas_config.from_file")
@ -802,10 +807,10 @@ def test_last_resort_add_02(mock_start, mock_add, mock_exists, mock_run, mock_li
result = opencas.wait_for_startup(timeout=0, interval=0) result = opencas.wait_for_startup(timeout=0, interval=0)
mock_start.assert_any_call(config.caches[1], True) mock_start.assert_any_call(config.caches[1], load=True)
mock_start.assert_any_call(config.caches[2], True) mock_start.assert_any_call(config.caches[2], load=True)
mock_add.assert_any_call(config.cores[0], True) mock_add.assert_any_call(config.cores[0], try_add=True)
mock_add.assert_any_call(config.cores[1], True) mock_add.assert_any_call(config.cores[1], try_add=True)
mock_run.assert_called_with(["udevadm", "settle"]) mock_run.assert_called_with(["udevadm", "settle"])
@ -883,10 +888,10 @@ def test_last_resort_add_04(mock_start, mock_add, mock_exists, mock_run, mock_li
result = opencas.wait_for_startup(timeout=2, interval=0.1) result = opencas.wait_for_startup(timeout=2, interval=0.1)
mock_start.assert_any_call(config.caches[1], True) mock_start.assert_any_call(config.caches[1], load=True)
mock_start.assert_any_call(config.caches[2], True) mock_start.assert_any_call(config.caches[2], load=True)
mock_add.assert_any_call(config.cores[0], True) mock_add.assert_any_call(config.cores[0], try_add=True)
mock_add.assert_any_call(config.cores[1], True) mock_add.assert_any_call(config.cores[1], try_add=True)
mock_run.assert_called_with(["udevadm", "settle"]) mock_run.assert_called_with(["udevadm", "settle"])
@ -896,7 +901,7 @@ def test_last_resort_add_04(mock_start, mock_add, mock_exists, mock_run, mock_li
@patch("os.path.exists") @patch("os.path.exists")
@patch("opencas.add_core") @patch("opencas.add_core")
@patch("opencas.start_cache") @patch("opencas.start_cache")
def test_last_resort_add_04(mock_start, mock_add, mock_exists, mock_run, mock_list, mock_config): def test_last_resort_add_05(mock_start, mock_add, mock_exists, mock_run, mock_list, mock_config):
""" """
Check if adding cores/starting caches is attempted while waiting for startup for lazy_startup Check if adding cores/starting caches is attempted while waiting for startup for lazy_startup
devices once before returning. devices once before returning.
@ -919,11 +924,11 @@ def test_last_resort_add_04(mock_start, mock_add, mock_exists, mock_run, mock_li
result = opencas.wait_for_startup(timeout=0.5, interval=0.1) result = opencas.wait_for_startup(timeout=0.5, interval=0.1)
mock_start.assert_any_call(config.caches[1], True) mock_start.assert_any_call(config.caches[1], load=True)
mock_start.assert_any_call(config.caches[2], True) mock_start.assert_any_call(config.caches[2], load=True)
assert mock_start.call_count == 2, "start cache was called more than once per device" assert mock_start.call_count == 2, "start cache was called more than once per device"
mock_add.assert_any_call(config.cores[0], True) mock_add.assert_any_call(config.cores[0], try_add=True)
mock_add.assert_any_call(config.cores[1], True) mock_add.assert_any_call(config.cores[1], try_add=True)
assert mock_add.call_count == 2, "add core was called more than once per device" assert mock_add.call_count == 2, "add core was called more than once per device"
mock_run.assert_called_with(["udevadm", "settle"]) mock_run.assert_called_with(["udevadm", "settle"])
@ -934,7 +939,7 @@ def test_last_resort_add_04(mock_start, mock_add, mock_exists, mock_run, mock_li
@patch("os.path.exists") @patch("os.path.exists")
@patch("opencas.add_core") @patch("opencas.add_core")
@patch("opencas.start_cache") @patch("opencas.start_cache")
def test_last_resort_add_05(mock_start, mock_add, mock_exists, mock_run, mock_list, mock_config): def test_last_resort_add_06(mock_start, mock_add, mock_exists, mock_run, mock_list, mock_config):
""" """
Check if adding cores/starting caches is not attempted while waiting for startup for lazy Check if adding cores/starting caches is not attempted while waiting for startup for lazy
startup devices if paths show up after half of the startup timeout expires. startup devices if paths show up after half of the startup timeout expires.
@ -960,3 +965,53 @@ def test_last_resort_add_05(mock_start, mock_add, mock_exists, mock_run, mock_li
mock_start.assert_not_called() mock_start.assert_not_called()
mock_add.assert_not_called() mock_add.assert_not_called()
mock_run.assert_called_with(["udevadm", "settle"]) mock_run.assert_called_with(["udevadm", "settle"])
def assert_option_value(call, option, value):
try:
index = call.index(option)
except ValueError as e:
raise AssertionError(f"{option} not found in call ({call})") from e
assert call[index + 1] == value
@pytest.mark.parametrize("failover", ["standby", "active"])
@pytest.mark.parametrize("force", [True, False])
@pytest.mark.parametrize("load", [True, False])
@patch("subprocess.run")
def test_start_cache(mock_run, load, force, failover):
cache_config = opencas.cas_config.cache_config(
1,
"/dev/lizards",
"wt",
lazy_startup="true",
cache_line_size="64",
target_failover_state=failover,
)
mock_run.return_value = Mock(
returncode=0,
stderr="",
stdout="",
)
opencas.start_cache(cache_config, load, force)
casadm_call = mock_run.call_args[0][0]
assert "/sbin/casadm" in casadm_call
assert_option_value(casadm_call, "--cache-device", "/dev/lizards")
if not load:
assert_option_value(casadm_call, "--cache-id", "1")
assert_option_value(casadm_call, "--cache-line-size", "64")
if failover == "active":
assert "--start-cache" in casadm_call
assert_option_value(casadm_call, "--cache-mode", "wt")
else:
assert "--standby" in casadm_call
assert "--init" in casadm_call
else:
assert "--load" in casadm_call
assert "--cache-id" not in casadm_call
assert "--cache-mode" not in casadm_call
assert "--cache-line-size" not in casadm_call

View File

@ -44,7 +44,7 @@ def start():
for cache in config.caches.values(): for cache in config.caches.values():
try: try:
opencas.start_cache(cache, True) opencas.start_cache(cache, load=True)
except opencas.casadm.CasadmError as e: except opencas.casadm.CasadmError as e:
eprint( eprint(
"Unable to load cache {0} ({1}). Reason:\n{2}".format( "Unable to load cache {0} ({1}). Reason:\n{2}".format(
@ -116,7 +116,7 @@ def init(force):
for cache in config.caches.values(): for cache in config.caches.values():
try: try:
opencas.start_cache(cache, False, force) opencas.start_cache(cache, load=False, force=force)
except opencas.casadm.CasadmError as e: except opencas.casadm.CasadmError as e:
eprint( eprint(
"Unable to start cache {0} ({1}). Reason:\n{2}".format( "Unable to start cache {0} ({1}). Reason:\n{2}".format(

View File

@ -24,7 +24,7 @@ Cache device <DEVICE>
.br .br
Cache mode {wt|wb|wa|pt|wo} Cache mode {wt|wb|wa|pt|wo}
.br .br
Extra fields (optional) ioclass_file=<file>,cleaning_policy=<alru,nop>,promotion_policy=<always,nhit> Extra fields (optional) ioclass_file=<file>,cleaning_policy=<alru,nop>,promotion_policy=<always,nhit>,target_failover_state=<active,standby>
.RE .RE
.TP .TP
\fB[cores]\fR Cores configuration. Following columns are required: \fB[cores]\fR Cores configuration. Following columns are required:

View File

@ -60,8 +60,9 @@ class casadm:
return cls.run_cmd(cmd) return cls.run_cmd(cmd)
@classmethod @classmethod
def start_cache(cls, device, cache_id=None, cache_mode=None, def start_cache(
cache_line_size=None, load=False, force=False): cls, device, cache_id=None, cache_mode=None, cache_line_size=None, load=False, force=False
):
cmd = [cls.casadm_path, cmd = [cls.casadm_path,
'--start-cache', '--start-cache',
'--cache-device', device] '--cache-device', device]
@ -77,6 +78,22 @@ class casadm:
cmd += ['--force'] cmd += ['--force']
return cls.run_cmd(cmd) return cls.run_cmd(cmd)
@classmethod
def start_standby_cache(
cls, device, cache_id=None, cache_line_size=None, load=False, force=False
):
cmd = [cls.casadm_path,
'--standby',
'--init' if not load else '--load',
'--cache-device', device]
if cache_id:
cmd += ['--cache-id', str(cache_id)]
if cache_line_size:
cmd += ['--cache-line-size', str(cache_line_size)]
if force:
cmd += ['--force']
return cls.run_cmd(cmd)
@classmethod @classmethod
def add_core(cls, device, cache_id, core_id=None, try_add=False): def add_core(cls, device, cache_id, core_id=None, try_add=False):
cmd = [cls.casadm_path, cmd = [cls.casadm_path,
@ -197,7 +214,7 @@ class cas_config(object):
def __init__(self, cache_id, device, cache_mode, **params): def __init__(self, cache_id, device, cache_mode, **params):
self.cache_id = int(cache_id) self.cache_id = int(cache_id)
self.device = device self.device = device
self.cache_mode = cache_mode self.cache_mode = cache_mode.lower()
self.params = params self.params = params
self.cores = dict() self.cores = dict()
@ -215,7 +232,7 @@ class cas_config(object):
params = dict() params = dict()
if len(values) > 3: if len(values) > 3:
for param in values[3].split(','): for param in values[3].lower().split(','):
param_name, param_value = param.split('=') param_name, param_value = param.split('=')
if param_name in params: if param_name in params:
raise ValueError('Invalid cache configuration (repeated parameter') raise ValueError('Invalid cache configuration (repeated parameter')
@ -250,6 +267,8 @@ class cas_config(object):
self.check_cache_line_size_valid(param_value) self.check_cache_line_size_valid(param_value)
elif param_name == "lazy_startup": elif param_name == "lazy_startup":
self.check_lazy_startup_valid(param_value) self.check_lazy_startup_valid(param_value)
elif param_name == "target_failover_state":
self.check_failover_state_valid(param_value)
else: else:
raise ValueError(f'{param_name} is invalid parameter name') raise ValueError(f'{param_name} is invalid parameter name')
@ -273,19 +292,23 @@ class cas_config(object):
) )
def check_cache_mode_valid(self, cache_mode): def check_cache_mode_valid(self, cache_mode):
if cache_mode.lower() not in ['wt', 'pt', 'wa', 'wb', 'wo']: if cache_mode not in ['wt', 'pt', 'wa', 'wb', 'wo']:
raise ValueError(f'Invalid cache mode {cache_mode}') raise ValueError(f'Invalid cache mode {cache_mode}')
def check_cleaning_policy_valid(self, cleaning_policy): def check_cleaning_policy_valid(self, cleaning_policy):
if cleaning_policy.lower() not in ['acp', 'alru', 'nop']: if cleaning_policy not in ['acp', 'alru', 'nop']:
raise ValueError(f'{cleaning_policy} is invalid cleaning policy name') raise ValueError(f'{cleaning_policy} is invalid cleaning policy name')
def check_lazy_startup_valid(self, lazy_startup): def check_lazy_startup_valid(self, lazy_startup):
if lazy_startup.lower() not in ["true", "false"]: if lazy_startup not in ["true", "false"]:
raise ValueError('{0} is invalid lazy_startup value'.format(lazy_startup)) raise ValueError('{0} is invalid lazy_startup value'.format(lazy_startup))
def check_failover_state_valid(self, failover_state):
if failover_state not in ["active", "standby"]:
raise ValueError(f"{failover_state} is invalid target_failover_state value")
def check_promotion_policy_valid(self, promotion_policy): def check_promotion_policy_valid(self, promotion_policy):
if promotion_policy.lower() not in ['always', 'nhit']: if promotion_policy not in ['always', 'nhit']:
raise ValueError(f'{promotion_policy} is invalid promotion policy name') raise ValueError(f'{promotion_policy} is invalid promotion policy name')
def check_cache_line_size_valid(self, cache_line_size): def check_cache_line_size_valid(self, cache_line_size):
@ -319,7 +342,7 @@ class cas_config(object):
return ret return ret
def is_lazy(self): def is_lazy(self):
return self.params.get("lazy_startup", "false").lower() == "true" return self.params.get("lazy_startup", "false") == "true"
class core_config(object): class core_config(object):
def __init__(self, cache_id, core_id, path, **params): def __init__(self, cache_id, core_id, path, **params):
@ -369,7 +392,7 @@ class cas_config(object):
def validate_parameter(self, param_name, param_value): def validate_parameter(self, param_name, param_value):
if param_name == "lazy_startup": if param_name == "lazy_startup":
if param_value.lower() not in ["true", "false"]: if param_value not in ["true", "false"]:
raise ValueError( raise ValueError(
f"{param_value} is invalid value for '{param_name}' core param" f"{param_value} is invalid value for '{param_name}' core param"
) )
@ -401,7 +424,7 @@ class cas_config(object):
return ret return ret
def is_lazy(self): def is_lazy(self):
return self.params.get("lazy_startup", "false").lower() == "true" return self.params.get("lazy_startup", "false") == "true"
def __init__(self, caches=None, cores=None, version_tag=None): def __init__(self, caches=None, cores=None, version_tag=None):
self.caches = caches if caches else dict() self.caches = caches if caches else dict()
@ -545,13 +568,24 @@ class cas_config(object):
def start_cache(cache, load, force=False): def start_cache(cache, load, force=False):
casadm.start_cache( target_state = cache.params.get("target_failover_state")
if target_state is not None and target_state == "standby":
casadm.start_standby_cache(
device=cache.device, device=cache.device,
cache_id=cache.cache_id, cache_id=cache.cache_id if not load else None,
cache_mode=cache.cache_mode, cache_line_size=cache.params.get("cache_line_size") if not load else None,
cache_line_size=cache.params.get('cache_line_size'),
load=load, load=load,
force=force) force=force
)
else:
casadm.start_cache(
device=cache.device,
cache_id=cache.cache_id if not load else None,
cache_mode=cache.cache_mode if not load else None,
cache_line_size=cache.params.get('cache_line_size') if not load else None,
load=load,
force=force
)
def configure_cache(cache): def configure_cache(cache):
@ -820,9 +854,9 @@ def wait_for_startup(timeout=300, interval=5):
def start_device(dev): def start_device(dev):
if os.path.exists(dev.device): if os.path.exists(dev.device):
if type(dev) is cas_config.core_config: if type(dev) is cas_config.core_config:
add_core(dev, True) add_core(dev, try_add=True)
elif type(dev) is cas_config.cache_config: elif type(dev) is cas_config.cache_config:
start_cache(dev, True) start_cache(dev, load=True)
stop_time = time.time() + int(timeout) stop_time = time.time() + int(timeout)