「指定ブロックがどのファイルに属するか調べる」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(赤字リンクの解消)
(翻訳を継続)
18行目: 18行目:
 
badblocks -v /dev/sdxy
 
badblocks -v /dev/sdxy
   
  +
ディスク全体をスキャンすると計算が少し面倒になります。各ファイルシステムはパーティションの先頭からブロック番号を数え始めるため、例えば 2 番目のパーティション上に破損ブロックがあり、そのパーティションがブロック 1000 から始まっていた場合、求めるブロック番号を得るには badblocks が表示するブロック番号から 1000 を引かなければなりません。つまりディスク全体のスキャンでブロック 1005 が破損していると表示された場合、2 番目のパーティションのブロック 5 が求める破損ブロックになります。
The downside to scanning the drive as a whole is that each filesystem is going to start its block count relative to the partition it's on. This means that if you have a bad block that happens to be on, let's say, the second partition, and that partition starts on block 1000, then you will have to subtract 1000 from your block number in order to get the number you want. So if a scan from the beginning of the disk results in block number 1005 being bad, then block 5 of the second partition is what you'll actually be using.
 
   
  +
あるいは、ディスク全体をスキャンして破損ブロックが見つかった場合、それがどのパーティションにあるかを計算して、そのパーティションに対して再度スキャンすることでもブロック番号が得られます。
Otherwise, if you've found bad blocks after doing a full scan, you can simply figure out which partitions they're on, and rescan those in order to get the block number, rather than do any block math.
 
   
もう一つ覚えておべきなのは、badblocks はデフォルトでは 1024 バイトを 1 ブロックとすることです。そのため、-b オプションでブロックサイズを変更してファイルシステムのブロックサイズに一致させるか、後の手順において手計算でブロック番号する必要があります。
+
もう一つ覚えておべきなのは、badblocks はデフォルトでは 1024 バイトを 1 ブロックとすることです。そのため、-b オプションでブロックサイズを変更してファイルシステムのブロックサイズに一致させるか、後の手順において手計算でブロック番号を変換する必要があります。
   
 
パーティションの開始・終了位置を調べるには fdisk を使います(古いバージョンではデフォルトでシリンダー単位になるかもしれません。その場合は -u オプションでセクタ単位に変更できます)。fdisk で表示されるブロックサイズをメモしておいて、後でブロック数を変換できるようしておいてください。
 
パーティションの開始・終了位置を調べるには fdisk を使います(古いバージョンではデフォルトでシリンダー単位になるかもしれません。その場合は -u オプションでセクタ単位に変更できます)。fdisk で表示されるブロックサイズをメモしておいて、後でブロック数を変換できるようしておいてください。
34行目: 34行目:
 
Disk identifier: 0x00000000
 
Disk identifier: 0x00000000
   
れによって、破損ブロックのブロック番号(そのパーティションの開始位置からの相対位置)が分かりました。
+
こまでで、破損ブロックのブロック番号(そのパーティションの開始位置からの相対位置)が分かりました。
   
 
==ファイルシステムをデバッグする (JFS)==
 
==ファイルシステムをデバッグする (JFS)==
125行目: 125行目:
 
tune2fs -j /dev/sdxy
 
tune2fs -j /dev/sdxy
   
==強制的に破損ブロックを再配置させる==
+
==強制的に破損ブロックを代替処理させる==
  +
まず、smartctl コマンドでハードディスク上にいくつの破損ブロックが認識されているかを調べられます:
First you'll want to see how many badblocks the harddrive is aware of through the smartctl command:
 
   
smartctl -t long /dev/sdx [wait until test completes, then]
+
smartctl -t long /dev/sdx [テストが完了するまで待ってから]
 
smartctl -l selftest /dev/sdx
 
smartctl -l selftest /dev/sdx
   
137行目: 137行目:
 
'''198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 0'''
 
'''198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 0'''
   
  +
透過的に破損ブロックをスペアの予備セクタへ代替させるには、単に root で dd コマンドを使って破損ブロックにゼロを書き込むだけです。注意すべきなのは、このコマンドを実行するとき、ファイルシステムと同じブロックサイズを使うことと、ブロックの位置をディスク全体でなくファイルシステムがあるパーティションからの相対位置で指定することです:
To make the harddrive transparently map out the badblock with a spare good sector you will have to simply write zeros to the bad block using the dd command as root. Remember that with this command you have to work with the same block size as your filesystem and the block as to be relative to the partition the filesystem is on and NOT the harddrive as a whole:
 
   
 
dd if=/dev/zero of=/dev/sdxy bs=4096 count=1 seek=2269012
 
dd if=/dev/zero of=/dev/sdxy bs=4096 count=1 seek=2269012
 
sync
 
sync
   
  +
本当に破損セクタが代替処理されたかどうかを確認するには、smartctl コマンドを使って Reallocated_Sector_Ct か Reallocated_Event_Count の値が増えているかを確認します。
You can see if the harddrive did indeed map out an additional bad sector by checking with the smartctl command and seeing if the reallocated sector or event count went up:
 
  +
   
 
