With THP 'always' journald's mmapped journal files sit in 2 MiB folios, so each small journal write dirties and writes back 2 MiB; on the control node that saturated the root mirror holding the bus store and the store, and the controller lost its lease. The module sets the mode from a per-machine setting (default always, the kernel's own, so assigning it changes nothing until a machine sets madvise), verifies it took, rotates the journal once so new files are mapped under the new mode, gives back what it found when stopped, and serves kernel_huge_pages to measure file_thp per unit.
66 lines
1.6 KiB
Go
66 lines
1.6 KiB
Go
package main
|
|
|
|
// The machine as the tools see it: the files they read, under a root that tests replace with a stand-in
|
|
// tree. Everything read here is readable by the runtime's account; nothing is escalated.
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// Machine reads this machine's kernel files under Root ("/" on the machine).
|
|
type Machine struct {
|
|
Root string
|
|
}
|
|
|
|
// ThisMachine is the machine the runtime launched this bundle on.
|
|
func ThisMachine() *Machine { return &Machine{Root: "/"} }
|
|
|
|
func (m *Machine) path(p string) string { return filepath.Join(m.Root, p) }
|
|
|
|
func (m *Machine) read(p string) (string, error) {
|
|
b, err := os.ReadFile(m.path(p))
|
|
return string(b), err
|
|
}
|
|
|
|
func (m *Machine) dirs(p string) ([]string, error) {
|
|
entries, err := os.ReadDir(m.path(p))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var out []string
|
|
for _, e := range entries {
|
|
if e.IsDir() || e.Type()&fs.ModeSymlink != 0 {
|
|
out = append(out, e.Name())
|
|
}
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// whole is a whole-number argument with a default, kept within bounds.
|
|
func whole(args map[string]any, key string, def, least, most int) (int, error) {
|
|
raw, present := args[key]
|
|
if !present || raw == nil {
|
|
return def, nil
|
|
}
|
|
f, ok := raw.(float64)
|
|
if !ok || f != float64(int(f)) {
|
|
return 0, fmt.Errorf("%s must be a whole number", key)
|
|
}
|
|
n := int(f)
|
|
if n < least {
|
|
return 0, fmt.Errorf("%s must be at least %d", key, least)
|
|
}
|
|
if n > most {
|
|
n = most
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
// schema is a tool's input: its properties.
|
|
func schema(properties map[string]any) map[string]any {
|
|
return map[string]any{"type": "object", "properties": properties}
|
|
}
|