diff options
author | Zdenek Kabelac <zkabelac@redhat.com> | 2017-03-31 17:07:21 +0200 |
---|---|---|
committer | Zdenek Kabelac <zkabelac@redhat.com> | 2017-03-31 17:12:00 +0200 |
commit | 970df59f914733b9ade15d9cb48e758b08140d42 (patch) | |
tree | e1cbadc519510de5d027e79587189bc068f27c45 /lib/cache_segtype | |
parent | 13ca11cc1472fe5689e63555780acfb40cb3bcd9 (diff) | |
download | lvm2-970df59f914733b9ade15d9cb48e758b08140d42.tar.gz |
cache: scan kallsyms for kernel symbols
With monolithic kernels we can't actually modprobe
for cache modules as they are already compiled-in
and policy modules do not export version symbol.
Reported issue on list:
https://www.redhat.com/archives/dm-devel/2017-March/msg00061.html
Fix will try to look for explicit kernel symbols first before
calling modprobe.
Diffstat (limited to 'lib/cache_segtype')
-rw-r--r-- | lib/cache_segtype/cache.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/lib/cache_segtype/cache.c b/lib/cache_segtype/cache.c index 55b4c6e7e..da23dae3c 100644 --- a/lib/cache_segtype/cache.c +++ b/lib/cache_segtype/cache.c @@ -258,6 +258,39 @@ static void _destroy(struct segment_type *segtype) } #ifdef DEVMAPPER_SUPPORT +/* + * Parse and look for kernel symbol in /proc/kallsyms + * this could be our only change to figure out there is + * cache policy symbol already in the monolithic kernel + * where 'modprobe dm-cache-smq' will simply not work + */ +static int _lookup_kallsyms(const char *symbol) +{ + static const char _syms[] = "/proc/kallsyms"; + int ret = 0; + char *line = NULL; + size_t len; + FILE *s; + + if (!(s = fopen(_syms, "r"))) + log_sys_debug("fopen", _syms); + else { + while (getline(&line, &len, s) != -1) + if (strstr(line, symbol)) { + ret = 1; /* Found symbol */ + log_debug("Found kernel symbol%s.", symbol); /* space is in symbol */ + break; + } + + free(line); + if (fclose(s)) + log_sys_debug("fclose", _syms); + } + + return ret; +} + + static int _target_present(struct cmd_context *cmd, const struct lv_segment *seg __attribute__((unused)), unsigned *attributes __attribute__((unused))) @@ -270,14 +303,15 @@ static int _target_present(struct cmd_context *cmd, unsigned cache_alias; const char feature[12]; const char module[12]; /* check dm-%s */ + const char ksymbol[12]; /* check for kernel symbol */ const char *aliasing; } _features[] = { - /* Assumption: cache >=1.9 always aliases MQ policy */ { 1, 10, CACHE_FEATURE_METADATA2, 0, "metadata2" }, + /* Assumption: cache >=1.9 always aliases MQ policy */ { 1, 9, CACHE_FEATURE_POLICY_SMQ, CACHE_FEATURE_POLICY_MQ, "policy_smq", "cache-smq", - " and aliases cache-mq" }, - { 1, 8, CACHE_FEATURE_POLICY_SMQ, 0, "policy_smq", "cache-smq" }, - { 1, 3, CACHE_FEATURE_POLICY_MQ, 0, "policy_mq", "cache-mq" }, + " smq_exit", " and aliases cache-mq" }, + { 1, 8, CACHE_FEATURE_POLICY_SMQ, 0, "policy_smq", "cache-smq", " smq_exit" }, + { 1, 3, CACHE_FEATURE_POLICY_MQ, 0, "policy_mq", "cache-mq", " mq_init" }, }; static const char _lvmconf[] = "global/cache_disabled_features"; static unsigned _attrs = 0; @@ -323,7 +357,8 @@ static int _target_present(struct cmd_context *cmd, } if (((maj > _features[i].maj) || (maj == _features[i].maj && min >= _features[i].min)) && - module_present(cmd, _features[i].module)) { + ((_features[i].ksymbol[0] && _lookup_kallsyms(_features[i].ksymbol)) || + module_present(cmd, _features[i].module))) { log_debug_activation("Cache policy %s is available%s.", _features[i].module, _features[i].aliasing ? : ""); |