概要
最近、ストレージ技術を学ぼうとしたが、HDDを買う資金もないほどの金欠。なので、USBメモリを使ってLVM技術について学んでみる。
USB4本を一つのボリュームとしてLV化する。
LVMとは
LVM(Logical Volume Manager)はLinuxのデバイス(ストレージ)を抽象化する技術。ファイルサイズの分割や結合などを行うことができる。3つの層を用いてストレージ管理を行う。
物理層 PV Physical Volume ← 物理ディスクそのもの
↓
論理層 VG Volume Group ← PVをまとめたプール
↓
仮想層 LV Logical Volume ← OSに見せる仮想ディスク
- PV|Physical Volume(物理ボリューム)
「LVMが管理できるようにした物理ディスク」 - VG|Volume Group(ボリュームグループ)
「PVをまとめた大きなストレージプール」 - LV|Logical Volume(論理ボリューム)
「VGから切り出した仮想ディスク」
PE
PE(Physical Extent)は、LVMがストレージを管理するための最小単位のブロックのことを指す。
1PE = 4MiB(デフォルト)
機材
ラズパイ5(16GB)
OS UbuntuServerOS
USBメモリ(KIOXA_32GB_USB-A3.2) x 4本
USBハブ(IO DATA_US3-HB4)
手順
ラズパイに各USBをハブ経由で繋げる。
本記事の環境ではMacBookAirのssh接続でラズパイに接続する。
デバイス認識
ラズパイ側でデバイスの認識を確認。sd1~sd4がUSBのディスク名。
デバイス自体は/dev内に格納されている。
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop1 7:1 0 41.6M 1 loop /snap/snapd/25939
loop2 7:2 0 41.8M 1 loop /snap/snapd/26383
sda 8:0 1 28.9G 0 disk
└─sda1 8:1 1 28.9G 0 part
sdb 8:16 1 28.9G 0 disk
└─sdb1 8:17 1 28.9G 0 part
sdc 8:32 1 28.9G 0 disk
└─sdc1 8:33 1 28.9G 0 part
sdd 8:48 1 28.9G 0 disk
└─sdd1 8:49 1 28.9G 0 part
mmcblk0 179:0 0 58.2G 0 disk
├─mmcblk0p1 179:1 0 512M 0 part /boot/firmware
└─mmcblk0p2 179:2 0 57.7G 0 part /
LV作成
sudo apt update
sudo apt install lvm2
一応、Ubuntuでは標準で入ってるぽい。
$ sudo apt install lvm2
lvm2 is already the newest version (2.03.31-2ubuntu2).
Summary:
Upgrading: 0, Installing: 0, Removing: 0, Not Upgrading: 45
各デバイスをPVとして初期化
$ sudo pvcreate /dev/sd1
WARNING: vfat signature detected on /dev/sda1 at offset 0. Wipe it? [y/n]: y
Wiping vfat signature on /dev/sda1.
WARNING: vfat signature detected on /dev/sda1 at offset 510. Wipe it? [y/n]: y
Wiping vfat signature on /dev/sda1.
Physical volume "/dev/sda1" successfully created.
$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sda1 lvm2 --- 28.87g 28.87g
PVデータ
$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sda1 lvm2 --- 28.87g 28.87g
/dev/sdb1 lvm2 --- 28.87g 28.87g
/dev/sdc1 lvm2 --- 28.87g 28.87g
/dev/sdd1 lvm2 --- 28.87g 28.87g
$ sudo pvdisplay
"/dev/sda1" is a new physical volume of "28.87 GiB"
--- NEW Physical volume ---
PV Name /dev/sda1
VG Name
PV Size 28.87 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID DBnzPc-WcPz-fovM-fAjt-a1GD-fWX9-1bHdbL
"/dev/sdb1" is a new physical volume of "28.87 GiB"
--- NEW Physical volume ---
PV Name /dev/sdb1
VG Name
PV Size 28.87 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID nizCar-ChA5-57aO-RB8A-rc5K-Ai9T-f7U2AO
"/dev/sdc1" is a new physical volume of "28.87 GiB"
--- NEW Physical volume ---
PV Name /dev/sdc1
VG Name
PV Size 28.87 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID oP8bJI-tqG3-oVd5-T847-TXNX-yuQg-ujpNzE
"/dev/sdd1" is a new physical volume of "28.87 GiB"
--- NEW Physical volume ---
PV Name /dev/sdd1
VG Name
PV Size 28.87 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID eS4q2X-37tQ-oyv2-eW71-izsU-MH9B-9d5YJr
VG作成
sudo vgcreate vg_usb /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1
VGデータ
$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
vg_usb 4 0 0 wz--n- <115.47g <115.47g
$ sudo vgdisplay vg_usb
--- Volume group ---
VG Name vg_usb
System ID
Format lvm2
Metadata Areas 4
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 4
Act PV 4
VG Size <115.47 GiB
PE Size 4.00 MiB
Total PE 29560
Alloc PE / Size 0 / 0
Free PE / Size 29560 / <115.47 GiB
VG UUID UilJLn-Kabk-XuA9-ZwmA-zVom-CqIc-xpOSgZ
LVの作成
-l 100%FREE でVG容量すべてを割り当て
sudo lvcreate -l 100%FREE -n lv_data vg_usb
LVデータ
sudo lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_data vg_usb -wi-a----- <115.47g
sudo lvdisplay
--- Logical volume ---
LV Path /dev/vg_usb/lv_data
LV Name lv_data
VG Name vg_usb
LV UUID Rcm8lT-tSjC-cZGq-Cx7S-IbWu-nm09-RaVvQK
LV Write Access read/write
LV Creation host, time ubmiya, 2026-03-22 20:42:57 +0900
LV Status available
# open 0
LV Size <115.47 GiB
Current LE 29560
Segments 4
Allocation inherit
Read ahead sectors auto
- currently set to 4096
Block device 253:0
現時点でのファイルは/devに存在する。
/dev/vg_usb/lv_data
ファイルシステムの割り当てとマウント
ext4でフォーマット
sudo mkfs.ext4 /dev/vg_usb/lv_data
mke2fs 1.47.2 (1-Jan-2025)
Creating filesystem with 30269440 4k blocks and 7569408 inodes
Filesystem UUID: 2cd49085-1a2b-4d55-99a5-e936839d2cb7
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872
Allocating group tables: done
Writing inode tables: done
Creating journal (131072 blocks): done
Writing superblocks and filesystem accounting information: done
マウントポイント作成・マウント
sudo mkdir -p /mnt/usb_pool
sudo mount /dev/vg_usb/lv_data /mnt/usb_pool
自動マウント設定
再起動後もマウントされるように設定。
UUID確認
sudo blkid /dev/vg_usb/lv_data
/dev/vg_usb/lv_data: UUID="2cd49085-1a2b-4d55-99a5-e936839d2cb7" BLOCK_SIZE="4096" TYPE="ext4"
fstabに追記(バックアップも作成)
sudo cp /etc/fstab /etc/fstab.bak
nano /etc/fstab
#下記を末尾に追記する
UUID=2cd49085-1a2b-4d55-99a5-e936839d2cb7 /mnt/usb_pool ext4 defaults 0 2
#ファイル中身
LABEL=writable / ext4 defaults 0 1
LABEL=system-boot /boot/firmware vfat defaults 0 1
UUID=2cd49085-1a2b-4d55-99a5-e936839d2cb7 /mnt/usb_pool ext4 defaults 0 2
再起動後マウント確認
$ sudo reboot
$ df -h | grep usb_pool
/dev/mapper/vg_usb-lv_data 114G 2.1M 108G 1% /mnt/**usb_pool**
シンボリックリンクをホームディレクトリに作成すると便利
ln -s /mnt/usb_pool ~/usb_pool
テスト
今回は、ファイルのブロック番号を用いた確認を行う。
- filefrag でブロック番号取得
- extent番号に変換
- どのPVか特定
テストファイル作成
echo "LVMテスト用ファイル" | sudo tee /mnt/usb_pool/test.txt
sync # バッファをディスクに確実に書き出す
ファイルのブロック番号を調べる -> 34304
$ sudo filefrag -v /mnt/usb_pool/lvm_test.txt
Filesystem type is: ef53
File size of /mnt/usb_pool/lvm_test.txt is 28 (1 block of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 34304.. 34304: 1: last,eof
/mnt/usb_pool/lvm_test.txt: 1 extent found
物理マッピングを確認
$ sudo lvdisplay -m /dev/vg_usb/lv_data
--- Logical volume ---
LV Path /dev/vg_usb/lv_data
LV Name lv_data
VG Name vg_usb
LV UUID Rcm8lT-tSjC-cZGq-Cx7S-IbWu-nm09-RaVvQK
LV Write Access read/write
LV Creation host, time ****, 2026-03-22 20:42:57 +0900
LV Status available
# open 1
LV Size <115.47 GiB
Current LE 29560
Segments 4
Allocation inherit
Read ahead sectors auto
- currently set to 4096
Block device 253:0
--- Segments ---
Logical extents 0 to 7389:
Type linear
Physical volume /dev/sda1
Physical extents 0 to 7389
Logical extents 7390 to 14779:
Type linear
Physical volume /dev/sdd1
Physical extents 0 to 7389
Logical extents 14780 to 22169:
Type linear
Physical volume /dev/sdb1
Physical extents 0 to 7389
Logical extents 22170 to 29559:
Type linear
Physical volume /dev/sdc1
Physical extents 0 to 7389
dmsetupで詳細マッピングを見る(裏付け作業、やる必要はない)
$ sudo dmsetup table vg_usb-lv_data
0 60538880 linear 8:1 2048
60538880 60538880 linear 8:49 2048
121077760 60538880 linear 8:17 2048
181616640 60538880 linear 8:33 2048
結果から、
# filefrag でブロック番号取得
physical_offset: 34304 ← この数字(単位: 4096バイトブロック)
#extent番号に変換
34304 ÷ 1024 = 33.8 → logical extent 33番
#どのPVか特定
Logical extents 0 to 7389:
Type linear
Physical volume /dev/sda1
Physical extents 0 to 7389
よって、33.8番はextents 0 to 7389 の間より、sda1のディスクに格納。
ファイル使用量
テスト後含めた最終的なLVデータ
全体の使用量・空き容量
$ df -h /mnt/usb_pool
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_usb-lv_data 114G 2.1M 108G 1% /mnt/usb_pool
各ファイルの容量
$ sudo du -sh /mnt/*
16K /mnt/usb_pool/lost+found
4.0K /mnt/usb_pool/lvm_test.txt
LV・VGの使用状況
$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
vg_usb 4 1 0 wz--n- <115.47g 0
$ sudo lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_data vg_usb -wi-ao---- <115.47g
まとめ
今回はざっくりとしたLVMの手順を試した。実際の実用性としては非常に扱いづらいものの、
LVというボリュームを作成する概念を学ぶことができてなかなか面白かった。ストレージ技術においてはRAIDが
有名ではあるが、一部の環境ではRAIDとLVMを組み合わせたストレージ構成などもあるらしいので、学んでおいて損はないとは思う。