mdadm RAID1 入れ替えディスク

#背景
Linuxで、ソフトウェアRAIDを運用いています。たまに、ハードディスクが壊れます。あるいは、そろそろ新品と入れ替えたいと思ったりします。
そのときの手順を記録しておきます

#ポイント
- 新しいHDDへ、現行のパーティションテーブルを移行
- HDDを初期化
- mdadmを使って、現行RAID構成へ追加
- 追加ディスクでも起動するためのおまじない祈祷

#新しいHDDへ、現行のパーティションテーブルを移行
いろいろな情報ですと、"sgdisk"を使え、と出てきます。
これが使えるのは、新しいディスク容量が、現行のディスク容量よりも多い場合のみです。もし、小さいまま使うと、容量不足でエラーが返ってきます。
そのため、ここでは、partedを利用して、ベタにセクター情報を書き込みます。

```
$ sudo sgdisk /dev/sda -R /dev/sdb

***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. 
***************************************************************


Warning! Secondary partition table overlaps the last partition by
33 blocks!
You will need to delete this partition or resize it in another utility.
Caution! Secondary header was placed beyond the disk's limits! Moving the
header, but other problems may occur!

Warning! Secondary partition table overlaps the last partition by
34 blocks!
You will need to delete this partition or resize it in another utility.

Problem: partition 2 is too big for the disk.
Aborting write operation!
Aborting write of new partition table.
```
partitionがでかすぎるぜぇ、と怒られて、中断しています。
もともと、現行HDDも追加購入のHDDも、Seagateの2.5inch 2.0Tです。ただ、現行は内蔵、追加購入はUSB3.0接続です。このため、微妙に差異があるようです。(現行の方が1セクター多い)

```txt:ST2000LM015-2E8174
sd 1:0:0:0: [sda] 3907029168 512-byte logical blocks: (2.00 TB/1.81 TiB)
```

```txt:ST2000LM015-2E81
sd 6:0:0:0: [sdb] 3907029167 512-byte logical blocks: (2.00 TB/1.81 TiB)
```


そこで、sgdiskをあきらめて、partedで続けます。
コピー元(/dev/sda)の情報を確認します。

```text:
$sudo parted /dev/sda
GNU Parted 2.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p                                                                
Model: ATA ST2000LM015-2E81 (scsi)
Disk /dev/sda: 2000GB
Sector size (logical/physical): 512B/4096B
Partition Table: msdos

Number  Start   End     Size    Type     File system  Flags
 1      1049kB  214MB   213MB   primary  ext4         boot
 2      214MB   2000GB  2000GB  primary  ext4

(parted) u                                                                
Unit?  [compact]? s                                                       
(parted) p                                                                
Model: ATA ST2000LM015-2E81 (scsi)
Disk /dev/sda: 3907029168s
Sector size (logical/physical): 512B/4096B
Partition Table: msdos

Number  Start    End          Size         Type     File system  Flags
 1      2048s    417791s      415744s      primary  ext4         boot
 2      417792s  3907029167s  3906611376s  primary  ext4

(parted) q                                                                
```
セクタ情報が重要です。どこかにメモしておきましょう。
上の操作にあるように、単位がサイズで表示されると、意味がない(新旧とも2000Gになってします)ので、sectorに変える必要がります。コマンドは、Unit -> Sector の頭文字(U/S)を入力し、操作しています。

続いて、コピー先の操作です。

```
$ sudo parted /dev/sdb
GNU Parted 2.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p                                                                
Model: Seagate Expansion (scsi)
Disk /dev/sdb: 2000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name  Flags
 1      33.6MB  503MB   470MB   fat32              raid
 2      503MB   2000GB  2000GB  ext4               raid
```
いまのpartition tableです。先のsgdiskのゴミではなく、別に使っていたテーブルが見えています。

単位がセクタではないので、変更します。

```
(parted) u                                                                
Unit?  [compact]? c                                                       
parted: invalid token: c
Unit?  [compact]? s                                                       
(parted) p                                                                
Model: Seagate Expansion (scsi)
Disk /dev/sdb: 3907029167s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start    End          Size         File system  Name  Flags
 1      65535s   983024s      917490s      fat32              raid
 2      983025s  3907000094s  3906017070s  ext4               raid
```
表示単位がセクタになったので、これら、いらないpartitionを削除します。

```
(parted) rm
Partition number? 2
(parted) rm 1
(parted) p
Model: Seagate Expansion (scsi)
Disk /dev/sdb: 2000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start  End  Size  File system  Name  Flags
(parted)                                                          
```
無事に削除できたことが確認できます。
次に、partitionの追加です。

