ファイルシステムの検査・修復 fsck

一般的な検査と修復に利用する fsck コマンドがありますが、その利用で badblocks の機能を伴って、不良セクタをリカバリする機能があることを知りました。

その機能の学習を兼ねて、不良ディスクとして保留していたハードディスクを使って実行してみました。

$ sudo fsck -vcck /dev/sdb2
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
Checking for bad blocks (non-destructive read-write test)
Testing with random pattern: done                                                 
system: Updating bad block inode.
Pass 1: Checking iノードs, blocks, and sizes
Pass 2: Checking ディレクトリ structure
Pass 3: Checking ディレクトリ connectivity
Pass 4: Checking reference counts
Pass 5: Checking グループ summary information

system: ***** ファイルシステムは変更されました *****

          11 inodes used (0.00%, out of 2621440)
           0 non-contiguous files (0.0%)
           0 non-contiguous directories (0.0%)
             # of inodes with ind/dind/tind blocks: 0/0/0
             Extent depth histogram: 3
      242382 blocks used (2.31%, out of 10485760)
           0 bad blocks
           1 large file

           0 regular files
           2 directories
           0 character device files
           0 block device files
           0 fifos
           0 links
           0 symbolic links (0 fast symbolic links)
           0 sockets
------------
           2 files

前述が実行結果です。

時間は長く掛かりましたが、以前頻繁にエラーを吐き出していたパーティション位置に対して非破壊型の読み書きテストだとのことです。

このパーティションは、mkfs.ext4 で1度ファイルを生成したのですが、気になるメッセージが最終行にあって、再び mkfs.ext4 で書き直した直後に、前述の fsck を実行しています。

途中に『system: ファイルシステムは変更されました 』の文脈がありますが、不良箇所があって一部が変更されたということでしょうか。初めての実行なので詳細が分かりません。

次にパーティションをファイルに生成した時の1度目と、気になって再実行した2度目のメッセージについて次に示します。

$ sudo mkfs.ext4 -L system /dev/sdb2
mke2fs 1.44.1 (24-Mar-2018)
Creating filesystem with 10485760 4k blocks and 2621440 inodes
Filesystem UUID: 3cf7fb03-0d7d-491b-8d6b-8265e2798161
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000, 7962624

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information:        
Warning, had trouble writing out superblocks.
$ sudo mkfs.ext4 -L system /dev/sdb2
mke2fs 1.44.1 (24-Mar-2018)
Creating filesystem with 10485760 4k blocks and 2621440 inodes
Filesystem UUID: 789bf9e8-5e1d-4dbc-ae81-a8d25a02529b
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000, 7962624

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done   

元々不良ディスクとして、使わずに置かれていたディスクなので、多少なりとも利用できれば学習も兼ねて儲けものかもしれません。

障害発生のハードディスク

数年前にラズパイに搭載していたハードディスクがありました。ラズパイ発売当初の頃、今となってはかなり昔の話になります。ラズパイの使い方は今も変わらないと思いますが、SD あるいは micro SD にシステムを入れて立ち上げ利用します。

その当時、たまたま手持ちの SD 類が低品質だったのか、ラズパイとの相性の問題なのかは今でも納得できないでいますが、使い始めてこれからと思う所まで作業を進めた頃に必ずシステムが飛んでしまい、操作や定義した内容が成果として残らないことが多々ありました。

そのようなこともあり、ラズパイの初期利用の頃からOSの raspbian を最初のboot パーティションを除きハードディスクのパーティションに移して運用していました。それ以降はずっと安定してラズパイを利用していたのですが、ある時1台のラズパイが不安定になり、原因がラズパイのハード本体か、ハードディスクか、SD のブートなのかと疑い、多分ハードディスクだろうとの結論になりました。

当時ハードディスクの確認方法に、どのようなものがあるのか、調べたものの時間もなく『不良』と張り紙して捨てずに残しておきました。

そのハードディスクを見付けて、そう言えば保留で放置していたなと思い出して、調べてみることにしました。

