From 679e4bf01190be6ddb3a5881ce34c7b0e4dae562 Mon Sep 17 00:00:00 2001 From: Leonard Foerster Date: Fri, 15 Sep 2023 09:12:17 +0000 Subject: [PATCH 1/3] models: add new setting to auto-load kernel modules Loading specific kernel modules can be necessary to use specific features on your node. One example would be loading the correct module for your choice of scheduling algorithm for ipvs. Loading kernel modules is currently only possible during boot and requires the use and maintenance of an init-container image to load the desired kernel modules on boot. We can simplify that by adding the additional setting `autoload` for kernel modules and utilizing the already available systemd-modules-load service. Module auto-loading is in conflict with blocking modules from loading through the sibling setting `allowed`. Hence, do not auto-load a module if the module is not allowed at the same time. Blocking takes precedence, as it is the more prohibitive operation. Signed-off-by: Leonard Foerster --- README.md | 11 +++++++++++ packages/release/modules-load.template | 9 +++++++++ packages/release/release.spec | 3 +++ sources/models/shared-defaults/defaults.toml | 8 ++++++-- sources/models/src/lib.rs | 1 + 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 packages/release/modules-load.template diff --git a/README.md b/README.md index 6a1270484d0..c5cceef2ce8 100644 --- a/README.md +++ b/README.md @@ -1164,6 +1164,17 @@ Here are the metrics settings: allowed = false ``` +* `settings.kernel.modules..autoload`: Whether the named kernel modules shall be loaded automatically. + **Important note:** this setting needs to be used in conjunction with the `allowed` setting for the same module to ensure we are not auto-loading a module that is blocked. + + Example user data for auto-loading a kernel module on boot: + + ```toml + [settings.kernel.modules.ip_vs_lc] + allowed = true + autoload = true + ``` + * `settings.kernel.sysctl`: Key/value pairs representing Linux kernel parameters. Remember to quote keys (since they often contain ".") and to quote all values. diff --git a/packages/release/modules-load.template b/packages/release/modules-load.template new file mode 100644 index 00000000000..a3cacfc56c6 --- /dev/null +++ b/packages/release/modules-load.template @@ -0,0 +1,9 @@ +{{#if settings.kernel.modules}} +{{#each settings.kernel.modules}} +{{#if this.allowed}} +{{#if this.autoload}} +{{@key}} +{{/if}} +{{/if}} +{{/each}} +{{/if}} diff --git a/packages/release/release.spec b/packages/release/release.spec index e18d7ccde4a..4e1533db90e 100644 --- a/packages/release/release.spec +++ b/packages/release/release.spec @@ -23,6 +23,7 @@ Source204: modprobe-conf.template Source205: netdog.template Source206: aws-config Source207: aws-credentials +Source208: modules-load.template Source1001: multi-user.target Source1002: configured.target @@ -194,6 +195,7 @@ install -p -m 0644 %{S:204} %{buildroot}%{_cross_templatedir}/modprobe-conf install -p -m 0644 %{S:205} %{buildroot}%{_cross_templatedir}/netdog-toml install -p -m 0644 %{S:206} %{buildroot}%{_cross_templatedir}/aws-config install -p -m 0644 %{S:207} %{buildroot}%{_cross_templatedir}/aws-credentials +install -p -m 0644 %{S:208} %{buildroot}%{_cross_templatedir}/modules-load install -p -m 0644 %{S:1302} %{buildroot}%{_cross_templatedir}/log4j-hotpatch-enabled install -d %{buildroot}%{_cross_udevrulesdir} @@ -260,6 +262,7 @@ ln -s preconfigured.target %{buildroot}%{_cross_unitdir}/default.target %{_cross_templatedir}/hosts %{_cross_templatedir}/aws-config %{_cross_templatedir}/aws-credentials +%{_cross_templatedir}/modules-load %{_cross_templatedir}/log4j-hotpatch-enabled %{_cross_udevrulesdir}/61-mount-cdrom.rules diff --git a/sources/models/shared-defaults/defaults.toml b/sources/models/shared-defaults/defaults.toml index c35f4c1b6f6..f86b071f6dc 100644 --- a/sources/models/shared-defaults/defaults.toml +++ b/sources/models/shared-defaults/defaults.toml @@ -129,13 +129,17 @@ restart-commands = ["/usr/bin/corndog sysctl"] affected-services = ["sysctl"] [services.kernel-modules] -configuration-files = ["modprobe-conf"] -restart-commands = [] +configuration-files = ["modprobe-conf", "modules-load"] +restart-commands = ["/usr/bin/systemctl try-restart systemd-modules-load"] [configuration-files.modprobe-conf] path = "/etc/modprobe.d/modprobe.conf" template-path = "/usr/share/templates/modprobe-conf" +[configuration-files.modules-load] +path = "/etc/modules-load.d/modules-load.conf" +template-path = "/usr/share/templates/modules-load" + [metadata.settings.kernel.modules] affected-services = ["kernel-modules"] diff --git a/sources/models/src/lib.rs b/sources/models/src/lib.rs index e1ebf9e40c5..5cce1bdd888 100644 --- a/sources/models/src/lib.rs +++ b/sources/models/src/lib.rs @@ -422,6 +422,7 @@ struct KernelSettings { #[model] struct KmodSetting { allowed: bool, + autoload: bool, } // Kernel boot settings From e5189056dde03ec6c83a2c7ac29e04765a599ac2 Mon Sep 17 00:00:00 2001 From: Leonard Foerster Date: Mon, 18 Sep 2023 13:14:40 +0000 Subject: [PATCH 2/3] Bump Release.toml for the next 1.16.0 release This updates Release.toml so all new builds done off of the develop branch reflect that they are part of the 1.16.0 cycle. Signed-off-by: Leonard Foerster --- Release.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Release.toml b/Release.toml index fcc7cc74696..12fffa595af 100644 --- a/Release.toml +++ b/Release.toml @@ -1,4 +1,4 @@ -version = "1.15.0" +version = "1.16.0" [migrations] "(0.3.1, 0.3.2)" = ["migrate_v0.3.2_admin-container-v0-5-0.lz4"] @@ -234,3 +234,5 @@ version = "1.15.0" "migrate_v1.15.0_log4j-hotpatch-enabled-metadata.lz4", "migrate_v1.15.0_deprecate-log4j-hotpatch-enabled.lz4", ] +"(1.15.0, 1.16.0)" = [ +] From 18ed9ffcfa6cca1112b3171f81a9d0dc903a175f Mon Sep 17 00:00:00 2001 From: Leonard Foerster Date: Mon, 18 Sep 2023 12:06:46 +0000 Subject: [PATCH 3/3] migrations: handle new setting for kernel module autoload Clean up the kernel modules autoload setting on downgrade, as older releases do not support this functionality. Signed-off-by: Leonard Foerster --- Release.toml | 4 ++ sources/Cargo.lock | 31 +++++++++++ sources/Cargo.toml | 4 ++ .../Cargo.toml | 15 ++++++ .../src/main.rs | 23 ++++++++ .../kernel-modules-autoload-files/Cargo.toml | 15 ++++++ .../kernel-modules-autoload-files/src/main.rs | 23 ++++++++ .../Cargo.toml | 15 ++++++ .../src/main.rs | 23 ++++++++ .../Cargo.toml | 14 +++++ .../src/main.rs | 53 +++++++++++++++++++ 11 files changed, 220 insertions(+) create mode 100644 sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-configs/Cargo.toml create mode 100644 sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-configs/src/main.rs create mode 100644 sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-files/Cargo.toml create mode 100644 sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-files/src/main.rs create mode 100644 sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-restart/Cargo.toml create mode 100644 sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-restart/src/main.rs create mode 100644 sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-settings/Cargo.toml create mode 100644 sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-settings/src/main.rs diff --git a/Release.toml b/Release.toml index 12fffa595af..df0692879fa 100644 --- a/Release.toml +++ b/Release.toml @@ -235,4 +235,8 @@ version = "1.16.0" "migrate_v1.15.0_deprecate-log4j-hotpatch-enabled.lz4", ] "(1.15.0, 1.16.0)" = [ + "migrate_v1.16.0_kernel-modules-autoload-configs.lz4", + "migrate_v1.16.0_kernel-modules-autoload-files.lz4", + "migrate_v1.16.0_kernel-modules-autoload-restart.lz4", + "migrate_v1.16.0_kernel-modules-autoload-settings.lz4", ] diff --git a/sources/Cargo.lock b/sources/Cargo.lock index c3d1b60ebfb..e92ec98830c 100644 --- a/sources/Cargo.lock +++ b/sources/Cargo.lock @@ -2325,6 +2325,37 @@ dependencies = [ "serde_json", ] +[[package]] +name = "kernel-modules-autoload-configs" +version = "0.1.0" +dependencies = [ + "migration-helpers", + "serde_json", +] + +[[package]] +name = "kernel-modules-autoload-files" +version = "0.1.0" +dependencies = [ + "migration-helpers", + "serde_json", +] + +[[package]] +name = "kernel-modules-autoload-restart" +version = "0.1.0" +dependencies = [ + "migration-helpers", + "serde_json", +] + +[[package]] +name = "kernel-modules-autoload-settings" +version = "0.1.0" +dependencies = [ + "migration-helpers", +] + [[package]] name = "kubelet-config-settings" version = "0.1.0" diff --git a/sources/Cargo.toml b/sources/Cargo.toml index 7961dcaed69..c4ee7abaea8 100644 --- a/sources/Cargo.toml +++ b/sources/Cargo.toml @@ -69,6 +69,10 @@ members = [ "api/migration/migrations/v1.15.0/public-control-container-v0-7-4", "api/migration/migrations/v1.15.0/deprecate-log4j-hotpatch-enabled", "api/migration/migrations/v1.15.0/log4j-hotpatch-enabled-metadata", + "api/migration/migrations/v1.16.0/kernel-modules-autoload-configs", + "api/migration/migrations/v1.16.0/kernel-modules-autoload-files", + "api/migration/migrations/v1.16.0/kernel-modules-autoload-restart", + "api/migration/migrations/v1.16.0/kernel-modules-autoload-settings", "bloodhound", diff --git a/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-configs/Cargo.toml b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-configs/Cargo.toml new file mode 100644 index 00000000000..cb6ad2c1839 --- /dev/null +++ b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-configs/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "kernel-modules-autoload-configs" +version = "0.1.0" +authors = ["Leonard Foerster "] +license = "Apache-2.0 OR MIT" +edition = "2021" +publish = false +# Don't rebuild crate just because of changes to README. +exclude = ["README.md"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +migration-helpers = { path = "../../../migration-helpers/", version = "0.1.0" } +serde_json = "1" diff --git a/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-configs/src/main.rs b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-configs/src/main.rs new file mode 100644 index 00000000000..3be5090a0ab --- /dev/null +++ b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-configs/src/main.rs @@ -0,0 +1,23 @@ +use migration_helpers::common_migrations::AddPrefixesMigration; +use migration_helpers::{migrate, Result}; +use std::process; + +/// We added new settings under `settings.kernel.modules` for configuring +/// /etc/modules-load.d/modules-load.conf. The actual autoload settings are +/// migrated separately in kernel-modules-autoload-settings migration as they +/// require a custom migration implementation. +fn run() -> Result<()> { + migrate(AddPrefixesMigration(vec![ + "configuration-files.modules-load", + ])) +} + +// Returning a Result from main makes it print a Debug representation of the error, but with Snafu +// we have nice Display representations of the error, so we wrap "main" (run) and print any error. +// /~https://github.com/shepmaster/snafu/issues/110 +fn main() { + if let Err(e) = run() { + eprintln!("{}", e); + process::exit(1); + } +} diff --git a/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-files/Cargo.toml b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-files/Cargo.toml new file mode 100644 index 00000000000..8f2124a8525 --- /dev/null +++ b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-files/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "kernel-modules-autoload-files" +version = "0.1.0" +authors = ["Leonard Foerster "] +license = "Apache-2.0 OR MIT" +edition = "2021" +publish = false +# Don't rebuild crate just because of changes to README. +exclude = ["README.md"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +migration-helpers = { path = "../../../migration-helpers/", version = "0.1.0" } +serde_json = "1" diff --git a/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-files/src/main.rs b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-files/src/main.rs new file mode 100644 index 00000000000..3897007991a --- /dev/null +++ b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-files/src/main.rs @@ -0,0 +1,23 @@ +use migration_helpers::common_migrations::{ListReplacement, ReplaceListsMigration}; +use migration_helpers::{migrate, Result}; +use std::process; + +/// We added a config file to the configuration-files list for services.kernel-modules +/// to facilitate module autoload. This needs to be restored to prior values on downgrade. +fn run() -> Result<()> { + migrate(ReplaceListsMigration(vec![ListReplacement { + setting: "services.kernel-modules.configuration-files", + old_vals: &["modprobe-conf"], + new_vals: &["modprobe-conf", "modules-load"], + }])) +} + +// Returning a Result from main makes it print a Debug representation of the error, but with Snafu +// we have nice Display representations of the error, so we wrap "main" (run) and print any error. +// /~https://github.com/shepmaster/snafu/issues/110 +fn main() { + if let Err(e) = run() { + eprintln!("{}", e); + process::exit(1); + } +} diff --git a/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-restart/Cargo.toml b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-restart/Cargo.toml new file mode 100644 index 00000000000..02a78c659ac --- /dev/null +++ b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-restart/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "kernel-modules-autoload-restart" +version = "0.1.0" +authors = ["Leonard Foerster "] +license = "Apache-2.0 OR MIT" +edition = "2021" +publish = false +# Don't rebuild crate just because of changes to README. +exclude = ["README.md"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +migration-helpers = { path = "../../../migration-helpers/", version = "0.1.0" } +serde_json = "1" diff --git a/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-restart/src/main.rs b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-restart/src/main.rs new file mode 100644 index 00000000000..55290bc004c --- /dev/null +++ b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-restart/src/main.rs @@ -0,0 +1,23 @@ +use migration_helpers::common_migrations::{ListReplacement, ReplaceListsMigration}; +use migration_helpers::{migrate, Result}; +use std::process; + +/// We added a new `autoload` setting to `settings.kernel.modules`, which needs +/// re restart of `systemd-modules-load.services`. +fn run() -> Result<()> { + migrate(ReplaceListsMigration(vec![ListReplacement { + setting: "services.kernel-modules.restart-commands", + old_vals: &[], + new_vals: &["/usr/bin/systemctl try-restart systemd-modules-load"], + }])) +} + +// Returning a Result from main makes it print a Debug representation of the error, but with Snafu +// we have nice Display representations of the error, so we wrap "main" (run) and print any error. +// /~https://github.com/shepmaster/snafu/issues/110 +fn main() { + if let Err(e) = run() { + eprintln!("{}", e); + process::exit(1); + } +} diff --git a/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-settings/Cargo.toml b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-settings/Cargo.toml new file mode 100644 index 00000000000..442b9ebaa19 --- /dev/null +++ b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-settings/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "kernel-modules-autoload-settings" +version = "0.1.0" +authors = ["Leonard Foerster "] +license = "Apache-2.0 OR MIT" +edition = "2021" +publish = false +# Don't rebuild crate just because of changes to README. +exclude = ["README.md"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +migration-helpers = { path = "../../../migration-helpers/", version = "0.1.0" } diff --git a/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-settings/src/main.rs b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-settings/src/main.rs new file mode 100644 index 00000000000..58c77918a1b --- /dev/null +++ b/sources/api/migration/migrations/v1.16.0/kernel-modules-autoload-settings/src/main.rs @@ -0,0 +1,53 @@ +use migration_helpers::{migrate, Migration, MigrationData, Result}; +use std::process; + +const KMOD_AUTOLOAD_PREFIX: &str = "settings.kernel.modules"; +const KMOD_AUTOLOAD_SETTING: &str = "autoload"; + +/// We added a new autoload setting to the kernel.mudules set of tables. These tables +/// come with a variable name containing the module name. We can hence not just use +/// an `AddSettingsMigration` as these require the full name. We rather need a hybrid +/// of `AddSettingsMigration` and `AddPrefixesMigration` in order to select the correct +/// parts of these variably named tables to remove on downgrade. Similar to the common +/// forms of `Add*Migrations` we do not need to do anything on upgrade. +pub struct AddKmodAutoload; + +impl Migration for AddKmodAutoload { + /// On upgrade there is nothing to do (see above). + fn forward(&mut self, input: MigrationData) -> Result { + Ok(input) + } + + /// On downgrade, we need to find the `autoload` setting in all tables with + /// prefix `settings.kernel.modules` and remove them. + fn backward(&mut self, mut input: MigrationData) -> Result { + let settings = input + .data + .keys() + .filter(|k| k.starts_with(KMOD_AUTOLOAD_PREFIX)) + .filter(|k| k.ends_with(KMOD_AUTOLOAD_SETTING)) + .cloned() + .collect::>(); + for setting in settings { + if let Some(data) = input.data.remove(&setting) { + println!("Removed {}, which was set to '{}'", setting, data); + } + } + Ok(input) + } +} + +/// We added `settigns.kernel.modules..auotload`. +fn run() -> Result<()> { + migrate(AddKmodAutoload) +} + +// Returning a Result from main makes it print a Debug representation of the error, but with Snafu +// we have nice Display representations of the error, so we wrap "main" (run) and print any error. +// /~https://github.com/shepmaster/snafu/issues/110 +fn main() { + if let Err(e) = run() { + eprintln!("{}", e); + process::exit(1); + } +}