mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-19 07:49:17 +00:00
virtcontainers: address some comments
* Move makeNameID() func to virtcontainers/utils file as it's a generic function for making name and ID. * Move bindDevicetoVFIO() and bindDevicetoHost() to vfio driver package. Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
This commit is contained in:
@@ -830,7 +830,7 @@ func (c *Container) hotplugDrive() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add drive with id as container id
|
// Add drive with id as container id
|
||||||
devID := makeNameID("drive", c.id)
|
devID := utils.MakeNameID("drive", c.id, maxDevIDSize)
|
||||||
drive := drivers.Drive{
|
drive := drivers.Drive{
|
||||||
File: devicePath,
|
File: devicePath,
|
||||||
Format: "raw",
|
Format: "raw",
|
||||||
@@ -867,7 +867,7 @@ func (c *Container) removeDrive() (err error) {
|
|||||||
if c.isDriveUsed() && c.state.HotpluggedDrive {
|
if c.isDriveUsed() && c.state.HotpluggedDrive {
|
||||||
c.Logger().Info("unplugging block device")
|
c.Logger().Info("unplugging block device")
|
||||||
|
|
||||||
devID := makeNameID("drive", c.id)
|
devID := utils.MakeNameID("drive", c.id, maxDevIDSize)
|
||||||
drive := &drivers.Drive{
|
drive := &drivers.Drive{
|
||||||
ID: devID,
|
ID: devID,
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
var devLogger = logrus.FieldLogger(logrus.New())
|
var devLogger = logrus.FieldLogger(logrus.New())
|
||||||
|
|
||||||
// SetLogger sets the logger for virtcontainers package.
|
// SetLogger sets the logger for device api package.
|
||||||
func SetLogger(logger logrus.FieldLogger) {
|
func SetLogger(logger logrus.FieldLogger) {
|
||||||
devLogger = logger
|
devLogger = logger
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ type DeviceReceiver interface {
|
|||||||
HotplugAddDevice(Device, config.DeviceType) error
|
HotplugAddDevice(Device, config.DeviceType) error
|
||||||
HotplugRemoveDevice(Device, config.DeviceType) error
|
HotplugRemoveDevice(Device, config.DeviceType) error
|
||||||
|
|
||||||
// this is only for virtio-blk support
|
// this is only for virtio-blk and virtio-scsi support
|
||||||
GetAndSetSandboxBlockIndex() (int, error)
|
GetAndSetSandboxBlockIndex() (int, error)
|
||||||
DecrementSandboxBlockIndex() error
|
DecrementSandboxBlockIndex() error
|
||||||
|
|
||||||
|
@@ -15,6 +15,8 @@ import (
|
|||||||
"github.com/kata-containers/runtime/virtcontainers/utils"
|
"github.com/kata-containers/runtime/virtcontainers/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const maxDevIDSize = 31
|
||||||
|
|
||||||
// Drive represents a block storage drive which may be used in case the storage
|
// Drive represents a block storage drive which may be used in case the storage
|
||||||
// driver has an underlying block storage device.
|
// driver has an underlying block storage device.
|
||||||
type Drive struct {
|
type Drive struct {
|
||||||
@@ -89,7 +91,7 @@ func (device *BlockDevice) Attach(devReceiver api.DeviceReceiver) (err error) {
|
|||||||
drive := Drive{
|
drive := Drive{
|
||||||
File: device.DeviceInfo.HostPath,
|
File: device.DeviceInfo.HostPath,
|
||||||
Format: "raw",
|
Format: "raw",
|
||||||
ID: makeNameID("drive", device.DeviceInfo.ID),
|
ID: utils.MakeNameID("drive", device.DeviceInfo.ID, maxDevIDSize),
|
||||||
Index: index,
|
Index: index,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,8 +7,6 @@
|
|||||||
package drivers
|
package drivers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/kata-containers/runtime/virtcontainers/device/api"
|
"github.com/kata-containers/runtime/virtcontainers/device/api"
|
||||||
@@ -17,17 +15,3 @@ import (
|
|||||||
func deviceLogger() *logrus.Entry {
|
func deviceLogger() *logrus.Entry {
|
||||||
return api.DeviceLogger()
|
return api.DeviceLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: this is duplicate code from virtcontainers/hypervisor.go
|
|
||||||
const maxDevIDSize = 31
|
|
||||||
|
|
||||||
// FIXME: this is duplicate code from virtcontainers/hypervisor.go
|
|
||||||
//Generic function for creating a named-id for passing on the hypervisor commandline
|
|
||||||
func makeNameID(namedType string, id string) string {
|
|
||||||
nameID := fmt.Sprintf("%s-%s", namedType, id)
|
|
||||||
if len(nameID) > maxDevIDSize {
|
|
||||||
nameID = nameID[:maxDevIDSize]
|
|
||||||
}
|
|
||||||
|
|
||||||
return nameID
|
|
||||||
}
|
|
||||||
|
@@ -20,6 +20,14 @@ import (
|
|||||||
"github.com/kata-containers/runtime/virtcontainers/utils"
|
"github.com/kata-containers/runtime/virtcontainers/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// bind/unbind paths to aid in SRIOV VF bring-up/restore
|
||||||
|
var (
|
||||||
|
pciDriverUnbindPath = "/sys/bus/pci/devices/%s/driver/unbind"
|
||||||
|
pciDriverBindPath = "/sys/bus/pci/drivers/%s/bind"
|
||||||
|
vfioNewIDPath = "/sys/bus/pci/drivers/vfio-pci/new_id"
|
||||||
|
vfioRemoveIDPath = "/sys/bus/pci/drivers/vfio-pci/remove_id"
|
||||||
|
)
|
||||||
|
|
||||||
// VFIODevice is a vfio device meant to be passed to the hypervisor
|
// VFIODevice is a vfio device meant to be passed to the hypervisor
|
||||||
// to be used by the Virtual Machine.
|
// to be used by the Virtual Machine.
|
||||||
type VFIODevice struct {
|
type VFIODevice struct {
|
||||||
@@ -101,3 +109,70 @@ func getBDF(deviceSysStr string) (string, error) {
|
|||||||
tokens = strings.SplitN(deviceSysStr, ":", 2)
|
tokens = strings.SplitN(deviceSysStr, ":", 2)
|
||||||
return tokens[1], nil
|
return tokens[1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BindDevicetoVFIO binds the device to vfio driver after unbinding from host.
|
||||||
|
// Will be called by a network interface or a generic pcie device.
|
||||||
|
func BindDevicetoVFIO(bdf, hostDriver, vendorDeviceID string) error {
|
||||||
|
|
||||||
|
// Unbind from the host driver
|
||||||
|
unbindDriverPath := fmt.Sprintf(pciDriverUnbindPath, bdf)
|
||||||
|
deviceLogger().WithFields(logrus.Fields{
|
||||||
|
"device-bdf": bdf,
|
||||||
|
"driver-path": unbindDriverPath,
|
||||||
|
}).Info("Unbinding device from driver")
|
||||||
|
|
||||||
|
if err := utils.WriteToFile(unbindDriverPath, []byte(bdf)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add device id to vfio driver.
|
||||||
|
deviceLogger().WithFields(logrus.Fields{
|
||||||
|
"vendor-device-id": vendorDeviceID,
|
||||||
|
"vfio-new-id-path": vfioNewIDPath,
|
||||||
|
}).Info("Writing vendor-device-id to vfio new-id path")
|
||||||
|
|
||||||
|
if err := utils.WriteToFile(vfioNewIDPath, []byte(vendorDeviceID)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind to vfio-pci driver.
|
||||||
|
bindDriverPath := fmt.Sprintf(pciDriverBindPath, "vfio-pci")
|
||||||
|
|
||||||
|
api.DeviceLogger().WithFields(logrus.Fields{
|
||||||
|
"device-bdf": bdf,
|
||||||
|
"driver-path": bindDriverPath,
|
||||||
|
}).Info("Binding device to vfio driver")
|
||||||
|
|
||||||
|
// Device may be already bound at this time because of earlier write to new_id, ignore error
|
||||||
|
utils.WriteToFile(bindDriverPath, []byte(bdf))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindDevicetoHost binds the device to the host driver driver after unbinding from vfio-pci.
|
||||||
|
func BindDevicetoHost(bdf, hostDriver, vendorDeviceID string) error {
|
||||||
|
// Unbind from vfio-pci driver
|
||||||
|
unbindDriverPath := fmt.Sprintf(pciDriverUnbindPath, bdf)
|
||||||
|
api.DeviceLogger().WithFields(logrus.Fields{
|
||||||
|
"device-bdf": bdf,
|
||||||
|
"driver-path": unbindDriverPath,
|
||||||
|
}).Info("Unbinding device from driver")
|
||||||
|
|
||||||
|
if err := utils.WriteToFile(unbindDriverPath, []byte(bdf)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// To prevent new VFs from binding to VFIO-PCI, remove_id
|
||||||
|
if err := utils.WriteToFile(vfioRemoveIDPath, []byte(vendorDeviceID)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind back to host driver
|
||||||
|
bindDriverPath := fmt.Sprintf(pciDriverBindPath, hostDriver)
|
||||||
|
api.DeviceLogger().WithFields(logrus.Fields{
|
||||||
|
"device-bdf": bdf,
|
||||||
|
"driver-path": bindDriverPath,
|
||||||
|
}).Info("Binding back device to host driver")
|
||||||
|
|
||||||
|
return utils.WriteToFile(bindDriverPath, []byte(bdf))
|
||||||
|
}
|
||||||
|
@@ -116,16 +116,6 @@ func newHypervisor(hType HypervisorType) (hypervisor, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Generic function for creating a named-id for passing on the hypervisor commandline
|
|
||||||
func makeNameID(namedType string, id string) string {
|
|
||||||
nameID := fmt.Sprintf("%s-%s", namedType, id)
|
|
||||||
if len(nameID) > maxDevIDSize {
|
|
||||||
nameID = nameID[:maxDevIDSize]
|
|
||||||
}
|
|
||||||
|
|
||||||
return nameID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is a key/value representation for hypervisor and kernel parameters.
|
// Param is a key/value representation for hypervisor and kernel parameters.
|
||||||
type Param struct {
|
type Param struct {
|
||||||
Key string
|
Key string
|
||||||
|
@@ -25,7 +25,6 @@ import (
|
|||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/kata-containers/runtime/virtcontainers/device/api"
|
|
||||||
"github.com/kata-containers/runtime/virtcontainers/device/drivers"
|
"github.com/kata-containers/runtime/virtcontainers/device/drivers"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/pkg/uuid"
|
"github.com/kata-containers/runtime/virtcontainers/pkg/uuid"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/utils"
|
"github.com/kata-containers/runtime/virtcontainers/utils"
|
||||||
@@ -1350,85 +1349,12 @@ func createPhysicalEndpoint(netInfo NetworkInfo) (*PhysicalEndpoint, error) {
|
|||||||
return physicalEndpoint, nil
|
return physicalEndpoint, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind/unbind paths to aid in SRIOV VF bring-up/restore
|
|
||||||
var pciDriverUnbindPath = "/sys/bus/pci/devices/%s/driver/unbind"
|
|
||||||
var pciDriverBindPath = "/sys/bus/pci/drivers/%s/bind"
|
|
||||||
var vfioNewIDPath = "/sys/bus/pci/drivers/vfio-pci/new_id"
|
|
||||||
var vfioRemoveIDPath = "/sys/bus/pci/drivers/vfio-pci/remove_id"
|
|
||||||
|
|
||||||
// bindDevicetoVFIO binds the device to vfio driver after unbinding from host.
|
|
||||||
// Will be called by a network interface or a generic pcie device.
|
|
||||||
func bindDevicetoVFIO(bdf, hostDriver, vendorDeviceID string) error {
|
|
||||||
|
|
||||||
// Unbind from the host driver
|
|
||||||
unbindDriverPath := fmt.Sprintf(pciDriverUnbindPath, bdf)
|
|
||||||
api.DeviceLogger().WithFields(logrus.Fields{
|
|
||||||
"device-bdf": bdf,
|
|
||||||
"driver-path": unbindDriverPath,
|
|
||||||
}).Info("Unbinding device from driver")
|
|
||||||
|
|
||||||
if err := utils.WriteToFile(unbindDriverPath, []byte(bdf)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add device id to vfio driver.
|
|
||||||
api.DeviceLogger().WithFields(logrus.Fields{
|
|
||||||
"vendor-device-id": vendorDeviceID,
|
|
||||||
"vfio-new-id-path": vfioNewIDPath,
|
|
||||||
}).Info("Writing vendor-device-id to vfio new-id path")
|
|
||||||
|
|
||||||
if err := utils.WriteToFile(vfioNewIDPath, []byte(vendorDeviceID)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind to vfio-pci driver.
|
|
||||||
bindDriverPath := fmt.Sprintf(pciDriverBindPath, "vfio-pci")
|
|
||||||
|
|
||||||
api.DeviceLogger().WithFields(logrus.Fields{
|
|
||||||
"device-bdf": bdf,
|
|
||||||
"driver-path": bindDriverPath,
|
|
||||||
}).Info("Binding device to vfio driver")
|
|
||||||
|
|
||||||
// Device may be already bound at this time because of earlier write to new_id, ignore error
|
|
||||||
utils.WriteToFile(bindDriverPath, []byte(bdf))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// bindDevicetoHost binds the device to the host driver driver after unbinding from vfio-pci.
|
|
||||||
func bindDevicetoHost(bdf, hostDriver, vendorDeviceID string) error {
|
|
||||||
// Unbind from vfio-pci driver
|
|
||||||
unbindDriverPath := fmt.Sprintf(pciDriverUnbindPath, bdf)
|
|
||||||
api.DeviceLogger().WithFields(logrus.Fields{
|
|
||||||
"device-bdf": bdf,
|
|
||||||
"driver-path": unbindDriverPath,
|
|
||||||
}).Info("Unbinding device from driver")
|
|
||||||
|
|
||||||
if err := utils.WriteToFile(unbindDriverPath, []byte(bdf)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// To prevent new VFs from binding to VFIO-PCI, remove_id
|
|
||||||
if err := utils.WriteToFile(vfioRemoveIDPath, []byte(vendorDeviceID)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind back to host driver
|
|
||||||
bindDriverPath := fmt.Sprintf(pciDriverBindPath, hostDriver)
|
|
||||||
api.DeviceLogger().WithFields(logrus.Fields{
|
|
||||||
"device-bdf": bdf,
|
|
||||||
"driver-path": bindDriverPath,
|
|
||||||
}).Info("Binding back device to host driver")
|
|
||||||
|
|
||||||
return utils.WriteToFile(bindDriverPath, []byte(bdf))
|
|
||||||
}
|
|
||||||
|
|
||||||
func bindNICToVFIO(endpoint *PhysicalEndpoint) error {
|
func bindNICToVFIO(endpoint *PhysicalEndpoint) error {
|
||||||
return bindDevicetoVFIO(endpoint.BDF, endpoint.Driver, endpoint.VendorDeviceID)
|
return drivers.BindDevicetoVFIO(endpoint.BDF, endpoint.Driver, endpoint.VendorDeviceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func bindNICToHost(endpoint *PhysicalEndpoint) error {
|
func bindNICToHost(endpoint *PhysicalEndpoint) error {
|
||||||
return bindDevicetoHost(endpoint.BDF, endpoint.Driver, endpoint.VendorDeviceID)
|
return drivers.BindDevicetoHost(endpoint.BDF, endpoint.Driver, endpoint.VendorDeviceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Long term, this should be made more configurable. For now matching path
|
// Long term, this should be made more configurable. For now matching path
|
||||||
|
@@ -290,7 +290,7 @@ func (q *qemuArchBase) appendImage(devices []govmmQemu.Device, path string) ([]g
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
id := makeNameID("image", hex.EncodeToString(randBytes))
|
id := utils.MakeNameID("image", hex.EncodeToString(randBytes), maxDevIDSize)
|
||||||
|
|
||||||
drive := drivers.Drive{
|
drive := drivers.Drive{
|
||||||
File: path,
|
File: path,
|
||||||
@@ -466,16 +466,16 @@ func (q *qemuArchBase) appendVhostUserDevice(devices []govmmQemu.Device, vhostUs
|
|||||||
// TODO: find a way to remove dependency of drivers package
|
// TODO: find a way to remove dependency of drivers package
|
||||||
switch vhostUserDevice := vhostUserDevice.(type) {
|
switch vhostUserDevice := vhostUserDevice.(type) {
|
||||||
case *drivers.VhostUserNetDevice:
|
case *drivers.VhostUserNetDevice:
|
||||||
qemuVhostUserDevice.TypeDevID = makeNameID("net", vhostUserDevice.ID)
|
qemuVhostUserDevice.TypeDevID = utils.MakeNameID("net", vhostUserDevice.ID, maxDevIDSize)
|
||||||
qemuVhostUserDevice.Address = vhostUserDevice.MacAddress
|
qemuVhostUserDevice.Address = vhostUserDevice.MacAddress
|
||||||
case *drivers.VhostUserSCSIDevice:
|
case *drivers.VhostUserSCSIDevice:
|
||||||
qemuVhostUserDevice.TypeDevID = makeNameID("scsi", vhostUserDevice.ID)
|
qemuVhostUserDevice.TypeDevID = utils.MakeNameID("scsi", vhostUserDevice.ID, maxDevIDSize)
|
||||||
case *drivers.VhostUserBlkDevice:
|
case *drivers.VhostUserBlkDevice:
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuVhostUserDevice.VhostUserType = govmmQemu.VhostUserDeviceType(vhostUserDevice.Type())
|
qemuVhostUserDevice.VhostUserType = govmmQemu.VhostUserDeviceType(vhostUserDevice.Type())
|
||||||
qemuVhostUserDevice.SocketPath = vhostUserDevice.Attrs().SocketPath
|
qemuVhostUserDevice.SocketPath = vhostUserDevice.Attrs().SocketPath
|
||||||
qemuVhostUserDevice.CharDevID = makeNameID("char", vhostUserDevice.Attrs().ID)
|
qemuVhostUserDevice.CharDevID = utils.MakeNameID("char", vhostUserDevice.Attrs().ID, maxDevIDSize)
|
||||||
|
|
||||||
devices = append(devices, qemuVhostUserDevice)
|
devices = append(devices, qemuVhostUserDevice)
|
||||||
|
|
||||||
|
@@ -1322,10 +1322,17 @@ func togglePauseSandbox(sandboxID string, pause bool) (*Sandbox, error) {
|
|||||||
func (s *Sandbox) HotplugAddDevice(device api.Device, devType config.DeviceType) error {
|
func (s *Sandbox) HotplugAddDevice(device api.Device, devType config.DeviceType) error {
|
||||||
switch devType {
|
switch devType {
|
||||||
case config.DeviceVFIO:
|
case config.DeviceVFIO:
|
||||||
return s.hypervisor.hotplugAddDevice(device, vfioDev)
|
vfioDevice, ok := device.(*drivers.VFIODevice)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
||||||
|
}
|
||||||
|
return s.hypervisor.hotplugAddDevice(*vfioDevice, vfioDev)
|
||||||
case config.DeviceBlock:
|
case config.DeviceBlock:
|
||||||
device := device.(*drivers.BlockDevice)
|
blockDevice, ok := device.(*drivers.BlockDevice)
|
||||||
return s.hypervisor.hotplugAddDevice(device.BlockDrive, blockDev)
|
if !ok {
|
||||||
|
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
||||||
|
}
|
||||||
|
return s.hypervisor.hotplugAddDevice(blockDevice.BlockDrive, blockDev)
|
||||||
case config.DeviceGeneric:
|
case config.DeviceGeneric:
|
||||||
// TODO: what?
|
// TODO: what?
|
||||||
return nil
|
return nil
|
||||||
@@ -1338,10 +1345,17 @@ func (s *Sandbox) HotplugAddDevice(device api.Device, devType config.DeviceType)
|
|||||||
func (s *Sandbox) HotplugRemoveDevice(device api.Device, devType config.DeviceType) error {
|
func (s *Sandbox) HotplugRemoveDevice(device api.Device, devType config.DeviceType) error {
|
||||||
switch devType {
|
switch devType {
|
||||||
case config.DeviceVFIO:
|
case config.DeviceVFIO:
|
||||||
return s.hypervisor.hotplugRemoveDevice(device, vfioDev)
|
vfioDevice, ok := device.(*drivers.VFIODevice)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
||||||
|
}
|
||||||
|
return s.hypervisor.hotplugRemoveDevice(*vfioDevice, vfioDev)
|
||||||
case config.DeviceBlock:
|
case config.DeviceBlock:
|
||||||
device := device.(*drivers.BlockDevice)
|
blockDevice, ok := device.(*drivers.BlockDevice)
|
||||||
return s.hypervisor.hotplugRemoveDevice(device.BlockDrive, blockDev)
|
if !ok {
|
||||||
|
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
||||||
|
}
|
||||||
|
return s.hypervisor.hotplugRemoveDevice(blockDevice.BlockDrive, blockDev)
|
||||||
case config.DeviceGeneric:
|
case config.DeviceGeneric:
|
||||||
// TODO: what?
|
// TODO: what?
|
||||||
return nil
|
return nil
|
||||||
|
@@ -164,3 +164,13 @@ func GetSCSIAddress(index int) (string, error) {
|
|||||||
|
|
||||||
return fmt.Sprintf("%d:%d", scsiID, lun), nil
|
return fmt.Sprintf("%d:%d", scsiID, lun), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeNameID is generic function for creating a named-id for passing on the hypervisor commandline
|
||||||
|
func MakeNameID(namedType, id string, maxLen int) string {
|
||||||
|
nameID := fmt.Sprintf("%s-%s", namedType, id)
|
||||||
|
if len(nameID) > maxLen {
|
||||||
|
nameID = nameID[:maxLen]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nameID
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user