Skip to content
19 changes: 19 additions & 0 deletions pkg/option/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"io"
"log"
"os"

"github.com/jaypipes/pcidb"
)

const (
Expand Down Expand Up @@ -140,6 +142,12 @@ type Option struct {
// during a call to the `context.WithContext` function. Only used internally.
// This is an interface to get around recursive package import issues.
Context interface{}

// PCIDB allows users to provide a custom instance of the PCI database (pcidb.PCIDB)
// to be used by ghw. This can be useful for testing, supplying a preloaded database,
// or providing an instance created with custom pcidb.WithOption settings, instead of
// letting ghw load the PCI database automatically.
PCIDB *pcidb.PCIDB
}

// SnapshotOptions contains options for handling of ghw snapshots
Expand Down Expand Up @@ -195,6 +203,14 @@ func WithDisableTools() *Option {
return &Option{EnableTools: &false_}
}

// WithPCIDB allows you to provide a custom instance of the PCI database (pcidb.PCIDB)
// to ghw. This is useful if you want to use a preloaded or specially configured
// PCI database, such as one created with custom pcidb.WithOption settings, instead
// of letting ghw load the PCI database automatically.
func WithPCIDB(pcidb *pcidb.PCIDB) *Option {
return &Option{PCIDB: pcidb}
}

// PathOverrides is a map, keyed by the string name of a mount path, of override paths
type PathOverrides map[string]string

Expand Down Expand Up @@ -233,6 +249,9 @@ func Merge(opts ...*Option) *Option {
if opt.Context != nil {
merged.Context = opt.Context
}
if opt.PCIDB != nil {
merged.PCIDB = opt.PCIDB
}
}
// Set the default value if missing from mergeOpts
if merged.Chroot == nil {
Expand Down
24 changes: 24 additions & 0 deletions pkg/option/option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
package option_test

import (
"runtime"
"testing"

"github.com/jaypipes/ghw/pkg/option"
"github.com/jaypipes/pcidb"
)

type optTestCase struct {
Expand All @@ -20,6 +22,25 @@ type optTestCase struct {

// nolint: gocyclo
func TestOption(t *testing.T) {
var pciTest *optTestCase
pcidb, err := pcidb.New()
if err != nil {
t.Fatalf("error creating new pcidb: %v", err)
}
if runtime.GOOS == "linux" {
pciTest = &optTestCase{
name: "pcidb",
opts: []*option.Option{
option.WithPCIDB(pcidb),
option.WithChroot("/my/chroot/dir"),
},
merged: &option.Option{
Chroot: stringPtr("/my/chroot/dir"),
PCIDB: pcidb,
},
}
}

optTCases := []optTestCase{
{
name: "multiple chroots",
Expand Down Expand Up @@ -151,6 +172,9 @@ func TestOption(t *testing.T) {
},
},
}
if pciTest != nil {
optTCases = append(optTCases, *pciTest)
}
for _, optTCase := range optTCases {
t.Run(optTCase.name, func(t *testing.T) {
opt := option.Merge(optTCase.opts...)
Expand Down
3 changes: 3 additions & 0 deletions pkg/pci/pci.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ func New(opts ...*option.Option) (*Info, error) {
} else {
ctx.Warn("error detecting system topology: %v", err)
}
if merged.PCIDB != nil {
info.db = merged.PCIDB
}
return info.load()
}

Expand Down
10 changes: 6 additions & 4 deletions pkg/pci/pci_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ func (i *Info) load() error {
if i.ctx.SnapshotPath != "" {
chroot = option.DefaultChroot
}
db, err := pcidb.New(pcidb.WithChroot(chroot))
if err != nil {
return err
if i.db == nil {
db, err := pcidb.New(pcidb.WithChroot(chroot))
if err != nil {
return err
}
i.db = db
}
i.db = db
i.Devices = i.getDevices()
return nil
}
Expand Down
Loading