Specifying partition sizes in the Debian Installer

Introduction

Rather inconveniently, the Debian installer and the various other commands (e.g. lvs, fdisk), by default, disagree about how many bytes in 1 kilobyte or 1 megabyte, etc. Getting the Debian installer to create a logical volume of size ‘1G’ results in the unexpected and rather ugly output from lvs:

~# lvs
LV   VG  Attr       Lsize
root vg0 -wi-a----- 952.00m
~#

and getting the Debian installer to create a partition of size ‘550M’ resulted in this output from fdisk:

# fdisk -l /dev/nvme0n1 | egrep '(Device|EFI)'
Device           Start       End   Sectors  Size Type
/dev/nvme0n1p1    2048   1075199   1073152  524M EFI System
# 

Since I solved this and, having seen other people struggling (e.g. here or here), I thought this very short article might prove useful. A bug report regarding this disagreement has been submitted to Debian.

Analysis

1KB used to be 1024 bytes, but these days it isn’t: these days it is 1000 bytes (although strictly, 1kB, with a little ‘k’, is 1000 bytes). If we want to refer to 1024 bytes then we use 1KiB.

1MB used to be 1024 x 1024 bytes but these days it isn’t: these days it is 1000 x 1000 bytes (but not with a little ‘m’).  If we want to refer to 1024 x 1024 bytes then we use 1MiB.

And so on! Full details can be found in a nice table in Wikipedia.

This analysis focuses on the disgreement regarding the default size unit between the Debian installer and LVM, rather than the disagreement between the Debian installer and other commands (e.g. fdisk).

In the Debian installer, when creating a logical volume, if we enter the size as ‘1G’ (or ‘1g’) then we get a logical volume of around 1000000000 bytes. We can verify this extremely crudely, by pressing ALT-F2 (to flip to the second VT), ENTER (to activate shell) and then running lvs:

~# lvs
LV   VG  Attr       Lsize
root vg0 -wi-a----- 952.00m
~#

The lower-than-1000-number (952 as in ‘952.00m’) indicates that the requested number (1 as in ‘1G’) was first multiplied by a power of 1000 (by the Debian installer) but then divided by a power of 1024 (by lvs), resulting in the number (ignoring the powers of 1000 or 1024) going down a bit (from 1 to 952).

Alignment

The Debian installer or lvcreate, which the Debian installer presumably delegates to, is still doing some kind of alignment. Perhaps it is the Debian installer thinking “I bet they want the volume to be aligned on a 4KiB boundary so that a filesystem will fit in it as snuggly as possible, so I’m going to round your request accordingly” or perhaps it is lvcreate thinking “You might have asked for a size in some unit or other, but internally I use ‘extents’ and those are 4MiB in size and I only allocate a whole number of them, so I’m going to round your request accordingly.”

Get the Debian installer to create a logical volume of size ‘1067448368B’ (note that ‘B’ on the end!): if this number was rounded to a 4KiB boundary by the Debian installer then it would be rounded down to 1067446272B or maybe up to 1067450368B; but if it was rounded to a 4MiB boundary by lvcreate then it would be rounded down to 1065353216B or maybe up to 1069547520B. So which is it?

~# lvs --units=B
LV   VG   Attr      Lsize
root vg0 -wi-a----- 1065353216B
~#

So rounding is done downwards to a 4MiB boundary, which makes me think that the rounding was done by lvcreate. Okay, there’s quite a lot of supposition in there and, in any case, alignment and rounding for reasons of alignment are not the main concern of this short article.

The solution

The above analysis already hinted at the solution: when talking to the Debian installer, always specify logical volume sizes as multiples of 4MiB, but in bytes!

For example: instead of entering size ‘1G’: do a little bit of maths (1 x 1024 x 1024 x 1024) and then enter  ‘1073741824B’, which results in lvs displaying:

~# lvs
LV   VG  Attr       Lsize
root vg0 -wi-a----- 1.00g
~#

Much cleaner!

See also