annotate src/lib/file-dotlock.c @ 5938:805f2527a982 HEAD

If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting dotlock deletion instead of just sleeping randomly.
author Timo Sirainen <tss@iki.fi>
date Mon, 09 Jul 2007 07:01:08 +0300
parents b796701a6927
children 29770d8a013b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* Copyright (C) 2003 Timo Sirainen */
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
5938
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
4 #include "ioloop.h"
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
5 #include "str.h"
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
6 #include "hex-binary.h"
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "hostpid.h"
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
8 #include "randgen.h"
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #include "write-full.h"
5543
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
10 #include "safe-mkstemp.h"
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include "file-dotlock.h"
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
13 #include <stdio.h>
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14 #include <stdlib.h>
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 #include <signal.h>
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 #include <time.h>
3982
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
17 #include <utime.h>
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 #include <sys/stat.h>
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19
1974
d85f71ffeb8f file_dotlock_open/delete/replace now has lock_suffix parameter. NULL
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
20 #define DEFAULT_LOCK_SUFFIX ".lock"
d85f71ffeb8f file_dotlock_open/delete/replace now has lock_suffix parameter. NULL
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
21
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 /* 0.1 .. 0.2msec */
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 #define LOCK_RANDOM_USLEEP_TIME (100000 + (unsigned int)rand() % 100000)
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24
5353
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
25 /* If the dotlock is newer than this, don't verify that the PID it contains
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
26 is valid (since it most likely is). */
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
27 #define STALE_PID_CHECK_SECS 2
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
28
5664
b796701a6927 Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents: 5663
diff changeset
29 /* Maximum difference between current time and create file's ctime before
b796701a6927 Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents: 5663
diff changeset
30 logging a warning. Should be less than a second in normal operation. */
b796701a6927 Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents: 5663
diff changeset
31 #define MAX_TIME_DIFF 30
b796701a6927 Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents: 5663
diff changeset
32
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
33 struct dotlock {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
34 struct dotlock_settings settings;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
35
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
36 dev_t dev;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
37 ino_t ino;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
38 time_t mtime;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
39
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
40 char *path;
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
41 char *lock_path;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
42 int fd;
3576
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
43
4306
ce3c09a75b87 Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents: 4211
diff changeset
44 time_t lock_time;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
45 };
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
46
3981
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
47 struct file_change_info {
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
48 dev_t dev;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
49 ino_t ino;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
50 off_t size;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
51 time_t ctime, mtime;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
52 };
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
53
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 struct lock_info {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
55 const struct dotlock_settings *set;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
56 const char *path, *lock_path, *temp_path;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
57 int fd;
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58
3981
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
59 struct file_change_info lock_info;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
60 struct file_change_info file_info;
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61
5938
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
62 bool have_pid, use_io_notify;
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 time_t last_pid_check;
3981
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
64 time_t last_change;
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 };
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
67 static struct dotlock *
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
68 file_dotlock_alloc(const struct dotlock_settings *settings)
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
69 {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
70 struct dotlock *dotlock;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
71
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
72 dotlock = i_new(struct dotlock, 1);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
73 dotlock->settings = *settings;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
74 if (dotlock->settings.lock_suffix == NULL)
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
75 dotlock->settings.lock_suffix = DEFAULT_LOCK_SUFFIX;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
76 dotlock->fd = -1;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
77
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
78 return dotlock;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
79 }
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
80
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 static pid_t read_local_pid(const char *lock_path)
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82 {
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 char buf[512], *host;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84 int fd;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85 ssize_t ret;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 fd = open(lock_path, O_RDONLY);
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 if (fd == -1)
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 return -1; /* ignore the actual error */
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91 /* read line */
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 ret = read(fd, buf, sizeof(buf)-1);
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93 (void)close(fd);
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94 if (ret <= 0)
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95 return -1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 /* fix the string */
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98 if (buf[ret-1] == '\n')
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 ret--;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 buf[ret] = '\0';
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102 /* it should contain pid:host */
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103 host = strchr(buf, ':');
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 if (host == NULL)
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105 return -1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 *host++ = '\0';
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 /* host must be ours */
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 if (strcmp(host, my_hostname) != 0)
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110 return -1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 if (!is_numeric(buf, '\0'))
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 return -1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 return (pid_t)strtoul(buf, NULL, 0);
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116
3981
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
117 static bool
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
118 update_change_info(const struct stat *st, struct file_change_info *change,
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
119 time_t *last_change_r, time_t now)
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
120 {
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
121 if (change->ino != st->st_ino || !CMP_DEV_T(change->dev, st->st_dev) ||
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
122 change->ctime != st->st_ctime || change->mtime != st->st_mtime ||
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
123 change->size != st->st_size) {
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
124 time_t change_time = now;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
125
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
126 if (change->ctime == 0) {
4307
f92485c7bbd7 When checking if we want to override dotlocks, don't use the
Timo Sirainen <tss@iki.fi>
parents: 4306
diff changeset
127 /* First check, set last_change to file's change time.
f92485c7bbd7 When checking if we want to override dotlocks, don't use the
Timo Sirainen <tss@iki.fi>
parents: 4306
diff changeset
128 Use mtime instead if it's higher, but only if it's
f92485c7bbd7 When checking if we want to override dotlocks, don't use the
Timo Sirainen <tss@iki.fi>
parents: 4306
diff changeset
129 not higher than current time, because the mtime
f92485c7bbd7 When checking if we want to override dotlocks, don't use the
Timo Sirainen <tss@iki.fi>
parents: 4306
diff changeset
130 can also be used for keeping metadata. */
f92485c7bbd7 When checking if we want to override dotlocks, don't use the
Timo Sirainen <tss@iki.fi>
parents: 4306
diff changeset
131 change_time = st->st_mtime > now ? st->st_ctime :
f92485c7bbd7 When checking if we want to override dotlocks, don't use the
Timo Sirainen <tss@iki.fi>
parents: 4306
diff changeset
132 I_MAX(st->st_ctime, st->st_mtime);
3981
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
133 }
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
134 if (*last_change_r < change_time)
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
135 *last_change_r = change_time;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
136 change->ino = st->st_ino;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
137 change->dev = st->st_dev;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
138 change->ctime = st->st_ctime;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
139 change->mtime = st->st_mtime;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
140 change->size = st->st_size;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
141 return TRUE;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
142 }
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
143 return FALSE;
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
144 }
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
145
5353
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
146 static int update_lock_info(time_t now, struct lock_info *lock_info,
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
147 bool *changed_r)
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 {
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149 struct stat st;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 if (lstat(lock_info->lock_path, &st) < 0) {
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 if (errno != ENOENT) {
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 i_error("lstat(%s) failed: %m", lock_info->lock_path);
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154 return -1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156 return 1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158
5353
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
159 *changed_r = update_change_info(&st, &lock_info->lock_info,
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
160 &lock_info->last_change, now);
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
161 return 0;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
162 }
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
163
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
164 static int check_lock(time_t now, struct lock_info *lock_info)
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
165 {
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
166 time_t stale_timeout = lock_info->set->stale_timeout;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
167 pid_t pid;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
168 bool changed;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
169 int ret;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
170
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
171 if ((ret = update_lock_info(now, lock_info, &changed)) != 0)
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
172 return ret;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
173 if (changed) {
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
174 /* either our first check or someone else got the lock file.
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
175 if the dotlock was created only a couple of seconds ago,
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
176 don't bother to read its PID. */
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
177 pid = lock_info->lock_info.mtime >=
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
178 now - STALE_PID_CHECK_SECS ? -1 :
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
179 read_local_pid(lock_info->lock_path);
2651
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
180 lock_info->have_pid = pid != -1;
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
181 } else if (!lock_info->have_pid) {
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
182 /* no pid checking */
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
183 pid = -1;
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
184 } else {
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
185 if (lock_info->last_pid_check == now) {
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
186 /* we just checked the pid */
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
187 return 0;
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
188 }
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
189
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
190 /* re-read the pid. even if all times and inodes are the same,
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
191 the PID in the file might have changed if lock files were
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
192 rapidly being recreated. */
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
193 pid = read_local_pid(lock_info->lock_path);
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
194 lock_info->have_pid = pid != -1;
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
196
2651
ec6cd5dcf618 Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents: 2630
diff changeset
197 if (lock_info->have_pid) {
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
198 /* we've local PID. Check if it exists. */
2948
0e7a0e204f5d If pid in dotlock file is same as ours, assume a stale lock file.
Timo Sirainen <tss@iki.fi>
parents: 2728
diff changeset
199 if (kill(pid, 0) == 0 || errno != ESRCH) {
0e7a0e204f5d If pid in dotlock file is same as ours, assume a stale lock file.
Timo Sirainen <tss@iki.fi>
parents: 2728
diff changeset
200 if (pid != getpid())
0e7a0e204f5d If pid in dotlock file is same as ours, assume a stale lock file.
Timo Sirainen <tss@iki.fi>
parents: 2728
diff changeset
201 return 0;
0e7a0e204f5d If pid in dotlock file is same as ours, assume a stale lock file.
Timo Sirainen <tss@iki.fi>
parents: 2728
diff changeset
202 /* it's us. either we're locking it again, or it's a
0e7a0e204f5d If pid in dotlock file is same as ours, assume a stale lock file.
Timo Sirainen <tss@iki.fi>
parents: 2728
diff changeset
203 stale lock file with same pid than us. either way,
0e7a0e204f5d If pid in dotlock file is same as ours, assume a stale lock file.
Timo Sirainen <tss@iki.fi>
parents: 2728
diff changeset
204 recreate it.. */
0e7a0e204f5d If pid in dotlock file is same as ours, assume a stale lock file.
Timo Sirainen <tss@iki.fi>
parents: 2728
diff changeset
205 }
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
206
5353
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
207 /* doesn't exist - now check again if the dotlock was just
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
208 deleted or replaced */
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
209 if ((ret = update_lock_info(now, lock_info, &changed)) != 0)
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
210 return ret;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
211
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
212 if (!changed) {
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
213 /* still there, go ahead and override it */
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
214 if (unlink(lock_info->lock_path) < 0 &&
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
215 errno != ENOENT) {
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
216 i_error("unlink(%s) failed: %m",
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
217 lock_info->lock_path);
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
218 return -1;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
219 }
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
220 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221 return 1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
223
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
224 if (stale_timeout == 0) {
2728
486a5dbbc9c8 Check that dotlock PID exists even if we don't do stale lock timeouting.
Timo Sirainen <tss@iki.fi>
parents: 2720
diff changeset
225 /* no change checking */
486a5dbbc9c8 Check that dotlock PID exists even if we don't do stale lock timeouting.
Timo Sirainen <tss@iki.fi>
parents: 2720
diff changeset
226 return 0;
486a5dbbc9c8 Check that dotlock PID exists even if we don't do stale lock timeouting.
Timo Sirainen <tss@iki.fi>
parents: 2720
diff changeset
227 }
486a5dbbc9c8 Check that dotlock PID exists even if we don't do stale lock timeouting.
Timo Sirainen <tss@iki.fi>
parents: 2720
diff changeset
228
3981
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
229 if (now > lock_info->last_change + stale_timeout) {
5353
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
230 struct stat st;
0f352077f789 If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents: 5352
diff changeset
231
3981
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
232 /* possibly stale lock file. check also the timestamp of the
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
233 file we're protecting. */
1624
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
234 if (stat(lock_info->path, &st) < 0) {
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
235 if (errno == ENOENT) {
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
236 /* file doesn't exist. treat it as if
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
237 it hasn't changed */
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
238 } else {
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
239 i_error("stat(%s) failed: %m", lock_info->path);
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
240 return -1;
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
241 }
3981
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
242 } else {
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
243 (void)update_change_info(&st, &lock_info->file_info,
0d64f8888dcd Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
244 &lock_info->last_change, now);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
245 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
246 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
247
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
248 if (now > lock_info->last_change + stale_timeout) {
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
249 /* no changes for a while, assume stale lock */
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
250 if (unlink(lock_info->lock_path) < 0 && errno != ENOENT) {
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
251 i_error("unlink(%s) failed: %m", lock_info->lock_path);
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
252 return -1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
253 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
254 return 1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
255 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
256
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
257 return 0;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
258 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
259
3564
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
260 static int file_write_pid(int fd, const char *path)
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
261 {
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
262 const char *str;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
263
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
264 /* write our pid and host, if possible */
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
265 str = t_strdup_printf("%s:%s", my_pid, my_hostname);
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
266 if (write_full(fd, str, strlen(str)) < 0) {
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
267 /* failed, leave it empty then */
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
268 if (ftruncate(fd, 0) < 0) {
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
269 i_error("ftruncate(%s) failed: %m", path);
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
270 return -1;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
271 }
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
272 }
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
273 return 0;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
274 }
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
275
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
276 static int try_create_lock_hardlink(struct lock_info *lock_info, bool write_pid,
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
277 string_t *tmp_path)
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
278 {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
279 const char *temp_prefix = lock_info->set->temp_prefix;
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
280 const char *p;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
281
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
282 if (lock_info->temp_path == NULL) {
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
283 /* we'll need our temp file first. */
3174
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
284 i_assert(lock_info->fd == -1);
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
285
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
286 p = strrchr(lock_info->lock_path, '/');
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
287
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
288 str_truncate(tmp_path, 0);
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
289 if (temp_prefix != NULL) {
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
290 if (*temp_prefix != '/' && p != NULL) {
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
291 /* add directory */
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
292 str_append_n(tmp_path, lock_info->lock_path,
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
293 p - lock_info->lock_path);
4211
044889ec438e Fixed last change: added missing '/' back
Timo Sirainen <tss@iki.fi>
parents: 4207
diff changeset
294 str_append_c(tmp_path, '/');
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
295 }
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
296 str_append(tmp_path, temp_prefix);
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
297 } else {
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
298 if (p != NULL) {
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
299 /* add directory */
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
300 str_append_n(tmp_path, lock_info->lock_path,
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
301 p - lock_info->lock_path);
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
302 str_append_c(tmp_path, '/');
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
303 }
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
304 str_printfa(tmp_path, ".temp.%s.%s.",
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
305 my_hostname, my_pid);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
306 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
307
5543
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
308 lock_info->fd = safe_mkstemp(tmp_path, 0666,
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
309 (uid_t)-1, (gid_t)-1);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
310 if (lock_info->fd == -1)
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
311 return -1;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
312
5543
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
313 if (write_pid) {
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
314 if (file_write_pid(lock_info->fd,
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
315 str_c(tmp_path)) < 0) {
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
316 (void)close(lock_info->fd);
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
317 lock_info->fd = -1;
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
318 return -1;
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
319 }
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
320 }
a240e903841e Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents: 5541
diff changeset
321
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
322 lock_info->temp_path = str_c(tmp_path);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
323 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
324
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
325 if (link(lock_info->temp_path, lock_info->lock_path) < 0) {
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
326 if (errno == EEXIST)
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
327 return 0;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
328
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
329 i_error("link(%s, %s) failed: %m",
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
330 lock_info->temp_path, lock_info->lock_path);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
331 return -1;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
332 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
333
4308
b0c4e02d715b If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents: 4307
diff changeset
334 if (unlink(lock_info->temp_path) < 0) {
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
335 i_error("unlink(%s) failed: %m", lock_info->temp_path);
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
336 /* non-fatal, continue */
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
337 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
338 lock_info->temp_path = NULL;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
339
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
340 return 1;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
341 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
342
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3715
diff changeset
343 static int try_create_lock_excl(struct lock_info *lock_info, bool write_pid)
3564
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
344 {
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
345 int fd;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
346
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
347 fd = open(lock_info->lock_path, O_RDWR | O_EXCL | O_CREAT, 0666);
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
348 if (fd == -1) {
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
349 if (errno == EEXIST)
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
350 return 0;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
351
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
352 i_error("open(%s) failed: %m", lock_info->lock_path);
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
353 return -1;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
354 }
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
355
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
356 if (write_pid) {
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
357 if (file_write_pid(fd, lock_info->lock_path) < 0) {
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
358 (void)close(fd);
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
359 return -1;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
360 }
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
361 }
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
362
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
363 lock_info->fd = fd;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
364 return 1;
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
365 }
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
366
5938
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
367 static void dotlock_wait_end(struct ioloop *ioloop)
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
368 {
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
369 io_loop_stop(ioloop);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
370 }
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
371
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
372 static void dotlock_wait(struct lock_info *lock_info)
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
373 {
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
374 struct ioloop *ioloop;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
375 struct io *io;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
376 struct timeout *to;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
377
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
378 if (!lock_info->use_io_notify) {
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
379 usleep(LOCK_RANDOM_USLEEP_TIME);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
380 return;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
381 }
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
382
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
383 ioloop = io_loop_create();
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
384 switch (io_add_notify(lock_info->lock_path, dotlock_wait_end,
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
385 ioloop, &io)) {
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
386 case IO_NOTIFY_ADDED:
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
387 break;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
388 case IO_NOTIFY_NOTFOUND:
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
389 /* the lock file doesn't exist anymore, don't sleep */
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
390 io_loop_destroy(&ioloop);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
391 return;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
392 case IO_NOTIFY_DISABLED:
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
393 /* listening for files not supported */
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
394 io_loop_destroy(&ioloop);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
395 lock_info->use_io_notify = FALSE;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
396 usleep(LOCK_RANDOM_USLEEP_TIME);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
397 return;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
398 }
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
399 to = timeout_add(LOCK_RANDOM_USLEEP_TIME/1000,
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
400 dotlock_wait_end, ioloop);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
401 io_loop_run(ioloop);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
402 io_remove(&io);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
403 timeout_remove(&to);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
404 io_loop_destroy(&ioloop);
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
405 }
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
406
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
407 static int dotlock_create(const char *path, struct dotlock *dotlock,
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3715
diff changeset
408 enum dotlock_create_flags flags, bool write_pid)
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
409 {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
410 const struct dotlock_settings *set = &dotlock->settings;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
411 const char *lock_path;
3132
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
412 struct lock_info lock_info;
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
413 struct stat st;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
414 unsigned int stale_notify_threshold;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
415 unsigned int change_secs, wait_left;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
416 time_t now, max_wait_time, last_notify;
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
417 string_t *tmp_path;
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3715
diff changeset
418 int ret;
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3715
diff changeset
419 bool do_wait;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
420
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
421 now = time(NULL);
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
422
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
423 lock_path = t_strconcat(path, set->lock_suffix, NULL);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
424 stale_notify_threshold = set->stale_timeout / 2;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
425 max_wait_time = (flags & DOTLOCK_CREATE_FLAG_NONBLOCK) != 0 ? 0 :
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
426 now + set->timeout;
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
427 tmp_path = t_str_new(256);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
428
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
429 memset(&lock_info, 0, sizeof(lock_info));
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
430 lock_info.path = path;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
431 lock_info.set = set;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
432 lock_info.lock_path = lock_path;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
433 lock_info.fd = -1;
5938
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
434 lock_info.use_io_notify = set->use_io_notify;
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
435 ;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
436 last_notify = 0; do_wait = FALSE;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
437
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
438 do {
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
439 if (do_wait) {
5938
805f2527a982 If use_io_notify dotlock setting is enabled, use I/O notify loop for waiting
Timo Sirainen <tss@iki.fi>
parents: 5664
diff changeset
440 dotlock_wait(&lock_info);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
441 do_wait = FALSE;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
442 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
443
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
444 ret = check_lock(now, &lock_info);
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
445 if (ret < 0)
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
446 break;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
447
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
448 if (ret == 1) {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
449 if ((flags & DOTLOCK_CREATE_FLAG_CHECKONLY) != 0)
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
450 break;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
451
3564
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
452 ret = set->use_excl_lock ?
d3f246330d37 Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents: 3174
diff changeset
453 try_create_lock_excl(&lock_info, write_pid) :
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
454 try_create_lock_hardlink(&lock_info, write_pid,
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
455 tmp_path);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
456 if (ret != 0)
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
457 break;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
458 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
459
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
460 do_wait = TRUE;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
461 if (last_notify != now && set->callback != NULL) {
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
462 last_notify = now;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
463 change_secs = now - lock_info.last_change;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
464 wait_left = max_wait_time - now;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
465
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
466 t_push();
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
467 if (change_secs >= stale_notify_threshold &&
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
468 change_secs <= wait_left) {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
469 unsigned int secs_left =
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
470 set->stale_timeout < change_secs ?
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
471 0 : set->stale_timeout - change_secs;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
472 if (!set->callback(secs_left, TRUE,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
473 set->context)) {
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
474 /* we don't want to override */
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
475 lock_info.last_change = now;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
476 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
477 } else {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
478 (void)set->callback(wait_left, FALSE,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
479 set->context);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
480 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
481 t_pop();
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
482 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
483
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
484 now = time(NULL);
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
485 } while (now < max_wait_time);
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
486
3174
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
487 if (ret > 0) {
3132
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
488 if (fstat(lock_info.fd, &st) < 0) {
3174
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
489 i_error("fstat(%s) failed: %m", lock_path);
3132
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
490 ret = -1;
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
491 } else {
3576
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
492 /* successful dotlock creation */
3132
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
493 dotlock->dev = st.st_dev;
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
494 dotlock->ino = st.st_ino;
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
495
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
496 dotlock->path = i_strdup(path);
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
497 dotlock->fd = lock_info.fd;
3576
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
498 dotlock->lock_time = now;
3174
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
499 lock_info.fd = -1;
5662
fdc30be3b5e5 If created dotlock file's ctime is smaller than the current time (NFS
Timo Sirainen <tss@iki.fi>
parents: 5590
diff changeset
500
5664
b796701a6927 Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents: 5663
diff changeset
501 if (st.st_ctime + MAX_TIME_DIFF < now ||
b796701a6927 Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents: 5663
diff changeset
502 st.st_ctime - MAX_TIME_DIFF > now) {
5662
fdc30be3b5e5 If created dotlock file's ctime is smaller than the current time (NFS
Timo Sirainen <tss@iki.fi>
parents: 5590
diff changeset
503 i_warning("Created dotlock file's timestamp is "
5663
3c026711c35b Log a warning if filesystem's clock is +-30 different from the system clock
Timo Sirainen <tss@iki.fi>
parents: 5662
diff changeset
504 "different than current time "
3c026711c35b Log a warning if filesystem's clock is +-30 different from the system clock
Timo Sirainen <tss@iki.fi>
parents: 5662
diff changeset
505 "(%s vs %s): %s", dec2str(st.st_ctime),
5662
fdc30be3b5e5 If created dotlock file's ctime is smaller than the current time (NFS
Timo Sirainen <tss@iki.fi>
parents: 5590
diff changeset
506 dec2str(now), path);
fdc30be3b5e5 If created dotlock file's ctime is smaller than the current time (NFS
Timo Sirainen <tss@iki.fi>
parents: 5590
diff changeset
507 }
3132
3281674159b5 Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents: 3106
diff changeset
508 }
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
509 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
510
3174
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
511 if (lock_info.fd != -1) {
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
512 int old_errno = errno;
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
513
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
514 if (close(lock_info.fd) < 0)
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
515 i_error("close(%s) failed: %m", lock_path);
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
516 errno = old_errno;
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
517 }
4308
b0c4e02d715b If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents: 4307
diff changeset
518 if (lock_info.temp_path != NULL) {
b0c4e02d715b If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents: 4307
diff changeset
519 if (unlink(lock_info.temp_path) < 0)
b0c4e02d715b If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents: 4307
diff changeset
520 i_error("unlink(%s) failed: %m", lock_info.temp_path);
b0c4e02d715b If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents: 4307
diff changeset
521 }
3174
091821cac480 If we failed to lock the dotlock, don't try to close the file twice.
Timo Sirainen <tss@iki.fi>
parents: 3132
diff changeset
522
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
523 if (ret == 0)
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
524 errno = EAGAIN;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
525 return ret;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
526 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
527
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
528 static void file_dotlock_free(struct dotlock *dotlock)
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
529 {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
530 int old_errno;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
531
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
532 if (dotlock->fd != -1) {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
533 old_errno = errno;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
534 if (close(dotlock->fd) < 0)
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
535 i_error("close(%s) failed: %m", dotlock->path);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
536 dotlock->fd = -1;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
537 errno = old_errno;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
538 }
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
539
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
540 i_free(dotlock->path);
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
541 i_free(dotlock->lock_path);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
542 i_free(dotlock);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
543 }
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
544
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
545 int file_dotlock_create(const struct dotlock_settings *set, const char *path,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
546 enum dotlock_create_flags flags,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
547 struct dotlock **dotlock_r)
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
548 {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
549 struct dotlock *dotlock;
2720
b0474af863ab Write host:pid into lock file *before* link()ing it into real lock file.
Timo Sirainen <tss@iki.fi>
parents: 2651
diff changeset
550 const char *lock_path;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
551 struct stat st;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
552 int fd, ret;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
553
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
554 *dotlock_r = NULL;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
555
4113
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
556 t_push();
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
557 dotlock = file_dotlock_alloc(set);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
558 lock_path = t_strconcat(path, dotlock->settings.lock_suffix, NULL);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
559
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
560 ret = dotlock_create(path, dotlock, flags, TRUE);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
561 if (ret <= 0 || (flags & DOTLOCK_CREATE_FLAG_CHECKONLY) != 0) {
4113
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
562 file_dotlock_free(dotlock);
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
563 t_pop();
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
564 return ret;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
565 }
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
566
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
567 fd = dotlock->fd;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
568 dotlock->fd = -1;
2077
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
569
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
570 if (close(fd) < 0) {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
571 i_error("close(%s) failed: %m", lock_path);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
572 file_dotlock_free(dotlock);
4113
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
573 t_pop();
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
574 return -1;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
575 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
576
2077
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
577 /* some NFS implementations may have used cached mtime in previous
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
578 fstat() call. Check again to avoid "dotlock was modified" errors. */
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
579 if (stat(lock_path, &st) < 0) {
5590
eb4902fc7693 Give a better error message if dotlock is deleted immediately under us (or
Timo Sirainen <tss@iki.fi>
parents: 5543
diff changeset
580 if (errno != ENOENT)
eb4902fc7693 Give a better error message if dotlock is deleted immediately under us (or
Timo Sirainen <tss@iki.fi>
parents: 5543
diff changeset
581 i_error("stat(%s) failed: %m", lock_path);
eb4902fc7693 Give a better error message if dotlock is deleted immediately under us (or
Timo Sirainen <tss@iki.fi>
parents: 5543
diff changeset
582 else {
eb4902fc7693 Give a better error message if dotlock is deleted immediately under us (or
Timo Sirainen <tss@iki.fi>
parents: 5543
diff changeset
583 i_error("dotlock %s was immediately deleted under us",
eb4902fc7693 Give a better error message if dotlock is deleted immediately under us (or
Timo Sirainen <tss@iki.fi>
parents: 5543
diff changeset
584 lock_path);
eb4902fc7693 Give a better error message if dotlock is deleted immediately under us (or
Timo Sirainen <tss@iki.fi>
parents: 5543
diff changeset
585 }
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
586 file_dotlock_free(dotlock);
4113
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
587 t_pop();
2077
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
588 return -1;
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
589 }
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
590 /* extra sanity check won't hurt.. */
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
591 if (st.st_dev != dotlock->dev || st.st_ino != dotlock->ino) {
2077
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
592 i_error("dotlock %s was immediately recreated under us",
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
593 lock_path);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
594 file_dotlock_free(dotlock);
4113
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
595 t_pop();
2077
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
596 return -1;
d5b20d679b8a Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents: 2025
diff changeset
597 }
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
598 dotlock->mtime = st.st_mtime;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
599
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
600 *dotlock_r = dotlock;
4113
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
601 t_pop();
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
602 return 1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
603 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
604
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
605 int file_dotlock_delete(struct dotlock **dotlock_p)
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
606 {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
607 struct dotlock *dotlock;
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
608 const char *lock_path;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
609 struct stat st;
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
610
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
611 dotlock = *dotlock_p;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
612 *dotlock_p = NULL;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
613
3715
9680bd9e6346 Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents: 3591
diff changeset
614 lock_path = file_dotlock_get_lock_path(dotlock);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
615 if (lstat(lock_path, &st) < 0) {
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
616 if (errno == ENOENT) {
3576
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
617 i_warning("Our dotlock file %s was deleted "
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
618 "(kept it %d secs)", lock_path,
5352
19338f65fa9a Log "kept it for n seconds", not -n seconds.
Timo Sirainen <tss@iki.fi>
parents: 4308
diff changeset
619 (int)(time(NULL) - dotlock->lock_time));
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
620 file_dotlock_free(dotlock);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
621 return 0;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
622 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
623
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
624 i_error("lstat(%s) failed: %m", lock_path);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
625 file_dotlock_free(dotlock);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
626 return -1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
627 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
628
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
629 if (dotlock->ino != st.st_ino ||
1359
bbcbe27926ad Use different warning message for dotlock mtime change.
Timo Sirainen <tss@iki.fi>
parents: 1313
diff changeset
630 !CMP_DEV_T(dotlock->dev, st.st_dev)) {
3576
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
631 i_warning("Our dotlock file %s was overridden "
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
632 "(kept it %d secs)", lock_path,
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
633 (int)(dotlock->lock_time - time(NULL)));
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents: 1825
diff changeset
634 errno = EEXIST;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
635 file_dotlock_free(dotlock);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
636 return 0;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
637 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
638
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
639 if (dotlock->mtime != st.st_mtime && dotlock->fd == -1) {
1359
bbcbe27926ad Use different warning message for dotlock mtime change.
Timo Sirainen <tss@iki.fi>
parents: 1313
diff changeset
640 i_warning("Our dotlock file %s was modified (%s vs %s), "
3576
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
641 "assuming it wasn't overridden (kept it %d secs)",
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
642 lock_path,
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
643 dec2str(dotlock->mtime), dec2str(st.st_mtime),
5352
19338f65fa9a Log "kept it for n seconds", not -n seconds.
Timo Sirainen <tss@iki.fi>
parents: 4308
diff changeset
644 (int)(time(NULL) - dotlock->lock_time));
1359
bbcbe27926ad Use different warning message for dotlock mtime change.
Timo Sirainen <tss@iki.fi>
parents: 1313
diff changeset
645 }
bbcbe27926ad Use different warning message for dotlock mtime change.
Timo Sirainen <tss@iki.fi>
parents: 1313
diff changeset
646
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
647 if (unlink(lock_path) < 0) {
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
648 if (errno == ENOENT) {
3576
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
649 i_warning("Our dotlock file %s was deleted "
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
650 "(kept it %d secs)", lock_path,
5352
19338f65fa9a Log "kept it for n seconds", not -n seconds.
Timo Sirainen <tss@iki.fi>
parents: 4308
diff changeset
651 (int)(time(NULL) - dotlock->lock_time));
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
652 file_dotlock_free(dotlock);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
653 return 0;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
654 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
655
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
656 i_error("unlink(%s) failed: %m", lock_path);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
657 file_dotlock_free(dotlock);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
658 return -1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
659 }
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
660
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
661 file_dotlock_free(dotlock);
1161
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
662 return 1;
fc5d2e44cc5e Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
663 }
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
664
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
665 int file_dotlock_open(const struct dotlock_settings *set, const char *path,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
666 enum dotlock_create_flags flags,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
667 struct dotlock **dotlock_r)
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
668 {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
669 struct dotlock *dotlock;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
670 int ret;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
671
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
672 dotlock = file_dotlock_alloc(set);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
673
4113
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
674 t_push();
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
675 ret = dotlock_create(path, dotlock, flags, FALSE);
4113
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
676 t_pop();
770c06dc9adb Added some t_push/t_pop calls
Timo Sirainen <tss@iki.fi>
parents: 3982
diff changeset
677
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
678 if (ret <= 0) {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
679 file_dotlock_free(dotlock);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
680 *dotlock_r = NULL;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
681 return -1;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
682 }
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
683
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
684 *dotlock_r = dotlock;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
685 return dotlock->fd;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
686 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
687
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
688 int file_dotlock_replace(struct dotlock **dotlock_p,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
689 enum dotlock_replace_flags flags)
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
690 {
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
691 struct dotlock *dotlock;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
692 struct stat st, st2;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
693 const char *lock_path;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
694 int fd;
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
695
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
696 dotlock = *dotlock_p;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
697 *dotlock_p = NULL;
1974
d85f71ffeb8f file_dotlock_open/delete/replace now has lock_suffix parameter. NULL
Timo Sirainen <tss@iki.fi>
parents: 1915
diff changeset
698
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
699 fd = dotlock->fd;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
700 if ((flags & DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) != 0)
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
701 dotlock->fd = -1;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
702
3715
9680bd9e6346 Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents: 3591
diff changeset
703 lock_path = file_dotlock_get_lock_path(dotlock);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
704 if ((flags & DOTLOCK_REPLACE_FLAG_VERIFY_OWNER) != 0) {
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
705 if (fstat(fd, &st) < 0) {
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
706 i_error("fstat(%s) failed: %m", lock_path);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
707 file_dotlock_free(dotlock);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
708 return -1;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
709 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
710
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
711 if (lstat(lock_path, &st2) < 0) {
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
712 i_error("lstat(%s) failed: %m", lock_path);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
713 file_dotlock_free(dotlock);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
714 return -1;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
715 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
716
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
717 if (st.st_ino != st2.st_ino ||
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
718 !CMP_DEV_T(st.st_dev, st2.st_dev)) {
3576
827c7137fd78 If dotlock is overwritten/deleted, say in the error message how long we kept
Timo Sirainen <tss@iki.fi>
parents: 3564
diff changeset
719 i_warning("Our dotlock file %s was overridden "
3591
69f731759776 compiler warning fix
Timo Sirainen <tss@iki.fi>
parents: 3576
diff changeset
720 "(kept it %d secs)", lock_path,
5352
19338f65fa9a Log "kept it for n seconds", not -n seconds.
Timo Sirainen <tss@iki.fi>
parents: 4308
diff changeset
721 (int)(time(NULL) - dotlock->lock_time));
1915
79790750c349 importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents: 1825
diff changeset
722 errno = EEXIST;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
723 file_dotlock_free(dotlock);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
724 return 0;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
725 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
726 }
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
727
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
728 if (rename(lock_path, dotlock->path) < 0) {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
729 i_error("rename(%s, %s) failed: %m", lock_path, dotlock->path);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
730 file_dotlock_free(dotlock);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
731 return -1;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
732 }
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
733 file_dotlock_free(dotlock);
1597
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
734 return 1;
9f503b7851ab Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents: 1369
diff changeset
735 }
3715
9680bd9e6346 Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents: 3591
diff changeset
736
3982
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
737 int file_dotlock_touch(struct dotlock *dotlock)
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
738 {
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
739 time_t now = time(NULL);
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
740 struct utimbuf buf;
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
741 const char *lock_path;
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
742 int ret = 0;
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
743
4306
ce3c09a75b87 Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents: 4211
diff changeset
744 if (dotlock->mtime == now)
3982
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
745 return 0;
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
746
4306
ce3c09a75b87 Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents: 4211
diff changeset
747 dotlock->mtime = now;
3982
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
748 buf.actime = buf.modtime = now;
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
749
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
750 t_push();
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
751 lock_path = file_dotlock_get_lock_path(dotlock);
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
752 if (utime(lock_path, &buf) < 0) {
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
753 i_error("utime(%s) failed: %m", lock_path);
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
754 ret = -1;
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
755 }
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
756 t_pop();
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
757 return ret;
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
758 }
15c48c43cc75 Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents: 3981
diff changeset
759
3715
9680bd9e6346 Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents: 3591
diff changeset
760 const char *file_dotlock_get_lock_path(struct dotlock *dotlock)
9680bd9e6346 Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents: 3591
diff changeset
761 {
4207
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
762 if (dotlock->lock_path == NULL) {
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
763 dotlock->lock_path =
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
764 i_strconcat(dotlock->path,
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
765 dotlock->settings.lock_suffix, NULL);
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
766 }
96f3908b7c34 file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents: 4113
diff changeset
767 return dotlock->lock_path;
3715
9680bd9e6346 Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents: 3591
diff changeset
768 }