summaryrefslogtreecommitdiffstats
path: root/tools/list-discoverable-partitions.py
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-11-18 15:09:30 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-11-19 18:49:46 +0100
commit00db9a114eed92a9f0badaa72e1b86ca276f5ee3 (patch)
treeef32e0a927eb0a172192f836ef41cdec92f28a91 /tools/list-discoverable-partitions.py
parentshared/gpt: ARM_64 → ARM64 (diff)
downloadsystemd-00db9a114eed92a9f0badaa72e1b86ca276f5ee3.tar.xz
systemd-00db9a114eed92a9f0badaa72e1b86ca276f5ee3.zip
docs: generate table from header using a script
This adds a helper script: $ python3 tools/list-discoverable-partitions.py <src/shared/gpt.h <!-- generated with tools/list-discoverable-partitions.py --> | Partition Type UUID | Name | Allowed File Systems | Explanation | |---------------------|------|----------------------|-------------| | _Root Partition (Alpha)_ | `6523f8ae-3eb1-4e2a-a05a-18b695ae656f` | [Root Partition] | [Root Partition more] | | _Root Partition (ARC)_ | `d27f46ed-2919-4cb8-bd25-9531f3c16534` | ditto | ditto | ... The output can be pasted into the markdown file. I think this works better than trying to match the two lists by hand.
Diffstat (limited to 'tools/list-discoverable-partitions.py')
-rw-r--r--tools/list-discoverable-partitions.py181
1 files changed, 181 insertions, 0 deletions
diff --git a/tools/list-discoverable-partitions.py b/tools/list-discoverable-partitions.py
new file mode 100644
index 0000000000..30e37611a8
--- /dev/null
+++ b/tools/list-discoverable-partitions.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+import re
+import sys
+import uuid
+
+HEADER = f'''\
+<!-- generated with {sys.argv[0]} -->
+| Partition Type UUID | Name | Allowed File Systems | Explanation |
+|---------------------|------|----------------------|-------------|
+'''
+
+ARCHITECTURES = {
+ 'ALPHA': 'Alpha',
+ 'ARC': 'ARC',
+ 'ARM': '32-bit ARM',
+ 'ARM64': '64-bit ARM/AArch64',
+ 'IA64': 'Itanium/IA-64',
+ 'LOONGARCH64': 'LoongArch 64-bit',
+ 'MIPS_LE': '32-bit MIPS LittleEndian (mipsel)',
+ 'MIPS64_LE': '64-bit MIPS LittleEndian (mips64el)',
+ 'PPC': '32-bit PowerPC',
+ 'PPC64': '64-bit PowerPC BigEndian',
+ 'PPC64LE': '64-bit PowerPC LittleEndian',
+ 'RISCV32': 'RISC-V 32-bit',
+ 'RISCV64': 'RISC-V 64-bit',
+ 'S390': 's390',
+ 'S390X': 's390x',
+ 'TILEGX': 'TILE-Gx',
+ 'X86': 'x86',
+ 'X86_64': 'amd64/x86_64',
+}
+
+TYPES = {
+ 'ROOT' : 'Root Partition',
+ 'ROOT_VERITY' : 'Root Verity Partition',
+ 'ROOT_VERITY_SIG' : 'Root Verity Signature Partition',
+ 'USR' : '`/usr/` Partition',
+ 'USR_VERITY' : '`/usr/` Verity Partition',
+ 'USR_VERITY_SIG' : '`/usr/` Verity Signature Partition',
+
+ 'ESP': 'EFI System Partition',
+ 'SRV': 'Server Data Partition',
+ 'VAR': 'Variable Data Partition',
+ 'TMP': 'Temporary Data Partition',
+ 'SWAP': 'Swap',
+ 'HOME': 'Home Partition',
+ 'LINUX_GENERIC': 'Generic Linux Data Partition',
+ 'XBOOTLDR': 'Extended Boot Loader Partition',
+}
+
+DESCRIPTIONS = {
+ 'ROOT': (
+ 'Any native, optionally in LUKS',
+ 'On systems with matching architecture, the first partition with this type UUID on the disk '
+ 'containing the active EFI ESP is automatically mounted to the root directory <tt>/</tt>. '
+ 'If the partition is encrypted with LUKS or has dm-verity integrity data (see below), the '
+ 'device mapper file will be named `/dev/mapper/root`.'),
+ 'USR': (
+ 'A dm-verity superblock followed by hash data',
+ 'Contains dm-verity integrity hash data for the matching root partition. If this feature is '
+ 'used the partition UUID of the root partition should be the first 128 bits of the root hash '
+ 'of the dm-verity hash data, and the partition UUID of this dm-verity partition should be the '
+ 'final 128 bits of it, so that the root partition and its Verity partition can be discovered '
+ 'easily, simply by specifying the root hash.'),
+ 'ROOT_VERITY': (
+ 'A serialized JSON object, see below',
+ 'Contains a root hash and a PKCS#7 signature for it, permitting signed dm-verity GPT images.'),
+ 'USR_VERITY': (
+ 'Any native, optionally in LUKS',
+ 'Similar semantics to root partition, but just the `/usr/` partition.'),
+ 'ROOT_VERITY_SIG': (
+ 'A dm-verity superblock followed by hash data',
+ 'Similar semantics to root Verity partition, but just for the `/usr/` partition.'),
+ 'USR_VERITY_SIG': (
+ 'A serialized JSON object, see below',
+ 'Similar semantics to root Verity signature partition, but just for the `/usr/` partition.'),
+
+ 'ESP': (
+ 'VFAT',
+ 'The ESP used for the current boot is automatically mounted to `/efi/` (or `/boot/` as '
+ 'fallback), unless a different partition is mounted there (possibly via `/etc/fstab`, or '
+ 'because the Extended Boot Loader Partition — see below — exists) or the directory is '
+ 'non-empty on the root disk. This partition type is defined by the '
+ '[UEFI Specification](http://www.uefi.org/specifications).'),
+ 'XBOOTLDR': (
+ 'Typically VFAT',
+ 'The Extended Boot Loader Partition (XBOOTLDR) used for the current boot is automatically '
+ 'mounted to <tt>/boot/</tt>, unless a different partition is mounted there (possibly via '
+ '<tt>/etc/fstab</tt>) or the directory is non-empty on the root disk. This partition type '
+ 'is defined by the [Boot Loader Specification](https://systemd.io/BOOT_LOADER_SPECIFICATION).'),
+ 'SWAP': (
+ 'Swap, optionally in LUKS',
+ 'All swap partitions on the disk containing the root partition are automatically enabled. '
+ 'If the partition is encrypted with LUKS, the device mapper file will be named '
+ '`/dev/mapper/swap`. This partition type predates the Discoverable Partitions Specification.'),
+ 'HOME': (
+ 'Any native, optionally in LUKS',
+ 'The first partition with this type UUID on the disk containing the root partition is '
+ 'automatically mounted to `/home/`. If the partition is encrypted with LUKS, the device '
+ 'mapper file will be named `/dev/mapper/home`.'),
+ 'SRV': (
+ 'Any native, optionally in LUKS',
+ 'The first partition with this type UUID on the disk containing the root partition is '
+ 'automatically mounted to `/srv/`. If the partition is encrypted with LUKS, the device '
+ 'mapper file will be named `/dev/mapper/srv`.'),
+ 'VAR': (
+ 'Any native, optionally in LUKS',
+ 'The first partition with this type UUID on the disk containing the root partition is '
+ 'automatically mounted to `/var/` — under the condition that its partition UUID matches '
+ 'the first 128 bits of `HMAC-SHA256(machine-id, 0x4d21b016b53445c2a9fb5c16e091fd2d)` '
+ '(i.e. the SHA256 HMAC hash of the binary type UUID keyed by the machine ID as read from '
+ '[`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html). '
+ 'This special requirement is made because `/var/` (unlike the other partition types '
+ 'listed here) is inherently private to a specific installation and cannot possibly be '
+ 'shared between multiple OS installations on the same disk, and thus should be bound to '
+ 'a specific instance of the OS, identified by its machine ID. If the partition is '
+ 'encrypted with LUKS, the device mapper file will be named `/dev/mapper/var`.'),
+ 'TMP': (
+ 'Any native, optionally in LUKS',
+ 'The first partition with this type UUID on the disk containing the root partition is '
+ 'automatically mounted to `/var/tmp/`. If the partition is encrypted with LUKS, the '
+ 'device mapper file will be named `/dev/mapper/tmp`. Note that the intended mount point '
+ 'is indeed `/var/tmp/`, not `/tmp/`. The latter is typically maintained in memory via '
+ '<tt>tmpfs</tt> and does not require a partition on disk. In some cases it might be '
+ 'desirable to make `/tmp/` persistent too, in which case it is recommended to make it '
+ 'a symlink or bind mount to `/var/tmp/`, thus not requiring its own partition type UUID.'),
+ 'LINUX_GENERIC': (
+ 'Any native, optionally in LUKS',
+ 'No automatic mounting takes place for other Linux data partitions. This partition type '
+ 'should be used for all partitions that carry Linux file systems. The installer needs '
+ 'to mount them explicitly via entries in <tt>/etc/fstab</tt>. Optionally, these '
+ 'partitions may be encrypted with LUKS. This partition type predates the Discoverable '
+ 'Partitions Specification.'),
+}
+
+def extract(file):
+ for line in file:
+ # print(line)
+ m = re.match(r'^#define\s+GPT_(.*SD_ID128_MAKE.*)', line)
+ if not m:
+ continue
+
+ if m2 := re.match(r'^(ROOT|USR)_([A-Z0-9]+|X86_64|MIPS_LE|MIPS64_LE)(|_VERITY|_VERITY_SIG)\s+SD_ID128_MAKE\((.*)\)', m.group(1)):
+ type, arch, suffix, u = m2.groups()
+ u = uuid.UUID(u.replace(',', ''))
+ assert arch in ARCHITECTURES
+ type = f'{type}{suffix}'
+ assert type in TYPES
+
+ yield type, arch, u
+
+ elif m2 := re.match(r'(\w+)\s+SD_ID128_MAKE\((.*)\)', m.group(1)):
+ type, u = m2.groups()
+ u = uuid.UUID(u.replace(',', ''))
+ yield type, None, u
+
+ else:
+ raise Exception(f'Failed to match: {m.group(1)}')
+
+def generate(defines):
+ prevtype = None
+
+ print(HEADER, end='')
+
+ for type, arch, uuid in defines:
+ tdesc = TYPES[type]
+ adesc = '' if arch is None else f' ({ARCHITECTURES[arch]})'
+
+ if type != prevtype:
+ prevtype = type
+ morea, moreb = DESCRIPTIONS[type]
+ else:
+ morea = moreb = 'ditto'
+
+ print(f'| _{tdesc}{adesc}_ | `{uuid}` | {morea} | {moreb} |')
+
+if __name__ == '__main__':
+ known = extract(sys.stdin)
+ generate(known)