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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
37 struct dotlock {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
38 struct dotlock_settings settings;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
39
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
40 dev_t dev;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
41 ino_t ino;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
42 time_t mtime;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
43
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
49 };
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
78 {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
79 struct dotlock *dotlock;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
80
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
81 dotlock = i_new(struct dotlock, 1);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
82 dotlock->settings = *settings;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
83 if (dotlock->settings.lock_suffix == NULL)
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
86 dotlock->fd = -1;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
87
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
88 return dotlock;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
89 }
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
41911abe6fa7 NFS cache flushing updates.
Timo Sirainen <tss@iki.fi>
parents: 6829
diff changeset
170 if (lock_info->set->nfs_flush && lock_info->lock_stated) {
41911abe6fa7 NFS cache flushing updates.
Timo Sirainen <tss@iki.fi>
parents: 6829
diff changeset
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
41911abe6fa7 NFS cache flushing updates.
Timo Sirainen <tss@iki.fi>
parents: 6829
diff changeset
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
8af71985e97b Comment updates
Timo Sirainen <tss@iki.fi>
parents: 7340
diff changeset
244 if (pid != getpid()) {
8af71985e97b Comment updates
Timo Sirainen <tss@iki.fi>
parents: 7340
diff changeset
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
8af71985e97b Comment updates
Timo Sirainen <tss@iki.fi>
parents: 7340
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
41911abe6fa7 NFS cache flushing updates.
Timo Sirainen <tss@iki.fi>
parents: 6829
diff changeset
275 if (lock_info->set->nfs_flush) {
41911abe6fa7 NFS cache flushing updates.
Timo Sirainen <tss@iki.fi>
parents: 6829
diff changeset
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
41911abe6fa7 NFS cache flushing updates.
Timo Sirainen <tss@iki.fi>
parents: 6829
diff changeset
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
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
280 if (errno == ENOENT) {
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
281 /* file doesn't exist. treat it as if
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
282 it hasn't changed */
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
283 } else {
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
284 i_error("stat(%s) failed: %m", lock_info->path);
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
285 return -1;
b31688700d63 Minor speedup
Timo Sirainen <tss@iki.fi>
parents: 1597
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
b6135e6a5ff2 Don't log an ENOENT error.
Timo Sirainen <tss@iki.fi>
parents: 6647
diff changeset
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
8af71985e97b Comment updates
Timo Sirainen <tss@iki.fi>
parents: 7340
diff changeset
450 /* timeout after a random time even when using notify, since it
8af71985e97b Comment updates
Timo Sirainen <tss@iki.fi>
parents: 7340
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
480 stale_notify_threshold = set->stale_timeout / 2;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
481 max_wait_time = (flags & DOTLOCK_CREATE_FLAG_NONBLOCK) != 0 ? 0 :
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
537 unsigned int secs_left =
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
538 set->stale_timeout < change_secs ?
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
539 0 : set->stale_timeout - change_secs;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
540 if (!set->callback(secs_left, TRUE,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
546 (void)set->callback(wait_left, FALSE,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
596 struct dotlock *dotlock = *_dotlock;
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
597 int old_errno;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
598
6937
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
599 *_dotlock = NULL;
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
600
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
601 if (dotlock->fd != -1) {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
602 old_errno = errno;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
603 if (close(dotlock->fd) < 0)
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
604 i_error("close(%s) failed: %m", dotlock->path);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
605 dotlock->fd = -1;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
606 errno = old_errno;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
607 }
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
608
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
611 i_free(dotlock);
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
612 }
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
615 enum dotlock_create_flags flags)
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
625 fd = dotlock->fd;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
652 dotlock->mtime = st.st_mtime;
6937
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
653 return 1;
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
654 }
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
655
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
656 int file_dotlock_create(const struct dotlock_settings *set, const char *path,
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
657 enum dotlock_create_flags flags,
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
658 struct dotlock **dotlock_r)
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
659 {
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
660 struct dotlock *dotlock;
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
661 int ret;
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
667 if (ret <= 0 || (flags & DOTLOCK_CREATE_FLAG_CHECKONLY) != 0)
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
668 file_dotlock_free(&dotlock);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
669
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
670 *dotlock_r = dotlock;
6937
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
700 dotlock = *dotlock_p;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
701 *dotlock_p = NULL;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
702
3715
9680bd9e6346 Added file_dotlock_get_lock_path()
Timo Sirainen <tss@iki.fi>
parents: 3591
diff changeset
703 lock_path = file_dotlock_get_lock_path(dotlock);
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
748 int file_dotlock_open(const struct dotlock_settings *set, const char *path,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
749 enum dotlock_create_flags flags,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
752 struct dotlock *dotlock;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
753 int ret;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
762 if (ret <= 0) {
6937
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
763 file_dotlock_free(&dotlock);
3106
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
764 *dotlock_r = NULL;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
765 return -1;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
768 *dotlock_r = dotlock;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
823 int file_dotlock_replace(struct dotlock **dotlock_p,
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
829 dotlock = *dotlock_p;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
832 if ((flags & DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) != 0)
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
833 dotlock->fd = -1;
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
844 if (rename(lock_path, dotlock->path) < 0) {
9c4aa309dbac Changed dotlocking API.
Timo Sirainen <tss@iki.fi>
parents: 3041
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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
94e94e3b5b30 Code cleanups
Timo Sirainen <tss@iki.fi>
parents: 6857
diff changeset
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 }