NOTE: You may experience random issues in multi-process mode. For more information about the "nbproc" option please see the HAProxy Documentation.
]]>true
+
+ haproxy.general.tuning.nbthread
+
+ text
+
+ haproxy.general.tuning.maxConnections
diff --git a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml
index 6b135564a..de0c9093a 100644
--- a/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml
+++ b/net/haproxy/src/opnsense/mvc/app/models/OPNsense/HAProxy/HAProxy.xml
@@ -69,6 +69,13 @@
Please specify a value between 1 and 128.Y
+
+ 1
+ 1
+ 1024
+ Please specify a value between 1 and 1024.
+ N
+ Yignore
@@ -502,6 +509,18 @@
Should be a number between 1 and 8 characters, optionally followed by either "d", "h", "m", "s", "ms" or "us".N
+
+
+
+ OPNsense.HAProxy.HAProxy
+ cpus.cpu
+ name
+
+
+ Related CPU affinity rule not found
+ Y
+ N
+ 0Y
@@ -2085,5 +2104,236 @@
+
+
+
+ Y
+
+
+ 1
+ Y
+
+
+ /^[^\t^,^;^\.^\[^\]^\{^\}]{1,255}$/u
+ Should be a string between 1 and 255 characters.
+ Y
+
+
+ Y
+
+ All HAProxy processes
+ Processes with odd ID
+ Processes with even ID
+ Process 1
+ Process 2
+ Process 3
+ Process 4
+ Process 5
+ Process 6
+ Process 7
+ Process 8
+ Process 9
+ Process 10
+ Process 11
+ Process 12
+ Process 13
+ Process 14
+ Process 15
+ Process 16
+ Process 17
+ Process 18
+ Process 19
+ Process 20
+ Process 21
+ Process 22
+ Process 23
+ Process 24
+ Process 25
+ Process 26
+ Process 27
+ Process 28
+ Process 29
+ Process 30
+ Process 31
+ Process 32
+ Process 33
+ Process 34
+ Process 35
+ Process 36
+ Process 37
+ Process 38
+ Process 39
+ Process 40
+ Process 41
+ Process 42
+ Process 43
+ Process 44
+ Process 45
+ Process 46
+ Process 47
+ Process 48
+ Process 49
+ Process 50
+ Process 51
+ Process 52
+ Process 53
+ Process 54
+ Process 55
+ Process 56
+ Process 57
+ Process 58
+ Process 59
+ Process 60
+ Process 61
+ Process 62
+ Process 63
+
+
+
+ Y
+
+ All HAProxy threads
+ Threads with odd ID
+ Threads with even ID
+ Thread 1
+ Thread 2
+ Thread 3
+ Thread 4
+ Thread 5
+ Thread 6
+ Thread 7
+ Thread 8
+ Thread 9
+ Thread 10
+ Thread 11
+ Thread 12
+ Thread 13
+ Thread 14
+ Thread 15
+ Thread 16
+ Thread 17
+ Thread 18
+ Thread 19
+ Thread 20
+ Thread 21
+ Thread 22
+ Thread 23
+ Thread 24
+ Thread 25
+ Thread 26
+ Thread 27
+ Thread 28
+ Thread 29
+ Thread 30
+ Thread 31
+ Thread 32
+ Thread 33
+ Thread 34
+ Thread 35
+ Thread 36
+ Thread 37
+ Thread 38
+ Thread 39
+ Thread 40
+ Thread 41
+ Thread 42
+ Thread 43
+ Thread 44
+ Thread 45
+ Thread 46
+ Thread 47
+ Thread 48
+ Thread 49
+ Thread 50
+ Thread 51
+ Thread 52
+ Thread 53
+ Thread 54
+ Thread 55
+ Thread 56
+ Thread 57
+ Thread 58
+ Thread 59
+ Thread 60
+ Thread 61
+ Thread 62
+ Thread 63
+
+
+
+ Y
+ Y
+
+ All CPUs
+ CPUs with odd ID
+ CPUs with even ID
+ CPU 0
+ CPU 1
+ CPU 2
+ CPU 3
+ CPU 4
+ CPU 5
+ CPU 6
+ CPU 7
+ CPU 8
+ CPU 9
+ CPU 10
+ CPU 11
+ CPU 12
+ CPU 13
+ CPU 14
+ CPU 15
+ CPU 16
+ CPU 17
+ CPU 18
+ CPU 19
+ CPU 20
+ CPU 21
+ CPU 22
+ CPU 23
+ CPU 24
+ CPU 25
+ CPU 26
+ CPU 27
+ CPU 28
+ CPU 29
+ CPU 30
+ CPU 31
+ CPU 32
+ CPU 33
+ CPU 34
+ CPU 35
+ CPU 36
+ CPU 37
+ CPU 38
+ CPU 39
+ CPU 40
+ CPU 41
+ CPU 42
+ CPU 43
+ CPU 44
+ CPU 45
+ CPU 46
+ CPU 47
+ CPU 48
+ CPU 49
+ CPU 50
+ CPU 51
+ CPU 52
+ CPU 53
+ CPU 54
+ CPU 55
+ CPU 56
+ CPU 57
+ CPU 58
+ CPU 59
+ CPU 60
+ CPU 61
+ CPU 62
+ CPU 63
+
+
+
+
diff --git a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt
index f97a8f6ae..52a9c842a 100644
--- a/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt
+++ b/net/haproxy/src/opnsense/mvc/app/views/OPNsense/HAProxy/index.volt
@@ -184,6 +184,19 @@ POSSIBILITY OF SUCH DAMAGE.
}
);
+ $("#grid-cpus").UIBootgrid(
+ { search:'/api/haproxy/settings/searchCpus',
+ get:'/api/haproxy/settings/getCpu/',
+ set:'/api/haproxy/settings/setCpu/',
+ add:'/api/haproxy/settings/addCpu/',
+ del:'/api/haproxy/settings/delCpu/',
+ toggle:'/api/haproxy/settings/toggleCpu/',
+ options: {
+ rowCount:[10,25,50,100,500,1000]
+ }
+ }
+ );
+
// hook into on-show event for dialog to extend layout.
$('#DialogAcl').on('shown.bs.modal', function (e) {
$("#acl\\.expression").change(function(){
@@ -516,6 +529,7 @@ POSSIBILITY OF SUCH DAMAGE.
{{ lang._("%sError Messages:%s Return a custom message instead of errors generated by HAProxy. Useful to overwrite HAProxy's internal error messages. The message must represent the full HTTP response and include required HTTP headers.") | format('', '') }}
{{ lang._("%sLua scripts:%s Include your own Lua code/scripts to extend HAProxy's functionality. The Lua code can be used in certain %sRules%s, for example.") | format('', '', '', '') }}
{{ lang._("%sMap Files:%s A map allows to map a data in input to an other one on output. For example, this makes it possible to map a large number of domains to backend pools without using the GUI. Map files need to be used in %sRules%s, otherwise they are ignored.") | format('', '', '', '') }}
+
{{ lang._("%sCPU Affinity Rules:%s This feature makes it possible to bind HAProxy's processes/threads to a specific CPU (or a CPU set). Furthermore it is possible to select CPU Affinity Rules in %sPublic Services%s to restrict them to a certain set of processes/threads/CPUs.") | format('', '', '', '') }}
-
{{ lang._("For more details visit HAProxy's official documentation regarding the %sError Messages%s, %sLua Script%s and the %sMap Files%s features.") | format('', '', '', '', '', '') }}
+
{{ lang._("For more details visit HAProxy's official documentation regarding the %sError Messages%s, %sLua Script%s and the %sMap Files%s features. More information on HAProxy's CPU Affinity is also available %shere%s, %shere%s and %shere%s.") | format('', '', '', '', '', '' ,'', '' ,'', '' ,'', '') }}
@@ -1006,6 +1021,43 @@ POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
{{ lang._('CPU Rule ID') }}
+
{{ lang._('Enabled') }}
+
{{ lang._('Name') }}
+
{{ lang._('Process ID') }}
+
{{ lang._('Thread ID') }}
+
{{ lang._('CPU ID') }}
+
{{ lang._('Commands') }}
+
{{ lang._('ID') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{# include dialogs #}
@@ -1020,3 +1072,4 @@ POSSIBILITY OF SUCH DAMAGE.
{{ partial("layout_partials/base_dialog",['fields':formDialogLua,'id':'DialogLua','label':lang._('Edit Lua Script')])}}
{{ partial("layout_partials/base_dialog",['fields':formDialogErrorfile,'id':'DialogErrorfile','label':lang._('Edit Error Message')])}}
{{ partial("layout_partials/base_dialog",['fields':formDialogMapfile,'id':'DialogMapfile','label':lang._('Edit Map File')])}}
+{{ partial("layout_partials/base_dialog",['fields':formDialogCpu,'id':'DialogCpu','label':lang._('Edit CPU Affinity Rule')])}}
diff --git a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
index 398e9561b..7029e93cd 100644
--- a/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
+++ b/net/haproxy/src/opnsense/service/templates/OPNsense/HAProxy/haproxy.conf
@@ -758,6 +758,16 @@ global
stats socket /var/run/haproxy.socket level admin
{% endif %}
nbproc {{OPNsense.HAProxy.general.tuning.nbproc}}
+{% if OPNsense.HAProxy.general.tuning.nbthread|default('') != '' %}
+ nbthread {{OPNsense.HAProxy.general.tuning.nbthread}}
+{% endif %}
+{% if helpers.exists('OPNsense.HAProxy.cpus.cpu') %}
+{% for cpu_map in helpers.toList('OPNsense.HAProxy.cpus.cpu') %}
+{% if cpu_map.enabled == '1' %}
+ cpu-map {{cpu_map.process_id|replace('x', '')}}/{{cpu_map.thread_id|replace('x', '')}} {{cpu_map.cpu_id|replace('x', '')|replace(',', ' ')}}
+{% endif %}
+{% endfor %}
+{% endif %}
{% if helpers.exists('OPNsense.HAProxy.general.tuning.maxConnections') %}
maxconn {{OPNsense.HAProxy.general.tuning.maxConnections}}
{% endif %}
@@ -969,10 +979,27 @@ frontend {{frontend.name}}
{% endif %}
{% endif %}
{% endif %}
+{# # CPU affinity configuration #}
+{% set bind_process = [] %}
+{% set process_thread = [] %}
+{% if frontend.linkedCpuAffinityRules|default('') != '' %}
+{% for cpu_map in frontend.linkedCpuAffinityRules.split(',') %}
+{% set cpu_map_data = helpers.getUUID(cpu_map) %}
+{% if cpu_map_data.enabled == '1' %}
+{# # Limit visibility to a certain set of processes #}
+{% do bind_process.append(cpu_map_data.process_id|replace('x', '')) %}
+{# # Restrict the list of processes/threads on which this listener is allowed to run #}
+{% do process_thread.append('process ' ~ cpu_map_data.process_id|replace('x', '') ~ '/' ~ cpu_map_data.thread_id|replace('x', '')) %}
+{% endif %}
+{% endfor %}
+{% if bind_process|length > 0 %}
+ bind-process {{bind_process|join(' ')}}
+{% endif %}
+{% endif %}
{# # bind/listen configuration #}
{% if frontend.bind|default("") != "" %}
{% for bind in frontend.bind.split(",") %}
- bind {{bind}} name {{bind}} {% if frontend.bindOptions|default("") != "" %}{{ frontend.bindOptions }} {% endif %}{% if frontend.ssl_enabled == '1' and ssl_certs|default("") != "" %}ssl {{ ssl_options|join(' ') }} {{ ssl_certs|join(' ') }} {% endif %}
+ bind {{bind}} name {{bind}} {% if frontend.bindOptions|default("") != "" %}{{ frontend.bindOptions }} {% endif %}{% if frontend.ssl_enabled == '1' and ssl_certs|default("") != "" %}ssl {{ ssl_options|join(' ') }} {{ ssl_certs|join(' ') }} {% endif %}{% if process_thread|length > 0 %} {{ process_thread|join(' ') }} {% endif %}
{% endfor %}
{% endif %}