Expanding a Linux image based filesystem

A colleague asked me how to expand a Linux filesystem captured in a (image) file. The file was named rootfs and was part of a HP QuickWeb installation. In this post I will explain the steps how I was able to extend the filesystem without losing data.

First I took a copy of the file over to my Slackware Linux workstation after which I was able to quickly determine the content of the rootfs with the file command:

file rootfs

The file command showed me the I was dealing with the ext2 filesystem.

# file rootfs
rootfs: Linux rev 1.0 ext2 filesystem data, UUID=xyz (large files)

To make sure I was dealing with a single filesystem and not an image containing several partitions and filesystems I used fdisk.

fdisk -l rootfs

Running fdisk gave the following output:

# fdisk -l rootfs

Disk rootfs: 2352 MB, 2352283648 bytes
255 heads, 63 sectors/track, 285 cylinders, total 4594304 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

Because the image file was not partitioned this confirmed I was dealing with a single filesystem.

Next step was to grow the rootfs file in order to add space required for extending the filesystem without destroying its content.

The first tool which came to mind was dd. After checking the dd man page I decided on:

dd if=/dev/zero of=rootfs bs=1M count=4096 oflag=append conv=notrunc

I used /dev/zero to add 4096 megabytes to the rootfs file. Notice the append flag to add to the existing content of the file. The man page suggested the use of conv=notrunc.

Running dd on the rootfs file gave the following output:

# dd if=/dev/zero of=rootfs bs=1M count=4096 oflag=append conv=notrunc
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 37.1787 s, 116 MB/s

Before extending the filesystem I decided to check and repair the filesystem with e2fsck:

e2fsck -f rootfs

Which resulted in:

# e2fsck -f rootfs
e2fsck 1.42.8 (20-Jun-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 3A: Optimizing directories
Pass 4: Checking reference counts
Pass 5: Checking group summary information

rootfs: ***** FILE SYSTEM WAS MODIFIED *****
rootfs: 56673/143712 files (0.2% non-contiguous), 496569/574288 blocks

After the check was I was able to extend the filesystem contained in the image with:

resize2fs rootfs

The resize command completed in no time and gave me the following output:

# resize2fs rootfs
resize2fs 1.42.8 (20-Jun-2013)
Resizing the filesystem on rootfs to 1622864 (4k) blocks.
The filesystem on rootfs is now 1622864 blocks long.

As a final check I mounted the filesystem and ran df (diskfree):

# mount rootfs /mnt/tmp/
# df -h /mnt/tmp/
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0      6.1G  1.9G  4.0G  33% /mnt/tmp

And that completed the procedure.