Merge branch 'fsync-shadow-files-before-rename' of https://github.com/awelzel/zeek

* 'fsync-shadow-files-before-rename' of https://github.com/awelzel/zeek:
  logging/writers/ascii: shadow files: Add fsync() before rename()
This commit is contained in:
Johanna Amann 2021-10-15 09:21:42 +01:00
commit 1b3b9a3cfc
5 changed files with 45 additions and 3 deletions

View file

@ -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 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) * Replace most uses of typedef with using for type aliasing (Tim Wojtulewicz, Corelight)

View file

@ -1 +1 @@
4.2.0-dev.255 4.2.0-dev.260

View file

@ -465,7 +465,7 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Fiel
if ( sfd < 0 ) 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; 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, ppf, strlen(ppf));
util::safe_write(sfd, "\n", 1); util::safe_write(sfd, "\n", 1);
util::safe_fsync(sfd);
util::safe_close(sfd); util::safe_close(sfd);
if ( rename(tmp_sfname.data(), sfname.data()) == -1 ) if ( rename(tmp_sfname.data(), sfname.data()) == -1 )

View file

@ -2162,6 +2162,36 @@ bool safe_pwrite(int fd, const unsigned char* data, size_t len, size_t offset)
return true; 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) void safe_close(int fd)
{ {
/* /*

View file

@ -461,6 +461,10 @@ extern bool safe_write(int fd, const char* data, int len);
// Same as safe_write(), but for pwrite(). // Same as safe_write(), but for pwrite().
extern bool safe_pwrite(int fd, const unsigned char* data, size_t len, size_t offset); 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. // Wraps close(2) to emit error messages and abort on unrecoverable errors.
extern void safe_close(int fd); extern void safe_close(int fd);