+Knot Resolver 2.0.0 (2018-xx-yy)
+================================
+Incompatible changes
+--------------------
+- script supervisor.py was removed, please migrate to a real process manager
+
Knot Resolver 1.5.1 (2017-1x-yy)
================================
$ kresd -v
+To run the daemon by hand, such as under ``nohup``, use ``-f 1`` to start a single fork. For example:
+
+.. code-block:: bash
+
+ $ nohup ./daemon/kresd -a 127.0.0.1 -f 1 -v &
+
+
Scaling out
===========
.. _daemon-reuseport:
-.. note:: On recent Linux supporting ``SO_REUSEPORT`` (since 3.9, backported to RHEL 2.6.32) it is also able to bind to the same endpoint and distribute the load between the forked processes. If your OS doesn't support it, you can :ref:`use supervisor <daemon-supervised>` that is going to bind to sockets before starting multiple processes.
+.. note:: On recent Linux supporting ``SO_REUSEPORT`` (since 3.9, backported to RHEL 2.6.32) it is also able to bind to the same endpoint and distribute the load between the forked processes. If your OS doesn't support it, use only one daemon process.
Notice the absence of an interactive CLI. You can attach to the the consoles for each process, they are in ``rundir/tty/PID``.
Knot Resolver can run under a supervisor to allow for graceful restarts, watchdog process and socket activation. This way the supervisor binds to sockets and lends them to the resolver daemon. If the resolver terminates or is killed, the sockets remain open and no queries are dropped.
-The watchdog process must notify kresd about active file descriptors, and kresd will automatically determine the socket type and bound address, thus it will appear as any other address. There's a tiny supervisor script for convenience, but you should have a look at `real process managers`_.
-
-.. code-block:: bash
-
- $ python scripts/supervisor.py ./daemon/kresd -a 127.0.0.1
- $ [system] interactive mode
- > quit()
- > [2016-03-28 16:06:36.795879] process finished, pid = 99342, status = 0, uptime = 0:00:01.720612
- [system] interactive mode
- >
+The watchdog process must notify kresd about active file descriptors, and kresd will automatically determine the socket type and bound address, thus it will appear as any other address. You should have a look at `real process managers`_.
The daemon also supports `systemd socket activation`_, it is automatically detected and requires no configuration on users's side.
-To run the daemon by hand, such as under ``nohup``, use ``-f 1`` to start a single fork. For example:
-
-.. code-block:: bash
-
- $ nohup ./daemon/kresd -a 127.0.0.1 -f 1 &
-
-
Configuration
=============
+++ /dev/null
-#!/usr/bin/env python
-#
-# This is an example of simple supervisor process owning bound sockets and
-# handing them over to supervised process, allowing for graceful restarts.
-#
-import time, datetime
-import socket
-import os, sys
-
-# Help
-def help():
- print('Usage: %s <bin> addr@port ...' % sys.argv[0])
- print('Example: python scripts/supervisor.py ./daemon/kresd -a 127.0.0.1')
- sys.exit(1)
-if len(sys.argv) < 3:
- help()
-# Bind to sockets
-args = []
-unparsed = sys.argv[1:]
-sockets = []
-while len(unparsed) > 0:
- tok = unparsed.pop(0)
- # Rewrite '-a' only, copy otherwise
- if tok != '-a':
- args.append(tok)
- continue
- # Parse address
- addr = unparsed.pop(0)
- try:
- if '@' in addr:
- addr, port = addr.split('@')
- port = int(port)
- elif '#' in addr:
- addr, port = addr.split('#')
- port = int(port)
- else:
- port = 53
- except: help()
- # Open TCP socket
- family = socket.AF_INET6 if ':' in addr else socket.AF_INET
- tcp = socket.socket(family, socket.SOCK_STREAM)
- tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- tcp.bind((addr, port))
- tcp.listen(16)
- sockets.append(tcp)
- # Open UDP socket
- udp = socket.socket(family, socket.SOCK_DGRAM)
- udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- udp.bind((addr, port))
- sockets.append(udp)
-args = args + ['-S %d' % s.fileno() for s in sockets]
-while True: # Fork forever
- pid = os.fork()
- if pid == 0:
- os.execv(args[0], args)
- else: # Wait for fork to die
- start = datetime.datetime.now()
- _, status = os.waitpid(pid, 0)
- end = datetime.datetime.now()
- print('[%s] process finished, pid = %d, status = %d, uptime = %s' % \
- (start, pid, status, end - start))
- time.sleep(0.5)