概要
Linux上でソフトウェアRAIDを構築するmdadmをラズパイで動かしてしばらく運用していたのですが、接続していたHDDのデバイス名が勝手に変わってしまい使えなくなる事態が発生しました。何とか復旧できたので、その方法をご紹介します。
注意事項
本記事でご紹介する方法はmdadmについての知識が不十分な筆者が試行錯誤で行ったものなので「ベストな方法ではない」ことにご注意願います。筆者が失敗したり紆余曲折した内容をもとに、同じ問題に直面した方がより良い解決方法を模索していただくきっかけになれば幸いです。
また本記事でご紹介する復旧コマンドは、接続ディスクの状況によっては保存されているファイルの内容を書き換えてしまう可能性があることにもご注意ください。
環境情報
- マシン名
- Raspberry Pi 4 Model B 4GB
- OS
- Ubuntu 22.04 LTS
- mdadmのバージョン
- v4.2 - 2021-12-30
- 構成
- 2台のHDDでRAID1を構築(同じデータが2台のHDDに存在)
- xfsでフォーマット
初期構築
ラズパイにUSB接続した2台のHDDが、OSから /dev/sda,/dev/sdbとして認識されており、次のコマンドで構築しました。
- RAID1を構築して
/dev/md127として認識させるsudo mdadm --create /dev/md127 --level=1 --raid-devices=2 /dev/sda /dev/sdb - xfsでファイルシステムを作る
sudo mkfs.xfs /dev/md127
あとは指定ディレクトリにマウントして、しばらくはこのまま問題なく運用できていました。
この後に示すトラブル時の結果と比較できるようにするため、現時点の正常な状態がわかるコマンド出力を以下に記載します。
$ sudo mdadm --detail /dev/md127
(出力省略)
Number Major Minor RaidDevice State
0 8 16 0 active sync /dev/sda
1 8 48 1 active sync /dev/sdb
デバイス名が勝手に変わる現象が発生...
ところがある時、マウントしたディレクトリにアクセス出来なくなる事態が発生...
/dev/md127の状況を以下のコマンドで確認すると、2つのHDDのデバイスがどっちもRAIDアレイとして認識されていないことを確認します。
$ sudo mdadm --detail /dev/md127
(出力省略)
Number Major Minor RaidDevice State
0 8 0 0 active sync missing
- 0 0 1 removed
HDDのデバイス名を確認すると、もともと/dev/sda,/dev/sdbという名前だったものが/dev/sdc,/dev/sddに変わっているではありませんか...
$ lsblk | grep ^sd
sdc 8:16 0 1.8T 0 disk
sdd 8:48 0 1.8T 0 disk
少し余談だが重要かもしれない話
「デバイス名が変わってしまう」という事象は、以下記事のように例えばOSが再起動した際などによく発生するようです。今回の事象が発覚した時点での記憶があやふやなのですが、再起動によって変わってしまった可能性も高そうです...
なのでもし仮に「RAIDアレイを最初に構築する時(または構築後)に各ディスクのUUIDを指定する」ことができれば全て解決だと思います。例えば以下のようなコマンドが実行できるのであれば(あくまでも妄想です)。
sudo mdadm --create /dev/md127 --level=1 --raid-devices=2 \
/dev/disk/by-uuid/[uuid-of-sda] \
/dev/disk/by-uuid/[uuid-of-sdb]
しかしながら、(私の知識が間違っていなければ)RAIDアレイを作成する前の段階で、ディスクには有効なUUIDは付与されていないはずです。なので少なくとも、RAIDアレイの構築前にディスクのUUID指定は無理という認識です。
RAIDアレイ構築後であればディスクにもUUIDとUUID_SUBが付与されるので、これを使ってデバイス名に依存しない設定ができるのかもしれません。
$ sudo blkid /dev/sdb
/dev/sda: UUID="[uuid]" UUID_SUB="[uuid-sub]" LABEL="[hostname]:0" TYPE="linux_raid_member"
重要かも!?
記事を書いた直後に知ったのですが、RAIDアレイ構築後に次のコマンドを使って/etc/mdadm/mdadm.conf に現在構築中の情報を追記すれば、仮に再起動してデバイス名が変わってもRAIDアレイが使えそうです(だとしたら私の完全な知識不足...)
sudo bash -c 'mdadm --detail --scan | tee -a /etc/mdadm/mdadm.conf'
復旧のために試行錯誤するも失敗
本題に戻ります。
とりあえずはデバイス名が変わってしまったHDDをRAIDアレイに追加することを試みますが、どちらも追加できません。
$ sudo mdadm --manage /dev/md127 --add /dev/sdc
mdadm: cannot load array metadata from /dev/md127
$ sudo mdadm --manage /dev/md127 --add /dev/sdd
mdadm: cannot load array metadata from /dev/md127
ChatGPTに相談してアレイの停止やumountをしてみても、エラーが出て状況は変わらず...
$ sudo mdadm --stop /dev/md127
mdadm: Cannot get exclusive access to /dev/md127:Perhaps \
a running process, mounted filesystem or active volume group?
$ sudo umount /dev/md127
umount: /dev/md127: not mounted.
解決策
おそらくベストな方法からはほど遠いですが、次の手順で解決しました。
/dev/md127を削除
本当は必要ないかもしれませんが、今回の試行錯誤の過程では削除しました。
sudo rm /dev/md127
mdadmのRAIDアレイを再構築
/dev/md0に新たにRAIDアレイを構築します。
調査した限りだと「mdadm --create ..を実行した際、既にディスクに格納されているデータが残るかどうか?」がわかりませんでした(その辺が書いてあるWeb記事がなかなか見つからない...)。なので以下のコマンドを実行する場合は「既存のデータが書き換えられる」危険性も考慮し、ご自身の判断と責任で実行してください。
$ sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdc /dev/sdd
(出力)
mdadm: /dev/sdc appears to be part of a raid array:
level=raid1 devices=2 ctime=Wed Jan 18 19:35:09 2023
mdadm: Note: this array has metadata at the start and
may not be suitable as a boot device. If you plan to
store '/boot' on this device please ensure that
your boot-loader understands md/v1.x metadata, or use
--metadata=0.90
mdadm: /dev/sdd appears to be part of a raid array:
level=raid1 devices=2 ctime=Wed Jan 18 19:35:09 2023
Continue creating array? y # yを押下
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
これで、以下のように二つのディスクが/dev/md0のRAIDアレイに仲間入りできました。
$ lsblk | grep -A 1 ^sd
sdc 8:16 0 1.8T 0 disk
└─md0 9:0 0 1.8T 0 raid1
sdd 8:48 0 1.8T 0 disk
└─md0 9:0 0 1.8T 0 raid1
また/dev/md0のファイルシステムもこれまで通りxfsになっているのを確認できています。
$ sudo parted /dev/md0 print
Model: Linux Software RAID Array (md)
Disk /dev/md0: 2000GB
Sector size (logical/physical): 512B/4096B
Partition Table: loop
Disk Flags:
Number Start End Size File system Flags
1 0.00B 2000GB 2000GB xfs
UUIDが重複してマウントできない...
「あとは実際にマウントして解決!」のはずが、マウントできません...
$ sudo mount /dev/md0 /path/to/mount
mount: /path/to/mount: wrong fs type, bad option, \
bad superblock on /dev/md0, missing codepage or \
helper program, or other error.
/var/log/syslogの内容を調べると、/dev/md0のUUIDが他のデバイスと重複していることがマウント失敗の原因のようです。
Dec 7 06:08:01 ubuntu kernel: [2594369.042898] XFS \
(md0): Filesystem has duplicate UUID \
xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb - can't mount
半分は推測ですが、前にRAIDアレイとして使っていた/dev/md127のUUIDがシステムにまだ残っていて、それが/dev/md127のUUIDと重なっているのが原因と思っています。なので/dev/md127に向けてmdadm --createを実行していたらこの問題は発生していなかったかもしれません。
UUIDを変更して解決
そこで、/dev/md0のUUIDを変更を以下コマンドで試みますが、失敗します...
$ sudo xfs_admin -U generate /dev/md0
ERROR: The filesystem has valuable metadata changes in a log which needs to
be replayed. Mount the filesystem to replay the log, and unmount it before
re-running xfs_admin. If you are unable to mount the filesystem, then use
the xfs_repair -L option to destroy the log and attempt a repair.
Note that destroying the log may cause corruption -- please attempt a mount
of the filesystem before doing this.
どうやら一回/dev/md0をどこかのパスにマウントする必要があるのですが、既にさっきマウントしようとして失敗している、という事実もあります。。。これはもはや詰んのだか...
しばらく絶望しかけましたが、こちらの記事を参考にして-o nouuidでマウントできました!
sudo mount -t xfs -o nouuid /dev/md0 /path/to/mount
一回アンマウントして、
sudo umount /path/to/mount
UUIDが変更できることを確認。
$ sudo xfs_admin -U generate /dev/md0
Clearing log and setting UUID
writing all SBs
new UUID = xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbc
次はオプションなしでRAIDアレイがマウントできることを確認できました!
$ sudo mount /dev/md0 /path/to/mount
(マウント成功)
$ $ df -h | grep md0
/dev/md0 1.9T 1.4T 531G 72% /path/to/mount