summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-11-11 13:56:54 +0100
committerLennart Poettering <lennart@poettering.net>2015-11-11 14:29:10 +0100
commitdbd6e31cf91ab86a4a2fffeb50ccef211da3126d (patch)
tree9f97ae27e0bf78cbb1b73260e4e88a8f2afc6eee
parent94b6551662e0db8eb09768ed70f77759f322b4c6 (diff)
downloadsystemd-dbd6e31cf91ab86a4a2fffeb50ccef211da3126d.tar.gz
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.xml14
-rw-r--r--src/journal/journalctl.c47
-rw-r--r--src/journal/journald-server.c3
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;
}