]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
manager: added FreeBSD support
authorAleš Mrázek <ales.mrazek@nic.cz>
Tue, 18 Nov 2025 14:08:15 +0000 (15:08 +0100)
committerAleš Mrázek <ales.mrazek@nic.cz>
Wed, 26 Nov 2025 17:28:05 +0000 (18:28 +0100)
Multiple workers are supported only on Linux systems or FreeBSD with SO_REUSEPORT_LB socket option.

python/knot_resolver/constants.py
python/knot_resolver/constants.py.in
python/knot_resolver/controller/supervisord/config_file.py
python/knot_resolver/datamodel/config_schema.py
python/knot_resolver/manager/manager.py

index fb12f5bd9f244069fdc5d77015356722dc0f9ae4..7cec351d5ed61499f733dd62525fb8e9d7d39f6b 100644 (file)
@@ -1,5 +1,5 @@
 import importlib.util
-import sys
+import platform
 from pathlib import Path
 
 VERSION = "6.0.16"
@@ -21,12 +21,12 @@ KRESD_EXECUTABLE = SBIN_DIR / "kresd"
 KRES_CACHE_GC_EXECUTABLE = SBIN_DIR / "kres-cache-gc"
 
 LINUX_SYS = False
-if sys.platform.startswith("linux"):
+if platform.system() == "Linux":
     LINUX_SYS = True
 
-APPLE_SYS = False
-if sys.platform == "darwin":
-    APPLE_SYS = True
+FREEBSD_SYS = False
+if platform.system() == "FreeBSD":
+    FREEBSD_SYS = True
 
 WATCHDOG_LIB = False
 if importlib.util.find_spec("watchdog"):
index ec1d26a26470facd76ccf9879eb265b71bcbd595..ae66227a05e44a661c1248033ddd3d6bf32543c8 100644 (file)
@@ -1,5 +1,5 @@
 import importlib.util
-import sys
+import platform
 from pathlib import Path
 
 VERSION = "@version@"
@@ -21,12 +21,12 @@ KRESD_EXECUTABLE = SBIN_DIR / "kresd"
 KRES_CACHE_GC_EXECUTABLE = SBIN_DIR / "kres-cache-gc"
 
 LINUX_SYS = False
-if sys.platform.startswith("linux"):
+if platform.system() == "Linux":
     LINUX_SYS = True
 
-APPLE_SYS = False
-if sys.platform == "darwin":
-    APPLE_SYS = True
+FREEBSD_SYS = False
+if platform.system() == "FreeBSD":
+    FREEBSD_SYS = True
 
 WATCHDOG_LIB = False
 if importlib.util.find_spec("watchdog"):
index 9d02ba6cbfe4dc934aee588b5a426be349a473af..57c8261570f5ffe0886c73c99f73c2abbc6b5a21 100644 (file)
@@ -7,7 +7,7 @@ from typing import Literal
 
 from jinja2 import Template
 
-from knot_resolver.constants import APPLE_SYS, KRES_CACHE_GC_EXECUTABLE, KRESD_EXECUTABLE, LINUX_SYS
+from knot_resolver.constants import FREEBSD_SYS, KRES_CACHE_GC_EXECUTABLE, KRESD_EXECUTABLE, LINUX_SYS
 from knot_resolver.controller.interface import KresID, SubprocessType
 from knot_resolver.datamodel.config_schema import KresConfig, workers_max_count
 from knot_resolver.datamodel.logging_schema import LogTargetEnum
@@ -112,17 +112,21 @@ class ProcessTypeConfig:
     @staticmethod
     def create_kresd_config(config: KresConfig) -> "ProcessTypeConfig":
         cwd = str(os.getcwd())
-        startsecs = 3
         environment = 'SYSTEMD_INSTANCE="%(process_num)d"'
 
+        # Default for non-Linux systems without SO_REUSEPORT/SO_REUSEPORT_LB support.
+        # This means that there is no support for multiple kresd workers and NOTIFY messages.
+        startsecs = 0
+
         if LINUX_SYS:
