Implement further functionality
- Detect multifunction based on functions available per PCI device - Merge subfunctions of Loc into main function - Handle errors better in Loc - Rename some errors - Don't exit if already renamed, instead skip renaming and add alias (useful with -force) - Add missing altnames only - Add alternative naming schemes as altnames
This commit is contained in:
parent
b98771012d
commit
f2c6fb79dc
102
loc.go
102
loc.go
@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -36,10 +37,21 @@ func (i *iface) ProcLoc() (err error) {
|
||||
}
|
||||
|
||||
var (
|
||||
pci, usb, tmp string
|
||||
procmode int
|
||||
pci, usb string
|
||||
procmode int
|
||||
path = strings.Split(devpath, "/")
|
||||
|
||||
cdir = strings.Join([]string{
|
||||
SYSFS,
|
||||
"devices",
|
||||
}, "/")
|
||||
)
|
||||
for _, v := range strings.Split(devpath, "/") {
|
||||
for i, v := range path {
|
||||
if i >= 1 {
|
||||
// Append to currend directory
|
||||
cdir = strings.Join([]string{cdir, path[i-1]}, "/")
|
||||
}
|
||||
|
||||
if strings.HasPrefix(v, "pci") {
|
||||
procmode = PathProcPCI
|
||||
continue
|
||||
@ -51,24 +63,92 @@ func (i *iface) ProcLoc() (err error) {
|
||||
switch procmode {
|
||||
case PathProcPCI:
|
||||
{
|
||||
if tmp, err = i.ProcPCI(v); err != nil {
|
||||
var (
|
||||
domain, bus, device, function int
|
||||
)
|
||||
if _, err = fmt.Sscanf(v, "%x:%x:%x.%x", &domain, &bus, &device, &function); err != nil {
|
||||
err = ErrInvalidPCIFormat
|
||||
continue
|
||||
}
|
||||
pci = tmp
|
||||
var name strings.Builder
|
||||
if domain != 0 {
|
||||
// Hey, if you're reading this you're cool.
|
||||
// Do you know any machine which has a PCI domain other than 0?
|
||||
// Mail me at caskd@redxen.eu about it.
|
||||
name.WriteString(fmt.Sprintf("P%d", domain))
|
||||
}
|
||||
name.WriteString(fmt.Sprintf("p%ds%d", bus, device))
|
||||
|
||||
// List PCI path to see if there's any other functions available under the same device
|
||||
var matches []string
|
||||
dir := os.DirFS(cdir)
|
||||
glob := fmt.Sprintf("%04x:%02x:%02x.?", domain, bus, device)
|
||||
matches, _ = fs.Glob(dir, glob)
|
||||
if len(matches) > 1 {
|
||||
// Multi-function device
|
||||
name.WriteString(fmt.Sprintf("f%d", function))
|
||||
}
|
||||
|
||||
pci = name.String()
|
||||
}
|
||||
case PathProcUSB:
|
||||
{
|
||||
if tmp, err = i.ProcUSB(v); err != nil {
|
||||
var (
|
||||
bus, conf, iface int
|
||||
port_path []int
|
||||
work string
|
||||
)
|
||||
|
||||
res := strings.Split(v, ":")
|
||||
if len(res) != 2 {
|
||||
err = ErrInvalidUSBFormat
|
||||
continue
|
||||
}
|
||||
usb = tmp
|
||||
|
||||
// Bus and ports
|
||||
if _, err = fmt.Sscanf(res[0], "%d-%s", &bus, &work); err != nil {
|
||||
err = ErrInvalidUSBFormat
|
||||
continue
|
||||
}
|
||||
|
||||
for _, v := range strings.Split(work, ".") {
|
||||
var cp int
|
||||
if _, err = fmt.Sscanf(v, "%d", &cp); err != nil {
|
||||
err = ErrInvalidUSBFormat
|
||||
continue
|
||||
}
|
||||
port_path = append(port_path, cp)
|
||||
}
|
||||
|
||||
// Configuration and interface
|
||||
if _, err = fmt.Sscanf(res[1], "%d.%d", &conf, &iface); err != nil {
|
||||
err = ErrInvalidUSBFormat
|
||||
continue
|
||||
}
|
||||
|
||||
var name strings.Builder
|
||||
for _, v := range port_path {
|
||||
name.WriteString(fmt.Sprintf("u%d", v))
|
||||
}
|
||||
if conf != 1 {
|
||||
name.WriteString(fmt.Sprintf("c%d", conf))
|
||||
}
|
||||
if iface != 0 {
|
||||
name.WriteString(fmt.Sprintf("i%d", iface))
|
||||
}
|
||||
usb = name.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
if pci == "" && usb == "" {
|
||||
return
|
||||
}
|
||||
i.names[IfNameLoc] = strings.Join([]string{i.pfx, pci, usb}, "")
|
||||
|
||||
// Discard path errors if something was found
|
||||
if pci != "" && errors.Is(err, ErrInvalidPCIFormat) {
|
||||
err = nil
|
||||
}
|
||||
if usb != "" && errors.Is(err, ErrInvalidUSBFormat) {
|
||||
err = nil
|
||||
}
|
||||
|
||||
i.names[IfNameLoc] = strings.Join([]string{i.pfx, pci, usb}, "")
|
||||
return
|
||||
}
|
||||
|
47
main.go
47
main.go
@ -48,7 +48,7 @@ func main() {
|
||||
|
||||
var l netlink.Link
|
||||
if l, err = netlink.LinkByName(ifname); err != nil {
|
||||
mainlog.Fatalln("Interface", ifname, "disappeared before it could be selected")
|
||||
mainlog.Fatalln("Interface", ifname, "doesn't exist or disappeared before it could be selected")
|
||||
}
|
||||
|
||||
var cif iface
|
||||
@ -74,27 +74,38 @@ func main() {
|
||||
// Main name
|
||||
// This must be set before the next are following as altname cannot be added if a interface with the same name exists
|
||||
if ifname == cif.names[main] {
|
||||
mainlog.Println("Interface already named correctly")
|
||||
return
|
||||
}
|
||||
mainlog.Printf("Renaming %s to %s\n", ifname, cif.names[main])
|
||||
if err = netlink.LinkSetName(l, cif.names[main]); err != nil {
|
||||
mainlog.Fatalf("Could not rename interface %s: %s\n", ifname, err)
|
||||
mainlog.Println("Interface already named correctly, skipping")
|
||||
} else {
|
||||
mainlog.Printf("Renaming %s to %s\n", ifname, cif.names[main])
|
||||
if err = netlink.LinkSetName(l, cif.names[main]); err != nil {
|
||||
mainlog.Fatalf("Could not rename interface %s: %s\n", ifname, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Alt names
|
||||
var result = make(map[string]int)
|
||||
for k, v := range cif.names {
|
||||
switch k {
|
||||
case main:
|
||||
{
|
||||
continue
|
||||
}
|
||||
default:
|
||||
{
|
||||
if err = netlink.LinkAddAltName(l, v); err != nil {
|
||||
mainlog.Printf("Adding altname %s failed for %s: %s\n", v, ifname, err)
|
||||
}
|
||||
}
|
||||
if k != main {
|
||||
result[v]++
|
||||
}
|
||||
}
|
||||
|
||||
// Invalidate main name
|
||||
result[cif.names[main]]--
|
||||
|
||||
// Invalidate already present alternative names
|
||||
for _, v := range l.Attrs().AltNames {
|
||||
result[v]--
|
||||
}
|
||||
|
||||
for k, v := range result {
|
||||
if v != 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
mainlog.Printf("Adding altname %s for %s\n", k, ifname)
|
||||
if err = netlink.LinkAddAltName(l, k); err != nil {
|
||||
mainlog.Printf("Adding altname %s failed for %s: %s\n", k, ifname, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
23
pci.go
23
pci.go
@ -1,23 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (i *iface) ProcPCI(devpath string) (seg string, err error) {
|
||||
var (
|
||||
domain, bus, device, function int
|
||||
)
|
||||
if _, err = fmt.Sscanf(devpath, "%x:%x:%x.%x", &domain, &bus, &device, &function); err != nil {
|
||||
err = ErrInvalidPCIFormat
|
||||
return
|
||||
}
|
||||
var name strings.Builder
|
||||
if domain != 0 {
|
||||
name.WriteString(fmt.Sprintf("P%d", domain))
|
||||
}
|
||||
name.WriteString(fmt.Sprintf("p%ds%df%d", bus, device, function))
|
||||
seg = name.String()
|
||||
return
|
||||
}
|
49
usb.go
49
usb.go
@ -1,49 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (i *iface) ProcUSB(devpath string) (seg string, err error) {
|
||||
var (
|
||||
bus, conf, iface int
|
||||
port_path []int
|
||||
work string
|
||||
)
|
||||
|
||||
res := strings.Split(devpath, ":")
|
||||
if len(res) != 2 {
|
||||
err = ErrInvalidUSBFormat
|
||||
return
|
||||
}
|
||||
|
||||
// Bus and ports
|
||||
if _, err = fmt.Sscanf(res[0], "%d-%s", &bus, &work); err != nil {
|
||||
err = ErrInvalidUSBFormat
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range strings.Split(work, ".") {
|
||||
var cp int
|
||||
if _, err = fmt.Sscanf(v, "%d", &cp); err != nil {
|
||||
err = ErrInvalidUSBFormat
|
||||
return
|
||||
}
|
||||
port_path = append(port_path, cp)
|
||||
}
|
||||
|
||||
// Configuration and interface
|
||||
if _, err = fmt.Sscanf(res[1], "%d.%d", &conf, &iface); err != nil {
|
||||
err = ErrInvalidUSBFormat
|
||||
return
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
for _, v := range port_path {
|
||||
b.WriteString(fmt.Sprintf("u%d", v))
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("i%d", iface))
|
||||
seg = b.String()
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue
Block a user