Technical background

Wikipedia disk partitioning

The EBR/EPBR

Each logical partition is preceded by an Extended Boot Record (EBR) a.k.a. Extended Partition Boot Record (EPBR) of one sector followed by a number of unused sectors. There are commonly 62 unused sectors which, with the EBR, fill a historical 63 sector track.

Which partition management utility to use?

From the fdisk man page:

There are several *fdisk programs around. Each has its problems and strengths. Try them in the order cfdisk, fdisk, sfdisk. (Indeed, cfdisk is a beautiful program that has strict requirements on the partition tables it accepts, and produces high quality partition tables. Use it if you can. fdisk is a buggy program that does fuzzy things - usually it happens to produce reasonable results. Its single advantage is that it has some support for BSD disk labels and other non-DOS partition tables. Avoid it if you can. sfdisk is for hackers only -- the user interface is terrible, but it is more correct than fdisk and more powerful than both fdisk and cfdisk. Moreover, it can be used noninteractively.)

These days there also is parted. The cfdisk interface is nicer, but parted does much more: it not only resizes partitions, but also the filesystems that live in them.

Find an exact partition size

The easiest way to find an exact partition size is to read the /sys/block/sd*/sd*/size file, for example cat /sys/block/sda/sda2/size.  This gives the size of the sda2 partition in sectors.

TODO: check what happens with a 4 kB sector size HDD.  If /sys/block/sd*/sd*/size then lists the size in 4k sectors, how best to find the sector size?  fdisk?

The alternatives are:

The partition size shown by fdisk (in 1024 bytes Blocks) is rounded; if an exact partition size is required it can be calculated by End - Start + 1 (fdisk shows End and Start in sectors). For example:

fdisk -l /dev/sdb 
[snip] 
Device Boot Start End Blocks Id System 
[snip] 
/dev/sdb7 1224268508 1250261614 12996553+ 83 Linux

End - Start + 1 is 1250261614 - 1224268508 + 1 = 25993107.

Exact size in sectors, converted to blocks: 25993107 / 2 = 12996553.5

The most informative listing is produced by the print option -P with the display sectors option -s (other units are rounded for display).

In the output, illustrated below:

root@CW8:~# cfdisk -Ps /dev/sdb
Partition Table for /dev/sdb
 First Last
 # Type Sector Sector Offset Length Filesystem Type (ID) Flag
-- ------- ----------- ----------- ------ ----------- -------------------- ----
[snip]
 7 Logical 1224268445* 1250261614* 63 25993170 Linux (83) None

Length less Offset: 25993170 - 63 = 25993107.

Create a partition with an exact size