dovecot-2.0: master-child API change: Use a separate fd for trac...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Dec 15 19:07:14 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/b0ec48006d57
changeset: 12526:b0ec48006d57
user: Timo Sirainen <tss at iki.fi>
date: Wed Dec 15 17:07:01 2010 +0000
description:
master-child API change: Use a separate fd for tracking when master dies.
This works around a Linux performance problem where when one process writes
to status fd all the other processes of the same service type wake up.
diffstat:
src/lib-master/master-interface.h | 5 ++++-
src/lib-master/master-service.c | 2 +-
src/master/common.h | 2 +-
src/master/main.c | 8 ++++++--
src/master/service-process.c | 1 +
5 files changed, 13 insertions(+), 5 deletions(-)
diffs (88 lines):
diff -r cde0d403c6ff -r b0ec48006d57 src/lib-master/master-interface.h
--- a/src/lib-master/master-interface.h Mon Dec 13 13:40:27 2010 +0000
+++ b/src/lib-master/master-interface.h Wed Dec 15 17:07:01 2010 +0000
@@ -68,13 +68,16 @@
/* Shared pipe to master, used to send master_status reports */
#define MASTER_STATUS_FD 5
+/* Pipe to master, used to detect when it dies. (MASTER_STATUS_FD would have
+ been fine for this, except it's inefficient in Linux) */
+#define MASTER_DEAD_FD 6
/* First file descriptor where process is expected to be listening.
The file descriptor count is given in -s parameter, defaulting to 1.
master_status.available_count reports how many accept()s we're still
accepting. Once no children are listening, master will do it and create
new child processes when needed. */
-#define MASTER_LISTEN_FD_FIRST 6
+#define MASTER_LISTEN_FD_FIRST 7
/* Timeouts: base everything on how long we can wait for login clients. */
#define MASTER_LOGIN_TIMEOUT_SECS (3*60)
diff -r cde0d403c6ff -r b0ec48006d57 src/lib-master/master-service.c
--- a/src/lib-master/master-service.c Mon Dec 13 13:40:27 2010 +0000
+++ b/src/lib-master/master-service.c Wed Dec 15 17:07:01 2010 +0000
@@ -375,7 +375,7 @@
master_service_set_service_count(service, count);
/* start listening errors for status fd, it means master died */
- service->io_status_error = io_add(MASTER_STATUS_FD, IO_ERROR,
+ service->io_status_error = io_add(MASTER_DEAD_FD, IO_ERROR,
master_status_error, service);
} else {
master_service_set_client_limit(service, 1);
diff -r cde0d403c6ff -r b0ec48006d57 src/master/common.h
--- a/src/master/common.h Mon Dec 13 13:40:27 2010 +0000
+++ b/src/master/common.h Wed Dec 15 17:07:01 2010 +0000
@@ -9,7 +9,7 @@
extern gid_t master_gid;
extern bool core_dumps_disabled;
extern const char *ssl_manual_key_password;
-extern int null_fd;
+extern int null_fd, master_dead_pipe_fd[2];
extern struct service_list *services;
void process_exec(const char *cmd, const char *extra_args[]) ATTR_NORETURN;
diff -r cde0d403c6ff -r b0ec48006d57 src/master/main.c
--- a/src/master/main.c Mon Dec 13 13:40:27 2010 +0000
+++ b/src/master/main.c Wed Dec 15 17:07:01 2010 +0000
@@ -42,7 +42,7 @@
gid_t master_gid;
bool core_dumps_disabled;
const char *ssl_manual_key_password;
-int null_fd;
+int null_fd, master_dead_pipe_fd[2];
struct service_list *services;
static char *pidfile_path;
@@ -412,7 +412,7 @@
lib_signals_set_handler(SIGUSR1, TRUE, sig_log_reopen, NULL);
lib_signals_set_handler(SIGCHLD, TRUE, sig_reap_children, NULL);
lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
- lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
+ lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
create_pid_file(pidfile_path);
create_config_symlink(set);
@@ -712,6 +712,10 @@
i_fatal("Can't open /dev/null: %m");
fd_close_on_exec(null_fd, TRUE);
} while (null_fd <= STDERR_FILENO);
+ if (pipe(master_dead_pipe_fd) < 0)
+ i_fatal("pipe() failed: %m");
+ fd_close_on_exec(master_dead_pipe_fd[0], TRUE);
+ fd_close_on_exec(master_dead_pipe_fd[1], TRUE);
set = master_settings_read();
if (ask_key_pass) {
diff -r cde0d403c6ff -r b0ec48006d57 src/master/service-process.c
--- a/src/master/service-process.c Mon Dec 13 13:40:27 2010 +0000
+++ b/src/master/service-process.c Wed Dec 15 17:07:01 2010 +0000
@@ -116,6 +116,7 @@
break;
}
dup2_append(&dups, service->status_fd[1], MASTER_STATUS_FD);
+ dup2_append(&dups, master_dead_pipe_fd[1], MASTER_DEAD_FD);
if (service->type == SERVICE_TYPE_LOG) {
/* keep stderr as-is. this is especially important when
More information about the dovecot-cvs
mailing list