Documentation / technical / api-lockfile.txton commit Merge branch 'rs/maint-config-use-labs' into maint (e8c2351)
   1lockfile API
   2============
   3
   4The lockfile API serves two purposes:
   5
   6* Mutual exclusion and atomic file updates. When we want to change a
   7  file, we create a lockfile `<filename>.lock`, write the new file
   8  contents into it, and then rename the lockfile to its final
   9  destination `<filename>`. We create the `<filename>.lock` file with
  10  `O_CREAT|O_EXCL` so that we can notice and fail if somebody else has
  11  already locked the file, then atomically rename the lockfile to its
  12  final destination to commit the changes and unlock the file.
  13
  14* Automatic cruft removal. If the program exits after we lock a file
  15  but before the changes have been committed, we want to make sure
  16  that we remove the lockfile. This is done by remembering the
  17  lockfiles we have created in a linked list and setting up an
  18  `atexit(3)` handler and a signal handler that clean up the
  19  lockfiles. This mechanism ensures that outstanding lockfiles are
  20  cleaned up if the program exits (including when `die()` is called)
  21  or if the program dies on a signal.
  22
  23Please note that lockfiles only block other writers. Readers do not
  24block, but they are guaranteed to see either the old contents of the
  25file or the new contents of the file (assuming that the filesystem
  26implements `rename(2)` atomically).
  27
  28
  29Calling sequence
  30----------------
  31
  32The caller:
  33
  34* Allocates a `struct lock_file` either as a static variable or on the
  35  heap, initialized to zeros. Once you use the structure to call the
  36  `hold_lock_file_*` family of functions, it belongs to the lockfile
  37  subsystem and its storage must remain valid throughout the life of
  38  the program (i.e. you cannot use an on-stack variable to hold this
  39  structure).
  40
  41* Attempts to create a lockfile by passing that variable and the path
  42  of the final destination (e.g. `$GIT_DIR/index`) to
  43  `hold_lock_file_for_update` or `hold_lock_file_for_append`.
  44
  45* Writes new content for the destination file by either:
  46
  47  * writing to the file descriptor returned by the `hold_lock_file_*`
  48    functions (also available via `lock->fd`).
  49
  50  * calling `fdopen_lock_file` to get a `FILE` pointer for the open
  51    file and writing to the file using stdio.
  52
  53When finished writing, the caller can:
  54
  55* Close the file descriptor and rename the lockfile to its final
  56  destination by calling `commit_lock_file` or `commit_lock_file_to`.
  57
  58* Close the file descriptor and remove the lockfile by calling
  59  `rollback_lock_file`.
  60
  61* Close the file descriptor without removing or renaming the lockfile
  62  by calling `close_lock_file`, and later call `commit_lock_file`,
  63  `commit_lock_file_to`, `rollback_lock_file`, or `reopen_lock_file`.
  64
  65Even after the lockfile is committed or rolled back, the `lock_file`
  66object must not be freed or altered by the caller. However, it may be
  67reused; just pass it to another call of `hold_lock_file_for_update` or
  68`hold_lock_file_for_append`.
  69
  70If the program exits before you have called one of `commit_lock_file`,
  71`commit_lock_file_to`, `rollback_lock_file`, or `close_lock_file`, an
  72`atexit(3)` handler will close and remove the lockfile, rolling back
  73any uncommitted changes.
  74
  75If you need to close the file descriptor you obtained from a
  76`hold_lock_file_*` function yourself, do so by calling
  77`close_lock_file`. You should never call `close(2)` or `fclose(3)`
  78yourself! Otherwise the `struct lock_file` structure would still think
  79that the file descriptor needs to be closed, and a commit or rollback
  80would result in duplicate calls to `close(2)`. Worse yet, if you close
  81and then later open another file descriptor for a completely different
  82purpose, then a commit or rollback might close that unrelated file
  83descriptor.
  84
  85
  86Error handling
  87--------------
  88
  89The `hold_lock_file_*` functions return a file descriptor on success
  90or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see below). On
  91errors, `errno` describes the reason for failure. Errors can be
  92reported by passing `errno` to one of the following helper functions:
  93
  94unable_to_lock_message::
  95
  96        Append an appropriate error message to a `strbuf`.
  97
  98unable_to_lock_error::
  99
 100        Emit an appropriate error message using `error()`.
 101
 102unable_to_lock_die::
 103
 104        Emit an appropriate error message and `die()`.
 105
 106Similarly, `commit_lock_file`, `commit_lock_file_to`, and
 107`close_lock_file` return 0 on success. On failure they set `errno`
 108appropriately, do their best to roll back the lockfile, and return -1.
 109
 110
 111Flags
 112-----
 113
 114The following flags can be passed to `hold_lock_file_for_update` or
 115`hold_lock_file_for_append`:
 116
 117LOCK_NO_DEREF::
 118
 119        Usually symbolic links in the destination path are resolved
 120        and the lockfile is created by adding ".lock" to the resolved
 121        path. If `LOCK_NO_DEREF` is set, then the lockfile is created
 122        by adding ".lock" to the path argument itself. This option is
 123        used, for example, when locking a symbolic reference, which
 124        for backwards-compatibility reasons can be a symbolic link
 125        containing the name of the referred-to-reference.
 126
 127LOCK_DIE_ON_ERROR::
 128
 129        If a lock is already taken for the file, `die()` with an error
 130        message. If this option is not specified, trying to lock a
 131        file that is already locked returns -1 to the caller.
 132
 133
 134The functions
 135-------------
 136
 137hold_lock_file_for_update::
 138
 139        Take a pointer to `struct lock_file`, the path of the file to
 140        be locked (e.g. `$GIT_DIR/index`) and a flags argument (see
 141        above). Attempt to create a lockfile for the destination and
 142        return the file descriptor for writing to the file.
 143
 144hold_lock_file_for_append::
 145
 146        Like `hold_lock_file_for_update`, but before returning copy
 147        the existing contents of the file (if any) to the lockfile and
 148        position its write pointer at the end of the file.
 149
 150fdopen_lock_file::
 151
 152        Associate a stdio stream with the lockfile. Return NULL
 153        (*without* rolling back the lockfile) on error. The stream is
 154        closed automatically when `close_lock_file` is called or when
 155        the file is committed or rolled back.
 156
 157get_locked_file_path::
 158
 159        Return the path of the file that is locked by the specified
 160        lock_file object. The caller must free the memory.
 161
 162commit_lock_file::
 163
 164        Take a pointer to the `struct lock_file` initialized with an
 165        earlier call to `hold_lock_file_for_update` or
 166        `hold_lock_file_for_append`, close the file descriptor, and
 167        rename the lockfile to its final destination. Return 0 upon
 168        success. On failure, roll back the lock file and return -1,
 169        with `errno` set to the value from the failing call to
 170        `close(2)` or `rename(2)`. It is a bug to call
 171        `commit_lock_file` for a `lock_file` object that is not
 172        currently locked.
 173
 174commit_lock_file_to::
 175
 176        Like `commit_lock_file()`, except that it takes an explicit
 177        `path` argument to which the lockfile should be renamed. The
 178        `path` must be on the same filesystem as the lock file.
 179
 180rollback_lock_file::
 181
 182        Take a pointer to the `struct lock_file` initialized with an
 183        earlier call to `hold_lock_file_for_update` or
 184        `hold_lock_file_for_append`, close the file descriptor and
 185        remove the lockfile. It is a NOOP to call
 186        `rollback_lock_file()` for a `lock_file` object that has
 187        already been committed or rolled back.
 188
 189close_lock_file::
 190
 191        Take a pointer to the `struct lock_file` initialized with an
 192        earlier call to `hold_lock_file_for_update` or
 193        `hold_lock_file_for_append`. Close the file descriptor (and
 194        the file pointer if it has been opened using
 195        `fdopen_lock_file`). Return 0 upon success. On failure to
 196        `close(2)`, return a negative value and roll back the lock
 197        file. Usually `commit_lock_file`, `commit_lock_file_to`, or
 198        `rollback_lock_file` should eventually be called if
 199        `close_lock_file` succeeds.
 200
 201reopen_lock_file::
 202
 203        Re-open a lockfile that has been closed (using
 204        `close_lock_file`) but not yet committed or rolled back. This
 205        can be used to implement a sequence of operations like the
 206        following:
 207
 208        * Lock file.
 209
 210        * Write new contents to lockfile, then `close_lock_file` to
 211          cause the contents to be written to disk.
 212
 213        * Pass the name of the lockfile to another program to allow it
 214          (and nobody else) to inspect the contents you wrote, while
 215          still holding the lock yourself.
 216
 217        * `reopen_lock_file` to reopen the lockfile. Make further
 218          updates to the contents.
 219
 220        * `commit_lock_file` to make the final version permanent.