$ sudo fdisk /dev/sdb

fdisk (util-linux 2.31.1) へようこそ。                                                        
ここで設定した内容は、書き込みコマンドを実行するまでメモリのみに保持されます。
書き込みコマンドを使用する際は、注意して実行してください。


コマンド (m でヘルプ): p
ディスク /dev/sdb: 931.5 GiB, 1000204886016 バイト, 1953525168 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 4096 バイト
I/O サイズ (最小 / 推奨): 4096 バイト / 33553920 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0xab9fb81c

デバイス   起動   開始位置   最後から     セクタ サイズ Id タイプ
/dev/sdb1             2048    2099199    2097152     1G  b W95 FAT32
/dev/sdb2          2099200   44042239   41943040    20G 83 Linux
/dev/sdb3         44042240   48236543    4194304     2G 82 Linux スワップ / Solaris
/dev/sdb4         48236544 1953525167 1905288624 908.5G  5 拡張領域
/dev/sdb5         48238592  635441151  587202560   280G 83 Linux
/dev/sdb6        635443200 1222645759  587202560   280G 83 Linux
/dev/sdb7       1222647808 1953525167  730877360 348.5G 83 Linux

コマンド (m でヘルプ): q

$ sudo blkid
  --
     途中省略
              --
/dev/sdb1: UUID="7C91-A3DA" TYPE="vfat" PARTUUID="ab9fb81c-01"
/dev/sdb2: UUID="83670319-849c-459b-84aa-fe7f3f776145" TYPE="ext4" PARTUUID="ab9fb81c-02"
/dev/sdb3: UUID="c3a4d72a-7866-4ffe-a864-5a3f24fb889f" TYPE="swap" PARTUUID="ab9fb81c-03"
/dev/sdb5: LABEL="home" UUID="35786e95-ea9a-4975-aa39-c10ba1d47e3f" TYPE="ext4" PARTUUID="ab9fb81c-05"
/dev/sdb6: LABEL="data" UUID="217555fc-a5d3-4cd8-9702-06f1b5c77f6d" TYPE="ext4" PARTUUID="ab9fb81c-06"
/dev/sdb7: LABEL="bkup" UUID="8aec4e2f-e576-4b73-9aa1-38b905c68dc1" TYPE="ext4" PARTUUID="ab9fb81c-07"

$ sudo fsck /dev/sdb1
fsck from util-linux 2.31.1
fsck.fat 4.1 (2017-01-24)
/dev/sdb1: 0 files, 1/261629 clusters

$ sudo fsck /dev/sdb2
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
/dev/sdb2: clean, 15/1310720 files, 285254/5242880 blocks

$ sudo fsck /dev/sdb5
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
home: clean, 953/18350080 files, 1202987/73400320 blocks

$ sudo fsck /dev/sdb6
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
data: clean, 703/18350080 files, 1345817/73400320 blocks

$ sudo fsck /dev/sdb7
fsck from util-linux 2.31.1
e2fsck 1.44.1 (24-Mar-2018)
bkup: clean, 11/22847488 files, 1483745/91359670 blocks

前述のように、一般的なパラメータ無しで fsck コマンドを実行しても何のエラーも表示されません。しかし、システムを稼働させるとシステムダウンを起こすほどの不安定な動きをします。

昔は、色々な物が手作りのようで、低レベルフォーマットの話も聞いたことがありますが、時代は変わり、現在は一般利用者が利用できるレベルでもないようです。調べるとディスクドライブ全域にスペースを書き込む方法については見つかりました。

昔の記事の中には、使えるものがメーカーで異なっていたとか、ガードが掛からずスーパーブロックまで消去されてしまい大問題になったらしいた記事等もありました。

なお、Linux システムで、 /dev/sdb ドライブに ‘0’ を充填するコマンドは次のコマンドです。

# dd if=/dev/zero of=/dev/sdb bs=1M

ディスクの修復等をキーワードで検索すると、『Linuxでディスクのエラーや不良セクタのチェックと修正をする方法』を見付けました。

