Amazon EBSマウント時の「wrong fs type, bad option, bad superblock on…」というエラーを解決する方法を教えてください

Amazon EBSマウント時にUUIDの重複エラーが発生した時の解決方法を紹介します。
2020.05.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

困っていた内容

EC2で障害が発生し、サーバーにアクセスできなくなりました。

トラブルシュートのために、障害の起きたEC2インスタンスのAMIバックアップから新規EC2インスタンスを起動し、障害の起きたEC2インスタンスを停止してEBSをディタッチし、新しいEC2インスタンスにアタッチしました。

アタッチしたEBSをいざマウントしようとすると、エラーが発生します。

$ sudo mount -t xfs /dev/nvme1n1p1 /mnt/data
mount: /mnt/data: wrong fs type, bad option, bad superblock on /dev/nvme1n1p1, missing codepage or helper program, or other error.

/var/log/messagesを見ると、ファイルシステムでUUIDの重複エラーが発生しています。

$ sudo tail /var/log/messages
...
May  4 17:02:59 ip-172-31-13-195 kernel: XFS (nvme1n1p1): Filesystem has duplicate UUID 55da5202-8008-43e8-8ade-2572319d9185 - can't mount
...

どう対応すればいいの?

ブロックストレージEBSのスナップショットはddコマンドのコピーのように、ブロック単位で全く同じコピーが作成されます。

スナップショットに基づいて EBS ボリュームを作成すると、新しいボリュームは、スナップショットの作成に使用された元のボリュームの完全なレプリカとなります。

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSSnapshots.html

したがって、今回の様な操作を行うと、同じUUIDを持つ2つのファイルシステムを同時にマウントしようとしているため、"Filesystem has duplicate UUID" エラーが発生します。

$ lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0   8G  0 disk
├─nvme0n1p1   259:1    0   8G  0 part /
└─nvme0n1p128 259:2    0   1M  0 part
nvme1n1       259:3    0   8G  0 disk
├─nvme1n1p1   259:4    0   8G  0 part
└─nvme1n1p128 259:5    0   1M  0 part

$ sudo blkid
/dev/nvme0n1p1: LABEL="/" UUID="55da5202-8008-43e8-8ade-2572319d9185" TYPE="xfs" PARTLABEL="Linux" PARTUUID="591e81f0-99a2-498d-93ec-c9ec776ecf42"
/dev/nvme1n1p1: LABEL="/" UUID="55da5202-8008-43e8-8ade-2572319d9185" TYPE="xfs" PARTLABEL="Linux" PARTUUID="591e81f0-99a2-498d-93ec-c9ec776ecf42"
/dev/nvme0n1: PTUUID="83181c97-6d5e-43c9-9ede-e2f50ead5338" PTTYPE="gpt"
/dev/nvme0n1p128: PARTLABEL="BIOS Boot Partition" PARTUUID="4908ae49-9d5b-423e-a23c-a507a47bacf5"
/dev/nvme1n1: PTUUID="83181c97-6d5e-43c9-9ede-e2f50ead5338" PTTYPE="gpt"
/dev/nvme1n1p128: PARTLABEL="BIOS Boot Partition" PARTUUID="4908ae49-9d5b-423e-a23c-a507a47bacf5"

解決策は2種類あります

  1. 一時的なマウントのために、UUIDの重複を無視
  2. 永続的にマウントさせるために、新しいUUIDを割り当てる

1. 一時的にマウントするために、UUIDの重複を無視する

アタッチしたボリュームは一時的にマウントするためのものであり、本来のEC2にアタッチし直す場合は、このアプローチを採用します。

マウント時にUUIDの重複を無視するオプション(-o nouuid)を渡します。

$ sudo mount -t xfs -o nouuid /dev/nvme1n1p1 /mnt/data

$ lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0   8G  0 disk
├─nvme0n1p1   259:1    0   8G  0 part /
└─nvme0n1p128 259:2    0   1M  0 part
nvme1n1       259:3    0   8G  0 disk
├─nvme1n1p1   259:4    0   8G  0 part /mnt/data
└─nvme1n1p128 259:5    0   1M  0 part

2. 永続的にマウントするために、新しいUUIDを割り当てる

アタッチしたボリュームを永続的にマウントする場合は、このアプローチを採用します。

xfs_adminコマンドでファイルシステムに新規UUIDを割り当てた後でマウントします。

$ sudo xfs_admin -U generate /dev/nvme1n1p1
Clearing log and setting UUID
writing all SBs
new UUID = 7b690860-d330-4c6e-9727-46b3b92f7e25

$ sudo blkid
/dev/nvme1n1: PTUUID="83181c97-6d5e-43c9-9ede-e2f50ead5338" PTTYPE="gpt"
/dev/nvme1n1p1: LABEL="/" UUID="7b690860-d330-4c6e-9727-46b3b92f7e25" TYPE="xfs" PARTLABEL="Linux" PARTUUID="591e81f0-99a2-498d-93ec-c9ec776ecf42"
/dev/nvme1n1p128: PARTLABEL="BIOS Boot Partition" PARTUUID="4908ae49-9d5b-423e-a23c-a507a47bacf5"
/dev/nvme0n1: PTUUID="83181c97-6d5e-43c9-9ede-e2f50ead5338" PTTYPE="gpt"
/dev/nvme0n1p1: LABEL="/" UUID="55da5202-8008-43e8-8ade-2572319d9185" TYPE="xfs" PARTLABEL="Linux" PARTUUID="591e81f0-99a2-498d-93ec-c9ec776ecf42"
/dev/nvme0n1p128: PARTLABEL="BIOS Boot Partition" PARTUUID="4908ae49-9d5b-423e-a23c-a507a47bacf5"

新しいUUIDを割り当てたあとで、本来のEC2にアタッチし直す場合は注意が必要です。

/etc/fstab内でデバイス名 (/dev/xvdfなど)ではなくUUIDを使ってマウントしている場合、UUIDが変わったためにマウントに失敗します。

xfs_copyでコピーするとUUIDはどうなる?

XFSファイルシステムにはコピーに特化したxfs_copyコマンドが存在します。

このコマンドでファイルシステムをコピーすると、UUIDだけが異なるレプリカを作成します。

xfs_copy does not alter the source filesystem in any way. Each new (target) filesystem is identical to the original filesystem except that new filesystems each have a new unique filesystem identifier (UUID). Therefore, if both the old and new filesystems will be used as separate distinct filesystems, xfs_copy or xfsdump(8)/xfsrestore(8) should be used to generate the new filesystem(s) instead of dd(1) or other programs that do block-by-block disk copying.

https://linux.die.net/man/8/xfs_copy

関連情報