From 4d30b03c0fa896b17cf2bbfa6685503f5f1df797 Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Mon, 23 Feb 2026 15:17:33 +0100 Subject: [PATCH 1/2] Adjust RLIMITs after freezing `Configuration` namespace Adjust resource limits only after freezing the `Configuration` to account for any user-provided overrides via the `-D/--define` command line option. Previously, resource limits were adjusted before processing command line options, and any user-provided overrides were accepted but not applied. Now, a command like this one works as intended and used 32 as the stack limit instead of the 64 provided as env var: $ ICINGA2_RLIMIT_STACK=64 icinga2 daemon -DConfiguration.RLimitStack=32 --- icinga-app/icinga.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index eaab44fca..81073d31f 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -281,9 +281,6 @@ static int Main() #endif /* RLIMIT_STACK */ } - if (!autocomplete) - Application::SetResourceLimits(); - LogSeverity logLevel = Logger::GetConsoleLogSeverity(); Logger::SetConsoleLogSeverity(LogWarning); @@ -442,6 +439,10 @@ static int Main() Configuration::Concurrency = std::thread::hardware_concurrency(); } + if (!autocomplete) { + Application::SetResourceLimits(); + } + Application::GetTP().Restart(); /* Ensure that all defined constants work in the way we expect them. */ From 1a170bed74fe5bcd10e898b34d59534dd46b5539 Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Mon, 23 Feb 2026 15:38:26 +0100 Subject: [PATCH 2/2] Apply RLIMIT adjustment conditionally based on the target command Apply resource limits only when the target command needs it. This allows to run sub-commands that do not need the resource limits without requiring elevated privileges. Each command that needs the resource limits should override `CLICommand::NeedsRLimitAdjustment()` to return true. --- icinga-app/icinga.cpp | 2 +- lib/cli/clicommand.cpp | 5 +++++ lib/cli/clicommand.hpp | 1 + lib/cli/consolecommand.cpp | 5 +++++ lib/cli/consolecommand.hpp | 1 + lib/cli/daemoncommand.cpp | 5 +++++ lib/cli/daemoncommand.hpp | 1 + 7 files changed, 19 insertions(+), 1 deletion(-) diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index 81073d31f..5c398444c 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -439,7 +439,7 @@ static int Main() Configuration::Concurrency = std::thread::hardware_concurrency(); } - if (!autocomplete) { + if (!autocomplete && command && command->NeedsRLimitAdjustment()) { Application::SetResourceLimits(); } diff --git a/lib/cli/clicommand.cpp b/lib/cli/clicommand.cpp index 46b702831..d841a68c9 100644 --- a/lib/cli/clicommand.cpp +++ b/lib/cli/clicommand.cpp @@ -96,6 +96,11 @@ bool CLICommand::IsDeprecated() const return false; } +bool CLICommand::NeedsRLimitAdjustment() const +{ + return false; +} + std::mutex& CLICommand::GetRegistryMutex() { static std::mutex mtx; diff --git a/lib/cli/clicommand.hpp b/lib/cli/clicommand.hpp index a122101c2..d15907716 100644 --- a/lib/cli/clicommand.hpp +++ b/lib/cli/clicommand.hpp @@ -42,6 +42,7 @@ public: virtual int GetMaxArguments() const; virtual bool IsHidden() const; virtual bool IsDeprecated() const; + virtual bool NeedsRLimitAdjustment() const; virtual void InitParameters(boost::program_options::options_description& visibleDesc, boost::program_options::options_description& hiddenDesc) const; virtual ImpersonationLevel GetImpersonationLevel() const; diff --git a/lib/cli/consolecommand.cpp b/lib/cli/consolecommand.cpp index 37a35d499..1223cd94f 100644 --- a/lib/cli/consolecommand.cpp +++ b/lib/cli/consolecommand.cpp @@ -167,6 +167,11 @@ ImpersonationLevel ConsoleCommand::GetImpersonationLevel() const return ImpersonateNone; } +bool ConsoleCommand::NeedsRLimitAdjustment() const +{ + return true; +} + void ConsoleCommand::InitParameters(boost::program_options::options_description& visibleDesc, [[maybe_unused]] boost::program_options::options_description& hiddenDesc) const { diff --git a/lib/cli/consolecommand.hpp b/lib/cli/consolecommand.hpp index b35939408..644684303 100644 --- a/lib/cli/consolecommand.hpp +++ b/lib/cli/consolecommand.hpp @@ -30,6 +30,7 @@ public: String GetDescription() const override; String GetShortDescription() const override; ImpersonationLevel GetImpersonationLevel() const override; + bool NeedsRLimitAdjustment() const override; void InitParameters(boost::program_options::options_description& visibleDesc, boost::program_options::options_description& hiddenDesc) const override; int Run(const boost::program_options::variables_map& vm, const std::vector& ap) const override; diff --git a/lib/cli/daemoncommand.cpp b/lib/cli/daemoncommand.cpp index 8cf095a3e..80df51b8d 100644 --- a/lib/cli/daemoncommand.cpp +++ b/lib/cli/daemoncommand.cpp @@ -176,6 +176,11 @@ String DaemonCommand::GetShortDescription() const return "starts Icinga 2"; } +bool DaemonCommand::NeedsRLimitAdjustment() const +{ + return true; +} + void DaemonCommand::InitParameters(boost::program_options::options_description& visibleDesc, [[maybe_unused]] boost::program_options::options_description& hiddenDesc) const { diff --git a/lib/cli/daemoncommand.hpp b/lib/cli/daemoncommand.hpp index 4aabb03f9..d868e3cd8 100644 --- a/lib/cli/daemoncommand.hpp +++ b/lib/cli/daemoncommand.hpp @@ -21,6 +21,7 @@ public: String GetDescription() const override; String GetShortDescription() const override; + bool NeedsRLimitAdjustment() const override; void InitParameters(boost::program_options::options_description& visibleDesc, boost::program_options::options_description& hiddenDesc) const override; std::vector GetArgumentSuggestions(const String& argument, const String& word) const override;