Linux Partitioning

From trapsink.com
Jump to: navigation, search


Overview

After understanding the design of how x86 Storage works the next logical step is learning and using the various utilities to manipulate the MBR/GPT and partitions themselves. We'll focus on the most common utilities herein and common tasks and how they differ and their use with both partition types.


MBR vs. GPT

This topic is covered in detail in the Linux x86 Storage article; a quick recap of the basics:

Purpose MBR GPT
Max Partitions 4 Primary or
3 Primary, 1 Extended, Unlimited Logical
128
Max Size 2 TiB ((2^32)*512 bytes) 8 ZiB ((2^64)*512 bytes)

Extrapolating from this table we can then make a set of rules to live by:

  • MBR format is limited to 2 TiB
  • GPT format is limited to 8 ZiB
  • Use GPT format if your storage is greater than 2 TiB
  • Use GPT if your storage could grow larger than 2 TiB
  • If a 4th MBR partition is marked Primary, you cannot use Extended
  • If 3 MBR Primary partitions exist, make the 4th one Extended rest of device
  • Logical MBR partitions 5+ live inside the 4th Extended partition
  • Adding a new Logical partition requires growing the Extended partition first


MBR Extended/Logical Partitions

Having only 4 primary partitions is a limit of the original MBR design - as such, an extension was invented called the extended partition with a very wide open design. The 4th primary partition is created as a type extended which points to the first Extended Boot Record (EBR) of the first logical partition within. The extended partition is normally created with the rest of the disk as it's size, it will contain logical partitions inside.

