(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 ファイルが設定ファイル