tags:
Contents
Overview
Virtualization makes it easy to add more disk capacity to a virtual machine. Extending a virtual disk in VMware will grant the VM access to more storage, but we still have to make that storage usable to the operating system.
This post will explain the steps required to make this additional storage usable within a Linux virtual machine. These steps work with both CentOS7 and Ubuntu 16 and 17, and is done completely from the command line.
It is always best to use extreme caution when making changes to a production system. While these instructions will allow you to do this on a running system without rebooting, I would suggest using a maintenance window to perform this operation and I would not do this live on a mission critical system.
Under those circumstances I would suggest extending your volume by attaching the disk to another VM or booting from a Live CD and these instructions still apply.
That said there are many scenarios where the risk is acceptable. However, backup and verify important data before making any changes to a disk!
Before we begin we are assuming the following:
- CentOS7 or Ubuntu is being used.
- The disks are partitioned using the Linux Logical Volume Manager (LVM)
We will need to resize the disk on several “levels” before we are done.
The first level is the virtual disk itself (this is representative of a physical hard drive in a physical server). This step is performed using the virtualization manager, and isn’t covered here in detail. Level two is resizing the disk partition we will be using. Third is the physical volume. Fourth is the logical volume. Finally we resize the file system.
Step 1 - Verify the Disk Size in Linux
The first thing we need to do is make sure the operating system sees that the disk has been increased in size. The bus will be rescanned on a reboot, but what if we don’t want to reboot? To force the system to rescan a device run the following command. Note that this is disk specific. The command below will rescan /dev/sda (the first disk).
echo 1 > /sys/block/sda/device/rescan
Here is an example where 1GB was added to a 200GB disk. Notice the Disk size after each fdisk
command.
root@lasrv:~# fdisk -l
Disk /dev/sda: 200 GiB, 214748364800 bytes, 419430400 sectors
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: 0x4756842e
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 415236095 415234048 198G 83 Linux
/dev/sda2 415238142 419428351 4190210 2G 5 Extended
/dev/sda5 415238144 419428351 4190208 2G 82 Linux swap / Solaris
root@lasrv:~# echo 1 > /sys/block/sda/dev/rescan
root@lasrv:~# fdisk -l
Disk /dev/sda: 201 GiB, 215822106624 bytes, 421527552 sectors
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: 0x4756842e
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 415236095 415234048 198G 83 Linux
/dev/sda2 415238142 419428351 4190210 2G 5 Extended
/dev/sda5 415238144 419428351 4190208 2G 82 Linux swap / Solaris
The size shown by fdisk should match the size shown in your virtualization software. Once you’ve verified this move on to step 2.
Step 2 - Resizing the Partition
With the OS seeing the underlying disk size correctly we can proceed to resize the physical disk partition. This is done using fdisk
and requires that we delete the existing partition and create a new, larger, partition in its place.
Although this may sound scary, it is not. No data should be lost, and you have your system backed up, right? RIGHT?
Here is our starting point. Notice the size of our disk /dev/mapper/centos-root
is 11.5GB.
[root@localhost ~]# fdisk -l
Disk /dev/sda: 14.0 GB, 13958643712 bytes, 27262976 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000912b7
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 1026047 512000 83 Linux
/dev/sda2 1026048 25165823 12069888 8e Linux LVM
Disk /dev/mapper/centos-root: 11.5 GB, 11496587264 bytes, 22454272 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/centos-swap: 859 MB, 859832320 bytes, 1679360 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Now we are going to use fdisk
to delete the existing partition and create a new, larger, partition to replace it. Be sure to know whether the partition is Primary or Extended, the partition number, and the partition type. In the example below, we are working on a Primary partition and it’s is partition number 2
. Linux LVM partitions are type 8e
.
Be sure to change the type to 8e
before writing the changes to disk. I am assuming you have some experience using fdisk
, but the console log below goes through every step required. For more information the fdisk man page is a good place to start.
[root@localhost ~]# fdisk /dev/sda
Welcome to fdisk (util-linux 2.23.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): d
Partition number (1,2, default 2):
Partition 2 is deleted
Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p):
Using default response p
Partition number (2-4, default 2):
First sector (1026048-27262975, default 1026048):
Using default value 1026048
Last sector, +sectors or +size{K,M,G} (1026048-27262975, default 27262975):
Using default value 27262975
Partition 2 of type Linux and of size 12.5 GiB is set
Command (m for help): t
Partition number (1,2, default 2): 8e
Partition number (1,2, default 2):
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'
Command (m for help): p
Disk /dev/sda: 14.0 GB, 13958643712 bytes, 27262976 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000912b7
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 1026047 512000 83 Linux
/dev/sda2 1026048 27262975 13118464 8e Linux LVM
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
We are almost done. We will need to tell the kernel to rescan the partition and use it’s new size. Although the suggested command above is partprobe
this cannot be run (on CentOS7) on a partition that is in use. We will use the command partx
instead.
[root@localhost ~]# partx -u /dev/sda
Now when we run fdisk
again you will see that the block size has changed for the partition we re-created. In this case it went from 12069888 blocks to 13118464 blocks.
Step 3 - Resizing the Physical Volume
If we weren’t using LVM we could now resize the filesystem and be done. But, we are using LVM so we need to run some additional commands to use the new disk space.
The first thing we need to do is resize the physical volume. We can view the size of the physical volumes using the command pvdisplay
.
[root@localhost ~]# pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name centos
PV Size <11.51 GiB / not usable 2.00 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 2946
Free PE 0
Allocated PE 2946
PV UUID XepyHg-H23c-Qkma-2sDl-f5if-diC8-f7Gsn7
Note the PV Name /dev/sda2
and PV Size 11.51Gib above. Afer resizing the physical volume this will increase. To resize the physical volume we’ll use the pvresize
command.
[root@localhost ~]# pvresize /dev/sda2
Physical volume "/dev/sda2" changed
1 physical volume(s) resized / 0 physical volume(s) not resized
Now we’ll run pvdisplay
again and see the new size.
[root@localhost ~]# pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name centos
PV Size <12.51 GiB / not usable 2.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 3202
Free PE 256
Allocated PE 2946
PV UUID XepyHg-H23c-Qkma-2sDl-f5if-diC8-f7Gsn7
The PV Size now reads 12.51Gib and we can move on to resizing the logical volume.
Step 4 - Resizing the Logical Volume
Let’s take a look at the size of the logical volume using the lvdisplay
command.
[root@localhost ~]# lvdisplay
--- Logical volume ---
LV Path /dev/centos/root
LV Name root
VG Name centos
LV UUID 2j5NcR-5Uec-PPd3-z34J-ON18-k3d5-g2OuDw
LV Write Access read/write
LV Creation host, time localhost, 2017-12-12 11:46:22 -0500
LV Status available
# open 1
LV Size <10.71 GiB
Current LE 2741
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:0
This command will list all logical volumes on the system. In this case we are working with the root volume. Make sure you are looking at the correct volume. The two important pieces of information displayed are LV Path
and LV Size
. We can see above the size is listed as 10.71Gib.
Let’s extend the logical volume.
[root@localhost ~]# lvextend -l +100%FREE /dev/centos/root
Size of logical volume centos/root changed from <10.71 GiB (2741 extents) to <11.71 GiB (2997 extents).
Logical volume centos/root successfully resized.
This command may need a bit of additional explanation. The switch -l
tells the command we are specifying disk extents. We are telling the command to add all free extents by using +100%FREE
.
You can see in the output that the volume was extended from 10.71Gib to 11.71Gib. We can verify this using the lvdisplay
command again.
[root@localhost ~]# lvdisplay
--- Logical volume ---
LV Path /dev/centos/root
LV Name root
VG Name centos
LV UUID 2j5NcR-5Uec-PPd3-z34J-ON18-k3d5-g2OuDw
LV Write Access read/write
LV Creation host, time localhost, 2017-12-12 11:46:22 -0500
LV Status available
# open 1
LV Size <11.71 GiB
Current LE 2997
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:0
Now we can proceed to the final step.
Step 5 - Growing the Filesystem
The commands used for this step will differ depending on the filesystem in use. By default CentOS7 uses XFS, and Ubuntu user EXT4.
First let’s see what size the OS sees using df -h
.
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 11G 1.1G 9.7G 11% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 497M 0 497M 0% /dev/shm
tmpfs 497M 6.6M 490M 2% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/sda1 497M 151M 347M 31% /boot
tmpfs 100M 0 100M 0% /run/user/0
Notice that /dev/mapper/centos-root
is 11G. Let’s extend this filesystem.
The command on CentOS7 (XFS):
[root@localhost ~]# xfs_growfs /dev/mapper/centos-root
meta-data=/dev/mapper/centos-root isize=256 agcount=7, agsize=436992 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0 spinodes=0
data = bsize=4096 blocks=2806784, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 2806784 to 3068928
The command on Ubuntu (EXT4):
root@ubuntu:~# resize2fs /dev/ubuntu-vg/root
resize2fs 1.43.5 (04-Aug-2017)
Filesystem at /dev/ubuntu-vg/root is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 2
The filesystem on /dev/ubuntu-vg/root is now 2883584 (4k) blocks long.
Notice the filesystem paths are different between CentOS7 and Ubuntu. You can use the filesystem path displayed in the df -h
command.
Let’s verify our CentOS system shows the additional size for the root volume by running df -h
again.
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 12G 1.1G 11G 10% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 497M 0 497M 0% /dev/shm
tmpfs 497M 6.6M 490M 2% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/sda1 497M 151M 347M 31% /boot
tmpfs 100M 0 100M 0% /run/user/0
Our work is done. We now have the additional disk space available to use within the OS. Not quite as simple as point and click, but this would be easily scriptable.
Conclusion
What we just did was walk through the steps required to make additional disk space available within the Linux OS after extending a virtual disk in VMware (or any other hypervisor).
Again, I would not do this without having a verified backup of important data. I also would not recommend doing this live unless you don’t have any other choice or it’s a system that is not critical and easily restored.