-
Notifications
You must be signed in to change notification settings - Fork 149
Description
There are (at least) 3 different types of UUIDs for Linux filesystems/partitions:
-
The filesystem UUID. This is intrinsic to the filesystem, so it can exist with both MBR and GPT, and its format depends on the specific filesystem (8 hex chars on FAT, a GUID for most other filesystems). You can mount a disk by its filesystem UUID by running
mount UUID=<uuid>, and you can display a filesystem's UUID by runninglsblk --output=name,fstype,uuid. Theoretically, no 2 disks should ever have the same filesystem UUIDs. -
The partition UUID. This is a part of GPT, so it has the same format for every filesystem, but it doesn't work with MBR. You can mount a disk by its partition UUID by running
mount PARTUUID=<uuid>, and you can display a partitions's UUID by runninglsblk --output=name,fstype,partuuid. Theoretically, no 2 disks should ever have the same partition UUIDs. -
The partition type UUID. This is a part of GPT, so it has the same format for every filesystem, but it doesn't work with MBR. You can mount a disk by its partition type UUID with
systemd-gpt-auto-generator, and you can display a partitions's type UUID by runninglsblk --output=name,fstype,parttype(or…,parttypenamefor its friendly name). Many disks will have the same partition type UUIDs, and common values are defined by the Discoverable Partitions Specification.
Right now, bootc is setting the filesystem UUIDs to one of the values defined by the DPS:
bootc/crates/lib/src/bootc_composefs/boot.rs
Lines 415 to 418 in 71dc8e5
| Cmdline::from(format!( | |
| "root=UUID={} {RW_KARG} {COMPOSEFS_CMDLINE}={id_hex}", | |
| this_arch_root() | |
| )), |
bootc/crates/lib/src/install/baseline.rs
Lines 116 to 134 in 71dc8e5
| let u = uuid::Uuid::parse_str(crate::discoverable_partition_specification::this_arch_root())?; | |
| let mut t = Task::new( | |
| &format!("Creating {label} filesystem ({fs}) on device {dev} (size={size})"), | |
| format!("mkfs.{fs}"), | |
| ); | |
| match fs { | |
| Filesystem::Xfs => { | |
| if wipe { | |
| t.cmd.arg("-f"); | |
| } | |
| t.cmd.arg("-m"); | |
| t.cmd.arg(format!("uuid={u}")); | |
| } | |
| Filesystem::Btrfs | Filesystem::Ext4 => { | |
| t.cmd.arg("-U"); | |
| t.cmd.arg(u.to_string()); | |
| } | |
| }; |
This is bad because
-
This isn't actually following the DPS, so tools like
systemd-gpt-auto-generatorwon't recognize this. -
Some software assumes that filesystem/partition UUIDs are truly unique, so bad things will happen if you try to mount 2 disks formatted this way at the same time.
Here's an example of the disk generated by bootc install to-disk (using v1.10):
$ lsblk --output=name,fstype,parttypename,uuid,partuuid,parttype
NAME FSTYPE PARTTYPENAME UUID PARTUUID PARTTYPE
loop0
├─loop0p1 BIOS boot 6188eeaa-d52e-4c89-b077-6373578a8146 21686148-6449-6e6f-744e-656564454649
├─loop0p2 vfat EFI System 5081-C36B d30abf07-204f-40a0-9d25-62f089c73137 c12a7328-f81f-11d2-ba4b-00a0c93ec93b
└─loop0p3 btrfs Linux filesystem 4f68bce3-e8cd-4db1-96e7-fbcaf984b709 834f3c93-e330-443c-97fc-4c0238e90a81 0fc63daf-8483-4772-8e79-3d69d8477de4(Note how the filesystem and partition UUIDs for loop0p2 are random, but the partition type UUID is set to c12a7328-…, so the partition type name shows up as EFI System.)
Here's an example from my server running bootc, where I manually corrected the partition types with sfdisk --part-type:
$ lsblk --output=name,fstype,parttypename,uuid,partuuid,parttype | cat
NAME FSTYPE PARTTYPENAME UUID PARTUUID PARTTYPE
vda
├─vda1 vfat EFI System 312A-0AD0 1c8b0885-9a88-4bb8-a494-22f27c793b3c c12a7328-f81f-11d2-ba4b-00a0c93ec93b
├─vda2 ext4 Linux extended boot 26d65031-c51b-4e2c-999f-9642f90ebcab b692ac66-0966-4811-a186-885208933efd bc13c2ff-59e6-4262-a352-b275fd6f7172
├─vda3 swap Linux swap 25c85fb7-eadd-414c-9c56-475bf2a401f4 6f6482e5-128f-4347-a428-d557940a92a1 0657fd6d-a4ab-43c4-84e5-0933c84b4f4f
└─vda4 btrfs Linux root (x86-64) 54b902ba-941a-495f-ae19-770ee22681c4 3b5f07c0-7a5d-4025-9bfe-b89e28974fdd 4f68bce3-e8cd-4db1-96e7-fbcaf984b709(Note how the filesystem and partition UUIDs for vda4 are random, but the partition type UUID is set to 4f68bce3-…, so the partition type name shows up as Linux root (x86-64). Whereas in the previous example with the filesystem UUID set to 4f68bce3-…, the partition type name only shows up as Linux filesystem)
A nice side effect of this is that you no longer need to pass a long architecture-dependent UUID in the kernel cmdline; instead, you can just use root=gpt-auto, and systemd will automatically find the correct partition. I've done exactly this on my server running bootc, and everything works as expected.
The only catch is that older versions of Grub don't set the required UEFI variables, so you'll need to make sure to run bootupctl update first. And this also won't work on MBR-based systems (since the partition type is only defined in GPT), so if you need to support MBR-based systems, I'd recommend using the filesystem label (mount LABEL=<label>) instead of trying to reuse filesystem UUIDs.