その記事では、 fdisk えふでぃすく | hdparm えいちでぃーぱーむ | badblocks ばっどぶろっくす | e2fsck いーつーえふえすしーけー | fsck えふえすしーけー について記述されていました。

私が使ったことのない初めて知るようなコマンドも説明してくれています。 hdparm は昔何かの講習会で聞いたような気もしますが、すでに記憶からは飛んでいました。

ハードディスクの情報を取得

その中で、ハードディスクのモデルを表示するコマンドを見付けましたが、試してみると残念ながら再現しませんでした。コマンドが変わったのか、ディスクの情報の持たせ方が変わったのか、詳細は分かりませんが時代の変化なのかもしれません。

$ sudo hdparm -i /dev/sdb1 |fgrep Model
 Model=Hitachi HDS5C3020ALA632, FwRev=ML6OA5C0, SerialNo=ZZZZZZZZZZZZZZ

前述が説明のサンプルですが、実際の結果が次になります。

$ sudo hdparm -i /dev/sdb |fgrep Model
 HDIO_GET_IDENTITY failed: Invalid argument

hdparm のオプションを -I に変えて実行すると、色々な情報が表示されるので、何かが変わったのでしょうね。

$ sudo hdparm -I /dev/sdb

/dev/sdb:

ATA device, with non-removable media
        Model Number:       ST1000LM024 HN-M101MBB                  
        Serial Number:      S30EJ9GF304434      
        Firmware Revision:  2BA30001
        Transport:          Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6, SATA Rev 3.0
Standards:
        Used: unknown (minor revision code 0x0028) 
        Supported: 8 7 6 5 
        Likely used: 8
Configuration:
        Logical         max     current
        cylinders       16383   16383
        heads           16      16
        sectors/track   63      63
        --
        CHS current addressable sectors:    16514064
        LBA    user addressable sectors:   268435455
        LBA48  user addressable sectors:  1953525168
        Logical  Sector size:                   512 bytes
        Physical Sector size:                  4096 bytes
        Logical Sector-0 offset:                  0 bytes
        device size with M = 1024*1024:      953869 MBytes
        device size with M = 1000*1000:     1000204 MBytes (1000 GB)
        cache/buffer size  = 16384 KBytes
        Form Factor: 2.5 inch
        Nominal Media Rotation Rate: 5400
Capabilities:
        LBA, IORDY(can be disabled)
        Queue depth: 32
        Standby timer values: spec'd by Standard, no device specific minimum
        R/W multiple sector transfer: Max = 16  Current = ?
        Advanced power management level: disabled
        Recommended acoustic management value: 254, current value: 0
        DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6 
             Cycle time: min=120ns recommended=120ns
        PIO: pio0 pio1 pio2 pio3 pio4 
             Cycle time: no flow control=120ns  IORDY flow control=120ns
Commands/features:
        Enabled Supported:
           *    SMART feature set
                Security Mode feature set
           *    Power Management feature set
           *    Write cache
           *    Look-ahead
           *    Host Protected Area feature set
           *    WRITE_BUFFER command
           *    READ_BUFFER command
           *    NOP cmd
           *    DOWNLOAD_MICROCODE
                Advanced Power Management feature set
                Power-Up In Standby feature set
           *    SET_FEATURES required to spinup after power up
                SET_MAX security extension
                Automatic Acoustic Management feature set
           *    48-bit Address feature set
           *    Device Configuration Overlay feature set
           *    Mandatory FLUSH_CACHE
           *    FLUSH_CACHE_EXT
           *    SMART error logging
           *    SMART self-test
           *    General Purpose Logging feature set
           *    64-bit World wide name
           *    IDLE_IMMEDIATE with UNLOAD
           *    WRITE_UNCORRECTABLE_EXT command
           *    {READ,WRITE}_DMA_EXT_GPL commands
           *    Segmented DOWNLOAD_MICROCODE
           *    Gen1 signaling speed (1.5Gb/s)
           *    Gen2 signaling speed (3.0Gb/s)
           *    Gen3 signaling speed (6.0Gb/s)
           *    Native Command Queueing (NCQ)
           *    Phy event counters
           *    Idle-Unload when NCQ is active
           *    NCQ priority information
                DMA Setup Auto-Activate optimization
                Device-initiated interface power management
           *    Software settings preservation
           *    SMART Command Transport (SCT) feature set
           *    SCT Read/Write Long (AC1), obsolete
           *    SCT Write Same (AC2)
           *    SCT Error Recovery Control (AC3)
           *    SCT Features Control (AC4)
           *    SCT Data Tables (AC5)
