]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journald: Retry if posix_fallocate returned -1 (EINTR)
authorIgor Zhbanov <i.zhbanov@omprussia.ru>
Tue, 20 Apr 2021 17:22:28 +0000 (17:22 +0000)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 21 Apr 2021 21:08:35 +0000 (23:08 +0200)
On some conditions (particularly when mobile CPUs are going to sleep),
the posix_fallocate(), which is called when a new journal file is allocated,
can return -1 (EINTR). This is counted as a fatal error. So the journald
closes both old and journals, and simply throwing away further incoming
events, because of no log files open.

Introduce posix_fallocate_loop() that restarts the function in the case
of EINTR. Also let's make code base more uniform by returning negative
values on error.

Fix assert in test-sigbus.c that incorrectly counted positive values as
success. After changing the function return values, that will actually work.

Fixes: #19041
Signed-off-by: Igor Zhbanov <i.zhbanov@omprussia.ru>
src/basic/fs-util.c
src/basic/fs-util.h
src/journal/journald-kmsg.c
src/libsystemd/sd-journal/journal-file.c
src/test/test-sigbus.c

index b2a4e8036f8d3653a7e69e61e769f5bfc36f5f35..46d6f7780e18941b08487dfdd252d580afcb2e47 100644 (file)
@@ -24,6 +24,7 @@
 #include "path-util.h"
 #include "process-util.h"
 #include "random-util.h"
+#include "ratelimit.h"
 #include "stat-util.h"
 #include "stdio-util.h"
 #include "string-util.h"
@@ -1715,3 +1716,23 @@ do_rename:
 
         return 1;
 }
+
+int posix_fallocate_loop(int fd, uint64_t offset, uint64_t size) {
+        RateLimit rl;
+        int r;
+
+        r = posix_fallocate(fd, offset, size); /* returns positive errnos on error */
+        if (r != EINTR)
+                return -r; /* Let's return negative errnos, like common in our codebase */
+
+        /* On EINTR try a couple of times more, but protect against busy looping
+         * (not more than 16 times per 10s) */
+        rl = (RateLimit) { 10 * USEC_PER_SEC, 16 };
+        while (ratelimit_below(&rl)) {
+                r = posix_fallocate(fd, offset, size);
+                if (r != EINTR)
+                        return -r;
+        }
+
+        return -EINTR;
+}
index 45115fd3db18581fc2dbb6863ab7b7f452b91da2..027037f7a724ac22d482b5595a1fee40cff2bebc 100644 (file)
@@ -146,3 +146,5 @@ int conservative_renameat(int olddirfd, const char *oldpath, int newdirfd, const
 static inline int conservative_rename(const char *oldpath, const char *newpath) {
         return conservative_renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath);
 }
+
+int posix_fallocate_loop(int fd, uint64_t offset, uint64_t size);
index 29b8437fe29169bf2527d43eb105c2f8104dc55e..c96b84e61f841c8d7314d1a61b41a7d70e9a3692 100644 (file)
@@ -14,6 +14,7 @@
 #include "escape.h"
 #include "fd-util.h"
 #include "format-util.h"
+#include "fs-util.h"
 #include "io-util.h"
 #include "journald-kmsg.h"
 #include "journald-server.h"
@@ -436,8 +437,8 @@ int server_open_kernel_seqnum(Server *s) {
                 return 0;
         }
 
-        r = posix_fallocate(fd, 0, sizeof(uint64_t));
-        if (r != 0) {
+        r = posix_fallocate_loop(fd, 0, sizeof(uint64_t));
+        if (r < 0) {
                 log_error_errno(r, "Failed to allocate sequential number file, ignoring: %m");
                 return 0;
         }
index f8bb708e582bbbfb5e4bac582708b65b099e02d3..3cf26f8e44353659e0039e38b9b3c73c5db478a4 100644 (file)
@@ -707,9 +707,9 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
         /* Note that the glibc fallocate() fallback is very
            inefficient, hence we try to minimize the allocation area
            as we can. */
-        r = posix_fallocate(f->fd, old_size, new_size - old_size);
-        if (r != 0)
-                return -r;
+        r = posix_fallocate_loop(f->fd, old_size, new_size - old_size);
+        if (r < 0)
+                return r;
 
         f->header->arena_size = htole64(new_size - old_header_size);
 
index d141735320a2f3a169b1a9a94f5610ea8c48656a..5262947c087e450202ebd73756f8231ccee0be5f 100644 (file)
@@ -9,6 +9,7 @@
 #endif
 
 #include "fd-util.h"
+#include "fs-util.h"
 #include "memory-util.h"
 #include "sigbus.h"
 #include "tests.h"
@@ -35,7 +36,7 @@ int main(int argc, char *argv[]) {
 
         assert_se((fd = mkostemp(template, O_RDWR|O_CREAT|O_EXCL)) >= 0);
         assert_se(unlink(template) >= 0);
-        assert_se(posix_fallocate(fd, 0, page_size() * 8) >= 0);
+        assert_se(posix_fallocate_loop(fd, 0, page_size() * 8) >= 0);
 
         p = mmap(NULL, page_size() * 16, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
         assert_se(p != MAP_FAILED);