From 33a631f026ae98eafd9ba7cf7b94164b71a2da9c Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 20 May 2022 23:27:53 +0400 Subject: [PATCH] feat: look up Links PCI vendor/product via PCI ID database This increases `initramfs` size by 356060 bytes (raw text database is 1.3 MiB). In QEMU: ``` $ talosctl -n 172.20.0.2 get links eth0 -o yaml spec: ... productID: "0x1000" vendorID: "0x1af4" product: Virtio network device vendor: Red Hat, Inc. ``` Signed-off-by: Andrey Smirnov --- go.mod | 3 + go.sum | 5 ++ .../pkg/controllers/network/link_status.go | 18 ++++++ internal/pkg/pci/pci.go | 25 +++++++++ internal/pkg/pci/sysfs.go | 55 +++++++++++++++++++ .../resources/network/link_status.go | 4 ++ 6 files changed, 110 insertions(+) create mode 100644 internal/pkg/pci/pci.go create mode 100644 internal/pkg/pci/sysfs.go diff --git a/go.mod b/go.mod index 496bcbf32..6302aea64 100644 --- a/go.mod +++ b/go.mod @@ -85,6 +85,7 @@ require ( github.com/ryanuber/go-glob v1.0.0 github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.9 + github.com/siderolabs/go-pcidb v0.1.0 github.com/siderolabs/go-pointer v1.0.0 github.com/spf13/cobra v1.4.0 github.com/spf13/pflag v1.0.5 @@ -269,8 +270,10 @@ require ( go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 // indirect golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/text v0.3.7 // indirect + golang.org/x/tools v0.1.10 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d // indirect google.golang.org/api v0.75.0 // indirect diff --git a/go.sum b/go.sum index 666a79683..885afe84e 100644 --- a/go.sum +++ b/go.sum @@ -1055,6 +1055,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sethgrid/pester v0.0.0-20190127155807-68a33a018ad0 h1:X9XMOYjxEfAYSy3xK1DzO5dMkkWhs9E9UCcS1IERx2k= github.com/sethgrid/pester v0.0.0-20190127155807-68a33a018ad0/go.mod h1:Ad7IjTpvzZO8Fl0vh9AzQ+j/jYZfyp2diGwI8m5q+ns= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/siderolabs/go-pcidb v0.1.0 h1:6cJPBBmHlIF4GouYR/1g3JXS/niAON+6lIOfKl/t794= +github.com/siderolabs/go-pcidb v0.1.0/go.mod h1:wT/tUxNZFlKSuGBniVwXL53vlGQq2/CVu16y6sMGIao= github.com/siderolabs/go-pointer v1.0.0 h1:6TshPKep2doDQJAAtHUuHWXbca8ZfyRySjSBT/4GsMU= github.com/siderolabs/go-pointer v1.0.0/go.mod h1:HTRFUNYa3R+k0FFKNv11zgkaCLzEkWVzoYZ433P3kHc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -1355,6 +1357,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1679,6 +1682,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/app/machined/pkg/controllers/network/link_status.go b/internal/app/machined/pkg/controllers/network/link_status.go index ca5dfeceb..679c6cb3e 100644 --- a/internal/app/machined/pkg/controllers/network/link_status.go +++ b/internal/app/machined/pkg/controllers/network/link_status.go @@ -22,6 +22,7 @@ import ( networkadapter "github.com/talos-systems/talos/internal/app/machined/pkg/adapters/network" "github.com/talos-systems/talos/internal/app/machined/pkg/controllers/network/watch" + "github.com/talos-systems/talos/internal/pkg/pci" "github.com/talos-systems/talos/pkg/machinery/nethelpers" "github.com/talos-systems/talos/pkg/machinery/resources/network" ) @@ -257,6 +258,23 @@ func (ctrl *LinkStatusController) reconcile( status.BusPath = driverInfo.BusInfo } + var pciDev *pci.Device + + pciDev, err = pci.SysfsDeviceInfo(driverInfo.BusInfo) + if err != nil { + logger.Warn("failure looking up sysfs PCI info", zap.Error(err), zap.String("link", link.Attributes.Name)) + } + + if pciDev != nil { + pciDev.LookupDB() + + status.VendorID = fmt.Sprintf("0x%04x", pciDev.VendorID) + status.ProductID = fmt.Sprintf("0x%04x", pciDev.ProductID) + + status.Vendor = pciDev.Vendor + status.Product = pciDev.Product + } + status.DriverVersion = driverInfo.Version status.FirmwareVersion = driverInfo.FwVersion diff --git a/internal/pkg/pci/pci.go b/internal/pkg/pci/pci.go new file mode 100644 index 000000000..6ad3f9ab3 --- /dev/null +++ b/internal/pkg/pci/pci.go @@ -0,0 +1,25 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Package pci provides methods to access PCI-related data. +package pci + +import ( + "github.com/siderolabs/go-pcidb/pkg/pcidb" +) + +// Device describes PCI device. +type Device struct { + VendorID uint16 + ProductID uint16 + + Vendor string + Product string +} + +// LookupDB looks up device info in the PCI database. +func (d *Device) LookupDB() { + d.Vendor, _ = pcidb.LookupVendor(d.VendorID) + d.Product, _ = pcidb.LookupProduct(d.VendorID, d.ProductID) +} diff --git a/internal/pkg/pci/sysfs.go b/internal/pkg/pci/sysfs.go new file mode 100644 index 000000000..3b55429c7 --- /dev/null +++ b/internal/pkg/pci/sysfs.go @@ -0,0 +1,55 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package pci + +import ( + "bytes" + "errors" + "fmt" + "io/fs" + "io/ioutil" + "strconv" +) + +const sysfsPath = "/sys/bus/pci/devices/%s/%s" + +func readID(busPath, name string) (uint16, error) { + contents, err := ioutil.ReadFile(fmt.Sprintf(sysfsPath, busPath, name)) + if err != nil { + return 0, err + } + + v, err := strconv.ParseUint(string(bytes.TrimSpace(contents)), 0, 16) + + return uint16(v), err +} + +// SysfsDeviceInfo looks up vendor and product ID from sysfs. +func SysfsDeviceInfo(busPath string) (*Device, error) { + var ( + d Device + err error + ) + + d.ProductID, err = readID(busPath, "device") + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil, nil + } + + return nil, err + } + + d.VendorID, err = readID(busPath, "vendor") + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil, nil + } + + return nil, err + } + + return &d, err +} diff --git a/pkg/machinery/resources/network/link_status.go b/pkg/machinery/resources/network/link_status.go index 24bc5d784..37f34df3c 100644 --- a/pkg/machinery/resources/network/link_status.go +++ b/pkg/machinery/resources/network/link_status.go @@ -38,6 +38,10 @@ type LinkStatusSpec struct { Driver string `yaml:"driver,omitempty"` DriverVersion string `yaml:"driverVersion,omitempty"` FirmwareVersion string `yaml:"firmwareVersion,omitempty"` + ProductID string `yaml:"productID,omitempty"` + VendorID string `yaml:"vendorID,omitempty"` + Product string `yaml:"product,omitempty"` + Vendor string `yaml:"vendor,omitempty"` // Fields coming from ethtool API. LinkState bool `yaml:"linkState"` SpeedMegabits int `yaml:"speedMbit,omitempty"`