From 3f48d37e7a13b505eb204cb745e272cbe8d32907 Mon Sep 17 00:00:00 2001 From: Ilia Ross Date: Sun, 21 Jun 2026 22:52:13 +0200 Subject: [PATCH] Add Apache 2.4 MPM process limit directives Expose missing prefork, worker, and event MPM tuning directives under Apache Processes and Limits, including MaxRequestWorkers, ServerLimit, ThreadLimit, ThreadsPerChild, and spare-thread controls. https://github.com/webmin/webmin/issues/1821 --- apache/core.pl | 73 +++++++++++++++++++++++++++++++++++++++ apache/lang/en | 8 +++-- apache/mod_mpm_event.pl | 10 ++++-- apache/mod_mpm_prefork.pl | 2 ++ apache/mod_mpm_worker.pl | 27 +++++++++++++++ apache/prefork.pl | 3 ++ apache/worker.pl | 5 ++- 7 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 apache/mod_mpm_worker.pl diff --git a/apache/core.pl b/apache/core.pl index 4fc4fcecc..1a11af350 100755 --- a/apache/core.pl +++ b/apache/core.pl @@ -118,6 +118,19 @@ return &parse_opt("MaxClients", '^\d+$', $text{'core_emaxconc'}); } +sub edit_MaxRequestWorkers +{ +return (1, + $text{'core_maxconc'}, + &opt_input($_[0]->{'value'}, "MaxRequestWorkers", + $text{'core_default'}, 4)); +} +sub save_MaxRequestWorkers +{ +return &parse_opt("MaxRequestWorkers", '^\d+$', + $text{'core_emaxconc'}); +} + sub edit_MaxKeepAliveRequests { return (1, @@ -178,6 +191,66 @@ return &parse_opt("StartServers", '^\d+$', $text{'core_einitial'}); } +sub edit_ServerLimit +{ +return (1, + $text{'core_serverlimit'}, + &opt_input($_[0]->{'value'}, "ServerLimit", $text{'core_default'}, 4)); +} +sub save_ServerLimit +{ +return &parse_opt("ServerLimit", '^\d+$', + $text{'core_eserverlimit'}); +} + +sub edit_MinSpareThreads +{ +return (1, + $text{'worker_minspare'}, + &opt_input($_[0]->{'value'},"MinSpareThreads",$text{'core_default'}, 4)); +} +sub save_MinSpareThreads +{ +return &parse_opt("MinSpareThreads", '^\d+$', + $text{'worker_eminspare'}); +} + +sub edit_MaxSpareThreads +{ +return (1, + $text{'worker_maxspare'}, + &opt_input($_[0]->{'value'},"MaxSpareThreads",$text{'core_default'}, 4)); +} +sub save_MaxSpareThreads +{ +return &parse_opt("MaxSpareThreads", '^\d+$', + $text{'worker_emaxspare'}); +} + +sub edit_ThreadLimit +{ +return (1, + $text{'worker_threadlimit'}, + &opt_input($_[0]->{'value'},"ThreadLimit",$text{'core_default'}, 4)); +} +sub save_ThreadLimit +{ +return &parse_opt("ThreadLimit", '^\d+$', + $text{'worker_ethreadlimit'}); +} + +sub edit_ThreadsPerChild +{ +return (1, + $text{'worker_threads'}, + &opt_input($_[0]->{'value'},"ThreadsPerChild",$text{'core_default'}, 4)); +} +sub save_ThreadsPerChild +{ +return &parse_opt("ThreadsPerChild", '^\d+$', + $text{'worker_ethreads'}); +} + sub edit_RLimitCPU { return &rlimit_input("RLimitCPU", $text{'core_cpulimit'}, $_[0]); diff --git a/apache/lang/en b/apache/lang/en index 011c32837..78fdf4132 100644 --- a/apache/lang/en +++ b/apache/lang/en @@ -346,13 +346,15 @@ core_maxkeep=Maximum keepalives per connection core_maxreq=Maximum requests per server process core_minspare=Minimum spare server processes core_maxspare=Maximum spare server processes -core_initial=Initial server processes +core_initial=Server processes at startup +core_serverlimit=Server process limit core_emaxconc=Maximum concurrent requests must be an integer core_emaxkeep=Maximum keepalives per connection must be an integer core_emaxreq=Maximum requests per server process must be an integer core_eminspare=Minimum spare server processes must be an integer core_emaxspare=Maximum spare server processes must be an integer -core_einitial=Initial server processes must be an integer +core_einitial=Server processes at startup must be an integer +core_eserverlimit=Server process limit must be an integer core_default=Default core_cpulimit=CPU resource limit core_memlimit=Memory resource limit @@ -1064,6 +1066,8 @@ worker_eminspare=Minimum spare threads must be an integer worker_emaxspare=Maximum spare threads must be an integer worker_threads=Threads per child process worker_ethreads=Number of threads per child process must be an integer +worker_threadlimit=Thread limit per child process +worker_ethreadlimit=Thread limit per child process must be an integer perchild_sthreads=Initial threads per child process perchild_esthreads=Number of threads per child process must be an integer diff --git a/apache/mod_mpm_event.pl b/apache/mod_mpm_event.pl index b70094ad2..357ddc586 100755 --- a/apache/mod_mpm_event.pl +++ b/apache/mod_mpm_event.pl @@ -1,5 +1,5 @@ # mod_mpm_event.pl -# Defines editors for the pre-forking module in apache 2.4. +# Defines editors for the event MPM module in apache 2.4. # The actual functions for all of these are still in core.pl sub mod_mpm_event_directives @@ -9,13 +9,17 @@ $rv = [ [ 'CoreDumpDirectory', 0, 9, 'global', 2.0 ], [ 'BindAddress Listen Port', 1, 1, 'global', 2.0, 10 ], [ 'ListenBacklog', 0, 1, 'global', 2.0 ], [ 'LockFile', 0, 9, 'global', 2.0 ], + [ 'MaxRequestWorkers', 0, 0, 'global', 2.313 ], [ 'MaxRequestsPerChild', 0, 0, 'global', 2.0 ], - [ 'MinSpareServers', 0, 0, 'global', 2.0 ], - [ 'MaxSpareServers', 0, 0, 'global', 2.0 ], + [ 'MinSpareThreads', 0, 0, 'global', 2.0 ], + [ 'MaxSpareThreads', 0, 0, 'global', 2.0 ], [ 'PidFile', 0, 9, 'global', 2.0 ], [ 'ScoreBoardFile', 0, 9, 'global', 2.0 ], [ 'SendBufferSize', 0, 1, 'global', 2.0 ], + [ 'ServerLimit', 0, 0, 'global', 2.0 ], [ 'StartServers', 0, 0, 'global', 2.0 ], + [ 'ThreadLimit', 0, 0, 'global', 2.0 ], + [ 'ThreadsPerChild', 0, 0, 'global', 2.0 ], [ 'Group', 0, 8, 'global', 2.0 ], [ 'User', 0, 8, 'global', 2.0, 10 ] ]; return &make_directives($rv, $_[0], "mod_mpm_event"); diff --git a/apache/mod_mpm_prefork.pl b/apache/mod_mpm_prefork.pl index 02fb0904e..c0c178b15 100755 --- a/apache/mod_mpm_prefork.pl +++ b/apache/mod_mpm_prefork.pl @@ -9,12 +9,14 @@ $rv = [ [ 'CoreDumpDirectory', 0, 9, 'global', 2.0 ], [ 'BindAddress Listen Port', 1, 1, 'global', 2.0, 10 ], [ 'ListenBacklog', 0, 1, 'global', 2.0 ], [ 'LockFile', 0, 9, 'global', 2.0 ], + [ 'MaxRequestWorkers', 0, 0, 'global', 2.313 ], [ 'MaxRequestsPerChild', 0, 0, 'global', 2.0 ], [ 'MinSpareServers', 0, 0, 'global', 2.0 ], [ 'MaxSpareServers', 0, 0, 'global', 2.0 ], [ 'PidFile', 0, 9, 'global', 2.0 ], [ 'ScoreBoardFile', 0, 9, 'global', 2.0 ], [ 'SendBufferSize', 0, 1, 'global', 2.0 ], + [ 'ServerLimit', 0, 0, 'global', 2.0 ], [ 'StartServers', 0, 0, 'global', 2.0 ], [ 'Group', 0, 8, 'global', 2.0 ], [ 'User', 0, 8, 'global', 2.0, 10 ] ]; diff --git a/apache/mod_mpm_worker.pl b/apache/mod_mpm_worker.pl new file mode 100644 index 000000000..01a3c3461 --- /dev/null +++ b/apache/mod_mpm_worker.pl @@ -0,0 +1,27 @@ +# mod_mpm_worker.pl +# Defines editors for the worker MPM module in apache 2.4. +# The actual functions for all of these are still in core.pl + +sub mod_mpm_worker_directives +{ +local $rv; +$rv = [ [ 'CoreDumpDirectory', 0, 9, 'global', 2.0 ], + [ 'BindAddress Listen Port', 1, 1, 'global', 2.0, 10 ], + [ 'ListenBacklog', 0, 1, 'global', 2.0 ], + [ 'LockFile', 0, 9, 'global', 2.0 ], + [ 'MaxRequestWorkers', 0, 0, 'global', 2.313 ], + [ 'MaxRequestsPerChild', 0, 0, 'global', 2.0 ], + [ 'MinSpareThreads', 0, 0, 'global', 2.0 ], + [ 'MaxSpareThreads', 0, 0, 'global', 2.0 ], + [ 'PidFile', 0, 9, 'global', 2.0 ], + [ 'ScoreBoardFile', 0, 9, 'global', 2.0 ], + [ 'SendBufferSize', 0, 1, 'global', 2.0 ], + [ 'ServerLimit', 0, 0, 'global', 2.0 ], + [ 'StartServers', 0, 0, 'global', 2.0 ], + [ 'ThreadLimit', 0, 0, 'global', 2.0 ], + [ 'ThreadsPerChild', 0, 0, 'global', 2.0 ], + [ 'Group', 0, 8, 'global', 2.0 ], + [ 'User', 0, 8, 'global', 2.0, 10 ] ]; +return &make_directives($rv, $_[0], "mod_mpm_worker"); +} + diff --git a/apache/prefork.pl b/apache/prefork.pl index 6f4c08c1e..4167c0720 100755 --- a/apache/prefork.pl +++ b/apache/prefork.pl @@ -9,12 +9,15 @@ $rv = [ [ 'CoreDumpDirectory', 0, 9, 'global', 2.0 ], [ 'BindAddress Listen Port', 1, 1, 'global', 2.0, 10 ], [ 'ListenBacklog', 0, 1, 'global', 2.0 ], [ 'LockFile', 0, 9, 'global', 2.0 ], + [ 'MaxClients', 0, 0, 'global', '2.0-2.313' ], + [ 'MaxRequestWorkers', 0, 0, 'global', 2.313 ], [ 'MaxRequestsPerChild', 0, 0, 'global', 2.0 ], [ 'MinSpareServers', 0, 0, 'global', 2.0 ], [ 'MaxSpareServers', 0, 0, 'global', 2.0 ], [ 'PidFile', 0, 9, 'global', 2.0 ], [ 'ScoreBoardFile', 0, 9, 'global', 2.0 ], [ 'SendBufferSize', 0, 1, 'global', 2.0 ], + [ 'ServerLimit', 0, 0, 'global', 2.0 ], [ 'StartServers', 0, 0, 'global', 2.0 ], [ 'Group', 0, 8, 'global', 2.0 ], [ 'User', 0, 8, 'global', 2.0, 10 ] ]; diff --git a/apache/worker.pl b/apache/worker.pl index 2009b7f55..8f68546e8 100755 --- a/apache/worker.pl +++ b/apache/worker.pl @@ -9,14 +9,17 @@ $rv = [ [ 'CoreDumpDirectory', 0, 9, 'global', 2.0 ], [ 'BindAddress Listen Port', 1, 1, 'global', 2.0, 10 ], [ 'ListenBacklog', 0, 1, 'global', 2.0 ], [ 'LockFile', 0, 9, 'global', 2.0 ], - [ 'MaxClients', 0, 0, 'global', 2.0 ], + [ 'MaxClients', 0, 0, 'global', '2.0-2.313' ], + [ 'MaxRequestWorkers', 0, 0, 'global', 2.313 ], [ 'MaxRequestsPerChild', 0, 0, 'global', 2.0 ], [ 'MinSpareThreads', 0, 0, 'global', 2.0 ], [ 'MaxSpareThreads', 0, 0, 'global', 2.0 ], [ 'PidFile', 0, 9, 'global', 2.0 ], [ 'ScoreBoardFile', 0, 9, 'global', 2.0 ], [ 'SendBufferSize', 0, 1, 'global', 2.0 ], + [ 'ServerLimit', 0, 0, 'global', 2.0 ], [ 'StartServers', 0, 0, 'global', 2.0 ], + [ 'ThreadLimit', 0, 0, 'global', 2.0 ], [ 'ThreadsPerChild', 0, 0, 'global', 2.0 ], [ 'Group', 0, 8, 'global', 2.0 ], [ 'User', 0, 8, 'global', 2.0, 10 ] ];