From 9461450be3d290d4c1031666b09b64a79392907c Mon Sep 17 00:00:00 2001 From: Christoph Ostarek Date: Thu, 15 Jan 2026 10:37:35 +0100 Subject: [PATCH] usb: uevent path 1. expose uevent path to the consumer of the library 2. allow filtering usb devices by uevent path this is useful when listening to uevents and using ghw library to get the usb device Signed-off-by: Christoph Ostarek --- pkg/option/option.go | 9 +++++++++ pkg/usb/usb.go | 27 ++++++++++++++------------- pkg/usb/usb_linux.go | 11 ++++++++--- pkg/usb/usb_test.go | 2 +- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/pkg/option/option.go b/pkg/option/option.go index 9e8b4b4a..2dcaa746 100644 --- a/pkg/option/option.go +++ b/pkg/option/option.go @@ -107,6 +107,9 @@ type Options struct { // custom pcidb.WithOption settings, instead of letting ghw load the PCI // database automatically. PCIDB *pcidb.PCIDB + + // Filter USB devices by uevent file path in sysfs + USBUeventPath string } func (o *Options) Warn(msg string, args ...interface{}) { @@ -156,6 +159,12 @@ func WithPCIDB(pcidb *pcidb.PCIDB) Option { } } +func WithUSBUeventPath(path string) Option { + return func(opts *Options) { + opts.USBUeventPath = path + } +} + // PathOverrides is a map, keyed by the string name of a mount path, of override paths type PathOverrides map[string]string diff --git a/pkg/usb/usb.go b/pkg/usb/usb.go index 79904241..b7bdc73b 100644 --- a/pkg/usb/usb.go +++ b/pkg/usb/usb.go @@ -16,19 +16,20 @@ import ( ) type Device struct { - Driver string `json:"driver"` - Type string `json:"type"` - VendorID string `json:"vendor_id"` - ProductID string `json:"product_id"` - Product string `json:"product"` - RevisionID string `json:"revision_id"` - Interface string `json:"interface"` - Devnum string `json:"devnum"` - Parent bus.BusParent `json:"parent,omitempty"` - Class string `json:"class"` - Subclass string `json:"subclass"` - Protocol string `json:"protocol"` - Controller string `json:"controller,omitempty"` + Driver string `json:"driver"` + Type string `json:"type"` + VendorID string `json:"vendor_id"` + ProductID string `json:"product_id"` + Product string `json:"product"` + RevisionID string `json:"revision_id"` + Interface string `json:"interface"` + Devnum string `json:"devnum"` + Parent bus.BusParent `json:"parent,omitempty"` + Class string `json:"class"` + Subclass string `json:"subclass"` + Protocol string `json:"protocol"` + Controller string `json:"controller,omitempty"` + UEventFilePath string usbAddress.Address } diff --git a/pkg/usb/usb_linux.go b/pkg/usb/usb_linux.go index 1734ae16..4f5d92d4 100644 --- a/pkg/usb/usb_linux.go +++ b/pkg/usb/usb_linux.go @@ -35,8 +35,8 @@ func (i *Info) load(opts *option.Options) error { return fmt.Errorf("error(s) happened during reading usb info: %+v", errs) } -func fillUSBFromUevent(dir string, dev *Device) (err error) { - ueventFp, err := os.Open(filepath.Join(dir, "uevent")) +func fillUSBFromUevent(dev *Device) (err error) { + ueventFp, err := os.Open(dev.UEventFilePath) if err != nil { return } @@ -112,7 +112,12 @@ func usbs(opts *option.Options) ([]*Device, []error) { dev := Device{} - err = fillUSBFromUevent(fullDir, &dev) + dev.UEventFilePath = filepath.Join(fullDir, "uevent") + if opts.USBUeventPath != "" && opts.USBUeventPath != dev.UEventFilePath { + continue + } + + err = fillUSBFromUevent(&dev) if err != nil { errs = append(errs, err) } diff --git a/pkg/usb/usb_test.go b/pkg/usb/usb_test.go index a7e9394f..f95946d2 100644 --- a/pkg/usb/usb_test.go +++ b/pkg/usb/usb_test.go @@ -45,7 +45,7 @@ MODALIAS=usb:v046ApA087d0101dc00dsc00dp00ic03isc01ip02in00 } var d Device - err = fillUSBFromUevent(usbDir, &d) + err = fillUSBFromUevent(&d) if err != nil { t.Fatalf("could not fill USB info from uevent file: %v", err) }