diff --git a/CHANGES b/CHANGES index d438502f84..3bceefbd05 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +4.2.0-dev.260 | 2021-10-15 09:45:45 +0100 + + * logging/writers/ascii: shadow files: Add fsync() before rename(). This + prevents potential problems with leftover files after unclean shutdowns. + (Arne Welzel, Corelight) + + * Fix typo in typedef changes that broke tests on 32-bit Debian 9 (Tim Wojtulewicz, Corelight) + 4.2.0-dev.255 | 2021-10-12 09:22:37 -0700 * Replace most uses of typedef with using for type aliasing (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index 73f4da94cb..f8979b0c9b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.2.0-dev.255 +4.2.0-dev.260 diff --git a/src/logging/writers/ascii/Ascii.cc b/src/logging/writers/ascii/Ascii.cc index a53464f925..d70e23db99 100644 --- a/src/logging/writers/ascii/Ascii.cc +++ b/src/logging/writers/ascii/Ascii.cc @@ -465,7 +465,7 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Fiel if ( sfd < 0 ) { - Error(Fmt("cannot open %s: %s", sfname.data(), Strerror(errno))); + Error(Fmt("cannot open %s: %s", tmp_sfname.data(), Strerror(errno))); return false; } @@ -478,7 +478,7 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Fiel util::safe_write(sfd, ppf, strlen(ppf)); util::safe_write(sfd, "\n", 1); - + util::safe_fsync(sfd); util::safe_close(sfd); if ( rename(tmp_sfname.data(), sfname.data()) == -1 ) diff --git a/src/util.cc b/src/util.cc index cfa612a864..d36161b7e0 100644 --- a/src/util.cc +++ b/src/util.cc @@ -2162,6 +2162,36 @@ bool safe_pwrite(int fd, const unsigned char* data, size_t len, size_t offset) return true; } +bool safe_fsync(int fd) + { + int r; + + /* + * Failure cases of fsync(2) are EABDF, EINTR, ENOSPC, EROFS, EINVAL, EDQUOT. + * + * For EINTR, one can just retry until it is not interrupted. For the others + * we report an error. + * + * Note that we don't use the reporter here to allow use from different threads. + */ + do + { + r = fsync(fd); + } while ( r < 0 && errno == EINTR ); + + if ( r < 0 ) + { + char buf[128]; + zeek_strerror_r(errno, buf, sizeof(buf)); + fprintf(stderr, "safe_fsync error %d: %s\n", errno, buf); + abort(); + + return false; + } + + return true; + } + void safe_close(int fd) { /* diff --git a/src/util.h b/src/util.h index fa07f585a7..5126dca59a 100644 --- a/src/util.h +++ b/src/util.h @@ -461,6 +461,10 @@ extern bool safe_write(int fd, const char* data, int len); // Same as safe_write(), but for pwrite(). extern bool safe_pwrite(int fd, const unsigned char* data, size_t len, size_t offset); +// Like fsync() but handles interrupted system calls by retrying and +// aborts on unrecoverable errors. +extern bool safe_fsync(int fd); + // Wraps close(2) to emit error messages and abort on unrecoverable errors. extern void safe_close(int fd);