Security: 
        Master password revision code = 65534
                supported
        not     enabled
        not     locked
        not     frozen
        not     expired: security count
                supported: enhanced erase
        194min for SECURITY ERASE UNIT. 194min for ENHANCED SECURITY ERASE UNIT.
Logical Unit WWN Device Identifier: 50004cf20ca73d80
        NAA             : 5
        IEEE OUI        : 0004cf
        Unique ID       : 20ca73d80
Checksum: correct

説明されていた hdparm のパラメータを変更した結果が次です。

$ sudo hdparm -I /dev/sdb |fgrep Model 
        Model Number:       ST1000LM024 HN-M101MBB

不良セクタを調べる方法も説明されていて、せっかくなのでそれを試してみました。不良箇所が多くて時間がかかったのか、1TB 2.5インチディスクの実行に丸1日以上かかりました。212箇所の不良ブロックでした。

$ sudo badblocks -v -s /dev/sdb | tee /tmp/badblocks.txt 
Checking blocks 0 to 976762583
Checking for bad blocks (read-only test): 6154392 done, 6:03 elapsed. (0/0/0 errors)
6154393 done, 6:37 elapsed. (1/0/0 errors)
6154394 done, 7:12 elapsed. (2/0/0 errors)
6154395 done, 7:45 elapsed. (3/0/0 errors)
6250116 done, 8:59 elapsed. (4/0/0 errors)
6250117 done, 9:34 elapsed. (5/0/0 errors)
6250118 done, 10:08 elapsed. (6/0/0 errors)
   --
       途中省略
                 --
329269885one, 6:23:07 elapsed. (205/0/0 errors)
329269886one, 6:23:42 elapsed. (206/0/0 errors)
329269887one, 6:24:17 elapsed. (207/0/0 errors)
329370036one, 6:25:04 elapsed. (208/0/0 errors)
329370037one, 6:25:38 elapsed. (209/0/0 errors)
329370038one, 6:26:12 elapsed. (210/0/0 errors)
329370039one, 6:26:46 elapsed. (211/0/0 errors)
done                                                 
Pass completed, 212 bad blocks found. (212/0/0 errors)

前述の方法で収集した情報を利用して、不良セクタをマークするとのこと試してみます。ただ良く理解できていないのは、説明されている例では、パーティションを対象に操作しています。

でもディスクドライブに対して不良セクタを除く必要があるようにも思うのですが…、それとスーパーブロックと呼ばれる領域は、各ファイルの中に作られるものでしょうか。
だとするとディスクドライブ全体に操作すること自体が間違いなのかとも思います。知識不足から釈然としませんが、その出力から次の結果となりました。

$ sudo e2fsck -l /tmp/badblocks.txt /dev/sdb
e2fsck 1.44.1 (24-Mar-2018)
ext2fs_open2: Bad magic number in super-block
e2fsck: Superblock invalid, trying backup blocks...
e2fsck: Bad magic number in super-block while trying to open /dev/sdb

The superblock could not be read or does not describe a valid ext2/ext3/ext4
ファイルシステム.  If the device is valid and it really contains an ext2/ext3/ext4
ファイルシステム (and not swap or ufs or something else), then the superblock
is corrupt, and you might try running e2fsck with an alternate superblock:
    e2fsck -b 8193 
 or
    e2fsck -b 32768 

Found a dos partition table in /dev/sdb

