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.
This commit is contained in:
Lennart Poettering 2015-11-11 13:56:54 +01:00
parent 94b6551662
commit dbd6e31cf9
3 changed files with 27 additions and 37 deletions

View File

@ -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" />

View File

@ -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;

View File

@ -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;
}