diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-11-11 13:56:54 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-11-11 14:29:10 +0100 |
commit | dbd6e31cf91ab86a4a2fffeb50ccef211da3126d (patch) | |
tree | 9f97ae27e0bf78cbb1b73260e4e88a8f2afc6eee | |
parent | 94b6551662e0db8eb09768ed70f77759f322b4c6 (diff) |
journalctl: make --rotate synchronous, too
Of course, ideally we'd just use normal synchronous bus calls, but this
is out of the question as long as we rely on dbus-daemon (which logs to
journald, and thus cannot use to avoid cyclic sync loops). Hence,
instead, reuse the wait logic already implemented for --sync, and use a
signal in one direction, and a mtime watch file for the reply.
-rw-r--r-- | man/journalctl.xml | 14 | ||||
-rw-r--r-- | src/journal/journalctl.c | 47 | ||||
-rw-r--r-- | src/journal/journald-server.c | 3 |
3 files changed, 27 insertions, 37 deletions
diff --git a/man/journalctl.xml b/man/journalctl.xml index 2160f3cba2..b57afb6ebf 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -775,12 +775,12 @@ <varlistentry> <term><option>--sync</option></term> - <listitem><para>Ask the journal daemon to write all yet + <listitem><para>Asks the journal daemon to write all yet unwritten journal data to the backing file system and synchronize all journals. This call does not return until the - operation is complete. This command guarantees that any log - messages written before its invocation are safely stored on - disk at the time it returns.</para></listitem> + synchronization operation is complete. This command guarantees + that any log messages written before its invocation are safely + stored on disk at the time it returns.</para></listitem> </varlistentry> <varlistentry> @@ -803,9 +803,11 @@ <varlistentry> <term><option>--rotate</option></term> - <listitem><para>Asks the journal daemon to rotate journal files. - </para></listitem> + <listitem><para>Asks the journal daemon to rotate journal + files. This call does not return until the rotation operation + is complete.</para></listitem> </varlistentry> + <xi:include href="standard-options.xml" xpointer="help" /> <xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="no-pager" /> diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 071349666c..521360b11b 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1822,31 +1822,7 @@ static int flush_to_var(void) { return 0; } -static int rotate(void) { - _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; - int r; - - r = bus_connect_system_systemd(&bus); - if (r < 0) - return log_error_errno(r, "Failed to get D-Bus connection: %m"); - - r = sd_bus_call_method( - bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "KillUnit", - &error, - NULL, - "ssi", "systemd-journald.service", "main", SIGUSR2); - if (r < 0) - return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r)); - - return 0; -} - -static int sync_journal(void) { +static int send_signal_and_wait(int sig, const char *watch_path) { _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; _cleanup_close_ int watch_fd = -1; usec_t start; @@ -1854,17 +1830,18 @@ static int sync_journal(void) { start = now(CLOCK_REALTIME); - /* Let's watch /run/systemd/sync until it's mtime is above - * the time we started the sync. Let's enqueue SIGRTMIN+1 to - * start the sync. */ + /* This call sends the specified signal to journald, and waits + * for acknowledgment by watching the mtime of the specified + * flag file. This is used to trigger syncing or rotation and + * then wait for the operation to complete. */ for (;;) { struct stat st; /* See if a sync happened by now. */ - if (stat("/run/systemd/journal/synced", &st) < 0) { + if (stat(watch_path, &st) < 0) { if (errno != ENOENT) - return log_error_errno(errno, "Failed to stat /run/systemd/journal/synced: %m"); + return log_error_errno(errno, "Failed to stat %s: %m", watch_path); } else { if (timespec_load(&st.st_mtim) >= start) return 0; @@ -1886,7 +1863,7 @@ static int sync_journal(void) { "KillUnit", &error, NULL, - "ssi", "systemd-journald.service", "main", SIGRTMIN+1); + "ssi", "systemd-journald.service", "main", sig); if (r < 0) return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r)); @@ -1925,6 +1902,14 @@ static int sync_journal(void) { return 0; } +static int rotate(void) { + return send_signal_and_wait(SIGUSR2, "/run/systemd/journal/rotated"); +} + +static int sync_journal(void) { + return send_signal_and_wait(SIGRTMIN+1, "/run/systemd/journal/synced"); +} + int main(int argc, char *argv[]) { int r; _cleanup_journal_close_ sd_journal *j = NULL; diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index f0a3c82d98..70ff101d5f 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1263,6 +1263,9 @@ static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo * server_rotate(s); server_vacuum(s, true, true); + /* Let clients know when the most recent rotation happened. */ + (void) touch("/run/systemd/journal/rotated"); + return 0; } |