gpart trying to force MBR partitions to be cylinder aligned


Well-Known Member

Reaction score: 70
Messages: 394

While attempting to use the gpart program to partition devices using the MBR scheme I discovered that it seems to be enforcing a certain alignment of partitions, which at first glance appeared to alignment to (fictitious) cylinder boundaries according to the reported disk geometry, as was required back in the days before Logical Block Addressing.

I was considering submitting a PR for this forced alignment, as it is inconvenient and no longer necessary with LBA addressing. Even Microsoft sees fit to disregard reported CHS geometry and instead starts the first MBR partition at an offset of exactly 2048 sectors in Windows 7.

In the course of drawing up my test case for the "How to repeat" PR field, I then discovered that the cylinder alignment seems to be done wrong anyway.

Consider the following test:

  1. Create a memory disk with a hard disk-like geometry (63 sectors/track x 4 heads/cylinder = 252 sectors/cylinder)
  2. Create an MBR partitioning scheme on the disk
  3. Create a single MBR partition spanning the device
  4. Examine the partition table

# mdconfig -a -t malloc -x 63 -y 4 -s 128m
root@atom:/root # diskinfo -v md0
        512             # sectorsize
        134217728       # mediasize in bytes (128M)
        262144          # mediasize in sectors
        0               # stripesize
        0               # stripeoffset
        1040            # Cylinders according to firmware.
        4               # Heads according to firmware.
        63              # Sectors according to firmware.

root@atom:/root # gpart create -s mbr md0
md0 created

root@atom:/root # gpart add -t freebsd md0
md0s1 added

root@atom:/root # gpart show md0
=>    63  262081  md0  MBR  (128M)
      63  262080    1  freebsd  (128M)
  262143       1       - free -  (512B)

Note that the MBR scheme is reserving the first 63 sectors of the device, then starting the first partition at sector 63 (numbering starts from zero). This seems to be incorrect behaviour. When using the MBR scheme strictly, the whole of the first cylinder should be reserved, which for this disk's geometry means 252 sectors (63 sectors x 4 heads).

I then tried to create a partition with an exact sector offset of 2048 (as recent version of Windows do):

root@atom:/root # gpart delete -i 1 md0
md0s1 deleted

root@atom:/root # gpart add -t freebsd -b 2048 md0
md0s1 added

root@atom:/root # gpart show md0
=>    63  262081  md0  MBR  (128M)
      63    2016       - free -  (1M)
    2079  260064    1  freebsd  (127M)
  262143       1       - free -  (512B)

Despite specifying an offset of exactly 2048 sectors, the new partition starts at sector 2079. I initially thought that gpart was enforcing a cylinder alignment, until I realised that sector 2079 is NOT at a cylinder boundary anyway.

2079 happens to be (252*8)+63, so it's equivalent to an eight cylinders plus the 63 sector reservation.

This raises two questions in my mind.

  1. Why does gpart still try to enforce CHS partition alignment in this LBA era?
  2. If there is a good reason for continuing to force CHS alignment, shouldn't it at least be done right?

Is my analysis correct here? Have I stumbled across an implementation error?


Beastie Himself

Reaction score: 3,706
Messages: 13,851

1. For standards compliance and backwards compatibility.
2. It's more likely that it is being done right and it only appears wrong. (Often heard in computer classes: "My program doesn't work right, there must be a bug in the compiler!")

3. Only use MBR when forced (gmirror(8)). GPT is so much easier and much more versatile.