Home

技術系のメモと日々の雑感

SATA HDD の書き込みが異常に遅い (解決)

昨日の続き。
df を叩いたときに異変に気づいた。

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda2             20315844   2891232  16375972  16% /
/dev/hda5            281319324   6345636 260452940   3% /home
/dev/hda1               124427     12721    105282  11% /boot
tmpfs                   901908         0    901908   0% /dev/shm
none                    901820       104    901716   1% /var/lib/xenstored

何で hda(PATA)で認識してるんだ?
念のため結線をチェックしてみたけど、ケーブルも SATA のものだし、間違ってない。
となると BIOS(Award V6.00PG - 1.31)の設定かもしれないと思って確認したら原因判明。

Advanced メニュー
  - Integrated Peripherals
  - OnChip IDE Devices

の画面にある「On Chip Serial ATA」を Auto にしていたんだけど、これだと SATA ポートに差していても PATA として認識されることがあるようだ。
Enhanced Mode に変更したら sda として認識された。
もう一度 Domain-U のイメージファイルを作ってみると

# dd if=/dev/zero of=/home/xen/test.img bs=1M count=6000
6000+0 records in
6000+0 records out
6291456000 bytes (6.3 GB) copied, 78.264 seconds, 80.4 MB/s

よしよし。
本来の速度になったね。
レスポンスが悪くなる現象ももちろん解消。
それにしても、PATA の設定のままで SATA の HDD が動いてしまうというのはびっくりだったな〜。

以下はおまけ。
今回の現象が出たマザーは MSI の 945GT Speedster(MS-9632 Ver1.A)だけど、マザー上の表記と HDD が認識される順番が違っているようだ。

SATA1  Channel1 Master  /dev/sdc
SATA2  Channel1 Slave   /dev/sdd
SATA3  Channel0 Master  /dev/sda
SATA4  Channel0 Slave   /dev/sdb

SATA1 に差しているのに /dev/sdc になったときは驚いたよ。

SATA HDD の書き込みが異常に遅い

SATA の新品の HDD に交換したマシンに CentOS 5.3 を入れたら書き込みが異常に遅いという現象に遭遇。
virt-install の準備として Domain-U の空のイメージファイルを作ろうとしたら

# dd if=/dev/zero of=/home/xen/hoge.img bs=1M count=6000
6000+0 records in
6000+0 records out
6291456000 bytes (6.3 GB) copied, 2200.38 seconds, 2.9 MB/s

目を疑うような転送速度・・・。
しかも、dd が走っている間は別のコンソールが応答しなくなるほど重くなる。
念のため、処理している間 top を眺めてたけど

top - 14:36:50 up  1:40,  2 users,  load average: 6.17, 5.32, 3.32
Tasks:  49 total,   5 running,  44 sleeping,   0 stopped,   0 zombie
Cpu(s):  6.4%us, 93.6%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1804288k total,  1498512k used,   305776k free,     8188k buffers
Swap:  1052248k total,        0k used,  1052248k free,  1404784k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 1329 root      20  -5     0    0    0 R 42.5  0.0   8:09.57 kjournald
 2816 root      15   0     0    0    0 S 18.6  0.0   0:09.29 pdflush
 2784 root      19   0  5852 1596 1516 R 10.1  0.1   0:20.54 dd
   12 root      10  -5     0    0    0 S  8.3  0.0   1:32.56 kblockd/0
    5 root      10  -5     0    0    0 S  7.3  0.0   4:10.62 events/0
 2813 root      18   0     0    0    0 R  6.1  0.0   0:08.18 pdflush

I/O wait がぜんぜん上がってない。
やっぱり普通じゃないね。
dmesg や /var/log/messages には変なログは出てなかったけど、コンソールに次のメッセージが出ていた。

hda: status timeout: status=0xd0 { Busy }
ide: failed opcode was: unknown
hda: no DRQ after issuing MULTWRITE_EXT
ide0: reset: success

なんか最近こういうパターン多いなぁ。
動きを見る限り、ハード障害というより何か設定をミスしてる感じ。
明日もうちょっと調べてみよう。

サイズの大きな rpm パッケージを見つけるには(続き)

さっきの続き。
rpm のマニュアルを見たらちゃんと書かれていた。
--qf(--queryformat)で表示する情報を選べるらしい。
指定できるタグ(項目名)は rpm --querytags で調べられるそうだ。

# rpm --querytags | grep -i size
SIGSIZE
SIZE
FILESIZES
ARCHIVESIZE
CACHEPKGSIZE
FSSIZES

なるほど。
さらに情報を探してみたら、この querytags について説明しているページがあった。
SIZE を指定しておけばよさそうだね。

# rpm -qa --qf '%{name} %{size}¥n' | sort -k 2 -nr

めでたしめでたし。

サイズの大きな rpm パッケージを見つけるには

ディスクの空きが少ないときなど、不要なパッケージを削除したいことがよくある。
ずっと前から気になってたんだけど、こういうときってサイズの大きなパッケージからチェックしたくなるよね。
でも、それぞれのパッケージのサイズをリストする方法って聞いたことがない。
ということで適当にスクリプトを書いてみた。

#!/usr/bin/perl
open(IN, "rpm -qa |") || die "Open Error";
@pkglist = <IN>;
close(IN);
chomp(@pkglist);

foreach $pkg (@pkglist) {
  open(IN2, "rpm -qi $pkg |") || die "Open Error";
  @info = <IN2>;
  close(IN2);
  $i = 0;
  while($info[$i]){
    if($info[$i] =~ /^Name/){
      @name = split(/ +/, $info[$i]);
    }elsif($info[$i] =~ /^Size/){
      @size = split(/ +/, $info[$i]);
      last;
    }
    $i++;
  }
  print "$name[2] $size[2]¥n";
}

結果が表示されるまでにかなり待たされるのはご愛嬌ということで・・・。
サイズが大きいものから表示するときは結果を sort -k 2 -nr にパイプすればいい。
もちろん、さらに時間がかかる。
これだけ遅いと実用的じゃないかな。

gzip Recovery Toolkit

とあるデータを久しぶりに展開しようとしたら、壊れてた・・・。

$ tar ztvf hoge.tar.gz
gzip: stdin: invalid compressed data--crc error
gzip: stdin: invalid compressed data--length error
drwxrwxr-x root/root       0 2006-08-29 23:44:20 hoge/
-rw-rw-r-- root/root     137 2006-08-29 23:14:27 hoge/Makefile
tar: Skipping to next header
tar: Child returned status 1
tar: Error exit delayed from previous errors

何とか復活させられないかと思ってもがいているうちに gzip Recovery Toolkit というツールを発見。
藁にもすがる思いでインストール。

$ tar zxvf gzrt-*.tar.gz
$ cd gzrt-*
$ make
$ su -
# cp gzrecover /usr/local/bin

手を合わせながら復活の呪文を唱えてみる。

$ gzrecover -v hoge.tar.gz
Opened input file for reading: hoge.tar.gz
Opened output file for writing: hoge.tar.recovered
Found error at byte 1044563 in input stream
Found good data at byte 1044563 in input stream
Total decompressed output = 0 bytes

おっ!
うまくいったかも!

$ cpio -F hoge.tar.recovered -i -v
hoge
hoge/Makefile
cpio: invalid header: checksum error
cpio: premature end of file

・・・ダメか。
hoge ディレクトリの中を見たら Makefile だけだった。
う〜ん、残念。
データがほとんど欠落せずに復活できることもあるそうなので、今回は運が悪かったってことだね。