annotate src/util/maildirlock.c @ 22644:2ed6735ffc7a

director: Change request callback to take mail_host parameter This allows accessing the IP address both as struct and as string without any conversions.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sat, 04 Nov 2017 02:05:26 +0200
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 19552
diff changeset
1 /* Copyright (c) 2008-2017 Dovecot authors, see the included COPYING file */
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "lib-signals.h"
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "ioloop.h"
8066
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
6 #include "write-full.h"
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "file-dotlock.h"
9072
fb11dca591da Compile fix.
Timo Sirainen <tss@iki.fi>
parents: 8882
diff changeset
8 #include "index/maildir/maildir-uidlist.h"
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include <stdio.h>
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
11 #include <unistd.h>
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 #include <signal.h>
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 static struct dotlock_settings dotlock_settings = {
10410
b757dab45756 Removed MEMBER() macro. Require C99 style struct initializer.
Timo Sirainen <tss@iki.fi>
parents: 9072
diff changeset
15 .stale_timeout = MAILDIR_UIDLIST_LOCK_STALE_TIMEOUT,
b757dab45756 Removed MEMBER() macro. Require C99 style struct initializer.
Timo Sirainen <tss@iki.fi>
parents: 9072
diff changeset
16 .use_io_notify = TRUE
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 };
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 static struct ioloop *ioloop;
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20
8882
9f3968f49ceb lib-signals: Changed callback API to return siginfo_t.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
21 static void sig_die(const siginfo_t *si ATTR_UNUSED, void *context ATTR_UNUSED)
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 {
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 io_loop_stop(ioloop);
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24 }
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 static int maildir_lock(const char *path, unsigned int timeout,
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 struct dotlock **dotlock_r)
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 {
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 dotlock_settings.timeout = timeout;
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 dotlock_settings.use_excl_lock = getenv("DOTLOCK_USE_EXCL") != NULL;
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 dotlock_settings.nfs_flush = getenv("MAIL_NFS_STORAGE") != NULL;
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
33 path = t_strconcat(path, "/" MAILDIR_UIDLIST_NAME, NULL);
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 return file_dotlock_create(&dotlock_settings, path, 0, dotlock_r);
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 }
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 int main(int argc, const char *argv[])
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 {
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 struct dotlock *dotlock;
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 unsigned int timeout;
11039
0f98525e4567 Removed dead code.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
41 pid_t pid;
8066
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
42 int fd[2], ret;
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
43 char c;
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 if (argc != 3) {
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
46 fprintf(stderr, "Usage: maildirlock <path> <timeout>\n"
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
47 " - SIGTERM will release the lock.\n");
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
48 return 1;
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
49 }
8066
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
50 if (pipe(fd) != 0) {
8296
698fca0d8b0a maildirlock: Don't use %m format with fprintf(), it's not portable.
Timo Sirainen <tss@iki.fi>
parents: 8066
diff changeset
51 fprintf(stderr, "pipe() failed: %s", strerror(errno));
8066
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
52 return 1;
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
53 }
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
54
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
55 pid = fork();
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
56 if (pid == (pid_t)-1) {
8296
698fca0d8b0a maildirlock: Don't use %m format with fprintf(), it's not portable.
Timo Sirainen <tss@iki.fi>
parents: 8066
diff changeset
57 fprintf(stderr, "fork() failed: %s", strerror(errno));
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 return 1;
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 }
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
61 /* call lib_init() only after fork so that PID gets set correctly */
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
62 lib_init();
8066
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
63 lib_signals_init();
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
64 ioloop = io_loop_create();
13065
6fdee880c5dc Use SA_RESTART flag for signals wherever possible.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
65 lib_signals_set_handler(SIGINT, LIBSIG_FLAG_DELAYED, sig_die, NULL);
6fdee880c5dc Use SA_RESTART flag for signals wherever possible.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
66 lib_signals_set_handler(SIGTERM, LIBSIG_FLAG_DELAYED, sig_die, NULL);
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
67
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
68 if (pid != 0) {
17496
3d3796c15074 Check for syscall errors that are quite unlikely to happen.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
69 i_close_fd(&fd[1]);
8066
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
70 ret = read(fd[0], &c, 1);
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
71 if (ret < 0) {
8296
698fca0d8b0a maildirlock: Don't use %m format with fprintf(), it's not portable.
Timo Sirainen <tss@iki.fi>
parents: 8066
diff changeset
72 i_error("read(pipe) failed: %m");
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
73 return 1;
8066
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
74 }
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
75 if (ret != 1) {
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
76 /* locking timed out */
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
77 return 1;
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
78 }
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
79
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
80 printf("%s", dec2str(pid));
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
81 return 0;
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
82 }
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
83
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
84 /* child process - stdout has to be closed so that caller knows when
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
85 to stop reading it. */
17496
3d3796c15074 Check for syscall errors that are quite unlikely to happen.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
86 if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0)
3d3796c15074 Check for syscall errors that are quite unlikely to happen.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
87 i_fatal("dup2() failed: %m");
7982
140d9f439c0f maildirlock: Previous implementation wasn't usable - redesigned.
Timo Sirainen <tss@iki.fi>
parents: 7977
diff changeset
88
19038
f8ab4f979e92 Removed all invocations of strtoll() and friends.
Stephan Bosch <stephan@rename-it.nl>
parents: 18137
diff changeset
89 if (str_to_uint(argv[2], &timeout) < 0)
f8ab4f979e92 Removed all invocations of strtoll() and friends.
Stephan Bosch <stephan@rename-it.nl>
parents: 18137
diff changeset
90 i_fatal("Invalid timeout value: %s", argv[2]);
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91 if (maildir_lock(argv[1], timeout, &dotlock) <= 0)
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 return 1;
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93
8066
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
94 /* locked - send a byte */
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
95 if (write_full(fd[1], "", 1) < 0)
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
96 i_fatal("write(pipe) failed: %m");
28b1c4f68c9f maildirlock: Do IPC with pipes instead of with signals. Fixes race conditions.
Timo Sirainen <tss@iki.fi>
parents: 8041
diff changeset
97
7977
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98 io_loop_run(ioloop);
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 file_dotlock_delete(&dotlock);
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101 lib_signals_deinit();
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103 io_loop_destroy(&ioloop);
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 lib_deinit();
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105 return 0;
fed87704b48a Added a new maildirlock utility for write-locking Dovecot MMaildir.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 }