6

Linux Kernelを変更して、Linux Virtual Server(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 に答える