Repartitioning a Standard Linux Cloud Server


Warning: Repartitioning a Cloud Server is a high-risk operation unsupported by Rackspace. Data on the server may be destroyed permanently. After repartitioning standard Cloud Server operations including backup, restore, resize to bigger size and migration may not work, and you will no longer be able to resize to a smaller server size. If you grow your server you will also need to repartition manually to use any additional space on the virtual disk. For additional information on manual and automatic disk partitioning, see Understanding and using automatic and manual disk partitioning in the Rackspace cloud.

Note: Partitioning is not an option on Performance Cloud Servers.

Backing up your Cloud Server before you proceed is highly recommended.


Partitions

A standard Rackspace Linux Cloud Server image is set up with a single root partition. This partition layout is sufficient for most servers and you usually won't need to change it. However, there are circumstances where customised partitioning is required. If you need custom partitions, read on.

One of the common Rackspace Cloud hypervisors (the backend software running everything) is Citrix Xen Server 5.x, the default for our newer stock images. If your Cloud server is running on this platform it will have one block devices defined, /dev/xvda. The /dev/xvda1 device houses the root partition with all your data and operating system. Older servers might also have a swap volume set up as /dev/xvdc.

Enter Rescue Mode

The root partition contains the active operating system, so we have to put the file system off-line before we can change its partition size. We'll do this by putting the Cloud Server in rescue mode.

All commands used in this article are based on a 512MB CentOS Cloud Server but should apply to Cloud Servers on other Linux distributions as well.

Locate Root Partition

Once you've put your server into rescue mode, log on via ssh and run this command at the command prompt:

fdisk -l | grep -B1 xvd

Output:

Disk /dev/xvdd: 536 MB, 536870912 bytes
--
    Device Boot      Start         End      Blocks   Id  System
/dev/xvdd1               1          65      522112   82  Linux swap / Solaris

Disk /dev/xvda: 20.4 GB, 20401094656 bytes
--
    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *           1        1241     9960448   83  Linux

Disk /dev/xvdb: 20.4 GB, 20401094656 bytes
--
    Device Boot      Start         End      Blocks   Id  System
/dev/xvdb1   *           1        1241     9960448   83  Linux

The output shows 4 block devices. The smallest (if present) is a swap partition for the rescue mode live Linux system. Similarly, /dev/xvda and /dev/xvdb are block devices for the root partitions. Looks confusing, but if you run:

mount | grep xvd

You'll see the output:

/dev/xvda1 on / type ext3 (rw,noatime,barrier=0)

From the output we see that /dev/xvda1 is the mounted root filesystem for the Live Linux instance, so /dev/xvdb is your server's root filesystem.

Shrink File System

Let's make sure the file system is good before we modify it by running:

fsck.ext3 -fy /dev/xvdb1

Output:

e2fsck 1.41.12 (17-May-2010)
/dev/xvdb1: recovering journal
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information

/dev/xvdb1: ***** FILE SYSTEM WAS MODIFIED *****
/dev/xvdb1: 22221/622592 files (0.3% non-contiguous), 237966/2490112 blocks

Now we'll remove journaling from the file system:

tune2fs -O ^has_journal /dev/xvdb1

Next check the current data size on the partition:

mount -oro /dev/xvdb1 /mnt; df -h /dev/xvdb1; umount /mnt

Output:

Filesystem            Size  Used Avail Use% Mounted on
/dev/xvdb1            9.4G  649M  8.3G   8% /mnt

In the example above 649MB of 9.4GB is used. We need to account for the space used by the operating system when we change the partition size. For our example we'll plan to shrink it to 4GB.

To be on the safe side we'll actually start by shrinking the root file system to a bit under our target (in this case, 3GB) to make sure it will fit the new partition. We'll expand it to 4GB once we have our partition sizes set.

Shrink the file system to 3GB with the command:

resize2fs /dev/xvdb1 3G

If successful the output will look like this:

resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/xvdb1 to 786432 (4k) blocks.
The filesystem on /dev/xvdb1 is now 786432 blocks long.

If we check the size again:

mount -oro /dev/xvdb1 /mnt; df -h /dev/xvdb1; umount /mnt

We see:

Filesystem            Size  Used Avail Use% Mounted on
/dev/xvdb1            3.0G  642M  2.2G  23% /mnt

Hooray, the root file system is changed! The new file system is much smaller than the partition it resides. You may notice the used size value has changed from before. That reflects the file system storing metadata that describes the partition - a smaller partition needs less metadata space. There is no data lost.

Shrink Partition

This is the most dangerous part of the whole task. The file system will be damaged if the disk space it requires for files is larger than partition where it resides. Make sure you have a backup of your data.

Before we make any changes we'll check the current partition layout with this command:

sfdisk -uS -l /dev/xvdb

Output:

Disk /dev/xvdb: 1240 cylinders, 255 heads, 63 sectors/track
Units = sectors of 512 bytes, counting from 0
   Device Boot    Start       End   #sectors  Id  System
/dev/xvdb1   *      2048  39843839   39841792  83  Linux
/dev/xvdb2             0         -          0   0  Empty
/dev/xvdb3             0         -          0   0  Empty
/dev/xvdb4             0         -          0   0  Empty

As you can see from the output, there is only one partition covering the whole disk. Let's save the current partition layout to a file called xvdb.out like this:

sfdisk -d /dev/xvdb > /root/xvdb.out

And use a text editor such as nano to open xvdb.out:

nano /root/xvdb.out

