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 writing to the file 46 descriptor returned by those functions (also available via 47 `lock->fd`). 48 49When finished writing, the caller can: 50 51* Close the file descriptor and rename the lockfile to its final 52 destination by calling `commit_lock_file` or `commit_lock_file_to`. 53 54* Close the file descriptor and remove the lockfile by calling 55 `rollback_lock_file`. 56 57* Close the file descriptor without removing or renaming the lockfile 58 by calling `close_lock_file`, and later call `commit_lock_file`, 59 `commit_lock_file_to`, `rollback_lock_file`, or `reopen_lock_file`. 60 61Even after the lockfile is committed or rolled back, the `lock_file` 62object must not be freed or altered by the caller. However, it may be 63reused; just pass it to another call of `hold_lock_file_for_update` or 64`hold_lock_file_for_append`. 65 66If the program exits before you have called one of `commit_lock_file`, 67`commit_lock_file_to`, `rollback_lock_file`, or `close_lock_file`, an 68`atexit(3)` handler will close and remove the lockfile, rolling back 69any uncommitted changes. 70 71If you need to close the file descriptor you obtained from a 72`hold_lock_file_*` function yourself, do so by calling 73`close_lock_file`. You should never call `close(2)` yourself! 74Otherwise the `struct lock_file` structure would still think that the 75file descriptor needs to be closed, and a commit or rollback would 76result in duplicate calls to `close(2)`. Worse yet, if you `close(2)` 77and then later open another file descriptor for a completely different 78purpose, then a commit or rollback might close that unrelated file 79descriptor. 80 81 82Error handling 83-------------- 84 85The `hold_lock_file_*` functions return a file descriptor on success 86or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see below). On 87errors, `errno` describes the reason for failure. Errors can be 88reported by passing `errno` to one of the following helper functions: 89 90unable_to_lock_message:: 91 92 Append an appropriate error message to a `strbuf`. 93 94unable_to_lock_error:: 95 96 Emit an appropriate error message using `error()`. 97 98unable_to_lock_die:: 99 100 Emit an appropriate error message and `die()`. 101 102Similarly, `commit_lock_file`, `commit_lock_file_to`, and 103`close_lock_file` return 0 on success. On failure they set `errno` 104appropriately, do their best to roll back the lockfile, and return -1. 105 106 107Flags 108----- 109 110The following flags can be passed to `hold_lock_file_for_update` or 111`hold_lock_file_for_append`: 112 113LOCK_NO_DEREF:: 114 115 Usually symbolic links in the destination path are resolved 116 and the lockfile is created by adding ".lock" to the resolved 117 path. If `LOCK_NO_DEREF` is set, then the lockfile is created 118 by adding ".lock" to the path argument itself. This option is 119 used, for example, when locking a symbolic reference, which 120 for backwards-compatibility reasons can be a symbolic link 121 containing the name of the referred-to-reference. 122 123LOCK_DIE_ON_ERROR:: 124 125 If a lock is already taken for the file, `die()` with an error 126 message. If this option is not specified, trying to lock a 127 file that is already locked returns -1 to the caller. 128 129 130The functions 131------------- 132 133hold_lock_file_for_update:: 134 135 Take a pointer to `struct lock_file`, the path of the file to 136 be locked (e.g. `$GIT_DIR/index`) and a flags argument (see 137 above). Attempt to create a lockfile for the destination and 138 return the file descriptor for writing to the file. 139 140hold_lock_file_for_append:: 141 142 Like `hold_lock_file_for_update`, but before returning copy 143 the existing contents of the file (if any) to the lockfile and 144 position its write pointer at the end of the file. 145 146get_locked_file_path:: 147 148 Return the path of the file that is locked by the specified 149 lock_file object. The caller must free the memory. 150 151commit_lock_file:: 152 153 Take a pointer to the `struct lock_file` initialized with an 154 earlier call to `hold_lock_file_for_update` or 155 `hold_lock_file_for_append`, close the file descriptor, and 156 rename the lockfile to its final destination. Return 0 upon 157 success. On failure, roll back the lock file and return -1, 158 with `errno` set to the value from the failing call to 159 `close(2)` or `rename(2)`. It is a bug to call 160 `commit_lock_file` for a `lock_file` object that is not 161 currently locked. 162 163commit_lock_file_to:: 164 165 Like `commit_lock_file()`, except that it takes an explicit 166 `path` argument to which the lockfile should be renamed. The 167 `path` must be on the same filesystem as the lock file. 168 169rollback_lock_file:: 170 171 Take a pointer to the `struct lock_file` initialized with an 172 earlier call to `hold_lock_file_for_update` or 173 `hold_lock_file_for_append`, close the file descriptor and 174 remove the lockfile. It is a NOOP to call 175 `rollback_lock_file()` for a `lock_file` object that has 176 already been committed or rolled back. 177 178close_lock_file:: 179 180 Take a pointer to the `struct lock_file` initialized with an 181 earlier call to `hold_lock_file_for_update` or 182 `hold_lock_file_for_append`, and close the file descriptor. 183 Return 0 upon success. On failure to `close(2)`, return a 184 negative value and roll back the lock file. Usually 185 `commit_lock_file`, `commit_lock_file_to`, or 186 `rollback_lock_file` should eventually be called if 187 `close_lock_file` succeeds. 188 189reopen_lock_file:: 190 191 Re-open a lockfile that has been closed (using 192 `close_lock_file`) but not yet committed or rolled back. This 193 can be used to implement a sequence of operations like the 194 following: 195 196 * Lock file. 197 198 * Write new contents to lockfile, then `close_lock_file` to 199 cause the contents to be written to disk. 200 201 * Pass the name of the lockfile to another program to allow it 202 (and nobody else) to inspect the contents you wrote, while 203 still holding the lock yourself. 204 205 * `reopen_lock_file` to reopen the lockfile. Make further 206 updates to the contents. 207 208 * `commit_lock_file` to make the final version permanent.