dovecot-2.2: dsync: Use iostreams instead of fd when receiving c...

dovecot at dovecot.org dovecot at dovecot.org
Mon Feb 25 14:00:21 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/1841a4b95783
changeset: 15929:1841a4b95783
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Feb 25 14:00:10 2013 +0200
description:
dsync: Use iostreams instead of fd when receiving connection from doveadm-server.

diffstat:

 src/doveadm/dsync/doveadm-dsync.c |  53 ++++++++++++++++++++------------------
 src/doveadm/server-connection.c   |  25 +++++++++++++----
 src/doveadm/server-connection.h   |   6 +++-
 3 files changed, 52 insertions(+), 32 deletions(-)

diffs (149 lines):

diff -r 217fb4ca9b5a -r 1841a4b95783 src/doveadm/dsync/doveadm-dsync.c
--- a/src/doveadm/dsync/doveadm-dsync.c	Mon Feb 25 13:00:40 2013 +0200
+++ b/src/doveadm/dsync/doveadm-dsync.c	Mon Feb 25 14:00:10 2013 +0200
@@ -55,7 +55,8 @@
 
 	int fd_in, fd_out, fd_err;
 	struct io *io_err;
-	struct istream *err_stream;
+	struct istream *input, *err_stream;
+	struct ostream *output;
 
 	enum dsync_run_type run_type;
 	struct server_connection *tcp_conn;
@@ -404,17 +405,21 @@
 cmd_dsync_icb_stream_init(struct dsync_cmd_context *ctx,
 			  const char *name, const char *temp_prefix)
 {
-	struct istream *input;
-	struct ostream *output;
-
-	fd_set_nonblock(ctx->fd_in, TRUE);
-	fd_set_nonblock(ctx->fd_out, TRUE);
-
-	input = i_stream_create_fd(ctx->fd_in, (size_t)-1, FALSE);
-	output = o_stream_create_fd(ctx->fd_out, (size_t)-1, FALSE);
-	if (ctx->rawlog_path != NULL)
-		iostream_rawlog_create_path(ctx->rawlog_path, &input, &output);
-	return dsync_ibc_init_stream(input, output, name, temp_prefix);
+	if (ctx->input == NULL) {
+		fd_set_nonblock(ctx->fd_in, TRUE);
+		fd_set_nonblock(ctx->fd_out, TRUE);
+		ctx->input = i_stream_create_fd(ctx->fd_in, (size_t)-1, FALSE);
+		ctx->output = o_stream_create_fd(ctx->fd_out, (size_t)-1, FALSE);
+	} else {
+		i_stream_ref(ctx->input);
+		o_stream_ref(ctx->output);
+	}
+	if (ctx->rawlog_path != NULL) {
+		iostream_rawlog_create_path(ctx->rawlog_path,
+					    &ctx->input, &ctx->output);
+	}
+	return dsync_ibc_init_stream(ctx->input, ctx->output,
+				     name, temp_prefix);
 }
 
 static int
@@ -523,10 +528,9 @@
 		ctx->error = "Failed to start dsync-server command";
 		break;
 	case SERVER_CMD_REPLY_OK:
-		ctx->fd_in = ctx->fd_out =
-			dup(server_connection_get_fd(ctx->tcp_conn));
-		if (ctx->fd_in == -1)
-			ctx->error = t_strdup_printf("dup() failed: %m");
+		server_connection_extract(ctx->tcp_conn, &ctx->input,
+					  &ctx->output);
+		ctx->fd_in = ctx->fd_out = -1;
 		break;
 	case SERVER_CMD_REPLY_INTERNAL_FAILURE:
 		ctx->error = "Disconnected from remote";
@@ -786,15 +790,10 @@
 	if (_ctx->conn != NULL) {
 		/* doveadm-server connection. start with a success reply.
 		   after that follows the regular dsync protocol. */
-		ctx->fd_in = _ctx->conn->fd;
-		ctx->fd_out = _ctx->conn->fd;
-		if (write_full(ctx->fd_out, "\n+\n", 3) < 0) {
-			i_error("write(initial reply) failed: %m");
-			return -1;
-		}
-		/* make sure nothing more is written by the generic doveadm
-		   connection code */
-		o_stream_close(_ctx->conn->output);
+		ctx->fd_in = ctx->fd_out = -1;
+		ctx->input = _ctx->conn->input;
+		ctx->output = _ctx->conn->output;
+		o_stream_nsend(ctx->output, "\n+\n", 3);
 	}
 
 	user->admin = TRUE;
@@ -814,6 +813,10 @@
 		_ctx->exit_code = EX_TEMPFAIL;
 	dsync_ibc_deinit(&ibc);
 
+	/* make sure nothing more is written by the generic doveadm
+	   connection code */
+	o_stream_close(_ctx->conn->output);
+
 	return _ctx->exit_code == 0 ? 0 : -1;
 }
 
diff -r 217fb4ca9b5a -r 1841a4b95783 src/doveadm/server-connection.c
--- a/src/doveadm/server-connection.c	Mon Feb 25 13:00:40 2013 +0200
+++ b/src/doveadm/server-connection.c	Mon Feb 25 14:00:10 2013 +0200
@@ -366,12 +366,16 @@
 	if (printing_conn == conn)
 		print_connection_released();
 
-	i_stream_destroy(&conn->input);
-	o_stream_destroy(&conn->output);
+	if (conn->input != NULL)
+		i_stream_destroy(&conn->input);
+	if (conn->output != NULL)
+		o_stream_destroy(&conn->output);
 	if (conn->io != NULL)
 		io_remove(&conn->io);
-	if (close(conn->fd) < 0)
-		i_error("close(server) failed: %m");
+	if (conn->fd != -1) {
+		if (close(conn->fd) < 0)
+			i_error("close(server) failed: %m");
+	}
 	pool_unref(&conn->pool);
 }
 
@@ -400,7 +404,16 @@
 	return conn->callback == NULL;
 }
 
-int server_connection_get_fd(struct server_connection *conn)
+void server_connection_extract(struct server_connection *conn,
+			       struct istream **istream_r,
+			       struct ostream **ostream_r)
 {
-	return conn->fd;
+	*istream_r = conn->input;
+	*ostream_r = conn->output;
+
+	conn->input = NULL;
+	conn->output = NULL;
+	if (conn->io != NULL)
+		io_remove(&conn->io);
+	conn->fd = -1;
 }
diff -r 217fb4ca9b5a -r 1841a4b95783 src/doveadm/server-connection.h
--- a/src/doveadm/server-connection.h	Mon Feb 25 13:00:40 2013 +0200
+++ b/src/doveadm/server-connection.h	Mon Feb 25 14:00:10 2013 +0200
@@ -26,6 +26,10 @@
 /* Returns TRUE if no command is being processed */
 bool server_connection_is_idle(struct server_connection *conn);
 
-int server_connection_get_fd(struct server_connection *conn);
+/* Extract iostreams from connection. Afterwards the server_connection simply
+   waits for itself to be destroyed. */
+void server_connection_extract(struct server_connection *conn,
+			       struct istream **istream_r,
+			       struct ostream **ostream_r);
 
 #endif


More information about the dovecot-cvs mailing list