-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #487 from intel-go/develop
Release v0.6.0
- Loading branch information
Showing
100 changed files
with
3,803 additions
and
4,829 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright 2018 Intel Corporation. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package devices helps to query DPDK compatibles devices and to bind/unbind drivers | ||
package devices | ||
|
||
// Device is a DPDK compatible device and should be able to bind, unbind and | ||
// probe. | ||
type Device interface { | ||
// Binds a driver to the device | ||
Bind(driver string) error | ||
// Unbinds the current driver from the device | ||
Unbind() error | ||
// Returns the name of the driver that is currently bound | ||
CurrentDriver() (string, error) | ||
// Probes the currently bound driver and checks if there is an error | ||
Probe() error | ||
// Returns the ID of the device | ||
ID() string | ||
} | ||
|
||
// New returns a corresponding device by given input | ||
func New(input string) (Device, error) { | ||
switch { | ||
case IsPciID.Match([]byte(input)): | ||
return NewDeviceByPciID(input) | ||
case IsUUID.Match([]byte(input)): | ||
return NewDeviceByVmbusID(input) | ||
default: | ||
return NewDeviceByNicName(input) | ||
} | ||
} | ||
|
||
// NewDeviceByPciID returns a PCI device by given PCI ID | ||
func NewDeviceByPciID(pciID string) (Device, error) { | ||
device, err := GetPciDeviceByPciID(pciID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return device, nil | ||
} | ||
|
||
// NewDeviceByVmbusID returns a VMBus device by given UUID | ||
func NewDeviceByVmbusID(uuid string) (Device, error) { | ||
device, err := GetVmbusDeviceByUUID(uuid) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return device, nil | ||
} | ||
|
||
// NewDeviceByNicName returns a device by given NIC name, e.g. eth0. | ||
func NewDeviceByNicName(nicName string) (Device, error) { | ||
devID, err := GetDeviceID(nicName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
device, err := newDevice(devID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return device, nil | ||
} | ||
|
||
func newDevice(id string) (Device, error) { | ||
if IsPciID.Match([]byte(id)) { | ||
return GetPciDeviceByPciID(id) | ||
} | ||
return GetVmbusDeviceByUUID(id) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// Copyright 2018 Intel Corporation. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package devices helps to query DPDK compatibles devices and to bind/unbind drivers | ||
package devices | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
) | ||
|
||
// Driver names | ||
const ( | ||
DriverHvNetvcs = "hv_netvcs" | ||
DriverUioPciGeneric = "uio_pci_generic" | ||
DriverIgUio = "ig_uio" | ||
DriverVfioPci = "vfio-pci" | ||
DriverUioHvGeneric = "uio_hv_generic" | ||
) | ||
|
||
// Path to PCI | ||
const ( | ||
PathSysPciDevices = "/sys/bus/pci/devices" | ||
PathSysPciDrivers = "/sys/bus/pci/drivers" | ||
PathSysPciDriverProbe = "/sys/bus/pci/drivers_probe" | ||
) | ||
|
||
// Path to VMBus | ||
const ( | ||
PathSysVmbusDevices = "/sys/bus/vmbus/devices" | ||
PathSysVmbusDrivers = "/sys/bus/vmbus/drivers" | ||
) | ||
|
||
// Path to net | ||
const ( | ||
PathSysClassNet = "/sys/class/net" | ||
) | ||
|
||
// Regular expressions for PCI-ID and UUID | ||
var ( | ||
IsPciID *regexp.Regexp | ||
IsUUID *regexp.Regexp | ||
) | ||
|
||
// DPDK related drivers | ||
var ( | ||
DefaultDpdkDriver = DriverUioPciGeneric | ||
DpdkDrivers = [...]string{DriverUioPciGeneric, DriverIgUio, DriverVfioPci, DriverUioHvGeneric} | ||
DpdkPciDrivers = [...]string{DriverUioPciGeneric, DriverIgUio, DriverVfioPci} | ||
DpdkVmbusDrivers = [...]string{DriverUioHvGeneric} | ||
) | ||
|
||
type stringBuilder string | ||
|
||
func (s stringBuilder) With(args ...interface{}) string { | ||
return fmt.Sprintf(string(s), args...) | ||
} | ||
|
||
var ( | ||
pathSysPciDevicesBind stringBuilder = PathSysPciDevices + "/%s/driver/bind" | ||
pathSysPciDevicesUnbind stringBuilder = PathSysPciDevices + "/%s/driver/unbind" | ||
pathSysPciDevicesOverrideDriver stringBuilder = PathSysPciDevices + "/%s/driver_override" | ||
|
||
pathSysPciDriversBind stringBuilder = PathSysPciDrivers + "/%s/bind" | ||
pathSysPciDriversUnbind stringBuilder = PathSysPciDrivers + "/%s/unbind" | ||
pathSysPciDriversNewID stringBuilder = PathSysPciDrivers + "/%s/new_id" | ||
) | ||
|
||
var ( | ||
pathSysVmbusDriversBind stringBuilder = PathSysVmbusDrivers + "/%s/bind" | ||
pathSysVmbusDriversUnbind stringBuilder = PathSysVmbusDrivers + "/%s/unbind" | ||
pathSysVmbusDriversNewID stringBuilder = PathSysVmbusDrivers + "/%s/new_id" | ||
) | ||
|
||
var ( | ||
pathSysClassNetDeviceDriver stringBuilder = PathSysClassNet + "/%s/device/driver" | ||
pathSysClassNetDevice stringBuilder = PathSysClassNet + "/%s/device" | ||
) | ||
|
||
var ( | ||
vmbusDeviceStringer stringBuilder = "ID: %s\nClass:\t%s\nDriver:\t%s" | ||
pciDeviceStringer stringBuilder = "ID: %s\nClass:\t%s\nVendor:\t%s\nDevice:\t%s\nDriver:\t%s" | ||
) | ||
|
||
var ( | ||
// for ethtool output | ||
rPciIDForEthtool *regexp.Regexp | ||
|
||
// for lspci output | ||
rPciClass *regexp.Regexp | ||
rPciVendor *regexp.Regexp | ||
rPciDevice *regexp.Regexp | ||
rPciDriver *regexp.Regexp | ||
|
||
// for find output | ||
rVmbusDriver *regexp.Regexp | ||
) | ||
|
||
func init() { | ||
rPciIDForEthtool = regexp.MustCompile("bus-info:\\s([0-9:.]+)") | ||
|
||
rPciClass = regexp.MustCompile("[Cc]lass:\\s([0-9a-zA-Z]{4})") | ||
rPciVendor = regexp.MustCompile("[Vv]endor:\\s([0-9a-zA-Z]{4})") | ||
rPciDevice = regexp.MustCompile("[Dd]evice:\\s([0-9a-zA-Z]{4})") | ||
rPciDriver = regexp.MustCompile("[Dd]river:\\s(\\S+)") | ||
|
||
rVmbusDriver = regexp.MustCompile("/sys/bus/vmbus/drivers/(\\S+)/") | ||
|
||
IsPciID = regexp.MustCompile("^\\d{4}:\\d{2}:\\d{2}.\\d$") | ||
IsUUID = regexp.MustCompile("^[[:xdigit:]]{8}-[[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}$") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright 2018 Intel Corporation. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package devices helps to query DPDK compatibles devices and to bind/unbind drivers | ||
package devices | ||
|
||
import ( | ||
"errors" | ||
) | ||
|
||
// Errors of devices package | ||
var ( | ||
ErrNoBoundDriver = errors.New("no driver is bound to the device") | ||
ErrAlreadyBoundDriver = errors.New("device has already bound the selected driver") | ||
ErrBind = errors.New("fail to bind the driver") | ||
ErrUnbind = errors.New("fail to unbind the driver") | ||
ErrUnsupportedDriver = errors.New("unsupported DPDK driver") | ||
ErrNotProbe = errors.New("device doesn't support 'drive_probe'") | ||
ErrKernelModuleNotLoaded = errors.New("kernel module is not loaded") | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright 2018 Intel Corporation. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package devices helps to query DPDK compatibles devices and to bind/unbind drivers | ||
package devices | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
"time" | ||
) | ||
|
||
var defaultTimeoutLimitation = 5 * time.Second | ||
|
||
// FindDefaultDpdkDriver returns a default DPDK driver that the given NIC can | ||
// use. | ||
func FindDefaultDpdkDriver(nicName string) string { | ||
driver, err := readlinkBaseCmd(pathSysClassNetDeviceDriver.With(nicName)) | ||
if err != nil { | ||
return DefaultDpdkDriver | ||
} | ||
switch driver { | ||
case DriverHvNetvcs: | ||
return DriverUioHvGeneric | ||
default: | ||
return DefaultDpdkDriver | ||
} | ||
} | ||
|
||
// GetDeviceID returns the device ID of given NIC name. | ||
func GetDeviceID(nicName string) (string, error) { | ||
// DEV_ID=$(basename $(readlink /sys/class/net/<nicName>/device)) | ||
return readlinkBaseCmd(pathSysClassNetDevice.With(nicName)) | ||
} | ||
|
||
// IsModuleLoaded checks if the kernel has already loaded the driver or not. | ||
func IsModuleLoaded(driver string) bool { | ||
output, err := cmdOutputWithTimeout(defaultTimeoutLimitation, "lsmod") | ||
if err != nil { | ||
// Can't run lsmod, return false | ||
return false | ||
} | ||
lines := strings.Split(string(output), "\n") | ||
for _, line := range lines { | ||
if checkModuleLine(line, driver) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func writeToTargetWithData(sysfs string, flag int, mode os.FileMode, data string) error { | ||
writer, err := os.OpenFile(sysfs, flag, mode) | ||
if err != nil { | ||
return fmt.Errorf("OpenFile failed: %s", err.Error()) | ||
} | ||
defer writer.Close() | ||
|
||
_, err = writer.Write([]byte(data)) | ||
if err != nil { | ||
return fmt.Errorf("WriteFile failed: %s", err.Error()) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func readlinkBaseCmd(path string) (string, error) { | ||
output, err := cmdOutputWithTimeout(defaultTimeoutLimitation, "readlink", path) | ||
if err != nil { | ||
return "", fmt.Errorf("Cmd Execute readlink failed: %s", err.Error()) | ||
} | ||
outputStr := strings.Trim(string(output), "\n") | ||
result := filepath.Base(outputStr) | ||
return result, nil | ||
} | ||
|
||
func checkModuleLine(line, driver string) bool { | ||
if !strings.Contains(line, driver) { | ||
return false | ||
} | ||
elements := strings.Split(line, " ") | ||
return elements[0] == driver | ||
} | ||
|
||
func cmdOutputWithTimeout(duration time.Duration, cmd string, parameters ...string) ([]byte, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), duration) | ||
defer cancel() | ||
output, err := exec.CommandContext(ctx, cmd, parameters...).Output() | ||
if err != nil { | ||
return nil, err | ||
} | ||
return output, nil | ||
} |
Oops, something went wrong.