2012年12月28日金曜日

cactiが動かないので遠回りに色々トレースしてみた

俺の仕事用VMはこんな感じでメジャーバージョン違いのMySQLが複数入っている
(しかも、昨日から同時起動している)関係で、ポートやソケットファイルがデフォルトと違う状態で4つある。

色々あってそこにcactiを突っ込みたくなって、cactiのデータ格納用MySQLに5.5.29を任命。
portは64055, socketは/usr/mysql/5.5.29/data/mysql.sock。

さて、cacti/include/config.phpを書き換えてっと。

多分接続先をlocalhostにすると、TCP portを使わずにソケット使おうとして、
/var/lib/mysql/mysql.sockを見に行って転けるだろうから、
(ソケットを指定できそうなパラメータはconfig.phpには無かったので)

$host = '127.0.0.1';
$port = '64055';

にしておく。
…が、敢え無く失敗。


FATAL: Cannot connect to MySQL server on '127.0.0.1'. Please make sure you have specified a valid MySQL database name in 'include/config.php'


ヽ(`Д´)ノ 肝心の`どうして接続出来なかったのか'が書いてNEEE。

ポートもDB名もユーザー名もパスワードも、クライアントからは行けるのになぁ。。


と思ってtcpdumpを取る。


# tcpdump -i any port 64055
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel


…0 packets caputured。。
64055叩いてないねこりゃ。3306になってるかな?
行ってみようstrace。


# strace php index.php 2>&1 | egrep -v "map"
execve("/usr/bin/php", ["php", "index.php"], [/* 23 vars */]) = 0
..
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4
fcntl(4, F_SETFL, O_RDONLY)             = 0
fcntl(4, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(4, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
connect(4, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
fcntl(4, F_SETFL, O_RDWR)               = 0
poll([{fd=4, events=POLLIN|POLLPRI}], 1, 60000) = 1 ([{fd=4, revents=POLLIN|POLLERR|POLLHUP}])
setsockopt(4, SOL_SOCKET, SO_RCVTIMEO, "\2003\341\1\0\0\0\0\0\0\0\0\0\0\0\0", 16) = 0
setsockopt(4, SOL_SOCKET, SO_SNDTIMEO, "\2003\341\1\0\0\0\0\0\0\0\0\0\0\0\0", 16) = 0
setsockopt(4, SOL_IP, IP_TOS, [8], 4)   = 0
setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(4, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
poll([{fd=4, events=POLLIN}], 1, 60000) = 1 ([{fd=4, revents=POLLIN|POLLERR|POLLHUP}])
read(4, 0x189ede0, 16384)               = -1 ECONNREFUSED (Connection refused)
shutdown(4, 2 /* send and receive */)   = -1 ENOTCONN (Transport endpoint is not connected)
close(4)                                = 0
..


はい、大当たり。。
この出力のちょっと前あたりに
..
open("/var/www/cacti/lib/adodb/adodb-iterator.inc.php", O_RDONLY) = 4
..
open("/var/www/cacti/lib/database.php", O_RDONLY) = 4
..
open("/var/www/cacti/lib/adodb/drivers/adodb-mysql.inc.php", O_RDONLY) = 4
..
と並んでいるのを見つけるので、この辺りを探る。


lib/database.phpの中で

$cnn_id = ADONewConnection($dsn);

で接続しているところまでは雰囲気で判ったんだけど、その後がどうも判らない。。(PHP読めない)
$dsnはちゃんとport=64055を渡してるんだけどな。。書き方が違うのかしら。よく判らん。


結局こちらさまを参考にしてsocketファイルでつなぐ様に変えたら5秒で動かせたんだけど、
/etc/php.iniとかが怪しいのかなぁ…?

5秒で済むことに30分かけて結局謎が解けなくても、楽しかったから良いのです。
バイナリだったらこのままgdbでステップ実行してたと思う。
There's more than one way to do itなのですよ(いや、解決してないけど)


良いお年を。

0 件のコメント :

コメントを投稿