Proxmox VE 6.2のZFSで故障したディスクを交換

# まえがき
余ったパーツの使いみち探しで__Proxmox__にたどり着いた。HDD4本のPCに__Proxmox VE 6.2__をZFSを選択してインストール。触り始めたら、すぐにHDD1台が故障。いきなり交換することになった。知識ゼロだったので、いろいろと調べる羽目に。。。　次回のHDD故障のときと知人のために、メモとして記録。
__注意：__家庭用にPCで遊んでいるおっさんが、ゼロ知識で行った作業のメモなので__大きく間違っている可能性があります__。「情報元」を確認するなどして自己防衛してください。

# 故障したディスクを特定する
Webインターフェイスの「**ノード**」→「**ディスク**」→「**ZFS**」でプールの一覧が表示される。正常なプールでは「状態」表示が**ONLINE**となる。問題が発生しているときは**DEGRADED**などの表示になる。
**DEGRADED**状態のプールを選択して「**詳細**」ボタンを押すと、そのプールを構成しているデバイス一覧が表示される。ここでも正常なデバイスの表示は**ONLINE**となる。**UNAVAIL**のような表示になっているものは故障しているので交換が必要になる。
別の方法として、Webインターフェイスの「**ノード**」→「**シェル**」、もしくはSSHでログインすることで、コマンドラインから故障したディスクを特定することもできる。`zpool status`コマンドでZFSのプールのステータスが表示される。

```
root@proxmox01:~# zpool status
  pool: rpool
 state: DEGRADED
status: One or more devices could not be used because the label is missing or
        invalid.  Sufficient replicas exist for the pool to continue
        functioning in a degraded state.
action: Replace the device using 'zpool replace'.
   see: http://zfsonlinux.org/msg/ZFS-8000-4J
  scan: resilvered 915M in 0 days 00:00:56 with 0 errors on Sun Aug 23 10:43:16 2020
config:

        NAME                                       STATE     READ WRITE CKSUM
        rpool                                      DEGRADED     0     0     0
          raidz1-0                                 DEGRADED     0     0     0
            ata-ST3000DM001-1CH166_Z1F3QAAA-part3  ONLINE       0     0     0
            ata-ST3000DM001-1CH166_W1F4HBBB-part3  ONLINE       0     0     0
            ata-ST3000DM001-1CH166_W1F4HCCC-part3  ONLINE       0     0     0
            7967839420105811388                    UNAVAIL      0     0     0  was /dev/disk/by-id/ata-ST3000DM001-1CH166_Z1F3RXXX-part3

errors: No known data errors
```

ここでは4つ目のデバイスである**ata-ST3000DM001-1CH166_Z1F3RXXX-part3**が認識されずに**UNAVAIL**になっている。
表示されるデバイス名は__/dev/sd*__の形式ではなく、インターフェイス、製品モデル名、ファームウェアのバージョン、シリアル番号、パーティションを**-**で連結したものになってるようだ。これらの情報からディスクを特定した。__ata-*__の形式と__/dev/sd*__の形式との関連性は`ls /dev/disk/by-id -ahl`コマンドで確認できる。

```
root@proxmox01:~# ls /dev/disk/by-id/ -ahl
== 中略 ==
lrwxrwxrwx 1 root root   9 Aug 23 10:56 ata-ST3000DM001-1CH166_Z1F3RXXX -> ../../sdd
== 中略 ==
```

今回は、SATAの4番目のポートに接続されている品名「__ST3000DM001__」、ファームウェアバージョン「__1CH166__」、シリアル番号「__Z1F3RXXX__」というハードディスクが交換対象だ。

# 故障したハードディスクを交換
交換すべきディスクが特定できたらシャットダウンして電源を切ったあとで、故障したハードディスクと新しいハードディスク（ここではシリアル番号「__Z1F3RYYY__」としておく）を交換した。

