]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal: explicitly sync namespaced journals before stopping socket units
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 1 May 2024 21:18:52 +0000 (06:18 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 2 May 2024 17:41:01 +0000 (19:41 +0200)
Otherwise, if a service unit that requests LogNamespace= stopped before
systemd-journald@.service is started, logs generated by the service will be
lost, as systemd-journald@.socket is stopped and
systemd-journald@.service will never started.

To prevent the issue, let's introduce another implicit dependency to
a oneshot service that explicitly synchronizes a namespaced journal file
when the log namespace is not needed anymore.

Fixes #32604.

src/core/unit.c
units/meson.build
units/systemd-journald-sync@.service [new file with mode: 0644]

index c12ffeec273f2ae93000f0c16474e42d3e739147..b1ba47c9895da3661d5979b9694c75d075f1faec 100644 (file)
@@ -1311,21 +1311,33 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
          * is run first. */
 
         if (c->log_namespace) {
-                _cleanup_free_ char *socket_unit = NULL, *varlink_socket_unit = NULL;
+                _cleanup_free_ char *unit = NULL;
 
-                r = unit_name_build_from_type("systemd-journald", c->log_namespace, UNIT_SOCKET, &socket_unit);
+                r = unit_name_build_from_type("systemd-journald", c->log_namespace, UNIT_SOCKET, &unit);
                 if (r < 0)
                         return r;
 
-                r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, socket_unit, true, UNIT_DEPENDENCY_FILE);
+                r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, unit, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
 
-                r = unit_name_build_from_type("systemd-journald-varlink", c->log_namespace, UNIT_SOCKET, &varlink_socket_unit);
+                unit = mfree(unit);
+
+                r = unit_name_build_from_type("systemd-journald-varlink", c->log_namespace, UNIT_SOCKET, &unit);
+                if (r < 0)
+                        return r;
+
+                r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, unit, true, UNIT_DEPENDENCY_FILE);
+                if (r < 0)
+                        return r;
+
+                unit = mfree(unit);
+
+                r = unit_name_build_from_type("systemd-journald-sync", c->log_namespace, UNIT_SERVICE, &unit);
                 if (r < 0)
                         return r;
 
-                r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, varlink_socket_unit, true, UNIT_DEPENDENCY_FILE);
+                r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, unit, true, UNIT_DEPENDENCY_FILE);
                 if (r < 0)
                         return r;
         } else {
index 5b2410fe9321fb37747712420e63b4a0cf354bf8..b231341a1fb1af00416c176c1563671a11bd6ac5 100644 (file)
@@ -403,6 +403,7 @@ units = [
           'file' : 'systemd-journald-dev-log.socket',
           'symlinks' : ['sockets.target.wants/'],
         },
+        { 'file' : 'systemd-journald-sync@.service' },
         { 'file' : 'systemd-journald-varlink@.socket' },
         {
           'file' : 'systemd-journald.service.in',
diff --git a/units/systemd-journald-sync@.service b/units/systemd-journald-sync@.service
new file mode 100644 (file)
index 0000000..3eafcd0
--- /dev/null
@@ -0,0 +1,24 @@
+#  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=Sync Journal for Namespace %i
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+
+# At the time when journalctl in ExecStop= is invoked,
+# systemd-journald@.service may not be started yet. Hence, both socket
+# units must be active when journalctl is invoked.
+Requires=systemd-journald@%i.socket systemd-journald-varlink@%i.socket
+After=systemd-journald@%i.socket systemd-journald-varlink@%i.socket
+StopWhenUnneeded=yes
+
+[Service]
+ExecStop=journalctl --namespace=%i --sync
+Type=oneshot
+RemainAfterExit=yes