Skip to content

Commit

Permalink
adds compatibility with compressed kernel modules
Browse files Browse the repository at this point in the history
  • Loading branch information
hyposcaler-bot committed Oct 21, 2024
1 parent 6859e39 commit 1c9d209
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
6 changes: 4 additions & 2 deletions clab/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,9 @@ func (c *CLab) verifyLinks(ctx context.Context) error {
// LoadKernelModules loads containerlab-required kernel modules.
func (c *CLab) loadKernelModules() error {
modules := []string{"ip_tables", "ip6_tables"}

opts := []kmod.Option{
kmod.SetInitFunc(utils.ModInitFunc),
}
for _, m := range modules {
isLoaded, err := utils.IsKernelModuleLoaded(m)
if err != nil {
Expand All @@ -406,7 +408,7 @@ func (c *CLab) loadKernelModules() error {

log.Debugf("kernel module %q is not loaded. Trying to load", m)
// trying to load the kernel modules.
km, err := kmod.New()
km, err := kmod.New(opts...)
if err != nil {
log.Warnf("Unable to init module loader: %v. Skipping...", err)

Expand Down
60 changes: 60 additions & 0 deletions utils/kernel_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ package utils

import (
"bufio"
"compress/gzip"
"fmt"
"io"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"

"github.com/klauspost/compress/zstd"
log "github.com/sirupsen/logrus"
"github.com/ulikunitz/xz"
"golang.org/x/sys/unix"
)

// IsKernelModuleLoaded checks if a kernel module is loaded by parsing /proc/modules file.
Expand Down Expand Up @@ -95,3 +101,57 @@ func (kv *KernelVersion) GreaterOrEqual(cmpKv *KernelVersion) bool {

return true
}

// modInitFunc supports uncompressed files and gzip and xz compressed files.
func ModInitFunc(path, params string, flags int) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()

switch filepath.Ext(path) {
case ".gz":
rd, err := gzip.NewReader(f)
if err != nil {
return err
}
defer rd.Close()
return initModule(rd, params)
case ".xz":
rd, err := xz.NewReader(f)
if err != nil {
return err
}
return initModule(rd, params)
case ".zst":
rd, err := zstd.NewReader(f)
if err != nil {
return err
}
defer rd.Close()
return initModule(rd, params)
}

// uncompressed file, first try finitModule then initModule
if err := finitModule(int(f.Fd()), params); err != nil {
if err == unix.ENOSYS {
return initModule(f, params)
}
}
return nil
}

// finitModule inserts a module file via syscall finit_module(2).
func finitModule(fd int, params string) error {
return unix.FinitModule(fd, params, 0)
}

// initModule inserts a module via syscall init_module(2).
func initModule(rd io.Reader, params string) error {
buf, err := io.ReadAll(rd)
if err != nil {
return err
}
return unix.InitModule(buf, params)
}

0 comments on commit 1c9d209

Please sign in to comment.