diff options
-rw-r--r-- | src/basic/fileio.c | 36 | ||||
-rw-r--r-- | src/basic/fileio.h | 4 | ||||
-rw-r--r-- | src/journal/journalctl.c | 18 | ||||
-rw-r--r-- | src/journal/journald-server.c | 16 |
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; } |