]> git.ipfire.org Git - thirdparty/git.git/blame - lockfile.c
Git 2.8-rc0
[thirdparty/git.git] / lockfile.c
CommitLineData
021b6e45
JH
1/*
2 * Copyright (c) 2005, Junio C Hamano
3 */
2db69de8 4
021b6e45 5#include "cache.h"
697cc8ef 6#include "lockfile.h"
021b6e45 7
5d5a7a67 8/*
0c0d6e86 9 * path = absolute or relative path name
5d5a7a67 10 *
0c0d6e86
MH
11 * Remove the last path name element from path (leaving the preceding
12 * "/", if any). If path is empty or the root directory ("/"), set
13 * path to the empty string.
5d5a7a67 14 */
0c0d6e86 15static void trim_last_path_component(struct strbuf *path)
5d5a7a67 16{
0c0d6e86 17 int i = path->len;
5d5a7a67
BS
18
19 /* back up past trailing slashes, if any */
0c0d6e86
MH
20 while (i && path->buf[i - 1] == '/')
21 i--;
5d5a7a67
BS
22
23 /*
0c0d6e86
MH
24 * then go backwards until a slash, or the beginning of the
25 * string
5d5a7a67 26 */
0c0d6e86
MH
27 while (i && path->buf[i - 1] != '/')
28 i--;
29
30 strbuf_setlen(path, i);
5d5a7a67
BS
31}
32
33
34/* We allow "recursive" symbolic links. Only within reason, though */
35#define MAXDEPTH 5
36
37/*
6cad8053 38 * path contains a path that might be a symlink.
5d5a7a67 39 *
6cad8053
MH
40 * If path is a symlink, attempt to overwrite it with a path to the
41 * real file or directory (which may or may not exist), following a
42 * chain of symlinks if necessary. Otherwise, leave path unmodified.
5d5a7a67 43 *
6cad8053
MH
44 * This is a best-effort routine. If an error occurs, path will
45 * either be left unmodified or will name a different symlink in a
46 * symlink chain that started with the original path.
5d5a7a67 47 */
6cad8053 48static void resolve_symlink(struct strbuf *path)
5d5a7a67
BS
49{
50 int depth = MAXDEPTH;
5025d845 51 static struct strbuf link = STRBUF_INIT;
5d5a7a67
BS
52
53 while (depth--) {
6cad8053 54 if (strbuf_readlink(&link, path->buf, path->len) < 0)
5025d845 55 break;
5d5a7a67 56
6cad8053 57 if (is_absolute_path(link.buf))
5d5a7a67 58 /* absolute path simply replaces p */
6cad8053 59 strbuf_reset(path);
0c0d6e86 60 else
5d5a7a67 61 /*
5025d845 62 * link is a relative path, so replace the
5d5a7a67
BS
63 * last element of p with it.
64 */
0c0d6e86 65 trim_last_path_component(path);
6cad8053
MH
66
67 strbuf_addbuf(path, &link);
5d5a7a67 68 }
5025d845 69 strbuf_reset(&link);
5d5a7a67
BS
70}
71
447ff1bf 72/* Make sure errno contains a meaningful value on error */
acd3b9ec 73static int lock_file(struct lock_file *lk, const char *path, int flags)
021b6e45 74{
1a9d15db
MH
75 int fd;
76 struct strbuf filename = STRBUF_INIT;
04e57d4d 77
1a9d15db
MH
78 strbuf_addstr(&filename, path);
79 if (!(flags & LOCK_NO_DEREF))
80 resolve_symlink(&filename);
fa137f67 81
1a9d15db
MH
82 strbuf_addstr(&filename, LOCK_SUFFIX);
83 fd = create_tempfile(&lk->tempfile, filename.buf);
84 strbuf_release(&filename);
85 return fd;
021b6e45
JH
86}
87
044b6a9e
MH
88/*
89 * Constants defining the gaps between attempts to lock a file. The
90 * first backoff period is approximately INITIAL_BACKOFF_MS
91 * milliseconds. The longest backoff period is approximately
92 * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds.
93 */
94#define INITIAL_BACKOFF_MS 1L
95#define BACKOFF_MAX_MULTIPLIER 1000
96
97/*
98 * Try locking path, retrying with quadratic backoff for at least
99 * timeout_ms milliseconds. If timeout_ms is 0, try locking the file
100 * exactly once. If timeout_ms is -1, try indefinitely.
101 */
102static int lock_file_timeout(struct lock_file *lk, const char *path,
103 int flags, long timeout_ms)
104{
105 int n = 1;
106 int multiplier = 1;
a8a17756 107 long remaining_ms = 0;
044b6a9e
MH
108 static int random_initialized = 0;
109
110 if (timeout_ms == 0)
111 return lock_file(lk, path, flags);
112
113 if (!random_initialized) {
1e9676ec 114 srand((unsigned int)getpid());
044b6a9e
MH
115 random_initialized = 1;
116 }
117
a8a17756
JS
118 if (timeout_ms > 0)
119 remaining_ms = timeout_ms;
044b6a9e
MH
120
121 while (1) {
a8a17756 122 long backoff_ms, wait_ms;
044b6a9e
MH
123 int fd;
124
125 fd = lock_file(lk, path, flags);
126
127 if (fd >= 0)
128 return fd; /* success */
129 else if (errno != EEXIST)
130 return -1; /* failure other than lock held */
a8a17756 131 else if (timeout_ms > 0 && remaining_ms <= 0)
044b6a9e
MH
132 return -1; /* failure due to timeout */
133
134 backoff_ms = multiplier * INITIAL_BACKOFF_MS;
135 /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
a8a17756 136 wait_ms = (750 + rand() % 500) * backoff_ms / 1000;
30f8160d 137 sleep_millisec(wait_ms);
a8a17756 138 remaining_ms -= wait_ms;
044b6a9e
MH
139
140 /* Recursion: (n+1)^2 = n^2 + 2n + 1 */
141 multiplier += 2*n + 1;
142 if (multiplier > BACKOFF_MAX_MULTIPLIER)
143 multiplier = BACKOFF_MAX_MULTIPLIER;
144 else
145 n++;
146 }
147}
148
6af926e8 149void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
e43a6fd3 150{
bdfd739d 151 if (err == EEXIST) {
6af926e8 152 strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
e43a6fd3
MM
153 "If no other git process is currently running, this probably means a\n"
154 "git process crashed in this repository earlier. Make sure no other git\n"
155 "process is running and remove the file manually to continue.",
e2a57aac 156 absolute_path(path), strerror(err));
1b018fd9 157 } else
6af926e8 158 strbuf_addf(buf, "Unable to create '%s.lock': %s",
e2a57aac 159 absolute_path(path), strerror(err));
1b018fd9
MV
160}
161
e197c218 162NORETURN void unable_to_lock_die(const char *path, int err)
1b018fd9 163{
6af926e8
RS
164 struct strbuf buf = STRBUF_INIT;
165
166 unable_to_lock_message(path, err, &buf);
167 die("%s", buf.buf);
e43a6fd3
MM
168}
169
447ff1bf 170/* This should return a meaningful errno on failure */
044b6a9e
MH
171int hold_lock_file_for_update_timeout(struct lock_file *lk, const char *path,
172 int flags, long timeout_ms)
40aaae88 173{
044b6a9e 174 int fd = lock_file_timeout(lk, path, flags, timeout_ms);
acd3b9ec 175 if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
e197c218 176 unable_to_lock_die(path, errno);
40aaae88
JH
177 return fd;
178}
179
ec38b4e4
MH
180char *get_locked_file_path(struct lock_file *lk)
181{
1a9d15db 182 struct strbuf ret = STRBUF_INIT;
013870cd 183
1a9d15db
MH
184 strbuf_addstr(&ret, get_tempfile_path(&lk->tempfile));
185 if (ret.len <= LOCK_SUFFIX_LEN ||
186 strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
ec38b4e4 187 die("BUG: get_locked_file_path() called for malformed lock object");
9c77381d 188 /* remove ".lock": */
1a9d15db
MH
189 strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN);
190 return strbuf_detach(&ret, NULL);
93dcaea2
JH
191}
192
751baced 193int commit_lock_file(struct lock_file *lk)
021b6e45 194{
9c77381d 195 char *result_path = get_locked_file_path(lk);
8a1c7533 196
9c77381d 197 if (commit_lock_file_to(lk, result_path)) {
1b1648f4 198 int save_errno = errno;
9c77381d 199 free(result_path);
1b1648f4 200 errno = save_errno;
d6cf61bf 201 return -1;
1b1648f4 202 }
9c77381d 203 free(result_path);
d6cf61bf 204 return 0;
021b6e45 205}