dovecot: If Dovecot master dies with a fatal failure, log the er...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Feb 11 20:47:49 EET 2008
details: http://hg.dovecot.org/dovecot/rev/586abf9b561c
changeset: 7229:586abf9b561c
user: Timo Sirainen <tss at iki.fi>
date: Mon Feb 11 20:47:45 2008 +0200
description:
If Dovecot master dies with a fatal failure, log the error message to a file
in base_dir. If the file exists at startup, show its contents and a comment
about looking at error logs why it happened. Hopefully this will reduce "why
Dovecot died without a reason?" questions.
diffstat:
1 file changed, 55 insertions(+)
src/master/main.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
diffs (86 lines):
diff -r 45a083e03fba -r 586abf9b561c src/master/main.c
--- a/src/master/main.c Mon Feb 11 20:44:23 2008 +0200
+++ b/src/master/main.c Mon Feb 11 20:47:45 2008 +0200
@@ -32,6 +32,8 @@
higher, it's not dropped. */
#define DOVECOT_MASTER_FD_MIN_LIMIT 65536
+#define FATAL_FILENAME "master-fatal.lastlog"
+
static const char *configfile = SYSCONFDIR "/" PACKAGE ".conf";
struct ioloop *ioloop;
@@ -44,6 +46,57 @@ bool gdb;
bool gdb;
#endif
+static void ATTR_NORETURN ATTR_FORMAT(3, 0)
+master_fatal_callback(enum log_type type, int status,
+ const char *format, va_list args)
+{
+ const struct settings *set = settings_root->defaults;
+ const char *path, *str;
+ int fd;
+
+ /* write the error message to a file */
+ path = t_strconcat(set->base_dir, "/"FATAL_FILENAME, NULL);
+ fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
+ if (fd != -1) {
+ str = t_strdup_vprintf(format, args);
+ write_full(fd, str, strlen(str));
+ (void)close(fd);
+ }
+
+ /* write it to log as well */
+ if (*set->log_path == '\0')
+ i_syslog_fatal_handler(type, status, format, args);
+ else
+ default_fatal_handler(type, status, format, args);
+}
+
+static void fatal_log_check(void)
+{
+ const struct settings *set = settings_root->defaults;
+ const char *path;
+ char buf[1024];
+ ssize_t ret;
+ int fd;
+
+ path = t_strconcat(set->base_dir, "/"FATAL_FILENAME, NULL);
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return;
+
+ ret = read(fd, buf, sizeof(buf));
+ if (ret < 0)
+ i_error("read(%s) failed: %m", path);
+ else {
+ buf[ret] = '\0';
+ i_warning("Last died with error (see error log for more "
+ "information): %s", buf);
+ }
+
+ close(fd);
+ if (unlink(path) < 0)
+ i_error("unlink(%s) failed: %m", path);
+}
+
static void set_logfile(struct settings *set)
{
int facility;
@@ -57,6 +110,7 @@ static void set_logfile(struct settings
/* log to file or stderr */
i_set_failure_file(set->log_path, "dovecot: ");
}
+ i_set_fatal_handler(master_fatal_callback);
if (*set->info_log_path != '\0')
i_set_info_file(set->info_log_path);
@@ -492,6 +546,7 @@ int main(int argc, char *argv[])
if (!log_error)
open_fds();
+ fatal_log_check();
if (!foreground)
daemonize(settings_root->defaults);
More information about the dovecot-cvs
mailing list