dovecot-2.2: rawlog: Buffer writing to rawlog files to improve p...

dovecot at dovecot.org dovecot at dovecot.org
Tue Jun 10 14:41:55 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/c8efc101826b
changeset: 17452:c8efc101826b
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jun 10 16:40:46 2014 +0200
description:
rawlog: Buffer writing to rawlog files to improve performance.

diffstat:

 src/util/rawlog.c |  99 +++++++++++++++++++++++++-----------------------------
 1 files changed, 46 insertions(+), 53 deletions(-)

diffs (178 lines):

diff -r 7b25994a8cb7 -r c8efc101826b src/util/rawlog.c
--- a/src/util/rawlog.c	Mon Jun 09 23:08:18 2014 +0300
+++ b/src/util/rawlog.c	Tue Jun 10 16:40:46 2014 +0200
@@ -36,20 +36,28 @@
 	struct io *client_io, *server_io;
 	struct ostream *client_output, *server_output;
 
-	int fd_in, fd_out;
+	struct ostream *in_output, *out_output;
 	enum rawlog_flags flags;
 	bool prev_lf_in, prev_lf_out;
 };
 
 static void rawlog_proxy_destroy(struct rawlog_proxy *proxy)
 {
-	if (proxy->fd_in != -1) {
-		if (close(proxy->fd_in) < 0)
-			i_error("close(in) failed: %m");
+	if (proxy->in_output != NULL) {
+		o_stream_uncork(proxy->in_output);
+		if (o_stream_nfinish(proxy->in_output) < 0) {
+			i_error("write(in) failed: %s",
+				o_stream_get_error(proxy->in_output));
+		}
+		o_stream_destroy(&proxy->in_output);
 	}
-	if (proxy->fd_out != -1) {
-		if (close(proxy->fd_out) < 0)
-			i_error("close(out) failed: %m");
+	if (proxy->out_output != NULL) {
+		o_stream_uncork(proxy->out_output);
+		if (o_stream_nfinish(proxy->out_output) < 0) {
+			i_error("write(out) failed: %s",
+				o_stream_get_error(proxy->out_output));
+		}
+		o_stream_destroy(&proxy->out_output);
 	}
 	if (proxy->client_io != NULL)
 		io_remove(&proxy->client_io);
@@ -70,12 +78,10 @@
 	io_loop_stop(ioloop);
 }
 
-static int
-write_with_timestamps(int fd, bool *prev_lf,
+static void
+write_with_timestamps(struct ostream *output, bool *prev_lf,
 		      const unsigned char *data, size_t size)
 {
-	int ret;
-
 	T_BEGIN {
 		const char *timestamp = t_strdup_printf("%ld.%06lu ",
 			(long)ioloop_timeval.tv_sec,
@@ -92,57 +98,40 @@
 				str_append(str, timestamp);
 		}
 		*prev_lf = data[i-1] == '\n';
-		ret = write_full(fd, str_data(str), str_len(str));
+		o_stream_nsend(output, str_data(str), str_len(str));
 	} T_END;
-	return ret;
 }
 
-static int proxy_write_data(struct rawlog_proxy *proxy, int fd,
-			    bool *prev_lf, const void *data, size_t size)
+static void proxy_write_data(struct rawlog_proxy *proxy, struct ostream *output,
+			     bool *prev_lf, const void *data, size_t size)
 {
-	if (fd == -1 || size == 0)
-		return 0;
+	if (output == NULL || output->closed || size == 0)
+		return;
 
-	if ((proxy->flags & RAWLOG_FLAG_LOG_BOUNDARIES) != 0) {
-		if (write_full(fd, "<<<\n", 4) < 0)
-			return -1;
-	}
+	if ((proxy->flags & RAWLOG_FLAG_LOG_BOUNDARIES) != 0)
+		o_stream_nsend_str(output, "<<<\n");
 
-	if ((proxy->flags & RAWLOG_FLAG_LOG_TIMESTAMPS) != 0) {
-		if (write_with_timestamps(fd, prev_lf, data, size) < 0)
-			return -1;
-	} else {
-		if (write_full(fd, data, size) < 0)
-			return -1;
-	}
+	if ((proxy->flags & RAWLOG_FLAG_LOG_TIMESTAMPS) != 0)
+		write_with_timestamps(output, prev_lf, data, size);
+	else
+		o_stream_nsend(output, data, size);
 
-	if ((proxy->flags & RAWLOG_FLAG_LOG_BOUNDARIES) != 0) {
-		if (write_full(fd, ">>>\n", 4) < 0)
-			return -1;
-	}
-	return 0;
+	if ((proxy->flags & RAWLOG_FLAG_LOG_BOUNDARIES) != 0)
+		o_stream_nsend_str(output, ">>>\n");
 }
 
 static void proxy_write_in(struct rawlog_proxy *proxy,
 			   const void *data, size_t size)
 {
-	if (proxy_write_data(proxy, proxy->fd_in, &proxy->prev_lf_in,
-			     data, size) < 0) {
-		/* failed, disable logging */
-		i_error("write(in) failed: %m");
-		i_close_fd(&proxy->fd_in);
-	}
+	proxy_write_data(proxy, proxy->in_output, &proxy->prev_lf_in,
+			 data, size);
 }
 
 static void proxy_write_out(struct rawlog_proxy *proxy,
 			    const void *data, size_t size)
 {
-	if (proxy_write_data(proxy, proxy->fd_out, &proxy->prev_lf_out,
-			     data, size) < 0) {
-		/* failed, disable logging */
-		i_error("write(out) failed: %m");
-		i_close_fd(&proxy->fd_out);
-	}
+	proxy_write_data(proxy, proxy->out_output, &proxy->prev_lf_out,
+			 data, size);
 }
 
 static void server_input(struct rawlog_proxy *proxy)
@@ -226,28 +215,33 @@
 static void proxy_open_logs(struct rawlog_proxy *proxy, const char *path)
 {
 	const char *fname, *timestamp;
+	int fd;
 
 	timestamp = t_strflocaltime("%Y%m%d-%H%M%S", time(NULL));
 
 	if ((proxy->flags & RAWLOG_FLAG_LOG_INPUT) != 0) {
 		fname = t_strdup_printf("%s/%s-%s.in", path, timestamp,
 					dec2str(getpid()));
-		proxy->fd_in = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600);
-		if (proxy->fd_in == -1) {
-			i_error("rawlog_open: open() failed for %s: %m", fname);
+		fd = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600);
+		if (fd == -1) {
+			i_error("rawlog_open: creat(%s): %m", fname);
 			return;
 		}
+		proxy->in_output = o_stream_create_fd_file(fd, 0, TRUE);
+		o_stream_cork(proxy->in_output);
 	}
 
 	if ((proxy->flags & RAWLOG_FLAG_LOG_OUTPUT) != 0) {
 		fname = t_strdup_printf("%s/%s-%s.out", path, timestamp,
 					dec2str(getpid()));
-		proxy->fd_out = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600);
-		if (proxy->fd_out == -1) {
-			i_error("rawlog_open: open() failed for %s: %m", fname);
-			i_close_fd(&proxy->fd_in);
+		fd = open(fname, O_CREAT|O_EXCL|O_WRONLY, 0600);
+		if (fd == -1) {
+			i_error("rawlog_open: creat(%s): %m", fname);
+			o_stream_destroy(&proxy->in_output);
 			return;
 		}
+		proxy->out_output = o_stream_create_fd_file(fd, 0, TRUE);
+		o_stream_cork(proxy->out_output);
 	}
 }
 
@@ -279,7 +273,6 @@
 	proxy->flags = flags;
 
 	proxy->prev_lf_in = proxy->prev_lf_out = TRUE;
-	proxy->fd_in = proxy->fd_out = -1;
 	proxy_open_logs(proxy, path);
 	return proxy;
 }


More information about the dovecot-cvs mailing list