# パーティション情報を書き込む
ディスク交換後に電源をいれシステムが起動したら新しいディスクにパーティション情報を書き込む。コマンドは`sgdisk <正常なドライブのデバイス> -R <新しいドライブのデバイス>`になる（ここでのデバイスは__/dev/sda__のような形式）。今回は__/dev/sdd__を交換したので正常なデバイス__/dev/sda__から複製するのでコマンドは`sgdisk /dev/sda -R /dev/sdd`となる。

```
root@proxmox01:~# sgdisk /dev/sda -R /dev/sdd
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
```
### GUIDの書き込み
パーティション情報を書き込んだら、次にディスクとパーティションにGUIDをランダム生成して割り当てる。コマンドは`sgdisk -G <新しいドライブのデバイス>`になる（ここでのデバイスは__/dev/sda__のような形式）。

```
root@proxmox01:~# sgdisk -G /dev/sdd
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
```

変更したパーティション情報を反映させるために、システムを再起動する。


# ZFSプール上で新しいディスクを入れ替える
再起動後はコマンドラインで作業を続ける。
まず交換前のデバイス名と交換後デバイス名を調べておく。コマンドは`zpool status`と`ls /dev/disk/by-id -ahl`だ。

```
root@proxmox01:~# zpool status
  pool: rpool
 state: DEGRADED
== 中略 ==
            7967839420105811388                    UNAVAIL      0     0     0  was /dev/disk/by-id/ata-ST3000DM001-1CH166_Z1F3RXXX-part3
== 中略 ==
root@proxmox01:~# ls /dev/disk/by-id -ahl
== 中略 ==
lrwxrwxrwx 1 root root   9 Aug 23 11:10 ata-ST3000DM001-1CH166_Z1F3RYYY -> ../../sdd
lrwxrwxrwx 1 root root  10 Aug 23 11:10 ata-ST3000DM001-1CH166_Z1F3RYYY-part1 -> ../../sdd1
lrwxrwxrwx 1 root root  10 Aug 23 11:10 ata-ST3000DM001-1CH166_Z1F3RYYY-part2 -> ../../sdd2
lrwxrwxrwx 1 root root  10 Aug 23 11:10 ata-ST3000DM001-1CH166_Z1F3RYYY-part3 -> ../../sdd3
== 中略 ==
```

ここでは交換前デバイス名：__ata-ST3000DM001-1CH166_Z1F3RXXX-part3__、交換後デバイス名：__ata-ST3000DM001-1CH166_Z1F3RYYY-part3__、対象プール名：__rpool__になる。
プールのデバイスの交換コマンドは`zpool replace -f <対象のプール名> <交換前のデバイス名> <交換後のデバイス名>`だ。上記のデバイス名に置き換えると`zpool replace -f rpool ata-ST3000DM001-1CH166_Z1F3RXXX-part3 ata-ST3000DM001-1CH166_Z1F3RYYY-part3`となる。

```
root@proxmox01:~# zpool replace -f rpool /dev/disk/by-id/ata-ST3000DM001-1CH166_Z1F3RXXX-part3 ata-ST3000DM001-1CH166_Z1F3RYYY-part3
Make sure to wait until resilver is done before rebooting.
```

コマンド実行後、同期（resilvering）が始まる。途中経過はコマンド`zpool status -v`で確認できる。

```
root@proxmox01:~# zpool status -v
  pool: rpool
 state: DEGRADED
== 中略 ==
            replacing-3                              DEGRADED     0     0     0
              7967839420105811388                    UNAVAIL      0     0     0  was /dev/disk/by-id/ata-ST3000DM001-1CH166_Z1F3RXXX-part3
              ata-ST3000DM001-1CH166_Z1F3RYYY-part3  ONLINE       0     0     0  (resilvering)
== 中略 ==
```

同期が終了すると`zpool status -v`コマンドでステータスが__ONLINE__になる。

