The Zerofox Syndicate

How to extending the disk of a CentOS 7 VM

2019-11-01

Here I explain how to expand the disk of a running CentOS 7 machine without rebooting. I am using a default CentOS 7 VM with LVM. I am running this VM on top of ESX, although the hypervisor doesn’t really matter. I am mainly focussing how to get CentOS to use newly available disk space.

Extend the VM disk.

Start with extending the disk in the hypervisor. This is relatively straightforward in ESX. First remove all the snapshots and then edit the virtual hard drive. The procedure is similar in other hypervisors.

After expanding the drive in the hypervisor I suggest creating a snapshot of the virtual machine.

The effect of a disk expansion isn’t always immediatly visible inside a VM. We can observe the OS’ point of view with the lsblk command.

[root@host ~]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
fd0               2:0    1    4K  0 disk
sda               8:0    0   40G  0 disk
├─sda1            8:1    0    1G  0 part /boot
└─sda2            8:2    0   19G  0 part
  ├─centos-root 253:0    0   17G  0 lvm  /
  └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
sr0              11:0    1 1024M  0 rom

Scan for changes in a block device

We need to nudge the OS to take another look at the SCSI block device. To rescan the 0:0:0:0 SCSI block device we can use the following command.

echo "- - -" > /sys/class/scsi_device/0\:0\:0\:0/device/rescan

With the command ls /sys/class/scsi_device/ you can list all SCSI block devices in case you are not attempting to extend 0:0:0:0.

When we execute fdisk -l /dev/sda | grep Disk we should see the new disk size.

Grow the partition

This part is tricky. If you haven’t already taken a snapshot of you VM yet, now might be a good time. We are going to overwrite (and potentialy break) the partition table.

The first step is to list our partitions. We write down the string block of our root partition. We will need this later.

[root@host ~]# fdisk -l /dev/sda
Disk /dev/sda: 42.9 GB, 42949672960 bytes, 83886080 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: 0x000cd253
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    41943039    19921920   8e  Linux LVM

In this case /dev/sda2 starts with block 2099200. We will now remove this partition and recreate it.

[root@host ~]# 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): 2
Partition 2 is deleted

Now the partion is removed. We will recreate it. Please double check the starting block. In this example I am lucky that I can use the proposed values, this is not always the case.

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 (2099200-83886079, default 2099200):
Using default value 2099200
Last sector, +sectors or +size{K,M,G} (2099200-83886079, default 83886079):
Using default value 83886079
Partition 2 of type Linux and of size 39 GiB is set

With the p command you can display your proposed changed to the partition table. Note that the Id from our LVM partition is wrongly set to 83.

Command (m for help): t
Partition number (1,2, default 2):
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'

Take one last look at the partition table. Make sure the partition Start block and id are correct. If you are ready to commit to this change press w and hit <enter>.

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.

To notify the OS of a change in the partition table we execute the partprobe command.

partprobe

The above command should work. If it does not I can only suggest you reboot.

Expanding the file system (LVM)

First we tell LVM to resize the physical volume.

[root@host ~]# pvresize /dev/sda2
  Physical volume "/dev/sda2" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized

We can confirm that this resize was succesful with pvdisplay.

[root@host ~]# pvdisplay
  --- Physical volume ---
  PV Name               /dev/sda2
  VG Name               centos
  PV Size               <39.00 GiB / not usable 2.00 MiB
  Allocatable           yes
  PE Size               4.00 MiB
  Total PE              9983
  Free PE               5120
  Allocated PE          4863
  PV UUID               bi0H73-15j6-4yTa-OrpD-cs7w-8feX-EQQ9jo

Now we need to expand the logical volume that contains our root partition. In CentOS this will either be /dev/centos/root or /dev/cl/root. Adjust the the following command accordingly.

[root@host ~]# lvextend -r -l +100%FREE /dev/centos/root
  Size of logical volume centos/root changed from <17.00 GiB (4351 extents) to <37.00 GiB (9471 extents).
  Logical volume centos/root successfully resized.
meta-data=/dev/mapper/centos-root isize=512    agcount=4, agsize=1113856 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=4455424, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
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 4455424 to 9698304

To view the effect of our changes on our logical volume we can use the lvs command.

[root@host ~]# lvs
  LV   VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root centos -wi-ao---- <37.00g
  swap centos -wi-ao----   2.00g

We can check the amount of available disk space with the df command. The -h flag so we get something human readable instead of plain bytes.

[root@host ~]# df -h /
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   37G   13G   25G  34% /

Now your disk is succesfully expanded. Hopefully you succeeded without the need of a reboot or breaking the partition table and requiring you to restore a snapshot.

Tags: linux