Linuxで既存の単一ドライブを新しいドライブとミラーリングする

#概要
###はじめに
本稿では、Linux(筆者環境ではopenSUSE)環境にて**既存HDD/SSDのデータを保ったまま**新しいHDD/SSDとRAID1(ミラーリング)を行う際の方法を紹介します。
作成するRAIDアレイからブートする場合は追加の手順が必要になるのでご注意ください(末尾のURL参照)。
**※必要に応じてバックアップを取った上で、自己責任で実行してください。**

###この記事での前提
- 起動用SSD：`/dev/nvme0n1`
- 既存のHDD：`/dev/sda`
    - 既存のパーティション：`/dev/sda1`
- 新しいHDD：`/dev/sdb`
    - 中身は空(後に`/dev/sdb1`を作成)
- 作成するRAIDアレイ：`/dev/md0`
    - `/dev/sda1`と`/dev/sdb1`でRAID1

必要に応じて読み替えてください。

###大まかな流れ
1. `/dev/sdb1`だけで(ペアが存在しない状態で)、2台で構成されるRAID1アレイ(`/dev/md0`)を作る

2. `/dev/sda1`の中身を`/dev/md0`にコピーする

3. アレイに`/dev/sda1`を追加(して再構築)

#本題
###空のドライブにパーティションを作る
まず、空のドライブにパーティションを作成します。
`lsblk`コマンドで対象のドライブを確認しておくと安心です。

```
$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0   2.7T  0 disk
└─sda1        8:1    0   2.7T  0 part /srv/samba
sdb           8:16   0   2.7T  0 disk
nvme0n1     259:0    0 119.2G  0 disk
├─nvme0n1p1 259:1    0   100G  0 part /
├─nvme0n1p2 259:2    0    10G  0 part [SWAP]
└─nvme0n1p3 259:3    0   9.3G  0 part /boot/efi
```

`/dev/sdb`が空のドライブなので、今回はここにパーティションを作成します。
今回は`gdisk`コマンドを用います。パーティションタイプがLinux RAID(FD00)になるようにしてください。

```
 # gdisk
GPT fdisk (gdisk) version 1.0.1

Type device filename, or press <Enter> to exit: /dev/sdb
Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help): n
Partition number (1-128, default 1):
First sector (34-5860533134, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-5860533134, default = 5860533134) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): FD00
Changed type of partition to 'Linux RAID'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.
```

これで`/dev/sdb`上に`/dev/sdb1`が作成されます。

```
$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0   2.7T  0 disk
└─sda1        8:1    0   2.7T  0 part /srv/samba
sdb           8:16   0   2.7T  0 disk
└─sdb1        8:17   0   2.7T  0 part
nvme0n1     259:0    0 119.2G  0 disk
├─nvme0n1p1 259:1    0   100G  0 part /
├─nvme0n1p2 259:2    0    10G  0 part [SWAP]
└─nvme0n1p3 259:3    0   9.3G  0 part /boot/efi
```

###RAIDアレイの作成
先程作成した`/dev/sdb1`のみで2台を前提とするRAIDアレイを作成します。

```
# mdadm --create /dev/md0 --level=1 --raid-devices=2 missing /dev/sdb1
```

起動ドライブ(`/boot`のあるパーティション)に対して行う場合は…という趣旨のメッセージが表示されますが、今回は当てはまらないので無視します。

また、RAIDアレイが正常に作成されたことを確認するため`/proc/mdstat`の内容をチェックしておくと良いでしょう。

```
$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb1[1]
      2930133440 blocks super 1.2 [2/1] [_U]
      bitmap: 22/22 pages [88KB], 65536KB chunk

unused devices: <none>
```

作成した`/dev/md0`にファイルシステムを作成します。以下はext4での例です。

```
# mke2fs -t ext4 /dev/md0
```

###既存のドライブの内容をコピーする
まず、`/dev/md0`をマウントします。今回は`/mnt/md0`にマウントします。

```
# mkdir /mnt/md0
# mount /dev/md0 /mnt/md0
```
次に、rsyncコマンドを用いて既存のドライブの内容をコピーします。
既存のドライブ(`/dev/sda`上のパーティション`/dev/sda1`)が`/mnt/sda1`にマウントされている場合は以下のようにします。

```
# rsync -aAXv /mnt/sda1 /mnt/md0
```
終わったら、それぞれをアンマウントします。

```
# umount /dev/md0 /dev/sda1
```

問題なくアンマウントできたら、新しいドライブのパーティションテーブルを既存のドライブにコピーして同じレイアウトになるようにします。

```
# sfdisk -d /dev/sdb | sfdisk /dev/sda
Checking that no-one is using this disk right now ... OK

Disk /dev/sda: 2.7 TiB, 3000592982016 bytes, 5860533168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: FB0EFFBE-DF23-4332-BF9E-4057533D2DB1

Old situation:

Device     Start        End    Sectors  Size Type
/dev/sda1   2048 5860532223 5860530176  2.7T Microsoft basic data

>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Script header accepted.
>>> Created a new GPT disklabel (GUID: 781FB817-61D9-4452-BE5C-3D176B1F5EB7).
/dev/sda1: Created a new partition 1 of type 'Linux RAID' and of size 2.7 TiB.
Partition #1 contains a ext4 signature.
/dev/sda2: Done.

New situation:
Disklabel type: gpt
Disk identifier: 781FB817-61D9-4452-BE5C-3D176B1F5EB7

Device     Start        End    Sectors  Size Type
/dev/sda1   2048 5860533134 5860531087  2.7T Linux RAID

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
```

念の為、同じレイアウトになっているか確認しておくと良いでしょう。

```
# fdisk -l
(中略)

Device     Start        End    Sectors  Size Type
/dev/sda1   2048 5860533134 5860531087  2.7T Linux RAID

(中略)

Device     Start        End    Sectors  Size Type
/dev/sdb1   2048 5860533134 5860531087  2.7T Linux RAID

(中略)
```

次に、RAIDアレイに既存のドライブを追加します。

```
# mdadm /dev/md0 -a /dev/sda1
mdadm: added /dev/sda1
```

`/proc/mdstat`の内容を確認して、再構築が行われていることを確認しましょう。

```
# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sda1[2] sdb1[1]
      2930133440 blocks super 1.2 [2/1] [_U]
      [>....................]  recovery =  0.1% (3984384/2930133440) finish=342.7min speed=142299K/sec
      bitmap: 22/22 pages [88KB], 65536KB chunk

unused devices: <none>
```

必要に応じて`/dev/md0`をマウントすることでアクセスできるようになります。

#参考URL
[シングルドライブ環境を RAID に変換 - ArchWiki](https://wiki.archlinux.jp/index.php/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E7%92%B0%E5%A2%83%E3%82%92_RAID_%E3%81%AB%E5%A4%89%E6%8F%9B#.E3.82.B7.E3.83.8A.E3.83.AA.E3.82.AA)