Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions images/virtualization-dra/internal/plugin/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ func (d *Driver) UnprepareResourceClaims(ctx context.Context, claims []kubeletpl

func (d *Driver) unprepareResourceClaim(ctx context.Context, claim kubeletplugin.NamespacedObject) error {
if err := d.allocator.Unprepare(ctx, claim.UID); err != nil {
d.log.Error("error unpreparing devices for claim", slog.Any("error", err), slog.String("uid", string(claim.UID)))

return fmt.Errorf("error unpreparing devices for claim %v: %w", claim.UID, err)
}

Expand Down
17 changes: 10 additions & 7 deletions images/virtualization-dra/internal/usb-gateway/attach_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,20 @@ func (r *attachRecordManager) Refresh() error {
return err
}

// keep only real entries
var newEntries []AttachEntry
newEntries := make([]AttachEntry, 0, len(record.Entries))
for _, e := range record.Entries {
if _, ok := ports[e.Rhport]; ok {
newEntries = append(newEntries, e)
}
}

record.Entries = newEntries

r.record = record
newRecord := attachRecord{Entries: newEntries}
if slices.Equal(record.Entries, newRecord.Entries) {
r.record = newRecord
return nil
}

return nil
return r.storeLocked(newRecord)
}

func (r *attachRecordManager) GetEntries() []AttachEntry {
Expand Down Expand Up @@ -163,8 +164,10 @@ func (r *attachRecordManager) AddEntry(e AttachEntry) error {
newEntries := slices.Clone(r.record.Entries)
newEntries = append(newEntries, e)

record := attachRecord{Entries: newEntries}
return r.storeLocked(attachRecord{Entries: newEntries})
}

func (r *attachRecordManager) storeLocked(record attachRecord) error {
b, err := json.Marshal(record)
if err != nil {
return err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ func (c *USBGatewayController) Detach(deviceName string) error {
}

entry := c.findEntry(deviceName)
if entry != nil {
if entry == nil {
log.Info("Device is already detached")
} else {
log.Info("Detaching USB device")
err = c.usbIP.Detach(entry.Rhport)
if err != nil {
Expand All @@ -115,6 +117,10 @@ func (c *USBGatewayController) Detach(deviceName string) error {
return fmt.Errorf("failed to unexport device %s: %w", deviceName, err)
}

if err := c.attachRecordManager.Refresh(); err != nil {
return fmt.Errorf("failed to Refresh attach record after detach for device %s: %w", deviceName, err)
}

return nil
}

Expand Down
45 changes: 25 additions & 20 deletions images/virtualization-dra/internal/usb/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,29 +436,34 @@ func (s *AllocationStore) Unprepare(_ context.Context, claimUID types.UID) error
return fmt.Errorf("unprepare called before synchronize NRI Hook")
}

usbGatewayEnabled := featuregates.Default().USBGatewayEnabled()

allocatedDevices := s.resourceClaimAllocations[claimUID]
s.log.Info("Unpreparing devices", slog.Any("devices", allocatedDevices), slog.String("claimUID", string(claimUID)))

for _, device := range allocatedDevices {
if usbGatewayEnabled {
count := s.usbipAllocatedDevicesCount[device]
s.log.Info("Device attached by USBGateway", slog.String("device", device), slog.Int("count", count))
if count <= 1 {
s.log.Info("Detaching device because has only one consumer", slog.String("device", device))
if err := s.usbGateway.Detach(device); err != nil {
return fmt.Errorf("failed to detach device %s: %w", device, err)
allocatedDevices, exists := s.resourceClaimAllocations[claimUID]
if !exists || len(allocatedDevices) == 0 {
s.log.Info("Claim has no tracked allocations, skipping device cleanup", slog.String("claimUID", string(claimUID)))
} else {
usbGatewayEnabled := featuregates.Default().USBGatewayEnabled()

s.log.Info("Unpreparing devices", slog.Any("devices", allocatedDevices), slog.String("claimUID", string(claimUID)))

for _, device := range allocatedDevices {
if usbGatewayEnabled {
count, hasCount := s.usbipAllocatedDevicesCount[device]
s.log.Info("Device attached by USBGateway", slog.String("device", device), slog.Int("count", count))
switch {
case !hasCount || count <= 1:
s.log.Info("Device has no tracked consumers, attempting detach cleanup", slog.String("device", device), slog.Int("count", count))
if err := s.usbGateway.Detach(device); err != nil {
return fmt.Errorf("failed to detach device %s: %w", device, err)
}
delete(s.usbipAllocatedDevicesCount, device)
default:
s.log.Info("Decrementing device consumer count", slog.String("device", device), slog.Int("newCount", count-1))
s.usbipAllocatedDevicesCount[device]--
}
delete(s.usbipAllocatedDevicesCount, device)
} else {
s.log.Info("Decrementing device consumer count", slog.String("device", device), slog.Int("newCount", count-1))
s.usbipAllocatedDevicesCount[device]--
}
}

s.log.Info("Deleting device from allocated devices", slog.String("device", device))
s.allocatedDevices.Delete(device)
s.log.Info("Deleting device from allocated devices", slog.String("device", device))
s.allocatedDevices.Delete(device)
}
}

s.log.Info("Deleting CDI claim spec file", slog.String("claimUID", string(claimUID)))
Expand Down
7 changes: 4 additions & 3 deletions images/virtualization-dra/pkg/usbip/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@ func (e *usbExporter) Unexport(host, busID string, port int) error {
return fmt.Errorf("unsupported USBIP version: %d", unExportReply.Version)
}

if unExportReply.Status != protocol.OpStatusOk {
switch unExportReply.Status {
case protocol.OpStatusOk, protocol.OpStatusNoDev:
return nil
default:
return fmt.Errorf("reply failed: %s", unExportReply.Status.String())
}

return nil
}

func (e *usbExporter) usbipNetTCPConnect(host string, port int) (*net.TCPConn, error) {
Expand Down
Loading