]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
allow multiple managers docs-develop-mult-8twxj2/deployments/6231
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 18 Feb 2025 14:23:45 +0000 (15:23 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 18 Feb 2025 14:23:45 +0000 (15:23 +0100)
This concerns the AF_UNIX socket for sd_notify() protocol
between supervisord and the individual kresd processes.
Before: "@knot-resolver-control-socket"
Now: "/the_rundir/supervisor-notify-socket"

Nits: also some refactoring (goto)

NEWS
python/knot_resolver/controller/supervisord/plugin/notifymodule.c
python/knot_resolver/controller/supervisord/plugin/sd_notify.py

diff --git a/NEWS b/NEWS
index 8f4de84b76794c4584d71f1fce828c8cbc3b9821..3e80bfb8461ad4c99b662af2fb19dbb22878abc0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,10 @@ Bugfixes
 - manager: fix processes watchdog errors during shutdown (!1651)
 - /cache/prefill/*/ca_file: fix setting this attribute (!1655)
 
+Improvements
+------------
+- manager: allow multiple instances with different rundirs (!1656)
+
 
 Knot Resolver 6.0.10 (2025-01-20)
 =================================
index d56ee7d2a81bdedfea607da3084f1f1ca0106ecc..7a1c5852c6a54cf36c023d6bbeca9b08d176dcf4 100644 (file)
@@ -15,7 +15,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
-#define CONTROL_SOCKET_NAME "knot-resolver-control-socket"
+#define CONTROL_SOCKET_NAME "supervisor-notify-socket"
 #define NOTIFY_SOCKET_NAME "NOTIFY_SOCKET"
 #define MODULE_NAME "notify"
 #define RECEIVE_BUFFER_SIZE 2048
@@ -26,36 +26,29 @@ static PyObject *init_control_socket(PyObject *self, PyObject *args)
 {
        /* create socket */
        int controlfd = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0);
-       if (controlfd == -1) {
-               PyErr_SetFromErrno(NotifySocketError);
-               return NULL;
-       }
+       if (controlfd == -1) goto fail_errno;
 
-       /* create address */
-       struct sockaddr_un server_addr;
-       bzero(&server_addr, sizeof(server_addr));
+       /* construct the address; sd_notify() requires that the path is absolute */
+       struct sockaddr_un server_addr = {0};
        server_addr.sun_family = AF_UNIX;
-       server_addr.sun_path[0] = '\0'; // mark it as abstract namespace socket
-       strcpy(server_addr.sun_path + 1, CONTROL_SOCKET_NAME);
-       size_t addr_len = offsetof(struct sockaddr_un, sun_path) +
-                         strlen(CONTROL_SOCKET_NAME) + 1;
-
-       /* bind to the address */
-       int res = bind(controlfd, (struct sockaddr *)&server_addr, addr_len);
-       if (res < 0) {
-               PyErr_SetFromErrno(NotifySocketError);
-               return NULL;
-       }
-
-       /* make sure that we are send credentials */
+       const size_t cwd_max = sizeof(server_addr) - offsetof(struct sockaddr_un, sun_path)
+               /* but we also need space for making the path longer: */
+               - 1/*slash*/ - strlen(CONTROL_SOCKET_NAME);
+       if (!getcwd(server_addr.sun_path, cwd_max))
+               goto fail_errno;
+       char *p = server_addr.sun_path + strlen(server_addr.sun_path);
+       *p = '/';
+       strcpy(p + 1, CONTROL_SOCKET_NAME);
+
+       /* overwrite the (pseudo-)file if it exists */
+       (void)unlink(CONTROL_SOCKET_NAME);
+       int res = bind(controlfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
+       if (res < 0) goto fail_errno;
+
+       /* make sure that we get credentials with messages */
        int data = (int)true;
-       res = setsockopt(controlfd, SOL_SOCKET, SO_PASSCRED, &data,
-                        sizeof(data));
-       if (res < 0) {
-               PyErr_SetFromErrno(NotifySocketError);
-               return NULL;
-       }
-
+       res = setsockopt(controlfd, SOL_SOCKET, SO_PASSCRED, &data, sizeof(data));
+       if (res < 0) goto fail_errno;
        /* store the name of the socket in env to fake systemd */
        char *old_value = getenv(NOTIFY_SOCKET_NAME);
        if (old_value != NULL) {
@@ -64,13 +57,13 @@ static PyObject *init_control_socket(PyObject *self, PyObject *args)
                // fixme
        }
 
-       res = setenv(NOTIFY_SOCKET_NAME, "@" CONTROL_SOCKET_NAME, 1);
-       if (res < 0) {
-               PyErr_SetFromErrno(NotifySocketError);
-               return NULL;
-       }
+       res = setenv(NOTIFY_SOCKET_NAME, server_addr.sun_path, 1);
+       if (res < 0) goto fail_errno;
 
        return PyLong_FromLong((long)controlfd);
+fail_errno:
+       PyErr_SetFromErrno(NotifySocketError);
+       return NULL;
 }
 
 static PyObject *handle_control_socket_connection_event(PyObject *self,
index 4894b6f7adb5af61aeac14e5a78fba50e7023f06..f1558d94d7bf486af3a0333a2d679b4438f182ac 100644 (file)
@@ -174,7 +174,7 @@ def supervisord_get_process_map(supervisord: Any, mp: Dict[Any, Any]) -> Dict[An
 
 def process_spawn_as_child_add_env(slf: Subprocess, *args: Any) -> Tuple[Any, ...]:
     if is_type_notify(slf):
-        slf.config.environment["NOTIFY_SOCKET"] = "@knot-resolver-control-socket"
+        slf.config.environment["NOTIFY_SOCKET"] = os.getcwd() + "/supervisor-notify-socket"
     return (slf, *args)