SRIOVFindFreeVirtualFunction looks on the specified parent device for an unused virtual function. Returns the name of the interface and virtual function index ID if found, error if not.
(s *state.State, parentDev string)
| 101 | // SRIOVFindFreeVirtualFunction looks on the specified parent device for an unused virtual function. |
| 102 | // Returns the name of the interface and virtual function index ID if found, error if not. |
| 103 | func SRIOVFindFreeVirtualFunction(s *state.State, parentDev string) (string, int, error) { |
| 104 | reservedDevices, err := SRIOVGetHostDevicesInUse(s) |
| 105 | if err != nil { |
| 106 | return "", -1, fmt.Errorf("Failed getting in use device list: %w", err) |
| 107 | } |
| 108 | |
| 109 | sriovNumVFsFile := fmt.Sprintf("/sys/class/net/%s/device/sriov_numvfs", parentDev) |
| 110 | |
| 111 | // Verify that this is indeed a SR-IOV enabled device. |
| 112 | if !util.PathExists(sriovNumVFsFile) { |
| 113 | return "", -1, fmt.Errorf("Parent device %q doesn't support SR-IOV", parentDev) |
| 114 | } |
| 115 | |
| 116 | // Get parent dev_port and dev_id values. |
| 117 | pfDevPort, err := os.ReadFile(fmt.Sprintf("/sys/class/net/%s/dev_port", parentDev)) |
| 118 | if err != nil { |
| 119 | return "", -1, err |
| 120 | } |
| 121 | |
| 122 | pfDevID, err := os.ReadFile(fmt.Sprintf("/sys/class/net/%s/dev_id", parentDev)) |
| 123 | if err != nil { |
| 124 | return "", -1, err |
| 125 | } |
| 126 | |
| 127 | // Get number of currently enabled VFs. |
| 128 | sriovNumVFsBuf, err := os.ReadFile(sriovNumVFsFile) |
| 129 | if err != nil { |
| 130 | return "", -1, err |
| 131 | } |
| 132 | |
| 133 | sriovNumVFs, err := strconv.Atoi(strings.TrimSpace(string(sriovNumVFsBuf))) |
| 134 | if err != nil { |
| 135 | return "", -1, err |
| 136 | } |
| 137 | |
| 138 | // Ensure parent is up (needed for Intel at least). |
| 139 | link := &ip.Link{Name: parentDev} |
| 140 | err = link.SetUp() |
| 141 | if err != nil { |
| 142 | return "", -1, err |
| 143 | } |
| 144 | |
| 145 | // Check if any free VFs are already enabled. |
| 146 | vfID, nicName, err := sriovGetFreeVFInterface(reservedDevices, parentDev, sriovNumVFs, 0, pfDevID, pfDevPort) |
| 147 | if err != nil { |
| 148 | return "", -1, err |
| 149 | } |
| 150 | |
| 151 | if nicName == "" { |
| 152 | return "", -1, fmt.Errorf("All virtual functions on parent device %q are already in use", parentDev) |
| 153 | } |
| 154 | |
| 155 | // Found a free VF. |
| 156 | return nicName, vfID, nil |
| 157 | } |
| 158 | |
| 159 | // sriovGetFreeVFInterface checks the system for a free VF interface that belongs to the same device and port as |
| 160 | // the parent device starting from the startVFID to the vfCount-1. Returns VF ID and VF interface name if found or |
no test coverage detected
searching dependent graphs…