Mercurial > dovecot > core-2.2
annotate src/lib/file-dotlock.c @ 22955:812e5c961328
fts: Indexing virtual mailbox didn't always index the last mails
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 03 May 2018 18:33:00 +0300 |
parents | cb108f786fb4 |
children |
rev | line source |
---|---|
22713
cb108f786fb4
Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21519
diff
changeset
|
1 /* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */ |
1161
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" |
20684
d57011982d77
lib: Track how much time has been spent on waiting for locks.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
8 #include "file-lock.h" |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
9 #include "eacces-error.h" |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include "write-full.h" |
5543
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
11 #include "safe-mkstemp.h" |
5969
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
12 #include "nfs-workarounds.h" |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #include "file-dotlock.h" |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
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
|
15 #include <stdio.h> |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 #include <signal.h> |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 #include <time.h> |
3982
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
18 #include <utime.h> |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 #include <sys/stat.h> |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 |
1974
d85f71ffeb8f
file_dotlock_open/delete/replace now has lock_suffix parameter. NULL
Timo Sirainen <tss@iki.fi>
parents:
1915
diff
changeset
|
21 #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
|
22 |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 /* 0.1 .. 0.2msec */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 #define LOCK_RANDOM_USLEEP_TIME (100000 + (unsigned int)rand() % 100000) |
8691
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
25 /* Maximum 3 second wait between dotlock checks */ |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
26 #define LOCK_MAX_WAIT_USECS (1000000 * 3) |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 |
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
|
28 /* 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
|
29 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
|
30 #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
|
31 |
5664
b796701a6927
Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents:
5663
diff
changeset
|
32 /* 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
|
33 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
|
34 #define MAX_TIME_DIFF 30 |
13550
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
35 /* NFS may return a cached mtime in stat(). A later non-cached stat() may |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
36 return a slightly different mtime. Allow the difference to be this much |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
37 and still consider it to be the same mtime. */ |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
38 #define FILE_DOTLOCK_MAX_STAT_MTIME_DIFF 1 |
5664
b796701a6927
Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents:
5663
diff
changeset
|
39 |
3106 | 40 struct dotlock { |
41 struct dotlock_settings settings; | |
42 | |
43 dev_t dev; | |
44 ino_t ino; | |
45 time_t mtime; | |
46 | |
47 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
|
48 char *lock_path; |
3106 | 49 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
|
50 |
4306
ce3c09a75b87
Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents:
4211
diff
changeset
|
51 time_t lock_time; |
3106 | 52 }; |
53 | |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
54 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
|
55 dev_t dev; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
56 ino_t ino; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
57 off_t size; |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
58 time_t ctime, mtime; |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
59 }; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
60 |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 struct lock_info { |
3106 | 62 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
|
63 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
|
64 int fd; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
66 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
|
67 struct file_change_info file_info; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 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
|
70 time_t last_change; |
8691
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
71 unsigned int wait_usecs; |
6647
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
72 |
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
73 unsigned int have_pid:1; |
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
74 unsigned int pid_read:1; |
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
75 unsigned int use_io_notify:1; |
6799
c1bd43be8f9a
Don't flush attribute cache the first time when stating a lock file. Usually
Timo Sirainen <tss@iki.fi>
parents:
6797
diff
changeset
|
76 unsigned int lock_stated:1; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 }; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 |
3106 | 79 static struct dotlock * |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
80 file_dotlock_alloc(const struct dotlock_settings *settings, const char *path) |
3106 | 81 { |
82 struct dotlock *dotlock; | |
83 | |
84 dotlock = i_new(struct dotlock, 1); | |
85 dotlock->settings = *settings; | |
86 if (dotlock->settings.lock_suffix == NULL) | |
87 dotlock->settings.lock_suffix = DEFAULT_LOCK_SUFFIX; | |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
88 dotlock->path = i_strdup(path); |
3106 | 89 dotlock->fd = -1; |
90 | |
91 return dotlock; | |
92 } | |
93 | |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 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
|
95 { |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 char buf[512], *host; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 int fd; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 ssize_t ret; |
7065
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
99 pid_t pid; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 fd = open(lock_path, O_RDONLY); |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 if (fd == -1) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 return -1; /* ignore the actual error */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 /* read line */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 ret = read(fd, buf, sizeof(buf)-1); |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14688
diff
changeset
|
107 i_close_fd(&fd); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 if (ret <= 0) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 /* fix the string */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 if (buf[ret-1] == '\n') |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 ret--; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 buf[ret] = '\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 /* it should contain pid:host */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 host = strchr(buf, ':'); |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 if (host == NULL) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 *host++ = '\0'; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 /* host must be ours */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 if (strcmp(host, my_hostname) != 0) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 |
11086
260e190306b0
Started using str_to_*() functions instead of libc's ones.
Timo Sirainen <tss@iki.fi>
parents:
11039
diff
changeset
|
126 if (str_to_pid(buf, &pid) < 0) |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 return -1; |
7065
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
128 if (pid <= 0) |
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
129 return -1; |
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
130 return pid; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
132 |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
133 static bool |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
134 update_change_info(const struct stat *st, struct file_change_info *change, |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
135 time_t *last_change_r, time_t now, bool check_ctime) |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
136 { |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
137 /* ctime is checked only if we're not doing NFS attribute cache |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
138 flushes. it changes them. */ |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
139 if (change->ino != st->st_ino || !CMP_DEV_T(change->dev, st->st_dev) || |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
140 (change->ctime != st->st_ctime && check_ctime) || |
6590
b9b201f5c581
Don't check ctime changes, because we change it ourself all the time when
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
141 change->mtime != st->st_mtime || change->size != st->st_size) { |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
142 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
|
143 |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
144 if (change->ctime == 0) { |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
145 /* First check, set last_change to file's change time. |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
146 Use mtime instead if it's higher, but only if it's |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
147 not higher than current time, because the mtime |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
148 can also be used for keeping metadata. */ |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
149 change_time = st->st_mtime <= now && |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
150 (st->st_mtime > st->st_ctime || !check_ctime) ? |
6590
b9b201f5c581
Don't check ctime changes, because we change it ourself all the time when
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
151 st->st_mtime : st->st_ctime; |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
152 } |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
153 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
|
154 *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
|
155 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
|
156 change->dev = st->st_dev; |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
157 change->ctime = st->st_ctime; |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
158 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
|
159 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
|
160 return TRUE; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
161 } |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
162 return FALSE; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
163 } |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
164 |
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
|
165 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
|
166 bool *changed_r) |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 { |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
168 struct stat st; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 |
6799
c1bd43be8f9a
Don't flush attribute cache the first time when stating a lock file. Usually
Timo Sirainen <tss@iki.fi>
parents:
6797
diff
changeset
|
170 /* don't waste time flushing attribute cache the first time we're here. |
c1bd43be8f9a
Don't flush attribute cache the first time when stating a lock file. Usually
Timo Sirainen <tss@iki.fi>
parents:
6797
diff
changeset
|
171 if it's stale we'll get back here soon. */ |
6857 | 172 if (lock_info->set->nfs_flush && lock_info->lock_stated) { |
173 nfs_flush_file_handle_cache(lock_info->lock_path); | |
6829
dbab5e592577
NFS cache flushing APIs changed and backend implements it a bit differently.
Timo Sirainen <tss@iki.fi>
parents:
6819
diff
changeset
|
174 nfs_flush_attr_cache_unlocked(lock_info->lock_path); |
6857 | 175 } |
6799
c1bd43be8f9a
Don't flush attribute cache the first time when stating a lock file. Usually
Timo Sirainen <tss@iki.fi>
parents:
6797
diff
changeset
|
176 |
c1bd43be8f9a
Don't flush attribute cache the first time when stating a lock file. Usually
Timo Sirainen <tss@iki.fi>
parents:
6797
diff
changeset
|
177 lock_info->lock_stated = TRUE; |
5969
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
178 if (nfs_safe_lstat(lock_info->lock_path, &st) < 0) { |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
179 if (errno != ENOENT) { |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
180 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
|
181 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 return 1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
184 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
185 |
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
|
186 *changed_r = update_change_info(&st, &lock_info->lock_info, |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
187 &lock_info->last_change, now, |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
188 !lock_info->set->nfs_flush); |
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
|
189 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
|
190 } |
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
|
191 |
7053
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
192 static int dotlock_override(struct lock_info *lock_info) |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
193 { |
19136
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
194 if (i_unlink_if_exists(lock_info->lock_path) < 0) |
7053
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
195 return -1; |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
196 |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
197 /* make sure we sleep for a while after overriding the lock file. |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
198 otherwise another process might try to override it at the same time |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
199 and unlink our newly created dotlock. */ |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
200 if (lock_info->use_io_notify) |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
201 usleep(LOCK_RANDOM_USLEEP_TIME); |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
202 return 0; |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
203 } |
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
204 |
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
|
205 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
|
206 { |
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 time_t stale_timeout = lock_info->set->stale_timeout; |
6647
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
208 pid_t pid = -1; |
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
|
209 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
|
210 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
|
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 ((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
|
213 return ret; |
6647
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
214 if (changed || !lock_info->pid_read) { |
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
|
215 /* 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
|
216 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
|
217 don't bother to read its PID. */ |
6647
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
218 if (lock_info->lock_info.mtime >= now - STALE_PID_CHECK_SECS) |
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
219 lock_info->pid_read = FALSE; |
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
220 else { |
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
221 pid = read_local_pid(lock_info->lock_path); |
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
222 lock_info->pid_read = TRUE; |
6dd5df1c1ec9
If dotlock was less than 2 seconds old, we never read PID from it. Now it's
Timo Sirainen <tss@iki.fi>
parents:
6593
diff
changeset
|
223 } |
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
|
224 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
|
225 } 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
|
226 /* 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
|
227 } 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
|
228 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
|
229 /* 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
|
230 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
|
231 } |
ec6cd5dcf618
Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents:
2630
diff
changeset
|
232 |
ec6cd5dcf618
Re-read the PID from lock file every time before checking if it exists,
Timo Sirainen <tss@iki.fi>
parents:
2630
diff
changeset
|
233 /* 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
|
234 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
|
235 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
|
236 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
|
237 lock_info->have_pid = pid != -1; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
238 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 |
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
|
240 if (lock_info->have_pid) { |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
241 /* 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
|
242 if (kill(pid, 0) == 0 || errno != ESRCH) { |
7456 | 243 if (pid != getpid()) { |
244 /* process exists, don't override */ | |
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
|
245 return 0; |
7456 | 246 } |
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
|
247 /* 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
|
248 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
|
249 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
|
250 } |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
251 |
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
|
252 /* 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
|
253 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
|
254 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
|
255 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
|
256 |
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
|
257 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
|
258 /* still there, go ahead and override it */ |
7053
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
259 return dotlock_override(lock_info); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
260 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
261 return 1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
262 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
263 |
3106 | 264 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
|
265 /* 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
|
266 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
|
267 } |
486a5dbbc9c8
Check that dotlock PID exists even if we don't do stale lock timeouting.
Timo Sirainen <tss@iki.fi>
parents:
2720
diff
changeset
|
268 |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
269 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
|
270 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
|
271 |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
272 /* 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
|
273 file we're protecting. */ |
6857 | 274 if (lock_info->set->nfs_flush) { |
275 nfs_flush_file_handle_cache(lock_info->path); | |
6829
dbab5e592577
NFS cache flushing APIs changed and backend implements it a bit differently.
Timo Sirainen <tss@iki.fi>
parents:
6819
diff
changeset
|
276 nfs_flush_attr_cache_maybe_locked(lock_info->path); |
6857 | 277 } |
5969
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
278 if (nfs_safe_stat(lock_info->path, &st) < 0) { |
1624 | 279 if (errno == ENOENT) { |
280 /* file doesn't exist. treat it as if | |
281 it hasn't changed */ | |
282 } else { | |
283 i_error("stat(%s) failed: %m", lock_info->path); | |
284 return -1; | |
285 } | |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
286 } else { |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
287 (void)update_change_info(&st, &lock_info->file_info, |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
288 &lock_info->last_change, now, |
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
289 !lock_info->set->nfs_flush); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
290 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
291 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
292 |
3106 | 293 if (now > lock_info->last_change + stale_timeout) { |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
294 /* no changes for a while, assume stale lock */ |
7053
622fa7cef9db
If we use notify I/O to watch for dotlock deletion, make sure we still sleep
Timo Sirainen <tss@iki.fi>
parents:
6940
diff
changeset
|
295 return dotlock_override(lock_info); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
297 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
298 return 0; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 |
10131
9ef0821a2ce7
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9693
diff
changeset
|
301 static int file_write_pid(int fd, const char *path, bool nfs_flush) |
3564
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
302 { |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
303 const char *str; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
304 |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
305 /* write our pid and host, if possible */ |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
306 str = t_strdup_printf("%s:%s", my_pid, my_hostname); |
10131
9ef0821a2ce7
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9693
diff
changeset
|
307 if (write_full(fd, str, strlen(str)) < 0 || |
9ef0821a2ce7
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9693
diff
changeset
|
308 (nfs_flush && fdatasync(fd) < 0)) { |
3564
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
309 /* failed, leave it empty then */ |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
310 if (ftruncate(fd, 0) < 0) { |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
311 i_error("ftruncate(%s) failed: %m", path); |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
312 return -1; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
313 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
314 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
315 return 0; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
316 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
317 |
4207
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
318 static int try_create_lock_hardlink(struct lock_info *lock_info, bool write_pid, |
12711
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
319 string_t *tmp_path, time_t now) |
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
|
320 { |
3106 | 321 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
|
322 const char *p; |
9476
d394cca843a9
safe_mkstemp() was used incorrectly. umask() no longer changes its behavior.
Timo Sirainen <tss@iki.fi>
parents:
9192
diff
changeset
|
323 mode_t old_mask; |
12711
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
324 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
|
325 |
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 (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
|
327 /* 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
|
328 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
|
329 |
4207
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
330 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
|
331 |
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
332 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
|
333 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
|
334 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
|
335 /* 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
|
336 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
|
337 p - lock_info->lock_path); |
4211
044889ec438e
Fixed last change: added missing '/' back
Timo Sirainen <tss@iki.fi>
parents:
4207
diff
changeset
|
338 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
|
339 } |
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
340 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
|
341 } else { |
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
342 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
|
343 /* 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
|
344 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
|
345 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
|
346 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
|
347 } |
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
348 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
|
349 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
|
350 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
351 |
9476
d394cca843a9
safe_mkstemp() was used incorrectly. umask() no longer changes its behavior.
Timo Sirainen <tss@iki.fi>
parents:
9192
diff
changeset
|
352 old_mask = umask(0666); |
d394cca843a9
safe_mkstemp() was used incorrectly. umask() no longer changes its behavior.
Timo Sirainen <tss@iki.fi>
parents:
9192
diff
changeset
|
353 lock_info->fd = safe_mkstemp(tmp_path, 0666 ^ old_mask, |
5543
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
354 (uid_t)-1, (gid_t)-1); |
9476
d394cca843a9
safe_mkstemp() was used incorrectly. umask() no longer changes its behavior.
Timo Sirainen <tss@iki.fi>
parents:
9192
diff
changeset
|
355 umask(old_mask); |
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
|
356 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
|
357 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
|
358 |
5543
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
359 if (write_pid) { |
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
360 if (file_write_pid(lock_info->fd, |
10131
9ef0821a2ce7
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9693
diff
changeset
|
361 str_c(tmp_path), |
9ef0821a2ce7
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9693
diff
changeset
|
362 lock_info->set->nfs_flush) < 0) { |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14688
diff
changeset
|
363 i_close_fd(&lock_info->fd); |
5543
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
364 return -1; |
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
365 } |
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
366 } |
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
367 |
4207
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
368 lock_info->temp_path = str_c(tmp_path); |
12711
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
369 } else if (fstat(lock_info->fd, &st) < 0) { |
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
370 i_error("fstat(%s) failed: %m", lock_info->temp_path); |
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
371 return -1; |
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
372 } else if (st.st_ctime < now) { |
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
373 /* we've been waiting for a while. |
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
374 refresh the file's timestamp. */ |
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
375 if (utime(lock_info->temp_path, NULL) < 0) |
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
376 i_error("utime(%s) failed: %m", lock_info->temp_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
|
377 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
378 |
6813
575235932194
nfs_safe_link(): Support linking files without original link count=1. Use it
Timo Sirainen <tss@iki.fi>
parents:
6812
diff
changeset
|
379 if (nfs_safe_link(lock_info->temp_path, |
575235932194
nfs_safe_link(): Support linking files without original link count=1. Use it
Timo Sirainen <tss@iki.fi>
parents:
6812
diff
changeset
|
380 lock_info->lock_path, TRUE) < 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
|
381 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
|
382 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
|
383 |
7340
09cdd4330d73
file_dotlock_create(): Don't log an EACCES failures.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
384 if (errno != EACCES) { |
09cdd4330d73
file_dotlock_create(): Don't log an EACCES failures.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
385 i_error("link(%s, %s) failed: %m", |
09cdd4330d73
file_dotlock_create(): Don't log an EACCES failures.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
386 lock_info->temp_path, lock_info->lock_path); |
09cdd4330d73
file_dotlock_create(): Don't log an EACCES failures.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
387 } |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
388 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
|
389 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
390 |
19136
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
391 if (i_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
|
392 /* 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
|
393 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
394 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
|
395 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
|
396 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
397 |
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
|
398 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
|
399 { |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
400 int fd; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
401 |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
402 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
|
403 if (fd == -1) { |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
404 if (errno == EEXIST) |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
405 return 0; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
406 |
7340
09cdd4330d73
file_dotlock_create(): Don't log an EACCES failures.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
407 if (errno != ENOENT && errno != EACCES) |
6775 | 408 i_error("open(%s) failed: %m", lock_info->lock_path); |
3564
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
409 return -1; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
410 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
411 |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
412 if (write_pid) { |
10131
9ef0821a2ce7
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9693
diff
changeset
|
413 if (file_write_pid(fd, lock_info->lock_path, |
9ef0821a2ce7
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9693
diff
changeset
|
414 lock_info->set->nfs_flush) < 0) { |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14688
diff
changeset
|
415 i_close_fd(&fd); |
3564
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
416 return -1; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
417 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
418 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
419 |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
420 lock_info->fd = fd; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
421 return 1; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
422 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
423 |
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
|
424 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
|
425 { |
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
|
426 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
|
427 } |
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
|
428 |
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
|
429 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
|
430 { |
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
|
431 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
|
432 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
|
433 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
|
434 |
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 if (!lock_info->use_io_notify) { |
8691
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
436 usleep(lock_info->wait_usecs); |
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
|
437 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
|
438 } |
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
|
439 |
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 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
|
441 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
|
442 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
|
443 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
|
444 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
|
445 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
|
446 /* 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
|
447 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
|
448 return; |
7457
940641318f12
Renamed IO_NOTIFY_DISABLED to IO_NOTIFY_NOSUPPORT. IO_NOTIFY_NOSUPPORT is
Timo Sirainen <tss@iki.fi>
parents:
7456
diff
changeset
|
449 case IO_NOTIFY_NOSUPPORT: |
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
|
450 /* 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
|
451 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
|
452 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
|
453 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
|
454 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
|
455 } |
7456 | 456 /* timeout after a random time even when using notify, since it |
457 doesn't work reliably with e.g. NFS. */ | |
8691
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
458 to = timeout_add(lock_info->wait_usecs/1000, |
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
|
459 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
|
460 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
|
461 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
|
462 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
|
463 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
|
464 } |
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
|
465 |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
466 static int |
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
467 dotlock_create(struct dotlock *dotlock, enum dotlock_create_flags flags, |
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
468 bool write_pid, const char **lock_path_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
|
469 { |
3106 | 470 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
|
471 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
|
472 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
|
473 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
|
474 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
|
475 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
|
476 time_t now, max_wait_time, last_notify; |
8691
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
477 time_t prev_last_change = 0, prev_wait_update = 0; |
4207
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
478 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
|
479 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
|
480 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
|
481 |
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 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
|
483 |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
484 lock_path = *lock_path_r = |
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
485 t_strconcat(dotlock->path, set->lock_suffix, NULL); |
3106 | 486 stale_notify_threshold = set->stale_timeout / 2; |
487 max_wait_time = (flags & DOTLOCK_CREATE_FLAG_NONBLOCK) != 0 ? 0 : | |
488 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
|
489 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
|
490 |
21389
59437f8764c6
global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
20948
diff
changeset
|
491 i_zero(&lock_info); |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
492 lock_info.path = dotlock->path; |
3106 | 493 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
|
494 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
|
495 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
|
496 lock_info.use_io_notify = set->use_io_notify; |
6799
c1bd43be8f9a
Don't flush attribute cache the first time when stating a lock file. Usually
Timo Sirainen <tss@iki.fi>
parents:
6797
diff
changeset
|
497 |
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
|
498 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
|
499 |
20684
d57011982d77
lib: Track how much time has been spent on waiting for locks.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
500 file_lock_wait_start(); |
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
|
501 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
|
502 if (do_wait) { |
8691
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
503 if (prev_last_change != lock_info.last_change) { |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
504 /* dotlock changed since last check, |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
505 reset the wait time */ |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
506 lock_info.wait_usecs = LOCK_RANDOM_USLEEP_TIME; |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
507 prev_last_change = lock_info.last_change; |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
508 prev_wait_update = now; |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
509 } else if (prev_wait_update != now && |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
510 lock_info.wait_usecs < LOCK_MAX_WAIT_USECS) { |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
511 /* we've been waiting for a while now, increase |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
512 the wait time to avoid wasting CPU */ |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
513 prev_wait_update = now; |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
514 lock_info.wait_usecs += lock_info.wait_usecs/2; |
81a146c34a5c
dotlocking: Increase the wait time 1,5 x every second until we reach 3 seconds.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
515 } |
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
|
516 dotlock_wait(&lock_info); |
12706
5a3c87124066
dotlocks: Refresh current time after having waited for a lock.
Timo Sirainen <tss@iki.fi>
parents:
11086
diff
changeset
|
517 now = time(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
|
518 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
519 |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
520 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
|
521 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
|
522 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
|
523 |
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 if (ret == 1) { |
3106 | 525 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
|
526 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
|
527 |
3564
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
528 ret = set->use_excl_lock ? |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
529 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
|
530 try_create_lock_hardlink(&lock_info, write_pid, |
12711
3582271a897e
dotlocks: When locking using hard links, make sure the dotlock's timestamp is new enough.
Timo Sirainen <tss@iki.fi>
parents:
12706
diff
changeset
|
531 tmp_path, now); |
14196
2ea29ab6f10f
file-dotlock: Avoid "timestamp is different than current time" errors during high disk I/O load.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
532 if (ret != 0) { |
2ea29ab6f10f
file-dotlock: Avoid "timestamp is different than current time" errors during high disk I/O load.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
533 /* if we succeeded, get the current time once |
2ea29ab6f10f
file-dotlock: Avoid "timestamp is different than current time" errors during high disk I/O load.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
534 more in case disk I/O usage was really high |
2ea29ab6f10f
file-dotlock: Avoid "timestamp is different than current time" errors during high disk I/O load.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
535 and it took a long time to create the lock */ |
2ea29ab6f10f
file-dotlock: Avoid "timestamp is different than current time" errors during high disk I/O load.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
536 now = time(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
|
537 break; |
14196
2ea29ab6f10f
file-dotlock: Avoid "timestamp is different than current time" errors during high disk I/O load.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
538 } |
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
|
539 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
540 |
3106 | 541 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
|
542 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
|
543 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
|
544 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
|
545 |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
546 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
|
547 change_secs <= wait_left) { |
3106 | 548 unsigned int secs_left = |
549 set->stale_timeout < change_secs ? | |
550 0 : set->stale_timeout - change_secs; | |
551 if (!set->callback(secs_left, TRUE, | |
552 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
|
553 /* 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
|
554 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
|
555 } |
9192
4f12a7c7f140
dotlocking: Don't generate "Will override dotlock in 0 secs" messages.
Timo Sirainen <tss@iki.fi>
parents:
8852
diff
changeset
|
556 } else if (wait_left > 0) { |
3106 | 557 (void)set->callback(wait_left, FALSE, |
558 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
|
559 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
560 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
561 |
11039 | 562 do_wait = TRUE; |
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
|
563 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
|
564 } while (now < max_wait_time); |
20948
ec169b08f74e
lib: Add FILE_LOCK_SLOW_WARNING_MSECS environment.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20684
diff
changeset
|
565 file_lock_wait_end(dotlock->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
|
566 |
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
|
567 if (ret > 0) { |
21519
9722a49567e0
global: Add asserts to make static analyzer happier.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
568 i_assert(lock_info.fd != -1); |
3132
3281674159b5
Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents:
3106
diff
changeset
|
569 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
|
570 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
|
571 ret = -1; |
3281674159b5
Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents:
3106
diff
changeset
|
572 } 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
|
573 /* 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
|
574 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
|
575 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
|
576 |
3281674159b5
Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents:
3106
diff
changeset
|
577 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
|
578 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
|
579 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
|
580 |
5664
b796701a6927
Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents:
5663
diff
changeset
|
581 if (st.st_ctime + MAX_TIME_DIFF < now || |
b796701a6927
Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents:
5663
diff
changeset
|
582 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
|
583 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
|
584 "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
|
585 "(%s vs %s): %s", dec2str(st.st_ctime), |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
586 dec2str(now), dotlock->path); |
5662
fdc30be3b5e5
If created dotlock file's ctime is smaller than the current time (NFS
Timo Sirainen <tss@iki.fi>
parents:
5590
diff
changeset
|
587 } |
3132
3281674159b5
Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents:
3106
diff
changeset
|
588 } |
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
|
589 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
590 |
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
|
591 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
|
592 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
|
593 |
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
|
594 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
|
595 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
|
596 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
|
597 } |
19136
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
598 if (lock_info.temp_path != NULL) |
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
599 i_unlink(lock_info.temp_path); |
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
|
600 |
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
|
601 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
|
602 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
|
603 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
|
604 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
605 |
6937 | 606 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
|
607 { |
6937 | 608 struct dotlock *dotlock = *_dotlock; |
3106 | 609 int old_errno; |
610 | |
6937 | 611 *_dotlock = NULL; |
612 | |
3106 | 613 if (dotlock->fd != -1) { |
614 old_errno = errno; | |
615 if (close(dotlock->fd) < 0) | |
616 i_error("close(%s) failed: %m", dotlock->path); | |
617 dotlock->fd = -1; | |
618 errno = old_errno; | |
619 } | |
620 | |
621 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
|
622 i_free(dotlock->lock_path); |
3106 | 623 i_free(dotlock); |
624 } | |
625 | |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
626 static int file_dotlock_create_real(struct dotlock *dotlock, |
6937 | 627 enum dotlock_create_flags flags) |
3106 | 628 { |
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
|
629 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
|
630 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
|
631 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
|
632 |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
633 ret = dotlock_create(dotlock, flags, TRUE, &lock_path); |
6937 | 634 if (ret <= 0 || (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
|
635 return ret; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
636 |
3106 | 637 fd = dotlock->fd; |
638 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
|
639 |
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
|
640 if (close(fd) < 0) { |
3106 | 641 i_error("close(%s) failed: %m", 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
|
642 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
|
643 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
644 |
5969
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
645 /* With NFS the writes may have been flushed only when closing the |
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
646 file. Get the mtime again after that to avoid "dotlock was modified" |
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
647 errors. */ |
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
648 if (lstat(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
|
649 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
|
650 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
|
651 else { |
eb4902fc7693
Give a better error message if dotlock is deleted immediately under us (or
Timo Sirainen <tss@iki.fi>
parents:
5543
diff
changeset
|
652 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
|
653 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
|
654 } |
2077
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
655 return -1; |
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
656 } |
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
657 /* extra sanity check won't hurt.. */ |
3106 | 658 if (st.st_dev != dotlock->dev || st.st_ino != dotlock->ino) { |
6803
9f40c3f83773
If file_dotlock_create() fails with "dotlock was immediately recreated under
Timo Sirainen <tss@iki.fi>
parents:
6799
diff
changeset
|
659 errno = ENOENT; |
2077
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
660 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
|
661 lock_path); |
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
662 return -1; |
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
663 } |
3106 | 664 dotlock->mtime = st.st_mtime; |
6937 | 665 return 1; |
666 } | |
667 | |
668 int file_dotlock_create(const struct dotlock_settings *set, const char *path, | |
669 enum dotlock_create_flags flags, | |
670 struct dotlock **dotlock_r) | |
671 { | |
672 struct dotlock *dotlock; | |
673 int ret; | |
674 | |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
675 dotlock = file_dotlock_alloc(set, path); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7134
diff
changeset
|
676 T_BEGIN { |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
677 ret = file_dotlock_create_real(dotlock, flags); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7134
diff
changeset
|
678 } T_END; |
6937 | 679 if (ret <= 0 || (flags & DOTLOCK_CREATE_FLAG_CHECKONLY) != 0) |
680 file_dotlock_free(&dotlock); | |
3106 | 681 |
682 *dotlock_r = dotlock; | |
6937 | 683 return ret; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
684 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
685 |
8178
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
686 static void dotlock_replaced_warning(struct dotlock *dotlock, bool deleted) |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
687 { |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
688 const char *lock_path; |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
689 time_t now = time(NULL); |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
690 |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
691 lock_path = file_dotlock_get_lock_path(dotlock); |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
692 if (dotlock->mtime == dotlock->lock_time) { |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
693 i_warning("Our dotlock file %s was %s " |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
694 "(locked %d secs ago, touched %d secs ago)", |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
695 lock_path, deleted ? "deleted" : "overridden", |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
696 (int)(now - dotlock->lock_time), |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
697 (int)(now - dotlock->mtime)); |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
698 } else { |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
699 i_warning("Our dotlock file %s was %s " |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
700 "(kept it %d secs)", lock_path, |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
701 deleted ? "deleted" : "overridden", |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
702 (int)(now - dotlock->lock_time)); |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
703 } |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
704 } |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
705 |
13550
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
706 static bool file_dotlock_has_mtime_changed(time_t t1, time_t t2) |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
707 { |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
708 time_t diff; |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
709 |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
710 if (t1 == t2) |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
711 return FALSE; |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
712 |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
713 /* with NFS t1 may have been looked up from local cache. |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
714 allow it to be a little bit different. */ |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
715 diff = t1 > t2 ? t1-t2 : t2-t1; |
13551
df74f0052707
file_dotlock: And fix to previous change..
Timo Sirainen <tss@iki.fi>
parents:
13550
diff
changeset
|
716 return diff > FILE_DOTLOCK_MAX_STAT_MTIME_DIFF; |
13550
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
717 } |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
718 |
14688
128c598d2870
Avoid using (void)s by adding ATTR_NOWARN_UNUSED_RESULT attributes and other ways.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
719 int file_dotlock_delete(struct dotlock **dotlock_p) |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
720 { |
3106 | 721 struct dotlock *dotlock; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
722 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
|
723 struct stat st; |
19136
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
724 int ret; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
725 |
3106 | 726 dotlock = *dotlock_p; |
727 *dotlock_p = NULL; | |
728 | |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
729 lock_path = file_dotlock_get_lock_path(dotlock); |
5969
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
730 if (nfs_safe_lstat(lock_path, &st) < 0) { |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
731 if (errno == ENOENT) { |
8178
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
732 dotlock_replaced_warning(dotlock, TRUE); |
6937 | 733 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
734 return 0; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
735 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
736 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
737 i_error("lstat(%s) failed: %m", lock_path); |
6937 | 738 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
739 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
740 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
741 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
742 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
|
743 !CMP_DEV_T(dotlock->dev, st.st_dev)) { |
8178
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
744 dotlock_replaced_warning(dotlock, FALSE); |
1915
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1825
diff
changeset
|
745 errno = EEXIST; |
6937 | 746 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
747 return 0; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
748 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
749 |
13550
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
750 if (file_dotlock_has_mtime_changed(dotlock->mtime, st.st_mtime) && |
fecd095394b6
file_dotlock: Don't warn about changed mtime when it's 1 second.
Timo Sirainen <tss@iki.fi>
parents:
12782
diff
changeset
|
751 dotlock->fd == -1) { |
1359
bbcbe27926ad
Use different warning message for dotlock mtime change.
Timo Sirainen <tss@iki.fi>
parents:
1313
diff
changeset
|
752 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
|
753 "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
|
754 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
|
755 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
|
756 (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
|
757 } |
bbcbe27926ad
Use different warning message for dotlock mtime change.
Timo Sirainen <tss@iki.fi>
parents:
1313
diff
changeset
|
758 |
19136
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
759 if ((ret = i_unlink_if_exists(lock_path)) == 0) |
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
760 dotlock_replaced_warning(dotlock, TRUE); |
6937 | 761 file_dotlock_free(&dotlock); |
19136
fefaa6d09a81
Replaced unlink() calls with i_unlink*() wherever possible.
Timo Sirainen <tss@iki.fi>
parents:
18137
diff
changeset
|
762 return ret; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
763 } |
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
|
764 |
3106 | 765 int file_dotlock_open(const struct dotlock_settings *set, const char *path, |
766 enum dotlock_create_flags flags, | |
767 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
|
768 { |
3106 | 769 struct dotlock *dotlock; |
770 int ret; | |
771 | |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
772 dotlock = file_dotlock_alloc(set, path); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7134
diff
changeset
|
773 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
774 const char *lock_path; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
775 |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
776 ret = dotlock_create(dotlock, flags, FALSE, &lock_path); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7134
diff
changeset
|
777 } T_END; |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
778 |
3106 | 779 if (ret <= 0) { |
6937 | 780 file_dotlock_free(&dotlock); |
3106 | 781 *dotlock_r = NULL; |
782 return -1; | |
783 } | |
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
|
784 |
3106 | 785 *dotlock_r = dotlock; |
786 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
|
787 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
788 |
14629
c93ca5e46a8a
Marked functions parameters that are allowed to be NULL. Some APIs were also changed.
Timo Sirainen <tss@iki.fi>
parents:
14196
diff
changeset
|
789 static int ATTR_NULL(7) |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
790 file_dotlock_open_mode_full(const struct dotlock_settings *set, const char *path, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
791 enum dotlock_create_flags flags, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
792 mode_t mode, uid_t uid, gid_t gid, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
793 const char *gid_origin, struct dotlock **dotlock_r) |
8036
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
794 { |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
795 struct dotlock *dotlock; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
796 mode_t old_mask; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
797 int fd; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
798 |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
799 old_mask = umask(0666 ^ mode); |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
800 fd = file_dotlock_open(set, path, flags, &dotlock); |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
801 umask(old_mask); |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
802 |
9693
03b52be4da81
Fixed file_dotlock_open*() logging errors in some OSes.
Timo Sirainen <tss@iki.fi>
parents:
9560
diff
changeset
|
803 if (fd != -1 && (uid != (uid_t)-1 || gid != (gid_t)-1)) { |
8036
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
804 if (fchown(fd, uid, gid) < 0) { |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
805 if (errno == EPERM && uid == (uid_t)-1) { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
806 i_error("%s", eperm_error_get_chgrp("fchown", |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
807 file_dotlock_get_lock_path(dotlock), |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
808 gid, gid_origin)); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
809 } else { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
810 i_error("fchown(%s, %ld, %ld) failed: %m", |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
811 file_dotlock_get_lock_path(dotlock), |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
812 (long)uid, (long)gid); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
813 } |
8036
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
814 file_dotlock_delete(&dotlock); |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
815 return -1; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
816 } |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
817 } |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
818 *dotlock_r = dotlock; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
819 return fd; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
820 } |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
821 |
9537
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
822 int file_dotlock_open_mode(const struct dotlock_settings *set, const char *path, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
823 enum dotlock_create_flags flags, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
824 mode_t mode, uid_t uid, gid_t gid, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
825 struct dotlock **dotlock_r) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
826 { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
827 return file_dotlock_open_mode_full(set, path, flags, mode, uid, gid, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
828 NULL, dotlock_r); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
829 } |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
830 |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
831 int file_dotlock_open_group(const struct dotlock_settings *set, const char *path, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
832 enum dotlock_create_flags flags, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
833 mode_t mode, gid_t gid, const char *gid_origin, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
834 struct dotlock **dotlock_r) |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
835 { |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
836 return file_dotlock_open_mode_full(set, path, flags, mode, (uid_t)-1, |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
837 gid, gid_origin, dotlock_r); |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
838 } |
b373de4973cd
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9476
diff
changeset
|
839 |
3106 | 840 int file_dotlock_replace(struct dotlock **dotlock_p, |
841 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
|
842 { |
3106 | 843 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
|
844 const char *lock_path; |
17468
aac4f4b886d2
lib: Fixed file_dotlock_replace(flags=DOTLOCK_REPLACE_FLAG_VERIFY_OWNER|DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD)
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
845 bool is_locked; |
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
|
846 |
3106 | 847 dotlock = *dotlock_p; |
848 *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
|
849 |
17468
aac4f4b886d2
lib: Fixed file_dotlock_replace(flags=DOTLOCK_REPLACE_FLAG_VERIFY_OWNER|DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD)
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
850 is_locked = (flags & DOTLOCK_REPLACE_FLAG_VERIFY_OWNER) == 0 ? TRUE : |
aac4f4b886d2
lib: Fixed file_dotlock_replace(flags=DOTLOCK_REPLACE_FLAG_VERIFY_OWNER|DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD)
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
851 file_dotlock_is_locked(dotlock); |
aac4f4b886d2
lib: Fixed file_dotlock_replace(flags=DOTLOCK_REPLACE_FLAG_VERIFY_OWNER|DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD)
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
852 |
3106 | 853 if ((flags & DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) != 0) |
854 dotlock->fd = -1; | |
855 | |
17468
aac4f4b886d2
lib: Fixed file_dotlock_replace(flags=DOTLOCK_REPLACE_FLAG_VERIFY_OWNER|DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD)
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
856 if (!is_locked) { |
8178
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
857 dotlock_replaced_warning(dotlock, FALSE); |
7134
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
858 errno = EEXIST; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
859 file_dotlock_free(&dotlock); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
860 return 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
|
861 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
862 |
17468
aac4f4b886d2
lib: Fixed file_dotlock_replace(flags=DOTLOCK_REPLACE_FLAG_VERIFY_OWNER|DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD)
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
863 lock_path = file_dotlock_get_lock_path(dotlock); |
3106 | 864 if (rename(lock_path, dotlock->path) < 0) { |
865 i_error("rename(%s, %s) failed: %m", lock_path, dotlock->path); | |
8178
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
866 if (errno == ENOENT) |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
867 dotlock_replaced_warning(dotlock, TRUE); |
6937 | 868 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
|
869 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
|
870 } |
6937 | 871 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
|
872 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
|
873 } |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
874 |
3982
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
875 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
|
876 { |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
877 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
|
878 struct utimbuf buf; |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
879 int ret = 0; |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
880 |
4306
ce3c09a75b87
Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents:
4211
diff
changeset
|
881 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
|
882 return 0; |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
883 |
4306
ce3c09a75b87
Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents:
4211
diff
changeset
|
884 dotlock->mtime = now; |
3982
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
885 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
|
886 |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7134
diff
changeset
|
887 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
888 const char *lock_path = file_dotlock_get_lock_path(dotlock); |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
889 if (utime(lock_path, &buf) < 0) { |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
890 i_error("utime(%s) failed: %m", lock_path); |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
891 ret = -1; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
892 } |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7134
diff
changeset
|
893 } T_END; |
3982
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
894 return ret; |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
895 } |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
896 |
7134
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
897 bool file_dotlock_is_locked(struct dotlock *dotlock) |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
898 { |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
899 struct stat st, st2; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
900 const char *lock_path; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
901 |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
902 lock_path = file_dotlock_get_lock_path(dotlock); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
903 if (fstat(dotlock->fd, &st) < 0) { |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
904 i_error("fstat(%s) failed: %m", lock_path); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
905 return FALSE; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
906 } |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
907 |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
908 if (nfs_safe_lstat(lock_path, &st2) < 0) { |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
909 i_error("lstat(%s) failed: %m", lock_path); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
910 return FALSE; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
911 } |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
912 return st.st_ino == st2.st_ino && CMP_DEV_T(st.st_dev, st2.st_dev); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
913 } |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
914 |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
915 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
|
916 { |
4207
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
917 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
|
918 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
|
919 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
|
920 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
|
921 } |
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
922 return dotlock->lock_path; |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
923 } |