Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add PCI device info to ghwc #209

Merged
merged 1 commit into from
Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -692,31 +692,29 @@ are exposed on the `ghw.PCIInfo` struct.
The `ghw.PCI()` function returns a `ghw.PCIInfo` struct. The `ghw.PCIInfo`
struct contains a number of fields that may be queried for PCI information:

* `ghw.PCIInfo.Devices` is a slice of pointers to `ghw.PCIDevice` structs that
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is not clear to me if calling ListDevices() is now deprecated or still fully supported. Both approaches works from client perspective. As API consumer I for myself prefer to have functions as part of the APIs (e.g. calling ListDevices() explicitely to get a fresh list of devices) but this is mostly personal taste.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced ListDevices() with a PCIInfo.Devices slice to make the interface match the other "XXXInfo" structs for consistency purposes. I've gone ahead and deprecated the ListDevices exported function and will unexport it in the v1.0 release (as of yet, I don't have a release date target for v1.0 though) :)

describe the PCI devices on the host system
* `ghw.PCIInfo.Classes` is a map, keyed by the PCI class ID (a hex-encoded
string) of pointers to `pcidb.Class` structs, one for each class of PCI
device known to `ghw`
(**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the
`github.com/jaypipes/pcidb` library for exploring PCI database information)
* `ghw.PCIInfo.Vendors` is a map, keyed by the PCI vendor ID (a hex-encoded
string) of pointers to `pcidb.Vendor` structs, one for each PCI vendor
known to `ghw`
* `ghw.PCIInfo.Products` is a map, keyed by the PCI product ID* (a hex-encoded
(**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the
`github.com/jaypipes/pcidb` library for exploring PCI database information)
* `ghw.PCIInfo.Products` is a map, keyed by the PCI product ID (a hex-encoded
string) of pointers to `pcidb.Product` structs, one for each PCI product
known to `ghw`
(**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the
`github.com/jaypipes/pcidb` library for exploring PCI database information)

**NOTE**: PCI products are often referred to by their "device ID". We use
the term "product ID" in `ghw` because it more accurately reflects what the
identifier is for: a specific product line produced by the vendor.

#### Listing and accessing host PCI device information

In addition to the above information, the `ghw.PCIInfo` struct has the
following methods:

* `ghw.PCIInfo.ListDevices() []*PCIDevice`
* `ghw.PCIInfo.GetDevice(address string) *PCIDevice`

This methods return either an array of or a single pointer to a `ghw.PCIDevice`
struct, which has the following fields:

The `ghw.PCIDevice` struct has the following fields:

* `ghw.PCIDevice.Vendor` is a pointer to a `pcidb.Vendor` struct that
describes the device's primary vendor. This will always be non-nil.
Expand All @@ -732,6 +730,13 @@ struct, which has the following fields:
`pcidb.ProgrammingInterface` struct that describes the device subclass'
programming interface. This will always be non-nil.

#### Finding a PCI device by PCI address

In addition to the above information, the `ghw.PCIInfo` struct has the
following method:

* `ghw.PCIInfo.GetDevice(address string)`

The following code snippet shows how to call the `ghw.PCIInfo.ListDevices()`
method and output a simple list of PCI address and vendor/product information:

Expand All @@ -751,13 +756,8 @@ func main() {
}
fmt.Printf("host PCI devices:\n")
fmt.Println("====================================================")
devices := pci.ListDevices()
if len(devices) == 0 {
fmt.Printf("error: could not retrieve PCI devices\n")
return
}

for _, device := range devices {
for _, device := range pci.Devices {
vendor := device.Vendor
vendorName := vendor.Name
if len(vendor.Name) > 20 {
Expand Down
35 changes: 35 additions & 0 deletions cmd/ghwc/commands/pci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// Use and distribution licensed under the Apache license version 2.
//
// See the COPYING file in the root project directory for full text.
//

package commands

import (
"github.com/jaypipes/ghw"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

// pciCmd represents the install command
var pciCmd = &cobra.Command{
Use: "pci",
Short: "Show information about PCI devices on the host system",
RunE: showPCI,
}

// showPCI shows information for PCI devices on the host system.
func showPCI(cmd *cobra.Command, args []string) error {
pci, err := ghw.PCI()
if err != nil {
return errors.Wrap(err, "error getting PCI info")
}

printInfo(pci)
return nil
}

func init() {
rootCmd.AddCommand(pciCmd)
}
10 changes: 9 additions & 1 deletion host.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/jaypipes/ghw/pkg/marshal"
"github.com/jaypipes/ghw/pkg/memory"
"github.com/jaypipes/ghw/pkg/net"
"github.com/jaypipes/ghw/pkg/pci"
"github.com/jaypipes/ghw/pkg/product"
"github.com/jaypipes/ghw/pkg/topology"
)
Expand All @@ -35,6 +36,7 @@ type HostInfo struct {
BIOS *bios.Info `json:"bios"`
Baseboard *baseboard.Info `json:"baseboard"`
Product *product.Info `json:"product"`
PCI *pci.Info `json:"pci"`
}

// Host returns a pointer to a HostInfo struct that contains fields with
Expand Down Expand Up @@ -80,6 +82,10 @@ func Host(opts ...*WithOption) (*HostInfo, error) {
if err != nil {
return nil, err
}
pciInfo, err := pci.New(opts...)
if err != nil {
return nil, err
}
return &HostInfo{
CPU: cpuInfo,
Memory: memInfo,
Expand All @@ -91,14 +97,15 @@ func Host(opts ...*WithOption) (*HostInfo, error) {
BIOS: biosInfo,
Baseboard: baseboardInfo,
Product: productInfo,
PCI: pciInfo,
}, nil
}

// String returns a newline-separated output of the HostInfo's component
// structs' String-ified output
func (info *HostInfo) String() string {
return fmt.Sprintf(
"%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
"%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
info.Block.String(),
info.CPU.String(),
info.GPU.String(),
Expand All @@ -109,6 +116,7 @@ func (info *HostInfo) String() string {
info.BIOS.String(),
info.Baseboard.String(),
info.Product.String(),
info.PCI.String(),
)
}

Expand Down
37 changes: 34 additions & 3 deletions pkg/pci/pci.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/jaypipes/pcidb"

"github.com/jaypipes/ghw/pkg/context"
"github.com/jaypipes/ghw/pkg/marshal"
"github.com/jaypipes/ghw/pkg/option"
"github.com/jaypipes/ghw/pkg/util"
)
Expand Down Expand Up @@ -128,12 +129,24 @@ func (d *Device) String() string {

type Info struct {
ctx *context.Context
// All PCI devices on the host system
Devices []*Device
// hash of class ID -> class information
Classes map[string]*pcidb.Class
// DEPRECATED. Will be removed in v1.0. Please use
// github.com/jaypipes/pcidb to explore PCIDB information
Classes map[string]*pcidb.Class `json:"-"`
// hash of vendor ID -> vendor information
Vendors map[string]*pcidb.Vendor
// DEPRECATED. Will be removed in v1.0. Please use
// github.com/jaypipes/pcidb to explore PCIDB information
Vendors map[string]*pcidb.Vendor `json:"-"`
// hash of vendor ID + product/device ID -> product information
Products map[string]*pcidb.Product
// DEPRECATED. Will be removed in v1.0. Please use
// github.com/jaypipes/pcidb to explore PCIDB information
Products map[string]*pcidb.Product `json:"-"`
}

func (i *Info) String() string {
return fmt.Sprintf("PCI (%d devices)", len(i.Devices))
}

type Address struct {
Expand Down Expand Up @@ -178,3 +191,21 @@ func New(opts ...*option.Option) (*Info, error) {
}
return info, nil
}

// simple private struct used to encapsulate PCI information in a top-level
// "pci" YAML/JSON map/object key
type pciPrinter struct {
Info *Info `json:"pci"`
}

// YAMLString returns a string with the PCI information formatted as YAML
// under a top-level "pci:" key
func (i *Info) YAMLString() string {
return marshal.SafeYAML(pciPrinter{i})
}

// JSONString returns a string with the PCI information formatted as JSON
// under a top-level "pci:" key
func (i *Info) JSONString(indent bool) string {
return marshal.SafeJSON(pciPrinter{i}, indent)
}
3 changes: 3 additions & 0 deletions pkg/pci/pci_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func (i *Info) load() error {
i.Classes = db.Classes
i.Vendors = db.Vendors
i.Products = db.Products
i.Devices = i.ListDevices()
return nil
}

Expand Down Expand Up @@ -272,6 +273,8 @@ func (info *Info) GetDevice(address string) *Device {

// ListDevices returns a list of pointers to Device structs present on the
// host system
// DEPRECATED. Will be removed in v1.0. Please use
// github.com/jaypipes/pcidb to explore PCIDB information
func (info *Info) ListDevices() []*Device {
paths := linuxpath.New(info.ctx)
devs := make([]*Device, 0)
Expand Down