lockfile.con commit commit_lock_file_to(): refactor a helper out of commit_lock_file() (751bace)
   1/*
   2 * Copyright (c) 2005, Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "sigchain.h"
   6
   7/*
   8 * File write-locks as used by Git.
   9 *
  10 * For an overview of how to use the lockfile API, please see
  11 *
  12 *     Documentation/technical/api-lockfile.txt
  13 *
  14 * This module keeps track of all locked files in lock_file_list for
  15 * use at cleanup. This list and the lock_file objects that comprise
  16 * it must be kept in self-consistent states at all time, because the
  17 * program can be interrupted any time by a signal, in which case the
  18 * signal handler will walk through the list attempting to clean up
  19 * any open lock files.
  20 *
  21 * A lockfile is owned by the process that created it. The lock_file
  22 * object has an "owner" field that records its owner. This field is
  23 * used to prevent a forked process from closing a lockfile created by
  24 * its parent.
  25 *
  26 * The possible states of a lock_file object are as follows:
  27 *
  28 * - Uninitialized.  In this state the object's on_list field must be
  29 *   zero but the rest of its contents need not be initialized.  As
  30 *   soon as the object is used in any way, it is irrevocably
  31 *   registered in the lock_file_list, and on_list is set.
  32 *
  33 * - Locked, lockfile open (after hold_lock_file_for_update(),
  34 *   hold_lock_file_for_append(), or reopen_lock_file()). In this
  35 *   state:
  36 *   - the lockfile exists
  37 *   - active is set
  38 *   - filename holds the filename of the lockfile
  39 *   - fd holds a file descriptor open for writing to the lockfile
  40 *   - owner holds the PID of the process that locked the file
  41 *
  42 * - Locked, lockfile closed (after successful close_lock_file()).
  43 *   Same as the previous state, except that the lockfile is closed
  44 *   and fd is -1.
  45 *
  46 * - Unlocked (after commit_lock_file(), commit_lock_file_to(),
  47 *   rollback_lock_file(), a failed attempt to lock, or a failed
  48 *   close_lock_file()).  In this state:
  49 *   - active is unset
  50 *   - filename is empty (usually, though there are transitory
  51 *     states in which this condition doesn't hold). Client code should
  52 *     *not* rely on the filename being empty in this state.
  53 *   - fd is -1
  54 *   - the object is left registered in the lock_file_list, and
  55 *     on_list is set.
  56 */
  57
  58static struct lock_file *volatile lock_file_list;
  59
  60static void remove_lock_file(void)
  61{
  62        pid_t me = getpid();
  63
  64        while (lock_file_list) {
  65                if (lock_file_list->owner == me)
  66                        rollback_lock_file(lock_file_list);
  67                lock_file_list = lock_file_list->next;
  68        }
  69}
  70
  71static void remove_lock_file_on_signal(int signo)
  72{
  73        remove_lock_file();
  74        sigchain_pop(signo);
  75        raise(signo);
  76}
  77
  78/*
  79 * path = absolute or relative path name
  80 *
  81 * Remove the last path name element from path (leaving the preceding
  82 * "/", if any).  If path is empty or the root directory ("/"), set
  83 * path to the empty string.
  84 */
  85static void trim_last_path_component(struct strbuf *path)
  86{
  87        int i = path->len;
  88
  89        /* back up past trailing slashes, if any */
  90        while (i && path->buf[i - 1] == '/')
  91                i--;
  92
  93        /*
  94         * then go backwards until a slash, or the beginning of the
  95         * string
  96         */
  97        while (i && path->buf[i - 1] != '/')
  98                i--;
  99
 100        strbuf_setlen(path, i);
 101}
 102
 103
 104/* We allow "recursive" symbolic links. Only within reason, though */
 105#define MAXDEPTH 5
 106
 107/*
 108 * path contains a path that might be a symlink.
 109 *
 110 * If path is a symlink, attempt to overwrite it with a path to the
 111 * real file or directory (which may or may not exist), following a
 112 * chain of symlinks if necessary.  Otherwise, leave path unmodified.
 113 *
 114 * This is a best-effort routine.  If an error occurs, path will
 115 * either be left unmodified or will name a different symlink in a
 116 * symlink chain that started with the original path.
 117 */
 118static void resolve_symlink(struct strbuf *path)
 119{
 120        int depth = MAXDEPTH;
 121        static struct strbuf link = STRBUF_INIT;
 122
 123        while (depth--) {
 124                if (strbuf_readlink(&link, path->buf, path->len) < 0)
 125                        break;
 126
 127                if (is_absolute_path(link.buf))
 128                        /* absolute path simply replaces p */
 129                        strbuf_reset(path);
 130                else
 131                        /*
 132                         * link is a relative path, so replace the
 133                         * last element of p with it.
 134                         */
 135                        trim_last_path_component(path);
 136
 137                strbuf_addbuf(path, &link);
 138        }
 139        strbuf_reset(&link);
 140}
 141
 142/* Make sure errno contains a meaningful value on error */
 143static int lock_file(struct lock_file *lk, const char *path, int flags)
 144{
 145        size_t pathlen = strlen(path);
 146
 147        if (!lock_file_list) {
 148                /* One-time initialization */
 149                sigchain_push_common(remove_lock_file_on_signal);
 150                atexit(remove_lock_file);
 151        }
 152
 153        if (lk->active)
 154                die("BUG: cannot lock_file(\"%s\") using active struct lock_file",
 155                    path);
 156        if (!lk->on_list) {
 157                /* Initialize *lk and add it to lock_file_list: */
 158                lk->fd = -1;
 159                lk->active = 0;
 160                lk->owner = 0;
 161                strbuf_init(&lk->filename, pathlen + LOCK_SUFFIX_LEN);
 162                lk->next = lock_file_list;
 163                lock_file_list = lk;
 164                lk->on_list = 1;
 165        } else if (lk->filename.len) {
 166                /* This shouldn't happen, but better safe than sorry. */
 167                die("BUG: lock_file(\"%s\") called with improperly-reset lock_file object",
 168                    path);
 169        }
 170
 171        strbuf_add(&lk->filename, path, pathlen);
 172        if (!(flags & LOCK_NODEREF))
 173                resolve_symlink(&lk->filename);
 174        strbuf_addstr(&lk->filename, LOCK_SUFFIX);
 175        lk->fd = open(lk->filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666);
 176        if (lk->fd < 0) {
 177                strbuf_reset(&lk->filename);
 178                return -1;
 179        }
 180        lk->owner = getpid();
 181        lk->active = 1;
 182        if (adjust_shared_perm(lk->filename.buf)) {
 183                int save_errno = errno;
 184                error("cannot fix permission bits on %s", lk->filename.buf);
 185                rollback_lock_file(lk);
 186                errno = save_errno;
 187                return -1;
 188        }
 189        return lk->fd;
 190}
 191
 192void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
 193{
 194        if (err == EEXIST) {
 195                strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
 196                    "If no other git process is currently running, this probably means a\n"
 197                    "git process crashed in this repository earlier. Make sure no other git\n"
 198                    "process is running and remove the file manually to continue.",
 199                            absolute_path(path), strerror(err));
 200        } else
 201                strbuf_addf(buf, "Unable to create '%s.lock': %s",
 202                            absolute_path(path), strerror(err));
 203}
 204
 205int unable_to_lock_error(const char *path, int err)
 206{
 207        struct strbuf buf = STRBUF_INIT;
 208
 209        unable_to_lock_message(path, err, &buf);
 210        error("%s", buf.buf);
 211        strbuf_release(&buf);
 212        return -1;
 213}
 214
 215NORETURN void unable_to_lock_die(const char *path, int err)
 216{
 217        struct strbuf buf = STRBUF_INIT;
 218
 219        unable_to_lock_message(path, err, &buf);
 220        die("%s", buf.buf);
 221}
 222
 223/* This should return a meaningful errno on failure */
 224int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
 225{
 226        int fd = lock_file(lk, path, flags);
 227        if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
 228                unable_to_lock_die(path, errno);
 229        return fd;
 230}
 231
 232int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
 233{
 234        int fd, orig_fd;
 235
 236        fd = lock_file(lk, path, flags);
 237        if (fd < 0) {
 238                if (flags & LOCK_DIE_ON_ERROR)
 239                        unable_to_lock_die(path, errno);
 240                return fd;
 241        }
 242
 243        orig_fd = open(path, O_RDONLY);
 244        if (orig_fd < 0) {
 245                if (errno != ENOENT) {
 246                        if (flags & LOCK_DIE_ON_ERROR)
 247                                die("cannot open '%s' for copying", path);
 248                        rollback_lock_file(lk);
 249                        return error("cannot open '%s' for copying", path);
 250                }
 251        } else if (copy_fd(orig_fd, fd)) {
 252                if (flags & LOCK_DIE_ON_ERROR)
 253                        exit(128);
 254                rollback_lock_file(lk);
 255                return -1;
 256        }
 257        return fd;
 258}
 259
 260int close_lock_file(struct lock_file *lk)
 261{
 262        int fd = lk->fd;
 263
 264        if (fd < 0)
 265                return 0;
 266
 267        lk->fd = -1;
 268        if (close(fd)) {
 269                int save_errno = errno;
 270                rollback_lock_file(lk);
 271                errno = save_errno;
 272                return -1;
 273        }
 274        return 0;
 275}
 276
 277int reopen_lock_file(struct lock_file *lk)
 278{
 279        if (0 <= lk->fd)
 280                die(_("BUG: reopen a lockfile that is still open"));
 281        if (!lk->active)
 282                die(_("BUG: reopen a lockfile that has been committed"));
 283        lk->fd = open(lk->filename.buf, O_WRONLY);
 284        return lk->fd;
 285}
 286
 287int commit_lock_file_to(struct lock_file *lk, const char *path)
 288{
 289        if (!lk->active)
 290                die("BUG: attempt to commit unlocked object to \"%s\"", path);
 291
 292        if (close_lock_file(lk))
 293                return -1;
 294
 295        if (rename(lk->filename.buf, path)) {
 296                int save_errno = errno;
 297                rollback_lock_file(lk);
 298                errno = save_errno;
 299                return -1;
 300        }
 301
 302        lk->active = 0;
 303        strbuf_reset(&lk->filename);
 304        return 0;
 305}
 306
 307int commit_lock_file(struct lock_file *lk)
 308{
 309        static struct strbuf result_file = STRBUF_INIT;
 310        int err;
 311
 312        if (!lk->active)
 313                die("BUG: attempt to commit unlocked object");
 314
 315        if (lk->filename.len <= LOCK_SUFFIX_LEN ||
 316            strcmp(lk->filename.buf + lk->filename.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
 317                die("BUG: lockfile filename corrupt");
 318
 319        /* remove ".lock": */
 320        strbuf_add(&result_file, lk->filename.buf,
 321                   lk->filename.len - LOCK_SUFFIX_LEN);
 322        err = commit_lock_file_to(lk, result_file.buf);
 323        strbuf_reset(&result_file);
 324        return err;
 325}
 326
 327int hold_locked_index(struct lock_file *lk, int die_on_error)
 328{
 329        return hold_lock_file_for_update(lk, get_index_file(),
 330                                         die_on_error
 331                                         ? LOCK_DIE_ON_ERROR
 332                                         : 0);
 333}
 334
 335void rollback_lock_file(struct lock_file *lk)
 336{
 337        if (!lk->active)
 338                return;
 339
 340        if (!close_lock_file(lk)) {
 341                unlink_or_warn(lk->filename.buf);
 342                lk->active = 0;
 343                strbuf_reset(&lk->filename);
 344        }
 345}