ディスクドライブに対しての操作ですが、そもそも e2fsck 自体が、ext2 ext3 等のファイルに対するチェックや修復のコマンドなので、私の操作そのものが誤りなのでしょうね。

$ sudo e2fsck -b 32768 /dev/sdb
e2fsck 1.44.1 (24-Mar-2018)
e2fsck: Bad magic number in super-block while trying to open /dev/sdb

The superblock could not be read or does not describe a valid ext2/ext3/ext4
ファイルシステム.  If the device is valid and it really contains an ext2/ext3/ext4
ファイルシステム (and not swap or ufs or something else), then the superblock
is corrupt, and you might try running e2fsck with an alternate superblock:
    e2fsck -b 8193 
 or
    e2fsck -b 32768 

Found a dos partition table in /dev/sdb

同様のメッセージが繰り返されるだけでした。パラメータを少し変えたりしながら試しましたが、同じメッセージが出されるだけでした。

そこで、ディスクドライブの全域に ‘0’ を書き込んでみることにしました。時間が掛かるのは当然としても想像していたよりは早く完了しました。

$ sudo dd if=/dev/zero of=/dev/sdb bs=1M
dd: '/dev/sdb' の書き込みエラー: デバイスに空き領域がありません
953870+0 レコード入力
953869+0 レコード出力
1000204886016 bytes (1.0 TB, 932 GiB) copied, 32963.1 s, 30.3 MB/s

当然ですが、定義してあったパーティションの情報は消去されています。

$ sudo fdisk /dev/sdb

fdisk (util-linux 2.31.1) へようこそ。
ここで設定した内容は、書き込みコマンドを実行するまでメモリのみに保持されます。
書き込みコマンドを使用する際は、注意して実行してください。

デバイスには認識可能なパーティション情報が含まれていません。
新しい DOS ディスクラベルを作成しました。識別子は 0x53cc047d です。

コマンド (m でヘルプ): p
ディスク /dev/sdb: 931.5 GiB, 1000204886016 バイト, 1953525168 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 4096 バイト
I/O サイズ (最小 / 推奨): 4096 バイト / 33553920 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x53cc047d

コマンド (m でヘルプ): q

次に、不良セクタを再び調べると、完了するまでの時間も短く、エラーしたメッセージは1つもありませんでした。実行時間が短いのは、リトライでの繰り返しが無くなっての短縮かと思われます。

$ sudo badblocks -v -s /dev/sdb | tee /tmp/badblocks.txt
Checking blocks 0 to 976762583
Checking for bad blocks (read-only test): done                                                 
Pass completed, 0 bad blocks found. (0/0/0 errors)

これで、色々なパーティションを作成してまともに利用できるのかは不明ですが、もう少し検証してみたいと考えています。


badblocks の修復説明サイト

別な情報を検索していると、badblocks の修復について説明しているサイトを見付けました。

ここの説明を見ると mkfs でファイルを作成する時や、 fsck でファイルをチェックする時に、badblocks で収集した不良セクタの情報を適用できるように説明されています。

安定してた共有サーバーダウン

昨日たまたま sshで操作ついでに思い立ち、通常のセキュリティアップデートのつもりで久し振りのコマンド操作後にリブートしたら、安定して運用中の Raspberry Pi 1B の共有サーバーが死にました。

学習しないで同じ轍を踏むとは自分でも悲しいです。最新版の Raspbian は、要注意だという事を改めて再認識させられました。

他にも Raspberry Pi のサーバーが稼働していますが、少し前の Raspbian をセットアップしたサーバーなので、単純にセキュリティアップデートだけが行われたらしく、そのままに稼働しています。

以前のメモを頼りに復活させますが、最新のOSで作って良いのか悩みます。

頭を冷やして少し考えてから判断したいと思います。

勝手に壊される raspbian

Raspberry pi は、Linuxシステムが壊れてしまう不安定なシステムとの認識を発売当初から持っています。最近では一般にSDとの相性問題と言われているような、SDに問題が有りそうだとのメーカー名と製品をリストにした情報が公開されています。

