Skip to content

Commit 4aeba1c

Browse files
committed
fix: perform backwards-compatible kernel args cleanup
Two changes: * `nvme_core.io_timeout` is AWS-specific, move into AWS platform code * `init_on_alloc` is enabled by default in the kernel config, so a kernel arg is no-op and confusing (as removing it won't disable it) Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
1 parent 9b7b2bf commit 4aeba1c

8 files changed

Lines changed: 274 additions & 16 deletions

File tree

internal/app/machined/pkg/runtime/v1alpha1/platform/aws/aws.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,22 @@ func (a *AWS) Mode() runtime.Mode {
318318
}
319319

320320
// KernelArgs implements the runtime.Platform interface.
321-
func (a *AWS) KernelArgs(string, quirks.Quirks) procfs.Parameters {
322-
return []*procfs.Parameter{
321+
func (a *AWS) KernelArgs(_ string, q quirks.Quirks) procfs.Parameters {
322+
result := []*procfs.Parameter{
323323
procfs.NewParameter("console").Append("tty1").Append("ttyS0"),
324324
procfs.NewParameter(constants.KernelParamNetIfnames).Append("0"),
325325
}
326+
327+
if q.NvmeCoreIoTimeoutAWSOnly() {
328+
// AWS recommends setting the nvme_core.io_timeout to the highest value possible.
329+
// See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html.
330+
result = append(
331+
result,
332+
procfs.NewParameter("nvme_core.io_timeout").Append("4294967295"),
333+
)
334+
}
335+
336+
return result
326337
}
327338

328339
// NetworkConfiguration implements the runtime.Platform interface.

pkg/imager/imager_test.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,126 @@ func TestImager(t *testing.T) {
148148

149149
expected: "talos.platform=metal console=ttyAMA0 console=tty0 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on selinux=1", //nolint:lll
150150
},
151+
{
152+
name: "cmdline-1.13-amd64",
153+
154+
prof: profile.Profile{
155+
BaseProfileName: "metal",
156+
Arch: "amd64",
157+
Output: profile.Output{
158+
Kind: profile.OutKindCmdline,
159+
OutFormat: profile.OutFormatRaw,
160+
},
161+
Version: "1.13.0",
162+
},
163+
164+
expected: "talos.platform=metal console=tty0 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on selinux=1 module.sig_enforce=1 proc_mem.force_override=never", //nolint:lll
165+
},
166+
{
167+
name: "cmdline-1.13-arm64",
168+
169+
prof: profile.Profile{
170+
BaseProfileName: "metal",
171+
Arch: "arm64",
172+
Output: profile.Output{
173+
Kind: profile.OutKindCmdline,
174+
OutFormat: profile.OutFormatRaw,
175+
},
176+
Version: "1.13.0",
177+
},
178+
179+
expected: "talos.platform=metal console=ttyAMA0 console=tty0 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on selinux=1 module.sig_enforce=1 proc_mem.force_override=never", //nolint:lll
180+
},
181+
{
182+
name: "cmdline-aws-1.13-amd64",
183+
184+
prof: profile.Profile{
185+
BaseProfileName: "aws",
186+
Arch: "amd64",
187+
Output: profile.Output{
188+
Kind: profile.OutKindCmdline,
189+
OutFormat: profile.OutFormatRaw,
190+
},
191+
Version: "1.13.0",
192+
},
193+
194+
expected: "talos.platform=aws console=tty1 console=ttyS0 net.ifnames=0 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on selinux=1 module.sig_enforce=1 proc_mem.force_override=never", //nolint:lll
195+
},
196+
{
197+
name: "cmdline-aws-1.13-arm64",
198+
199+
prof: profile.Profile{
200+
BaseProfileName: "aws",
201+
Arch: "arm64",
202+
Output: profile.Output{
203+
Kind: profile.OutKindCmdline,
204+
OutFormat: profile.OutFormatRaw,
205+
},
206+
Version: "1.13.0",
207+
},
208+
209+
expected: "talos.platform=aws console=tty1 console=ttyS0 net.ifnames=0 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on selinux=1 module.sig_enforce=1 proc_mem.force_override=never", //nolint:lll
210+
},
211+
{
212+
name: "cmdline-1.14-amd64",
213+
214+
prof: profile.Profile{
215+
BaseProfileName: "metal",
216+
Arch: "amd64",
217+
Output: profile.Output{
218+
Kind: profile.OutKindCmdline,
219+
OutFormat: profile.OutFormatRaw,
220+
},
221+
Version: "1.14.0",
222+
},
223+
224+
expected: "talos.platform=metal console=tty0 slab_nomerge pti=on consoleblank=0 printk.devkmsg=on selinux=1 module.sig_enforce=1 proc_mem.force_override=never", //nolint:lll
225+
},
226+
{
227+
name: "cmdline-1.14-arm64",
228+
229+
prof: profile.Profile{
230+
BaseProfileName: "metal",
231+
Arch: "arm64",
232+
Output: profile.Output{
233+
Kind: profile.OutKindCmdline,
234+
OutFormat: profile.OutFormatRaw,
235+
},
236+
Version: "1.14.0",
237+
},
238+
239+
expected: "talos.platform=metal console=ttyAMA0 console=tty0 slab_nomerge pti=on consoleblank=0 printk.devkmsg=on selinux=1 module.sig_enforce=1 proc_mem.force_override=never", //nolint:lll
240+
},
241+
{
242+
name: "cmdline-aws-1.14-amd64",
243+
244+
prof: profile.Profile{
245+
BaseProfileName: "aws",
246+
Arch: "amd64",
247+
Output: profile.Output{
248+
Kind: profile.OutKindCmdline,
249+
OutFormat: profile.OutFormatRaw,
250+
},
251+
Version: "1.14.0",
252+
},
253+
254+
expected: "talos.platform=aws console=tty1 console=ttyS0 net.ifnames=0 nvme_core.io_timeout=4294967295 slab_nomerge pti=on consoleblank=0 printk.devkmsg=on selinux=1 module.sig_enforce=1 proc_mem.force_override=never", //nolint:lll
255+
},
256+
{
257+
name: "cmdline-aws-1.14-arm64",
258+
259+
prof: profile.Profile{
260+
BaseProfileName: "aws",
261+
Arch: "arm64",
262+
Output: profile.Output{
263+
Kind: profile.OutKindCmdline,
264+
OutFormat: profile.OutFormatRaw,
265+
},
266+
Version: "1.14.0",
267+
},
268+
269+
expected: "talos.platform=aws console=tty1 console=ttyS0 net.ifnames=0 nvme_core.io_timeout=4294967295 slab_nomerge pti=on consoleblank=0 printk.devkmsg=on selinux=1 module.sig_enforce=1 proc_mem.force_override=never", //nolint:lll
270+
},
151271
} {
152272
t.Run(test.name, func(t *testing.T) {
153273
t.Parallel()

pkg/kernel/kspp/kspp.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ import (
1717
// RequiredKSPPKernelParameters is the set of kernel parameters required to
1818
// satisfy the KSPP.
1919
var RequiredKSPPKernelParameters = procfs.Parameters{
20-
// init_on_alloc and init_on_free are not enforced, as they default to '1' in kernel config
21-
// this way they can be overridden via installer extra args in case of severe performance issues
20+
// init_on_alloc and init_on_free are not enforced, as:
21+
// - init_on_alloc is enabled by default in the kernel config, but can be disabled with init_on_alloc=0 for performance reasons;
22+
// - init_on_free is disabled by default in the kernel config, as it has a significant performance impact, and is not required for security when init_on_alloc=1 is enabled.
23+
//
2224
// procfs.NewParameter("init_on_alloc").Append("1"),
2325
// procfs.NewParameter("init_on_free").Append("1"),
2426
procfs.NewParameter("slab_nomerge").Append(""),

pkg/machinery/imager/quirks/quirks.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,27 @@ func (q Quirks) SupportsFactoryTalosctlDownload() bool {
336336

337337
return q.v.GTE(minTalosVersionFactoryTalosctlDownload)
338338
}
339+
340+
var minTalosVersionDropInitOnAllocInArgs = semver.MustParse("1.14.0")
341+
342+
// DropInitOnAllocInArgs returns true if the Talos version should have no init_on_alloc=1 by default.
343+
func (q Quirks) DropInitOnAllocInArgs() bool {
344+
// if the version doesn't parse, we assume it's latest Talos
345+
if q.v == nil {
346+
return true
347+
}
348+
349+
return q.v.GTE(minTalosVersionDropInitOnAllocInArgs)
350+
}
351+
352+
var minTalosVersionNvmeCoreIoTimeoutAWSOnly = semver.MustParse("1.14.0")
353+
354+
// NvmeCoreIoTimeoutAWSOnly returns true if the Talos version should have nvme_core.io_timeout=4294967295 only for AWS.
355+
func (q Quirks) NvmeCoreIoTimeoutAWSOnly() bool {
356+
// if the version doesn't parse, we assume it's latest Talos
357+
if q.v == nil {
358+
return true
359+
}
360+
361+
return q.v.GTE(minTalosVersionNvmeCoreIoTimeoutAWSOnly)
362+
}

pkg/machinery/imager/quirks/quirks_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
)
1414

1515
func TestSupportsResetOption(t *testing.T) {
16+
t.Parallel()
17+
1618
for _, test := range []struct {
1719
version string
1820

@@ -31,12 +33,16 @@ func TestSupportsResetOption(t *testing.T) {
3133
},
3234
} {
3335
t.Run(test.version, func(t *testing.T) {
36+
t.Parallel()
37+
3438
assert.Equal(t, test.expected, quirks.New(test.version).SupportsResetGRUBOption())
3539
})
3640
}
3741
}
3842

3943
func TestSupportsCompressedEncodedMETA(t *testing.T) {
44+
t.Parallel()
45+
4046
for _, test := range []struct {
4147
version string
4248

@@ -59,12 +65,16 @@ func TestSupportsCompressedEncodedMETA(t *testing.T) {
5965
},
6066
} {
6167
t.Run(test.version, func(t *testing.T) {
68+
t.Parallel()
69+
6270
assert.Equal(t, test.expected, quirks.New(test.version).SupportsCompressedEncodedMETA())
6371
})
6472
}
6573
}
6674

6775
func TestSupportsOverlay(t *testing.T) {
76+
t.Parallel()
77+
6878
for _, test := range []struct {
6979
version string
7080

@@ -95,12 +105,16 @@ func TestSupportsOverlay(t *testing.T) {
95105
},
96106
} {
97107
t.Run(test.version, func(t *testing.T) {
108+
t.Parallel()
109+
98110
assert.Equal(t, test.expected, quirks.New(test.version).SupportsOverlay())
99111
})
100112
}
101113
}
102114

103115
func TestSupportsZstd(t *testing.T) {
116+
t.Parallel()
117+
104118
for _, test := range []struct {
105119
version string
106120

@@ -127,12 +141,16 @@ func TestSupportsZstd(t *testing.T) {
127141
},
128142
} {
129143
t.Run(test.version, func(t *testing.T) {
144+
t.Parallel()
145+
130146
assert.Equal(t, test.expected, quirks.New(test.version).UseZSTDCompression())
131147
})
132148
}
133149
}
134150

135151
func TestXFSMkfsConfigFile(t *testing.T) {
152+
t.Parallel()
153+
136154
for _, test := range []struct {
137155
version string
138156

@@ -176,12 +194,16 @@ func TestXFSMkfsConfigFile(t *testing.T) {
176194
},
177195
} {
178196
t.Run(test.version, func(t *testing.T) {
197+
t.Parallel()
198+
179199
assert.Equal(t, test.expected, quirks.New(test.version).XFSMkfsConfig())
180200
})
181201
}
182202
}
183203

184204
func TestPartitionSizes(t *testing.T) {
205+
t.Parallel()
206+
185207
const (
186208
MiB = 1024 * 1024
187209
GiB = 1024 * MiB
@@ -241,6 +263,8 @@ func TestPartitionSizes(t *testing.T) {
241263
},
242264
} {
243265
t.Run(test.version, func(t *testing.T) {
266+
t.Parallel()
267+
244268
ps := quirks.New(test.version).PartitionSizes()
245269

246270
assert.Equal(t, test.grubEFISize, ps.GrubEFISize())
@@ -253,3 +277,53 @@ func TestPartitionSizes(t *testing.T) {
253277
})
254278
}
255279
}
280+
281+
func TestDropInitOnAllocInArgs(t *testing.T) {
282+
t.Parallel()
283+
284+
for _, test := range []struct {
285+
version string
286+
287+
expected bool
288+
}{
289+
{
290+
version: "1.13.0",
291+
expected: false,
292+
},
293+
{
294+
version: "1.14.0-alpha.1",
295+
expected: true,
296+
},
297+
} {
298+
t.Run(test.version, func(t *testing.T) {
299+
t.Parallel()
300+
301+
assert.Equal(t, test.expected, quirks.New(test.version).DropInitOnAllocInArgs())
302+
})
303+
}
304+
}
305+
306+
func TestNvmeCoreIoTimeoutAWSOnly(t *testing.T) {
307+
t.Parallel()
308+
309+
for _, test := range []struct {
310+
version string
311+
312+
expected bool
313+
}{
314+
{
315+
version: "1.13.0",
316+
expected: false,
317+
},
318+
{
319+
version: "1.14.0-alpha.1",
320+
expected: true,
321+
},
322+
} {
323+
t.Run(test.version, func(t *testing.T) {
324+
t.Parallel()
325+
326+
assert.Equal(t, test.expected, quirks.New(test.version).NvmeCoreIoTimeoutAWSOnly())
327+
})
328+
}
329+
}

pkg/machinery/kernel/kernel.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,37 @@ const (
2222

2323
// DefaultArgs returns the Talos default kernel commandline options.
2424
func DefaultArgs(quirks quirks.Quirks) []string {
25-
result := []string{
26-
"init_on_alloc=1",
25+
var result []string
26+
27+
if !quirks.DropInitOnAllocInArgs() {
28+
result = append(
29+
result,
30+
"init_on_alloc=1",
31+
)
32+
}
33+
34+
result = append(
35+
result,
2736
"slab_nomerge=",
2837
"pti=on",
2938
"consoleblank=0",
39+
)
40+
41+
if !quirks.NvmeCoreIoTimeoutAWSOnly() {
3042
// AWS recommends setting the nvme_core.io_timeout to the highest value possible.
3143
// See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html.
32-
"nvme_core.io_timeout=4294967295",
33-
// Disable rate limited printk
34-
"printk.devkmsg=on",
44+
result = append(
45+
result,
46+
"nvme_core.io_timeout=4294967295",
47+
)
3548
}
3649

50+
// Disable rate limited printk
51+
result = append(
52+
result,
53+
"printk.devkmsg=on",
54+
)
55+
3756
if quirks.SupportsIMA() {
3857
// Enable IMAs for integrity measurement
3958
result = append(

0 commit comments

Comments
 (0)