smartctl -A /dev/sdx
 
smartctl -A /dev/sdx
151行目: 152行目:
 
'''198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 1'''
 
'''198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 1'''
   
To get Offline_Uncorrectable to go back to 0 you need to run a SMART long test and a selftest:
+
Offline_Uncorrectable 0 に戻すには、SMART のロングテストとセルフテストを実行する必要があります:
   
smartctl -t long /dev/sdx [wait until test completes, then]
+
smartctl -t long /dev/sdx [テストが完了するまで待ってから]
 
smartctl -l selftest /dev/sdx
 
smartctl -l selftest /dev/sdx
   

2016年1月14日 (木) 20:27時点における版

この記事では、ディスク上の指定のブロックがどのファイルに属するか調べる方法を説明します。主な目的は、ストレージに破損ブロックが生じたときに、どのファイルが破損したかを調べることです(そして重要なデータが失われたかどうかを確認できます)。

この記事の中のほとんどのコマンドを実行するには、root か、ディスクに直接読み込みアクセスができるユーザーになる必要があります(disk グループのメンバーであれば十分です)。いつもの通り、現在のバックアップを取っておくとよいでしょう。もうすぐディスクが壊れそうな場合は特にそうです。壊れそうかどうかを調べるには S.M.A.R.T. が役に立ちます。

今のところ、この記事は JFS と EXT ファイルシステムだけに向けて書かれています。

破損ブロックを見つける

badblocks コマンドを使います。このコマンドにはいくつかのスキャンモードがあります。リードオンリーモード(デフォルト)は正確さが一番低くなります。破壊的書き込みモード(-w オプション)は最も正確ですが、より時間がかかり、(当然ながら)ディスク上の全データを破壊します。ですのでこれはブロックが属するファイルを見つけるのには使えません。そして最後に非破壊的読み書きモードがあります。これはおそらく破壊的モードと同じくらい正確で、唯一のデメリットはおそらく一番遅いことです。しかし、ディスクが壊れつつあるとわかっているときは、リードオンリーモードが一番安全でしょう。

次のいずれかのコマンドを実行し、-v オプション(冗長表示)つきでリードオンリースキャンを実行します(x はディスクを表す文字で、y はパーティション番号です)。

ディスク全体をスキャンする:

badblocks -v /dev/sdx

1個のパーティションをスキャンする:

badblocks -v /dev/sdxy

ディスク全体をスキャンすると計算が少し面倒になります。各ファイルシステムはパーティションの先頭からブロック番号を数え始めるため、例えば 2 番目のパーティション上に破損ブロックがあり、そのパーティションがブロック 1000 から始まっていた場合、求めるブロック番号を得るには badblocks が表示するブロック番号から 1000 を引かなければなりません。つまりディスク全体のスキャンでブロック 1005 が破損していると表示された場合、2 番目のパーティションのブロック 5 が求める破損ブロックになります。

あるいは、ディスク全体をスキャンして破損ブロックが見つかった場合、それがどのパーティションにあるかを計算して、そのパーティションに対して再度スキャンすることでもブロック番号が得られます。

もう一つ覚えておくべきなのは、badblocks はデフォルトでは 1024 バイトを 1 ブロックとすることです。そのため、-b オプションでブロックサイズを変更してファイルシステムのブロックサイズに一致させるか、後の手順において手計算でブロック番号を変換する必要があります。

パーティションの開始・終了位置を調べるには fdisk を使います(古いバージョンではデフォルトでシリンダー単位になるかもしれません。その場合は -u オプションでセクタ単位に変更できます)。fdisk で表示されるブロックサイズをメモしておいて、後でブロック数を変換できるようしておいてください。

fdisk -l /dev/sdx
255 heads, 63 sectors/track, 19457 cylinders, total 312581808 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

ここまでで、破損ブロックのブロック番号(そのパーティションの開始位置からの相対位置)が分かりました。

ファイルシステムをデバッグする (JFS)

jfs_debugfs will give you access to all the low level structures within any JFS filesystem. Other filesystems such as the EXT filesystems have similar tools. It is probably a good idea to umount any filesystem before you run this on them. To use it just run:

jfs_debugfs /dev/sdxy

This puts you into a command console. The first thing you should note is your aggregate block size. This is (presumably) the block size the filesystem is using. JFS seems to default to 4096 bytes.

badblocks を実行したときのブロックサイズがこのファイルシステムのブロックサイズと一致していなかった場合は、ブロック番号を変換する必要があります(パーティションの開始位置からの相対ブロック番号を使うことに注意してください)。

つまり、ブロックサイズが 1024 バイトの場合のブロック番号 100 は、ブロックサイズが 4096 バイトの場合のブロック番号 25 になります。変換公式は:

(original block number) / ((filesystem block size) / (badblocks block size))

さて、本来の目的は inode 番号を取得することです。このコマンドを実行してください:

d blocknumber 0 i

この構文の意味は、d コマンドはディスプレイ、ブロック番号、オフセット(ここでは 0 にしている)、表示フォーマット i は inode となっています。

