Skip to content

Commit

Permalink
feat: automatically load modules based on hw info
Browse files Browse the repository at this point in the history
Fixes: #6802

Automatically load kernel modules based on hardware info and modules
alias info. udevd would automatically load modules based on HW
information present.

Signed-off-by: Noel Georgi <git@frezbo.dev>
  • Loading branch information
frezbo committed Feb 14, 2023
1 parent 7b75cd8 commit 2d01480
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ NAME = Talos

ARTIFACTS := _out
TOOLS ?= ghcr.io/siderolabs/tools:v1.4.0-alpha.0-11-g28d4a57
PKGS ?= v1.4.0-alpha.0-18-g987d24a
PKGS ?= v1.4.0-alpha.0-21-g1fae0b2
EXTRAS ?= v1.4.0-alpha.0-2-g8cb4792
# renovate: datasource=github-tags depName=golang/go
GO_VERSION ?= 1.19
Expand Down
20 changes: 18 additions & 2 deletions hack/release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,28 @@ preface = """\
[notes.updates]
title = "Component Updates"
description="""\
* Linux: 6.1.7
* containerd: v1.6.15
* Linux: 6.1.8
* containerd: v1.6.16
* Kubernetes: v1.26.1
* etcd: v3.5.7
Talos is built with Go 1.19.5.
"""

[notes.kernel-modules]
title = "Kernel Modules"
description="""\
Talos now supports automatically loading kernel drivers built as modules.
If any system extensions or the Talos base kernel build provides kernel modules and if they matches the system hardware (via PCI IDs), they will be loaded automatically.
Modules can still be loaded explicitly by defining it in [machine configuration](https://www.talos.dev/v1.4/reference/configuration/#kernelconfig).
"""

[notes.kernel-modules-tree]
title = "Kernel Modules Tree"
description="""\
Talos now supports re-building the kernel modules dependency tree information on upgrades.
This allows modules of same name to co-exist as in-tree and external modules.
System Extensions can provide modules installed into `extras` directory and when loading it'll take precendence over the in-tree module.
"""

[notes.etcd]
Expand Down
1 change: 1 addition & 0 deletions hack/test/e2e-qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ case "${TEST_MODE:-default}" in
;;
*)
get_kubeconfig
validate_virtio_modules
run_talos_integration_test
run_kubernetes_integration_test

Expand Down
4 changes: 4 additions & 0 deletions hack/test/e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,7 @@ function run_csi_tests {
# hack until https://github.com/kastenhq/kubestr/issues/101 is addressed
KUBERNETES_SERVICE_HOST= KUBECONFIG="${TMP}/kubeconfig" ${KUBESTR} fio --storageclass ceph-block --size 10G
}

function validate_virtio_modules {
${TALOSCTL} read /proc/modules | grep -q virtio
}
5 changes: 3 additions & 2 deletions internal/app/machined/pkg/runtime/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ type TaskExecutionFunc func(context.Context, *log.Logger, Runtime) error

// Phase represents a collection of tasks to be performed concurrently.
type Phase struct {
Name string
Tasks []TaskSetupFunc
Name string
Tasks []TaskSetupFunc
CheckFunc func() bool
}

// LockOptions represents the options for a controller.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ func (c *Controller) run(ctx context.Context, seq runtime.Sequence, phases []run
}()

for number, phase = range phases {
if phase.CheckFunc != nil && !phase.CheckFunc() {
continue
}

// Make the phase number human friendly.
number++

Expand Down
33 changes: 24 additions & 9 deletions internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ func (p PhaseList) AppendWhen(when bool, name string, tasks ...runtime.TaskSetup
return p
}

// AppendWithDeferredCheck appends a task to the phase list but skips the sequence if `check func()` returns `true` during execution.
func (p PhaseList) AppendWithDeferredCheck(check func() bool, name string, tasks ...runtime.TaskSetupFunc) PhaseList {
p = append(p, runtime.Phase{
Name: name,
Tasks: tasks,
CheckFunc: check,
})

return p
}

// AppendList appends an additional PhaseList to the existing one.
func (p PhaseList) AppendList(list PhaseList) PhaseList {
return append(p, list...)
Expand Down Expand Up @@ -88,15 +99,22 @@ func (*Sequencer) Initialize(r runtime.Runtime) []runtime.Phase {
"etc",
CreateSystemCgroups,
CreateOSReleaseFile,
).AppendWhen(
r.State().Machine().Installed(),
).Append(
"udevd",
StartUdevd,
).AppendWithDeferredCheck(
func() bool {
return r.State().Machine().Installed()
},
"mountSystem",
MountStatePartition,
).Append(
"config",
LoadConfig,
).AppendWhen(
r.State().Machine().Installed(),
).AppendWithDeferredCheck(
func() bool {
return r.State().Machine().Installed()
},
"unmountSystem",
UnmountStatePartition,
)
Expand Down Expand Up @@ -218,13 +236,10 @@ func (*Sequencer) Boot(r runtime.Runtime) []runtime.Phase {
).Append(
"legacyCleanup",
CleanupLegacyStaticPodFiles,
).Append(
"udevSetup",
WriteUdevRules,
).AppendWhen(
r.State().Platform().Mode() != runtime.ModeContainer,
"udevd",
StartUdevd,
"udevSetup",
WriteUdevRules,
).AppendWhen(
r.State().Platform().Mode() != runtime.ModeContainer,
"userDisks",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,13 @@ func WriteUdevRules(seq runtime.Sequence, data interface{}) (runtime.TaskExecuti
// StartUdevd represents the task to start udevd.
func StartUdevd(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
mp := mount.NewMountPoints()
mp.Set("udev-data", mount.NewMountPoint("", constants.UdevDir, "", unix.MS_I_VERSION, "", mount.WithFlags(mount.Overlay|mount.SystemOverlay|mount.Shared)))

if err = mount.Mount(mp); err != nil {
return err
}

svc := &services.Udevd{}

system.Services(r).LoadAndStart(svc)
Expand Down
13 changes: 6 additions & 7 deletions internal/app/machined/pkg/system/services/udevd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package services

import (
"context"
"fmt"
"time"

"github.com/siderolabs/go-cmd/pkg/cmd"
Expand Down Expand Up @@ -73,18 +72,18 @@ func (c *Udevd) Runner(r runtime.Runtime) (runner.Runner, error) {
},
}

env := []string{}
for key, val := range r.Config().Machine().Env() {
env = append(env, fmt.Sprintf("%s=%s", key, val))
debug := false

if r.Config() != nil {
debug = r.Config().Debug()
}

return restart.New(process.NewRunner(
r.Config().Debug(),
debug,
args,
runner.WithLoggingManager(r.Logging()),
runner.WithEnv(env),
runner.WithCgroupPath(constants.CgroupSystemRuntime),
runner.WithDroppedCapabilities(constants.DefaultDroppedCapabilities),
runner.WithDroppedCapabilities(constants.UdevdDroppedCapabilities),
),
restart.WithType(restart.Forever),
), nil
Expand Down
15 changes: 11 additions & 4 deletions pkg/machinery/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

const (
// DefaultKernelVersion is the default Linux kernel version.
DefaultKernelVersion = "6.1.7-talos"
DefaultKernelVersion = "6.1.8-talos"

// DefaultKernelModulesPath is the default path to the kernel modules.
DefaultKernelModulesPath = "/lib/modules" + "/" + DefaultKernelVersion
Expand Down Expand Up @@ -429,7 +429,7 @@ const (
TrustdUserID = 51

// DefaultContainerdVersion is the default container runtime version.
DefaultContainerdVersion = "1.6.15"
DefaultContainerdVersion = "1.6.16"

// SystemContainerdNamespace is the Containerd namespace for Talos services.
SystemContainerdNamespace = "system"
Expand Down Expand Up @@ -704,8 +704,11 @@ const (
// See: https://lore.kernel.org/wireguard/20190321033638.1ff82682@natsu/t/
KubeSpanLinkMinimumMTU = 1280

// UdevDir is the path to the udev directory.
UdevDir = "/usr/etc/udev"

// UdevRulesPath rules file path.
UdevRulesPath = "/usr/etc/udev/rules.d/99-talos.rules"
UdevRulesPath = UdevDir + "/" + "rules.d/99-talos.rules"

// LoggingFormatJSONLines represents "JSON lines" logging format.
LoggingFormatJSONLines = "json_lines"
Expand Down Expand Up @@ -817,7 +820,6 @@ var Overlays = []string{
"/etc/cni",
"/etc/kubernetes",
"/usr/libexec/kubernetes",
"/usr/etc/udev",
"/opt",
}

Expand All @@ -826,3 +828,8 @@ var DefaultDroppedCapabilities = map[string]struct{}{
"cap_sys_boot": {},
"cap_sys_module": {},
}

// UdevdDroppedCapabilities is the set of capabilities to drop for udevd.
var UdevdDroppedCapabilities = map[string]struct{}{
"cap_sys_boot": {},
}
2 changes: 1 addition & 1 deletion pkg/machinery/gendata/data/pkgs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.4.0-alpha.0-18-g987d24a
v1.4.0-alpha.0-21-g1fae0b2

0 comments on commit 2d01480

Please sign in to comment.