sfdisk can be used to list partition information and alter partition tables
cat /proc/partitions to see the list of kernel recognized drivers and partitions
sfdisk -l : list information
sfdisk -l -u M : list information using MiB as unit.
sfdisk -l -u S : List information using sector (512 bytes) as unit.
Example:
sudo sfdisk -l /dev/sdc -u M
Disk /dev/sdc: 1044 cylinders, 255 heads, 63 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = mebibytes of 1048576 bytes, blocks of 1024 bytes, counting from 0
Device Boot Start End MiB #blocks Id System
/dev/sdc1 * 1 7806 7806 7993344 83 Linux
/dev/sdc2 7807+ 8190 384- 392193 5 Extended
/dev/sdc3 0 - 0 0 0 Empty
/dev/sdc4 0 - 0 0 0 Empty
/dev/sdc5 7808 8190 383 392192 82 Linux swap / Solaris
Notice "7807+" and "384-" means that the numbers are not a multiple of MiB. Therefore that partition is not MiB aligned. For Extended partition, that is OK, but for real data-holding partitions, you may want them to be MiB aligned.
This is the list by sector results:
sudo sfdisk -l /dev/sdc -u S
Disk /dev/sdc: 1044 cylinders, 255 heads, 63 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = sectors of 512 bytes, counting from 0
Device Boot Start End #sectors Id System
/dev/sdc1 * 2048 15988735 15986688 83 Linux
/dev/sdc2 15990782 16775167 784386 5 Extended
/dev/sdc3 0 - 0 0 Empty
/dev/sdc4 0 - 0 0 Empty
/dev/sdc5 15990784 16775167 784384 82 Linux swap / Solaris
Notice now there is no +/- anymore, and start/end are in sectors. This will give you exact layout of the partitions.
Write partitions:
sfdisk takes two kinds of formats as input to write partitions: the "manual" format as documented in the man page, and the "dump" format.
Use "-d" to dump the current partition table.
sudo sfdisk -d /dev/sdc
# partition table of /dev/sdc
unit: sectors
/dev/sdc1 : start= 2048, size= 15986688, Id=83, bootable
/dev/sdc2 : start= 15990782, size= 784386, Id= 5
/dev/sdc3 : start= 0, size= 0, Id= 0
/dev/sdc4 : start= 0, size= 0, Id= 0
/dev/sdc5 : start= 15990784, size= 784384, Id=82
Now you can edit this file, and then feed it back to change partitions using command "sfdisk -d /dev/sdc < part.txt", supposing that you wrote the above text to "part.txt" file.
Now some explanation of the "dump" format:
1. Empty lines are ignored
2. # and things after it is ignored (for that line)
3. "unit: sectors" is recognized as a valid command to set unit to sectors
4. Each partition line starts with the partition name, which is ignored. Then ":", then multiplle "variable-name=value" separated by ",". "bootable" is special because it is a boolean value.
5. All values have to be present. No auto calculation as in "manual" mode.
Partition Alignment
When I tried to start partitioning on the 2nd cylinder instead of the first, I ran into issues. The command was:
sfdisk /dev/sdb -H 16 -S 63
<<EOF
1,159,83
,4096,82
,,83
;
EOF
My 80GB disk does not have a multiple of 2048 sectors, because the total number of sectors is a multiple of 63, which is the typical sectors per track. So to make my partition aligned at least to 4K, I used head of 16, which gives me the cylinder size of 63*16*512bytes=63*8KiB, so my cylinder is 4KiB aligned.
The above command will produce the following error:
sfdisk: Warning: given size (4096) exceeds max allowable size (1)
sfdisk: bad input
I was very puzzled. After compiling sfdisk from source code and adding debug statements in it, I finally found out the reason: sfdisk is trying to fit the 2nd partition in the first free cylinder because it think it is free! Well it is free except for the MBR in the first sector, but I don't want my 2nd partition to there. How do we tell sfdisk that? Here comes the "undocumented dangerous option" "--in-order". If you specify the "--in-order", sfdisk will work as you intended it to.
OR, you could manually specify the start address of each partition.
So the final working command is:
sfdisk /dev/sdb --in-order -H 16 -S 63 <<EOF
1,159,83
,4096,82
,,83
;
EOF
At last, you can use "hdparm -i" to list harddrive info, including number of LBA sectors. However, this may not work on some disks.