mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
cache: detect smq policy presence
Add code to detect available cache features. Support policy_mq & policy_smq features which might be disabled. Introduce global_cache_disabled_features_CFG.
This commit is contained in:
parent
694c88e031
commit
8a74d1ec79
@ -25,6 +25,11 @@
|
|||||||
#include "lv_alloc.h"
|
#include "lv_alloc.h"
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
|
|
||||||
|
static const char _cache_module[] = "cache";
|
||||||
|
|
||||||
|
/* TODO: using static field here, maybe should be a part of segment_type */
|
||||||
|
static unsigned _feature_mask;
|
||||||
|
|
||||||
#define SEG_LOG_ERROR(t, p...) \
|
#define SEG_LOG_ERROR(t, p...) \
|
||||||
log_error(t " segment %s of logical volume %s.", ## p, \
|
log_error(t " segment %s of logical volume %s.", ## p, \
|
||||||
dm_config_parent_name(sn), seg->lv->name), 0;
|
dm_config_parent_name(sn), seg->lv->name), 0;
|
||||||
@ -168,9 +173,26 @@ static int _target_present(struct cmd_context *cmd,
|
|||||||
const struct lv_segment *seg __attribute__((unused)),
|
const struct lv_segment *seg __attribute__((unused)),
|
||||||
unsigned *attributes __attribute__((unused)))
|
unsigned *attributes __attribute__((unused)))
|
||||||
{
|
{
|
||||||
uint32_t maj, min, patchlevel;
|
/* List of features with their kernel target version */
|
||||||
|
static const struct feature {
|
||||||
|
uint32_t maj;
|
||||||
|
uint32_t min;
|
||||||
|
unsigned cache_feature;
|
||||||
|
const char feature[12];
|
||||||
|
const char module[12]; /* check dm-%s */
|
||||||
|
} _features[] = {
|
||||||
|
{ 1, 3, CACHE_FEATURE_POLICY_MQ, "policy_mq", "cache-mq" },
|
||||||
|
{ 1, 8, CACHE_FEATURE_POLICY_SMQ, "policy_smq", "cache-smq" },
|
||||||
|
};
|
||||||
|
static const char _lvmconf[] = "global/cache_disabled_features";
|
||||||
|
static unsigned _attrs = 0;
|
||||||
static int _cache_checked = 0;
|
static int _cache_checked = 0;
|
||||||
static int _cache_present = 0;
|
static int _cache_present = 0;
|
||||||
|
uint32_t maj, min, patchlevel;
|
||||||
|
unsigned i;
|
||||||
|
const struct dm_config_node *cn;
|
||||||
|
const struct dm_config_value *cv;
|
||||||
|
const char *str;
|
||||||
|
|
||||||
if (!_cache_checked) {
|
if (!_cache_checked) {
|
||||||
_cache_present = target_present(cmd, "cache", 1);
|
_cache_present = target_present(cmd, "cache", 1);
|
||||||
@ -184,11 +206,53 @@ static int _target_present(struct cmd_context *cmd,
|
|||||||
|
|
||||||
if ((maj < 1) ||
|
if ((maj < 1) ||
|
||||||
((maj == 1) && (min < 3))) {
|
((maj == 1) && (min < 3))) {
|
||||||
log_error("The cache kernel module is version %u.%u.%u."
|
_cache_present = 0;
|
||||||
" Version 1.3.0+ is required.",
|
log_error("The cache kernel module is version %u.%u.%u. "
|
||||||
|
"Version 1.3.0+ is required.",
|
||||||
maj, min, patchlevel);
|
maj, min, patchlevel);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i) {
|
||||||
|
if (((maj > _features[i].maj) ||
|
||||||
|
(maj == _features[i].maj && min >= _features[i].min)) &&
|
||||||
|
(!_features[i].module[0] || module_present(cmd, _features[i].module)))
|
||||||
|
_attrs |= _features[i].cache_feature;
|
||||||
|
else
|
||||||
|
log_very_verbose("Target %s does not support %s.",
|
||||||
|
_cache_module, _features[i].feature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributes) {
|
||||||
|
if (!_feature_mask) {
|
||||||
|
/* Support runtime lvm.conf changes, N.B. avoid 32 feature */
|
||||||
|
if ((cn = find_config_tree_array(cmd, global_cache_disabled_features_CFG, NULL))) {
|
||||||
|
for (cv = cn->v; cv; cv = cv->next) {
|
||||||
|
if (cv->type != DM_CFG_STRING) {
|
||||||
|
log_error("Ignoring invalid string in config file %s.",
|
||||||
|
_lvmconf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
str = cv->v.str;
|
||||||
|
if (!*str)
|
||||||
|
continue;
|
||||||
|
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i)
|
||||||
|
if (strcasecmp(str, _features[i].feature) == 0)
|
||||||
|
_feature_mask |= _features[i].cache_feature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_feature_mask = ~_feature_mask;
|
||||||
|
|
||||||
|
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i)
|
||||||
|
if ((_attrs & _features[i].cache_feature) &&
|
||||||
|
!(_feature_mask & _features[i].cache_feature))
|
||||||
|
log_very_verbose("Target %s %s support disabled by %s",
|
||||||
|
_cache_module, _features[i].feature, _lvmconf);
|
||||||
|
}
|
||||||
|
*attributes = _attrs & _feature_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _cache_present;
|
return _cache_present;
|
||||||
@ -376,5 +440,8 @@ int init_cache_segtypes(struct cmd_context *cmd,
|
|||||||
return_0;
|
return_0;
|
||||||
log_very_verbose("Initialised segtype: %s", segtype->name);
|
log_very_verbose("Initialised segtype: %s", segtype->name);
|
||||||
|
|
||||||
|
/* Reset mask for recalc */
|
||||||
|
_feature_mask = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -909,6 +909,14 @@ cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CF
|
|||||||
"Example:\n"
|
"Example:\n"
|
||||||
"thin_disabled_features = [ \"discards\", \"block_size\" ]\n")
|
"thin_disabled_features = [ \"discards\", \"block_size\" ]\n")
|
||||||
|
|
||||||
|
cfg_array(global_cache_disabled_features_CFG, "cache_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 126), NULL, 0, NULL,
|
||||||
|
"Features to not use in the cache driver.\n"
|
||||||
|
"This can be helpful for testing, or to avoid\n"
|
||||||
|
"using a feature that is causing problems.\n"
|
||||||
|
"Features: policy_mq, policy_smq.\n"
|
||||||
|
"Example:\n"
|
||||||
|
"cache_disabled_features = [ \"policy_smq\" ]\n")
|
||||||
|
|
||||||
cfg(global_cache_check_executable_CFG, "cache_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, CACHE_CHECK_CMD, vsn(2, 2, 108), "@CACHE_CHECK_CMD@", 0, NULL,
|
cfg(global_cache_check_executable_CFG, "cache_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, CACHE_CHECK_CMD, vsn(2, 2, 108), "@CACHE_CHECK_CMD@", 0, NULL,
|
||||||
"The full path to the cache_check command.\n"
|
"The full path to the cache_check command.\n"
|
||||||
"LVM uses this command to check that a cache metadata\n"
|
"LVM uses this command to check that a cache metadata\n"
|
||||||
|
@ -191,6 +191,9 @@ int init_thin_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
|||||||
int init_cache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
int init_cache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CACHE_FEATURE_POLICY_MQ (1U << 0)
|
||||||
|
#define CACHE_FEATURE_POLICY_SMQ (1U << 1)
|
||||||
|
|
||||||
#define SNAPSHOT_FEATURE_FIXED_LEAK (1U << 0) /* version 1.12 */
|
#define SNAPSHOT_FEATURE_FIXED_LEAK (1U << 0) /* version 1.12 */
|
||||||
|
|
||||||
#ifdef SNAPSHOT_INTERNAL
|
#ifdef SNAPSHOT_INTERNAL
|
||||||
|
Loading…
Reference in New Issue
Block a user