github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/device/drivers/vhost_user_net.go (about)

     1  // Copyright (c) 2017-2018 Intel Corporation
     2  // Copyright (c) 2018-2019 Huawei Corporation
     3  //
     4  // SPDX-License-Identifier: Apache-2.0
     5  //
     6  
     7  package drivers
     8  
     9  import (
    10  	"encoding/hex"
    11  
    12  	"github.com/kata-containers/runtime/virtcontainers/device/api"
    13  	"github.com/kata-containers/runtime/virtcontainers/device/config"
    14  	persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
    15  	"github.com/kata-containers/runtime/virtcontainers/utils"
    16  )
    17  
    18  // VhostUserNetDevice is a network vhost-user based device
    19  type VhostUserNetDevice struct {
    20  	*GenericDevice
    21  	config.VhostUserDeviceAttrs
    22  }
    23  
    24  //
    25  // VhostUserNetDevice's implementation of the device interface:
    26  //
    27  
    28  // Attach is standard interface of api.Device, it's used to add device to some
    29  // DeviceReceiver
    30  func (device *VhostUserNetDevice) Attach(devReceiver api.DeviceReceiver) (err error) {
    31  	skip, err := device.bumpAttachCount(true)
    32  	if err != nil {
    33  		return err
    34  	}
    35  	if skip {
    36  		return nil
    37  	}
    38  
    39  	defer func() {
    40  		if err != nil {
    41  			device.bumpAttachCount(false)
    42  		}
    43  	}()
    44  
    45  	// generate a unique ID to be used for hypervisor commandline fields
    46  	randBytes, err := utils.GenerateRandomBytes(8)
    47  	if err != nil {
    48  		return err
    49  	}
    50  	id := hex.EncodeToString(randBytes)
    51  
    52  	device.DevID = id
    53  	device.Type = device.DeviceType()
    54  
    55  	return devReceiver.AppendDevice(device)
    56  }
    57  
    58  // Detach is standard interface of api.Device, it's used to remove device from some
    59  // DeviceReceiver
    60  func (device *VhostUserNetDevice) Detach(devReceiver api.DeviceReceiver) error {
    61  	_, err := device.bumpAttachCount(false)
    62  	return err
    63  }
    64  
    65  // DeviceType is standard interface of api.Device, it returns device type
    66  func (device *VhostUserNetDevice) DeviceType() config.DeviceType {
    67  	return config.VhostUserNet
    68  }
    69  
    70  // GetDeviceInfo returns device information used for creating
    71  func (device *VhostUserNetDevice) GetDeviceInfo() interface{} {
    72  	device.Type = device.DeviceType()
    73  	return &device.VhostUserDeviceAttrs
    74  }
    75  
    76  // Save converts Device to DeviceState
    77  func (device *VhostUserNetDevice) Save() persistapi.DeviceState {
    78  	ds := device.GenericDevice.Save()
    79  	ds.Type = string(device.DeviceType())
    80  	ds.VhostUserDev = &persistapi.VhostUserDeviceAttrs{
    81  		DevID:      device.DevID,
    82  		SocketPath: device.SocketPath,
    83  		Type:       string(device.Type),
    84  		MacAddress: device.MacAddress,
    85  	}
    86  	return ds
    87  }
    88  
    89  // Load loads DeviceState and converts it to specific device
    90  func (device *VhostUserNetDevice) Load(ds persistapi.DeviceState) {
    91  	device.GenericDevice = &GenericDevice{}
    92  	device.GenericDevice.Load(ds)
    93  
    94  	dev := ds.VhostUserDev
    95  	if dev == nil {
    96  		return
    97  	}
    98  
    99  	device.VhostUserDeviceAttrs = config.VhostUserDeviceAttrs{
   100  		DevID:      dev.DevID,
   101  		SocketPath: dev.SocketPath,
   102  		Type:       config.DeviceType(dev.Type),
   103  		MacAddress: dev.MacAddress,
   104  	}
   105  }
   106  
   107  // It should implement GetAttachCount() and DeviceID() as api.Device implementation
   108  // here it shares function from *GenericDevice so we don't need duplicate codes