zabbixのローダブルモジュールで、ロード元のプログラムを調べる

#2015年10月18日追記
2015年10月15日に公開されたzabbix3.0.0alpha3から、プログラムの種類の定義がZBX_DAEMON_TYPE_XXXからZBX_PROGRAM_TYPE_XXXに、プログラムの種類のグローバル変数がdaemon_typeからprogram_typeに変更されました。
zabbix3.0.0alpha3以降ではその部分を適宜変更する必要があります。

#はじめに
zabbix2.2で追加になった新機能「ローダブルモジュール」ですが、server/agent/proxyのどのプログラムからロードされたのかをモジュール側から調べることが出来そうだったのでやってみました。

#やってみた
zabbix2.2.xのソースに含まれるサンプル"dummy.c"との差分が下記の通りです。
試しに、エージェント以外のプロセスにロードされた時にはモジュールの初期化に失敗するようにしてみました。
zabbix-agentでのみ利用できるモジュール、という訳です。

```c
# diff -c dummy/dummy.c dummy-agent/dummy-agent.c
*** dummy/dummy.c       2014-04-07 18:12:32.000000000 +0900
--- dummy-agent/dummy-agent.c   2014-04-28 19:07:29.877924653 +0900
***************
*** 19,24 ****
--- 19,28 ----

  #include "sysinc.h"
  #include "module.h"
+ #include "log.h"
+ #include "common.h"
+
+ extern unsigned char daemon_type ;

  /* the variable keeps timeout setting for item processing */
  static int    item_timeout = 0;
***************
*** 173,182 ****
   ******************************************************************************/
  int   zbx_module_init()
  {
        /* initialization for dummy.random */
        srand(time(NULL));

!       return ZBX_MODULE_OK;
  }

  /******************************************************************************
--- 177,206 ----
   ******************************************************************************/
  int   zbx_module_init()
  {
+       int ret = ZBX_MODULE_FAIL;
+
        /* initialization for dummy.random */
        srand(time(NULL));

!       /* determine daemon process */
!       switch (daemon_type){
!               case ZBX_DAEMON_TYPE_SERVER:
!                       zabbix_log(LOG_LEVEL_WARNING, "module loaded by server process. [%d]", daemon_type);
!                       break;
!               case ZBX_DAEMON_TYPE_PROXY_ACTIVE:
!               case ZBX_DAEMON_TYPE_PROXY_PASSIVE:
!               case ZBX_DAEMON_TYPE_PROXY:
!                       zabbix_log(LOG_LEVEL_WARNING, "module loaded by proxy process. [%d]", daemon_type);
!                       break;
!               case ZBX_DAEMON_TYPE_AGENT:
!                       zabbix_log(LOG_LEVEL_WARNING, "module loaded by agent process. [%d]", daemon_type);
!                       ret = ZBX_MODULE_OK;
!                       break;
!               default:
!                       zabbix_log(LOG_LEVEL_WARNING, "unknown daemon_type [%d]", daemon_type );
!       }
!
!       return ret;
  }

  /******************************************************************************
```


##やったこと

* log.hとcommon.hをインクルード 
log.hはログ出力のため、common.hはZBX_DAEMON_TYPE_HOGEという定数の定義を取り込むため。

* サーバやエージェントなどのプロセス本体で定義されたグローバル変数"daemon_type"をextern
この変数からロード元のプログラムを調べます。

* プログラム起動時に呼び出される初期化関数"zbx_module_init()"の中に分岐とログ出力を追加 
ログ出力がわかりやすくなるように、ログレベルをわざとWARNにしています。
"daemon_type"がZBX_DAEMON_TYPE_AGENT以外の場合にはモジュールの初期化に失敗(ZBX_MODULE_FAIL)を返します。

#実際にロードしてみる

コンパイルの仕方とかモジュールをロードする設定は省きます。

##zabbix-agentからロード

```shell-session
# tail /var/log/zabbix/zabbix_agentd.log
 19243:20140428:191154.189 Zabbix Agent stopped. Zabbix 2.2.3 (revision 44105).
 19585:20140428:191154.336 Starting Zabbix Agent [fishbone]. Zabbix 2.2.3 (revision 44105).
 19585:20140428:191154.336 using configuration file: /etc/zabbix/zabbix_agentd.conf
 19585:20140428:191154.336 module loaded by agent process. [8]
 19585:20140428:191154.336 loaded modules: dummy-agent.so
 19587:20140428:191154.338 agent #0 started [collector]
 19588:20140428:191154.338 agent #1 started [listener #1]
 19589:20140428:191154.338 agent #2 started [listener #2]
 19590:20140428:191154.338 agent #3 started [listener #3]
 19591:20140428:191154.339 agent #4 started [active checks #1]
```

それっぽく動いています。

##zabbix-serverからロード

```shell-session
# tail /var/log/zabbix/zabbix_server.log
 19744:20140428:191300.368 Jabber notifications:      YES
 19744:20140428:191300.368 Ez Texting notifications:  YES
 19744:20140428:191300.368 ODBC:                      YES
 19744:20140428:191300.369 SSH2 support:              YES
 19744:20140428:191300.369 IPv6 support:              YES
 19744:20140428:191300.369 ******************************
 19744:20140428:191300.369 using configuration file: /etc/zabbix/zabbix_server.conf
 19744:20140428:191300.369 module loaded by server process. [1]
 19744:20140428:191300.369 cannot initialize module "dummy-agent.so"
 19744:20140428:191300.369 loading modules failed, exiting...
```

目論見通りにモジュールの初期化に失敗、サーバは起動しません。

##zabbix-proxyからロード
手元にzabbix-proxyが動作している環境がないため試していません。


#最後に

* 上記の内容はCentOS6.5にzabbixオフィシャルパッケージをインストールした環境でビルド・動作確認しています。
* 起動に失敗しても

```shell-session
# service zabbix-server restart
Shutting down Zabbix server:                               [  OK  ]
Starting Zabbix server:                                    [  OK  ]
```

とか表示するzabbix-serverって一体なんなんでしょう。