1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

cache: check module in modules builtin

Instead of parsing the whole /proc/kallsyms use faster variant
of using modprobe tool logic.

lvm2 here wants to know whether the particular DM cache policy is
present in the kernel - however since the cache policy does not have
any kernel module parameters and it can be built-in to a kernel
there is no /sys/modules directory in such case and we would need to call
modprobe everytime we want detect such case.

The old solution tried to look for particular kernel symbol
(and like not the right way, as smq_exit might be actually ommitted).

New version checks MODULES_PATH/`uname -r`/modules.builtin for
whether is present cache policy module instead of CPU expensive parsing
of kallsyms.
This commit is contained in:
Zdenek Kabelac 2024-02-08 14:58:32 +01:00
parent 1453ccd5b8
commit d19235993e
3 changed files with 45 additions and 38 deletions

View File

@ -1,5 +1,6 @@
Version 2.03.24 -
==================
Check for cache policy module presence in kernel's builtin modules file.
Add configure --with-modulesdir to select kernel modules directory.
Support creation of thin-pool with VDO use for its data volume.

View File

@ -563,6 +563,43 @@ int lvm_dm_prefix_check(int major, int minor, const char *prefix)
return dev_manager_check_prefix_dm_major_minor(major, minor, prefix);
}
/* Search modules.builtin file for built-in kernel module */
static int _check_modules_builtin(struct cmd_context *cmd, const char *target)
{
FILE *fp;
char *line = NULL;
size_t len;
int r = 0;
char path[PATH_MAX];
if (dm_snprintf(path, sizeof(path), "%s/%s/modules.builtin",
MODULES_PATH, cmd->kernel_vsn) < 0) {
log_debug("Modules path %s/%s/modules.builtin is too long.",
MODULES_PATH, cmd->kernel_vsn);
return 0;
}
if (!(fp = fopen(path, "r"))) {
if (errno != ENOENT)
log_sys_debug("fopen", path);
return 0;
}
while (getline(&line, &len, fp) > 0)
if (strstr(line, target)) {
log_debug("Found %s as built-in kernel module.", target);
r = 1;
break;
}
free(line);
if (fclose(fp))
log_sys_debug("fclose", path);
return r;
}
int module_present(struct cmd_context *cmd, const char *target_name)
{
int ret = 0;
@ -584,6 +621,9 @@ int module_present(struct cmd_context *cmd, const char *target_name)
log_debug_activation("Module directory %s exists.", path);
return 1;
}
if (path[i] == '/' && _check_modules_builtin(cmd, path + i + 1))
return 1;
}
#ifdef MODPROBE_CMD

View File

@ -300,38 +300,6 @@ 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)),
@ -345,15 +313,14 @@ 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[] = {
{ 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",
" 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" },
" 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" },
};
static const char _lvmconf[] = "global/cache_disabled_features";
static unsigned _attrs = 0;
@ -399,8 +366,7 @@ static int _target_present(struct cmd_context *cmd,
}
if (((maj > _features[i].maj) ||
(maj == _features[i].maj && min >= _features[i].min)) &&
((_features[i].ksymbol[0] && _lookup_kallsyms(_features[i].ksymbol)) ||
module_present(cmd, _features[i].module))) {
module_present(cmd, _features[i].module)) {
log_debug_activation("Cache policy %s is available%s.",
_features[i].module,
_features[i].aliasing ? : "");