enit: switch away from using udev for fstab device prefixes

This commit is contained in:
2025-12-25 11:10:17 +02:00
parent 84de96ceca
commit f69ca4d02c
2 changed files with 148 additions and 11 deletions
+83
View File
@@ -0,0 +1,83 @@
package main
import (
"os/exec"
"strings"
)
type BlockDevice struct {
Device string
UUID string
PartUUID string
Label string
PartLabel string
Type string
}
func GetBlockDevices() []BlockDevice {
cmd := exec.Command("/sbin/blkid")
out, err := cmd.Output()
if err != nil {
return make([]BlockDevice, 0)
}
blockDevices := make([]BlockDevice, 0)
for _, line := range strings.Split(string(out), "\n") {
line := strings.TrimSpace(line)
if len(line) == 0 {
continue
}
lineSplit := strings.SplitN(line, ": ", 2)
if len(lineSplit) != 2 {
return make([]BlockDevice, 0)
}
device := lineSplit[0]
line = lineSplit[1]
fields := []string{}
sb := &strings.Builder{}
quoted := false
for _, r := range line {
if r == '"' {
quoted = !quoted
} else if !quoted && r == ' ' {
fields = append(fields, sb.String())
sb.Reset()
} else {
sb.WriteRune(r)
}
}
if sb.Len() > 0 {
fields = append(fields, sb.String())
}
bd := BlockDevice{Device: device}
for _, field := range fields {
fieldSplit := strings.SplitN(field, "=", 2)
if len(fieldSplit) != 2 {
return make([]BlockDevice, 0)
}
fieldName := fieldSplit[0]
fieldValue := fieldSplit[1]
switch fieldName {
case "UUID":
bd.UUID = fieldValue
case "PARTUUID":
bd.PartUUID = fieldValue
case "LABEL":
bd.Label = fieldValue
case "PARTLABEL":
bd.PartLabel = fieldValue
case "TYPE":
bd.Type = fieldValue
}
}
blockDevices = append(blockDevices, bd)
}
return blockDevices
}
+65 -11
View File
@@ -158,23 +158,77 @@ func mountFstabEntries() (error, int) {
fstype := fields[2] fstype := fields[2]
options := fields[3] options := fields[3]
// Replace device prefixes // Convert mount options
if cutSource, ok := strings.CutPrefix(source, "LABEL="); ok {
source = "/dev/disk/by-label/" + strings.ReplaceAll(cutSource, " ", "\\x20")
} else if cutSource, ok := strings.CutPrefix(source, "UUID="); ok {
source = "/dev/disk/by-uuid/" + cutSource
} else if cutSource, ok := strings.CutPrefix(source, "PARTLABEL="); ok {
source = "/dev/disk/by-partlabel/" + cutSource
} else if cutSource, ok := strings.CutPrefix(source, "PARTUUID="); ok {
source = "/dev/disk/by-partuuid/" + cutSource
}
flags, data, extra := convertMountOptions(options) flags, data, extra := convertMountOptions(options)
// Skip if noauto flag is set
if slices.Contains(extra, "noauto") { if slices.Contains(extra, "noauto") {
continue continue
} }
// Get block devices
blockDevices := GetBlockDevices()
// Replace device prefixes
if strings.Contains(source, "=") {
fieldSplit := strings.SplitN(source, "=", 2)
if len(fieldSplit) != 2 {
if slices.Contains(extra, "nofail") {
fmt.Printf("Warning: could not mount fstab entry on line %d: Formatting error\n", i+1)
continue
} else {
return fmt.Errorf("Formatting error"), i + 1
}
}
fieldName := fieldSplit[0]
fieldValue := fieldSplit[1]
// Reset source field
source = ""
for _, bd := range blockDevices {
bdField := ""
switch fieldName {
case "LABEL":
bdField = bd.Label
case "UUID":
bdField = bd.UUID
case "PARTLABEL":
bdField = bd.PartLabel
case "PARTUUID":
bdField = bd.PartUUID
default:
if slices.Contains(extra, "nofail") {
fmt.Printf("Warning: could not mount fstab entry on line %d: Formatting error\n", i+1)
continue
} else {
return fmt.Errorf("Formatting error"), i + 1
}
}
if bdField == "" {
continue
}
if bdField == fieldValue {
source = bd.Device
break
}
}
// Ensure source was set
if source == "" {
if slices.Contains(extra, "nofail") {
fmt.Printf("Warning: could not mount fstab entry on line %d: could not resolve %s=\"%s\"\n", i+1, fieldName, fieldValue)
continue
} else {
return fmt.Errorf("could not resolve %s=\"%s\"", fieldName, fieldValue), i + 1
}
}
}
if fstype == "swap" { if fstype == "swap" {
b := append([]byte(source), 0) b := append([]byte(source), 0)
const SwapFlagPrioShift = 0 const SwapFlagPrioShift = 0