LVM2でRAID5

# 概要
mdadmを使用せず、LVM2のRAID機能を使用したRAID5論理ボリュームをループバックデバイスを用いて構築します。

# 構築環境
| 項目 | 詳細  |
|:----:|:-----:|
| OS | Gentoo Linux |
| initシステム | Systemd |
| LVM2 バージョン | 2.02.145-r2 |
| RAID5 ファイルシステム | XFS |

# 準備
各種ツールのインストール

```
# emerge lvm2 xfsprogs
# systemctl start lvm2-lvmetad
```

ループバックデバイスの作成

```
# mkdir /tmp/img
# cd /tmp/img
# dd if=/dev/zero of=./img128_0 bs=1M count=128
# dd if=/dev/zero of=./img128_1 bs=1M count=128
# dd if=/dev/zero of=./img128_2 bs=1M count=128
# dd if=/dev/zero of=./img256_0 bs=1M count=256
# dd if=/dev/zero of=./img256_1 bs=1M count=256
# losetup /dev/loop0 ./img128_0
# losetup /dev/loop1 ./img128_1
# losetup /dev/loop2 ./img128_2
# losetup /dev/loop3 ./img256_0
# losetup /dev/loop4 ./img256_1
```

# RAID5構築
論理ボリューム割り当てポリシー(*allocation policy* )に **cling** を用いてRAID5の論理ボリュームを構築します。**cling** では *lvextend* コマンドで論理ボリュームを拡張する際に、同じタグのついた物理ボリュームでサブ論理ボリュームを拡張します。したがって、同一の物理ボリュームに複数のサブ論理ボリュームが割り当てられなくなります。

## 物理ボリュームの作成

```
# pvcreate /dev/loop[0-2]
```

## ボリュームグループの作成

```
# vgcreate vg00 /dev/loop[0-2]
```

## cling用タグ付け

```
# pvchange --addtag raid5_0 /dev/loop0
# pvchange --addtag raid5_1 /dev/loop1
# pvchange --addtag raid5_2 /dev/loop2
# nano -w /etc/lvm/lvm.conf
```
*allocation* セクションの *cling_tag_list* を以下の様に設定 

``` text:/etc/lvm/lvm.conf
allocation {
	cling_tag_list = [ "@raid5_0", "@raid5_1", "@raid5_2" ]
}
```

タグの確認方法

```
# pvs -a -o +pv_tags /dev/loop[0-2]
  PV         VG   Fmt  Attr PSize   PFree   PV Tags
  /dev/loop0 vg00 lvm2 a--  124.00m 124.00m raid5_0
  /dev/loop1 vg00 lvm2 a--  124.00m 124.00m raid5_1
  /dev/loop2 vg00 lvm2 a--  124.00m 124.00m raid5_2
```

## RAID5構築
```
# lvcreate --alloc cling --type raid5 -i 2 -l 100%FREE -n r5 vg00 @raid5_0 @raid5_1 @raid5_2
# mkfs.xfs /dev/vg00/r5
```
*lvcreate* の最後のタグ指定は特に必要ありませんが他の物理ボリュームがあった場合、誤って別の物理ボリュームに作成される可能性があるため、指定したほうが無難です。

| パラメータ | 詳細 |
|:----:|:----:|
| --alloc | *allocation policy* を指定<br>**cling**
| --type | *segment type* を指定<br>RAID5を作るので**raid5** |
| -i | *stripes* を指定<br>**2**：3個の物理ボリュームを使ってRAID5を構築<br>**3**：4個の物理ボリュームを使ってRAID5を構築 |
| -L | 論理ボリュームのサイズ |
| -n | 論理ボリューム名 |

# デバイスの交換
*/dev/loop[0-1]* を容量の大きなデバイス */dev/loop[3-4]* と交換します。

## 新しい物理ボリュームの準備
```
# pvcreate /dev/loop[3-4]
# vgextend vg00 /dev/loop[3-4]
# pvchange --addtag raid5_0 /dev/loop3
# pvchange --addtag raid5_1 /dev/loop4
```

## 物理ボリュームの交換
*/dev/loop0* を */dev/loop3* に交換します。

