From c4f62f488890a6c644cf30e698680fdc81bc61a3 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Wed, 30 Sep 2026 04:21:55 +0300 Subject: [PATCH] fix(cozystack): load drbd_transport_tcp explicitly Talos v1.14 ships a kernel with an empty modprobe path (siderolabs/pkgs#1565), so /proc/sys/kernel/modprobe is empty and the kernel no longer loads modules on request_module(). DRBD requests its transport module that way when a resource first connects to a peer, so on v1.14 drbdsetup new-peer fails with "Failed to create transport (drbd_transport_xxx module missing?)" and every DRBD resource on the node stays in Connecting. Listing drbd_transport_tcp in machine.kernel.modules makes Talos load it up front; applying that to an affected node restored connectivity without a reboot. The module ships in the drbd extension for both v1.13 and v1.14, so loading it explicitly is safe on either. Signed-off-by: Aleksei Sviridkin Assisted-by: LLM --- charts/cozystack/templates/_helpers.tpl | 1 + charts/cozystack/values.yaml | 3 +- docs/manual-test-plan.md | 2 +- pkg/engine/contract_machine_test.go | 38 +++++++++++-------- .../cozystack-controlplane-legacy.golden.yaml | 1 + ...ozystack-controlplane-multidoc.golden.yaml | 1 + .../cozystack-worker-legacy.golden.yaml | 1 + .../cozystack-worker-multidoc.golden.yaml | 1 + 8 files changed, 30 insertions(+), 18 deletions(-) diff --git a/charts/cozystack/templates/_helpers.tpl b/charts/cozystack/templates/_helpers.tpl index 52d88035..480bbe44 100644 --- a/charts/cozystack/templates/_helpers.tpl +++ b/charts/cozystack/templates/_helpers.tpl @@ -124,6 +124,7 @@ machine: - name: drbd parameters: - usermode_helper=disabled + - name: drbd_transport_tcp - name: zfs - name: spl - name: vfio_pci diff --git a/charts/cozystack/values.yaml b/charts/cozystack/values.yaml index 35b58daa..53c9ad6f 100644 --- a/charts/cozystack/values.yaml +++ b/charts/cozystack/values.yaml @@ -140,7 +140,8 @@ etcd: # need different defaults fork the preset. # Extra kernel modules to load on every node, appended to the preset's -# built-in list (openvswitch, drbd, zfs, spl, vfio_pci, vfio_iommu_type1). +# built-in list (openvswitch, drbd, drbd_transport_tcp, zfs, spl, vfio_pci, +# vfio_iommu_type1). # Lists append unconditionally — duplicates by `name` are tolerated by # Talos at load time. Each entry is a Talos kernel module spec; see # Talos docs for the full shape. Examples: diff --git a/docs/manual-test-plan.md b/docs/manual-test-plan.md index d5a30175..129136b6 100644 --- a/docs/manual-test-plan.md +++ b/docs/manual-test-plan.md @@ -420,7 +420,7 @@ yq '.machine.files[].path' /tmp/render.yaml Expected: -- `.machine.kernel.modules` lists the built-in six (`openvswitch`, `drbd` with `usermode_helper=disabled`, `zfs`, `spl`, `vfio_pci`, `vfio_iommu_type1`) AND `nf_conntrack` — append, never override. +- `.machine.kernel.modules` lists the built-in seven (`openvswitch`, `drbd` with `usermode_helper=disabled`, `drbd_transport_tcp`, `zfs`, `spl`, `vfio_pci`, `vfio_iommu_type1`) AND `nf_conntrack` — append, never override. - `.machine.kubelet.extraConfig` carries the built-ins (`cpuManagerPolicy: static`, `maxPods: 512`) AND `feature-gates: NodeSwap=true`. Operator keys MUST NOT collide with built-ins; a collision fails the render at template time. - `.machine.sysctls` carries the built-in `gc_thresh1/2/3`, the always-on DRBD tuning (`net.ipv4.tcp_orphan_retries`, `net.ipv4.tcp_fin_timeout`, `net.core.netdev_max_backlog`, `net.core.netdev_budget`, `net.core.netdev_budget_usecs`), `vm.nr_hugepages` (when set), AND `net.core.somaxconn`. Same rejection-on-collision rule (the DRBD keys are preset-owned too). See B9 for the keepalive triplet and etcd quota. - `.machine.files[].path` lists `/etc/cri/conf.d/20-customization.part`, `/etc/lvm/lvm.conf`, AND `/etc/example/operator.conf`. diff --git a/pkg/engine/contract_machine_test.go b/pkg/engine/contract_machine_test.go index 29f31873..8b2d018e 100644 --- a/pkg/engine/contract_machine_test.go +++ b/pkg/engine/contract_machine_test.go @@ -196,13 +196,17 @@ func TestContract_Machine_Sysctls_NrHugepages_PresentWhenSet_Cozystack(t *testin assertContains(t, out, `vm.nr_hugepages: "1024"`) } -// Contract: cozystack pins six kernel modules (openvswitch, drbd, zfs, -// spl, vfio_pci, vfio_iommu_type1). Each is required by a specific -// cozystack feature: openvswitch for Cilium netkit-style routing, drbd -// for DRBD storage, zfs+spl for ZFS, vfio_* for PCI passthrough. +// Contract: cozystack pins seven kernel modules (openvswitch, drbd, +// drbd_transport_tcp, zfs, spl, vfio_pci, vfio_iommu_type1). Each is +// required by a specific cozystack feature: openvswitch for Cilium +// netkit-style routing, drbd for DRBD storage, zfs+spl for ZFS, vfio_* +// for PCI passthrough. // drbd carries `parameters: [usermode_helper=disabled]` — required so // drbd does not invoke /sbin/drbdadm at every state change (the -// cozystack image does not ship drbdadm). Removing any of these +// cozystack image does not ship drbdadm). drbd_transport_tcp is listed +// explicitly because the Talos v1.14 kernel has an empty modprobe path, +// so DRBD's request_module() for its transport no longer loads it and +// every DRBD resource stays in Connecting. Removing any of these // modules silently breaks the matching feature. func TestContract_Machine_KernelModules_Cozystack(t *testing.T) { for _, cell := range cozystackCells() { @@ -213,6 +217,7 @@ func TestContract_Machine_KernelModules_Cozystack(t *testing.T) { assertContains(t, out, "- name: openvswitch") assertContains(t, out, "- name: drbd") assertContains(t, out, "- usermode_helper=disabled") + assertContains(t, out, "- name: drbd_transport_tcp") assertContains(t, out, "- name: zfs") assertContains(t, out, "- name: spl") assertContains(t, out, "- name: vfio_pci") @@ -254,11 +259,11 @@ func TestContract_Machine_KernelModules_Cozystack(t *testing.T) { // failure mode for every built-in key. // Contract: values.extraKernelModules APPENDS to the cozystack preset's -// built-in module list — it never overrides. The built-in six -// (openvswitch, drbd, zfs, spl, vfio_pci, vfio_iommu_type1) are -// load-bearing for cozystack's storage/networking stack, so an -// operator who supplies extra modules must NOT silently drop any of -// the built-ins. +// built-in module list — it never overrides. The built-in seven +// (openvswitch, drbd, drbd_transport_tcp, zfs, spl, vfio_pci, +// vfio_iommu_type1) are load-bearing for cozystack's storage/networking +// stack, so an operator who supplies extra modules must NOT silently +// drop any of the built-ins. func TestContract_Machine_ExtraKernelModules_Cozystack_AppendValues(t *testing.T) { out := renderCozystackWith(t, helmEngineEmptyLookup, map[string]any{ "advertisedSubnets": []any{testAdvertisedSubnet}, @@ -267,10 +272,11 @@ func TestContract_Machine_ExtraKernelModules_Cozystack_AppendValues(t *testing.T map[string]any{"name": "br_netfilter"}, }, }) - // Built-in six still present. + // Built-in seven still present. assertContains(t, out, "- name: openvswitch") assertContains(t, out, "- name: drbd") assertContains(t, out, "- usermode_helper=disabled") + assertContains(t, out, "- name: drbd_transport_tcp") assertContains(t, out, "- name: zfs") assertContains(t, out, "- name: spl") assertContains(t, out, "- name: vfio_pci") @@ -281,7 +287,7 @@ func TestContract_Machine_ExtraKernelModules_Cozystack_AppendValues(t *testing.T } // Contract: an empty values.extraKernelModules (or its default `[]`) -// leaves the cozystack module list IDENTICAL to the built-in six — no +// leaves the cozystack module list IDENTICAL to the built-in seven — no // `[]` suffix, no empty-list artifact, no trailing module lines. The // `{{- with .Values.extraKernelModules }}` guard relies on Helm's // emptiness check; a regression that swaps `with` for a bare @@ -295,12 +301,12 @@ func TestContract_Machine_ExtraKernelModules_Cozystack_EmptyOmitsAppend(t *testi "advertisedSubnets": []any{testAdvertisedSubnet}, "extraKernelModules": []any{}, }) - // Built-in six present. + // Built-in seven present. assertContains(t, out, "- name: vfio_iommu_type1") // No empty-list artifact after the built-in tail. assertNotContains(t, out, "vfio_iommu_type1\n []") assertNotContains(t, out, "vfio_iommu_type1\n[]") - // Exactly six `- name:` lines inside the modules block: parse the + // Exactly seven `- name:` lines inside the modules block: parse the // block bounds and count. Anchors `kernel:` / `certSANs:` are the // adjacent siblings under machine.* in the cozystack chart. kernelIdx := strings.Index(out, " kernel:") @@ -314,8 +320,8 @@ func TestContract_Machine_ExtraKernelModules_Cozystack_EmptyOmitsAppend(t *testi } block := tail[:endIdx] gotCount := strings.Count(block, "- name:") - if gotCount != 6 { - t.Errorf("expected 6 modules in kernel.modules block with empty extraKernelModules, got %d\nblock:\n%s", gotCount, block) + if gotCount != 7 { + t.Errorf("expected 7 modules in kernel.modules block with empty extraKernelModules, got %d\nblock:\n%s", gotCount, block) } } diff --git a/pkg/engine/testdata/golden/cozystack-controlplane-legacy.golden.yaml b/pkg/engine/testdata/golden/cozystack-controlplane-legacy.golden.yaml index 0cb9a3e6..692e22a4 100644 --- a/pkg/engine/testdata/golden/cozystack-controlplane-legacy.golden.yaml +++ b/pkg/engine/testdata/golden/cozystack-controlplane-legacy.golden.yaml @@ -26,6 +26,7 @@ machine: - name: drbd parameters: - usermode_helper=disabled + - name: drbd_transport_tcp - name: zfs - name: spl - name: vfio_pci diff --git a/pkg/engine/testdata/golden/cozystack-controlplane-multidoc.golden.yaml b/pkg/engine/testdata/golden/cozystack-controlplane-multidoc.golden.yaml index fd03b73c..1513b020 100644 --- a/pkg/engine/testdata/golden/cozystack-controlplane-multidoc.golden.yaml +++ b/pkg/engine/testdata/golden/cozystack-controlplane-multidoc.golden.yaml @@ -26,6 +26,7 @@ machine: - name: drbd parameters: - usermode_helper=disabled + - name: drbd_transport_tcp - name: zfs - name: spl - name: vfio_pci diff --git a/pkg/engine/testdata/golden/cozystack-worker-legacy.golden.yaml b/pkg/engine/testdata/golden/cozystack-worker-legacy.golden.yaml index 9f88403a..3b25b9d4 100644 --- a/pkg/engine/testdata/golden/cozystack-worker-legacy.golden.yaml +++ b/pkg/engine/testdata/golden/cozystack-worker-legacy.golden.yaml @@ -23,6 +23,7 @@ machine: - name: drbd parameters: - usermode_helper=disabled + - name: drbd_transport_tcp - name: zfs - name: spl - name: vfio_pci diff --git a/pkg/engine/testdata/golden/cozystack-worker-multidoc.golden.yaml b/pkg/engine/testdata/golden/cozystack-worker-multidoc.golden.yaml index 6a52db2e..8a309230 100644 --- a/pkg/engine/testdata/golden/cozystack-worker-multidoc.golden.yaml +++ b/pkg/engine/testdata/golden/cozystack-worker-multidoc.golden.yaml @@ -23,6 +23,7 @@ machine: - name: drbd parameters: - usermode_helper=disabled + - name: drbd_transport_tcp - name: zfs - name: spl - name: vfio_pci