Mercurial > dovecot > core-2.2
annotate src/master/dict-process.c @ 8593:3cccf56e802a HEAD
Increase listen queues to handle high loads better.
Patch by Apple.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 07 Jan 2009 13:34:25 -0500 |
parents | b9faf4db2a9f |
children | 67c08c386702 |
rev | line source |
---|---|
8590
b9faf4db2a9f
Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents:
8219
diff
changeset
|
1 /* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */ |
3855 | 2 |
3 #include "common.h" | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
4 #include "array.h" |
3855 | 5 #include "ioloop.h" |
6 #include "network.h" | |
7 #include "fd-close-on-exec.h" | |
8 #include "env-util.h" | |
9 #include "log.h" | |
5843
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
10 #include "child-process.h" |
3855 | 11 #include "dict-process.h" |
12 | |
13 #include <syslog.h> | |
14 #include <unistd.h> | |
15 #include <sys/stat.h> | |
16 | |
3885
b624b687fe13
Create dict-server socket to base_dir.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
17 #define DICT_SERVER_SOCKET_NAME "dict-server" |
3855 | 18 |
19 struct dict_process { | |
5843
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
20 struct child_process process; |
3885
b624b687fe13
Create dict-server socket to base_dir.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
21 char *path; |
3855 | 22 int fd; |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
23 |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
24 struct log_io *log; |
3855 | 25 struct io *io; |
26 }; | |
27 | |
7561
1a58b18652a6
Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents:
7481
diff
changeset
|
28 static struct dict_process *dict_process; |
3855 | 29 |
30 static void dict_process_unlisten(struct dict_process *process); | |
31 | |
32 static int dict_process_start(struct dict_process *process) | |
33 { | |
34 struct log_io *log; | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
35 const char *executable, *const *dicts; |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
36 unsigned int i, count; |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
37 int log_fd; |
3855 | 38 pid_t pid; |
39 | |
40 log_fd = log_create_pipe(&log, 0); | |
41 if (log_fd < 0) | |
42 pid = -1; | |
43 else { | |
44 pid = fork(); | |
45 if (pid < 0) | |
46 i_error("fork() failed: %m"); | |
47 } | |
48 | |
49 if (pid < 0) { | |
50 (void)close(log_fd); | |
51 return -1; | |
52 } | |
53 | |
54 if (pid != 0) { | |
55 /* master */ | |
5843
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
56 child_process_add(pid, &process->process); |
3855 | 57 log_set_prefix(log, "dict: "); |
6542
402d14b5ef8b
If child process logged a fatal failure, don't show "returned error 89"
Timo Sirainen <tss@iki.fi>
parents:
6477
diff
changeset
|
58 log_set_pid(log, pid); |
3855 | 59 (void)close(log_fd); |
60 | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
61 process->log = log; |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
62 log_ref(process->log); |
3855 | 63 dict_process_unlisten(process); |
64 return 0; | |
65 } | |
66 log_set_prefix(log, "master-dict: "); | |
67 | |
68 /* set stdin and stdout to /dev/null, so anything written into it | |
69 gets ignored. */ | |
70 if (dup2(null_fd, 0) < 0) | |
71 i_fatal("dup2(stdin) failed: %m"); | |
72 if (dup2(null_fd, 1) < 0) | |
73 i_fatal("dup2(stdout) failed: %m"); | |
74 | |
75 /* stderr = log, 3 = listener */ | |
76 if (dup2(log_fd, 2) < 0) | |
77 i_fatal("dup2(stderr) failed: %m"); | |
78 if (dup2(process->fd, 3) < 0) | |
79 i_fatal("dup2(3) failed: %m"); | |
80 | |
81 for (i = 0; i <= 3; i++) | |
82 fd_close_on_exec(i, FALSE); | |
83 | |
7109
e6823d781317
Reverted "environment array" changes. It broke overriding imap/pop3 settings
Timo Sirainen <tss@iki.fi>
parents:
7091
diff
changeset
|
84 child_process_init_env(); |
e6823d781317
Reverted "environment array" changes. It broke overriding imap/pop3 settings
Timo Sirainen <tss@iki.fi>
parents:
7091
diff
changeset
|
85 env_put(t_strconcat("DICT_LISTEN_FROM_FD=", process->path, NULL)); |
3855 | 86 |
7481
768231eb84cf
Added dict_db_config setting to point to a Berkeley DB config file.
Timo Sirainen <tss@iki.fi>
parents:
7109
diff
changeset
|
87 if (settings_root->defaults->dict_db_config != NULL) { |
768231eb84cf
Added dict_db_config setting to point to a Berkeley DB config file.
Timo Sirainen <tss@iki.fi>
parents:
7109
diff
changeset
|
88 env_put(t_strconcat("DB_CONFIG=", |
768231eb84cf
Added dict_db_config setting to point to a Berkeley DB config file.
Timo Sirainen <tss@iki.fi>
parents:
7109
diff
changeset
|
89 settings_root->defaults->dict_db_config, |
768231eb84cf
Added dict_db_config setting to point to a Berkeley DB config file.
Timo Sirainen <tss@iki.fi>
parents:
7109
diff
changeset
|
90 NULL)); |
768231eb84cf
Added dict_db_config setting to point to a Berkeley DB config file.
Timo Sirainen <tss@iki.fi>
parents:
7109
diff
changeset
|
91 } |
768231eb84cf
Added dict_db_config setting to point to a Berkeley DB config file.
Timo Sirainen <tss@iki.fi>
parents:
7109
diff
changeset
|
92 |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
93 dicts = array_get(&settings_root->dicts, &count); |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
94 i_assert((count % 2) == 0); |
7109
e6823d781317
Reverted "environment array" changes. It broke overriding imap/pop3 settings
Timo Sirainen <tss@iki.fi>
parents:
7091
diff
changeset
|
95 for (i = 0; i < count; i += 2) |
e6823d781317
Reverted "environment array" changes. It broke overriding imap/pop3 settings
Timo Sirainen <tss@iki.fi>
parents:
7091
diff
changeset
|
96 env_put(t_strdup_printf("DICT_%s=%s", dicts[i], dicts[i+1])); |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
97 |
3855 | 98 /* make sure we don't leak syslog fd, but do it last so that |
99 any errors above will be logged */ | |
100 closelog(); | |
101 | |
102 executable = PKG_LIBEXECDIR"/dict"; | |
7109
e6823d781317
Reverted "environment array" changes. It broke overriding imap/pop3 settings
Timo Sirainen <tss@iki.fi>
parents:
7091
diff
changeset
|
103 client_process_exec(executable, ""); |
3855 | 104 i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", executable); |
105 return -1; | |
106 } | |
107 | |
4907
5b4c9b20eba0
Replaced void *context from a lot of callbacks with the actual context
Timo Sirainen <tss@iki.fi>
parents:
4393
diff
changeset
|
108 static void dict_process_listen_input(struct dict_process *process) |
3855 | 109 { |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
110 i_assert(process->log == NULL); |
3855 | 111 dict_process_start(process); |
112 } | |
113 | |
114 static int dict_process_listen(struct dict_process *process) | |
115 { | |
116 mode_t old_umask; | |
117 | |
8219
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7561
diff
changeset
|
118 old_umask = umask(0); |
8593
3cccf56e802a
Increase listen queues to handle high loads better.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
119 process->fd = net_listen_unix_unlink_stale(process->path, 128); |
8219
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7561
diff
changeset
|
120 umask(old_umask); |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7561
diff
changeset
|
121 if (process->fd == -1) { |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7561
diff
changeset
|
122 if (errno == EADDRINUSE) |
3855 | 123 i_error("Socket already exists: %s", process->path); |
8219
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7561
diff
changeset
|
124 else |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7561
diff
changeset
|
125 i_error("net_listen_unix(%s) failed: %m", process->path); |
ec83f6dcb585
Added net_listen_unix_unlink_stale() and use it where needed to avoid code duplication.
Timo Sirainen <tss@iki.fi>
parents:
7561
diff
changeset
|
126 return -1; |
3855 | 127 } |
128 fd_close_on_exec(process->fd, TRUE); | |
129 process->io = io_add(process->fd, IO_READ, | |
130 dict_process_listen_input, process); | |
131 | |
132 return process->fd != -1 ? 0 : -1; | |
133 } | |
134 | |
135 static void dict_process_unlisten(struct dict_process *process) | |
136 { | |
137 if (process->fd == -1) | |
138 return; | |
139 | |
3960
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3892
diff
changeset
|
140 io_remove(&process->io); |
aeb424e64f24
Call io_remove() before closing the fd. It's required by kqueue.
Timo Sirainen <tss@iki.fi>
parents:
3892
diff
changeset
|
141 |
3855 | 142 if (close(process->fd) < 0) |
143 i_error("close(dict) failed: %m"); | |
144 process->fd = -1; | |
145 } | |
146 | |
5843
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
147 static void |
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
148 dict_process_destroyed(struct child_process *process, |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5846
diff
changeset
|
149 pid_t pid ATTR_UNUSED, |
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5846
diff
changeset
|
150 bool abnormal_exit ATTR_UNUSED) |
5843
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
151 { |
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
152 struct dict_process *p = (struct dict_process *)process; |
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
153 |
6869
5f97bba6df15
Don't crash when dict process exists and we receive SIGHUP.
Timo Sirainen <tss@iki.fi>
parents:
6542
diff
changeset
|
154 if (p->log != NULL) { |
5f97bba6df15
Don't crash when dict process exists and we receive SIGHUP.
Timo Sirainen <tss@iki.fi>
parents:
6542
diff
changeset
|
155 /* not killed by ourself */ |
5f97bba6df15
Don't crash when dict process exists and we receive SIGHUP.
Timo Sirainen <tss@iki.fi>
parents:
6542
diff
changeset
|
156 log_unref(p->log); |
5f97bba6df15
Don't crash when dict process exists and we receive SIGHUP.
Timo Sirainen <tss@iki.fi>
parents:
6542
diff
changeset
|
157 p->log = NULL; |
5f97bba6df15
Don't crash when dict process exists and we receive SIGHUP.
Timo Sirainen <tss@iki.fi>
parents:
6542
diff
changeset
|
158 } |
5843
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
159 (void)dict_process_listen(p); |
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
160 } |
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
161 |
3855 | 162 void dict_process_init(void) |
163 { | |
7561
1a58b18652a6
Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents:
7481
diff
changeset
|
164 struct dict_process *process; |
1a58b18652a6
Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents:
7481
diff
changeset
|
165 |
1a58b18652a6
Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents:
7481
diff
changeset
|
166 process = dict_process = i_new(struct dict_process, 1); |
5843
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
167 process->process.type = PROCESS_TYPE_DICT; |
3855 | 168 process->fd = -1; |
3885
b624b687fe13
Create dict-server socket to base_dir.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
169 process->path = i_strconcat(settings_root->defaults->base_dir, |
3975
9de8bce1077e
Added plugin {} section to dovecot.conf for passing extra environment
Timo Sirainen <tss@iki.fi>
parents:
3960
diff
changeset
|
170 "/"DICT_SERVER_SOCKET_NAME, NULL); |
9de8bce1077e
Added plugin {} section to dovecot.conf for passing extra environment
Timo Sirainen <tss@iki.fi>
parents:
3960
diff
changeset
|
171 (void)dict_process_listen(process); |
5843
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
172 |
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
173 child_process_set_destroy_callback(PROCESS_TYPE_DICT, |
f655c4d4a419
Moved child process handling to child-process.[ch]. The hash table now uses
Timo Sirainen <tss@iki.fi>
parents:
4907
diff
changeset
|
174 dict_process_destroyed); |
3855 | 175 } |
176 | |
177 void dict_process_deinit(void) | |
178 { | |
7561
1a58b18652a6
Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents:
7481
diff
changeset
|
179 struct dict_process *process = dict_process; |
1a58b18652a6
Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents:
7481
diff
changeset
|
180 |
3855 | 181 dict_process_unlisten(process); |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
182 if (process->log != NULL) |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
183 log_unref(process->log); |
3885
b624b687fe13
Create dict-server socket to base_dir.
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
184 i_free(process->path); |
3855 | 185 i_free(process); |
186 } | |
187 | |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
188 void dict_process_kill(void) |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
189 { |
7561
1a58b18652a6
Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents:
7481
diff
changeset
|
190 struct dict_process *process = dict_process; |
1a58b18652a6
Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents:
7481
diff
changeset
|
191 |
4393
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
192 if (process->log != NULL) { |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
193 log_unref(process->log); |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
194 process->log = NULL; |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
195 } |
9928ebb54719
Instead of passing URIs directly to dictionary server, it now accepts only
Timo Sirainen <tss@iki.fi>
parents:
3975
diff
changeset
|
196 } |