```
# lvconvert --replace /dev/loop0 vg00/r5 /dev/loop3
# pvchange --deltag raid5_0 /dev/loop0
```
[同期](#同期の進捗率確認)が完了したら、*/dev/loop1* を */dev/loop4* に交換します。

```
# lvconvert --replace /dev/loop1 vg00/r5 /dev/loop4
# pvchange --deltag raid5_1 /dev/loop1
```

## 容量の拡張
*/dev/loop2* と上記で交換した */dev/loop0* を束ねて容量の拡張を行ないます。
ここで、論理ボリューム割り当てポリシー(*allocation policy* )の **cling** 効果が発揮されます。  

現状確認

```
# pvs -a -o +pv_tags /dev/loop[0-4]
  PV         VG   Fmt  Attr PSize   PFree   PV Tags
  /dev/loop0 vg00 lvm2 a--  124.00m 124.00m
  /dev/loop1 vg00 lvm2 a--  124.00m 124.00m
  /dev/loop2 vg00 lvm2 a--  124.00m      0  raid5_2
  /dev/loop3 vg00 lvm2 a--  252.00m 128.00m raid5_0
  /dev/loop4 vg00 lvm2 a--  252.00m 128.00m raid5_1
```

タグ設定  
*/dev/loop2* と同じタグを */dev/loop0* に設定します。

```
# pvchange --addtag raid5_2 /dev/loop0
# pvs -a -o +pv_tags /dev/loop[0-4]
  PV         VG   Fmt  Attr PSize   PFree   PV Tags
  /dev/loop0 vg00 lvm2 a--  124.00m 124.00m raid5_2
  /dev/loop1 vg00 lvm2 a--  124.00m 124.00m
  /dev/loop2 vg00 lvm2 a--  124.00m      0  raid5_2
  /dev/loop3 vg00 lvm2 a--  252.00m 128.00m raid5_0
  /dev/loop4 vg00 lvm2 a--  252.00m 128.00m raid5_1
```
容量拡張

```
# lvextend --alloc cling -r -l +100%FREE vg00/r5
# pvs -a -o +pv_tags /dev/loop[0-4]
  PV         VG   Fmt  Attr PSize   PFree   PV Tags
  /dev/loop0 vg00 lvm2 a--  124.00m      0  raid5_2
  /dev/loop1 vg00 lvm2 a--  124.00m 124.00m
  /dev/loop2 vg00 lvm2 a--  124.00m      0  raid5_2
  /dev/loop3 vg00 lvm2 a--  252.00m   4.00m raid5_0
  /dev/loop4 vg00 lvm2 a--  252.00m   4.00m raid5_1

# lvs -a -o name,devices,seg_le_ranges
  LV            Devices                                      PE Ranges
  r5            r5_rimage_0(0),r5_rimage_1(0),r5_rimage_2(0) r5_rimage_0:0-60 r5_rimage_1:0-60 r5_rimage_2:0-60
  [r5_rimage_0] /dev/loop3(1)                                /dev/loop3:1-61
  [r5_rimage_1] /dev/loop4(1)                                /dev/loop4:1-61
  [r5_rimage_2] /dev/loop2(1)                                /dev/loop2:1-30
  [r5_rimage_2] /dev/loop0(0)                                /dev/loop0:0-30
  [r5_rmeta_0]  /dev/loop3(0)                                /dev/loop3:0-0
  [r5_rmeta_1]  /dev/loop4(0)                                /dev/loop4:0-0
  [r5_rmeta_2]  /dev/loop2(0)                                /dev/loop2:0-0
```
上記の様に、*/dev/loop0* と */dev/loop2* が束ねられて、*/dev/loop3* と */dev/loop4* の **PFree** が減って新たに割り当てられたことがわかります。また、 *-r* オプションを付けることで自動でファイルシステム(XFS)の拡張も行われます。


# 同期の進捗率確認

```
# lvs -a -o name,sync_percent
  LV            Cpy%Sync
  r5            100.00
  [r5_rimage_0]
  [r5_rimage_1]
  [r5_rimage_2]
  [r5_rmeta_0]
  [r5_rmeta_1]
  [r5_rmeta_2]
```
*Cpy%Sync* 項目が進捗率になります。

# その他
物理ボリュームに障害が発生した後の復旧方法は[LVM - Gentoo Wiki](https://wiki.gentoo.org/wiki/LVM/ja#Striping_with_parity_.28RAID4_and_RAID5.29)を参照。