Monday, October 13, 2014

new sfdisk

The last partitioning tool from util-linux package without support for GPT (BSD, SGI, ...) and 4K disks was sfdisk. The situation was exactly the same like with cfdisk, it was impossible to incrementally improve the code, so the new version is written from scratch and based on libfdisk.

The most visible change is that the new sfdisk is all about sectors, it does not support obsolete Cylinder-Head-Sector addressing at all. This is no problem for users who use "--unit S", but if you still rely on old default cylinders than be careful with update. Frankly, LBA addressing is mandatory since ATA-3 (1997) and supported by Linux since beginning.

The new sfdisk also does not support some obscure or rarely used options like
--DOS, --IBM, --DOS-extended, --unhide, --show-extended, --cylinders, --heads, --sectors, --inside-outer, --not-inside-outer.

The last incompatibility is in backup mode. The old implementation uses sfdisk specific backup files. The new implementation uses the same concept like "wipefs --backup". The data are stored to ~/sfdisk-dev-offset.bak by default and it's possible to use dd(1) to restore your partition table or so. The backup files contains only data from the device, nothing else.  For example:
# sfdisk --backup /dev/sdb
Backup files:
        PMBR (offset     0, size   512): /root/sfdisk-sdb-0x00000000.bak
  GPT Header (offset   512, size   512): /root/sfdisk-sdb-0x00000200.bak
 GPT Entries (offset  1024, size 16384): /root/sfdisk-sdb-0x00000400.bak
and to restore:
 # dd if=~/sfdisk-sda-0x00000200.bak of=/dev/sdb \
      seek=$((0x00000200.bak)) bs=1 conv=notrunc 

All is described in the sfdisk man page. The another change is possibility to specify partition sizes in human readable notation {K,M,G,T...}, for example

# sfdisk /dev/sdb <<EOF
label: gpt
, 10G
, 10G

creates two 10GiB partitions. Note that default is to align all partitions to I/O limits (e.g. physical sector size). The first partition offset is by default 1MiB (e.g. 2048 512-byte-sectors). The partitions are by default aligned to megabytes. The same concept we use for fdisk and cfdisk (and parted probably too).

The default is DOS (MBR) disk label. If you want to use GPT then just add "--label gpt" to the command line or "label: gpt" to the script. The partition type shortcuts like 'L' (for Linux) or 'S' (for swap area) work for MBR as well as for GPT. If you want something else then you can use GUID for GPT or hex codes for MBR.

The new sfdisk supports nested disk labels. This is important for people who use BSD disk labels or hybrid GPT. The new command line option "--label-nested dos" forces sfdisk to modify protective MBR rather than the default GPT disk label. It means that you can manually create hybrid GPT. (No, we don't plan to add any "translate GPT to MBR" high-level feature for hybrid disks, hybrid GPT sucks.)

The nice new feature is that sfdisk allows to add new partitions to your partition table rather than always create whole partition table from scratch, all you need is the new --append command line option.

The important feature is that you can define your own output format for --list by new command line option "--output columns". sfdisk shares this new feature with fdisk where -o modifies 'p'rint output, for example:

# sfdisk --quiet --list -o DEVICE,SIZE,TYPE /dev/sda
Device      Size Type
/dev/sda1  1000M EFI System
/dev/sda2     2G Microsoft basic data
/dev/sda3   9.7G Linux swap
/dev/sda4  34.2G Microsoft basic data
/dev/sda5  63.2G Microsoft basic data
/dev/sda6  39.1G Microsoft basic data

You probably already know this concept from lsblk or findmnt. It's also supported to extend the default output by "-o+" notation, for example "fdisk --list -o+UUID /dev/sda" to see UUIDs for GPT partitions. 

Another features:
  • --part-uuid print or change GPT partition UUID
  • --part-type (or original --id) print or change partition type
  • --part-label print or changes GPT partition label (name)
  • --part-attrs print or change GPT partition attribute bites

The script parsing and --dump functionality is within libfdisk. The goal is to support partitioning dumps in fdisk and cfdisk too. It is going to be possible to "sfdisk --dump /dev/sda > foo" and then read the "foo" file to cfdisk or fdisk. And vice-versa, you can compose all your partition table by user-friendly cfdisk, save to the script file (rather than to device) and later use the file by sfdisk, etc.