summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/fileio.c36
-rw-r--r--src/basic/fileio.h4
-rw-r--r--src/journal/journalctl.c18
-rw-r--r--src/journal/journald-server.c16
4 files changed, 61 insertions, 13 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 619dafb517..be6e327690 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -28,8 +28,10 @@
#include "fileio.h"
#include "fs-util.h"
#include "hexdecoct.h"
+#include "parse-util.h"
#include "path-util.h"
#include "random-util.h"
+#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "umask-util.h"
@@ -1149,3 +1151,37 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
*ret = path_kill_slashes(t);
return 0;
}
+
+int write_timestamp_file_atomic(const char *fn, usec_t n) {
+ char ln[DECIMAL_STR_MAX(n)+2];
+
+ /* Creates a "timestamp" file, that contains nothing but a
+ * usec_t timestamp, formatted in ASCII. */
+
+ if (n <= 0 || n >= USEC_INFINITY)
+ return -ERANGE;
+
+ xsprintf(ln, USEC_FMT "\n", n);
+
+ return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
+}
+
+int read_timestamp_file(const char *fn, usec_t *ret) {
+ _cleanup_free_ char *ln = NULL;
+ uint64_t t;
+ int r;
+
+ r = read_one_line_file(fn, &ln);
+ if (r < 0)
+ return r;
+
+ r = safe_atou64(ln, &t);
+ if (r < 0)
+ return r;
+
+ if (t <= 0 || t >= (uint64_t) USEC_INFINITY)
+ return -ERANGE;
+
+ *ret = (usec_t) t;
+ return 0;
+}
diff --git a/src/basic/fileio.h b/src/basic/fileio.h
index fa7f192331..5f2c941498 100644
--- a/src/basic/fileio.h
+++ b/src/basic/fileio.h
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include "macro.h"
+#include "time-util.h"
typedef enum {
WRITE_STRING_FILE_CREATE = 1,
@@ -77,3 +78,6 @@ int open_tmpfile(const char *path, int flags);
int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
int tempfn_random(const char *p, const char *extra, char **ret);
int tempfn_random_child(const char *p, const char *extra, char **ret);
+
+int write_timestamp_file_atomic(const char *fn, usec_t n);
+int read_timestamp_file(const char *fn, usec_t *ret);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index ac0751c547..75a48c761c 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -1838,7 +1838,7 @@ static int send_signal_and_wait(int sig, const char *watch_path) {
return -EOPNOTSUPP;
}
- start = now(CLOCK_REALTIME);
+ start = now(CLOCK_MONOTONIC);
/* This call sends the specified signal to journald, and waits
* for acknowledgment by watching the mtime of the specified
@@ -1846,16 +1846,14 @@ static int send_signal_and_wait(int sig, const char *watch_path) {
* then wait for the operation to complete. */
for (;;) {
- struct stat st;
+ usec_t tstamp;
/* See if a sync happened by now. */
- if (stat(watch_path, &st) < 0) {
- if (errno != ENOENT)
- return log_error_errno(errno, "Failed to stat %s: %m", watch_path);
- } else {
- if (timespec_load(&st.st_mtim) >= start)
- return 0;
- }
+ r = read_timestamp_file(watch_path, &tstamp);
+ if (r < 0 && r != -ENOENT)
+ return log_error_errno(errno, "Failed to read %s: %m", watch_path);
+ if (r >= 0 && tstamp >= start)
+ return 0;
/* Let's ask for a sync, but only once. */
if (!bus) {
@@ -1889,7 +1887,7 @@ static int send_signal_and_wait(int sig, const char *watch_path) {
if (watch_fd < 0)
return log_error_errno(errno, "Failed to create inotify watch: %m");
- r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_ATTRIB|IN_DONT_FOLLOW|IN_ONLYDIR);
+ r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_MOVED_TO|IN_DONT_FOLLOW|IN_ONLYDIR);
if (r < 0)
return log_error_errno(errno, "Failed to watch journal directory: %m");
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 70ff101d5f..762b810109 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -41,6 +41,7 @@
#include "dirent-util.h"
#include "extract-word.h"
#include "fd-util.h"
+#include "fileio.h"
#include "formats-util.h"
#include "fs-util.h"
#include "hashmap.h"
@@ -1240,6 +1241,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void
static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
Server *s = userdata;
+ int r;
assert(s);
@@ -1249,13 +1251,16 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *
server_sync(s);
server_vacuum(s, false, false);
- (void) touch("/run/systemd/journal/flushed");
+ r = touch("/run/systemd/journal/flushed");
+ if (r < 0)
+ log_warning_errno(r, "Failed to touch /run/systemd/journal/flushed, ignoring: %m");
return 0;
}
static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
Server *s = userdata;
+ int r;
assert(s);
@@ -1264,7 +1269,9 @@ static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *
server_vacuum(s, true, true);
/* Let clients know when the most recent rotation happened. */
- (void) touch("/run/systemd/journal/rotated");
+ r = write_timestamp_file_atomic("/run/systemd/journal/rotated", now(CLOCK_MONOTONIC));
+ if (r < 0)
+ log_warning_errno(r, "Failed to write /run/systemd/journal/rotated, ignoring: %m");
return 0;
}
@@ -1282,6 +1289,7 @@ static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *
static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
Server *s = userdata;
+ int r;
assert(s);
@@ -1290,7 +1298,9 @@ static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo
server_sync(s);
/* Let clients know when the most recent sync happened. */
- (void) touch("/run/systemd/journal/synced");
+ r = write_timestamp_file_atomic("/run/systemd/journal/synced", now(CLOCK_MONOTONIC));
+ if (r < 0)
+ log_warning_errno(r, "Failed to write /run/systemd/journal/synced, ignoring: %m");
return 0;
}