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.