2011年1月29日土曜日

Fedora 14 再インストール後に起動できず少し格闘

調査用の Fedora 14 を yum アップデートしている途中、ダウン(panic ?)してしまった。パッケージ管理状態がおかしくなったらしかった(詳細は未確認、yum で山ほどエラー)ため、再インストールした。
ところが、この環境では、ブート時に root が sdc に見えていたため、インストーラで grub インストールを行わなかった。ハマりそうだとは思ったが、レスキューモードでなんとかなるだろうと・・・

当然ながら、インストール完了後にディスクブート出来ず。まずは、レスキューモードで sdc に、 grub-install を実行した。レスキューモード任せで、/mnt/sysimage に / と /boot をマウントさせ、シェルを呼び出して chroot /mnt/sysimage 後に実行でうまくいった。
bash-4.1# chroot /mnt/sysimage
bash-4.1# grub-install /dev/sdc
インストーラで grub をインストールしなかったために、grub.conf が無い状態なので、手動で作成。ここで、Fedora 14 の場合は、UUID 指定が必要なようだ。LABEL指定ではうまくいかなかった。UUID は blkid コマンドで確認できます。
default=0
timeout=60
title Fedora 14
        root (hd0,0)
        kernel /vmlinuz-2.6.35.6-45.fc14.x86_64 ro root=UUID=380cc2b7-99cc-4499-8bab-a4c3653b4d63
        initrd /initramfs-2.6.35.6-45.fc14.x86_64.img
ここで、(hd2,0) なのではないか?と思ったのですが、それではダメでした。
Fedora が起動後は sdc に見えるのですが、この環境では、BIOS の認識順序では (hd0,0) なのです。grub のコマンドプロンプトには、ファイル名補間機能(TABで候補表示)があり、これを使えば識別できます。
    GNU GRUB  version 0.97  (630K lower / 653184K upper memory)

 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.  ESC at any time exits.]

grub> kernel (hd0,0)/vmlinuz-2.6.35.  ※vm まで打って TAB で補間した場合
 Possible files are: vmlinuz-2.6.35.6-45.fc14.x86_64 vmlinuz-2.6.35.10-74.fc14.
x86_64

grub> kernel (hd0,0)/vmlinuz-2.6.35.

2011年1月23日日曜日

perl からプロセスグループを kill する構文

だいぶ前に自分で書いた perl スクリプトを見ていたら、次のような記述になっていた。
...
    if ($stop_flag) {
        kill -9, $my_pgid ;
...
あれれ、もしかしてプロセスグループを kill するつもりが、プロセスグループリーダー (PID=PGID) だけ kill するという指定になってないか? バグってないか?!
kill 9, -$my_pgid と書くのが正しいのではないか? うえー、バグってるかなと思った。
そこで、man perlfunc を読んでみたのだが、kill -9, $my_pgid で正しいようだ。きっと書いた当時は man を読んだのだろう。この場合、わかりにくいし、コメントでも書いておけば良かった。
       kill SIGNAL, LIST
...
               Unlike in the shell, if SIGNAL is negative, it kills process
               groups instead of processes.  (On System V, a negative PROCESS
               number will also kill process groups, but that's not portable.)
               That means you usually want to use positive not negative sig-
               nals.  You may also use a signal name in quotes.
シェル (bashなど) とは違い、負の SIGNAL を指定したら、プロセスグループを kill するとある。

2011-01-29追記
書き忘れましたが、もちろんのこと、strace で実際にプロセスグループ宛になっていることを確認しています。

2011年1月16日日曜日

CentOS 5 で netconsole

CentOS 5 で netconsole を使う際の設定方法と注意点のメモです。

まずは、ログサーバ側の syslogd の設定方法。
/etc/sysconfig/syslogd の SYSLOGD_OPTIONS を次のように設定します。
# Options to syslogd
# -m 0 disables 'MARK' messages.
# -r enables logging from remote machines
# -x disables DNS lookups on messages recieved with -r
# See syslogd(8) for more details
SYSLOGD_OPTIONS="-m 0 -r -x"
リモートからメッセージを受けるには、-r オプションだけでいいのですが、DNS へのアクセスを避けたい場合は、-x オプションも設定します。

次に netconsole 側の設定方法。CentOS 5 の場合は、/etc/sysconfig/netconsole を環境に合わせて設定()して、netconsole サービスを start すれば良い。
# This is the configuration file for the netconsole service.  By starting
# this service you allow a remote syslog daemon to record console output
# from this system.

# The local port number that the netconsole module will use
# LOCALPORT=6666

# The ethernet device to send console messages out of (only set this if it
# can't be automatically determined)
DEV=eth1                   ※

# The IP address of the remote syslog server to send messages to
SYSLOGADDR=192.168.11.222  ※

# The listening port of the remote syslog daemon
# SYSLOGPORT=514

# The MAC address of the remote syslog server (only set this if it can't
# be automatically determined)
SYSLOGMACADDR=00:0C:29:86:DC:7A  ※
netconsole サービスを起動します。
# service netconsole start
Initializing netconsole                                    [  OK  ]
# dmesg | tail -7
netconsole: local port 6666
netconsole: local IP 192.168.163.222
netconsole: interface eth1
netconsole: remote port 514
netconsole: remote IP 192.168.11.222
netconsole: remote ethernet address 00:0c:29:86:dc:7a
netconsole: network logging started
dmesg の出力から使用される IP アドレスとポートを確認できます。

最後に、動作確認ですが、次のように sysrq-trigger を使ってカーネルにメッセージを生成させればよいかと思います。
# echo p > /proc/sysrq-trigger 
# dmesg | tail -1
SysRq : Show Regs
ログサーバ側には、次のように出力されます。
# tail -2 /var/log/messages
Jan 16 19:59:29 192.168.163.222 SysRq : 
Jan 16 19:59:29 192.168.163.222 Show Regs
このように、ローカルでは1行で出力されるメッセージが、ログサーバ側には2行に分割されて出力されてしまいます。これは、netconsole の場合の特徴で、カーネル内でメッセージ出力の際に呼ばれる printk 関数毎に UDP パケットが生成/転送されるためです。SysRq p の対応コードを読めば printk が2回呼ばれていることが分かります。参照するカーネルソースファイルは、drivers/char/sysrq.c です。

注意点としては、以下が挙げられます。

●ローカルでは1行で出力されるメッセージが2行以上に分割される場合がある。

●残念ながら bonding インタフェースは利用できない。
 →Fedora 14 でも試してみましたが、やはり NG でした。bonding モジュールに netpoll サポートが無いためのようですが、実装は困難なのかもしれません。あまりニーズも無い?

●設定を行う際、ログサーバ側の iptables にも注意する。
 →当然ながら syslog 用ポート 514/udp が許可されている必要がある。

●ルータ越えを行う場合は、SYSLOGMACADDR にルータの MAC を設定する必要がある。
 →私の環境では、ルータ越えは動作しました。そもそも動作しないということはないようです。

2011-02-05追記
これら注意点から、普通は商用サーバでは使えないものと思っています。どうしてもダンプ(kdump)も採取できないような障害に遭遇して情報採取(SysRq 等)が必要な場合は、最も確実なシリアルコンソールを使うのが良いと思う。
人気ブログランキングへ にほんブログ村 IT技術ブログへ