当初は問題を切り分けできる情報も少なく、ある程度実用になる設定を施した頃になると、必ず水を挿すようにシステム障害になっていて、再びやり直しとなって時間ばっかり掛かるだけで使えませんでした。

そんなわけで、Raspberry pi は、ブートの初期には必ず SD や microSD を必要とするので、その後にマウントされるルートシステム以降の処理をUSBハードディスクに移行する方法で安定したシステムとして稼働させていました。

ルートシステムをハードディスクに移行してからは、Raspberry pi 1 B+ や Rasberry pi 2 B を純粋なサーバーとして利用していましたが、特に問題なく稼働していて、時々手動でシステムの update を実行していました。

でも何故か壊れる Raspberry pi 3 B です。こちらはデスクトップ環境で構築していて、特には利用していませんでしたが、付属として3.5インチLCDディスプレイとタッチパネルが装着されています。そして家屋内の共有ディスクとして利用して、データのバックアップシステムとしても利用していた重要なシステムでした。

問題のシステムが動作不能になったのは、ハードディスク障害等の明確なものを除くと、設置から今までの1年足らずで大きく数えて 2回あります。2回共に自動でシステム更新されたらしく、sshでネットログインが出来ず、再起動しても期待した立上げが行われませんでした。

ただし、1度目は大きく変更されていたわけではないようで、ルートファイルシステムとしてのUSBディスクが無効に変更されていたのが 原因で、ほぼその修正だけで立上げが行えました。ただし、デスクトップ画面は別物として一新して見た目は大きく変わっていました。

2度目の今回は、システムが勝手に大きく更新されているようで、前回のように簡単に修復が出来ませんでした。Raspberry pi は、頻繁にシステム構成が変わっているようなので、安定稼働を期待するサーバーの運用には向いていないのかと思ってしまいます。

何故か時々壊れる(壊される?) Raspberry pi 3 ですが、正常に運用していたシステムが動作不能になると、今までに色々とインストールしているモジュールやら設定が問題になります。

微かな期待として、何とかリカバリして上手く復旧が出来て、そのまま利用の継続ができればベストなのですが、今回はping での反応はしていたものの ssh 接続は出来ず、共有ディスクとしてのサービスも機能してなくて、ログ情報を定期的にメールとして送る機能も動作していませんでした。

電源OFF/ONによる再起動を試みたのですが、正常に立上がらないようで、仕方なくモニタ用にテレビをHDMI接続し、キーボードとマウスを繋いでの復旧を試みたのですが、見慣れない画面が出るだけで、Linuxで一般的な立上げバナーも皆無です。システムが大きく変更になったようでした。

ここまでの状況からは、システムの再インストールが必要な状況のようですが、そこで同じ程度の環境に戻すには、色々なモジュールのインストールや設定を再び施す必要があります。システムが正常に動作しているなら、dpkg -l のコマンドでインストールされたモジュールのリストが出るようです。しかし、再インストールしたら以前の情報は消去してしまいます。

立上げ不能のルートシステムを、別に立上げできる正常なシステムを利用して、そこに繋いで残された情報から調べる以外に無く、操作方法をネットの情報から調べ、 apt-get で操作した場合に残されるログから、インストール時に記録された情報を抽出することにします。

記録ファイルは、/var/log/dpkg…. で始まるファイル名で残されているようです。過去のものは圧縮されているようです。

/var/log/dpkg.log
/var/log/dpkg.log.1
/var/log/dpkg.log.xx.gz  … xx 部分が数字の圧縮ファイル

ざっとログ内容を見てみると、インストールしたモジュール名の抽出には、 grep -e  ‘ install ‘ が有効と思われます。指定する文字列は、 ‘install’ の両端を半角の空白で挟んで指定します。

再インストールと修復では、地道に稼働していた状態の最後の dpkg.log から突き合わせて元の状態に近づけようと考えてます。

まずは、ラズパイ3 の再インストールから作業を始めます。なんと1年前にも同様の書き込みがありました。