【ubuntu】LVMの再帰的な利用法とファイルシステムのコピーとBCACHE

論理ボリュームの管理がパーティーションに比べて楽なLVM。
パーティーションをPV（物理ボリューム）に設定して、VG（ボリュームグループ）にまとめ、LV（論理ボリューム）に切り出すやりかたで、必要とあらばVGに新しいPVを登録して拡張することも、LVのサイズを拡大・縮小することもできます。

ところで、LVを新しくPVに設定して、別のVGに登録できるというのは知っていますか？

LVMの設定をちょっと変えるだけでそれが可能なのです。

# LVMの再帰的な利用法
```diff_conf:/etc/lvm/lvm.conf
        # Configuration option devices/scan_lvs.
        # Scan LVM LVs for layered PVs, allowing LVs to be used as PVs.
        # When 1, LVM will detect PVs layered on LVs, and caution must be
        # taken to avoid a host accessing a layered VG that may not belong
        # to it, e.g. from a guest image. This generally requires excluding
        # the LVs with device filters. Also, when this setting is enabled,
        # every LVM command will scan every active LV on the system (unless
        # filtered), which can cause performance problems on systems with
        # many active LVs. When this setting is 0, LVM will not detect or
        # use PVs that exist on LVs, and will not allow a PV to be created on
        # an LV. The LVs are ignored using a built in device filter that
        # identifies and excludes LVs.
-        scan_lvs = 0
+        scan_lvs = 1
```

lvm.confのdevices {}内にある*scan_lvs*=0、これを1に変更するだけで、再帰的な構造が作れます。

うちの環境ですが、PVのリストがこうなっています。

```shell-session
$ sudo pvs
  PV             VG   Fmt  Attr PSize    PFree   
  /dev/main/boot boot lvm2 a--   <10.00g   <5.50g
  /dev/sda5      main lvm2 a--   <20.00g   <6.00g
  /dev/sdb3      main lvm2 a--  <500.00g <294.00g
```

VG bootが使っているPVが/dev/main/bootになっています。
これはVG main内に作ったbootというLVのことを指しています。
*pvcreate /dev/main/boot*でPV化しました。
VG mainではルートファイルシステムを、VG bootでは/bootを格納しています。
ルートファイルシステムと/bootは関連性が高いのでVG bootをVG mainの中に入れ子にしています。

```shell-session
$ sudo lvs -o +devices main/boot
  LV   VG   Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert Devices     
  boot main -wi-ao---- 10.00g                                                     /dev/sdb3(0)
```
今は/dev/main/bootをハードディスクである/dev/sdb3に置いてありますが、必要ならSSDの/dev/sda5に移動することも可能です。

# bcacheデバイスの作り方（１）

bcacheはLVM cacheと並ぶ、HDDをSSDでキャッシュする手段です。

bcacheを扱うためには*bcache-tools*をインストールする必要があります。

```shell-session
$ sudo apt install bcache-tools
```

一組のSSD/HDDペアを作る方法は簡単です。

```shell-session
$ sudo make-bcache -B /dev/hdd -C /dev/ssd
```

これだけでbcache0デバイスが作られ、キャッシュパーティーションのアタッチも自動でやってくれます。
後は/dev/bcache0にファイルシステムを作るだけです。
# ファイルシステムのコピー

これからbcache0デバイスを起動ドライブにしようとするわけですが、そのためには/bootに割り当てるデバイスと、ファイルシステムのコピーが必要になります。
面倒なのでLVを作ってサクッとやっちゃいましょう。

bcache0デバイスに入れたいファイルシステムとは別のlinuxファイルシステムから立ち上げます。
ライブCDから操作することも可能です。
以下のコマンドを実行して、bcache関連のコマンドをインストールします。
```shell-session
$ sudo apt install bcache-tools
```

そして、LVをサクサクと作ります。

```shell-session
$ sudo lvcreate -n new -L 60G main /dev/hdd
$ sudo lvcreate -n new -L 1G boot /dev/hdd
$ sudo lvcreate -n new-cache -L 5G main /dev/ssd
$ sudo make-bcache -B /dev/main/new -C /dev/main/new-cache
$ sudo mkfs.ext4 /dev/bcache0
$ sudo mkfs.ext4 /dev/boot/new 
```

これでファイルシステムのフォーマットまで終わりました。
続いて、既存のファイルシステムをマウントします。