注意: ブロックが使用中でないと表示される場合は、そのブロックが割り当てられておらず、空きスペースになっていることを意味します。これは、何も重要なデータが失われていないということなので良いことです。

The decimal number that di_number is set to is the one we want. From here you type x to exit out of the display mode. Repeat the display command for each bad block that you have and note all of their inode numbers. For more info on the inode such as permissions and filetype type:

i inodenumber

When you have all the inode numbers type q to quit.

破損ファイルを見つける (JFS/Universal)

これでようやく破損ファイルを見つけられます。GNU find ユーティリティを使います。ファイルシステムをマウントして次を実行します:

find / -inum inodenumber

"/" はその inode が属するファイルシステムのマウントポイントで置き換えてください。 / を検索して 2 個以上のファイルシステムがマウントされていたら(普通はそうなっているでしょう)、異なるファイルシステム上で同じ inode 番号のファイルが複数見つかるでしょう。そしてその場合は明らかに時間が長くかかります。inode はファイルシステムの中でだけユニークなことに注意してください。

ファイルシステムをデバッグする (EXT(2/3/4))

tune2fs を使うと、各種 EXT ファイルシステム内の全ての低レベル構造にアクセスできます。これを行う前に全てのファイルシステムをアンマウントしておくとよいでしょう。

最初にやることは、ファイルシステムのブロックサイズを取得することです。これを実行します:

tune2fs -l /dev/sdxy | grep Block
Block count:              29119820
Block size:               4096

この場合は 4096 がブロックサイズです(これがデフォルトのようです)。

badblocks を実行したときのブロックサイズがこのファイルシステムのブロックサイズと一致していなかった場合は、ブロック番号を変換する必要があります(パーティションの開始位置からの相対ブロック番号を使うことに注意してください)。

つまり、ブロックサイズが 1024 バイトの場合のブロック番号 100 は、ブロックサイズが 4096 バイトの場合のブロック番号 25 になります。変換公式は:

(original block number) / ((filesystem block size) / (badblocks block size))

さて、本来の目的は inode 番号を取得することです。このコマンドを実行してください:

debugfs

そして debugfs のコンソールにおいて、破損セクタを含んでいる EXT のパーティションを引数に open コマンドを実行します:

debugfs:  open /dev/sdxy

最後に testb コマンドを実行してそのブロックに関する情報を取得します(この例ではブロック 1000 番):

debugfs:  testb ブロック番号

注意: ブロックが使用中でないと表示される場合は、そのブロックが割り当てられておらず、空きスペースになっていることを意味します。これは、何も重要なデータが失われていないということなので良いことです。

ブロックが使用中なら、このコマンドで inode 番号を取得できます:

icheck ブロック番号

これは 2 個の数字を表示します。ブロック番号と inode 番号です。

破損ファイルを見つける (EXT(2/3/4))

inode 番号(icheck コマンドで表示される 2 番目の番号)を引数に ncheck コマンドを実行します:

ncheck inodenumber

この破損ブロックを使っているファイルのフルパスが表示されます。これで実際に何が破損したのかがわかります。

もし inode 番号が非常に小さくて ncheck がパス表示に失敗する場合は、おそらくジャーナル自体が壊れています。ジャーナルを削除するには、このコマンドをパーティションに対して実行します:

tune2fs -O ^has_journal /dev/sdxy

もう一度 debugfs コンソールでtestb コマンドを使ってそのブロックを調べると、もし本当にジャーナルに使われていたのであれば、今度は使われていると表示されないはずです。 次のコマンドで新しいジャーナルを構築します:

tune2fs -j /dev/sdxy

強制的に破損ブロックを代替処理させる

まず、smartctl コマンドでハードディスク上にいくつの破損ブロックが認識されているかを調べられます:

smartctl -t long /dev/sdx  [テストが完了するまで待ってから]
smartctl -l selftest /dev/sdx
 ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
5 Reallocated_Sector_Ct     0x0033   100   100   005    Pre-fail  Always       -       0
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       0

透過的に破損ブロックをスペアの予備セクタへ代替させるには、単に root で dd コマンドを使って破損ブロックにゼロを書き込むだけです。注意すべきなのは、このコマンドを実行するとき、ファイルシステムと同じブロックサイズを使うことと、ブロックの位置をディスク全体でなくファイルシステムがあるパーティションからの相対位置で指定することです:

dd if=/dev/zero of=/dev/sdxy bs=4096 count=1 seek=2269012
sync

本当に破損セクタが代替処理されたかどうかを確認するには、smartctl コマンドを使って Reallocated_Sector_Ct か Reallocated_Event_Count の値が増えているかを確認します。


smartctl -A /dev/sdx
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
5 Reallocated_Sector_Ct     0x0033   100   100   005    Pre-fail  Always       -       1
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       1
197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       1

Offline_Uncorrectable を 0 に戻すには、SMART のロングテストとセルフテストを実行する必要があります:

smartctl -t long /dev/sdx  [テストが完了するまで待ってから]
smartctl -l selftest /dev/sdx

参考

EXT2/3 badblocks howto