api-lockfile: revise and expand the documentation

Document a couple more functions and the flags argument as used by hold_lock_file_for_update() and hold_lock_file_for_append(). Reorganize the document to make it more accessible. Helped-by: Jonathan Nieder <jrnieder@gmail.com> Helped-by: Junio Hamano <gitster@pobox.com> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Oct 1, 2014 at 12:28 UTC a5e48669a2bb45e3a2a6daf30635270b90056085
1 file changed +167 -54
Documentation/technical/api-lockfile.txt
+167 -54
@@ -3,20 +3,125 @@ lockfile API
3
4 The lockfile API serves two purposes:
5
6 -* Mutual exclusion. When we write out a new index file, first
7 - we create a new file `$GIT_DIR/index.lock`, write the new
8 - contents into it, and rename it to the final destination
9 - `$GIT_DIR/index`. We try to create the `$GIT_DIR/index.lock`
10 - file with O_EXCL so that we can notice and fail when somebody
11 - else is already trying to update the index file.
12 -
13 -* Automatic cruft removal. After we create the "lock" file, we
14 - may decide to `die()`, and we would want to make sure that we
15 - remove the file that has not been committed to its final
16 - destination. This is done by remembering the lockfiles we
17 - created in a linked list and cleaning them up from an
18 - `atexit(3)` handler. Outstanding lockfiles are also removed
19 - when the program dies on a signal.
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 +
23 +Please note that lockfiles only block other writers. Readers do not
24 +block, but they are guaranteed to see either the old contents of the
25 +file or the new contents of the file (assuming that the filesystem
26 +implements `rename(2)` atomically).
27 +
28 +
29 +Calling sequence
30 +----------------
31 +
32 +The 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 +
49 +When 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`.
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 + `rollback_lock_file`, or `reopen_lock_file`.
60 +
61 +Even after the lockfile is committed or rolled back, the `lock_file`
62 +object must not be freed or altered by the caller. However, it may be
63 +reused; just pass it to another call of `hold_lock_file_for_update` or
64 +`hold_lock_file_for_append`.
65 +
66 +If the program exits before you have called one of `commit_lock_file`,
67 +`rollback_lock_file`, or `close_lock_file`, an `atexit(3)` handler
68 +will close and remove the lockfile, rolling back any uncommitted
69 +changes.
70 +
71 +If 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!
74 +Otherwise the `struct lock_file` structure would still think that the
75 +file descriptor needs to be closed, and a later call to
76 +`commit_lock_file` or `rollback_lock_file` or program exit would
77 +result in duplicate calls to `close(2)`. Worse yet, if you `close(2)`
78 +and then later open another file descriptor for a completely different
79 +purpose, then a call to `commit_lock_file` or `rollback_lock_file`
80 +might close that unrelated file descriptor.
81 +
82 +
83 +Error handling
84 +--------------
85 +
86 +The `hold_lock_file_*` functions return a file descriptor on success
87 +or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see below). On
88 +errors, `errno` describes the reason for failure. Errors can be
89 +reported by passing `errno` to one of the following helper functions:
90 +
91 +unable_to_lock_message::
92 +
93 + Append an appropriate error message to a `strbuf`.
94 +
95 +unable_to_lock_error::
96 +
97 + Emit an appropriate error message using `error()`.
98 +
99 +unable_to_lock_die::
100 +
101 + Emit an appropriate error message and `die()`.
102 +
103 +
104 +Flags
105 +-----
106 +
107 +The following flags can be passed to `hold_lock_file_for_update` or
108 +`hold_lock_file_for_append`:
109 +
110 +LOCK_NODEREF::
111 +
112 + Usually symbolic links in the destination path are resolved
113 + and the lockfile is created by adding ".lock" to the resolved
114 + path. If `LOCK_NODEREF` is set, then the lockfile is created
115 + by adding ".lock" to the path argument itself. This option is
116 + used, for example, when locking a symbolic reference, which
117 + for backwards-compatibility reasons can be a symbolic link
118 + containing the name of the referred-to-reference.
119 +
120 +LOCK_DIE_ON_ERROR::
121 +
122 + If a lock is already taken for the file, `die()` with an error
123 + message. If this option is not specified, trying to lock a
124 + file that is already locked returns -1 to the caller.
125
126
127 The functions
@@ -24,51 +129,59 @@ The functions
129
130 hold_lock_file_for_update::
131
27 - Take a pointer to `struct lock_file`, the filename of
28 - the final destination (e.g. `$GIT_DIR/index`) and a flag
29 - `die_on_error`. Attempt to create a lockfile for the
30 - destination and return the file descriptor for writing
31 - to the file. If `die_on_error` flag is true, it dies if
32 - a lock is already taken for the file; otherwise it
33 - returns a negative integer to the caller on failure.
132 + Take a pointer to `struct lock_file`, the path of the file to
133 + be locked (e.g. `$GIT_DIR/index`) and a flags argument (see
134 + above). Attempt to create a lockfile for the destination and
135 + return the file descriptor for writing to the file.
136 +
137 +hold_lock_file_for_append::
138 +
139 + Like `hold_lock_file_for_update`, but before returning copy
140 + the existing contents of the file (if any) to the lockfile and
141 + position its write pointer at the end of the file.
142
143 commit_lock_file::
144
37 - Take a pointer to the `struct lock_file` initialized
38 - with an earlier call to `hold_lock_file_for_update()`,
39 - close the file descriptor and rename the lockfile to its
40 - final destination. Returns 0 upon success, a negative
41 - value on failure to close(2) or rename(2).
145 + Take a pointer to the `struct lock_file` initialized with an
146 + earlier call to `hold_lock_file_for_update` or
147 + `hold_lock_file_for_append`, close the file descriptor and
148 + rename the lockfile to its final destination. Return 0 upon
149 + success or a negative value on failure to `close(2)` or
150 + `rename(2)`.
151
152 rollback_lock_file::
153
45 - Take a pointer to the `struct lock_file` initialized
46 - with an earlier call to `hold_lock_file_for_update()`,
47 - close the file descriptor and remove the lockfile.
154 + Take a pointer to the `struct lock_file` initialized with an
155 + earlier call to `hold_lock_file_for_update` or
156 + `hold_lock_file_for_append`, close the file descriptor and
157 + remove the lockfile.
158
159 close_lock_file::
50 - Take a pointer to the `struct lock_file` initialized
51 - with an earlier call to `hold_lock_file_for_update()`,
52 - and close the file descriptor. Returns 0 upon success,
53 - a negative value on failure to close(2).
54 -
55 -Because the structure is used in an `atexit(3)` handler, its
56 -storage has to stay throughout the life of the program. It
57 -cannot be an auto variable allocated on the stack.
58 -
59 -Call `commit_lock_file()` or `rollback_lock_file()` when you are
60 -done writing to the file descriptor. If you do not call either
61 -and simply `exit(3)` from the program, an `atexit(3)` handler
62 -will close and remove the lockfile.
63 -
64 -If you need to close the file descriptor you obtained from
65 -`hold_lock_file_for_update` function yourself, do so by calling
66 -`close_lock_file()`. You should never call `close(2)` yourself!
67 -Otherwise the `struct
68 -lock_file` structure still remembers that the file descriptor
69 -needs to be closed, and a later call to `commit_lock_file()` or
70 -`rollback_lock_file()` will result in duplicate calls to
71 -`close(2)`. Worse yet, if you `close(2)`, open another file
72 -descriptor for completely different purpose, and then call
73 -`commit_lock_file()` or `rollback_lock_file()`, they may close
74 -that unrelated file descriptor.
160 +
161 + Take a pointer to the `struct lock_file` initialized with an
162 + earlier call to `hold_lock_file_for_update` or
163 + `hold_lock_file_for_append`, and close the file descriptor.
164 + Return 0 upon success or a negative value on failure to
165 + close(2). Usually `commit_lock_file` or `rollback_lock_file`
166 + should be called after `close_lock_file`.
167 +
168 +reopen_lock_file::
169 +
170 + Re-open a lockfile that has been closed (using
171 + `close_lock_file`) but not yet committed or rolled back. This
172 + can be used to implement a sequence of operations like the
173 + following:
174 +
175 + * Lock file.
176 +
177 + * Write new contents to lockfile, then `close_lock_file` to
178 + cause the contents to be written to disk.
179 +
180 + * Pass the name of the lockfile to another program to allow it
181 + (and nobody else) to inspect the contents you wrote, while
182 + still holding the lock yourself.
183 +
184 + * `reopen_lock_file` to reopen the lockfile. Make further
185 + updates to the contents.
186 +
187 + * `commit_lock_file` to make the final version permanent.