地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

Nginxがユーザプロセスでulimitのハードを超えれるのはなぜか

突然思った。なんで?ulimitをユーザプロセス が変更する際はハードリミット以下で制限されるがworker_rlimit_nofileではこのハードリミットを超えることができる。

これはなんでって思ったので調べた。結論から言うとNginxは基本masterプロセスはrootで実行するがこのroot -> 一般ユーザでデーモン化するまでの間でulimtを設定するからだ。

nginxのworker_rlimit_nofileって?

nginx ではプロセス毎のファイルディスクリプタ上限数を指定する設定項目 worker_rlimit_nofile が用意されている。

この値はMaxClientsと誤解されがちだが違う値。1プロセスあたりのファイルディスクリプたの上限値を設定する。(C-Sでの通信だけならMaxClientsはあながち間違いではない)

ここでこのファイルディスクリプト(以下FD)はユーザプロセス として実行するならulimitによるlimitがかかるはずだかこの値を超えて設定できることが確認できる。

ソース的にはどの辺?

nginx/ngx_process_cycle.c at master · nginx/nginx · GitHub

起動時のmainから追っていくとこの辺でrlimitの設定をしてるのがわかる。setrlimit(2)は資源の制限を取得/設定する システムコールです。

    if (ccf->rlimit_nofile != NGX_CONF_UNSET) {
        rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile;
        rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile;

        if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "setrlimit(RLIMIT_NOFILE, %i) failed",
                          ccf->rlimit_nofile);
        }
    }

関数"ngx_worker_process_init"はこの時点ではrootで実行されている。そのためsoft/hardリミットを見ていないのがわかる。ちなみにOS全体のfd制限にはrootと言えど引っかかるのでこの件があっても注意は必要。

参考

その他

Man page of GETRLIMIT