```
(parted) mkpart 
Partition name?  []?                                                      
File system type?  [ext2]? ext4                                           
Start? 2048s                                                              
End? 417791s                                                              
(parted) p                                                                
Model: Seagate Expansion (scsi)
Disk /dev/sdb: 3907029167s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start  End      Size     File system  Name  Flags
 1      2048s  417791s  415744s
```
1つ目。うちでは、/boot用です。

```
(parted) mkpart                                                           
Partition name?  []?                                                      
File system type?  [ext2]? ext4                                           
Start? 417792s                                                            
End? 100%                                                                 
(parted) p                                                                
Model: Seagate Expansion (scsi)
Disk /dev/sdb: 3907029167s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start    End          Size         File system  Name  Flags
 1      2048s    417791s      415744s
 2      417792s  3907028991s  3906611200s
```
2つ目は、先頭さえ決めれば、あとは100%で行けます。(End? 100% となっているところ)

これで、partitionテーブルの設定は完了です。

#HDDを初期化
mkfsをかます工程になります。難しいことはありません。今回は、2つともext4なので、fsck.ex4で初期化します。

1つ目。

```
$ sudo mkfs.ext4 /dev/sdb1
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
52000 inodes, 207872 blocks
10393 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
26 block groups
8192 blocks per group, 8192 fragments per group
2000 inodes per group
Superblock backups stored on blocks: 
	8193, 24577, 40961, 57345, 73729, 204801

Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
```
2つめ。

```
$ sudo mkfs.ext4 /dev/sdb2
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
122085376 inodes, 488326400 blocks
24416320 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
14903 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 
	102400000, 214990848

Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 33 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
```

#mdadmを使って、現行RAID構成へ追加
mdadmにて、raid1へ登録します。オプションは、manageとaddになります。
- manage: 現行のraidを指定
- add: 追加したいデバイスを指定
ここでは、md0とmd1を現行のraidとして使用しています。/dev/sdbXが追加したいデバイスです。

```
$ sudo mdadm --manage /dev/md0 --add /dev/sdb1
mdadm: added /dev/sdb1
$ cat /proc/mdstat 
Personalities : [raid1] 
md0 : active raid1 sdb1[2] sda1[3]
      207856 blocks super 1.0 [2/1] [U_]
      [>....................]  recovery =  2.7% (6016/207856) finish=3.3min speed=1002K/sec
      
md1 : active raid1 sda2[2]
      1953304576 blocks super 1.1 [2/1] [U_]
      
unused devices: <none>

$ sudo mdadm --manage /dev/md1 --add /dev/sdb2
mdadm: added /dev/sdb2
$ cat /proc/mdstat 
Personalities : [raid1] 
md0 : active raid1 sdb1[2] sda1[3]
      207856 blocks super 1.0 [2/2] [UU]
      
md1 : active raid1 sdb2[3] sda2[2]
      1953304576 blocks super 1.1 [2/1] [U_]
      [==>..................]  recovery = 13.3% (261306496/1953304576) finish=262.5min speed=107411K/sec
      
unused devices: <none>
```
うちの環境ですと、2.0T追加完了まで5時間ほどかかるので、しばらく放置です。

#追加したディスクでも起動できる設定
上記操作だけだと、追加したディスクでは、起動しません。MBRに正しい情報が書かれていないためです。
ここでは、grubを利用して、起動可能な状態に持っていきます。
grubを起動して、次の2コマンドを投入します。
-  root (hd1,0)
-  setup (hd1)
新しいディスクが、/dev/sdb ケースで、(hd1,0)になります。

```
# grub /dev/sdb
Probing devices to guess BIOS drives. This may take a long time.


    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]
grub> root (hd1,0)
root (hd1,0)
 Filesystem type is ext2fs, partition type 0x83
grub> setup (hd1)
setup (hd1)
 Checking if "/boot/grub/stage1" exists... no
 Checking if "/grub/stage1" exists... yes
 Checking if "/grub/stage2" exists... yes
 Checking if "/grub/e2fs_stage1_5" exists... yes
 Running "embed /grub/e2fs_stage1_5 (hd1)"... failed (this is not fatal)
 Running "embed /grub/e2fs_stage1_5 (hd1,0)"... failed (this is not fatal)
 Running "install /grub/stage1 (hd1) /grub/stage2 p /grub/grub.conf "... succeeded
Done.
grub> quit
quit
```

なお、これらのコマンドは、Centos 6.9で実行しています。