lockfile.con commit each_ref_fn_adapter(): remove adapter (0a0c953)
   1/*
   2 * Copyright (c) 2005, Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "lockfile.h"
   6#include "sigchain.h"
   7
   8static struct lock_file *volatile lock_file_list;
   9
  10static void remove_lock_files(int skip_fclose)
  11{
  12        pid_t me = getpid();
  13
  14        while (lock_file_list) {
  15                if (lock_file_list->owner == me) {
  16                        /* fclose() is not safe to call in a signal handler */
  17                        if (skip_fclose)
  18                                lock_file_list->fp = NULL;
  19                        rollback_lock_file(lock_file_list);
  20                }
  21                lock_file_list = lock_file_list->next;
  22        }
  23}
  24
  25static void remove_lock_files_on_exit(void)
  26{
  27        remove_lock_files(0);
  28}
  29
  30static void remove_lock_files_on_signal(int signo)
  31{
  32        remove_lock_files(1);
  33        sigchain_pop(signo);
  34        raise(signo);
  35}
  36
  37/*
  38 * path = absolute or relative path name
  39 *
  40 * Remove the last path name element from path (leaving the preceding
  41 * "/", if any).  If path is empty or the root directory ("/"), set
  42 * path to the empty string.
  43 */
  44static void trim_last_path_component(struct strbuf *path)
  45{
  46        int i = path->len;
  47
  48        /* back up past trailing slashes, if any */
  49        while (i && path->buf[i - 1] == '/')
  50                i--;
  51
  52        /*
  53         * then go backwards until a slash, or the beginning of the
  54         * string
  55         */
  56        while (i && path->buf[i - 1] != '/')
  57                i--;
  58
  59        strbuf_setlen(path, i);
  60}
  61
  62
  63/* We allow "recursive" symbolic links. Only within reason, though */
  64#define MAXDEPTH 5
  65
  66/*
  67 * path contains a path that might be a symlink.
  68 *
  69 * If path is a symlink, attempt to overwrite it with a path to the
  70 * real file or directory (which may or may not exist), following a
  71 * chain of symlinks if necessary.  Otherwise, leave path unmodified.
  72 *
  73 * This is a best-effort routine.  If an error occurs, path will
  74 * either be left unmodified or will name a different symlink in a
  75 * symlink chain that started with the original path.
  76 */
  77static void resolve_symlink(struct strbuf *path)
  78{
  79        int depth = MAXDEPTH;
  80        static struct strbuf link = STRBUF_INIT;
  81
  82        while (depth--) {
  83                if (strbuf_readlink(&link, path->buf, path->len) < 0)
  84                        break;
  85
  86                if (is_absolute_path(link.buf))
  87                        /* absolute path simply replaces p */
  88                        strbuf_reset(path);
  89                else
  90                        /*
  91                         * link is a relative path, so replace the
  92                         * last element of p with it.
  93                         */
  94                        trim_last_path_component(path);
  95
  96                strbuf_addbuf(path, &link);
  97        }
  98        strbuf_reset(&link);
  99}
 100
 101/* Make sure errno contains a meaningful value on error */
 102static int lock_file(struct lock_file *lk, const char *path, int flags)
 103{
 104        size_t pathlen = strlen(path);
 105
 106        if (!lock_file_list) {
 107                /* One-time initialization */
 108                sigchain_push_common(remove_lock_files_on_signal);
 109                atexit(remove_lock_files_on_exit);
 110        }
 111
 112        if (lk->active)
 113                die("BUG: cannot lock_file(\"%s\") using active struct lock_file",
 114                    path);
 115        if (!lk->on_list) {
 116                /* Initialize *lk and add it to lock_file_list: */
 117                lk->fd = -1;
 118                lk->fp = NULL;
 119                lk->active = 0;
 120                lk->owner = 0;
 121                strbuf_init(&lk->filename, pathlen + LOCK_SUFFIX_LEN);
 122                lk->next = lock_file_list;
 123                lock_file_list = lk;
 124                lk->on_list = 1;
 125        } else if (lk->filename.len) {
 126                /* This shouldn't happen, but better safe than sorry. */
 127                die("BUG: lock_file(\"%s\") called with improperly-reset lock_file object",
 128                    path);
 129        }
 130
 131        if (flags & LOCK_NO_DEREF) {
 132                strbuf_add_absolute_path(&lk->filename, path);
 133        } else {
 134                struct strbuf resolved_path = STRBUF_INIT;
 135
 136                strbuf_add(&resolved_path, path, pathlen);
 137                resolve_symlink(&resolved_path);
 138                strbuf_add_absolute_path(&lk->filename, resolved_path.buf);
 139                strbuf_release(&resolved_path);
 140        }
 141
 142        strbuf_addstr(&lk->filename, LOCK_SUFFIX);
 143        lk->fd = open(lk->filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666);
 144        if (lk->fd < 0) {
 145                strbuf_reset(&lk->filename);
 146                return -1;
 147        }
 148        lk->owner = getpid();
 149        lk->active = 1;
 150        if (adjust_shared_perm(lk->filename.buf)) {
 151                int save_errno = errno;
 152                error("cannot fix permission bits on %s", lk->filename.buf);
 153                rollback_lock_file(lk);
 154                errno = save_errno;
 155                return -1;
 156        }
 157        return lk->fd;
 158}
 159
 160static int sleep_microseconds(long us)
 161{
 162        struct timeval tv;
 163        tv.tv_sec = 0;
 164        tv.tv_usec = us;
 165        return select(0, NULL, NULL, NULL, &tv);
 166}
 167
 168/*
 169 * Constants defining the gaps between attempts to lock a file. The
 170 * first backoff period is approximately INITIAL_BACKOFF_MS
 171 * milliseconds. The longest backoff period is approximately
 172 * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds.
 173 */
 174#define INITIAL_BACKOFF_MS 1L
 175#define BACKOFF_MAX_MULTIPLIER 1000
 176
 177/*
 178 * Try locking path, retrying with quadratic backoff for at least
 179 * timeout_ms milliseconds. If timeout_ms is 0, try locking the file
 180 * exactly once. If timeout_ms is -1, try indefinitely.
 181 */
 182static int lock_file_timeout(struct lock_file *lk, const char *path,
 183                             int flags, long timeout_ms)
 184{
 185        int n = 1;
 186        int multiplier = 1;
 187        long remaining_us = 0;
 188        static int random_initialized = 0;
 189
 190        if (timeout_ms == 0)
 191                return lock_file(lk, path, flags);
 192
 193        if (!random_initialized) {
 194                srandom((unsigned int)getpid());
 195                random_initialized = 1;
 196        }
 197
 198        if (timeout_ms > 0) {
 199                /* avoid overflow */
 200                if (timeout_ms <= LONG_MAX / 1000)
 201                        remaining_us = timeout_ms * 1000;
 202                else
 203                        remaining_us = LONG_MAX;
 204        }
 205
 206        while (1) {
 207                long backoff_ms, wait_us;
 208                int fd;
 209
 210                fd = lock_file(lk, path, flags);
 211
 212                if (fd >= 0)
 213                        return fd; /* success */
 214                else if (errno != EEXIST)
 215                        return -1; /* failure other than lock held */
 216                else if (timeout_ms > 0 && remaining_us <= 0)
 217                        return -1; /* failure due to timeout */
 218
 219                backoff_ms = multiplier * INITIAL_BACKOFF_MS;
 220                /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
 221                wait_us = (750 + random() % 500) * backoff_ms;
 222                sleep_microseconds(wait_us);
 223                remaining_us -= wait_us;
 224
 225                /* Recursion: (n+1)^2 = n^2 + 2n + 1 */
 226                multiplier += 2*n + 1;
 227                if (multiplier > BACKOFF_MAX_MULTIPLIER)
 228                        multiplier = BACKOFF_MAX_MULTIPLIER;
 229                else
 230                        n++;
 231        }
 232}
 233
 234void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
 235{
 236        if (err == EEXIST) {
 237                strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
 238                    "If no other git process is currently running, this probably means a\n"
 239                    "git process crashed in this repository earlier. Make sure no other git\n"
 240                    "process is running and remove the file manually to continue.",
 241                            absolute_path(path), strerror(err));
 242        } else
 243                strbuf_addf(buf, "Unable to create '%s.lock': %s",
 244                            absolute_path(path), strerror(err));
 245}
 246
 247NORETURN void unable_to_lock_die(const char *path, int err)
 248{
 249        struct strbuf buf = STRBUF_INIT;
 250
 251        unable_to_lock_message(path, err, &buf);
 252        die("%s", buf.buf);
 253}
 254
 255/* This should return a meaningful errno on failure */
 256int hold_lock_file_for_update_timeout(struct lock_file *lk, const char *path,
 257                                      int flags, long timeout_ms)
 258{
 259        int fd = lock_file_timeout(lk, path, flags, timeout_ms);
 260        if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
 261                unable_to_lock_die(path, errno);
 262        return fd;
 263}
 264
 265int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
 266{
 267        int fd, orig_fd;
 268
 269        fd = lock_file(lk, path, flags);
 270        if (fd < 0) {
 271                if (flags & LOCK_DIE_ON_ERROR)
 272                        unable_to_lock_die(path, errno);
 273                return fd;
 274        }
 275
 276        orig_fd = open(path, O_RDONLY);
 277        if (orig_fd < 0) {
 278                if (errno != ENOENT) {
 279                        int save_errno = errno;
 280
 281                        if (flags & LOCK_DIE_ON_ERROR)
 282                                die("cannot open '%s' for copying", path);
 283                        rollback_lock_file(lk);
 284                        error("cannot open '%s' for copying", path);
 285                        errno = save_errno;
 286                        return -1;
 287                }
 288        } else if (copy_fd(orig_fd, fd)) {
 289                int save_errno = errno;
 290
 291                if (flags & LOCK_DIE_ON_ERROR)
 292                        die("failed to prepare '%s' for appending", path);
 293                close(orig_fd);
 294                rollback_lock_file(lk);
 295                errno = save_errno;
 296                return -1;
 297        } else {
 298                close(orig_fd);
 299        }
 300        return fd;
 301}
 302
 303FILE *fdopen_lock_file(struct lock_file *lk, const char *mode)
 304{
 305        if (!lk->active)
 306                die("BUG: fdopen_lock_file() called for unlocked object");
 307        if (lk->fp)
 308                die("BUG: fdopen_lock_file() called twice for file '%s'", lk->filename.buf);
 309
 310        lk->fp = fdopen(lk->fd, mode);
 311        return lk->fp;
 312}
 313
 314char *get_locked_file_path(struct lock_file *lk)
 315{
 316        if (!lk->active)
 317                die("BUG: get_locked_file_path() called for unlocked object");
 318        if (lk->filename.len <= LOCK_SUFFIX_LEN)
 319                die("BUG: get_locked_file_path() called for malformed lock object");
 320        return xmemdupz(lk->filename.buf, lk->filename.len - LOCK_SUFFIX_LEN);
 321}
 322
 323int close_lock_file(struct lock_file *lk)
 324{
 325        int fd = lk->fd;
 326        FILE *fp = lk->fp;
 327        int err;
 328
 329        if (fd < 0)
 330                return 0;
 331
 332        lk->fd = -1;
 333        if (fp) {
 334                lk->fp = NULL;
 335
 336                /*
 337                 * Note: no short-circuiting here; we want to fclose()
 338                 * in any case!
 339                 */
 340                err = ferror(fp) | fclose(fp);
 341        } else {
 342                err = close(fd);
 343        }
 344
 345        if (err) {
 346                int save_errno = errno;
 347                rollback_lock_file(lk);
 348                errno = save_errno;
 349                return -1;
 350        }
 351
 352        return 0;
 353}
 354
 355int reopen_lock_file(struct lock_file *lk)
 356{
 357        if (0 <= lk->fd)
 358                die(_("BUG: reopen a lockfile that is still open"));
 359        if (!lk->active)
 360                die(_("BUG: reopen a lockfile that has been committed"));
 361        lk->fd = open(lk->filename.buf, O_WRONLY);
 362        return lk->fd;
 363}
 364
 365int commit_lock_file_to(struct lock_file *lk, const char *path)
 366{
 367        if (!lk->active)
 368                die("BUG: attempt to commit unlocked object to \"%s\"", path);
 369
 370        if (close_lock_file(lk))
 371                return -1;
 372
 373        if (rename(lk->filename.buf, path)) {
 374                int save_errno = errno;
 375                rollback_lock_file(lk);
 376                errno = save_errno;
 377                return -1;
 378        }
 379
 380        lk->active = 0;
 381        strbuf_reset(&lk->filename);
 382        return 0;
 383}
 384
 385int commit_lock_file(struct lock_file *lk)
 386{
 387        static struct strbuf result_file = STRBUF_INIT;
 388        int err;
 389
 390        if (!lk->active)
 391                die("BUG: attempt to commit unlocked object");
 392
 393        if (lk->filename.len <= LOCK_SUFFIX_LEN ||
 394            strcmp(lk->filename.buf + lk->filename.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
 395                die("BUG: lockfile filename corrupt");
 396
 397        /* remove ".lock": */
 398        strbuf_add(&result_file, lk->filename.buf,
 399                   lk->filename.len - LOCK_SUFFIX_LEN);
 400        err = commit_lock_file_to(lk, result_file.buf);
 401        strbuf_reset(&result_file);
 402        return err;
 403}
 404
 405void rollback_lock_file(struct lock_file *lk)
 406{
 407        if (!lk->active)
 408                return;
 409
 410        if (!close_lock_file(lk)) {
 411                unlink_or_warn(lk->filename.buf);
 412                lk->active = 0;
 413                strbuf_reset(&lk->filename);
 414        }
 415}