Skip to content
Draft
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
4 changes: 4 additions & 0 deletions internal/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net"
"reflect"
"time"
"kmod"

v1 "github.com/openshift/dpu-operator/api/v1"
"github.com/openshift/dpu-operator/internal/daemon/plugin"
Expand Down Expand Up @@ -177,6 +178,9 @@ func (d *Daemon) Serve(ctx context.Context) error {
Reason: "Initialized",
Message: "DPU plugin is initialized and ready.",
}
if err := kmod.Reload("idpf"); err != nil {
log.Fatalf("failed to reload idpf: %v", err)
}
} else {
newCondition = metav1.Condition{
Type: "Ready",
Expand Down
61 changes: 61 additions & 0 deletions internal/daemon/idpf_reload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package kmod

import (
"errors"
"fmt"
"os/exec"
"strings"

"golang.org/x/sys/unix"
)

/* Rmmod attempts to remove a module via delete_module(2).
If nonblock is true, use O_NONBLOCK only. NOTE: kernel will refuse if the driver is busy.
If exclusive is true, the call fails if the module is in use by anyone else.
*/
func Rmmod(name string, nonblock bool, exclusive bool) error {
flags := 0
if nonblock {
flags |= unix.O_NONBLOCK
}
if exclusive {
flags |= unix.O_EXCL
}
if err := unix.DeleteModule(name, flags); err != nil {
// Convert EBUSY to a clearer message.
if errors.Is(err, unix.EBUSY) {
return fmt.Errorf("rmmod %s: module is busy. rmmod failed.", name)
}
if errors.Is(err, unix.ENOENT) {
return nil // successfully removed.
}
return fmt.Errorf("rmmod %s: %w", name, err)
}
return nil
}

/* Modprobe tries to load a module by name using modprobe along with its dependencies.
opts can handle optional parameters like debug mode or similar.
*/
func Modprobe(name string, opts ...string) error {
args := append([]string{name}, opts...)
cmd := exec.Command("modprobe", args...)
out, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("modprobe %s failed: %v; output: %s", name, err, strings.TrimSpace(string(out)))
}
return nil
}

/* Reload removes the driver and loads it back.
*/
func Reload(name string) error {
// Best effort remove (non-blocking + exclusive to avoid stuck waits).
if err := Rmmod(name, true, true); err != nil {
return err
}
if err = Modprobe(name); err != nil {
return err
}
return nil
}