Each EBR contains a pointer to the next EBR (along with it's logical partition info) which allows chaining EBRs together. The number of logical partitions within an extended partition is limited only by the amount of available disk space in the extended partition; all of this work is handled by the various tools and does not need to be manually manipulated by the end user.


Partition Alignment

With the traditional design of a 512-byte sector, starting the first partition at LBA 63 poses no problem in alignment of the physical device (sometimes called the radial geometry) with the logical use by the CPU. Modern devices are starting to use 4096-byte (4k) sector sizes[1] - and in the case of SSD possibly 8192-bytes (8k), sometimes referred to as pages to match the CPU terminology. Externally they may emulate 512-byte sectors for compatibility (called 512e mode) but internally these devices are working with 4096.[2]

Starting a partition at LBA 63 with 4k pages it problematic -- mathematically this is one 512-byte sector short of a natural 4096 boundary of the physical geometry. If history had worked out better, using LBA 64 would have worked out mathematically:

(63*512)/4096 = 7.8750
(63*512)/8192 = 3.9375

(64*512)/4096 = 8.0000
(64*512)/8192 = 4.0000

To overcome this issue, in modern use the first partition is started with at LBA 2048 - with a 512-byte sector this is 1 MiB, or 256 pages of a 4096-byte sector. This conservative approach allows for future changes that are not foreseen today, allowing enough space and performing meticulous boundary alignment on the classic power of 2^8. SSD drives use multiples of 128 KiB, 256 KiB or 512 KiB depending on device, again creating a natural alignment mechanism.[3]

On a modern Linux distribution the userspace tools described below understand these alignment needs and default to using 2048 sector offset when creating the first partition on a drive.


Common Tools

fdisk

The fdisk utility is the classic partitioning tool. It's usage is based around a menu driven text interface; all changes performed are held into memory until a command is issued to write them out to disk; this technique allows one to cancel/exit if desired without changes, making it an enticing tool to use. The fdisk binary itself is part of the util-linux (or util-linux-ng) package of tools that also includes utilities like fsck, mount and umount.

One of the most important things to note about using fdisk: the version shipped on most enterprise class distributions (RHEL/CentOS for instance) tends to be an older but stable version. The downside is that these older stable releases only support the MBR (aka "dos" or "msdos") style and partition design, limiting your disk to 2 TiB. The most recent fdisk release are beginning to support GPT style, but as they are not yet packaged as for these distros means another tool must be used.

Use the -c and -u options to fdisk to disable DOS compatibility mode (C/H/S) and use Sector mode. These options can also be toggled while in fdisk with the c and u commands.


parted

The parted utility works the opposite of fdisk; as commands are issued the changes are made, whether it's used in pure commandline-only mode or when using the menu driven interface. This concept tends to make the usage of parted a bit scary to the beginning tech, and rightly so - once you do it, it's done. No backing out of a mistake (easily) like with fdisk.

The draw to parted tends to come in two parts: it's easily commandline scriptable and it fully supports GPT style disks (as well as MBR). This makes it the current de-facto utility for dealing with storage larger than 2 TiB and GPT partitions (required for UEFI). The parted package also includes the partprobe tool that many like.


gdisk

The gdisk utility (sometimes called gptdisk or GPT fdisk) is a newer tool designed to combine the two worlds of fdisk and parted; it provides a bit of commandline and a bit of menu driven interface. It allows all the GPT functionality but with the capability of staging in memory first before writing to disk, allowing for an exit without write as needed. The gdisk package includes complementary targeted tools such as cgdisk, sgdisk and fixparts which are designed for GPT/MBR manipulation

One of the largest draws to gdisk is it's ability to repair (or attempt to repair) corrupted or broken MBR and GPT partition style types. It can extract and back up partition tables, load them from backups, repair the primary GPT from the secondary copy, convert GPT to MBR and all sorts of advanced features. The use of gdisk in certain situations can achieve results that fdisk and parted cannot.

At this time the gdisk package is hosted via the EPEL project for RHEL/CentOS distributions and is not present in the standard vendor repositories. Conversely the Ubuntu LTS repositories do contain it, however they may have an older version (0.8.1 for 12.04 LTS). If working on GPT disks be sure and use a stable relatively bug-free version.

partx

The partx utility is useful for triggering the kernel subsystems to add/remove device nodes based on the partition map of a block device. It's akin to the partprobe tool however works a bit differently; in general it's a better choice than partprobe due to it's design and integration with the kernel. The most typical usage is to add new partition device nodes after new partitions were created, or delete in the reverse scenario. Normally these functions are handled by fdisk/parted/gdisk but in some cases they are not.

For example - if a device has partitions and devices nodes such as /dev/xvdb1, /dev/xvdb2, etc. and you utilize the zap feature of gdisk to zero out a disk, this does not trigger cleanup of the device nodes. Running partx -d /dev/xvdb will trigger a kernel level cleanup and remove them at runtime - likewise, it's common using fdisk /dev/sda to make a new partition results in an ioctl error when saving. You can use partx -a /dev/sda to trigger a kernel level refresh to create your new /dev/sdaX device node entry.


Usage Comparison

Utilizing fdisk and gdisk menu driven interfaces are nearly identical; while parted has a menu interface, the commands typed are the same as on the commandline scripted mode. A quick comparison of the most common operations being performed:

Purpose fdisk parted gdisk
List Partitions fdisk -cul /dev/xvdb parted /dev/xvdb unit s print gdisk -l /dev/xvdb
Create MBR or GPT fdisk -cu /dev/xvdb
o, w
parted -s -- /dev/xvdb mkpart table gpt gdisk /dev/xvdb
o, w
Create First Partition fdisk -cu /dev/xvdb
n, p, 1, 2048, size, w
parted -s -- /dev/xvdb mkpart primary 2048s 100% gdisk /dev/xvdb
n, 1, 2048, size, type, w
Set Partition to LVM fdisk -cu /dev/xvdb
t, 1, 8e, w
parted -s -- /dev/xvdb set 1 lvm on gdisk /dev/xvdb
t, 1, 8e00, w
Delete Partition fdisk -cu /dev/xvdb
d, 1, w
parted -s -- /dev/xvdb rm 1 gdisk /dev/xvdb
d, 1, w


Resizing Partitions

Resizing partitions is typically encountered when a disk is grown (expanded) or shrunk (reduced); remember that a higher level infrastructure sits on top of the partitions themselves in almost all cases. Given that, remember to take precautions such as:

  • If reducing, unmount the filesystem or make it inactive as required for safety
  • If reducing, resize the filesystem (ext3, ext4, etc.) before the container/partition
  • If reducing, reduce the container (LVM, etc.) before the partition
  • If expanding, expand the container (LVM, etc.) after the partition
  • If expanding, resize the filesystem (ext3, ext4, XFS, etc.) after the container/partition
  • Not all filesystem types can be reduced or expanded! XFS for example cannot be reduced

In practice using parted is the best tool for the job; however, remember that parted is a one shot tool - changes are immediate. Use gdisk for GPT or fdisk for MBR disks if you need to stage the work and double check it before executing. Do not use these tools to resize the filesystem itself! For example the parted tool has a resize command that works on some filesystem types and not others, and no way to ignore the filesystem.


Advanced Examples

Expanding MBR Primary

Warning: all data could be lost if this is done incorrectly! Pay very close attention to your start/end sectors and math

  • Scenario: MBR, 3 Primary partitions
  • Task: Increase partition 3 size +10G

Unmount the partition and record the layout; for this example only I'll show the disk in GiB to help in understanding the sector math first; we'll unmount it and fsck it to ensure the filesystem is OK before starting.

# df -h | grep xvdb3
/dev/xvdb3      9.9G  151M  9.2G   2% /mnt

# umount /mnt

# parted -s -- /dev/xvdb unit GiB print
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvdb: 100GiB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start    End      Size     Type     File system  Flags
 1      0.00GiB  10.0GiB  10.0GiB  primary
 2      10.0GiB  20.0GiB  10.0GiB  primary
 3      20.0GiB  30.0GiB  10.0GiB  primary  ext4

# fsck -fC /dev/xvdb3 
fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
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/xvdb3: 11/655360 files (0.0% non-contiguous), 79663/2621440 blocks         

Now let's do the work - first, the geometry needs to be recorded in sector mode as we must precisely recreate the starting sector of the partition:

# parted -s -- /dev/xvdb unit s print
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvdb: 209715200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start      End        Size       Type     File system  Flags
 1      2048s      20973568s  20971521s  primary
 2      20973569s  41945089s  20971521s  primary
 3      41945090s  62916610s  20971521s  primary  ext4

We use the built-in functionality of parted to simple change the starting and ending sectors. We will add 20971520 sectors (10 GiB @ 512-byte sector size) to the end of partition 3. We then tell parted to use the same starting sector (41945090s) and new ending sector (83888130s) we just computed.

Note that the numerical value ends in s to denote sectors! Do not forget your trailing s. Lastly, we resize (grow) the ext4 filesystem on top of it to the new size.

# echo "62916610 + 20971520" | bc -l
83888130

# parted -s -- /dev/xvdb rm 3
# parted -s -- /dev/xvdb mkpart primary 41945090s 83888130s
# resize2fs /dev/xvdb3 
# mount /dev/xvdb3 /mnt

# parted /dev/xvdb unit s print
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvdb: 209715200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start      End        Size       Type     File system  Flags
 1      2048s      20973568s  20971521s  primary
 2      20973569s  41945089s  20971521s  primary
 3      41945090s  83888130s  41943041s  primary  ext4

# df -h | grep mnt
/dev/xvdb3       20G  156M   19G   1% /mnt


Adding MBR Logical

Warning: all data could be lost if this is done incorrectly! Pay very close attention to your start/end sectors and math

  • Scenario: MBR, 3 Primary partitions, 1 Extended partition, 1 Logical partition
  • Task: Increase Extended partition, add new Logical partition

This builds upon the basic expansion of a primary partition concept, however the parted resize command is our saving grace; if it were done 100% manually (say, with fdisk) the process would go like this:

  1. Record geometry
  2. Delete Logical partition 1
  3. Delete Extended partition
  4. Recreate Extended partition larger
  5. Recreate Logical partition 1
  6. Add new Logical partition 2

Using parted however allows us to magically resize the Extended partition without having to perform all of the above steps. Once again, pay attention to your exact geometry and math!

# parted /dev/xvdb unit s print
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvdb: 209715200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start      End        Size       Type      File system  Flags
 1      2048s      20973568s  20971521s  primary
 2      20973569s  41945089s  20971521s  primary
 3      41945090s  62916610s  20971521s  primary   ext4
 4      62916611s  83888131s  20971521s  extended
 5      62918659s  83888131s  20969473s  logical   ext4

Notice the Start of 4 (Extended) and 5 (Logical) do not match - watch out for this, especially if you intended to resize 5 after growing 4. We will add 10G (20971520s) to the end of 4, then add a new 6 (Logical) using this new space starting after the existing 5. Note that I am adding 2048 to the ending sector of 5 to determine my start of 6 for optimal performance (in theory - this disk is misaligned starting at partition 2 already):

# echo "83888131 + 20971520" | bc -l
104859651

# parted -s -- /dev/xvdb resize 4 62916611s 104859651s

# parted /dev/xvdb unit s print
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvdb: 209715200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start      End         Size       Type      File system  Flags
 1      2048s      20973568s   20971521s  primary
 2      20973569s  41945089s   20971521s  primary
 3      41945090s  62916610s   20971521s  primary   ext4
 4      62916611s  104859651s  41943041s  extended
 5      62918659s  83888131s   20969473s  logical   ext4

# parted -s -- /dev/xvdb mkpart logical 83890179s 104859651s

# parted  /dev/xvdb unit s print
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvdb: 209715200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start      End         Size       Type      File system  Flags
 1      2048s      20973568s   20971521s  primary
 2      20973569s  41945089s   20971521s  primary
 3      41945090s  62916610s   20971521s  primary   ext4
 4      62916611s  104859651s  41943041s  extended
 5      62918659s  83888131s   20969473s  logical   ext4
 6      83890179s  104859651s  20969473s  logical


Zapping Devices

Zapping is the concept of completely wiping all traces of a MBR and/or GPT to result in clean device, as if it were brand new. All data is lost, use with caution! Use gdisk for this need:

# gdisk /dev/xvdb
GPT fdisk (gdisk) version 0.8.10

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): x

Expert command (? for help): z
About to wipe out GPT on /dev/xvdb. Proceed? (Y/N): Y
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
Blank out MBR? (Y/N): Y


References


Citations

  1. http://www.anandtech.com/show/2888
  2. https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/ch-iolimits.html
  3. http://blog.nuclex-games.com/2009/12/aligning-an-ssd-on-linux/