Multiple workers are supported only on Linux systems or FreeBSD with SO_REUSEPORT_LB socket option.
import importlib.util
-import sys
+import platform
from pathlib import Path
VERSION = "6.0.16"
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"):
import importlib.util
-import sys
+import platform
from pathlib import Path
VERSION = "@version@"
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"):
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
@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",
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
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()
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
# 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)