THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
5.6KB

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