読者です 読者をやめる 読者になる 読者になる

臥薪嘗胆

インフラエンジニアのあれこれ

Cやってみよう #3

C

先日の続き

偉大な先輩が言ってた
「時間があったら人のソースを読んで勉強しろ」
ということで、最近話題のソースを読んで勉強します。

お題はこちら:mod_vhost_maxclients
一つのapache複数のバーチャルホストを運用している場合は有用なのではないでしょうか!

C言語、勉強中ですので間違ってるかも知れません。
その時はすみません。
ツッコミお願いします!

情報はググッて仕入れてみます。
まず git cloneしてみよう

git clone https://github.com/matsumoto-r/mod_vhost_maxclients.git

このような内容でした

-rw-r--r--   1 kyswtnb  staff    148 10 13 21:39 .clang-format
drwxr-xr-x  12 kyswtnb  staff    408 10 13 21:39 .git
-rw-r--r--   1 kyswtnb  staff    112 10 13 21:39 .gitignore
-rw-r--r--   1 kyswtnb  staff   6529 10 13 21:39 .travis.yml
-rw-r--r--   1 kyswtnb  staff    175 10 13 21:39 LEGAL
-rw-r--r--   1 kyswtnb  staff   1073 10 13 21:39 MITL
-rw-r--r--   1 kyswtnb  staff   1293 10 13 21:39 Makefile
-rw-r--r--   1 kyswtnb  staff   2224 10 13 21:39 README.md
-rw-r--r--   1 kyswtnb  staff  12179 10 13 21:39 mod_vhost_maxclients.c
drwxr-xr-x  13 kyswtnb  staff    442 10 13 21:39 test

cで書かれているソースは mod_vhost_maxclients.c これですね。
では読んでみましょう。

まず、apache関連のヘッダーファイルを取り込んでます。たぶん。

28 #include "httpd.h"
29 #include "http_config.h"
30 #include "http_request.h"
31 #include "http_protocol.h"
32 #include "http_core.h"
33 #include "http_log.h"
34
35 #include "ap_mpm.h"
36 #include "apr_strings.h"
37 #include "scoreboard.h"

これはわかるぞ!
モジュール名とバージョンですね。

39 #define MODULE_NAME "mod_vhost_maxclients"
40 #define MODULE_VERSION "0.3.2"

これは分からない。。

42 #if (AP_SERVER_MINORVERSION_NUMBER > 2)
43 #define __APACHE24__
44 #endif
  • httpd-2.4.16.tar.gzを落としてきて、grepしたら↓が書いてあった
#define AP_SERVER_MINORVERSION_NUMBER 4
  • #includeしたヘッダーファイルの値を判定してるんですね。
  • 調べてみればわかるもんだ。

↑で定義した__APACHE24__があったらさらに変数を定義

46 #ifdef __APACHE24__
47 #define ap_get_scoreboard_worker ap_get_scoreboard_worker_from_indexes
48 #endif

そんな感じで、定義するところが続きます

50 #define _log_debug                                                                                                     \
51   ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "DEBUG: " MODULE_NAME "/" MODULE_VERSION "%s:%d", __func__, __LINE__)
52
53 #ifdef __APACHE24__
54 #include "http_main.h"
55 #else
56 #define ap_server_conf NULL
57 #endif
58
59 #define VHOST_MAXEXTENSIONS 16
60
61 #if !defined(__APACHE24__) && defined(_WIN32)
62 /*
63  * libhttpd.dll does not export following variables.
64  * This won't work correctly, but working well for other functional.
65  */
66 int ap_extended_status = 0;
67 #endif

windows,unix互換のマクロ AP_MODULE_DECLARE_DATA を記述。たぶん。

 69 module AP_MODULE_DECLARE_DATA vhost_maxclients_module;

スタティックな変数を宣言。同時に2つ宣言できるんですね。

 70 static int vhost_maxclients_server_limit, vhost_maxclients_thread_limit;

構造体(変数の塊)を vhost_maxclients_config という名前で定義している

72 typedef struct {
73
74   /* vhost max clinetns */
75   int dryrun;
76   signed int vhost_maxclients;
77   signed int vhost_maxclients_per_ip;
78   apr_array_header_t *ignore_extensions;
79
80 } vhost_maxclients_config;

これがポインタ?
* apr_pool_t bufferの保存場所?
* server_rec apacheが持ってる構造体
* apr_pcalloc メモリ領域を確保 * apr_array_make 配列を作成

ここでは、設定を読み込み領域を定義しているのかな〜と憶測

82 static void *vhost_maxclients_create_server_config(apr_pool_t *p, server_rec *s)
83 {
84   vhost_maxclients_config *scfg = (vhost_maxclients_config *)apr_pcalloc(p, sizeof(*scfg));
85
86   scfg->dryrun = -1;
87   scfg->vhost_maxclients = 0;
88   scfg->vhost_maxclients_per_ip = 0;
89   scfg->ignore_extensions = apr_array_make(p, VHOST_MAXEXTENSIONS, sizeof(char *));
90
91   return scfg;
92 }

ここも↑と同じで設定を読み込む構造体を定義しているように見える

94 static void* vhost_maxclients_create_server_merge_conf(apr_pool_t* p, void* b, void* n)
95 {
96   vhost_maxclients_config *base = (vhost_maxclients_config *)b;
97   vhost_maxclients_config *new = (vhost_maxclients_config *)n;
98   vhost_maxclients_config *scfg = (vhost_maxclients_config *)apr_pcalloc(p, sizeof(*scfg));
99
100   if (new->dryrun > -1) {
101       scfg->dryrun = new->dryrun;
102   } else {
103       scfg->dryrun = base->dryrun;
104   }
105   scfg->vhost_maxclients = new->vhost_maxclients;
106   scfg->vhost_maxclients_per_ip = new->vhost_maxclients_per_ip;
107   scfg->ignore_extensions = new->ignore_extensions;
108
109   return scfg;
110 }

ちょっとここからは難しくなってきたので、仕切りなおしてまた次の日に・・・。
慣れだけなのだろうけど、ぱっとみて何やってるのか把握するのが難しい。
続けよう。