6

我正在修改 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
}
4

1 回答 1

5

我认为您需要始终(或几乎始终)将蹦床加载到内核中。

在蹦床代码中,你需要这样的变量。

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_module_get()/module_put() 的开销。(但很难)

或者您可以在用户空间中使用一些类似蹦床的动态链接(您可能需要在 linux 内核中进行很多更改)

于 2012-07-13T05:55:13.623 回答