VMs: create partition with alignment starting at 4MiB + ending at 100%
authorMichael Prokop <mika@grml.org>
Mon, 6 Dec 2021 16:19:40 +0000 (17:19 +0100)
committerMichael Prokop <mika@grml.org>
Mon, 6 Dec 2021 17:13:14 +0000 (18:13 +0100)
Our partition creation process inside VMs used parted with "mkpart
primary ext4 2M -1", which could end up with unaligned partitions (as
reported in #185):

| (parted) mkpart primary ext4 2M -1
| Warning: The resulting partition is not properly aligned for best performance: 3906s % 4096s != 0s

This depends on the I/O settings of the underlying storage.

The mkpart start at "2M" is interpreted as 2 Megabyte (2000000 bytes or
3906 sectors) from the disk start.  The end "-1" is interpreted as 1
Megabyte (1000000 bytes or 1953 sectors) before the disk end.

On the other hand, "2MiB" is interpreted as 2 Mebibyte (2097152 bytes or
4096 sectors) from the disk start, and "100%" is interpreted as the disk
end.

Quoting from https://www.gnu.org/software/parted/manual/html_node/unit.html:

| Parted will compute sensible ranges for the locations you specify (e.g.,
| a range of +/- 500 MB when you specify the location in “G”, and a range
| of +/- 500 KB when you specify the location in “M”) and will select the
| nearest location in this range from the one you wrote that satisfies
| constraints from both the operation, the filesystem being worked on, the
| disk label, other partitions and so on.
| [...]
| Note that as of parted-2.4, when you specify start and/or end values
| using IEC binary units like “MiB”, “GiB”, “TiB”, etc., parted treats
| those values as exact, and equivalent to the same number specified in
| bytes (i.e., with the “B” suffix), in that it provides no “helpful”
| range of sloppiness. Contrast that with a partition start request of
| “4GB”, which may actually resolve to some sector up to 500MB before or
| after that point. Thus, when creating a partition, you should prefer
| to specify units of bytes (“B”), sectors (“s”), or IEC binary units
| like “MiB”, but not “MB”, “GB”, etc.

Furthermore quoting from https://www.gnu.org/software/parted/manual/html_node/mkpart.html#FOOT2:

| Cheap flash drives will be with us for a long time to come, and, for
| them, 1MiB alignment is not enough. Use at least 4MiB-aligned
| partitions. For details, see Arnd Bergman’s article,
| http://lwn.net/Articles/428584/ and its many comments.

A better default should be usage of an IEC binary unit with a
4MiB-aligned partition, so let's switch to "4MiB 100%".

Thanks: David Gnedt for the bug report and analysis, Darshaka Pathirana and Chris Hofstaedtler for further information and feedback
Closes: grml/grml-debootstrap#185

grml-debootstrap

index 2219b7b..9e5cee3 100755 (executable)
@@ -1474,7 +1474,7 @@ prepare_vm() {
     dd if="${MBRTMPFILE}" of="${TARGET}" conv=notrunc
     eend $?
   fi
     dd if="${MBRTMPFILE}" of="${TARGET}" conv=notrunc
     eend $?
   fi
-  parted -s "${TARGET}" 'mkpart primary ext4 2M -1'
+  parted -s "${TARGET}" 'mkpart primary ext4 4MiB 100%'
   parted -s "${TARGET}" 'set 1 boot on'
 
   DEVINFO=$(kpartx -asv "$TARGET") # e.g. 'add map loop0p1 (254:5): 0 20477 linear 7:0 3'
   parted -s "${TARGET}" 'set 1 boot on'
 
   DEVINFO=$(kpartx -asv "$TARGET") # e.g. 'add map loop0p1 (254:5): 0 20477 linear 7:0 3'