DEV Community

Cover image for LVM Land
jkeown
jkeown

Posted on

LVM Land

Related Series Links:
1.Partition Party
2.Filesystem & mounting
3.LVM Land (this article)

This post will explore the more practical world of the Logical Volume Manager. It provides enhanced storage management by allowing dynamic allocation of storage space. It enables administrators to create, resize, and manage disk partitions more flexibly than traditional partitioning methods. Let's first check our block status.

[sorad@dev9 ~]$ lsblk -f /dev/{sdb,sdc}
NAME   FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sdb                                                                           
├─sdb1 xfs                e191547c-35b1-44f8-9278-8160eac6e300                
├─sdb2 ext4   1.0         3060ac82-ea5e-4cf3-b2f7-975154512ed3                
├─sdb3                                                                        
├─sdb4                                                                        
├─sdb5                                                                        
└─sdb6                                                                        
sdc                                                                           
├─sdc1 xfs                81bff549-814e-407f-ab1f-396cb95a7f09    1.4G    28% /mountsdc
├─sdc2                                                                        
├─sdc3                                                                        
├─sdc4                                                                        
├─sdc5                                                                        
└─sdc6 
Enter fullscreen mode Exit fullscreen mode

We have 9 of our 2 GB partitions available. I'll use that space for logical volumes. It's back into fdisk to delete some partitions. For brevity's sake, I'll only show the process for sdc. Take note that deleting partition 4 (extended) also deletes its logical partitions.

[sorad@dev9 ~]$ sudo fdisk /dev/sdc

Welcome to fdisk (util-linux 2.37.4).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

This disk is currently in use - repartitioning is probably a bad idea.
It's recommended to umount all file systems, and swapoff all swap
partitions on this disk.


Command (m for help): p

Disk /dev/sdc: 10 GiB, 10737418240 bytes, 20971520 sectors
Disk model: VBOX HARDDISK   
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5ace204b

Device     Boot    Start      End Sectors Size Id Type
/dev/sdc1           2048  4196351 4194304   2G 83 Linux
/dev/sdc2        4196352  8390655 4194304   2G 83 Linux
/dev/sdc3        8390656 12584959 4194304   2G 83 Linux
/dev/sdc4       12584960 20971519 8386560   4G  5 Extended
/dev/sdc5       12587008 16781311 4194304   2G 83 Linux
/dev/sdc6       16783360 20971519 4188160   2G 83 Linux

Command (m for help): d
Partition number (1-6, default 6): 2

Partition 2 has been deleted.

Command (m for help): d
Partition number (1,3-6, default 6): 3

Partition 3 has been deleted.

Command (m for help): p
Disk /dev/sdc: 10 GiB, 10737418240 bytes, 20971520 sectors
Disk model: VBOX HARDDISK   
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5ace204b

Device     Boot    Start      End Sectors Size Id Type
/dev/sdc1           2048  4196351 4194304   2G 83 Linux
/dev/sdc4       12584960 20971519 8386560   4G  5 Extended
/dev/sdc5       12587008 16781311 4194304   2G 83 Linux
/dev/sdc6       16783360 20971519 4188160   2G 83 Linux

Command (m for help): d
Partition number (1,4-6, default 6): 4

Partition 4 has been deleted.

Command (m for help): p
Disk /dev/sdc: 10 GiB, 10737418240 bytes, 20971520 sectors
Disk model: VBOX HARDDISK   
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5ace204b

Device     Boot Start     End Sectors Size Id Type
/dev/sdc1        2048 4196351 4194304   2G 83 Linux

Command (m for help): w
The partition table has been altered.
Syncing disks.
Enter fullscreen mode Exit fullscreen mode

Reviewing the current block state again, we notice that the 9 unused partitions are no longer present.

[sorad@dev9 ~]$ lsblk -f /dev/{sdb,sdc}
NAME   FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sdb                                                                           
├─sdb1 xfs                e191547c-35b1-44f8-9278-8160eac6e300                
└─sdb2 ext4   1.0         3060ac82-ea5e-4cf3-b2f7-975154512ed3                
sdc                                                                           
└─sdc1 xfs                81bff549-814e-407f-ab1f-396cb95a7f09    1.4G    28% /mountsdc
Enter fullscreen mode Exit fullscreen mode

Back into fdisk, I'll allocate the remaining space for each disk to a single partition. The default options will be selected to use all available disk space. I'll label the new partitions using code 8e so their type shows LVM. Again, I'll only show the process for sdc.

[sorad@dev9 ~]$ sudo fdisk /dev/sdc

Welcome to fdisk (util-linux 2.37.4).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): 

Using default response p.
Partition number (2-4, default 2): 
First sector (4196352-20971519, default 4196352): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (4196352-20971519, default 20971519): 

Created a new partition 2 of type 'Linux' and of size 8 GiB.

Command (m for help): p
Disk /dev/sdc: 10 GiB, 10737418240 bytes, 20971520 sectors
Disk model: VBOX HARDDISK   
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5ace204b

Device     Boot   Start      End  Sectors Size Id Type
/dev/sdc1          2048  4196351  4194304   2G 83 Linux
/dev/sdc2       4196352 20971519 16775168   8G 83 Linux

