我正在修改 Linux 内核以向 Linux 虚拟服务器 (LVS) 添加一些功能。
我开发了一个模块(我称之为net/netfilter/ipvs/ip_vs_utils.c
)以及负载平衡时要使用的一些函数。这里的所有函数都是使用导出的EXPORT_SYMBOL()
.
从逻辑上讲,该模块不会一直加载。我的目的是让用户决定是否要使用此附加功能(加载或卸载模块)。
我的问题是我如何从现有的(当然是修改过的)模块中选择性地调用这些函数(取决于模块是否正在运行)(net/netfilter/ipvs/ip_vs_core.c
)。像这样的东西:
if(ip_vs_utils_IsLoaded)
{
function1(arg1, arg2, arg3); // being function1 defined on ip_vs_utils.c
}
我想你需要一个蹦床always(或几乎总是)加载到内核中。
在蹦床代码中,您需要这样的变量。
struct module *ip_vs_utils_mod;
EXPORT_SYMBOL(ip_vs_utils_mod);
/* function pointers */
ret_type (*ip_vs_utils_afunc_ptr)(func_arg_list); /* Add static if you put it in a header file! */
EXPORT_SYMBOL(ip_vs_utils_afunc_ptr); /* ******EXPORTED***** */
当ip_vs_utils加载时,需要初始化所有变量,初始化代码在ip_vs_utils.c中:
ip_vs_utils_mod = THIS_MODULE;
/* init function pointers */
/* ip_vs_utils_afunc_impl is the real implementation
* of the function, it is *****NOT***** needed to export it
*/
ip_vs_utils_afunc_ptr = ip_vs_utils_afunc_impl;
并在trampoline代码中添加trampoline函数:
ret_type ip_vs_utils_afunc(func_arg_list)
{
ret_type ret = DEFAULT_RET;
if (try_module_get(ip_vs_utils_mod)) {
ret = (*ip_vs_utils_afunc_ptr)(func_arg_list);
module_put(ip_vs_utils_mod);
}
return ret;
}
需要 try_module_get() 来保护模块在调用 ip_vs_utils_afunc_ptr() 时不被突然卸载。
您还可以使用 RCU 来减少 try_module_get()/module_put() 的开销。 (但是很难)
或者你可以在用户空间中使用一些类似于动态链接的trampoline-hack(你可能需要在linux内核中进行很多更改)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)