You will see the size of xvdb1 is 39841792, which is the maximum size for a partition on a 256MB Cloud Server. You may have a bigger Cloud Server and see a bigger partition size. The unit used in the size measurement is the "sector"; one sector is 512 bytes as you can see from the output of "sfdisk -uS -l /dev/xvdb".  That means the size value for 4GB is:

4GB / unit size = 4*1024*1024*1024 bytes / 512 bytes = 8388608

Edit the /root/xvbd.out file to change the size value for the /dev/xvdb1 partition to what we want.  For our example server the end result will look like this:

# partition table of /dev/xvdb
unit: sectors

/dev/xvdb1 : start=     2048, size= 8388608, Id=83, bootable
/dev/xvdb2 : start=        0, size=        0, Id= 0
/dev/xvdb3 : start=        0, size=        0, Id= 0
/dev/xvdb4 : start=        0, size=        0, Id= 0

We save and exit. Then apply the new partition layout back to /dev/xvdb:

sfdisk --force /dev/xvdb < /root/xvdb.out

Output:

Checking that no-one is using this disk right now ...
OK

Disk /dev/xvdb: 1240 cylinders, 255 heads, 63 sectors/track
Old situation:
Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start     End   #cyls    #blocks   Id  System
/dev/xvdb1   *      0+   1240-   1241-   9960448   83  Linux
/dev/xvdb2          0       -       0          0    0  Empty
/dev/xvdb3          0       -       0          0    0  Empty
/dev/xvdb4          0       -       0          0    0  Empty
New situation:
Warning: The partition table looks like it was made
  for C/H/S=*/76/1 (instead of 1240/255/63).
For this listing I'll assume that geometry.
Units = sectors of 512 bytes, counting from 0

   Device Boot    Start       End   #sectors  Id  System
/dev/xvdb1   *      2048   8390655    8388608  83  Linux
                start: (c,h,s) expected (26,72,1) found (0,32,33)
                end: (c,h,s) expected (1023,75,1) found (522,75,1)
/dev/xvdb2             0         -          0   0  Empty
/dev/xvdb3 0 - 0 0 Empty
/dev/xvdb4 0 - 0 0 Empty Warning: partition 1 does not end at a cylinder boundary
Successfully wrote the new partition table Re-reading the partition table ... If you created or changed a DOS partition, /dev/foo7, say, then use dd(1) to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1 (See fdisk(8).)

The /dev/xvdb1 partition is now changed to 4GB.

Align File System Size

Now we are going to expand the file system to fill the new partition, changing the file system from 3GB to 4GB.

resize2fs /dev/xvdb1

Output:

resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/xvdb1 to 1048576 (4k) blocks.
The filesystem on /dev/xvdb1 is now 1048576 blocks long.

Verify what we did by running:

mount -oro /dev/xvdb1 /mnt; df -h /dev/xvdb1; umount /mnt

Output:

Filesystem            Size  Used Avail Use% Mounted on
/dev/xvdb1            4.0G  647M  3.2G  17% /mnt

All good, the new size of 4.0G is what we expected.

Enable Journaling

Before we finish, don't forget to enable journaling for the file system, since we disabled it earlier. An EXT3 file system without journaling is EXT2 - that will still work, but it wouldn't have the safeguards of EXT3.

Enabling journaling is easy:

tune2fs -j /dev/xvdb1

Output:

tune2fs 1.41.12 (17-May-2010)

Creating journal inode: done
This filesystem will be automatically checked every -1 mounts or
0 days, whichever comes first. Use tune2fs -c or -i to override.

Exit Rescue Mode

By now we're all done shrinking the old root partition.

Go back to the Cloud Control Panel and have your server exit rescue mode. When it comes back up, connect to the server via SSH or the console.

Create New Partition

Assuming there are no problems, everything is ready. You can create new partitions from the free space you extracted from the root partition /dev/xvda1.

Before the change:

fdisk -l /dev/xvda | grep -B1 xvd

Output:

Disk /dev/xvda: 20.4 GB, 20401094656 bytes
--
 Device Boot Start End Blocks Id System
/dev/xvda1 27 110404 4194304 83 Linux

Let us create a new partition as an example. The single English letters in bold are what you need to key-in to respond to prompts:

fdisk -cu /dev/xvda
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First sector (8390656-19922943, default 8390656):
Using default value 8390656
Last sector, +sectors or +size{K,M,G} (8390656-19922943, default 19922943):
Using default value 19922943

Command (m for help): wq
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.

Let's check the partitions again:

fdisk -l /dev/xvda | grep -B1 xvd

Output:

Disk /dev/xvda: 20.4 GB, 20401094656 bytes
--
    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1              27      110404     4194304   83  Linux
/dev/xvda2          110404      262144     5766144   83  Linux

As you can see from the output above, you have a new partition /dev/xvda2. You may reboot your server:

reboot

Then log back in and format the new partition:

mkfs -t ext3 /dev/xvda2

Finally, mount it to wherever you want such as /mnt like this:

mount /dev/xvda2 /mnt

All done, let's check:

df -h

Output:

Filesystem            Size  Used Avail Use% Mounted on
/dev/xvda1            4.0G  775M  3.0G  21% /
tmpfs                 120M     0  120M   0% /dev/shm
/dev/xvda2            5.5G  140M  5.1G   3% /mnt

I hope you enjoyed this adventure. Partitioning your server can give you a lot of freedom with regard to how you allocate your space and what file systems your server uses.

Remember that if you grow your instance later, the system will not repartition for you - you'll need to manually adjust your partitions to use any new space allocated to your virtual disk.



Was this content helpful?




© 2014 Rackspace US, Inc.

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License


See license specifics and DISCLAIMER