第8章 モジュール

Jelmer Vernooij

Samba Team

19 March 2003

目次

利点
モジュールのロード
静的モジュール
動的モジュール
モジュールを書く
configure.inにおける静的/動的の選択

利点

新しいモジュールシステムは以下の利点を有する:

透過的な、静的および動的モジュールのローディング(サブシステムがモジュールについて 知る必要がない)
構成時に、静的および動的モジュールを簡単に選べる
安定モジューのパフォーマンスを向上するための"preload modules"オプション
ややこしい#define stuff anymoreが不要
すべてのバックエンドがプラグインとして提供されている(pdb_ldapとpdp_tdbを含む)

モジュールのロード

Samba内のいくつかのサブシステムは、異なったバックエンドを使う。それらのバックエンドは、 Sambaに静的にリンクするか、プラグインとして提供されているかのどちらかである。 サブシステムは、モジュールそれ自身を登録する事を許可する関数をもっている。例えば、 passdbサブシステムでは以下の通り:

NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init);

この関数は、モジュールそれ自身を登録するために初期化関数によって呼ばれる。

静的モジュール

モジュールシステムは、各サブシステムの静的モジュールのための初期化関数の一覧に従う。 例えば、(include/config.hから)現在は以下のようになっている:

/* Static init functions */
#define static_init_pdb { pdb_mysql_init(); pdb_ldap_init(); pdb_smbpasswd_init(); pdb_tdbsam_init(); pdb_guest_init();}

これらの関数はサブシステムが使われる前に呼ばれるべきである。それは、 サブシステムが初期化されるか、最初に使われるときに終了すべきである。

動的モジュール

サブシステムが特定のバックエンドを必要とする場合、それがすでに登録されているかを 調べるべきである。もしもバックエンドがまだ登録されていなかった場合、サブシステムは、 smb_probe_module(char *subsystem, char *backend)を呼び出すべきである。 この関数は、指定されたパス($LIBDIR/subsystem/backend.so)から正しいモジュールを ロードしようとする。もしも'backend'の最初の文字がスラッシュの場合には、 smb_probe_module()は'backend'で指定された絶対パスからモジュールをロードしようとする。

smb_probe_module()の実行後、サブシステムは、モジュールがすでに登録されたか どうかをチェックすべきである。

モジュールを書く

各モジュールは初期化関数をもっている。Sambaに含まれるモジュールでは、 この名前は 'subsystem_backend_init' である。(決して組み込まれないが、モジュールとしてのみ提供される)外部モジュールでは、 この名前は常時init_module'である(モジュールがSambaに含まれる場合、 configureシステムは#define subsystem_backend_init() init_module()を追加する)。 これらの関数のプロトタイプは以下の通り:

NTSTATUS init_module(void);

この関数は1回またはそれ以上登録関数を呼び出すべきである。関数は 成功時にはNT_STATUS_OKか、NT_STATUS_UNSUCCESSFULか、失敗時に便利に使える nt error codeを返すべきである。

たとえばpdb_ldap_init()は以下を含む:

NTSTATUS pdb_ldap_init(void)
{
smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam);
smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_nua", pdb_init_ldapsam_nua);
	return NT_STATUS_OK;
}

configure.inにおける静的/動的の選択

configure.in中のいくつかのマクロは、システムが正しく動くために必要な、種々の define文とsubstを生成する。既定値によって構築されるべきすべてのモジュールは、 既定値で'default_modules'変数に追加されなければならない。例えば、もしもldap が見つかった場合、pdb_ldapはこの変数に追加される。

condigure.inの最下部に、各モジュールのためにSMB_MODULE()が、各サブシステム用に SMB_SUBSYSTEM()が呼ばれなければならない。

文法:

SMB_MODULE(subsystem_backend, object files, plugin name, subsystem name, static_action, shared_action)
SMB_SUBSYSTEM(subsystem,depfile)

特定のサブシステム用のdepfileは、モジュール中に静的に構築されるための 初期化モジュールを呼び出すファイルである。

Makefile.in中の@SUBSYSTEM_MODULES@ は構築されるプラグインの名前に置き換わる。

すべての.cファイルに対し、'modules_clean'というmakeのターゲット中に./configureが 再構築されることで変更できるdefineを含むようにしておくこと。実際に、これは、 static_init_subsystem;コールを含むすべてのcファイルは、 再構築する必要がある。

注記

現在、configure.in中に、SMB_MODULE_PROVIVES()と呼ばれるコマンドがある。 これは複数のものを登録するモジュールのために使われる。これは将来なくなる予定 なので、調査(probe)のために使うべきではない。