...making Linux just a little more fun!

Joey's Notes: Logical Volume Creation and Expansion

By Joey Prestia

Joey's Notes image Joey's Notes is a new column by Joey Prestia, intended to introduce Linux users to basic and essential Linux tasks and skills. Joey's current work toward a degree in Linux networking, his daily experiences as a member of the RedHat Academy staff on campus, and his knowledge as a programmer in a number of languages provide him with an excellent list of qualifications for this task, and we hope that our readers will benefit from his expertise and enjoy these fun articles.
-- Ben

Information on Logical Volume configuration is somewhat sparse - at least if you want to use the command line. There is a Logical Volume Manager tool on RHEL 5, but it requires a GUI - and most servers only provide a console interface. I tried to find a quick start guide for the CLI (command line interface) and came up with nothing, so I wrote this little guide to help people like me gain a quick insight into the basics.

The hardest part about creating Logical Volumes is knowing which one must be created first; from that point on it's pretty straightforward. First, we have to create Physical Volumes on our hard disk; then, based on those Physical Volumes, we will create our Volume Groups; and finally, we'll set up our Logical Volumes. Let's start with a hard drive that's unpartitioned - say, one that we just added to our system. Start up fdisk -l to see how the device was assigned (we'll use '/dev/sdb' in this example.) While in fdisk, create 2 partitions of the same size (500M), then make sure to set their type to '8e' (LVM).

[root@localhost ~]# fdisk /dev/sdb

Disk /dev/sdb: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         200     1020096   8e  Linux LVM
/dev/sdb2             201         400     1020096   8e  Linux LVM

Write your changes and exit 'fdisk', then use the 'partprobe' command to re-read the partition table.

[root@localhost ~]# partprobe

Now that we have re-read the partition table, we can get on with the actual creation of the Physical Volumes on our hard disk partitions - the ones that we tagged as Linux LVM while in 'fdisk'. We'll use 'pvcreate' for this task. We can also specify both hard disk partitions on one line; 'pvcreate' doesn't mind.

[root@localhost ~]# pvcreate /dev/sdb1 /dev/sdb2
	Physical volume "/dev/sdb1" sucessfully created
	Physical volume "/dev/sdb2" sucessfully created

Ok, now we have two Physical Volumes, and we can create Volume Groups from these. We'll use the 'vgcreate' command to do this, and this time we'll specify a name for the volume group that we are creating. We'll use just one partition, and reserve the other for later.

[root@localhost ~]# vgcreate VolumeGroup_1 /dev/sdb1
	Volume group "VolumeGroup_1" successfully created

So far, so good. Let's get a look at the stats on this Volume Group - we'll use 'vgdisplay'. We need to pay close attention to the sections labeled 'VG Size' and 'Total PE'. PE is the number of physical extents that we have available. We want to avoid ever running out of physical extents, because that would prevent us from being able to resize our LVMs - something we'll be doing a little later.

 [root@localhost ~]# vgdisplay
    --- Volume group ---
  VG Name           	 	  	 VolumeGroup_1
  System ID             
  Format               			 lvm2
  Metadata Areas       	 		 1
  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                		 1
  Act PV                		 1
  VG Size               		 476.00 MB
  PE Size               		 4.00 MB
  Total PE              		 119
  Alloc PE / Size       		 0 / 0
  Free  PE / Size       		 119 / 476.00 MB
  VG UUID                  	     BCkPP1-2CM1-1hxW-7B2J-yfSt-mEMJ-7fMwNL

This says that we've done everything correctly; it also tells us the number of physical extents we have. In this case, it's 119 - and we'll need 5%-12% of our available physical extents to perform resizing operations on LVMs.

Okay, then - let's create a Logical Volume out of this Volume Group so we can put a file system on it. We'll be using - you guessed it - the 'lvcreate' command. It's similar to 'vgcreate', but we must specify more details on the command line to set things up correctly. The switches we will be using are '-l' to specify the number of extents to utilize and '-n' to assign a name to our logical volume. We will also have to specify it by '/dev/VolumeGroup_1' now rather than the physical designation (/dev/sdb1) as before.

[root@localhost ~]# lvcreate -l 50 -n LogicalVolume_1 /dev/VolumeGroup_1 
	Logical volume "LogicalVolume_1"  created

We have used 50 extents in this example, so about 200 MB worth of actual file system can be used on it. Run 'lvdisplay' to see the results. Now, let's put a file system on it so we can mount it and put it to use.

[root@localhost ~]# mkfs.ext3 /dev/VolumeGroup_1/LogicalVolume_1

Let's label it as '/data':

[root@localhost ~]# e2label /dev/VolumeGroup_1/LogicalVolume_1 /data

Now, we'll make a '/data' directory and mount our Logical Volume on it.

[root@localhost ~]# mkdir /data
[root@localhost ~]# mount /dev/VolumeGroup_1/LogicalVolume_1 /data 
[root@localhost ~]# ls /data 

Let's use that new space up so we can really see what all this logical volume resizing stuff is about:

[root@localhost ~]# cd /data
[root@localhost data]# dd if=/dev/zero of=crap bs=1000k  count=190
190+0 records in 
190+0 records out
194560000 bytes (195 MB) copied, 16.2202 seconds, 12.0 MB/s

That should push us to the limit of room on that logical volume. You can see this via 'df -h':

[root@localhost data]# df -h 
Filesystem            Size    Used   Avail Use% Mounted on
/dev/sda8             965M    302M   614M   33%      /
/dev/sda1              99M    5.9M    88M    7%      /boot
tmpfs                 629M       0   629M    0%      /dev/shm
/dev/sda7             965M    618M   298M   68%      /home
/dev/sda5             9.5G    3.1G   6.0G   34%      /usr
/dev/sda2              19G    8.6G   9.5G   48%      /var
                      194M    192M      0  100%      /data

First, let's increase our size a little. A simple way to do this is 'lvresize':

[root@localhost data]# lvresize -l 100 /dev/VolumeGroup_1/LogicalVolume_1
	Extending logical volume LogicalVolume_1 to 400.00 MB
	Logical volume Log_1 successfully resized

Now this looks good - but we still can't utilize the added room. You must first extend the file system onto the newly added area - remember, it's still kinda "raw". We can do this by using 'resize2fs'. The file system can be mounted while this is done, but I would recommend stopping all filesystem activity on this partition while this is being performed. If you have critical data on this partition, you will want to actually unmount it before resizing. I did a 'live' resize in this example because our partition does not contain any critical data.

[root@localhost data]# resize2fs /dev/VolumeGroup_1/LogicalVolume_1 
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/VolumeGroup_1/LogicalVolume_1 is mounted on /data; on-line resizing required
Performing an on-line resize of /dev/VolumeGroup_1/LogicalVolume_1 to 409600 (1k) blocks 
The filesystem on /dev/VolumeGroup_1/LogicalVolume_1 is now 409600 blocks long.

[root@localhost data]# df -h
Filesystem            Size    Used   Avail Use% Mounted on
/dev/sda8             965M    302M   614M   33%      /
/dev/sda1              99M    5.9M    88M    7%      /boot
tmpfs                 629M       0   629M    0%      /dev/shm
/dev/sda7             965M    618M   298M   68%      /home
/dev/sda5             9.5G    3.1G   6.0G   34%      /usr
/dev/sda2              19G    8.6G   9.5G   48%      /var
                      388M    193M   175M   53%      /data

As a last exercise, we'll add the other physical volume to this one. Let's assume that we need to add some more room to that logical volume; since we have a physical volume left over (/dev/sdb2), that's what we'll use. For this operation, we'll need the 'vgextend' and 'lvextend' commands. We'll need to remember the order in which we created them: Physical first, then the Volume group, and Logical Volume last of all. This order is very important, and is reversed for the removal of these logical devices. Here, we add the '/dev/sda2' physical volume area to our volume group VolumeGroup_1:

[root@localhost data]# vgextend /dev/VolumeGroup_1 /dev/sdb2
	Volume group "VolumeGroup_1" successfully extended

[root@localhost data]# vgdisplay 
    --- Volume group ---
  VG Name           	 	  	 VolumeGroup_1
  System ID             
  Format               			 lvm2
  Metadata Areas       	 		 2
  Metadata Sequence No 	 		 4
  VG Access            			 read/write
  VG Status            			 resizable
  MAX LV             			 0
  Cur LV               			 1
  Open LV               		 1	
  Max PV                		 0
  Cur PV               			 2
  Act PV                		 2
  VG Size               		 952.00 MB
  PE Size               		 4.00 MB
  Total PE              		 238
  Alloc PE / Size       		 100  / 400.00 MB
  Free  PE / Size       		 138  / 552.00 MB
  VG UUID                        BCkPP1-2CM1-1hxW-7B2J-yfSt-mEMJ-7fMwNL

That's it; we've created Physical Volumes, Volume Groups, and Logical Volumes and resized them. There's a lot more that can be done to and with these; I would recommend lots of practice before doing anything involving critical data and making sure you have a backup/snapshot of your data.

	fdisk ----- partitions hard disk 
	partprobe - force the kernel to reread the partition table
	pvcreate -- creates physical volumes
	pvdisplay - display details about physical volumes
	vgcreate -- creates volume groups
	vgdisplay - display details about volume groups
	vgextend -- extends volume group	
	lvcreate -- creates logical volumes
	lvdisplay - display details about logical volumes
	lvextend -- extends logical volume
	lvresize -- resize logical volume
	resize2fs - expands filesystem onto newly extended space

Talkback: Discuss this article with The Answer Gang


Joey was born in Phoenix and started programming at the age fourteen on a Timex Sinclair 1000. He was driven by hopes he might be able to do something with this early model computer. He soon became proficient in the BASIC and Assembly programming languages. Joey became a programmer in 1990 and added COBOL, Fortran, and Pascal to his repertoire of programming languages. Since then has become obsessed with just about every aspect of computer science. He became enlightened and discovered RedHat Linux in 2002 when someone gave him RedHat version six. This started off a new passion centered around Linux. Currently Joey is completing his degree in Linux Networking and working on campus for the college's RedHat Academy in Arizona. He is also on the staff of the Linux Gazette as the Mirror Coordinator.

Copyright © 2008, Joey Prestia. Released under the Open Publication License unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 148 of Linux Gazette, March 2008