```shell-session
$ sudo mkdir /mnt/{from,to}
$ sudo mount /dev/main/old /mnt/from
$ sudo mount /dev/boot/old /mnt/from/boot
$ sudo mount /dev/bcache0 /mnt/to
$ sudo mkdir /mnt/to/boot
$ sudo mount /dev/boot/new /mnt/to/boot
```
新旧のファイルシステムのマウントが終了しました。
後はコピーするだけです。

```shell-session
$ sudo rsync -ahHv /mnt/from/* /mnt/to
```

rsyncで古いファイルシステムから新しいファイルシステムへファイル／ディレクトリをコピーします。

コピーが終わったら、bcache0から起動するための準備を行います。
まずは特殊なディレクトリを/mnt/toにマウントした後、chrootします。

```shell-session
$ for fs in {sys,proc,dev};do sudo mount --rbind /$fs /mnt/to/$fs;done
$ sudo chroot /mnt/to
```

bcache0デバイスのuuidをコピーします。

```shell-session
# ls /dev/bcache/by-uuid/ -l |grep bcache
lrwxrwxrwx 1 root root 13  9月  2 19:24 2836f23c-1162-45cf-847f-ff062c4cb511 -> ../../bcache0
```

/etc/fstabを書き換えます。
/にマウントするデバイスは、複数のbcacheデバイスを作った時にナンバリングが入れ替わってしまうことがあるので、さきほどコピーしたuuidの入ったデバイス名を使います。

```config:/etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/dev/bcache/by-uuid/2836f23c-1162-45cf-847f-ff062c4cb511  /               ext4    errors=remount-ro 0       1
/dev/boot/new /boot           ext4    defaults        0       2
/swapfile        none            swap    sw              0       0
```

grubデータを書き換え、grubを物理デバイスにインストールします。

```shell-session
# update-grub
# grub-install /dev/hdd
# exit
```
これでbcache0デバイスから起動させる手順が終了しました。
# bcacheデバイスの作り方（2）

ここでは、2つのファイルシステムでキャッシュを共有する方法を紹介します。
新しくバッキングデバイスを作ります。

```shell-session
$ sudo lvcreate -n new2 -L 60G main
$ make-bcache -B /dev/main/new2
```

キャッシュデバイスのuuidをコピーします。
```shell-session
$ sudo bcache-super-show /dev/main/new-cache |grep cset
cset.uuid		5b3540df-5a65-4cbe-8d07-5e149460cf45
```

キャッシュデバイスをbcache1にアタッチします。
sudoでechoを使ってファイルに書き込むのがちょっとめんどくさいので、sudo -iで管理者モードに移行します。

```shell-session
$ sudo -i
# echo 5b3540df-5a65-4cbe-8d07-5e149460cf45> /sys/block/bcache1/bcache/attach
```

管理者モードにしない場合は、teeという標準入力をファイルと標準出力に出力するコマンドを使って、こう書きます。

```shell-session
$ echo 5b3540df-5a65-4cbe-8d07-5e149460cf45| sudo tee /sys/block/bcache1/bcache/attach
```
ちゃんとアタッチできているか確認してみましょう。
```shell-session
$ ls /sys/block/bcache1/bcache/dev/slaves/
dm-13  dm-21
$ ls /dev/main -l |grep dm-21
lrwxrwxrwx 1 root root 8  9月  2 20:17 new2 -> ../dm-21
$ ls /dev/main -l |grep dm-13
lrwxrwxrwx 1 root root 8  9月  2 19:24 new-cache -> ../dm-13
```

キャッシュのデタッチはこうです。
```shell-session
$ echo 5b3540df-5a65-4cbe-8d07-5e149460cf45| sudo tee /sys/block/bcache1/bcache/detach
```
キャッシュする対象の上限は/sys/block/bcacheN/bcache/sequential_cutoffに格納されています。
これに0を書き込むことで上限を外すことができます。

```shell-session
$ cat /sys/block/bcache1/bcache/sequential_cutoff 
4.0M
$ echo 0 | sudo tee /sys/block/bcache1/bcache/sequential_cutoff 
0
```

キャッシュを解放する場合。

```shell-session
$ echo 1|sudo tee /sys/fs/bcache/5b3540df-5a65-4cbe-8d07-5e149460cf45/stop
```

キャッシュの内容を消去する場合は以下のコマンドです。

```shell-session
$ sudo wipefs -a /dev/main/new-cache
```