Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Go HardWare discovery/inspection library

License

NotificationsYou must be signed in to change notification settings

jaypipes/ghw

Go ReferenceGo Report CardBuild StatusContributor Covenant

ghw mascot

ghw is a Go library providing hardware inspection and discovery for Linux andWindows. There currently exists partial support for MacOSX.

Design Principles

  • No root privileges needed for discovery

    ghw goes the extra mile to be useful without root priveleges. We query forhost hardware information as directly as possible without relying on shelloutsto programs likedmidecode that require root privileges to execute.

    Elevated privileges are indeed required to query for some information, butghw will never error out if blocked from reading that information. Instead,ghw will print a warning message about the information that could not beretrieved. You may disable these warning messages with theGHW_DISABLE_WARNINGS environment variable.

  • Well-documented code and plenty of example code

    The code itself should be well-documented with lots of usage examples.

  • Interfaces should be consistent across modules

    Each module in the library should be structured in a consistent fashion, andthe structs returned by various library functions should have consistentattribute and method names.

Inspecting != Monitoring

ghw is a tool for gathering information about your hardware'scapacityandcapabilities.

It is important to point out thatghw doesNOT report information that istemporary or variable. It isNOT a system monitor nor is it an appropriatetool for gathering data points for metrics that change over time. If you arelooking for a system that tracksusage of CPU, memory, network I/O or diskI/O, there are plenty of great open source tools that do this! Check out thePrometheus project for a great example.

Usage

ghw has functions that return anInfo object about a particular hardwaredomain (e.g. CPU, Memory, Block storage, etc).

Use the following functions inghw to inspect information about the hosthardware:

CPU

Theghw.CPU() function returns aghw.CPUInfo struct that containsinformation about the CPUs on the host system.

ghw.CPUInfo contains the following fields:

  • ghw.CPUInfo.TotalCores has the total number of physical cores the hostsystem contains
  • ghw.CPUInfo.TotalHardwareThreads has the total number of hardware threadsthe host system contains
  • ghw.CPUInfo.Processors is an array ofghw.Processor structs, one for eachphysical processor package contained in the host

Eachghw.Processor struct contains a number of fields:

  • ghw.Processor.ID is the physical processoruint32 ID according to thesystem
  • ghw.Processor.TotalCores is the number of physical cores in the processorpackage
  • ghw.Processor.TotalHardwareThreads is the number of hardware threads in theprocessor package
  • ghw.Processor.Vendor is a string containing the vendor name
  • ghw.Processor.Model is a string containing the vendor's model name
  • ghw.Processor.Capabilities (Linux only) is an array of strings indicatingthe features the processor has enabled
  • ghw.Processor.Cores (Linux only) is an array ofghw.ProcessorCore structsthat are packed onto this physical processor

Aghw.ProcessorCore has the following fields:

  • ghw.ProcessorCore.ID is theuint32 identifier that the host gave thiscore. Note that this doesnot necessarily equate to a zero-based index ofthe core within a physical package. For example, the core IDs for an Intel Corei7 are 0, 1, 2, 8, 9, and 10
  • ghw.ProcessorCore.TotalHardwareThreads is the number of hardware threadsassociated with the core
  • ghw.ProcessorCore.LogicalProcessors is an array of ints representing thelogical processor IDs assigned to any processing unit for the core. These aresometimes called the "thread siblings". Logical processor IDs are thezero-based index of the processor on the host and arenot related to thecore ID.
