]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
login: Add varlink socket unit
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 27 Jun 2025 14:18:23 +0000 (16:18 +0200)
committerDaanDeMeyer <daan.j.demeyer@gmail.com>
Thu, 3 Jul 2025 09:22:34 +0000 (11:22 +0200)
src/login/logind-varlink.c
src/login/logind-varlink.h
src/login/logind.c
units/meson.build
units/systemd-logind-varlink.socket [new file with mode: 0644]

index 40aa82f1f8f1ba1cef03cbb18826912b1524b191..757b4196fdf38ebdec526711b8fcf4472bc9c54b 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "alloc-util.h"
 #include "cgroup-util.h"
+#include "fd-util.h"
 #include "format-util.h"
 #include "hashmap.h"
 #include "json-util.h"
@@ -327,8 +328,9 @@ static int vl_method_release_session(sd_varlink *link, sd_json_variant *paramete
         return sd_varlink_reply(link, NULL);
 }
 
-int manager_varlink_init(Manager *m) {
+int manager_varlink_init(Manager *m, int fd) {
         _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
+        _unused_ _cleanup_close_ int fd_close = fd;
         int r;
 
         assert(m);
@@ -362,10 +364,15 @@ int manager_varlink_init(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to register varlink methods: %m");
 
-        r = sd_varlink_server_listen_address(s, "/run/systemd/io.systemd.Login", 0666);
+        if (fd < 0)
+                r = sd_varlink_server_listen_address(s, "/run/systemd/io.systemd.Login", /* mode= */ 0666);
+        else
+                r = sd_varlink_server_listen_fd(s, fd);
         if (r < 0)
                 return log_error_errno(r, "Failed to bind to varlink socket: %m");
 
+        TAKE_FD(fd_close);
+
         r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
         if (r < 0)
                 return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
index d99513d2103945fd6cddce377ca708bd883385d6..b6b74093a5912d892d666d774f1a7d2c39eb612a 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "logind-forward.h"
 
-int manager_varlink_init(Manager *m);
+int manager_varlink_init(Manager *m, int fd);
 void manager_varlink_done(Manager *m);
 
 int session_send_create_reply_varlink(Session *s, const sd_bus_error *error);
index adcf3065094bc036da7ee6898917d2693d97eb38..c5819101e537f43853b199f73a139838f9214f58 100644 (file)
@@ -525,9 +525,8 @@ fail_close:
 }
 
 static int manager_enumerate_sessions(Manager *m) {
-        _cleanup_strv_free_ char **fdnames = NULL;
         _cleanup_closedir_ DIR *d = NULL;
-        int r = 0, n;
+        int r = 0;
 
         assert(m);
 
@@ -560,6 +559,16 @@ static int manager_enumerate_sessions(Manager *m) {
                         RET_GATHER(r, log_warning_errno(k, "Failed to deserialize session '%s', ignoring: %m", s->id));
         }
 
+        return r;
+}
+
+static int manager_enumerate_fds(Manager *m, int *ret_varlink_fd) {
+        _cleanup_strv_free_ char **fdnames = NULL;
+        int varlink_fd = -EBADF, n, r = 0;
+
+        assert(m);
+        assert(ret_varlink_fd);
+
         n = sd_listen_fds_with_names(/* unset_environment = */ true, &fdnames);
         if (n < 0)
                 return log_error_errno(n, "Failed to acquire passed fd list: %m");
@@ -567,9 +576,18 @@ static int manager_enumerate_sessions(Manager *m) {
         for (int i = 0; i < n; i++) {
                 int fd = SD_LISTEN_FDS_START + i;
 
+                if (streq(fdnames[i], "varlink")) {
+                        assert(varlink_fd < 0);
+                        varlink_fd = fd;
+                        continue;
+                }
+
                 RET_GATHER(r, manager_attach_session_fd_one_consume(m, fdnames[i], fd));
         }
 
+        if (r >= 0)
+                *ret_varlink_fd = varlink_fd;
+
         return r;
 }
 
@@ -1171,6 +1189,7 @@ static int manager_dispatch_reload_signal(sd_event_source *s, const struct signa
 }
 
 static int manager_startup(Manager *m) {
+        _cleanup_close_ int varlink_fd = -EBADF;
         int r;
         Seat *seat;
         Session *session;
@@ -1202,10 +1221,6 @@ static int manager_startup(Manager *m) {
         if (r < 0)
                 return r;
 
-        r = manager_varlink_init(m);
-        if (r < 0)
-                return r;
-
         /* Instantiate magic seat 0 */
         r = manager_add_seat(m, "seat0", &m->seat0);
         if (r < 0)
@@ -1232,6 +1247,10 @@ static int manager_startup(Manager *m) {
         if (r < 0)
                 log_warning_errno(r, "Session enumeration failed: %m");
 
+        r = manager_enumerate_fds(m, &varlink_fd);
+        if (r < 0)
+                log_warning_errno(r, "File descriptor enumeration failed: %m");
+
         r = manager_enumerate_inhibitors(m);
         if (r < 0)
                 log_warning_errno(r, "Inhibitor enumeration failed: %m");
@@ -1240,6 +1259,10 @@ static int manager_startup(Manager *m) {
         if (r < 0)
                 log_warning_errno(r, "Button enumeration failed: %m");
 
+        r = manager_varlink_init(m, TAKE_FD(varlink_fd));
+        if (r < 0)
+                return r;
+
         manager_load_scheduled_shutdown(m);
 
         /* Remove stale objects before we start them */
index c595c1de5a3d39b87f21c62a4b32accdaa8550e3..3f3b047f3c11a9882ba99aa0e1595a0ce5d8ba12 100644 (file)
@@ -472,6 +472,11 @@ units = [
           'conditions' : ['ENABLE_LOCALED'],
           'symlinks' : ['dbus-org.freedesktop.locale1.service'],
         },
+        {
+          'file': 'systemd-logind-varlink.socket',
+          'conditions': ['ENABLE_LOGIND'],
+          'symlinks' : ['sockets.target.wants/'],
+        },
         {
           'file' : 'systemd-logind.service.in',
           'conditions' : ['ENABLE_LOGIND'],
diff --git a/units/systemd-logind-varlink.socket b/units/systemd-logind-varlink.socket
new file mode 100644 (file)
index 0000000..3978e8a
--- /dev/null
@@ -0,0 +1,18 @@
+#  SPDX-License-Identifier: LGPL-2.1-or-later
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=User Login Management Varlink Socket
+Documentation=man:systemd-logind.service(8)
+
+[Socket]
+ListenStream=/run/systemd/io.systemd.Login
+FileDescriptorName=varlink
+SocketMode=0666
+Service=systemd-logind.service