Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/file-dotlock.c @ 9451:9fff30644260 HEAD
istream-concat: Fixed a lot of bugs.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 26 Oct 2009 17:06:57 -0400 |
parents | c7948ebd433e |
children | 00cd9aacd03c |
rev | line source |
---|---|
8590
b9faf4db2a9f
Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents:
8184
diff
changeset
|
1 /* Copyright (c) 2003-2009 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" |
1597
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
8 #include "randgen.h" |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
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 <stdlib.h> |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 #include <signal.h> |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 #include <time.h> |
3982
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
19 #include <utime.h> |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 #include <sys/stat.h> |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 |
1974
d85f71ffeb8f
file_dotlock_open/delete/replace now has lock_suffix parameter. NULL
Timo Sirainen <tss@iki.fi>
parents:
1915
diff
changeset
|
22 #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
|
23 |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 /* 0.1 .. 0.2msec */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 #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
|
26 /* 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
|
27 #define LOCK_MAX_WAIT_USECS (1000000 * 3) |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 |
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
|
29 /* 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
|
30 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
|
31 #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
|
32 |
5664
b796701a6927
Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents:
5663
diff
changeset
|
33 /* 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
|
34 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
|
35 #define MAX_TIME_DIFF 30 |
b796701a6927
Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents:
5663
diff
changeset
|
36 |
3106 | 37 struct dotlock { |
38 struct dotlock_settings settings; | |
39 | |
40 dev_t dev; | |
41 ino_t ino; | |
42 time_t mtime; | |
43 | |
44 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
|
45 char *lock_path; |
3106 | 46 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
|
47 |
4306
ce3c09a75b87
Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents:
4211
diff
changeset
|
48 time_t lock_time; |
3106 | 49 }; |
50 | |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
51 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
|
52 dev_t dev; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
53 ino_t ino; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
54 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
|
55 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
|
56 }; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
57 |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 struct lock_info { |
3106 | 59 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
|
60 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
|
61 int fd; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
63 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
|
64 struct file_change_info file_info; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 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
|
67 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
|
68 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
|
69 |
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
|
70 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
|
71 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
|
72 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
|
73 unsigned int lock_stated:1; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 }; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 |
3106 | 76 static struct dotlock * |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
77 file_dotlock_alloc(const struct dotlock_settings *settings, const char *path) |
3106 | 78 { |
79 struct dotlock *dotlock; | |
80 | |
81 dotlock = i_new(struct dotlock, 1); | |
82 dotlock->settings = *settings; | |
83 if (dotlock->settings.lock_suffix == NULL) | |
84 dotlock->settings.lock_suffix = DEFAULT_LOCK_SUFFIX; | |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
85 dotlock->path = i_strdup(path); |
3106 | 86 dotlock->fd = -1; |
87 | |
88 return dotlock; | |
89 } | |
90 | |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 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
|
92 { |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 char buf[512], *host; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 int fd; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 ssize_t ret; |
7065
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
96 pid_t pid; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 fd = open(lock_path, O_RDONLY); |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 if (fd == -1) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 return -1; /* ignore the actual error */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 /* read line */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 ret = read(fd, buf, sizeof(buf)-1); |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
104 (void)close(fd); |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 if (ret <= 0) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 /* fix the string */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 if (buf[ret-1] == '\n') |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 ret--; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 buf[ret] = '\0'; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 /* it should contain pid:host */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 host = strchr(buf, ':'); |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
115 if (host == NULL) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
116 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 *host++ = '\0'; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
118 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
119 /* host must be ours */ |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 if (strcmp(host, my_hostname) != 0) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
121 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
122 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 if (!is_numeric(buf, '\0')) |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 return -1; |
7065
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
125 pid = (pid_t)strtoul(buf, NULL, 0); |
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
126 if (pid <= 0) |
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
127 return -1; |
04e048fcd6d7
If dotlock file contains pid <= 0, assume it's invalid.
Timo Sirainen <tss@iki.fi>
parents:
7053
diff
changeset
|
128 return pid; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
131 static bool |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
132 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
|
133 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
|
134 { |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
135 /* 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
|
136 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
|
137 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
|
138 (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
|
139 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
|
140 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
|
141 |
6593
be0a8109cde6
Check ctimes after all, but only as long as nfs_flush=FALSE.
Timo Sirainen <tss@iki.fi>
parents:
6592
diff
changeset
|
142 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
|
143 /* 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
|
144 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
|
145 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
|
146 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
|
147 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
|
148 (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
|
149 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
|
150 } |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
151 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
|
152 *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
|
153 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
|
154 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
|
155 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
|
156 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
|
157 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
|
158 return TRUE; |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
159 } |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
160 return FALSE; |
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 |
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
|
163 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
|
164 bool *changed_r) |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 { |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
166 struct stat st; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 |
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
|
168 /* 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
|
169 if it's stale we'll get back here soon. */ |
6857 | 170 if (lock_info->set->nfs_flush && lock_info->lock_stated) { |
171 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
|
172 nfs_flush_attr_cache_unlocked(lock_info->lock_path); |
6857 | 173 } |
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
|
174 |
c1bd43be8f9a
Don't flush attribute cache the first time when stating a lock file. Usually
Timo Sirainen <tss@iki.fi>
parents:
6797
diff
changeset
|
175 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
|
176 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
|
177 if (errno != ENOENT) { |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
178 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
|
179 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
180 } |
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 |
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
|
184 *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
|
185 &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
|
186 !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
|
187 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
|
188 } |
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 |
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
|
190 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
|
191 { |
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 if (unlink(lock_info->lock_path) < 0 && errno != ENOENT) { |
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 i_error("unlink(%s) failed: %m", |
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
|
194 lock_info->lock_path); |
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 |
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 /* 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
|
199 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
|
200 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
|
201 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
|
202 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
|
203 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
|
204 } |
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
|
205 |
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
|
206 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
|
207 { |
0f352077f789
If dotlock is newer than 2 seconds, don't bother reading PID from it and
Timo Sirainen <tss@iki.fi>
parents:
5352
diff
changeset
|
208 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
|
209 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
|
210 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
|
211 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
|
212 |
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 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
|
214 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
|
215 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
|
216 /* 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
|
217 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
|
218 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
|
219 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
|
220 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
|
221 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
|
222 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
|
223 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
|
224 } |
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
|
225 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
|
226 } 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
|
227 /* 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
|
228 } 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
|
229 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
|
230 /* 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
|
231 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
|
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 |
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 /* 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
|
235 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
|
236 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
|
237 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
|
238 lock_info->have_pid = pid != -1; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
240 |
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
|
241 if (lock_info->have_pid) { |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
242 /* 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
|
243 if (kill(pid, 0) == 0 || errno != ESRCH) { |
7456 | 244 if (pid != getpid()) { |
245 /* 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
|
246 return 0; |
7456 | 247 } |
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
|
248 /* 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
|
249 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
|
250 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
|
251 } |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
252 |
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
|
253 /* 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
|
254 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
|
255 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
|
256 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
|
257 |
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 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
|
259 /* 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
|
260 return dotlock_override(lock_info); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
261 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
262 return 1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
263 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
264 |
3106 | 265 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
|
266 /* 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
|
267 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
|
268 } |
486a5dbbc9c8
Check that dotlock PID exists even if we don't do stale lock timeouting.
Timo Sirainen <tss@iki.fi>
parents:
2720
diff
changeset
|
269 |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
270 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
|
271 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
|
272 |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
273 /* 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
|
274 file we're protecting. */ |
6857 | 275 if (lock_info->set->nfs_flush) { |
276 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
|
277 nfs_flush_attr_cache_maybe_locked(lock_info->path); |
6857 | 278 } |
5969
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
279 if (nfs_safe_stat(lock_info->path, &st) < 0) { |
1624 | 280 if (errno == ENOENT) { |
281 /* file doesn't exist. treat it as if | |
282 it hasn't changed */ | |
283 } else { | |
284 i_error("stat(%s) failed: %m", lock_info->path); | |
285 return -1; | |
286 } | |
3981
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
287 } else { |
0d64f8888dcd
Removed immediate_stale_timeout and changed the stale_timeout behavior to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
288 (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
|
289 &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
|
290 !lock_info->set->nfs_flush); |
1161
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 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
293 |
3106 | 294 if (now > lock_info->last_change + stale_timeout) { |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
295 /* 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
|
296 return dotlock_override(lock_info); |
1161
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 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 return 0; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
301 |
9449
c7948ebd433e
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9271
diff
changeset
|
302 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
|
303 { |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
304 const char *str; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
305 |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
306 /* write our pid and host, if possible */ |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
307 str = t_strdup_printf("%s:%s", my_pid, my_hostname); |
9449
c7948ebd433e
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9271
diff
changeset
|
308 if (write_full(fd, str, strlen(str)) < 0 || |
c7948ebd433e
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9271
diff
changeset
|
309 (nfs_flush && fdatasync(fd) < 0)) { |
3564
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
310 /* failed, leave it empty then */ |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
311 if (ftruncate(fd, 0) < 0) { |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
312 i_error("ftruncate(%s) failed: %m", path); |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
313 return -1; |
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 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
316 return 0; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
317 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
318 |
4207
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
319 static int try_create_lock_hardlink(struct lock_info *lock_info, bool write_pid, |
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
320 string_t *tmp_path) |
1597
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
321 { |
3106 | 322 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
|
323 const char *p; |
9131
c8bb7c18f17b
safe_mkstemp*() was used incorrectly. umask() no longer changes its behavior.
Timo Sirainen <tss@iki.fi>
parents:
9002
diff
changeset
|
324 mode_t 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
|
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 |
9131
c8bb7c18f17b
safe_mkstemp*() was used incorrectly. umask() no longer changes its behavior.
Timo Sirainen <tss@iki.fi>
parents:
9002
diff
changeset
|
352 old_mask = umask(0666); |
c8bb7c18f17b
safe_mkstemp*() was used incorrectly. umask() no longer changes its behavior.
Timo Sirainen <tss@iki.fi>
parents:
9002
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); |
9131
c8bb7c18f17b
safe_mkstemp*() was used incorrectly. umask() no longer changes its behavior.
Timo Sirainen <tss@iki.fi>
parents:
9002
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, |
9449
c7948ebd433e
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9271
diff
changeset
|
361 str_c(tmp_path), |
c7948ebd433e
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9271
diff
changeset
|
362 lock_info->set->nfs_flush) < 0) { |
5543
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
363 (void)close(lock_info->fd); |
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
364 lock_info->fd = -1; |
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
365 return -1; |
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 } |
a240e903841e
Use safe_mkstemp() instead of doing it ourself.
Timo Sirainen <tss@iki.fi>
parents:
5541
diff
changeset
|
368 |
4207
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
369 lock_info->temp_path = str_c(tmp_path); |
1597
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
370 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
371 |
6813
575235932194
nfs_safe_link(): Support linking files without original link count=1. Use it
Timo Sirainen <tss@iki.fi>
parents:
6812
diff
changeset
|
372 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
|
373 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
|
374 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
|
375 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
|
376 |
7340
09cdd4330d73
file_dotlock_create(): Don't log an EACCES failures.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
377 if (errno != EACCES) { |
09cdd4330d73
file_dotlock_create(): Don't log an EACCES failures.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
378 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
|
379 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
|
380 } |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
381 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
|
382 } |
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 |
4308
b0c4e02d715b
If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents:
4307
diff
changeset
|
384 if (unlink(lock_info->temp_path) < 0) { |
1597
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
385 i_error("unlink(%s) failed: %m", lock_info->temp_path); |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
386 /* 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
|
387 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
388 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
|
389 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
|
390 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
391 |
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
|
392 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
|
393 { |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
394 int fd; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
395 |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
396 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
|
397 if (fd == -1) { |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
398 if (errno == EEXIST) |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
399 return 0; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
400 |
7340
09cdd4330d73
file_dotlock_create(): Don't log an EACCES failures.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
401 if (errno != ENOENT && errno != EACCES) |
6775 | 402 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
|
403 return -1; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
404 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
405 |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
406 if (write_pid) { |
9449
c7948ebd433e
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9271
diff
changeset
|
407 if (file_write_pid(fd, lock_info->lock_path, |
c7948ebd433e
file_dotlock_create(): If nfs_flush is enabled, fdatasync after writing PID.
Timo Sirainen <tss@iki.fi>
parents:
9271
diff
changeset
|
408 lock_info->set->nfs_flush) < 0) { |
3564
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
409 (void)close(fd); |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
410 return -1; |
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 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
413 |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
414 lock_info->fd = fd; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
415 return 1; |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
416 } |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
417 |
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
|
418 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
|
419 { |
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
|
420 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
|
421 } |
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
|
422 |
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
|
423 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
|
424 { |
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 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
|
426 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
|
427 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
|
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 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
|
430 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
|
431 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
|
432 } |
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 |
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 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
|
435 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
|
436 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
|
437 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
|
438 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
|
439 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
|
440 /* 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
|
441 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
|
442 return; |
7457
940641318f12
Renamed IO_NOTIFY_DISABLED to IO_NOTIFY_NOSUPPORT. IO_NOTIFY_NOSUPPORT is
Timo Sirainen <tss@iki.fi>
parents:
7456
diff
changeset
|
443 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
|
444 /* 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
|
445 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
|
446 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
|
447 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
|
448 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
|
449 } |
7456 | 450 /* timeout after a random time even when using notify, since it |
451 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
|
452 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
|
453 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
|
454 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
|
455 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
|
456 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
|
457 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
|
458 } |
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 |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
460 static int |
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
461 dotlock_create(struct dotlock *dotlock, enum dotlock_create_flags flags, |
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
462 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
|
463 { |
3106 | 464 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
|
465 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
|
466 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
|
467 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
|
468 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
|
469 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
|
470 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
|
471 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
|
472 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
|
473 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
|
474 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
|
475 |
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 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
|
477 |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
478 lock_path = *lock_path_r = |
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
479 t_strconcat(dotlock->path, set->lock_suffix, NULL); |
3106 | 480 stale_notify_threshold = set->stale_timeout / 2; |
481 max_wait_time = (flags & DOTLOCK_CREATE_FLAG_NONBLOCK) != 0 ? 0 : | |
482 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
|
483 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
|
484 |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
485 memset(&lock_info, 0, sizeof(lock_info)); |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
486 lock_info.path = dotlock->path; |
3106 | 487 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
|
488 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
|
489 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
|
490 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
|
491 |
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
|
492 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
|
493 |
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 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
|
495 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
|
496 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
|
497 /* 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
|
498 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
|
499 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
|
500 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
|
501 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
|
502 } 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
|
503 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
|
504 /* 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
|
505 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
|
506 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
|
507 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
|
508 } |
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
|
509 dotlock_wait(&lock_info); |
1597
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
510 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
|
511 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
512 |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
513 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
|
514 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
|
515 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
|
516 |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
517 if (ret == 1) { |
3106 | 518 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
|
519 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
|
520 |
3564
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
521 ret = set->use_excl_lock ? |
d3f246330d37
Support creating locks with O_EXCL.
Timo Sirainen <tss@iki.fi>
parents:
3174
diff
changeset
|
522 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
|
523 try_create_lock_hardlink(&lock_info, write_pid, |
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
524 tmp_path); |
1597
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
525 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
|
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 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
528 |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
529 do_wait = TRUE; |
3106 | 530 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
|
531 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
|
532 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
|
533 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
|
534 |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
535 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
|
536 change_secs <= wait_left) { |
3106 | 537 unsigned int secs_left = |
538 set->stale_timeout < change_secs ? | |
539 0 : set->stale_timeout - change_secs; | |
540 if (!set->callback(secs_left, TRUE, | |
541 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
|
542 /* 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
|
543 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
|
544 } |
9002
89b825b20f76
dotlocking: Don't generate "Will override dotlock in 0 secs" messages.
Timo Sirainen <tss@iki.fi>
parents:
8852
diff
changeset
|
545 } else if (wait_left > 0) { |
3106 | 546 (void)set->callback(wait_left, FALSE, |
547 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
|
548 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
549 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
550 |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
551 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
|
552 } while (now < max_wait_time); |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
553 |
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
|
554 if (ret > 0) { |
3132
3281674159b5
Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents:
3106
diff
changeset
|
555 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
|
556 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
|
557 ret = -1; |
3281674159b5
Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents:
3106
diff
changeset
|
558 } 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
|
559 /* 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
|
560 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
|
561 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
|
562 |
3281674159b5
Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents:
3106
diff
changeset
|
563 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
|
564 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
|
565 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
|
566 |
5664
b796701a6927
Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents:
5663
diff
changeset
|
567 if (st.st_ctime + MAX_TIME_DIFF < now || |
b796701a6927
Continuing the previous time difference commit..
Timo Sirainen <tss@iki.fi>
parents:
5663
diff
changeset
|
568 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
|
569 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
|
570 "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
|
571 "(%s vs %s): %s", dec2str(st.st_ctime), |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
572 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
|
573 } |
3132
3281674159b5
Inode info wasn't saved when using file_dotlock_open() so
Timo Sirainen <tss@iki.fi>
parents:
3106
diff
changeset
|
574 } |
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
|
575 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
576 |
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
|
577 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
|
578 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
|
579 |
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
|
580 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
|
581 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
|
582 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
|
583 } |
4308
b0c4e02d715b
If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents:
4307
diff
changeset
|
584 if (lock_info.temp_path != NULL) { |
b0c4e02d715b
If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents:
4307
diff
changeset
|
585 if (unlink(lock_info.temp_path) < 0) |
b0c4e02d715b
If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents:
4307
diff
changeset
|
586 i_error("unlink(%s) failed: %m", lock_info.temp_path); |
b0c4e02d715b
If dotlock creation timeouts, unlink() the temp file we used
Timo Sirainen <tss@iki.fi>
parents:
4307
diff
changeset
|
587 } |
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
|
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 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
|
590 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
|
591 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
|
592 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
593 |
6937 | 594 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
|
595 { |
6937 | 596 struct dotlock *dotlock = *_dotlock; |
3106 | 597 int old_errno; |
598 | |
6937 | 599 *_dotlock = NULL; |
600 | |
3106 | 601 if (dotlock->fd != -1) { |
602 old_errno = errno; | |
603 if (close(dotlock->fd) < 0) | |
604 i_error("close(%s) failed: %m", dotlock->path); | |
605 dotlock->fd = -1; | |
606 errno = old_errno; | |
607 } | |
608 | |
609 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
|
610 i_free(dotlock->lock_path); |
3106 | 611 i_free(dotlock); |
612 } | |
613 | |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
614 static int file_dotlock_create_real(struct dotlock *dotlock, |
6937 | 615 enum dotlock_create_flags flags) |
3106 | 616 { |
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
|
617 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
|
618 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
|
619 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
|
620 |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
621 ret = dotlock_create(dotlock, flags, TRUE, &lock_path); |
6937 | 622 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
|
623 return ret; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
624 |
3106 | 625 fd = dotlock->fd; |
626 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
|
627 |
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
|
628 if (close(fd) < 0) { |
3106 | 629 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
|
630 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
|
631 } |
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 |
5969
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
633 /* 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
|
634 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
|
635 errors. */ |
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
636 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
|
637 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
|
638 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
|
639 else { |
eb4902fc7693
Give a better error message if dotlock is deleted immediately under us (or
Timo Sirainen <tss@iki.fi>
parents:
5543
diff
changeset
|
640 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
|
641 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
|
642 } |
2077
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
643 return -1; |
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
644 } |
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
645 /* extra sanity check won't hurt.. */ |
3106 | 646 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
|
647 errno = ENOENT; |
2077
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
648 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
|
649 lock_path); |
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
650 return -1; |
d5b20d679b8a
Removed hardcoded mechanism lists. It's now possible to add them
Timo Sirainen <tss@iki.fi>
parents:
2025
diff
changeset
|
651 } |
3106 | 652 dotlock->mtime = st.st_mtime; |
6937 | 653 return 1; |
654 } | |
655 | |
656 int file_dotlock_create(const struct dotlock_settings *set, const char *path, | |
657 enum dotlock_create_flags flags, | |
658 struct dotlock **dotlock_r) | |
659 { | |
660 struct dotlock *dotlock; | |
661 int ret; | |
662 | |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
663 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
|
664 T_BEGIN { |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
665 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
|
666 } T_END; |
6937 | 667 if (ret <= 0 || (flags & DOTLOCK_CREATE_FLAG_CHECKONLY) != 0) |
668 file_dotlock_free(&dotlock); | |
3106 | 669 |
670 *dotlock_r = dotlock; | |
6937 | 671 return ret; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
672 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
673 |
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
|
674 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
|
675 { |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
676 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
|
677 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
|
678 |
a6ae37414011
dotlocking: If rename() fails due to ENOENT, show how long we kept the lock.
Timo Sirainen <tss@iki.fi>
parents:
8036
diff
changeset
|
679 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
|
680 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
|
681 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
|
682 "(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
|
683 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
|
684 (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
|
685 (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
|
686 } 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
|
687 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
|
688 "(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
|
689 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
|
690 (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
|
691 } |
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 } |
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 |
3106 | 694 int file_dotlock_delete(struct dotlock **dotlock_p) |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
695 { |
3106 | 696 struct dotlock *dotlock; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
697 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
|
698 struct stat st; |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
699 |
3106 | 700 dotlock = *dotlock_p; |
701 *dotlock_p = NULL; | |
702 | |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
703 lock_path = file_dotlock_get_lock_path(dotlock); |
5969
29770d8a013b
Use nfs_safe_lstat() when dotlocking. Also use lstat() not stat() for
Timo Sirainen <tss@iki.fi>
parents:
5938
diff
changeset
|
704 if (nfs_safe_lstat(lock_path, &st) < 0) { |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
705 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
|
706 dotlock_replaced_warning(dotlock, TRUE); |
6937 | 707 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
708 return 0; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
709 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
710 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
711 i_error("lstat(%s) failed: %m", lock_path); |
6937 | 712 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
713 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
714 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
715 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
716 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
|
717 !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
|
718 dotlock_replaced_warning(dotlock, FALSE); |
1915
79790750c349
importing new index code. mbox still broken.
Timo Sirainen <tss@iki.fi>
parents:
1825
diff
changeset
|
719 errno = EEXIST; |
6937 | 720 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
721 return 0; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
722 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
723 |
3106 | 724 if (dotlock->mtime != st.st_mtime && dotlock->fd == -1) { |
1359
bbcbe27926ad
Use different warning message for dotlock mtime change.
Timo Sirainen <tss@iki.fi>
parents:
1313
diff
changeset
|
725 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
|
726 "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
|
727 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
|
728 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
|
729 (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
|
730 } |
bbcbe27926ad
Use different warning message for dotlock mtime change.
Timo Sirainen <tss@iki.fi>
parents:
1313
diff
changeset
|
731 |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
732 if (unlink(lock_path) < 0) { |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
733 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
|
734 dotlock_replaced_warning(dotlock, TRUE); |
6937 | 735 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
736 return 0; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
737 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
738 |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
739 i_error("unlink(%s) failed: %m", lock_path); |
6937 | 740 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
741 return -1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
742 } |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
743 |
6937 | 744 file_dotlock_free(&dotlock); |
1161
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
745 return 1; |
fc5d2e44cc5e
Locking code cleanups and small fixes
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
746 } |
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
|
747 |
3106 | 748 int file_dotlock_open(const struct dotlock_settings *set, const char *path, |
749 enum dotlock_create_flags flags, | |
750 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
|
751 { |
3106 | 752 struct dotlock *dotlock; |
753 int ret; | |
754 | |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
755 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
|
756 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
757 const char *lock_path; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
758 |
7975
03ab8199bbe1
dotlocking: Small code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
7457
diff
changeset
|
759 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
|
760 } T_END; |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
761 |
3106 | 762 if (ret <= 0) { |
6937 | 763 file_dotlock_free(&dotlock); |
3106 | 764 *dotlock_r = NULL; |
765 return -1; | |
766 } | |
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
|
767 |
3106 | 768 *dotlock_r = dotlock; |
769 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
|
770 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
771 |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
772 static int |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
773 file_dotlock_open_mode_full(const struct dotlock_settings *set, const char *path, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
774 enum dotlock_create_flags flags, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
775 mode_t mode, uid_t uid, gid_t gid, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
776 const char *gid_origin, struct dotlock **dotlock_r) |
8036
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
777 { |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
778 struct dotlock *dotlock; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
779 mode_t old_mask; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
780 int fd; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
781 |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
782 old_mask = umask(0666 ^ mode); |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
783 fd = file_dotlock_open(set, path, flags, &dotlock); |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
784 umask(old_mask); |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
785 |
9271
7a6be125e469
Fixed file_dotlock_open*() logging errors in some OSes.
Timo Sirainen <tss@iki.fi>
parents:
9187
diff
changeset
|
786 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
|
787 if (fchown(fd, uid, gid) < 0) { |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
788 if (errno == EPERM && uid == (uid_t)-1) { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
789 i_error("%s", eperm_error_get_chgrp("fchown", |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
790 file_dotlock_get_lock_path(dotlock), |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
791 gid, gid_origin)); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
792 } else { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
793 i_error("fchown(%s, %ld, %ld) failed: %m", |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
794 file_dotlock_get_lock_path(dotlock), |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
795 (long)uid, (long)gid); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
796 } |
8036
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
797 file_dotlock_delete(&dotlock); |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
798 return -1; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
799 } |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
800 } |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
801 *dotlock_r = dotlock; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
802 return fd; |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
803 } |
b3303b65c3f2
Added file_dotlock_open_mode().
Timo Sirainen <tss@iki.fi>
parents:
7975
diff
changeset
|
804 |
9168
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
805 int file_dotlock_open_mode(const struct dotlock_settings *set, const char *path, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
806 enum dotlock_create_flags flags, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
807 mode_t mode, uid_t uid, gid_t gid, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
808 struct dotlock **dotlock_r) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
809 { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
810 return file_dotlock_open_mode_full(set, path, flags, mode, uid, gid, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
811 NULL, dotlock_r); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
812 } |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
813 |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
814 int file_dotlock_open_group(const struct dotlock_settings *set, const char *path, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
815 enum dotlock_create_flags flags, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
816 mode_t mode, gid_t gid, const char *gid_origin, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
817 struct dotlock **dotlock_r) |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
818 { |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
819 return file_dotlock_open_mode_full(set, path, flags, mode, (uid_t)-1, |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
820 gid, gid_origin, dotlock_r); |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
821 } |
2bbf175bb6d3
Whenever file's group changing fails, show the group origin in the error message.
Timo Sirainen <tss@iki.fi>
parents:
9131
diff
changeset
|
822 |
3106 | 823 int file_dotlock_replace(struct dotlock **dotlock_p, |
824 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
|
825 { |
3106 | 826 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
|
827 const char *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
|
828 |
3106 | 829 dotlock = *dotlock_p; |
830 *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
|
831 |
3106 | 832 if ((flags & DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) != 0) |
833 dotlock->fd = -1; | |
834 | |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
835 lock_path = file_dotlock_get_lock_path(dotlock); |
7134
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
836 if ((flags & DOTLOCK_REPLACE_FLAG_VERIFY_OWNER) != 0 && |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
837 !file_dotlock_is_locked(dotlock)) { |
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
|
838 dotlock_replaced_warning(dotlock, FALSE); |
7134
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
839 errno = EEXIST; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
840 file_dotlock_free(&dotlock); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
841 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
|
842 } |
9f503b7851ab
Moved all dotlocking code to lib/. Also we now use temp file + link() rather
Timo Sirainen <tss@iki.fi>
parents:
1369
diff
changeset
|
843 |
3106 | 844 if (rename(lock_path, dotlock->path) < 0) { |
845 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
|
846 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
|
847 dotlock_replaced_warning(dotlock, TRUE); |
6937 | 848 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
|
849 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
|
850 } |
6937 | 851 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
|
852 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
|
853 } |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
854 |
3982
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
855 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
|
856 { |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
857 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
|
858 struct utimbuf buf; |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
859 int ret = 0; |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
860 |
4306
ce3c09a75b87
Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents:
4211
diff
changeset
|
861 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
|
862 return 0; |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
863 |
4306
ce3c09a75b87
Using file_dotlock_touch() caused Dovecot to think the dotlock had been
Timo Sirainen <tss@iki.fi>
parents:
4211
diff
changeset
|
864 dotlock->mtime = now; |
3982
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
865 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
|
866 |
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
|
867 T_BEGIN { |
6940
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
868 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
|
869 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
|
870 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
|
871 ret = -1; |
414c9d631a81
Replaced t_push/t_pop calls with T_FRAME*() macros.
Timo Sirainen <tss@iki.fi>
parents:
6937
diff
changeset
|
872 } |
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
|
873 } T_END; |
3982
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
874 return ret; |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
875 } |
15c48c43cc75
Added file_dotlock_touch() for updating lock file's timestamp.
Timo Sirainen <tss@iki.fi>
parents:
3981
diff
changeset
|
876 |
7134
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
877 bool file_dotlock_is_locked(struct dotlock *dotlock) |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
878 { |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
879 struct stat st, st2; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
880 const char *lock_path; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
881 |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
882 lock_path = file_dotlock_get_lock_path(dotlock); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
883 if (fstat(dotlock->fd, &st) < 0) { |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
884 i_error("fstat(%s) failed: %m", lock_path); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
885 return FALSE; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
886 } |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
887 |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
888 if (nfs_safe_lstat(lock_path, &st2) < 0) { |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
889 i_error("lstat(%s) failed: %m", lock_path); |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
890 return FALSE; |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
891 } |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
892 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
|
893 } |
9c2b65bfe604
Added file_dotlock_is_locked().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
894 |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
895 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
|
896 { |
4207
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
897 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
|
898 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
|
899 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
|
900 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
|
901 } |
96f3908b7c34
file_dotlock_get_lock_path() doesn't return the path from data stack
Timo Sirainen <tss@iki.fi>
parents:
4113
diff
changeset
|
902 return dotlock->lock_path; |
3715
9680bd9e6346
Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents:
3591
diff
changeset
|
903 } |