Apacheのモジュールロードのタイミング
モジュールをロードするコードはこのあたりだろうか。https://github.com/apache/httpd/blob/2.4.10/modules/core/mod_so.c
https://github.com/apache/httpd/blob/2.4.10/modules/core/mod_so.c
Apache からは APR の apr_dso_load() を使っているみたいなので、APRの方を覗いてみる。
https://github.com/apache/apr/blob/1.5.1/dso/unix/dso.c
複数のOSをサポートするために #ifdef が多用されててちょっと見にくいが、Linux環境であれば dlopen() が使用されるようだ。
さて、dlopen() が使用されるということが分かったので、呼び出し元に戻る。
最初に提示したコードは load_module() の中に記述されている。
これはどこからコールされているのかというと、同じ mod_so.c の中にある。
AP_INIT_TAKE2は引数を二つもつディレクティブで、
RSRC_CONFは
最後の EXEC_ON_READ は名前からも推測できますが、設定が読み込まれたときに実行されます。
実行するのは二つ目の引数である load_module() です。
設定が読み込まれたときに実行されると言うことは、graceful でも大丈夫な気がします。
モジュールをアップデートしてみる
graceful でも大丈夫そうということが分かったので、実際に試してみます。mod_hello という簡単なモジュールを作ってみます。
上記のGistの mod_hello は Hello という設定がコンフィグに出てくると、第一引数の文字列をエラーログに出力するだけのものです。
インストールは apxs で行います。
$ apxs -c mod_hello.c
$ sudo apxs -i -a -n hello mod_hello.la
httpd.conf に設定を追加します。
+LoadModule hello_module modules/mod_hello.so
+Hello world
Apache を起動します。
$ sudo apache2ctl start
* Starting apache2 ...
[Sun Dec 07 16:11:41.528152 2014] [:notice] [pid 24998] Hello world
エラーログに "Hello world" と表示されました。続いて、モジュールを書き換えてみます。
mod_hello.c の21行目を "Hello %s" から "Hell %s" にしてみます。
再度、モジュールをコンパイル・インストールし、graceful してみます。
$ apxs -c mod_hello.c
$ sudo apxs -i -a -n hello mod_hello.la
$ sudo apache2ctl graceful
* Gracefully restarting apache2 ...
[Sun Dec 07 16:30:57.456100 2014] [:notice] [pid 25436] Hell world
変わりました。結論
- モジュールをアップデートするときは graceful で十分
参考文献
追記(2015/02/01)
Apacheモジュール更新はgracefulで十分の件、どうだろう。mod_proxy周りは設定変更時にgracefulだとなんか死ぬし、弊害が出てくる場合がある気がする
— Gentoo遊民matsuu (@matsuu) 2015, 2月 1
mod_proxy では設定が反映されなかったりすることもあるそうで、graceful だと不十分な場合もあるようです。共有メモリを使うようなモジュールだと古い設定がそのまま使われるとかありそうなので、モジュールの中身次第では注意が必要そうです。