package mainimport ("fmt""math""strings""github.com/jaypipes/ghw")funcmain() {cpu,err:=ghw.CPU()iferr!=nil {fmt.Printf("Error getting CPU info: %v",err)}fmt.Printf("%v\n",cpu)for_,proc:=rangecpu.Processors {fmt.Printf(" %v\n",proc)for_,core:=rangeproc.Cores {fmt.Printf("  %v\n",core)}iflen(proc.Capabilities)>0 {// pretty-print the (large) block of capability strings into rows// of 6 capability stringsrows:=int(math.Ceil(float64(len(proc.Capabilities))/float64(6)))forrow:=1;row<rows;row=row+1 {rowStart:= (row*6)-1rowEnd:=int(math.Min(float64(rowStart+6),float64(len(proc.Capabilities))))rowElems:=proc.Capabilities[rowStart:rowEnd]capStr:=strings.Join(rowElems," ")ifrow==1 {fmt.Printf("  capabilities: [%s\n",capStr)}elseifrowEnd<len(proc.Capabilities) {fmt.Printf("                 %s\n",capStr)}else {fmt.Printf("                 %s]\n",capStr)}}}}}

Example output from my personal workstation:

cpu (1 physical package, 6 cores, 12 hardware threads) physical package #0 (6 cores, 12 hardware threads)  processor core #0 (2 threads), logical processors [0 6]  processor core #1 (2 threads), logical processors [1 7]  processor core #2 (2 threads), logical processors [2 8]  processor core #3 (2 threads), logical processors [3 9]  processor core #4 (2 threads), logical processors [4 10]  processor core #5 (2 threads), logical processors [5 11]  capabilities: [msr pae mce cx8 apic sep                 mtrr pge mca cmov pat pse36                 clflush dts acpi mmx fxsr sse                 sse2 ss ht tm pbe syscall                 nx pdpe1gb rdtscp lm constant_tsc arch_perfmon                 pebs bts rep_good nopl xtopology nonstop_tsc                 cpuid aperfmperf pni pclmulqdq dtes64 monitor                 ds_cpl vmx est tm2 ssse3 cx16                 xtpr pdcm pcid sse4_1 sse4_2 popcnt                 aes lahf_lm pti retpoline tpr_shadow vnmi                 flexpriority ept vpid dtherm ida arat]

Memory

Theghw.Memory() function returns aghw.MemoryInfo struct that containsinformation about the RAM on the host system.

ghw.MemoryInfo contains the following fields:

  • ghw.MemoryInfo.TotalPhysicalBytes contains the amount of physical memory onthe host
  • ghw.MemoryInfo.TotalUsableBytes contains the amount of memory thesystem can actually use. Usable memory accounts for things like the kernel'sresident memory size and some reserved system bits. Please note this value isNOT the amount of memory currently in use by processes in the system. See[the discussion][#physical-versus-usage-memory] about the difference.
  • ghw.MemoryInfo.SupportedPageSizes is an array of integers representing thesize, in bytes, of memory pages the system supports
  • ghw.MemoryInfo.Modules is an array of pointers toghw.MemoryModulestructs, one for each physicalDIMM.Currently, this information is only included on Windows, with Linux supportplanned.
package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {memory,err:=ghw.Memory()iferr!=nil {fmt.Printf("Error getting memory info: %v",err)}fmt.Println(memory.String())}

Example output from my personal workstation:

memory (24GB physical, 24GB usable)

Physical versus Usable Memory

There has beensomeconfusion regarding thedifference between the total physical bytes versus total usable bytes ofmemory.

Some of this confusion has been due to a misunderstanding of the term "usable".As mentionedabove,ghw does inspection of thesystem's capacity.

A host computer has two capacities when it comes to RAM. The first capacity isthe amount of RAM that is contained in all memory banks (DIMMs) that areattached to the motherboard.ghw.MemoryInfo.TotalPhysicalBytes refers to thisfirst capacity.

There is a (usually small) amount of RAM that is consumed by the bootloaderbefore the operating system is started (booted). Once the bootloader has bootedthe operating system, the amount of RAM that may be used by the operatingsystem and its applications is fixed.ghw.MemoryInfo.TotalUsableBytes refersto this second capacity.

You can determine the amount of RAM that the bootloader used (that is not madeavailable to the operating system) by subtractingghw.MemoryInfo.TotalUsableBytes fromghw.MemoryInfo.TotalPhysicalBytes:

package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {memory,err:=ghw.Memory()iferr!=nil {fmt.Printf("Error getting memory info: %v",err)}phys:=memory.TotalPhysicalBytesusable:=memory.TotalUsableBytesfmt.Printf("The bootloader consumes %d bytes of RAM\n",phys-usable)}

Example output from my personal workstation booted into a Windows10 operatingsystem with a Linux GRUB bootloader:

The bootloader consumes 3832720 bytes of RAM

Block storage

Theghw.Block() function returns aghw.BlockInfo struct that containsinformation about the block storage on the host system.

ghw.BlockInfo contains the following fields:

  • ghw.BlockInfo.TotalSizeBytes contains the amount of physical block storageon the host.
  • ghw.BlockInfo.Disks is an array of pointers toghw.Disk structs, one foreach disk found by the system

Eachghw.Disk struct contains the following fields:

  • ghw.Disk.Name contains a string with the short name of the disk, e.g. "sda"
  • ghw.Disk.SizeBytes contains the amount of storage the disk provides
  • ghw.Disk.PhysicalBlockSizeBytes contains the size of the physical blocksused on the disk, in bytes. This is typically the minimum amount of data thatwill be written in a single write operation for the disk.
  • ghw.Disk.IsRemovable contains a boolean indicating if the disk drive isremovable
  • ghw.Disk.DriveType is the type of drive. It is of typeghw.DriveTypewhich has aghw.DriveType.String() method that can be called to return astring representation of the bus. This string will beHDD,FDD,ODD,orSSD, which correspond to a hard disk drive (rotational), floppy drive,optical (CD/DVD) drive and solid-state drive.
  • ghw.Disk.StorageController is the type of storage controller. It is of typeghw.StorageController which has aghw.StorageController.String() methodthat can be called to return a string representation of the bus. This stringwill beSCSI,IDE,virtio,MMC, orNVMe
  • ghw.Disk.BusPath (Linux, Darwin only) is the filepath to the bus used bythe disk.
  • ghw.Disk.NUMANodeID (Linux only) is the numeric index of the NUMA node thisdisk is local to, or -1 if the host system is not a NUMA system or is notLinux.
  • ghw.Disk.Vendor contains a string with the name of the hardware vendor forthe disk
  • ghw.Disk.Model contains a string with the vendor-assigned disk model name
  • ghw.Disk.SerialNumber contains a string with the disk's serial number
  • ghw.Disk.WWN contains a string with the disk'sWorld Wide Name
  • ghw.Disk.Partitions contains an array of pointers toghw.Partitionstructs, one for each partition on the disk

Eachghw.Partition struct contains these fields:

  • ghw.Partition.Name contains a string with the short name of the partition,e.g.sda1
  • ghw.Partition.Label contains the label for the partition itself. On Linuxsystems, this is derived from theID_PART_ENTRY_NAMEudev entry forthe partition.
  • ghw.Partition.FilesystemLabel contains the label for the filesystem housedon the partition. On Linux systems, this is derived from theID_FS_NAMEudev entry for the partition.
  • ghw.Partition.SizeBytes contains the amount of storage the partitionprovides
  • ghw.Partition.MountPoint contains a string with the partition's mountpoint, or"" if no mount point was discovered
  • ghw.Partition.Type contains a string indicated the filesystem type for thepartition, or"" if the system could not determine the type
  • ghw.Partition.IsReadOnly is a bool indicating the partition is read-only
  • ghw.Partition.Disk is a pointer to theghw.Disk object associated withthe partition.
  • ghw.Partition.UUID is a string containing the partition UUID on Linux, thepartition UUID on MacOS and nothing on Windows. On Linux systems, this isderived from theID_PART_ENTRY_UUIDudev entry for the partition.
package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {block,err:=ghw.Block()iferr!=nil {fmt.Printf("Error getting block storage info: %v",err)}fmt.Printf("%v\n",block)for_,disk:=rangeblock.Disks {fmt.Printf(" %v\n",disk)for_,part:=rangedisk.Partitions {fmt.Printf("  %v\n",part)}}}

Example output from my personal workstation:

block storage (1 disk, 2TB physical storage) sda HDD (2TB) SCSI [@pci-0000:04:00.0-scsi-0:1:0:0 (node #0)] vendor=LSI model=Logical_Volume serial=600508e000000000f8253aac9a1abd0c WWN=0x600508e000000000f8253aac9a1abd0c  /dev/sda1 (100MB)  /dev/sda2 (187GB)  /dev/sda3 (449MB)  /dev/sda4 (1KB)  /dev/sda5 (15GB)  /dev/sda6 (2TB) [ext4] mounted@/

NOTE:ghw looks in the udev runtime database for some information. Ifyou are usingghw in a container, remember to bind mount/dev/disk and/run into your container, otherwiseghw won't be able to query the udevDB or sysfs paths for information.

Topology

NOTE: Topology support is currently Linux-only. Windows support isplanned.

Theghw.Topology() function returns aghw.TopologyInfo struct that containsinformation about the host computer's architecture (NUMA vs. SMP), the host'sNUMA node layout and processor-specific memory caches.

Theghw.TopologyInfo struct contains two fields:

  • ghw.TopologyInfo.Architecture contains an enum with the valueghw.NUMA orghw.SMP depending on what the topology of the system is
  • ghw.TopologyInfo.Nodes is an array of pointers toghw.TopologyNodestructs, one for each topology node (typically physical processor package)found by the system

Eachghw.TopologyNode struct contains the following fields:

  • ghw.TopologyNode.ID is the system'suint32 identifier for the node
  • ghw.TopologyNode.Memory is aghw.MemoryArea struct describing the memoryattached to this node.
  • ghw.TopologyNode.Cores is an array of pointers toghw.ProcessorCore structs thatare contained in this node
  • ghw.TopologyNode.Caches is an array of pointers toghw.MemoryCache structs thatrepresent the low-level caches associated with processors and cores on thesystem
  • ghw.TopologyNode.Distance is an array of distances between NUMA nodes as reportedby the system.

ghw.MemoryArea describes a collection ofphysical RAM on the host.

In the simplest and most common case, all system memory fits in a single memoryarea. In more complex host systems, likeNUMA systems, many memoryareas may be present in the host system (e.g. one for each NUMA cell).

Theghw.MemoryArea struct contains the following fields:

  • ghw.MemoryArea.TotalPhysicalBytes contains the amount of physical memoryassociated with this memory area.
  • ghw.MemoryArea.TotalUsableBytes contains the amount of memory of thismemory area the system can actually use. Usable memory accounts for thingslike the kernel's resident memory size and some reserved system bits. Pleasenote this value isNOT the amount of memory currently in use by processesin the system. See [the discussion][#physical-versus-usage-memory] aboutthe difference.

See above in theCPU section for information about theghw.ProcessorCore struct and how to use and query it.

Eachghw.MemoryCache struct contains the following fields:

  • ghw.MemoryCache.Type is an enum that contains one ofghw.DATA,ghw.INSTRUCTION orghw.UNIFIED depending on whether the cache stores CPUinstructions, program data, or both
  • ghw.MemoryCache.Level is a positive integer indicating how close the cacheis to the processor. The lower the number, the closer the cache is to theprocessor and the faster the processor can access its contents
  • ghw.MemoryCache.SizeBytes is an integer containing the number of bytes thecache can contain
  • ghw.MemoryCache.LogicalProcessors is an array of integers representing thelogical processors that use the cache
package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {topology,err:=ghw.Topology()iferr!=nil {fmt.Printf("Error getting topology info: %v",err)}fmt.Printf("%v\n",topology)for_,node:=rangetopology.Nodes {fmt.Printf(" %v\n",node)for_,cache:=rangenode.Caches {fmt.Printf("  %v\n",cache)}}}

Example output from my personal workstation:

topology SMP (1 nodes) node #0 (6 cores)  L1i cache (32 KB) shared with logical processors: 3,9  L1i cache (32 KB) shared with logical processors: 2,8  L1i cache (32 KB) shared with logical processors: 11,5  L1i cache (32 KB) shared with logical processors: 10,4  L1i cache (32 KB) shared with logical processors: 0,6  L1i cache (32 KB) shared with logical processors: 1,7  L1d cache (32 KB) shared with logical processors: 11,5  L1d cache (32 KB) shared with logical processors: 10,4  L1d cache (32 KB) shared with logical processors: 3,9  L1d cache (32 KB) shared with logical processors: 1,7  L1d cache (32 KB) shared with logical processors: 0,6  L1d cache (32 KB) shared with logical processors: 2,8  L2 cache (256 KB) shared with logical processors: 2,8  L2 cache (256 KB) shared with logical processors: 3,9  L2 cache (256 KB) shared with logical processors: 0,6  L2 cache (256 KB) shared with logical processors: 10,4  L2 cache (256 KB) shared with logical processors: 1,7  L2 cache (256 KB) shared with logical processors: 11,5  L3 cache (12288 KB) shared with logical processors: 0,1,10,11,2,3,4,5,6,7,8,9

Network

Theghw.Network() function returns aghw.NetworkInfo struct that containsinformation about the host computer's networking hardware.

Theghw.NetworkInfo struct contains one field:

  • ghw.NetworkInfo.NICs is an array of pointers toghw.NIC structs, onefor each network interface controller found for the systen

Eachghw.NIC struct contains the following fields:

  • ghw.NIC.Name is the system's identifier for the NIC
  • ghw.NIC.MACAddress is the Media Access Control (MAC) address for the NIC,if any
  • ghw.NIC.IsVirtual is a boolean indicating if the NIC is a virtualizeddevice
  • ghw.NIC.Capabilities (Linux only) is an array of pointers toghw.NICCapability structs that can describe the things the NIC supports.These capabilities match the returned values from theethtool -k <DEVICE>call on Linux as well as the AutoNegotiation and PauseFrameUse capabilitiesfromethtool.
  • ghw.NIC.PCIAddress (Linux only) is the PCI device address of the devicebacking the NIC. this is not-nil only if the backing device is indeed a PCIdevice; more backing devices (e.g. USB) will be added in future versions.
  • ghw.NIC.Speed (Linux only) is a string showing the current link speed. OnLinux, this field will be present even ifethtool is not available.
  • ghw.NIC.Duplex (Linux only) is a string showing the current link duplex. OnLinux, this field will be present even ifethtool is not available.
  • ghw.NIC.SupportedLinkModes (Linux only) is a string slice containing a listof supported link modes, e.g. "10baseT/Half", "1000baseT/Full".
  • ghw.NIC.SupportedPorts (Linux only) is a string slice containing the listof supported port types, e.g. "MII", "TP", "FIBRE", "Twisted Pair".
  • ghw.NIC.SupportedFECModes (Linux only) is a string slice containing a listof supported Forward Error Correction (FEC) Modes.
  • ghw.NIC.AdvertisedLinkModes (Linux only) is a string slice containing thelink modes being advertised during auto negotiation.
  • ghw.NIC.AdvertisedFECModes (Linux only) is a string slice containing theForward Error Correction (FEC) modes advertised during auto negotiation.

Theghw.NICCapability struct contains the following fields:

  • ghw.NICCapability.Name is the string name of the capability (e.g."tcp-segmentation-offload")
  • ghw.NICCapability.IsEnabled is a boolean indicating whether the capabilityis currently enabled/active on the NIC
  • ghw.NICCapability.CanEnable is a boolean indicating whether the capabilitymay be enabled
package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {net,err:=ghw.Network()iferr!=nil {fmt.Printf("Error getting network info: %v",err)    }fmt.Printf("%v\n",net)for_,nic:=rangenet.NICs {fmt.Printf(" %v\n",nic)enabledCaps:=make([]int,0)forx,cap:=rangenic.Capabilities {ifcap.IsEnabled {enabledCaps=append(enabledCaps,x)            }        }iflen(enabledCaps)>0 {fmt.Printf("  enabled capabilities:\n")for_,x:=rangeenabledCaps {fmt.Printf("   - %s\n",nic.Capabilities[x].Name)            }        }    }}

Example output from my personal laptop:

net (3 NICs) docker0  enabled capabilities:   - tx-checksumming   - tx-checksum-ip-generic   - scatter-gather   - tx-scatter-gather   - tx-scatter-gather-fraglist   - tcp-segmentation-offload   - tx-tcp-segmentation   - tx-tcp-ecn-segmentation   - tx-tcp-mangleid-segmentation   - tx-tcp6-segmentation   - udp-fragmentation-offload   - generic-segmentation-offload   - generic-receive-offload   - tx-vlan-offload   - highdma   - tx-lockless   - netns-local   - tx-gso-robust   - tx-fcoe-segmentation   - tx-gre-segmentation   - tx-gre-csum-segmentation   - tx-ipxip4-segmentation   - tx-ipxip6-segmentation   - tx-udp_tnl-segmentation   - tx-udp_tnl-csum-segmentation   - tx-gso-partial   - tx-sctp-segmentation   - tx-esp-segmentation   - tx-vlan-stag-hw-insert enp58s0f1  enabled capabilities:   - rx-checksumming   - generic-receive-offload   - rx-vlan-offload   - tx-vlan-offload   - highdma   - auto-negotiation wlp59s0  enabled capabilities:   - scatter-gather   - tx-scatter-gather   - generic-segmentation-offload   - generic-receive-offload   - highdma   - netns-local

PCI

ghw contains a PCI database inspection and querying facility that allowsdevelopers to not only gather information about devices on a local PCI bus butalso query for information about hardware device classes, vendor and productinformation.

NOTE: Parsing of the PCI-IDS file database is provided by the separategithub.com/jaypipes/pcidb library. Youcan read that library's README for more information about the various structsthat are exposed on theghw.PCIInfo struct.

Theghw.PCI() function returns aghw.PCIInfo struct that containsinformation about the host computer's PCI devices.

Theghw.PCIInfo struct contains one field:

  • ghw.PCIInfo.Devices is a slice of pointers toghw.PCIDevice structs thatdescribe the PCI devices on the host system

NOTE: PCI products are often referred to by their "device ID". We use theterm "product ID" inghw because it more accurately reflects what theidentifier is for: a specific product line produced by the vendor.

Theghw.PCIDevice struct has the following fields:

  • ghw.PCIDevice.Vendor is a pointer to apcidb.Vendor struct thatdescribes the device's primary vendor. This will always be non-nil.
  • ghw.PCIDevice.Product is a pointer to apcidb.Product struct thatdescribes the device's primary product. This will always be non-nil.
  • ghw.PCIDevice.Subsystem is a pointer to apcidb.Product struct thatdescribes the device's secondary/sub-product. This will always be non-nil.
  • ghw.PCIDevice.Class is a pointer to apcidb.Class struct thatdescribes the device's class. This will always be non-nil.
  • ghw.PCIDevice.Subclass is a pointer to apcidb.Subclass structthat describes the device's subclass. This will always be non-nil.
  • ghw.PCIDevice.ProgrammingInterface is a pointer to apcidb.ProgrammingInterface struct that describes the device subclass'programming interface. This will always be non-nil.
  • ghw.PCIDevice.Driver is a string representing the device driver thesystem is using to handle this device. Can be empty string if thisinformation is not available. If the information is not available, this doesnot mean the device is not functioning, but rather thatghw was not able toretrieve driver information.

Theghw.PCIAddress (which is an alias for theghw.pci.address.Addressstruct) contains the PCI address fields. It has aghw.PCIAddress.String()method that returns the canonical Domain:Bus:Device.Function ([D]BDF)representation of this Address.

Theghw.PCIAddress struct has the following fields:

  • ghw.PCIAddress.Domain is a string representing the PCI domain component ofthe address.
  • ghw.PCIAddress.Bus is a string representing the PCI bus component ofthe address.
  • ghw.PCIAddress.Device is a string representing the PCI device component ofthe address.
  • ghw.PCIAddress.Function is a string representing the PCI function component ofthe address.

NOTE: Older versions (pre-v0.9.0) erroneously referred to theDevicefield as theSlot field. As noted by@pearsonkin#220, this was a misnomer.

The following code snippet shows how to list the PCI devices on the host systemand output a simple list of PCI address and vendor/product information:

package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {pci,err:=ghw.PCI()iferr!=nil {fmt.Printf("Error getting PCI info: %v",err)}fmt.Printf("host PCI devices:\n")fmt.Println("====================================================")for_,device:=rangepci.Devices {vendor:=device.VendorvendorName:=vendor.Nameiflen(vendor.Name)>20 {vendorName=string([]byte(vendorName)[0:17])+"..."}product:=device.ProductproductName:=product.Nameiflen(product.Name)>40 {productName=string([]byte(productName)[0:37])+"..."}fmt.Printf("%-12s\t%-20s\t%-40s\n",device.Address,vendorName,productName)}}

on my local workstation the output of the above looks like the following:

host PCI devices:====================================================0000:00:00.0Intel Corporation   5520/5500/X58 I/O Hub to ESI Port0000:00:01.0Intel Corporation   5520/5500/X58 I/O Hub PCI Express Roo...0000:00:02.0Intel Corporation   5520/5500/X58 I/O Hub PCI Express Roo...0000:00:03.0Intel Corporation   5520/5500/X58 I/O Hub PCI Express Roo...0000:00:07.0Intel Corporation   5520/5500/X58 I/O Hub PCI Express Roo...0000:00:10.0Intel Corporation   7500/5520/5500/X58 Physical and Link ...0000:00:10.1Intel Corporation   7500/5520/5500/X58 Routing and Protoc...0000:00:14.0Intel Corporation   7500/5520/5500/X58 I/O Hub System Man...0000:00:14.1Intel Corporation   7500/5520/5500/X58 I/O Hub GPIO and S...0000:00:14.2Intel Corporation   7500/5520/5500/X58 I/O Hub Control St...0000:00:14.3Intel Corporation   7500/5520/5500/X58 I/O Hub Throttle R...0000:00:19.0Intel Corporation   82567LF-2 Gigabit Network Connection0000:00:1a.0Intel Corporation   82801JI (ICH10 Family) USB UHCI Contr...0000:00:1a.1Intel Corporation   82801JI (ICH10 Family) USB UHCI Contr...0000:00:1a.2Intel Corporation   82801JI (ICH10 Family) USB UHCI Contr...0000:00:1a.7Intel Corporation   82801JI (ICH10 Family) USB2 EHCI Cont...0000:00:1b.0Intel Corporation   82801JI (ICH10 Family) HD Audio Contr...0000:00:1c.0Intel Corporation   82801JI (ICH10 Family) PCI Express Ro...0000:00:1c.1Intel Corporation   82801JI (ICH10 Family) PCI Express Po...0000:00:1c.4Intel Corporation   82801JI (ICH10 Family) PCI Express Ro...0000:00:1d.0Intel Corporation   82801JI (ICH10 Family) USB UHCI Contr...0000:00:1d.1Intel Corporation   82801JI (ICH10 Family) USB UHCI Contr...0000:00:1d.2Intel Corporation   82801JI (ICH10 Family) USB UHCI Contr...0000:00:1d.7Intel Corporation   82801JI (ICH10 Family) USB2 EHCI Cont...0000:00:1e.0Intel Corporation   82801 PCI Bridge0000:00:1f.0Intel Corporation   82801JIR (ICH10R) LPC Interface Contr...0000:00:1f.2Intel Corporation   82801JI (ICH10 Family) SATA AHCI Cont...0000:00:1f.3Intel Corporation   82801JI (ICH10 Family) SMBus Controller0000:01:00.0NEC Corporation     uPD720200 USB 3.0 Host Controller0000:02:00.0Marvell Technolog...88SE9123 PCIe SATA 6.0 Gb/s controller0000:02:00.1Marvell Technolog...88SE912x IDE Controller0000:03:00.0NVIDIA Corporation  GP107 [GeForce GTX 1050 Ti]0000:03:00.1NVIDIA Corporation  UNKNOWN0000:04:00.0LSI Logic / Symbi...SAS2004 PCI-Express Fusion-MPT SAS-2 ...0000:06:00.0Qualcomm Atheros    AR5418 Wireless Network Adapter [AR50...0000:08:03.0LSI Corporation     FW322/323 [TrueFire] 1394a Controller0000:3f:00.0Intel Corporation   UNKNOWN0000:3f:00.1Intel Corporation   Xeon 5600 Series QuickPath Architectu...0000:3f:02.0Intel Corporation   Xeon 5600 Series QPI Link 00000:3f:02.1Intel Corporation   Xeon 5600 Series QPI Physical 00000:3f:02.2Intel Corporation   Xeon 5600 Series Mirror Port Link 00000:3f:02.3Intel Corporation   Xeon 5600 Series Mirror Port Link 10000:3f:03.0Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:03.1Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:03.4Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:04.0Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:04.1Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:04.2Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:04.3Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:05.0Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:05.1Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:05.2Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:05.3Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:06.0Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:06.1Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:06.2Intel Corporation   Xeon 5600 Series Integrated Memory Co...0000:3f:06.3Intel Corporation   Xeon 5600 Series Integrated Memory Co...

Finding a PCI device by PCI address

In addition to the above information, theghw.PCIInfo struct has thefollowing method:

  • ghw.PCIInfo.GetDevice(address string)

The following code snippet shows how to call theghw.PCIInfo.GetDevice()method and use its returnedghw.PCIDevice struct pointer:

package mainimport ("fmt""os""github.com/jaypipes/ghw")funcmain() {pci,err:=ghw.PCI()iferr!=nil {fmt.Printf("Error getting PCI info: %v",err)}addr:="0000:00:00.0"iflen(os.Args)==2 {addr=os.Args[1]}fmt.Printf("PCI device information for %s\n",addr)fmt.Println("====================================================")deviceInfo:=pci.GetDevice(addr)ifdeviceInfo==nil {fmt.Printf("could not retrieve PCI device information for %s\n",addr)return}vendor:=deviceInfo.Vendorfmt.Printf("Vendor: %s [%s]\n",vendor.Name,vendor.ID)product:=deviceInfo.Productfmt.Printf("Product: %s [%s]\n",product.Name,product.ID)subsystem:=deviceInfo.Subsystemsubvendor:=pci.Vendors[subsystem.VendorID]subvendorName:="UNKNOWN"ifsubvendor!=nil {subvendorName=subvendor.Name}fmt.Printf("Subsystem: %s [%s] (Subvendor: %s)\n",subsystem.Name,subsystem.ID,subvendorName)class:=deviceInfo.Classfmt.Printf("Class: %s [%s]\n",class.Name,class.ID)subclass:=deviceInfo.Subclassfmt.Printf("Subclass: %s [%s]\n",subclass.Name,subclass.ID)progIface:=deviceInfo.ProgrammingInterfacefmt.Printf("Programming Interface: %s [%s]\n",progIface.Name,progIface.ID)}

Here's a sample output from my local workstation:

PCI device information for 0000:03:00.0====================================================Vendor: NVIDIA Corporation [10de]Product: GP107 [GeForce GTX 1050 Ti] [1c82]Subsystem: UNKNOWN [8613] (Subvendor: ASUSTeK Computer Inc.)Class: Display controller [03]Subclass: VGA compatible controller [00]Programming Interface: VGA controller [00]

GPU

Theghw.GPU() function returns aghw.GPUInfo struct that containsinformation about the host computer's graphics hardware.

Theghw.GPUInfo struct contains one field:

  • ghw.GPUInfo.GraphicCards is an array of pointers toghw.GraphicsCardstructs, one for each graphics card found for the system

Eachghw.GraphicsCard struct contains the following fields:

  • ghw.GraphicsCard.Index is the system's numeric zero-based index for thecard on the bus
  • ghw.GraphicsCard.Address is the PCI address for the graphics card
  • ghw.GraphicsCard.DeviceInfo is a pointer to aghw.PCIDevice structdescribing the graphics card. This may benil if no PCI device informationcould be determined for the card.
  • ghw.GraphicsCard.Node is an pointer to aghw.TopologyNode struct that theGPU/graphics card is affined to. On non-NUMA systems, this will always benil.
package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {gpu,err:=ghw.GPU()iferr!=nil {fmt.Printf("Error getting GPU info: %v",err)}fmt.Printf("%v\n",gpu)for_,card:=rangegpu.GraphicsCards {fmt.Printf(" %v\n",card)}}

Example output from my personal workstation:

gpu (1 graphics card) card #0 @0000:03:00.0 -> class: 'Display controller' vendor: 'NVIDIA Corporation' product: 'GP107 [GeForce GTX 1050 Ti]'

NOTE: You canread more about the fields of theghw.PCIDevicestruct if you'd like to dig deeper into PCI subsystem and programming interfaceinformation

NOTE: You canread more about the fields of theghw.TopologyNode struct if you'd like to dig deeper into the NUMA/topologysubsystem

Accelerator

Theghw.Accelerator() function returns aghw.AcceleratorInfo struct that containsinformation about the host computer's processing accelerator hardware. In this categorywe can find used hardware for AI. The hardware detected in this category will beprocessing accelerators (PCI class1200), 3D controllers (0302) and Displaycontrollers (0380).

Theghw.AcceleratorInfo struct contains one field:

  • ghw.AcceleratorInfo.Devices is an array of pointers toghw.AcceleratorDevicestructs, one for each processing accelerator card found for the system.

Eachghw.AcceleratorDevice struct contains the following fields:

  • ghw.AcceleratorDevice.Address is the PCI address for the processing accelerator card.
  • ghw.AcceleratorDevice.PCIDevice is a pointer to aghw.PCIDevice struct.describing the processing accelerator card. This may benil if no PCI deviceinformation could be determined for the card.
package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {accel,err:=ghw.Accelerator()iferr!=nil {fmt.Printf("Error getting processing accelerator info: %v",err)}fmt.Printf("%v\n",accel)for_,card:=rangeaccel.Devices {fmt.Printf(" %v\n",device)}}

Example output from a testing machine:

processing accelerators (1 device) device @0000:00:04.0 -> driver: 'fake_pci_driver' class: 'Processing accelerators' vendor: 'Red Hat, Inc.' product: 'QEMU PCI Test Device'

NOTE: You canread more about the fields of theghw.PCIDevicestruct if you'd like to dig deeper into PCI subsystem and programming interfaceinformation

Chassis

Theghw.Chassis() function returns aghw.ChassisInfo struct that containsinformation about the host computer's hardware chassis.

Theghw.ChassisInfo struct contains multiple fields:

  • ghw.ChassisInfo.AssetTag is a string with the chassis asset tag
  • ghw.ChassisInfo.SerialNumber is a string with the chassis serial number
  • ghw.ChassisInfo.Type is a string with the chassis typecode
  • ghw.ChassisInfo.TypeDescription is a string with a description of thechassis type
  • ghw.ChassisInfo.Vendor is a string with the chassis vendor
  • ghw.ChassisInfo.Version is a string with the chassis version

NOTE: These fields are often missing for non-server hardware. Don't besurprised to see empty string or "None" values.

package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {chassis,err:=ghw.Chassis()iferr!=nil {fmt.Printf("Error getting chassis info: %v",err)}fmt.Printf("%v\n",chassis)}

Example output from my personal workstation:

chassis type=Desktop vendor=System76 version=thelio-r1

NOTE: Some of the values such as serial numbers are shown as unknownbecause the Linux kernel by default disallows access to those fields ifyou're not running as root. They will be populated if it runs as root orotherwise you may see warnings like the following:

WARNING: Unable to read chassis_serial: open /sys/class/dmi/id/chassis_serial: permission denied

You can ignore them or use theDisabling warning messagesfeature to quiet things down.

BIOS

Theghw.BIOS() function returns aghw.BIOSInfo struct that containsinformation about the host computer's basis input/output system (BIOS).

Theghw.BIOSInfo struct contains multiple fields:

  • ghw.BIOSInfo.Vendor is a string with the BIOS vendor
  • ghw.BIOSInfo.Version is a string with the BIOS version
  • ghw.BIOSInfo.Date is a string with the date the BIOS was flashed/created
package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {bios,err:=ghw.BIOS()iferr!=nil {fmt.Printf("Error getting BIOS info: %v",err)}fmt.Printf("%v\n",bios)}

Example output from my personal workstation:

bios vendor=System76 version=F2 Z5 date=11/14/2018

Baseboard

Theghw.Baseboard() function returns aghw.BaseboardInfo struct thatcontains information about the host computer's hardware baseboard.

Theghw.BaseboardInfo struct contains multiple fields:

  • ghw.BaseboardInfo.AssetTag is a string with the baseboard asset tag
  • ghw.BaseboardInfo.SerialNumber is a string with the baseboard serial number
  • ghw.BaseboardInfo.Vendor is a string with the baseboard vendor
  • ghw.BaseboardInfo.Product is a string with the baseboard name on Linux andProduct on Windows
  • ghw.BaseboardInfo.Version is a string with the baseboard version

NOTE: These fields are often missing for non-server hardware. Don't besurprised to see empty string or "None" values.

package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {baseboard,err:=ghw.Baseboard()iferr!=nil {fmt.Printf("Error getting baseboard info: %v",err)}fmt.Printf("%v\n",baseboard)}

Example output from my personal workstation:

baseboard vendor=System76 version=thelio-r1

NOTE: Some of the values such as serial numbers are shown as unknownbecause the Linux kernel by default disallows access to those fields ifyou're not running as root. They will be populated if it runs as root orotherwise you may see warnings like the following:

WARNING: Unable to read board_serial: open /sys/class/dmi/id/board_serial: permission denied

You can ignore them or use theDisabling warning messagesfeature to quiet things down.

Product

Theghw.Product() function returns aghw.ProductInfo struct thatcontains information about the host computer's hardware product line.

Theghw.ProductInfo struct contains multiple fields:

  • ghw.ProductInfo.Family is a string describing the product family
  • ghw.ProductInfo.Name is a string with the product name
  • ghw.ProductInfo.SerialNumber is a string with the product serial number
  • ghw.ProductInfo.UUID is a string with the product UUID
  • ghw.ProductInfo.SKU is a string with the product stock unit identifier(SKU)
  • ghw.ProductInfo.Vendor is a string with the product vendor
  • ghw.ProductInfo.Version is a string with the product version

NOTE: These fields are often missing for non-server hardware. Don't besurprised to see empty string, "Default string" or "None" values.

package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {product,err:=ghw.Product()iferr!=nil {fmt.Printf("Error getting product info: %v",err)}fmt.Printf("%v\n",product)}

Example output from my personal workstation:

product family=Default string name=Thelio vendor=System76 sku=Default string version=thelio-r1

NOTE: Some of the values such as serial numbers are shown as unknownbecause the Linux kernel by default disallows access to those fields ifyou're not running as root. They will be populated if it runs as root orotherwise you may see warnings like the following:

WARNING: Unable to read product_serial: open /sys/class/dmi/id/product_serial: permission denied

You can ignore them or use theDisabling warning messagesfeature to quiet things down.

Advanced Usage

Disabling warning messages

Whenghw isn't able to retrieve some information, it may print certainwarning messages tostderr. To disable these warnings, simply set theGHW_DISABLE_WARNINGS environs variable:

$ ghwc memoryWARNING:Could not determine total physical bytes of memory. This maybe due to the host being a virtual machine or container with no/var/log/syslog file, or the current user may not have necessaryprivileges to read the syslog. We are falling back to setting thetotal physical amount of memory to the total usable amount of memorymemory (24GB physical, 24GB usable)
$ GHW_DISABLE_WARNINGS=1 ghwc memorymemory (24GB physical, 24GB usable)

You can disable warning programmatically using theWithDisableWarnings option:

import ("github.com/jaypipes/ghw")mem,err:=ghw.Memory(ghw.WithDisableWarnings())

WithDisableWarnings is a alias for theWithNullAlerter option, which in turnleverages the more generalAlerter feature of ghw.

You may supply aAlerter to ghw to redirect all the warnings there, likelogger objects (see for example golang's stdliblog.Logger).Alerter is in fact the minimal logging interfaceghw needs. To learn more, please check theoption.Alerterinterface and theghw.WithAlerter()`function.

Overriding the root mountpointghw uses

Whenghw looks for information about the host system, it considers/ as itsroot mountpoint. So, for example, when looking up CPU information on a Linuxsystem,ghw.CPU() will use the path/proc/cpuinfo.

If you are callingghw from a system that has an alternate root mountpoint,you can either set theGHW_CHROOT environment variable to that alternatepath, or call one of the functions likeghw.CPU() orghw.Memory() with theghw.WithChroot() modifier.

For example, if you are executing from within an application container that hasbind-mounted the root host filesystem to the mount point/host, you would setGHW_CHROOT to/host so thatghw can find/proc/cpuinfo at/host/proc/cpuinfo.

Alternately, you can use theghw.WithChroot() function like so:

cpu,err:=ghw.CPU(ghw.WithChroot("/host"))

Serialization to JSON or YAML

All of theghwXXXInfo structs -- e.g.ghw.CPUInfo -- have two methodsfor producing a serialized JSON or YAML string representation of the containedinformation:

  • JSONString() returns a string containing the information serialized intoJSON. It accepts a single boolean parameter indicating whether to useindentation when outputting the string
  • YAMLString() returns a string containing the information serialized intoYAML
package mainimport ("fmt""github.com/jaypipes/ghw")funcmain() {mem,err:=ghw.Memory()iferr!=nil {fmt.Printf("Error getting memory info: %v",err)}fmt.Printf("%s",mem.YAMLString())}

the above example code prints the following out on my local workstation:

memory:  supported_page_sizes:  - 1073741824  - 2097152  total_physical_bytes: 25263415296  total_usable_bytes: 25263415296

Overriding a specific mountpoint (Linux only)

When running inside containers, it can be cumbersome to only override the rootmountpoint. Inside containers, when granting access to the host file systems,it is common to bind-mount them to a non-standard location, like/sys on/host-sys or/proc to/host-proc. It is rarer to mount them to a commonsubtree (e.g./sys to/host/sys and/proc to/host/proc...)

To better cover this use case,ghw.WithPathOverrides() can be used to supplya mapping of directories to mountpoints, like this example shows:

cpu,err:=ghw.CPU(ghw.WithPathOverrides(ghw.PathOverrides{"/proc":"/host-proc","/sys":"/host-sys",}))

NOTE: This feature works in addition and is composable with theghw.WithChroot() function andGHW_CHROOT environment variable.

Reading hardware information from aghw snapshot (Linux only)

Theghw-snapshot tool can create a snapshot of a host's hardware information.

Please readSNAPSHOT.md to learn about creating snapshots withtheghw-snapshot tool.

You can makeghw read hardware information from a snapshot created withghw-snapshot using environment variables or programmatically.

Use theGHW_SNAPSHOT_PATH environment variable to specify the filepath to asnapshot thatghw will read to determine hardware information. All the neededchroot changes will be automatically performed. By default, the snapshot isunpacked into a temporary directory managed byghw. This temporary directoryis automatically deleted whenghw is finished reading the snapshot.

Three other environment variables are relevant if and only ifGHW_SNAPSHOT_PATHis not empty:

  • GHW_SNAPSHOT_ROOT let users specify the directory on which the snapshotshould be unpacked. This moves the ownership of that directory fromghw tousers. For this reason,ghw willnot automatically clean up the contentunpacked intoGHW_SNAPSHOT_ROOT.
  • GHW_SNAPSHOT_EXCLUSIVE tellsghw that the directory is meant only tocontain the given snapshot, thusghw willnot attempt to unpack it unlessthe directory is empty. You can use bothGHW_SNAPSHOT_ROOT andGHW_SNAPSHOT_EXCLUSIVE to make sureghw unpacks the snapshot only onceregardless of how manyghw packages (e.g. cpu, memory) access it. Set thevalue of this environment variable to any non-empty string.
  • GHW_SNAPSHOT_PRESERVE tellsghw not to clean up the unpacked snapshot.Set the value of this environment variable to any non-empty string.
cpu,err:=ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{Path:"/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz",}))myRoot:="/my/safe/directory"cpu,err:=ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{Path:"/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz",Root:&myRoot,}))myOtherRoot:="/my/other/safe/directory"cpu,err:=ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{Path:"/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz",Root:&myOtherRoot,Exclusive:true,}))

Creating snapshots

You can createghw snapshots using theghw-snapshot tool orprogrammatically using thepkg/snapshot package.

Below is an example of creating aghw snapshot using thepkg/snapshotpackage.

import ("fmt""os""github.com/jaypipes/ghw/pkg/snapshot")// ...scratchDir,err:=os.MkdirTemp("","ghw-snapshot-*")iferr!=nil {fmt.Printf("Error creating clone directory: %v",err)}deferos.RemoveAll(scratchDir)// this step clones all the files and directories ghw cares aboutiferr:=snapshot.CloneTreeInto(scratchDir);err!=nil {fmt.Printf("error cloning into %q: %v",scratchDir,err)}// optionally, you may add extra content into your snapshot.// ghw will ignore the extra content.// Glob patterns like `filepath.Glob` are supported.fileSpecs:= []string{"/proc/cmdline",}// options allows the client code to optionally deference symlinks, or copy// them into the cloned tree as symlinksvaropts*snapshot.CopyFileOptionsiferr:=snapshot.CopyFilesInto(fileSpecs,scratchDir,opts);err!=nil {fmt.Printf("error cloning extra files into %q: %v",scratchDir,err)}// automates the creation of the gzipped tarball out of the given tree.iferr:=snapshot.PackFrom("my-snapshot.tgz",scratchDir);err!=nil {fmt.Printf("error packing %q into %q: %v",scratchDir,*output,err)}

Calling external programs

By defaultghw may call external programs, for exampleethtool, to learnabout hardware capabilities. In some rare circumstances it may be useful toopt out from this behaviour and rely only on the data provided bypseudo-filesystems, like sysfs.

The most common use case is when we want to read a snapshot fromghw. Inthese cases the information provided by tools will be inconsistent with thedata from the snapshot - since they will be run on a different host than thehost the snapshot was created for.

To preventghw from calling external tools, set theGHW_DISABLE_TOOLSenvironment variable to any value, or, programmatically, use theghw.WithDisableTools() function. The default behaviour of ghw is to callexternal tools when available.

WARNING: on all platforms, disabling external tools make ghw return lessdata. Unless noted otherwise, there isno fallback flow if external toolsare disabled. On MacOSX/Darwin, disabling external tools disables blocksupport entirely

Developers

Contributions toghw are welcomed! Fork the repo on GitHuband submit a pull request with your proposed changes. Or, feel free to log anissue for a feature request or bug report.


[8]ページ先頭

©2009-2025 Movatter.jp