rndc status の recursive clients
rndc status 打つと以下のような表示が出るが、
number of zones: 14 debug level: 0 xfers running: 0 xfers deferred: 0 soa queries in progress: 0 query logging is ON recursive clients: 194/1900/2000 tcp clients: 0/100 server is up and running
recursive clients: 194/1900/2000
これの真ん中の 1900 ってナニ?
という質問をされました。
気分転換に調べてみたのでメモ。
まずBINDのソースをダウンロードしてきます。
それを展開して以下のファイルを見ます。
bin/named/server.c
n = snprintf((char *)isc_buffer_used(text), isc_buffer_availablelength(text), "version: %s%s%s%s\n" #ifdef ISC_PLATFORM_USETHREADS "CPUs found: %u\n" "worker threads: %u\n" #endif "number of zones: %u\n" "debug level: %d\n" "xfers running: %u\n" "xfers deferred: %u\n" "soa queries in progress: %u\n" "query logging is %s\n" "recursive clients: %d/%d/%d\n" "tcp clients: %d/%d\n" "server is up and running", ns_g_version, ob, alt, cb, #ifdef ISC_PLATFORM_USETHREADS ns_g_cpus_detected, ns_g_cpus, #endif zonecount, ns_g_debuglevel, xferrunning, xferdeferred, soaqueries, server->log_queries ? "ON" : "OFF", server->recursionquota.used, server->recursionquota.soft, server->recursionquota.max, server->tcpquota.used, server->tcpquota.max);
ここに以下のような記述があります。
"recursive clients: %d/%d/%d\n"
実際に recursive clients: 194/1900/2000 と表示される部分ね。
ここの %d に当てはまるのがそれぞれ、
server->recursionquota.used, server->recursionquota.soft, server->recursionquota.max,
のようです。
usedとmaxはいいとして、softが何なのか謎です。
もうちょい調べてみる。
bin/named/server.c をもう一度良く見て、以下の記述を発見
/* * Configure various server options. */ configure_server_quota(maps, "transfers-out", &server->xfroutquota); configure_server_quota(maps, "tcp-clients", &server->tcpquota); configure_server_quota(maps, "recursive-clients", &server->recursionquota); if (server->recursionquota.max > 1000) isc_quota_soft(&server->recursionquota, server->recursionquota.max - 100); else isc_quota_soft(&server->recursionquota, 0);
ここでサーバパラメータを設定している。
MAXが1000より大きな値ならば、Soft Quotaに MAX - 100 の値を設定している。
たとえば
recursive clients: 194/1900/2000
のように 2000 にしたとしたら、 Soft Quotaは 1900 になる。
で、isc_quota_soft は何かというと以下のCファイルに関数が定義されていて、
lib/isc/quota.c
void isc_quota_soft(isc_quota_t *quota, int soft) { LOCK("a->lock); quota->soft = soft; UNLOCK("a->lock); }
isc_quota_soft(&server->recursionquota, server->recursionquota.max - 100);
のように呼び出して MAX - 100 の値を入れているだけのようだ。
設定されたSoft Quota がどのように利用されるかというと、
まず、lib/isc/quota.c の中の以下の関数で現在のクライアント数をカウントしていて、
lib/isc/quota.c
isc_result_t
isc_quota_reserve(isc_quota_t *quota) {
isc_result_t result;
LOCK("a->lock);
if (quota->max == 0 || quota->used < quota->max) {
if (quota->soft == 0 || quota->used < quota->soft)
result = ISC_R_SUCCESS;
else
result = ISC_R_SOFTQUOTA;
quota->used++;
} else
result = ISC_R_QUOTA;
UNLOCK("a->lock);
return (result);
}
通常は ISC_R_SUCCESS が返るが、Soft Quotaに達したら ISC_R_SOFTQUOTA を返す。
MAXに達したら ISC_R_QUOTA を返す。
その返り値を見て、
bin/named/query.c の
if (client->recursionquota == NULL) { result = isc_quota_attach(&ns_g_server->recursionquota, &client->recursionquota); if (result == ISC_R_SOFTQUOTA) { static isc_stdtime_t last = 0; isc_stdtime_t now; isc_stdtime_get(&now); if (now != last) { last = now; ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, ISC_LOG_WARNING, "recursive-clients soft limit " "exceeded, aborting oldest query"); } ns_client_killoldestquery(client); result = ISC_R_SUCCESS; } else if (result == ISC_R_QUOTA) { static isc_stdtime_t last = 0; isc_stdtime_t now; isc_stdtime_get(&now); if (now != last) { last = now; ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, ISC_LOG_WARNING, "no more recursive clients: %s", isc_result_totext(result)); } ns_client_killoldestquery(client); } if (result == ISC_R_SUCCESS && !client->mortal && (client->attributes & NS_CLIENTATTR_TCP) == 0) { result = ns_client_replace(client); if (result != ISC_R_SUCCESS) { ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, ISC_LOG_WARNING, "ns_client_replace() failed: %s", isc_result_totext(result)); isc_quota_detach(&client->recursionquota); } } if (result != ISC_R_SUCCESS) return (result); ns_client_recursing(client); }
if (result == ISC_R_SOFTQUOTA) でクライアント数がSoft Quotaに達したら
"recursive-clients soft limit "
"exceeded, aborting oldest query"
のようなログを吐いて、
ns_client_killoldestquery(client); 関数を呼んで
古いクエリを殺し、ISC_R_SUCCESS を返す。
if (result == ISC_R_QUOTA) でクライアント数がHard Quota (MAX)に達したら、
no more recursive clients:
のようなログを吐いて、
ns_client_killoldestquery(client); 関数を呼んで
古いクエリを殺すが ISC_R_SUCCESSは返さない。
このns_client_killoldestquery(client)関数の中身までは追ってない。
ソース読むの苦手だけど、BINDのソースってずいぶん丁寧に書かれていてわかりやすいな……すごい。
PC買い替え
PC本体
DELL Optiplex 780 デスクトップ筐体(Nシリーズ)
CPU: Celeron450 (ラインナップの中で一番低消費電力なやつがこれだった)
Memory: 8GB
HDDは以下を使って載せ替え
SuperMicroのCSE-M14TB
http://www.supermicro.com/products/accessories/mobilerack/CSE-M14.cfm
5インチベイに2.5インチHDD(またはSSD)を4基搭載可能なHard Disk Drive Trays
SATAカードは
HighPointのRocketRAID 2310 (PCI-Express x4 ロープロファイル)
に、CentOS 5(x86_64) を入れようとしたところ、色々と問題が出たのでメモ。
失敗その1
まず、DELLのデスクトップ筐体にCSE-M14TBが入らなかったw
5インチのDVD-ROMドライブあるから、それを取り払えば入るだろうくらいに思ってたが、
マウントの仕方が特殊すぎてネジ穴の位置が合わなくて挫折。
CSE-M14TBに無理やりネジ穴掘ろうかと思ったが、穴は空けられてもネジがHDDに干渉するのでNG。
仕方が無いので、両面マジックテープをCSE-M14TBに貼り付けて、ケーブルマネジメント用のマジックテープで
ぐるりと巻いて固定。
筐体のフタにこれまた共振防止用ゴムを貼り付けて、無理やり押さえつけたら固定できた。
でもあんまり強く押したりするとずれるかもwww
失敗その2
せっかくリムーバブルケース買ったのに、DELL筐体に収めたらDiskトレイの下側2本が引っかかって取り出せないw
ケースのプラをヤスリで削ればいけるけど、まだ実行してない。
失敗その3
CentOS 5.4 が、RocketRAID2310のドライバ入ってなかったため
RR2310側でRAID組んでも認識されなかったwww
所詮SoftwareRAIDカードなんてこんなものか。。。
SuperMicroのCSE-M14TB自体のレビューなど。
まず、これは誰しも書いてることだけどFANが死ぬほどうるさくて家庭での使用に堪えない。
ので、FANは取り外してジャンパを切らなければならない。
そうすると熱問題が持ち上がるので、HDDを使うのであれば5400rpmのものを使うほうが良いと思う。
トレイの取り扱いは、挿すときに若干の引っかかりは感じるものの、そうっと扱えば問題ないレベル。
あとは、HDDをトレイに取り付けるときにちゃんとネジをしっかり締めないと、そのネジに引っかかって
トレイが入らないことがあるので注意。
今のところこんな感じかな。。。
OpenLDAPのslapd.access(5)の話
ここ最近OpenLDAPを触っているんだけど、以下のような設定をするのにだいぶ悩んだ。
access toby
みたいな設定をするときに、特定グループに所属するユーザには管理者権限を与えたい。
つまり、管理者グループに所属するユーザにはLDAPの情報をRead/Writeする権限を与えたい。
例えば
uid=hoge,ou=People,dc=example,dc=com uid=fuga,ou=People,dc=example,dc=com cn=admin,ou=Groups,dc=example,dc=com
のような感じで登録してあったとして、
hogeユーザは一般人だけどfugaユーザは管理者なので、こいつには管理者権限を与えたい。
と言ったときに adminグループに所属していれば管理者だよーと出来ればラクかなぁと。
で、man slapd.access(5) を見ていたらどうやら以下を使えば出来そう。
group[/[/ ]] [. ]=
要は、上記式 group=
説明を読むとデフォルト値は groupOfNames オブジェクトクラスの member アトリビュートに所属するユーザ、ということになるので上記式に当てはめるとこうなる。
group/groupOfNames/member="cn=admin,ou=Groups,dc=example,dc=com" 省略してこう書ける。 group="cn=admin,ou=Groups,dc=example,dc=com" 実際書くとしたら by group="cn=admin,ou=Groups,dc=example,dc=com" write などと書くだろう。
ただ、groupOfNames オブジェクトクラスを使おうとすると、posixGroup オブジェクトクラスの cn とかぶってしまうのが困る。なのでposixGroupオブジェクトクラスのmemberUidが使えないかなぁと思ったりして以下のように設定してみた。
group/posixGroup/memberUid="cn=admin,ou=Groups,dc=example,dc=com"
ところがこうすると、
Checking configuration files for slapd: /etc/openldap/slapd.conf: line 75: group "cn=admin,ou=Groups,dc=example,dc=com": inappropriate syntax: 1.3.6.1.4.1.1466.115.121.1.26.
というエラーが出た。
データ型(SYNTAX)
1.3.6.1.4.1.1466.115.121.1.26 ASCII文字列
という意味らしい??
スキーマを読むとわかるのだが、memberUidにはASCII文字列しか書いてはいけないようだ。
つまり、右辺にDNは書けないことになる。うーむ。
色々悩んだ挙句、結局のところデフォルトの groupOfNames を使うことにした。
管理者用のグループは特殊扱いということで posixGroupオブジェクトクラスは入れずに top, groupOfNames オブジェクトクラスにして他とは別にした。他にいい案が浮かばなかったので仕方ない。
で、このmemberアトリビュートに uid=fuga,ou=People,dc=example,dc=com を登録すればよい。
以下のようなLDIFを作る。
dn: cn=ldapadmin,ou=Groups,dc=example,dc=com objectClass: top objectClass: groupOfNames cn: ldapadmin member: uid=fuga,ou=People,dc=example,dc=com
ldapaddコマンドで登録。
ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f ldapadmin.ldif
それで slapd.conf に
access to attrs=userPassword
by dn="cn=Manager,dc=example,dc=com" write
by group="cn=ldapadmin,ou=Groups,dc=example,dc=com" write
by self write
by anonymous auth
by * none
access to *
by dn="cn=Manager,dc=example,dc=com" write
by group="cn=ldapadmin,ou=Groups,dc=example,dc=com" write
by * read
とか書けば思った通りの動作をした。
terminfoとtermcap
昨日の続き。昨日は中身もよく知らずにやっていたので。
terminfo使っていれば .termcap ファイルは作成しなくても良かった。
http://www.linux.or.jp/JF/JFdocs/Text-Terminal-HOWTO-15.html
いままで特に気にしてなかったけど、termcap, terminfo の説明。あと ncurses についても少し。
そもそも ncurses に関して何をするものなのかよく分かって無かった。ほぼ必ず必要なパッケージだとは認識していたけれど、それが何をするものなのかまでは知ってなかった。
termcapは古い方法で、terminfoデータベースを使えるならそちらを使った方がよさそう。
Fedora9には /etc/termcap は無いし。/etc/terminfo/ はあるけどディレクトリは空っぽ。
terminfoを再コンパイルすることで ~/.terminfo/x/xterm ファイルが作成されたので、個人用にはこちらを使うのがいいのかな?
現在使用中の端末用データベースの内容を見るには infocmp とタイプする。$ infocmp > xterm.info とかしてテキストに落とす。
echo $TERM すれば現在使用中の端末タイプがわかる。
これを自分好みに編集後、terminfoコンパイラ tic を使ってコンパイルしなおせば良いことになる。
''tic'' はコンパイル後に、アプリケーションプログラムが使うであろう terminfo ディレクトリにコンパイル済ファイルを自動でインストールします
と書いてある。
で、結局
$ infocmp > xterm.info
$ vi xterm.info
して、rmcup=\E[?1049l, smcup=\E[?1049h, の2つを削除する。
そんで
$ tic -o ~/.terminfo xterm.info
とすれば新しいterminfoデータベースが作成されて万歳。
ticコマンドは -o つけなくても、デフォルトで ~/.terminfo/ ディレクトリ以下にファイルを作成してくれました。
termcap
今使っているFedora9でviとかlessとか使うと、終了した時に画面が元に戻ってしまうのをなんとかしたいと思ってました。
manとか読んでて q で抜けて、SEE ALSO をさらにmanしようと思ったときなんかに画面消されると非常に不愉快になります。なのでこういう動作は好きじゃないんだけど設定変更の仕方が分かりませんでした。
今日ふとどさにっきを見ていて変更の仕方が書いてあったので試しに調べて変更してみました。
参考にしたページ
http://slashdot.jp/~doda/journal/438524
http://ya.maya.st/d/200901a.html#s20090105_2
以下の内容の~/.termcapを作成する。
xterm|xterm X11R6 version:\
:te@:ti@:tc=xterm-r6:
つづけて、
% infocmp > xterm.ti
作成されたxterm.tiを編集し、rmcup=\E[?1049l, と smcup=\E[?1049m, を削除する。
% tic -o ~/.terminfo xterm.ti
望む動作になりました。
よかった^^
Getting update lists failed
Fedora9 を使っていて突然出始めたエラー。
何をしたんだっけ…。
Getting update lists failed
Failed to get updates
More details
A security policy in place prevents this sender from sending this message to this recipient, see message bus configuration file (rejected message had interface "org.freedesktop.PackageKit.Transaction" member "GetUpdates" error name "(unset)" destination "org.freedesktop.PackageKit")
つづき。
ここに情報があった。
http://www.linuxquestions.org/questions/fedora-35/package-kit-error-689295/
Fedora固有の現象らしい?
http://forums.fedoraforum.org/showthread.php?t=206797&page=4
# cp -ip /etc/dbus-1/system.d/org.freedesktop.PackageKit.conf{,.`date +%Y%m%d`}
# vi /etc/dbus-1/system.d/org.freedesktop.PackageKit.conf
# diff -c /etc/dbus-1/system.d/org.freedesktop.PackageKit.conf{.`date +%Y%m%d`,}
*** /etc/dbus-1/system.d/org.freedesktop.PackageKit.conf.20081210 Sat Sep 6 18:55:36 2008
--- /etc/dbus-1/system.d/org.freedesktop.PackageKit.conf Wed Dec 10 09:40:55 2008
***************
*** 14,19 ****
--- 14,20 ----
+
これで直るんだろうか。
海外のレシピ
http://www.cookingforengineers.com/
どこかのBlogで見つけたのでメモ。
海外のレシピサイトだけど、チャート表示がわかりやすい。