lvmcacheでCache LVドライブ障害からの復旧

## lvmcacheのcachepoolがあるドライブが死んだ。

Linux LVM2でlvmcache(dm-cache)をwritethroughモード(デフォルト）で使用している場合、cachepoolに使っているPVがあるドライブが死んでもファイルシステム復旧は可能。

ただしこの手順がlvmcacheなどのドキュメントに見当たらなかったので試行錯誤が必要だった。

### セットアップ

以下環境でテスト。
* Ubuntu 18.04 bionic + HWEカーネル 5.0.0-27
* LVM version:     2.02.176(2) (2017-11-03)

vgを作成。

```
root@ubuntu:~# pvcreate /dev/sdb1
root@ubuntu:~# pvcreate /dev/sdc1
root@ubuntu:~# vgcreate test-vg /dev/sdb1 /dev/sdc1
```

sdb1(fast)側にLV cacheを作成, sdc1(slow)側にLV originを作成し、cacheを有効化。

```
root@ubuntu:~# lvconvert --type cache --cachepool /dev/test-vg/cache /dev/test-vg/origin
root@ubuntu:~# lvs -a
  LV              VG        Attr       LSize   Pool    Origin         Data%  Meta%  Move Log Cpy%Sync Convert
  [cache]         test-vg   Cwi---C---   1.00g                        0.12   2.15            0.00
  [cache_cdata]   test-vg   Cwi-ao----   1.00g
  [cache_cmeta]   test-vg   ewi-ao----   8.00m
  [lvol0_pmspare] test-vg   ewi-------   8.00m
  origin          test-vg   Cwi-a-C---  10.00g [cache] [origin_corig] 0.12   2.15            0.00
  [origin_corig]  test-vg   owi-aoC---  10.00g
  root            ubuntu-vg -wi-ao---- <15.04g
  swap_1          ubuntu-vg -wi-ao---- 980.00m
```

障害やLocal SSDのワイプ後を想定して、sdbをVMからデタッチして起動。
PVが不足しているため`test-vg/origin`はアクティベーションされていない（aフラグがない）。device mapperから見えない、つまり`/dev/`には現れていない。

```
root@ubuntu:~# lvs -a
  WARNING: Device for PV jJVbPp-wu70-vM3y-4D0e-scWd-c20g-momBYa not found or rejected by a filter.
  LV              VG        Attr       LSize   Pool    Origin         Data%  Meta%  Move Log Cpy%Sync Convert
  [cache]         test-vg   Cwi---C-p-   1.00g
  [cache_cdata]   test-vg   Cwi-----p-   1.00g
  [cache_cmeta]   test-vg   ewi-------   8.00m
  [lvol0_pmspare] test-vg   ewi-------   8.00m
  origin          test-vg   Cwi---C-p-  10.00g [cache] [origin_corig]
  [origin_corig]  test-vg   owi---C---  10.00g
  root            ubuntu-vg -wi-ao---- <15.04g
  swap_1          ubuntu-vg -wi-ao---- 980.00m
```

### 復旧手順

復旧できた手順は
* `lvconvert --uncache OriginLV` で分解。この際CacheLVが削除される（通常の挙動）
* `vgreduce --removemissing` で消えたPVを削除。（後でいいけれどsdbが中途半端に復旧したりするとvg全体が壊れかねないので先にやっておく）
* `lvchange -a -y OriginLV` でdegradeしていたOriginLVをアクティベーション

これでマウントできるようになった。

作業ログ

```
root@ubuntu:~# lvconvert --uncache test-vg/origin
  WARNING: Device for PV jJVbPp-wu70-vM3y-4D0e-scWd-c20g-momBYa not found or rejected by a filter.
  WARNING: Cache pool data logical volume test-vg/cache_cdata is missing.
Do you really want to uncache test-vg/origin with missing LVs? [y/n]: y
Do you really want to remove and DISCARD logical volume test-vg/cache? [y/n]: y
  Logical volume "cache" successfully removed
  Logical volume test-vg/origin is not cached.

root@ubuntu:~# lvs
  WARNING: Device for PV jJVbPp-wu70-vM3y-4D0e-scWd-c20g-momBYa not found or rejected by a filter.
  LV     VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  origin test-vg   -wi-------  10.00g
  root   ubuntu-vg -wi-ao---- <15.04g
  swap_1 ubuntu-vg -wi-ao---- 980.00m

# エラーPVを排除しておく。これで万一sdbが戻ってきても安全のはず。もし他のLVがまだあるなら --force が必要
root@ubuntu:~# vgreduce --removemissing test-vg
  WARNING: Device for PV jJVbPp-wu70-vM3y-4D0e-scWd-c20g-momBYa not found or rejected by a filter.
  Wrote out consistent volume group test-vg.

# activateフラグが消えているので設定してdev mapperから見えるようにする。
root@ubuntu:~# lvchange -a y test-vg/origin
root@ubuntu:~# lvs
  LV     VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  origin test-vg   -wi-a-----  10.00g
  root   ubuntu-vg -wi-ao---- <15.04g
  swap_1 ubuntu-vg -wi-ao---- 980.00m


# /dev/に現れるのでマウント
root@ubuntu:~# mount /dev/test-vg/origin /mnt/test/

# 動作チェック
root@ubuntu:~# btrfs fi show
Label: none  uuid: 28a955fe-2075-4f57-9721-01ba194db356
        Total devices 1 FS bytes used 2.11GiB
        devid    1 size 15.04GiB used 3.77GiB path /dev/mapper/ubuntu--vg-root

Label: none  uuid: f670e05a-fa23-4835-86b2-715908d0a85b
        Total devices 1 FS bytes used 41.64MiB
        devid    1 size 10.00GiB used 1.27GiB path /dev/mapper/test--vg-origin
root@ubuntu:~# btrfs scrub start /mnt/test/
scrub started on /mnt/test/, fsid f670e05a-fa23-4835-86b2-715908d0a85b (pid=1442)
root@ubuntu:~# btrfs scrub status /mnt/test/
scrub status for f670e05a-fa23-4835-86b2-715908d0a85b
        scrub started at Fri Sep 13 11:47:33 2019 and finished after 00:00:00
        total bytes scrubbed: 41.64MiB with 0 errors
```



### 失敗例

以下は失敗。これではoriginが消されてしまう。

```
# lvconvert --splitcache /dev/test-vg/origin
  WARNING: Device for PV jJVbPp-wu70-vM3y-4D0e-scWd-c20g-momBYa not found or rejected by a filter.
  Cannot change VG test-vg while PVs are missing.
  Consider vgreduce --removemissing.
  Cannot process volume group test-vg

# vgreduce --removemissing test-vg
  WARNING: Device for PV jJVbPp-wu70-vM3y-4D0e-scWd-c20g-momBYa not found or rejected by a filter.
  WARNING: Partial LV origin needs to be repaired or removed.
  WARNING: Partial LV cache_cdata needs to be repaired or removed.
  WARNING: Partial LV cache_cmeta needs to be repaired or removed.
  WARNING: Partial LV cache needs to be repaired or removed.
  WARNING: Partial LV lvol0_pmspare needs to be repaired or removed.
  There are still partial LVs in VG test-vg.
  To remove them unconditionally use: vgreduce --removemissing --force.
  WARNING: Proceeding to remove empty missing PVs.

root@ubuntu:~# vgreduce --removemissing test-vg --force
  WARNING: Device for PV jJVbPp-wu70-vM3y-4D0e-scWd-c20g-momBYa not found or rejected by a filter.
  WARNING: Removing partial LV test-vg/origin.
  Logical volume "cache" successfully removed
  Logical volume "origin" successfully removed
  Wrote out consistent volume group test-vg.
```

### まとめ

* `lvconvert --splitcache` ではなく `lvconvert --uncache` を使う。
* lvmコマンドのメッセージに沿って盲目的に`vgreduce --removemissing --force`はダメ。（反省）

### 参考
* https://bugzilla.redhat.com/show_bug.cgi?id=1377850