```
root@proxmox01:~# zpool status -v
  pool: rpool
 state: ONLINE
  scan: resilvered 916M in 0 days 00:00:58 with 0 errors on Sun Aug 23 11:15:30 2020
config:

        NAME                                       STATE     READ WRITE CKSUM
        rpool                                      ONLINE       0     0     0
          raidz1-0                                 ONLINE       0     0     0
            ata-ST3000DM001-1CH166_Z1F3QAAA-part3  ONLINE       0     0     0
            ata-ST3000DM001-1CH166_W1F4HBBB-part3  ONLINE       0     0     0
            ata-ST3000DM001-1CH166_W1F4HCCC-part3  ONLINE       0     0     0
            ata-ST3000DM001-1CH166_Z1F3RYYY-part3  ONLINE       0     0     0

errors: No known data errors
```


# ブートローダーを書き込む
最後に交換後のディスクにブートローダーを書き込む。
Proxmox 6.2 VEでは、パーティション2がESPになる（バージョン5.4以降のインストーラ）。
ESPへのフォーマットと初期化のコマンドは`pve-efiboot-tool format <交換後のドライブのESP> --force`と`pve-efiboot-tool init <交換後のドライブのESP> --force`だ。ここでは`pve-efiboot-tool format /dev/sdd2 --force`と`pve-efiboot-tool init /dev/sdd2 --force`となる。

```
root@proxmox01:~# pve-efiboot-tool init /dev/sdd2 --force
Re-executing '/usr/sbin/pve-efiboot-tool' in new private mount namespace..
UUID="1F9D-86CC" SIZE="536870912" FSTYPE="vfat" PARTTYPE="c12a7328-f81f-11d2-ba4b-00a0c93ec93b" PKNAME="sdd" MOUNTPOINT=""
Mounting '/dev/sdd2' on '/var/tmp/espmounts/1F9D-86CC'.
Installing systemd-boot..
Created "/var/tmp/espmounts/1F9D-86CC/EFI/systemd".
Created "/var/tmp/espmounts/1F9D-86CC/EFI/BOOT".
Created "/var/tmp/espmounts/1F9D-86CC/loader".
Created "/var/tmp/espmounts/1F9D-86CC/loader/entries".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/var/tmp/espmounts/1F9D-86CC/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/var/tmp/espmounts/1F9D-86CC/EFI/BOOT/BOOTX64.EFI".
Created EFI boot entry "Linux Boot Manager".
Configuring systemd-boot..
Unmounting '/dev/sdd2'.
Adding '/dev/sdd2' to list of synced ESPs..
Refreshing kernels and initrds..
Running hook script 'pve-auto-removal'..
Running hook script 'zz-pve-efiboot'..
Copying and configuring kernels on /dev/disk/by-uuid/1F9D-86CC
        Copying kernel and creating boot-entry for 5.4.44-2-pve
Copying and configuring kernels on /dev/disk/by-uuid/FF9A-8A44
        Copying kernel and creating boot-entry for 5.4.44-2-pve
Copying and configuring kernels on /dev/disk/by-uuid/FF9B-5B5B
        Copying kernel and creating boot-entry for 5.4.44-2-pve
Copying and configuring kernels on /dev/disk/by-uuid/FF9C-1CA2
        Copying kernel and creating boot-entry for 5.4.44-2-pve
WARN: /dev/disk/by-uuid/FF9C-D922 does not exist - clean '/etc/kernel/pve-efiboot-uuids'! - skipping
```

最後に警告が出た。ファイル`/etc/kernel/pve-efiboot-uuids`に、交換前のディスクのUUID（ここではFF9C-D922）が残っていたためだ。ファイルを__vi__や__nano__で編集して、不要になったUUIDを削除しておくと良さそう。


# 情報元
情報元というか、そのまま使えた。
__本家の文書__
https://pve.proxmox.com/pve-docs/chapter-sysadmin.html#_zfs_administration
__本家フォーラムでの質問__
https://forum.proxmox.com/threads/replacing-bad-disk-on-zfs-rpool-uefi.70564/