Command (m for help): t
Partition number (1,2, default 2): 
Hex code or alias (type L to list all): 8e

Changed type of partition 'Linux' to 'Linux LVM'.

Command (m for help): p
Disk /dev/sdc: 10 GiB, 10737418240 bytes, 20971520 sectors
Disk model: VBOX HARDDISK   
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5ace204b

Device     Boot   Start      End  Sectors Size Id Type
/dev/sdc1          2048  4196351  4194304   2G 83 Linux
/dev/sdc2       4196352 20971519 16775168   8G 8e Linux LVM

Command (m for help): w
The partition table has been altered.
Syncing disks.
Enter fullscreen mode Exit fullscreen mode

Checking block status again, we see the single partitions added to each disk. sdb3 and sdc2 are ready for use.

[sorad@dev9 ~]$ lsblk -f /dev/{sdb,sdc}
NAME   FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sdb                                                                           
├─sdb1 xfs                e191547c-35b1-44f8-9278-8160eac6e300                
├─sdb2 ext4   1.0         3060ac82-ea5e-4cf3-b2f7-975154512ed3                
└─sdb3                                                                        
sdc                                                                           
├─sdc1 xfs                81bff549-814e-407f-ab1f-396cb95a7f09    1.4G    28% /mountsdc
└─sdc2
Enter fullscreen mode Exit fullscreen mode

Here comes the fun! The LVM structure consists of 3 layers:

  1. Physical Volumes: The partitions which make up the Volume Groups.

  2. Volume Groups: Combination of physical volumes creating one source of storage space.

  3. Logical Volumes: Virtual/Logical partitions using the storage space available in its assigned volume group.

Let's check the current list of physical volumes using pvs. We see there's only one.

[sorad@dev9 ~]$ sudo pvs
[sudo] password for sorad: 
  PV         VG      Fmt  Attr PSize   PFree
  /dev/sda2  cs_vbox lvm2 a--  <19.00g    0
Enter fullscreen mode Exit fullscreen mode

We can add sdb3 and sdc2 to the physical volumes using pvcreate specifying the partition to use.

[sorad@dev9 ~]$ sudo pvcreate /dev/sdb3
  Physical volume "/dev/sdb3" successfully created.

[sorad@dev9 ~]$ sudo pvcreate /dev/sdc2
  Physical volume "/dev/sdc2" successfully created.

[sorad@dev9 ~]$ sudo pvs
  PV         VG      Fmt  Attr PSize   PFree 
  /dev/sda2  cs_vbox lvm2 a--  <19.00g     0 
  /dev/sdb3          lvm2 ---   <6.00g <6.00g
  /dev/sdc2          lvm2 ---   <8.00g <8.00g
Enter fullscreen mode Exit fullscreen mode

Now, let's check the current Volume Groups with vgs, then create a new VG using vgcreate. The vgcreate syntax is:

vgcreate Name_for_the_Group Partition_to_Use

The PV and LV columns show the physical and logical volumes associated with each volume group.

[sorad@dev9 ~]$ sudo vgs
  VG      #PV #LV #SN Attr   VSize   VFree
  cs_vbox   1   2   0 wz--n- <19.00g    0 

[sorad@dev9 ~]$ sudo vgcreate party_lv /dev/sdb3
  Volume group "party_lv" successfully created

[sorad@dev9 ~]$ sudo vgs
  VG       #PV #LV #SN Attr   VSize   VFree 
  cs_vbox    1   2   0 wz--n- <19.00g     0 
  party_lv   1   0   0 wz--n-  <6.00g <6.00g
Enter fullscreen mode Exit fullscreen mode

Now to add sdc2 to the same volume group. Since the party_lv is already created, we need to use vgextend to add more physical volumes. The syntax is basically the same as vgcreate. Just specify the name of the existing VG to use. Be sure to look at the changes in the PV, LV, VSize, and VFree columns after.

[sorad@dev9 ~]$ sudo vgs
  VG       #PV #LV #SN Attr   VSize   VFree 
  cs_vbox    1   2   0 wz--n- <19.00g     0 
  party_lv   1   0   0 wz--n-  <6.00g <6.00g

[sorad@dev9 ~]$ sudo vgextend party_lv /dev/sdc2
  Volume group "party_lv" successfully extended

[sorad@dev9 ~]$ sudo vgs
  VG       #PV #LV #SN Attr   VSize   VFree 
  cs_vbox    1   2   0 wz--n- <19.00g     0 
  party_lv   2   0   0 wz--n-  13.99g 13.99g
Enter fullscreen mode Exit fullscreen mode

Oops—I made a mistake in the naming convention. We're still working with volume groups, but I accidentally named the example party_lv, which implies a logical volume. No problem—we can fix it using the vgrename command.

[sorad@dev9 ~]$ sudo vgrename party_lv party_vg
  Volume group "party_lv" successfully renamed to "party_vg"

[sorad@dev9 ~]$ sudo vgs
  VG       #PV #LV #SN Attr   VSize   VFree 
  cs_vbox    1   2   0 wz--n- <19.00g     0 
  party_vg   2   0   0 wz--n-  13.99g 13.99g
