From: Aleš Mrázek Date: Tue, 18 Nov 2025 14:08:15 +0000 (+0100) Subject: manager: added FreeBSD support X-Git-Tag: v6.0.17~4^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=59e0f9618b3ef44a3c97a75c1884adf6ab7855d7;p=thirdparty%2Fknot-resolver.git manager: added FreeBSD support Multiple workers are supported only on Linux systems or FreeBSD with SO_REUSEPORT_LB socket option. --- diff --git a/python/knot_resolver/constants.py b/python/knot_resolver/constants.py index fb12f5bd9..7cec351d5 100644 --- a/python/knot_resolver/constants.py +++ b/python/knot_resolver/constants.py @@ -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"): diff --git a/python/knot_resolver/constants.py.in b/python/knot_resolver/constants.py.in index ec1d26a26..ae66227a0 100644 --- a/python/knot_resolver/constants.py.in +++ b/python/knot_resolver/constants.py.in @@ -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"): diff --git a/python/knot_resolver/controller/supervisord/config_file.py b/python/knot_resolver/controller/supervisord/config_file.py index 9d02ba6cb..57c826157 100644 --- a/python/knot_resolver/controller/supervisord/config_file.py +++ b/python/knot_resolver/controller/supervisord/config_file.py @@ -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", diff --git a/python/knot_resolver/datamodel/config_schema.py b/python/knot_resolver/datamodel/config_schema.py index 760e3b16b..c4871def4 100644 --- a/python/knot_resolver/datamodel/config_schema.py +++ b/python/knot_resolver/datamodel/config_schema.py @@ -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() diff --git a/python/knot_resolver/manager/manager.py b/python/knot_resolver/manager/manager.py index be0335790..f8c6607f2 100644 --- a/python/knot_resolver/manager/manager.py +++ b/python/knot_resolver/manager/manager.py @@ -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)