dovecot-2.0: lib-master: Fixes to handling master-login services.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Oct 27 05:45:25 EET 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/9d13e9f78d52
changeset: 10199:9d13e9f78d52
user: Timo Sirainen <tss at iki.fi>
date: Mon Oct 26 23:41:54 2009 -0400
description:
lib-master: Fixes to handling master-login services.
diffstat:
5 files changed, 32 insertions(+), 10 deletions(-)
src/lib-master/master-login-auth.c | 5 +++++
src/lib-master/master-login-auth.h | 1 +
src/lib-master/master-login.c | 24 +++++++++++++++++++-----
src/lib-master/master-service-private.h | 2 ++
src/lib-master/master-service.c | 10 +++++-----
diffs (177 lines):
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-login-auth.c
--- a/src/lib-master/master-login-auth.c Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-login-auth.c Mon Oct 26 23:41:54 2009 -0400
@@ -288,3 +288,8 @@ void master_login_auth_request(struct ma
login_req->context = context;
hash_table_insert(auth->requests, POINTER_CAST(id), login_req);
}
+
+unsigned int master_login_auth_request_count(struct master_login_auth *auth)
+{
+ return hash_table_count(auth->requests);
+}
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-login-auth.h
--- a/src/lib-master/master-login-auth.h Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-login-auth.h Mon Oct 26 23:41:54 2009 -0400
@@ -14,5 +14,6 @@ void master_login_auth_request(struct ma
const struct master_auth_request *req,
master_login_auth_request_callback_t *callback,
void *context);
+unsigned int master_login_auth_request_count(struct master_login_auth *auth);
#endif
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-login.c
--- a/src/lib-master/master-login.c Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-login.c Mon Oct 26 23:41:54 2009 -0400
@@ -131,7 +131,8 @@ master_login_auth_callback(const char *c
{
struct master_login_client *client = context;
struct master_auth_reply reply;
- struct master_service *service = client->conn->login->service;
+ struct master_login_connection *conn = client->conn;
+ struct master_service *service = conn->login->service;
bool close_config;
memset(&reply, 0, sizeof(reply));
@@ -139,7 +140,7 @@ master_login_auth_callback(const char *c
reply.status = auth_args != NULL ? MASTER_AUTH_STATUS_OK :
MASTER_AUTH_STATUS_INTERNAL_ERROR;
reply.mail_pid = getpid();
- o_stream_send(client->conn->output, &reply, sizeof(reply));
+ o_stream_send(conn->output, &reply, sizeof(reply));
if (auth_args == NULL) {
if (close(client->fd) < 0)
@@ -148,17 +149,19 @@ master_login_auth_callback(const char *c
return;
}
+ i_assert(service->master_status.available_count > 0);
service->master_status.available_count--;
master_status_update(service);
close_config = service->master_status.available_count == 0 &&
service->service_count_left == 1;
- client->conn->login->callback(client, auth_args[0], auth_args+1);
+ conn->login->callback(client, auth_args[0], auth_args+1);
i_free(client);
if (close_config) {
/* we're dying as soon as this connection closes. */
master_service_close_config_fd(service);
+ master_login_conn_deinit(&conn);
}
}
@@ -166,7 +169,9 @@ static void master_login_conn_input(stru
{
struct master_auth_request req;
struct master_login_client *client;
+ struct master_login *login = conn->login;
unsigned char data[MASTER_AUTH_MAX_DATA_SIZE];
+ unsigned int request_count;
int ret, client_fd;
ret = master_login_conn_read_request(conn, &req, data, &client_fd);
@@ -188,8 +193,11 @@ static void master_login_conn_input(stru
client->auth_req = req;
memcpy(client->data, data, req.data_size);
- master_login_auth_request(conn->login->auth, &req,
+ master_login_auth_request(login->auth, &req,
master_login_auth_callback, client);
+ request_count = master_login_auth_request_count(login->auth);
+ if (login->service->master_status.available_count <= request_count)
+ io_remove(&conn->io);
}
void master_login_add(struct master_login *login, int fd)
@@ -203,6 +211,10 @@ void master_login_add(struct master_logi
conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
DLLIST_PREPEND(&login->conns, conn);
+
+ /* don't accept more connections. this is mainly a temporary
+ workaround.. */
+ master_service_io_listeners_remove(login->service);
}
static void master_login_conn_deinit(struct master_login_connection **_conn)
@@ -213,9 +225,11 @@ static void master_login_conn_deinit(str
DLLIST_REMOVE(&conn->login->conns, conn);
- io_remove(&conn->io);
+ if (conn->io != NULL)
+ io_remove(&conn->io);
o_stream_unref(&conn->output);
if (close(conn->fd) < 0)
i_error("close(master login) failed: %m");
+ master_service_io_listeners_add(conn->login->service);
i_free(conn);
}
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-service-private.h
--- a/src/lib-master/master-service-private.h Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-service-private.h Mon Oct 26 23:41:54 2009 -0400
@@ -62,4 +62,6 @@ void master_status_update(struct master_
void master_status_update(struct master_service *service);
void master_service_close_config_fd(struct master_service *service);
+void master_service_io_listeners_remove(struct master_service *service);
+
#endif
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-service.c
--- a/src/lib-master/master-service.c Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-service.c Mon Oct 26 23:41:54 2009 -0400
@@ -39,7 +39,6 @@ struct master_service *master_service;
struct master_service *master_service;
static void master_service_refresh_login_state(struct master_service *service);
-static void io_listeners_remove(struct master_service *service);
const char *master_service_getopt_string(void)
{
@@ -265,7 +264,7 @@ bool master_service_parse_option(struct
static void master_service_error(struct master_service *service)
{
- io_listeners_remove(service);
+ master_service_io_listeners_remove(service);
if (service->master_status.available_count ==
service->total_available_count || service->die_with_master) {
if (service->die_callback == NULL)
@@ -585,7 +584,7 @@ void master_service_deinit(struct master
*_service = NULL;
- io_listeners_remove(service);
+ master_service_io_listeners_remove(service);
master_service_close_config_fd(service);
if (service->to_die != NULL)
@@ -631,7 +630,7 @@ static void master_service_listen(struct
}
if (service->master_status.available_count == 0) {
- io_listeners_remove(service);
+ master_service_io_listeners_remove(service);
return;
}
}
@@ -663,6 +662,7 @@ static void master_service_listen(struct
if (service->login_connections)
close_config = FALSE;
else {
+ i_assert(service->master_status.available_count > 0);
service->master_status.available_count--;
master_status_update(service);
close_config = service->master_status.available_count == 0 &&
@@ -715,7 +715,7 @@ void master_service_io_listeners_add(str
}
}
-static void io_listeners_remove(struct master_service *service)
+void master_service_io_listeners_remove(struct master_service *service)
{
unsigned int i;
More information about the dovecot-cvs
mailing list