Enter fullscreen mode Exit fullscreen mode

Run lvs next to show our current logical volumes.

[sorad@dev9 ~]$ sudo lvs
  LV   VG      Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root cs_vbox -wi-ao---- <17.00g                                                    
  swap cs_vbox -wi-ao----   2.00g  
Enter fullscreen mode Exit fullscreen mode

You create logical volumes using lvcreate. For this example, I'll use the entire party_vg to create a single logical volume. However, you can allocate a smaller size if you'd like to repeat the process and create multiple logical volumes from party_vg. The lvcreate syntax is a bit more involved:

lvcreate -n Name_for_Volume -L Size_to_Make_Volume Volume_Group_to_Use

[sorad@dev9 ~]$ sudo lvcreate -n party_lv -L 13.99G party_vg
  Rounding up size to full physical extent 13.99 GiB
  Logical volume "party_lv" created.

[sorad@dev9 ~]$ sudo lvs
  LV       VG       Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root     cs_vbox  -wi-ao---- <17.00g                                                    
  swap     cs_vbox  -wi-ao----   2.00g                                                    
  party_lv party_vg -wi-a-----  13.99g
Enter fullscreen mode Exit fullscreen mode

There we have it! The party_lv is now ready for the steps we're already familiar with, adding a filesystem and mounting.

Note: The path to logical volumes differs from that of physical partitions. While they still begin with /dev, logical volumes typically follow one of two path formats:

  1. /dev/mapper/vg_name-lv_name

  2. /dev/vg_name/lv_name (symbolic link)

So for our example, either path will work:

  1. /dev/mapper/party_vg-party_lv

  2. /dev/party_vg/party_lv

In the following you will see both used just to demonstrate.

Add filesystem:

[sorad@dev9 ~]$ sudo mkfs.ext4 /dev/party_vg/party_lv
mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 3667968 4k blocks and 917504 inodes
Filesystem UUID: dd2e3dcd-a2fb-4ae4-b102-505a966e6a71
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done   

[sorad@dev9 ~]$ lsblk -f /dev/party_vg/party_lv 
NAME              FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
party_vg-party_lv ext4   1.0         dd2e3dcd-a2fb-4ae4-b102-505a966e6a71
Enter fullscreen mode Exit fullscreen mode

Mounting:

[sorad@dev9 ~]$ sudo mkdir /partition_party

[sorad@dev9 ~]$ sudo mount /dev/party_vg/party_lv /partition_party/

[sorad@dev9 ~]$ lsblk -f /dev/party_vg/party_lv 
NAME              FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
party_vg-party_lv ext4   1.0         dd2e3dcd-a2fb-4ae4-b102-505a966e6a71     13G     0% /partition_party
Enter fullscreen mode Exit fullscreen mode

Now I'll unmount the logical volume to demonstrate how to add it to the /etc/fstab file for persistent mounting. You can check the MOUNTPOINTS column (e.g., in the lsblk output) to see if and where the volume is currently mounted.

[sorad@dev9 ~]$ sudo umount /partition_party/

[sorad@dev9 ~]$ lsblk -f /dev/party_vg/party_lv 
NAME              FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
party_vg-party_lv ext4   1.0         dd2e3dcd-a2fb-4ae4-b102-505a966e6a71

[sorad@dev9 ~]$ sudo vi /etc/fstab
Enter fullscreen mode Exit fullscreen mode

In the /etc/fstab file, I'm adding the primary path for the party_lv:

/dev/mapper/party_vg-party_lv /partition_party ext4 defaults 0 0

When I run mount -a, I get a reload message so I'll run that also, then display that our LV is mounted again.

[sorad@dev9 ~]$ sudo mount -a
mount: (hint) your fstab has been modified, but systemd still uses
       the old version; use 'systemctl daemon-reload' to reload.

[sorad@dev9 ~]$ sudo systemctl daemon-reload

[sorad@dev9 ~]$ lsblk -f /dev/party_vg/party_lv 
NAME              FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
party_vg-party_lv ext4   1.0         dd2e3dcd-a2fb-4ae4-b102-505a966e6a71     13G     0% /partition_party
Enter fullscreen mode Exit fullscreen mode

To finish up and check the LV is operational, let's create a test file.

[sorad@dev9 ~]$ sudo touch /partition_party/great_party.txt

[sorad@dev9 ~]$ ll /partition_party/
total 16
-rw-r--r--. 1 root root     0 May 16 14:39 great_party.txt
drwx------. 2 root root 16384 May 16 14:32 lost+found
Enter fullscreen mode Exit fullscreen mode

I hope you've enjoyed this third journey with me in the storage realm. Questions, comments, and concerns are always welcome. Thank you again for reading.

P.S.
You may have noticed this warning in the beginning:

This disk is currently in use - repartitioning is probably a bad idea.
It's recommended to umount all file systems, and swapoff all swap
partitions on this disk.
Enter fullscreen mode Exit fullscreen mode

This article was completed without unmounting any file systems. Please let me know if there's a specific reason to always unmount file systems first, as stated in the warning.

Top comments (0)