From b0f7b9ab2d75f2f84329f9ad61fd1c61764cc072 Mon Sep 17 00:00:00 2001 From: Ryan Harper Date: Fri, 16 Feb 2024 12:18:13 -0600 Subject: [PATCH] linux/udev: fix udevadm info parser to not be fatal The current parser returns an error when it encounters newer prefix values in the output of udevadm info. Anytime a system upgrades to a newer release, there is a change new fields will be present preventing disko from producing any output. - Update and document prefixes defined in systemd v255 - Replace error with an warning output - make sure we have two tokens when parsing udevadm info output Signed-off-by: Ryan Harper --- linux/util.go | 41 +++++++++++++++++++++++++++++++++++++---- linux/util_test.go | 2 ++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/linux/util.go b/linux/util.go index e9b5e99..34c568e 100644 --- a/linux/util.go +++ b/linux/util.go @@ -47,15 +47,50 @@ func parseUdevInfo(out []byte, info *disko.UdevInfo) error { } toks = bytes.SplitN(line, []byte(": "), 2) - payload = string(toks[1]) + if len(toks) != 2 { + log.Printf("parseUdevInfo: ignoring unparsable line %q\n", line) + continue + } + + payload = string(toks[1]) switch toks[0][0] { case 'P': + // Device path in /sys/ info.SysPath = payload + case 'M': + // Device name in /sys/ (i.e. the last component of "P:") + continue + case 'R': + // Device number in /sys/ (i.e. the numeric suffix of the last component of "P:") + continue + case 'U': + // Kernel subsystem + continue + case 'T': + // Kernel device type with subsystem + continue + case 'D': + // Kernel device node major/minor + continue + case 'I': + // Network interface index + continue case 'N': + // Kernel device node name info.Name = payload + case 'L': + // Device node symlink priority + continue case 'S': + // Device node symlink info.Symlinks = append(info.Symlinks, strings.Split(payload, " ")...) + case 'Q': + // Block device sequence number (DISKSEQ) + continue + case 'V': + // Attached driver + continue case 'E': kv := strings.SplitN(payload, "=", 2) // use of Unquote is to decode \x20, \x2f and friends. @@ -67,10 +102,8 @@ func parseUdevInfo(out []byte, info *disko.UdevInfo) error { } info.Properties[kv[0]] = strings.TrimSpace(s) - case 'L': - // a 'devlink priority'. skip for now. default: - return fmt.Errorf("error parsing line: (%s)", line) + log.Printf("parseUdevInfo: ignoring unknown udevadm info prefix %q in %q\n", toks[0][0], line) } } diff --git a/linux/util_test.go b/linux/util_test.go index e2898ea..dd90e23 100644 --- a/linux/util_test.go +++ b/linux/util_test.go @@ -12,6 +12,7 @@ import ( func TestParseUdevInfo(t *testing.T) { data := []byte(`P: /devices/virtual/block/dm-0 N: dm-0 +M: dm-0 S: disk/by-id/dm-name-nvme0n1p6_crypt S: disk/by-id/dm-uuid-CRYPT-LUKS1-b174c64e7a714359a8b56b79fb66e92b-nvme0n1p6_crypt S: disk/by-uuid/25df9069-80c7-46f4-a47c-305613c2cb6b @@ -49,6 +50,7 @@ E: DEVNAME=/dev/dm-0 func TestParseUdevInfo2(t *testing.T) { data := []byte(`P: /devices/pci0000:00/..../block/sda N: sda +M: sda S: disk/by-id/scsi-35000c500a0d8963f S: disk/by-id/wwn-0x5000c500a0d8963f S: disk/by-path/pci-0000:05:00.0-scsi-0:0:8:0