diff --git a/raddb/mods-available/linelog b/raddb/mods-available/linelog index e28a70d50e743..0f045d34f1360 100644 --- a/raddb/mods-available/linelog +++ b/raddb/mods-available/linelog @@ -159,6 +159,14 @@ linelog { # a limited range should set this to `yes`. # escape_filenames = no + + # + # fsync:: + # + # Synchronise data written with the file system after every + # write, returning fail when the operation fails. + # + fsync = no } # diff --git a/src/modules/rlm_linelog/rlm_linelog.c b/src/modules/rlm_linelog/rlm_linelog.c index 71fd2a96883e2..8afc73b70388d 100644 --- a/src/modules/rlm_linelog/rlm_linelog.c +++ b/src/modules/rlm_linelog/rlm_linelog.c @@ -121,6 +121,7 @@ typedef struct { gid_t group; //!< Resolved gid. exfile_t *ef; //!< Exclusive file access handle. bool escape; //!< Do filename escaping, yes / no. + bool fsync; //!< fsync after each write. } file; struct { @@ -143,6 +144,7 @@ static const conf_parser_t file_config[] = { { FR_CONF_OFFSET("permissions", rlm_linelog_t, file.permissions), .dflt = "0600" }, { FR_CONF_OFFSET("group", rlm_linelog_t, file.group_str) }, { FR_CONF_OFFSET("escape_filenames", rlm_linelog_t, file.escape), .dflt = "no" }, + { FR_CONF_OFFSET("fsync", rlm_linelog_t, file.fsync), .dflt = "no" }, CONF_PARSER_TERMINATOR }; @@ -436,6 +438,11 @@ static int linelog_write(rlm_linelog_t const *inst, linelog_call_env_t const *ca return -1; } + if (inst->file.fsync && (fsync(fd) < 0)) { + RERROR("Failed syncing \"%pV\" to persistent storage: %s", call_env->filename, fr_syserror(errno)); + exfile_close(inst->file.ef, fd); + return -1; + } } if (RDEBUG_ENABLED3) linelog_hexdump(request, vector_p, vector_len, "linelog data");