1/* 2 * Copyright (c) 2005, Junio C Hamano 3 */ 4 5#include "cache.h" 6#include "lockfile.h" 7 8/* 9 * path = absolute or relative path name 10 * 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. 14 */ 15static void trim_last_path_component(struct strbuf *path) 16{ 17 int i = path->len; 18 19 /* back up past trailing slashes, if any */ 20 while (i && path->buf[i - 1] == '/') 21 i--; 22 23 /* 24 * then go backwards until a slash, or the beginning of the 25 * string 26 */ 27 while (i && path->buf[i - 1] != '/') 28 i--; 29 30 strbuf_setlen(path, i); 31} 32 33 34/* We allow "recursive" symbolic links. Only within reason, though */ 35#define MAXDEPTH 5 36 37/* 38 * path contains a path that might be a symlink. 39 * 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. 43 * 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. 47 */ 48static void resolve_symlink(struct strbuf *path) 49{ 50 int depth = MAXDEPTH; 51 static struct strbuf link = STRBUF_INIT; 52 53 while (depth--) { 54 if (strbuf_readlink(&link, path->buf, path->len) < 0) 55 break; 56 57 if (is_absolute_path(link.buf)) 58 /* absolute path simply replaces p */ 59 strbuf_reset(path); 60 else 61 /* 62 * link is a relative path, so replace the 63 * last element of p with it. 64 */ 65 trim_last_path_component(path); 66 67 strbuf_addbuf(path, &link); 68 } 69 strbuf_reset(&link); 70} 71 72/* Make sure errno contains a meaningful value on error */ 73static int lock_file(struct lock_file *lk, const char *path, int flags) 74{ 75 struct strbuf filename = STRBUF_INIT; 76 77 strbuf_addstr(&filename, path); 78 if (!(flags & LOCK_NO_DEREF)) 79 resolve_symlink(&filename); 80 81 strbuf_addstr(&filename, LOCK_SUFFIX); 82 lk->tempfile = create_tempfile(filename.buf); 83 strbuf_release(&filename); 84 return lk->tempfile ? lk->tempfile->fd : -1; 85} 86 87/* 88 * Constants defining the gaps between attempts to lock a file. The 89 * first backoff period is approximately INITIAL_BACKOFF_MS 90 * milliseconds. The longest backoff period is approximately 91 * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds. 92 */ 93#define INITIAL_BACKOFF_MS 1L 94#define BACKOFF_MAX_MULTIPLIER 1000 95 96/* 97 * Try locking path, retrying with quadratic backoff for at least 98 * timeout_ms milliseconds. If timeout_ms is 0, try locking the file 99 * exactly once. If timeout_ms is -1, try indefinitely. 100 */ 101static int lock_file_timeout(struct lock_file *lk, const char *path, 102 int flags, long timeout_ms) 103{ 104 int n = 1; 105 int multiplier = 1; 106 long remaining_ms = 0; 107 static int random_initialized = 0; 108 109 if (timeout_ms == 0) 110 return lock_file(lk, path, flags); 111 112 if (!random_initialized) { 113 srand((unsigned int)getpid()); 114 random_initialized = 1; 115 } 116 117 if (timeout_ms > 0) 118 remaining_ms = timeout_ms; 119 120 while (1) { 121 long backoff_ms, wait_ms; 122 int fd; 123 124 fd = lock_file(lk, path, flags); 125 126 if (fd >= 0) 127 return fd; /* success */ 128 else if (errno != EEXIST) 129 return -1; /* failure other than lock held */ 130 else if (timeout_ms > 0 && remaining_ms <= 0) 131 return -1; /* failure due to timeout */ 132 133 backoff_ms = multiplier * INITIAL_BACKOFF_MS; 134 /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */ 135 wait_ms = (750 + rand() % 500) * backoff_ms / 1000; 136 sleep_millisec(wait_ms); 137 remaining_ms -= wait_ms; 138 139 /* Recursion: (n+1)^2 = n^2 + 2n + 1 */ 140 multiplier += 2*n + 1; 141 if (multiplier > BACKOFF_MAX_MULTIPLIER) 142 multiplier = BACKOFF_MAX_MULTIPLIER; 143 else 144 n++; 145 } 146} 147 148void unable_to_lock_message(const char *path, int err, struct strbuf *buf) 149{ 150 if (err == EEXIST) { 151 strbuf_addf(buf, _("Unable to create '%s.lock': %s.\n\n" 152 "Another git process seems to be running in this repository, e.g.\n" 153 "an editor opened by 'git commit'. Please make sure all processes\n" 154 "are terminated then try again. If it still fails, a git process\n" 155 "may have crashed in this repository earlier:\n" 156 "remove the file manually to continue."), 157 absolute_path(path), strerror(err)); 158 } else 159 strbuf_addf(buf, _("Unable to create '%s.lock': %s"), 160 absolute_path(path), strerror(err)); 161} 162 163NORETURN void unable_to_lock_die(const char *path, int err) 164{ 165 struct strbuf buf = STRBUF_INIT; 166 167 unable_to_lock_message(path, err, &buf); 168 die("%s", buf.buf); 169} 170 171/* This should return a meaningful errno on failure */ 172int hold_lock_file_for_update_timeout(struct lock_file *lk, const char *path, 173 int flags, long timeout_ms) 174{ 175 int fd = lock_file_timeout(lk, path, flags, timeout_ms); 176 if (fd < 0) { 177 if (flags & LOCK_DIE_ON_ERROR) 178 unable_to_lock_die(path, errno); 179 if (flags & LOCK_REPORT_ON_ERROR) { 180 struct strbuf buf = STRBUF_INIT; 181 unable_to_lock_message(path, errno, &buf); 182 error("%s", buf.buf); 183 strbuf_release(&buf); 184 } 185 } 186 return fd; 187} 188 189char *get_locked_file_path(struct lock_file *lk) 190{ 191 struct strbuf ret = STRBUF_INIT; 192 193 strbuf_addstr(&ret, get_tempfile_path(lk->tempfile)); 194 if (ret.len <= LOCK_SUFFIX_LEN || 195 strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX)) 196 die("BUG: get_locked_file_path() called for malformed lock object"); 197 /* remove ".lock": */ 198 strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN); 199 return strbuf_detach(&ret, NULL); 200} 201 202int commit_lock_file(struct lock_file *lk) 203{ 204 char *result_path = get_locked_file_path(lk); 205 206 if (commit_lock_file_to(lk, result_path)) { 207 int save_errno = errno; 208 free(result_path); 209 errno = save_errno; 210 return -1; 211 } 212 free(result_path); 213 return 0; 214}