From 0402aa46dc66d222692a2e3ef3c545c91a42306a Mon Sep 17 00:00:00 2001 From: eriknordmark Date: Tue, 7 Jul 2026 15:09:39 -0700 Subject: [PATCH 1/2] discover: test sysfs PARTUUID discovery Selecting a partition by IdentifierByUUID on a real block device requires the sysfs discovery path to expose each partition's GUID. Add a regression test that builds a /sys fixture whose uevent carries PARTUUID and asserts findDisks populates the partition uuid, upper-cased to match go-diskfs's UUID() so the value compares equal on both discovery paths. Signed-off-by: eriknordmark Co-Authored-By: Claude Opus 4.8 --- discover_test.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/discover_test.go b/discover_test.go index edff615..9dc8d15 100644 --- a/discover_test.go +++ b/discover_test.go @@ -7,6 +7,7 @@ import ( "path" "path/filepath" "reflect" + "strings" "testing" ) @@ -176,3 +177,57 @@ func TestFindDisks(t *testing.T) { } }) } + +// TestFindDisksPopulatesPartUUID verifies the sysfs (block-device) discovery +// path fills in the partition GUID from the uevent PARTUUID key, so a caller can +// select a partition by IdentifierByUUID on a real device. Without it, uuid is +// empty and filterDisksByPartitions can never match a UUID identifier — a gap +// invisible to the image-file path, which already sets uuid from go-diskfs. +// +// The GUID is normalized to upper case to match go-diskfs's UUID(), which +// convert.go compares against when resolving the same identifier on the GPT; a +// lower-case value from the uevent would silently fail that later comparison. +func TestFindDisksPopulatesPartUUID(t *testing.T) { + const ( + partUUIDLower = "a94e71c5-a294-4512-8974-b2d52289ea18" + wantLabel = "EFI System" + ) + tmp := t.TempDir() + diskDir := filepath.Join(tmp, "class", "block", "sdy") + if err := os.MkdirAll(filepath.Join(diskDir, "queue"), 0755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(diskDir, "queue", "logical_block_size"), []byte("512\n"), 0644); err != nil { + t.Fatal(err) + } + part := filepath.Join(diskDir, "sdy1") + if err := os.Mkdir(part, 0755); err != nil { + t.Fatal(err) + } + for name, val := range map[string]string{"partition": "1\n", "start": "2\n", "size": "4\n"} { + if err := os.WriteFile(filepath.Join(part, name), []byte(val), 0644); err != nil { + t.Fatal(err) + } + } + uevent := "PARTNAME=" + wantLabel + "\nPARTUUID=" + partUUIDLower + "\n" + if err := os.WriteFile(filepath.Join(part, "uevent"), []byte(uevent), 0644); err != nil { + t.Fatal(err) + } + + disks, err := findDisks("", tmp) + if err != nil { + t.Fatalf("findDisks error: %v", err) + } + data, ok := disks["sdy"] + if !ok || len(data) != 1 { + t.Fatalf("unexpected disks map: %v", disks) + } + pd := data[0] + if pd.label != wantLabel { + t.Errorf("pd.label = %q, want %q", pd.label, wantLabel) + } + want := strings.ToUpper(partUUIDLower) + if pd.uuid != want { + t.Errorf("pd.uuid = %q, want %q", pd.uuid, want) + } +} From d97c593746f8cdc26bb2e8cde3018d25e4e926d7 Mon Sep 17 00:00:00 2001 From: eriknordmark Date: Tue, 7 Jul 2026 15:12:03 -0700 Subject: [PATCH 2/2] discover: populate partition UUID from sysfs uevent The block-device discovery path parsed only PARTNAME from a partition's uevent, leaving its UUID empty, so a caller selecting by IdentifierByUUID never matched a disk found via sysfs; it worked only for image files, which read the GUID through go-diskfs. Read PARTUUID from the same uevent and upper-case it to match go-diskfs's UUID(), the value convert.go compares against when resolving the identifier on the GPT. Signed-off-by: eriknordmark Co-Authored-By: Claude Opus 4.8 --- discover.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/discover.go b/discover.go index 99fd392..e5e4e52 100644 --- a/discover.go +++ b/discover.go @@ -185,9 +185,13 @@ func findDisks(disk, syspath string) (map[string][]partitionData, error) { } ue := parseKeyValueLines(ueventData) label := ue["PARTNAME"] + // go-diskfs (image path) reports GUIDs upper-cased; match it so + // the same identifier compares equal on both discovery paths. + uuid := strings.ToUpper(ue["PARTUUID"]) pd := partitionData{ name: name, label: label, + uuid: uuid, size: size * blockSize, start: start * blockSize, end: end * blockSize,