[dovecot-cvs]
dovecot/src/master auth-process.c, 1.76, 1.77 common.h,
1.21, 1.22 main.c, 1.60, 1.61 master-settings.c, 1.81,
1.82 master-settings.h, 1.53, 1.54
cras at dovecot.org
cras at dovecot.org
Tue Mar 1 00:19:24 EET 2005
- Previous message: [dovecot-cvs] dovecot/src/lib Makefile.am, 1.46,
1.47 unix-socket-create.c, NONE, 1.1 unix-socket-create.h, NONE, 1.1
- Next message: [dovecot-cvs] dovecot/src/auth Makefile.am, 1.44,
1.45 auth-master-connection.c, 1.28,
1.29 auth-master-connection.h, 1.9,
1.10 auth-request-balancer-child.c, 1.2,
NONE auth-request-balancer-worker.c, 1.1,
NONE auth-request-balancer.h, 1.1,
NONE auth-request-handler-balancer.c, 1.1,
NONE auth-request-handler-default.c, 1.5,
NONE auth-request-handler.c, 1.2, 1.3 auth-request-handler.h,
1.2, 1.3 auth-request.c, 1.10, 1.11 auth-request.h, 1.9,
1.10 auth.c, 1.13, 1.14 auth.h, 1.11, 1.12 common.h, 1.11,
1.12 main.c, 1.40, 1.41 passdb-bsdauth.c, 1.7,
1.8 passdb-checkpassword.c, 1.7, 1.8 passdb-ldap.c, 1.24,
1.25 passdb-pam.c, 1.21, 1.22 passdb-passwd-file.c, 1.15,
1.16 passdb-passwd.c, 1.10, 1.11 passdb-shadow.c, 1.11,
1.12 passdb-sql.c, 1.14, 1.15 passdb-vpopmail.c, 1.15,
1.16 passdb.c, 1.32, 1.33 passdb.h, 1.22, 1.23 userdb-ldap.c,
1.28, 1.29 userdb-passdb.c, 1.4, 1.5 userdb-passwd-file.c,
1.12, 1.13 userdb-passwd.c, 1.13, 1.14 userdb-sql.c, 1.7,
1.8 userdb-static.c, 1.11, 1.12 userdb-vpopmail.c, 1.14,
1.15 userdb.h, 1.20, 1.21
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/master
In directory talvi:/tmp/cvs-serv21285/src/master
Modified Files:
auth-process.c common.h main.c master-settings.c
master-settings.h
Log Message:
Restructuring of auth code. Balancer auth processes were a bad idea. Usually
the balancer itself took as much CPU as the actual workers because it acted
as a proxy.
Now auth worker means different thing: they're used to execute blocking
passdb and userdb queries. Currently just MySQL (PAM and checkpassword in
TODO).
Index: auth-process.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/auth-process.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -d -r1.76 -r1.77
--- auth-process.c 9 Jan 2005 20:12:35 -0000 1.76
+++ auth-process.c 28 Feb 2005 22:19:21 -0000 1.77
@@ -4,6 +4,7 @@
#include "ioloop.h"
#include "env-util.h"
#include "fd-close-on-exec.h"
+#include "unix-socket-create.h"
#include "network.h"
#include "istream.h"
#include "ostream.h"
@@ -18,7 +19,6 @@
#include <unistd.h>
#include <pwd.h>
#include <syslog.h>
-#include <sys/stat.h>
#define MAX_INBUF_SIZE 8192
#define MAX_OUTBUF_SIZE 65536
@@ -27,13 +27,10 @@
struct auth_process_group *next;
int listen_fd;
- int balancer_listen_fd;
struct auth_settings *set;
unsigned int process_count;
struct auth_process *processes;
-
- unsigned int need_balancer:1;
};
struct auth_process {
@@ -46,9 +43,11 @@
struct istream *input;
struct ostream *output;
+ int worker_listen_fd;
+ struct io *worker_io;
+
struct hash_table *requests;
- unsigned int balancer:1;
unsigned int external:1;
unsigned int version_received:1;
unsigned int initialized:1;
@@ -60,6 +59,7 @@
static struct auth_process_group *process_groups;
static void auth_process_destroy(struct auth_process *p);
+static int create_auth_worker(struct auth_process *process, int fd);
void auth_process_request(struct auth_process *process, unsigned int login_pid,
unsigned int login_id, void *context)
@@ -253,12 +253,29 @@
}
}
+static void auth_worker_input(void *context)
+{
+ struct auth_process *p = context;
+ int fd;
+
+ fd = net_accept(p->worker_listen_fd, NULL, NULL);
+ if (fd < 0) {
+ if (fd == -2)
+ i_fatal("net_accept(worker) failed: %m");
+ return;
+ }
+
+ net_set_nonblock(fd, TRUE);
+ fd_close_on_exec(fd, TRUE);
+
+ create_auth_worker(p, fd);
+}
+
static struct auth_process *
-auth_process_new(pid_t pid, int fd, struct auth_process_group *group,
- int balancer)
+auth_process_new(pid_t pid, int fd, struct auth_process_group *group)
{
struct auth_process *p;
- const char *handshake;
+ const char *path, *handshake;
if (pid != 0)
PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_AUTH);
@@ -274,12 +291,21 @@
FALSE);
p->requests = hash_create(default_pool, default_pool, 0, NULL, NULL);
- if (balancer) {
- p->balancer = TRUE;
- group->need_balancer = FALSE;
- } else {
- group->process_count++;
- }
+ group->process_count++;
+
+ path = t_strdup_printf("%s/auth-worker.%s",
+ group->set->parent->defaults->base_dir,
+ dec2str(pid));
+ p->worker_listen_fd =
+ unix_socket_create(path, 0600, group->set->uid,
+ group->set->gid, 16);
+ if (p->worker_listen_fd == -1)
+ i_fatal("Couldn't create auth worker listener");
+
+ net_set_nonblock(p->worker_listen_fd, TRUE);
+ fd_close_on_exec(p->worker_listen_fd, TRUE);
+ p->worker_io = io_add(p->worker_listen_fd, IO_READ,
+ auth_worker_input, p);
handshake = t_strdup_printf("VERSION\t%u\t%u\n",
AUTH_MASTER_PROTOCOL_MAJOR_VERSION,
@@ -296,6 +322,7 @@
struct hash_iterate_context *iter;
void *key, *value;
struct auth_process **pos;
+ const char *path;
if (!p->initialized && io_loop_is_running(ioloop) && !p->external) {
i_error("Auth process died too early - shutting down");
@@ -308,12 +335,16 @@
break;
}
}
- if (p->balancer) {
- /* the balancer process died, restart it */
- p->group->need_balancer = TRUE;
- } else {
- p->group->process_count--;
- }
+ p->group->process_count--;
+
+ path = t_strdup_printf("%s/auth-worker.%s",
+ p->group->set->parent->defaults->base_dir,
+ dec2str(p->pid));
+ (void)unlink(path);
+
+ if (close(p->worker_listen_fd) < 0)
+ i_error("close(worker_listen) failed: %m");
+ io_remove(p->worker_io);
iter = hash_iterate_init(p->requests);
while (hash_iterate(iter, &key, &value))
@@ -358,48 +389,64 @@
net_set_nonblock(fd, TRUE);
fd_close_on_exec(fd, TRUE);
- auth = auth_process_new(0, fd, group, FALSE);
+ auth = auth_process_new(0, fd, group);
auth->external = TRUE;
return 0;
}
-static int unix_socket_create(const char *path, int mode,
- uid_t uid, gid_t gid, int backlog)
+static void auth_set_environment(struct auth_settings *set)
{
- mode_t old_umask;
- int fd;
+ struct auth_socket_settings *as;
+ const char *str;
+ int i;
- (void)unlink(path);
+ /* setup access environment */
+ restrict_access_set_env(set->user, set->uid, set->gid, set->chroot,
+ 0, 0, NULL);
- old_umask = umask(0777 ^ mode);
- fd = net_listen_unix(path, backlog);
- umask(old_umask);
+ /* set other environment */
+ env_put("DOVECOT_MASTER=1");
+ env_put(t_strconcat("AUTH_NAME=", set->name, NULL));
+ env_put(t_strconcat("MECHANISMS=", set->mechanisms, NULL));
+ env_put(t_strconcat("REALMS=", set->realms, NULL));
+ env_put(t_strconcat("DEFAULT_REALM=", set->default_realm, NULL));
+ env_put(t_strconcat("USERDB=", set->userdb, NULL));
+ env_put(t_strconcat("PASSDB=", set->passdb, NULL));
+ env_put(t_strconcat("USERNAME_CHARS=", set->username_chars, NULL));
+ env_put(t_strconcat("USERNAME_TRANSLATION=",
+ set->username_translation, NULL));
+ env_put(t_strconcat("ANONYMOUS_USERNAME=",
+ set->anonymous_username, NULL));
+ env_put(t_strdup_printf("CACHE_SIZE=%u", set->cache_size));
+ env_put(t_strdup_printf("CACHE_TTL=%u", set->cache_ttl));
- if (fd < 0)
- i_fatal("Can't listen in UNIX socket %s: %m", path);
- net_set_nonblock(fd, TRUE);
- fd_close_on_exec(fd, TRUE);
+ for (as = set->sockets, i = 1; as != NULL; as = as->next, i++) {
+ if (strcmp(as->type, "listen") != 0)
+ continue;
- if (uid != (uid_t)-1 || gid != (gid_t)-1) {
- /* set correct permissions */
- if (chown(path, uid, gid) < 0) {
- i_fatal("login: chown(%s, %s, %s) failed: %m",
- path, dec2str(uid), dec2str(gid));
- }
+ str = t_strdup_printf("AUTH_%u", i);
+ socket_settings_env_put(str, &as->client);
+ socket_settings_env_put(t_strconcat(str, "_MASTER", NULL),
+ &as->master);
}
- return fd;
+
+ if (set->verbose)
+ env_put("VERBOSE=1");
+ if (set->debug)
+ env_put("VERBOSE_DEBUG=1");
+ if (set->ssl_require_client_cert)
+ env_put("SSL_REQUIRE_CLIENT_CERT=1");
+
+ restrict_process_size(set->process_size, (unsigned int)-1);
}
-static int create_auth_process(struct auth_process_group *group,
- int balancer_worker)
+static int create_auth_process(struct auth_process_group *group)
{
struct auth_socket_settings *as;
- const char *prefix, *str, *executable;
+ const char *prefix, *executable;
struct log_io *log;
pid_t pid;
- int fd[2], log_fd, i, balancer;
-
- balancer = group->balancer_listen_fd != -1 && !balancer_worker;
+ int fd[2], log_fd, i;
/* see if this is a connect socket */
as = group->set->sockets;
@@ -435,7 +482,7 @@
net_set_nonblock(fd[0], TRUE);
fd_close_on_exec(fd[0], TRUE);
- auth_process_new(pid, fd[0], group, balancer);
+ auth_process_new(pid, fd[0], group);
(void)close(fd[1]);
(void)close(log_fd);
return 0;
@@ -460,76 +507,94 @@
child_process_init_env();
- if (!balancer_worker) {
- i_assert(group->balancer_listen_fd != 3);
- if (group->listen_fd != 3) {
- if (dup2(group->listen_fd, 3) < 0)
- i_fatal("dup2() failed: %m");
- }
- fd_close_on_exec(3, FALSE);
- }
-
- if (balancer) {
- if (group->balancer_listen_fd != 4) {
- if (dup2(group->balancer_listen_fd, 4) < 0)
- i_fatal("dup2() failed: %m");
- }
- fd_close_on_exec(4, FALSE);
+ if (group->listen_fd != 3) {
+ if (dup2(group->listen_fd, 3) < 0)
+ i_fatal("dup2() failed: %m");
}
+ fd_close_on_exec(3, FALSE);
for (i = 0; i <= 2; i++)
fd_close_on_exec(i, FALSE);
- /* setup access environment */
- restrict_access_set_env(group->set->user, group->set->uid,
- group->set->gid, group->set->chroot,
- 0, 0, NULL);
+ auth_set_environment(group->set);
- /* set other environment */
- env_put("DOVECOT_MASTER=1");
- env_put(t_strconcat("AUTH_NAME=", group->set->name, NULL));
- env_put(t_strconcat("MECHANISMS=", group->set->mechanisms, NULL));
- env_put(t_strconcat("REALMS=", group->set->realms, NULL));
- env_put(t_strconcat("DEFAULT_REALM=", group->set->default_realm, NULL));
- env_put(t_strconcat("USERDB=", group->set->userdb, NULL));
- env_put(t_strconcat("PASSDB=", group->set->passdb, NULL));
- env_put(t_strconcat("USERNAME_CHARS=", group->set->username_chars, NULL));
- env_put(t_strconcat("USERNAME_TRANSLATION=",
- group->set->username_translation, NULL));
- env_put(t_strconcat("ANONYMOUS_USERNAME=",
- group->set->anonymous_username, NULL));
- env_put(t_strdup_printf("CACHE_SIZE=%u", group->set->cache_size));
- env_put(t_strdup_printf("CACHE_TTL=%u", group->set->cache_ttl));
+ env_put(t_strdup_printf("AUTH_WORKER_PATH=%s/auth-worker.%s",
+ group->set->parent->defaults->base_dir,
+ dec2str(getpid())));
+ env_put(t_strdup_printf("AUTH_WORKER_MAX_COUNT=%u",
+ group->set->worker_max_count));
- for (as = group->set->sockets, i = 1; as != NULL; as = as->next, i++) {
- if (strcmp(as->type, "listen") != 0)
- continue;
+ /* make sure we don't leak syslog fd, but do it last so that
+ any errors above will be logged */
+ closelog();
- str = t_strdup_printf("AUTH_%u", i);
- socket_settings_env_put(str, &as->client);
- socket_settings_env_put(t_strconcat(str, "_MASTER", NULL),
- &as->master);
+ executable = group->set->executable;
+ client_process_exec(executable, "");
+ i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", executable);
+ return -1;
+}
+
+static int create_auth_worker(struct auth_process *process, int fd)
+{
+ struct log_io *log;
+ const char *prefix, *executable;
+ pid_t pid;
+ int log_fd, i;
+
+ log_fd = log_create_pipe(&log, 0);
+ if (log_fd < 0)
+ pid = -1;
+ else {
+ pid = fork();
+ if (pid < 0)
+ i_error("fork() failed: %m");
}
- if (group->set->verbose)
- env_put("VERBOSE=1");
- if (group->set->debug)
- env_put("VERBOSE_DEBUG=1");
- if (group->set->ssl_require_client_cert)
- env_put("SSL_REQUIRE_CLIENT_CERT=1");
+ if (pid < 0) {
+ (void)close(log_fd);
+ return -1;
+ }
- restrict_process_size(group->set->process_size, (unsigned int)-1);
+ if (pid != 0) {
+ /* master */
+ PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_AUTH_WORKER);
+ prefix = t_strdup_printf("auth-worker(%s): ",
+ process->group->set->name);
+ log_set_prefix(log, prefix);
+ (void)close(fd);
+ (void)close(log_fd);
+ return 0;
+ }
+
+ prefix = t_strdup_printf("master-auth-worker(%s): ",
+ process->group->set->name);
+ log_set_prefix(log, prefix);
+
+ /* set stdin and stdout to /dev/null, so anything written into it
+ gets ignored. */
+ if (dup2(null_fd, 0) < 0)
+ i_fatal("dup2(stdin) failed: %m");
+ if (dup2(null_fd, 1) < 0)
+ i_fatal("dup2(stdout) failed: %m");
+
+ if (dup2(log_fd, 2) < 0)
+ i_fatal("dup2(stderr) failed: %m");
+
+ if (dup2(fd, 4) < 0)
+ i_fatal("dup2(stdin) failed: %m");
+
+ for (i = 0; i <= 2; i++)
+ fd_close_on_exec(i, FALSE);
+ fd_close_on_exec(4, FALSE);
+
+ child_process_init_env();
+ auth_set_environment(process->group->set);
/* make sure we don't leak syslog fd, but do it last so that
any errors above will be logged */
closelog();
- executable = group->set->executable;
- if (balancer || balancer_worker) {
- /* we are running in balancer mode */
- executable = t_strconcat(executable, balancer_worker ?
- " -bw" : " -b", NULL);
- }
+ executable = t_strconcat(process->group->set->executable, " -w", NULL);
client_process_exec(executable, "");
i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", executable);
return -1;
@@ -569,17 +634,11 @@
auth_set->name, NULL);
group->listen_fd = unix_socket_create(path, 0660, master_uid,
auth_set->parent->login_gid, 16);
+ if (group->listen_fd == -1)
+ i_fatal("Couldn't create auth process listener");
- if (auth_set->count <= 1)
- group->balancer_listen_fd = -1;
- else {
- path = t_strconcat(auth_set->parent->defaults->base_dir, "/",
- auth_set->name, "-balancer", NULL);
- group->balancer_listen_fd =
- unix_socket_create(path, 0600, (uid_t)-1, (gid_t)-1,
- group->set->count);
- group->need_balancer = TRUE;
- }
+ net_set_nonblock(group->listen_fd, TRUE);
+ fd_close_on_exec(group->listen_fd, TRUE);
}
static void auth_process_group_destroy(struct auth_process_group *group)
@@ -597,12 +656,6 @@
group->set->name, NULL);
(void)unlink(path);
- if (group->balancer_listen_fd != -1) {
- path = t_strconcat(group->set->parent->defaults->base_dir, "/",
- group->set->name, "-balancer", NULL);
- (void)unlink(path);
- }
-
if (close(group->listen_fd) < 0)
i_error("close(%s) failed: %m", path);
i_free(group);
@@ -637,7 +690,6 @@
{
struct auth_process_group *group;
unsigned int count;
- int balancer_worker;
if (process_groups == NULL) {
/* first time here, create the groups */
@@ -645,13 +697,9 @@
}
for (group = process_groups; group != NULL; group = group->next) {
- if (group->need_balancer)
- (void)create_auth_process(group, FALSE);
-
- balancer_worker = group->balancer_listen_fd != -1;
count = group->process_count;
for (; count < group->set->count; count++)
- (void)create_auth_process(group, balancer_worker);
+ (void)create_auth_process(group);
}
}
Index: common.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/common.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- common.h 24 Nov 2004 16:44:11 -0000 1.21
+++ common.h 28 Feb 2005 22:19:21 -0000 1.22
@@ -10,6 +10,7 @@
enum process_type {
PROCESS_TYPE_UNKNOWN,
PROCESS_TYPE_AUTH,
+ PROCESS_TYPE_AUTH_WORKER,
PROCESS_TYPE_LOGIN,
PROCESS_TYPE_IMAP,
PROCESS_TYPE_POP3,
Index: main.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/main.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- main.c 9 Jan 2005 16:51:06 -0000 1.60
+++ main.c 28 Feb 2005 22:19:21 -0000 1.61
@@ -25,6 +25,7 @@
const char *process_names[PROCESS_TYPE_MAX] = {
"unknown",
"auth",
+ "auth-worker",
"login",
"imap",
"pop3",
Index: master-settings.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/master-settings.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -d -r1.81 -r1.82
--- master-settings.c 29 Dec 2004 19:10:27 -0000 1.81
+++ master-settings.c 28 Feb 2005 22:19:21 -0000 1.82
@@ -155,6 +155,7 @@
DEF(SET_BOOL, ssl_require_client_cert),
DEF(SET_INT, count),
+ DEF(SET_INT, worker_max_count),
DEF(SET_INT, process_size),
{ 0, NULL, 0 }
@@ -330,6 +331,7 @@
MEMBER(ssl_require_client_cert) FALSE,
MEMBER(count) 1,
+ MEMBER(worker_max_count) 30,
MEMBER(process_size) 256,
/* .. */
Index: master-settings.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/master-settings.h,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- master-settings.h 29 Dec 2004 19:10:27 -0000 1.53
+++ master-settings.h 28 Feb 2005 22:19:21 -0000 1.54
@@ -144,6 +144,7 @@
int ssl_require_client_cert;
unsigned int count;
+ unsigned int worker_max_count;
unsigned int process_size;
/* .. */
- Previous message: [dovecot-cvs] dovecot/src/lib Makefile.am, 1.46,
1.47 unix-socket-create.c, NONE, 1.1 unix-socket-create.h, NONE, 1.1
- Next message: [dovecot-cvs] dovecot/src/auth Makefile.am, 1.44,
1.45 auth-master-connection.c, 1.28,
1.29 auth-master-connection.h, 1.9,
1.10 auth-request-balancer-child.c, 1.2,
NONE auth-request-balancer-worker.c, 1.1,
NONE auth-request-balancer.h, 1.1,
NONE auth-request-handler-balancer.c, 1.1,
NONE auth-request-handler-default.c, 1.5,
NONE auth-request-handler.c, 1.2, 1.3 auth-request-handler.h,
1.2, 1.3 auth-request.c, 1.10, 1.11 auth-request.h, 1.9,
1.10 auth.c, 1.13, 1.14 auth.h, 1.11, 1.12 common.h, 1.11,
1.12 main.c, 1.40, 1.41 passdb-bsdauth.c, 1.7,
1.8 passdb-checkpassword.c, 1.7, 1.8 passdb-ldap.c, 1.24,
1.25 passdb-pam.c, 1.21, 1.22 passdb-passwd-file.c, 1.15,
1.16 passdb-passwd.c, 1.10, 1.11 passdb-shadow.c, 1.11,
1.12 passdb-sql.c, 1.14, 1.15 passdb-vpopmail.c, 1.15,
1.16 passdb.c, 1.32, 1.33 passdb.h, 1.22, 1.23 userdb-ldap.c,
1.28, 1.29 userdb-passdb.c, 1.4, 1.5 userdb-passwd-file.c,
1.12, 1.13 userdb-passwd.c, 1.13, 1.14 userdb-sql.c, 1.7,
1.8 userdb-static.c, 1.11, 1.12 userdb-vpopmail.c, 1.14,
1.15 userdb.h, 1.20, 1.21
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list