仅当已插入的Linux内核模块中存在导出的符号时,才如何有选择地使用导出的符号? [英] How to use exported symbols optionally only if they are present in an insmoded Linux Kernel module?

查看:114
本文介绍了仅当已插入的Linux内核模块中存在导出的符号时,才如何有选择地使用导出的符号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am modifying a Linux Kernel to add some functionality to the Linux Virtual Server (LVS).

我开发了一个模块(我称为net/netfilter/ipvs/ip_vs_utils.c),其中包含一些在负载平衡时要使用的功能.使用EXPORT_SYMBOL()导出此处的所有功能.

I developed a module (which I called net/netfilter/ipvs/ip_vs_utils.c) with some functions to be used when load-balancing. All the functions here are exported using EXPORT_SYMBOL().

从逻辑上讲,此模块并非一直都在加载.我的意图是允许用户决定是否要使用此附加功能(加载或卸载模块).

This module, logically is not loaded all the time. My intention is to allow the user to decide if he want to use this additional functionality or not (loading or unloading the module).

我的问题是我该如何从现有的(当然是经过修改的)模块(net/netfilter/ipvs/ip_vs_core.c)中可选地调用这些函数(取决于模块是否在运行).像这样:

My question is how could I invoke these functions OPTIONALLY (depending if the module is running or not) from a existing (and of course modified) module (net/netfilter/ipvs/ip_vs_core.c). Something like this:

if(ip_vs_utils_IsLoaded)
{
  function1(arg1, arg2, arg3); // being function1 defined on ip_vs_utils.c
}

推荐答案

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

I think you need a trampoline always(or almost always) loaded into kernel.

在蹦床代码中,您需要这样的变量.

In trampoline code, you need to such variables.

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中的初始化代码:

When the ip_vs_utils is loaded, you need to init all the variables, initialization code in 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;

并在蹦床代码中添加蹦床功能:

And add the trampoline functions in trampoline code:

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()的开销. (但这很难)

try_module_get() is needed to protect the module from being suddenly unloaded while ip_vs_utils_afunc_ptr() is being invoked. You can also use RCU instead to reduce the overhead of try_module_get()/module_put(). (But it is hard)

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

Or you can used some trampoline-hack like dynamic link in userspace(you may need to change a lot in the linux kernel)

这篇关于仅当已插入的Linux内核模块中存在导出的符号时,才如何有选择地使用导出的符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