-            # Wait for NOTIFY message
+            # There is support for the SO_REUSEPORT option and support for NOTIFY message.
+            # Here, 'startsecs' serves as a timeout for waiting for NOTIFY message.
             startsecs = 60
             environment += ",X-SUPERVISORD-TYPE=notify"
-        if APPLE_SYS:
-            # There is no need to wait for anything on macOS
-            # No NOTIFY message and only 1 kresd worker
-            startsecs = 0
+        elif FREEBSD_SYS:
+            # There is support for the SO_REUSEPORT_LB option, but no support for NOTIFY message.
+            # Therefore, we need to give the kresd workers a few seconds to start properly.
+            startsecs = 3
 
         return ProcessTypeConfig(  # type: ignore[call-arg]
             logfile=supervisord_subprocess_log_dir(config) / "kresd%(process_num)d.log",
index 760e3b16b2ad3715ffe4a015d085de795d39bb59..c4871def4490190ad533e997b1db1389aabdb67b 100644 (file)
@@ -3,7 +3,7 @@ import os
 import socket
 from typing import Any, Dict, List, Literal, Optional, Tuple, Union
 
-from knot_resolver.constants import API_SOCK_FILE, APPLE_SYS, RUN_DIR, VERSION
+from knot_resolver.constants import API_SOCK_FILE, FREEBSD_SYS, LINUX_SYS, RUN_DIR, VERSION
 from knot_resolver.datamodel.cache_schema import CacheSchema
 from knot_resolver.datamodel.defer_schema import DeferSchema
 from knot_resolver.datamodel.dns64_schema import Dns64Schema
@@ -161,16 +161,18 @@ class KresConfig(ConfigSchema):
         return obj.hostname
 
     def _workers(self, obj: Raw) -> Any:
-        apple_sys_msg = (
-            "On macOS, you cannot run more than one worker because SO_REUSEPORT socket option support is absent."
-        )
+        no_support_msg = "On this system, you cannot run more than one worker because SO_REUSEPORT/SO_REUSEPORT_LB socket option is not supported."
 
-        if APPLE_SYS and (int(obj.workers) > 1):
-            raise ValueError(apple_sys_msg)
+        workers_support = LINUX_SYS or FREEBSD_SYS
+        if not workers_support and (int(obj.workers) > 1):
+            raise ValueError(no_support_msg)
 
         if obj.workers == "auto":
-            if APPLE_SYS:
-                logger.info(f"Running on macOS, 'workers' configuration automatically set to 1. {apple_sys_msg}")
+            if not workers_support:
+                logger.info(
+                    "Running on system without support for multiple workers,"
+                    f"' workers' configuration automatically set to 1. {no_support_msg}"
+                )
                 return IntPositive(1)
 
             count = _cpu_count()
index be0335790a1f26e05567ecaee604d882afc394e5..f8c6607f2dca31edc22529c97a42a90c4432113b 100644 (file)
@@ -7,7 +7,7 @@ from secrets import token_hex
 from subprocess import SubprocessError
 from typing import Any, Callable, List, Optional
 
-from knot_resolver.constants import APPLE_SYS
+from knot_resolver.constants import FREEBSD_SYS, LINUX_SYS
 from knot_resolver.controller.exceptions import SubprocessControllerError
 from knot_resolver.controller.interface import Subprocess, SubprocessController, SubprocessStatus, SubprocessType
 from knot_resolver.controller.registered_workers import command_registered_workers, get_registered_workers_kresids
@@ -143,8 +143,9 @@ class KresManager:  # pylint: disable=too-many-instance-attributes
         # register callback to reset policy rules for each 'kresd' worker
         await config_store.register_on_change_callback(self.reset_workers_policy_rules)
 
-        # This is not necessary on Apple systems, as only one kresd worker runs here
-        if not APPLE_SYS:
+        # Only necessary on systems that allow multiple kresd workers
+        # TLS session secret synchronization across all workers
+        if LINUX_SYS or FREEBSD_SYS:
             # register and immediately call a callback to set new TLS session ticket secret for 'kresd' workers
             await config_store.register_on_change_callback(
                 only_on_real_changes_update(config_nodes)(self.set_new_tls_sticket_secret)