Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果导出的符号存在于内置Linux内核模块中,如何选择使用它们?_Linux_Linux Kernel_Kernel Module - Fatal编程技术网

如果导出的符号存在于内置Linux内核模块中,如何选择使用它们?

如果导出的符号存在于内置Linux内核模块中,如何选择使用它们?,linux,linux-kernel,kernel-module,Linux,Linux Kernel,Kernel Module,我正在修改Linux内核以向Linux虚拟服务器(LVS)添加一些功能 我开发了一个模块(我称之为net/netfilter/ipvs/ip_vs_utils.c),其中包含一些用于负载平衡的函数。这里的所有函数都是使用EXPORT\u SYMBOL()导出的 逻辑上,此模块并非始终加载。我的意图是允许用户决定是否要使用此附加功能(加载或卸载模块) 我的问题是如何从现有(当然是修改过的)模块(net/netfilter/ipvs/ip_vs_core.c)选择性地调用这些函数(取决于模块是否正在

我正在修改Linux内核以向Linux虚拟服务器(LVS)添加一些功能

我开发了一个模块(我称之为
net/netfilter/ipvs/ip_vs_utils.c
),其中包含一些用于负载平衡的函数。这里的所有函数都是使用
EXPORT\u 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
}

我想你需要一个蹦床总是(或者几乎总是)加载到内核中

在trampoline代码中,您需要修改这些变量

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;
并在蹦床代码中添加蹦床功能:

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\u module\u get()/module\u put()的开销。(但这很难)


或者你可以在用户空间中使用一些蹦床黑客,比如动态链接(你可能需要在linux内核中做很多更改)

非常感谢你的回答,我想这对我来说很有用。只是个问题。如果我的模块ip_vs_utils先于其他模块加载,会发生什么情况?行
ip_vs_utils_afunc_ptr=ip_vs_utils_afunc_抛出错误,因为ip_vs_utils_afunc_ptr还不在符号表中?在这种情况下,您可能需要将蹦床链接到内核(或系统启动时始终加载的模块)之前。trampoline通常比实际的实现小得多,让它总是被加载是可以的。如果你的
if(ip\u vs\u utils)
代码一直都在内核中,Lai的答案是非常好的;但是,如果代码本身位于另一个可加载模块中,那么简单的模块依赖性可能是更好的方法。有关详细信息,请参见
depmod(8)