My primary motivation to automatically partition a disk came from a script that I was working on. When I was fiddling around with Arch Linux and getting my vfio passthrough to work, I reinstalled Arch several times and I kept thinking how nice it would be just to have a script that just did it for me.

If you never installed Arch before, it’s all done through the command line. As long as you follow along the ArchWiki, it’s pretty much a breeze. All you really do is partition the disk, run pacstrap, and do some configuration. So back to the point, how do we paritition a disk through a script?

How to Actually Do It

You might already be familiar with fdisk or cfdisk. fdisk is a utility to partition disks over the command line interactively, while cfdisk is fdisk with a psuedo GUI. Introduce, sfdisk, a script oriented version of fdisk. It can automate our disk partitioning and also has an assortment of other useful features. I won’t beat around the bush, here’s how you do it.

#this is equal to 8 GiB and this is the size of the swap disk
let swap_size=16777216
#this is equal to 500 MiB and this is the size for the efi partition
let efi_size=1024000

#makes the first needed partitions
sfdisk "$disk" <<-EOF
,$efi_size,C12A7328-F81F-11D2-BA4B-00A0C93EC93B,*
,$swap_size,0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
EOF

Normally when we think about sizes of disks, we talk about the number of Gigabytes or Megabytes a disk has. sfdisk on the contrary takes sectors as an argument. A sectors on a disk that we typically use (Hard Drives and Solid State Drives) are 512 bytes. Also, it’s important to note that in terms of digital storage, 1024 bytes is equal to one "Kibibyte", it’s symbol being KiB. Therefore, 2 sectors are equal to 1 KiB. In my case, I wanted to make a 500 MiB EFI partition and a 8 GiB swap partition. Consider the following table,

Sectors Bytes KiB MiB GiB

1

512

2

1028

1

2048

1024²

1024

1

2097152

1024³

1024²

1024

1

By using this table, we can calculate how many sectors are needed in order to make our desired partitions. So for example, the first partition I make is an EFI partition. Since it’s 500 MiB and 2048 sectors are equal to 1 MiB. I mulitply 2048 to get 102400 sectors. Notice the EOF and that it’s a multi-line command with mulitple parameters. The format for each line is,

<start> <size> <id> <bootable> <c,h,s> <c,h,s>

Everything is seperated by a comma. You can ignore the <c,h,s> portion and if you want to know more, just refer to the man page. The start portion refers to what sector to start on, you should leave this empty by default and let sfdisk figure it out. We only care about the three after. Size, id, and bootable. In my example with the EFI partition, we determined the size to be 1024000 because that’s how many sectors we need. Our id is C12A7328-F81F-11D2-BA4B-00A0C93EC93B , this comes from the GPT partition table. Lastly, we want to make the EFI partition bootable, it’s assumed not to be by default so we just tidy it up with the asterisk symbol.

Final Thoughts and Notes

Because of partition allignment, you’ll notice that even though even though you took only a certain amount of X sectors, it doesn’t start on the sector you thought it would. If the amount of sectors are not specified, sfdisk by default will take all the space available. In addition, sfdisk can also append partitions instead of rewriting the whole table. The way I have my script work is that it makes the partitions with the known amount of space needed and finishes it up by appending one last partition with all the space left.

It’s worth mentioning that one of these useful features is copying partition tables to another disk. Suppose you have 5 same disks and you want them all to be partitioned the same. With sfdisk it’s as simple as,

sfdisk -d /dev/sda > table.out
sfdisk -d /dev/sdb < table.out

After reading this you should have the tools (or the idea) to be able to automate partitioning. Good luck!