(2014.11)
Red Hat Enterprise Linux 6.3から, LVM がRAID logical volumeをサポートした。RHEL7 (Fedora 18~19相当) でも、サポートされている。RAID logical volume機能は, LV (=ファイルシステム) を複数の物理ディスクにミラーして配置できる。
/bootについては LVM化できないが、それ以外の領域については、全部をLVMに載せることで冗長性と柔軟性を得ることができる。
できあがりイメージはこんな感じ。
Volume Group (VG) を、物理ディスクをまたいで一つだけ作る。その上でミラー化された RAID logical volumeを作る。
swap領域は、ミラーリングしなくていいので、別々のLV にすればOK.
/boot については, mdカーネルドライバを使って RAID 1構成にする。その手順はこちら; Step by Step: シングルHDDをRAID 1に変換; LVM on RAID編 (Fedora 20)
注意!
parted は、コマンドを打つたびにディスクに書き込む。途中で取消しが効かない。
LVM で RAIDを組む場合, LV の "外側" にメタデータを置く領域が必要。LV を PV とピッタリの大きさで作ると詰む。特に XFS ファイルシステムは切り詰めることができないので、作り直しになる。
Step by Step
[[注意]] 私(堀川)の手元の環境ではできましたが、同じことをしても失敗するリスクがあります。データを失ったとしても,私は責任を負えません。事前に必ず, データをバックアップしてください。
1. 現況
lvsコマンドで現況を表示。-o オプションで表示する列を指定。
大きさについては, 何もオプションを指定しないと g (ギガ) / t (テラ) が自動で付く。--units g などとすると単位が揃う。大きさの単位が小文字のときは 1,024が基数, --units G などと大文字を与えると 1,000が基数になる. 1024基数のほうは MiB/GiB とも呼ばれる。
# lvs -a -o vg_name,name,copy_percent,devices,size
VG LV Copy% Devices LSize
vg_mypc lv_home /dev/sda2(186) 92.69g
vg_mypc lv_root /dev/sda2(3152) 50.00g
vg_mypc lv_swap /dev/sda2(0) 5.81g
LVについて表示したときに、どの物理ディスクに置かれているかが透けて見える。
いったん PCの電源を切り、HDD を追加する。新しいドライヴの場合は, cfdisk などで, 必要なパーティションを切る。
2. 新しいドライヴの場合, partition を切る
[2021-01] 2TB 超えで parted コマンドを使うように書き換えた。
2TB を超えるドライヴの場合は, GPT にしなければならない。parted か gdisk コマンドを使う。
parted は途中で取消しが効かないので、別のドライヴと取り違えないよう、入ったら必ず print して確認すること! gdisk は fdisk に似て, 抜けるときに書き込む。
# parted /dev/sdc
GNU Parted 3.3
/dev/sdc を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
(parted) print
Error: /dev/sdc: unrecognised disk label
Model: ATA ST4000VN008-2DR1 (scsi)
Disk /dev/sdc: 4001GB
Sector size (logical/physical): 512B/4096B
Partition Table: unknown
Disk Flags:
新品なら, 単純に, 1台目と2台目とでまったく同じに作る。
mklabel gpt で GPT にする (他方は msdos)。GPT の場合は MBR がないので、先頭に grub 用の領域が必要。
mkpart コマンドでパーティションを切る。引数は名前, 開始位置, 終了位置. ※msdos にした場合は引数が異なる。ほかの解説ページではゴッチャになっていることも。
大きさは mb などとすると1000が基数で, 1024基数にするには mib などとする。
(parted) mkpart grub 1mib 3mib
(parted) set 1 bios_grub on
(parted) mkpart boot 4mib 500mib
(parted) set 2 boot on
終了位置に -1 のようにマイナス値を指定すると、後ろから数える。-1 で最後までピッタリ。
(parted) mkpart rootfs 501mib -1
(parted) set 3 lvm on
確認。
(parted) print
Model: ATA ST4000VN008-2DR1 (scsi)
Disk /dev/sdc: 4001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 3146kB 2098kB grub bios_grub
2 4194kB 524MB 520MB boot boot, esp
3 525MB 4001GB 4000GB rootfs lvm
名前はただの区別のため何でもよい。名前を変えるには name 2 boot のようにする。
quit で抜ける。
3. 新しい1台目のドライヴ
RAID構成にするドライヴが2台とも新しい場合, 新しくVG (Volume Group) を作る。既存のドライヴ構成に HDD を追加した場合は, 既存の VG に新しいドライヴを追加する。
新しく VG を作るには vgcreate コマンド。--test オプションを付けると実行しない。確認したうえで --test を外して実行。
少なくとも一つ, PVが必要。
~# vgcreate --verbose vg_orange3 /dev/sdc3
Wiping signatures on new PV /dev/sdc3.
Adding physical volume '/dev/sdc3' to volume group 'vg_orange3'
Archiving volume group "vg_orange3" metadata (seqno 0).
Creating volume group backup "/etc/lvm/backup/vg_orange3" (seqno 1).
Volume group "vg_orange3" successfully created
vgdisplay コマンドで確認。
PE Size (Physical Extent size) 4.00 MiBで作られた。以前のは 32.00 MiBだった。PE size の異なる VG は合体できない。
次に, LV を作っていく。将来、こちらから boot するかもしれないので, root, swap, home と3つ作る。
lvcreate コマンドの引数として VolGrpName PhysicalVolName として, PVを指定することもできる。PV を指定しない場合は適当に選ばれる。
~# lvcreate vg_orange3 --size 50g --name lv3_root
Logical volume "lv3_root" created.
~# lvcreate vg_orange3 --size 4g --name lv3_swap
Logical volume "lv3_swap" created.
とりあえずピッタリで作る。--extents Number[PERCENT] オプションで指定。
~# lvcreate vg_orange3 -v --extents 100%FREE --name lv3_home
Converted 100% of FREE (939912) extents into 939912 (with mimages 1 and stripes 1 for segtype striped).
Archiving volume group "vg_orange3" metadata (seqno 3).
Creating logical volume lv3_home
Creating volume group backup "/etc/lvm/backup/vg_orange3" (seqno 4).
Activating logical volume vg_orange3/lv3_home.
activation/volume_list configuration setting not defined: Checking only host tags for vg_orange3/lv3_home.
Creating vg_orange3-lv3_home
Loading table for vg_orange3-lv3_home (253:7).
Resuming vg_orange3-lv3_home (253:7).
Wiping known signatures on logical volume vg_orange3/lv3_home.
Initializing 4.00 KiB of logical volume vg_orange3/lv3_home with value 0.
Logical volume "lv3_home" created.
実際のファイルシステムが格納される領域の外側で, metadata subvolume をデヴァイスに格納できるよう, ここで LV を縮めておく <- ★これが重要!! 下の例では 1GB 縮めているが、こんなに縮めなくてよい。1メタデータサブヴォリューム当たり1エクステント(=4 MiB) で十分。後ろの手順で, lv3_home_rmeta_0, lv3_home_rmeta_1 の2つが作られる。
~# lvreduce -v --size -1g vg_orange3/lv3_home
WARNING: Reducing active logical volume to 3.58 TiB.
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce vg_orange3/lv3_home? [y/n]: y
Accepted input: [y]
Archiving volume group "vg_orange3" metadata (seqno 4).
Reducing logical volume vg_orange3/lv3_home to 3.58 TiB
Size of logical volume vg_orange3/lv3_home changed from <3.59 TiB (939912 extents) to 3.58 TiB (939656 extents).
Loading table for vg_orange3-lv3_home (253:7).
Suspending vg_orange3-lv3_home (253:7) with device flush
Resuming vg_orange3-lv3_home (253:7).
Creating volume group backup "/etc/lvm/backup/vg_orange3" (seqno 5).
Logical volume vg_orange3/lv3_home successfully resized.
フォーマット。ファイルシステムはLVと同じ大きさ。
~# mkfs.xfs /dev/mapper/vg_orange3-lv3_home
meta-data=/dev/mapper/vg_orange3-lv3_home isize=512 agcount=4, agsize=240551936 blks
= sectsz=4096 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1
data = bsize=4096 blocks=962207744, imaxpct=5
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=469828, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
swap領域のフォーマットは mkswap コマンド
4-1. 新しい2台目のドライヴを追加の場合: VGに追加
既存の VG に新しい物理デヴァイスを追加する場合は、新しいドライヴはパーティションを切るだけ。
~# vgextend vg_orange3 /dev/sdd3
Volume group "vg_orange3" successfully extended
2台目のほうには, わざわざ LV はつくらない。(1台目のLVをミラーするので)
4-2. フォーマット済みのドライヴを追加の場合: VGを合体
新しく接続したHDDにすでにPV, VGがあった場合、VGを一つに統合する。
一つのVG上で LV 名が被ってはいけないので、RAID化しない生かす LVは名前を変える。
vgchangeコマンドで、アクティブ/非アクティブの切替え。-a nオプションで非アクティブにする。
# vgchange -a n vg_newhdd
lvrenameコマンドで, LVの名前変更. 例えば, 'root' LVが被っているとして, root2に変更。
いらないLVなら lvremove で単に削除してもOK.
# lvrename vg_newhdd lv_root lv_root2
vgmergeコマンドで, VGを連結して一つにする。コマンド引数は, dest srcの順。
# vgmerge -v vg_mypc vg_newhdd
Checking for volume group "vg_newhdd"
Checking for volume group "vg_mypc"
Extent sizes differ: 65536 (vg_mypc) and 8192 (vg_newhdd)
上のケースは失敗. 単一のVGには異なる大きさの物理エクステント (Physical Extent; PE) を混ぜることができない.
物理エクステントは, (PV/物理デヴァイスではなく) VGの属性で, VGの大きさの単位.
vgdisplayコマンドでPE sizeを確認できる. vgchange コマンドでPE sizeを変更できることになっているが、実際には成功しない.
この場合は, VGを作りなおすしかない. 当然, そのVG上のLV, データはすべて失われる. vgremove コマンドで VGを削除し, vgextend コマンドで VGに PVを追加する.
話を戻して, vgmerge コマンドが成功したら, 新しいHDDのほうの不要なLVを削除。
# lvremove vg_mypc/lv_root2
5. いよいよ RAIDデバイスに変換
Linear LV (RAIDでないLV) を, lvconvertコマンドで RAIDデバイスに変換する.
--type オプション...
linear |
striped |
mirror |
raidn n はraidレベル |
thin |
cache |
thin-pool |
cache-pool |
vdo-pool |
snapshot
-mオプション (--mirrors) ... ミラーの数. -m 1 だと 2-sides.
# lvconvert -v --type raid1 -m 1 vg_mypc/lv_root
Executing: /usr/sbin/modprobe dm-raid
Archiving volume group "vg_mypc" metadata (seqno 6).
Insufficient free space: 1 extents needed, but only 0 available
おや? 空き領域はあるのに。
理由: LVの領域のほかに metadataの領域が必要。VGに metadata分の空きがない場合, LVを縮めてやる必要がある。
metadata は 4MB~32MBぐらいあればいい。
LVを切り詰める
VGにmetadata分の空きがあれば、当然, このステップは不要。ファイルシステムがXFSだと, どうしようもない。xfsdump & xfsrestore しかない。
Fedora 32 では, ファイルシステムは次のいずれか。Btrfs はLVM上に載せる意味がない (Btrfs側がRAID機能も持つ)。ReiserFS ははるか昔に選択肢から外れた.
Red Hat Enterprise Linux 8 だと, XFS, ext4, GFS2, および XFS+LVM 上の Stratis ボリュームマネジャー.
| File system | サイズ変更可能?
|
| 拡張 | 縮小
|
| ext4 | on-line resize2fs ※1 | off-line resize2fs
|
| ext3 | on-line resize2fs ※1 | off-line resize2fs
|
| XFS | on-line xfs_growfs | 不能(!)
|
※1 ext3, ext4 のオンラインでの大きさ変更は, ファイルシステムの feature として resize_inode が有効になっている場合。普通は有効になっている。tune2fs -l で表示できる。
resize2fsコマンドはパーティションの大きさは変更しない。まず lvextend してから実行する。というか lvextend コマンドの --resizefs オプションで, LVの大きさ変更の際に, 同時にファイルシステムの大きさ変更が可能。これで一発で変更するのがよい。対応ファイルシステムは ext2, ext3, ext4, ReiserFS と XFS.
Root LVを縮めたいときは, GParted などのLive CDでブートして操作する。
ファイルシステムをアンマウントする.
# umount /home
逆に, Live CDでブートしたときは, LVが有効になっていないので、LVを有効にする。
$ sudo lvchange -a y /dev/vg_mypc/root
いずれの場合も, ファイルチェックを必ずおこなっておく。
# fsck.ext4 -f /dev/mapper/vg_mypc-lv_home
LVの上に載っているファイルシステムを縮める. 最後の引数が大きさ。下の例だと, 150Gにする。resize2fs に与える大きさは, 常に 1024が基数.
# resize2fs /dev/mapper/vg_mypc-lv_home 150G
その後、LVを縮める。このとき, LVは非アクティブでなければならない.
# lvreduce -L 150g /dev/mapper/vg_mypc-lv_home
再マウント。
# mount -t ext4 /dev/mapper/... /home
進捗
領域を空けてから lvconvert したら, 今度は成功。
~# lvconvert -v --type raid1 --mirrors 1 vg_orange3/lv3_home
Executing: /usr/sbin/modprobe dm-raid
Are you sure you want to convert linear LV vg_orange3/lv3_home to raid1 with 2 images enhancing resilience? [y/n]: y
Accepted input: [y]
Archiving volume group "vg_orange3" metadata (seqno 6).
Creating logical volume lv3_home_rmeta_0
Creating logical volume lv3_home_rmeta_1
Creating logical volume lv3_home_rimage_0
activation/volume_list configuration setting not defined: Checking only host tags for vg_orange3/lv3_home_rmeta_0.
Creating vg_orange3-lv3_home_rmeta_0
Loading table for vg_orange3-lv3_home_rmeta_0 (253:5).
Resuming vg_orange3-lv3_home_rmeta_0 (253:5).
activation/volume_list configuration setting not defined: Checking only host tags for vg_orange3/lv3_home_rmeta_1.
Creating vg_orange3-lv3_home_rmeta_1
Loading table for vg_orange3-lv3_home_rmeta_1 (253:6).
Resuming vg_orange3-lv3_home_rmeta_1 (253:6).
Initializing 4.00 KiB of logical volume vg_orange3/lv3_home_rmeta_0 with value 0.
Initializing 4.00 KiB of logical volume vg_orange3/lv3_home_rmeta_1 with value 0.
Removing vg_orange3-lv3_home_rmeta_0 (253:5)
Removing vg_orange3-lv3_home_rmeta_1 (253:6)
Creating logical volume lv3_home_rimage_0
Creating vg_orange3-lv3_home_rmeta_0
Loading table for vg_orange3-lv3_home_rmeta_0 (253:5).
Resuming vg_orange3-lv3_home_rmeta_0 (253:5).
Creating vg_orange3-lv3_home_rimage_0
Loading table for vg_orange3-lv3_home_rimage_0 (253:6).
Resuming vg_orange3-lv3_home_rimage_0 (253:6).
Creating vg_orange3-lv3_home_rmeta_1
Loading table for vg_orange3-lv3_home_rmeta_1 (253:7).
Resuming vg_orange3-lv3_home_rmeta_1 (253:7).
Creating vg_orange3-lv3_home_rimage_1
Loading table for vg_orange3-lv3_home_rimage_1 (253:8).
Resuming vg_orange3-lv3_home_rimage_1 (253:8).
Loading table for vg_orange3-lv3_home (253:4).
Suspending vg_orange3-lv3_home (253:4) with device flush
Loading table for vg_orange3-lv3_home_rmeta_0 (253:5).
Suppressed vg_orange3-lv3_home_rmeta_0 (253:5) identical table reload.
Loading table for vg_orange3-lv3_home_rimage_0 (253:6).
Suppressed vg_orange3-lv3_home_rimage_0 (253:6) identical table reload.
Loading table for vg_orange3-lv3_home_rmeta_1 (253:7).
Suppressed vg_orange3-lv3_home_rmeta_1 (253:7) identical table reload.
Loading table for vg_orange3-lv3_home_rimage_1 (253:8).
Suppressed vg_orange3-lv3_home_rimage_1 (253:8) identical table reload.
Resuming vg_orange3-lv3_home (253:4).
Monitored LVM-hW3uxpJvh3cRCavkXORcLXwSpBO53RNHVqdOSDq4o6wPYwqF7Zeybvzazy8CX6W3 for events
Creating volume group backup "/etc/lvm/backup/vg_orange3" (seqno 8).
Creating volume group backup "/etc/lvm/backup/vg_orange3" (seqno 9).
Logical volume vg_orange3/lv3_home successfully converted.
すぐに完了が返ってくるが, 裏でミラーリングが進行する。lvs コマンドで進捗を見れる。
# watch lvs -a -o vg_name,name,copy_percent,devices,size
Cpy%Sync が増加していくことが分かる。
Trouble shooting
(2014.12.10)
Fedora 20では上に書いた手順でよかったが, 別の機械のFedora 19で同じようにしたところ、ミラー化後の再起動時に, Dracut emergency modeに落ちてしまった。
ここから大嵌まり。
/boot はミラー化せず。
/ (root), /home は、LVM上にあり、両方ともミラー化した。
ミラー化は成功。しかし、/bootをMD RAID化していなかったため、initramfsに明示的にMDカーネルドライバを組込むのを失念していた。
LVM logical volumeでは, MDカーネルドライバを使っている。
Fedora 19では, Fedora 20とは違い, デフォルトでは組込まれないようだ。
こういう状況で、GRUB2から /boot上ののinitramfsを読み込むところまでは動くが、initramfsにMDカーネルドライバが含まれておらず、刺さった。
金庫の鍵が金庫の中状態。
どうするか。
1) インストールディスクでbootして、LVMを認識させる。
とにかく、LVMを認識できれば、後は何とかなる。
2) どこかのディレクトリ以下に各LVをmountして, ディレクトリツリーを再現する。
chrootしたうえで、dracutコマンドで initramfs を再作成。
dracutコマンドでinitramfsを作りなおしてもうまくいかなかった場合は, きちんとLVMが認識できている状態で, kernelのアップデートを行えばいい。アップデート中に, initramfsが裏で作成される。
dracut に与えるオプションが違うのだろうか。
(1) kernel module
/etc/modules.conf ファイルは, もはやない。insmod コマンドも古い.
今は modprobe コマンドを使う。
# /usr/sbin/modprobe dm-raid
名前が紛らわしいが, MDではなく dmやね.
どのカーネルモジュールがインストールされているかは lsmod コマンド。
lsinitrd コマンドで, initramfsファイルの内容を見れる。
usr/lib/modules/<kernel version>/kernel/drivers/md/dm-raid.ko が含まれるかどうかを確認する。
(2) LVM
/etc/sysconfig/lvm という設定ファイルも, もはやない。
/etc/lvm/lvm.conf ファイルに設定がある。
(3) LVが自動認識されない
dracut shellにて,
# vgscan
# vgchange -a y
# blkid
# ln -s /dev/mapper/luks-$UUID /dev/root
# exit
exit コマンドで, bootが再開される。/dev/root が dracutから抜けたときに root になる.
はずだが、今回の件では, root が認識できなかったので, dracut shell でvgscanコマンドなどが実行できなかった。
インストールディスクから boot すればよい。
(4) initramfs を作り直す
動いている状態で,
# dracut /boot/initramfs-raid.img 3.17.3
/etc/dracut.conf ファイルが設定ファイル