7 > import os |
7 > import os |
8 > import signal |
8 > import signal |
9 > from mercurial import extensions, util |
9 > from mercurial import extensions, util |
10 > |
10 > |
11 > def extsetup(ui): |
11 > def extsetup(ui): |
12 > def close(orig, *args, **kwargs): |
12 > def rename(orig, src, dest, *args, **kwargs): |
13 > path = util.normpath(args[0]._atomictempfile__name) |
13 > path = util.normpath(dest) |
14 > if path.endswith(b'/.hg/store/data/file.i'): |
14 > if path.endswith(b'data/file.i'): |
15 > os.kill(os.getpid(), signal.SIGKILL) |
15 > os.kill(os.getpid(), signal.SIGKILL) |
16 > return orig(*args, **kwargs) |
16 > return orig(src, dest, *args, **kwargs) |
17 > extensions.wrapfunction(util.atomictempfile, 'close', close) |
17 > extensions.wrapfunction(util, 'rename', rename) |
18 > EOF |
18 > EOF |
19 |
19 |
20 $ cat > $TESTTMP/intercept_after_rename.py << EOF |
20 $ cat > $TESTTMP/intercept_after_rename.py << EOF |
21 > import os |
21 > import os |
22 > import signal |
22 > import signal |
28 > r = orig(*args, **kwargs) |
28 > r = orig(*args, **kwargs) |
29 > if path.endswith(b'/.hg/store/data/file.i'): |
29 > if path.endswith(b'/.hg/store/data/file.i'): |
30 > os.kill(os.getpid(), signal.SIGKILL) |
30 > os.kill(os.getpid(), signal.SIGKILL) |
31 > return r |
31 > return r |
32 > extensions.wrapfunction(util.atomictempfile, 'close', close) |
32 > extensions.wrapfunction(util.atomictempfile, 'close', close) |
|
33 > def extsetup(ui): |
|
34 > def rename(orig, src, dest, *args, **kwargs): |
|
35 > path = util.normpath(dest) |
|
36 > r = orig(src, dest, *args, **kwargs) |
|
37 > if path.endswith(b'data/file.i'): |
|
38 > os.kill(os.getpid(), signal.SIGKILL) |
|
39 > return r |
|
40 > extensions.wrapfunction(util, 'rename', rename) |
33 > EOF |
41 > EOF |
34 |
42 |
35 $ cat > $TESTTMP/killme.py << EOF |
43 $ cat > $TESTTMP/killme.py << EOF |
36 > import os |
44 > import os |
37 > import signal |
45 > import signal |
125 Killed |
133 Killed |
126 [137] |
134 [137] |
127 #endif |
135 #endif |
128 |
136 |
129 |
137 |
130 The revlog have been split on disk |
138 The inline revlog still exist, but a split version exist next to it |
131 |
139 |
132 $ f -s .hg/store/data/file* |
140 $ f -s .hg/store/data/file* |
133 .hg/store/data/file.d: size=132139 |
141 .hg/store/data/file.d: size=132139 |
134 .hg/store/data/file.i: size=256 |
142 .hg/store/data/file.i: size=132395 |
135 |
143 .hg/store/data/file.i.s: size=256 |
136 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file | tail -1 |
144 |
137 data/file.i 128 |
|
138 |
145 |
139 The first file.i entry should match the "Reference size" above. |
146 The first file.i entry should match the "Reference size" above. |
140 The first file.d entry is the temporary record during the split, |
147 The first file.d entry is the temporary record during the split, |
141 |
148 |
142 The second entry after the split happened. The sum of the second file.d |
149 A "temporary file" entry exist for the split index. |
143 and the second file.i entry should match the first file.i entry. |
|
144 |
150 |
145 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file |
151 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file |
146 data/file.i 1174 |
152 data/file.i 1174 |
147 data/file.d 0 |
153 data/file.d 0 |
148 data/file.d 1046 |
154 $ cat .hg/store/journal.backupfiles | tr -s '\000' ' ' | tr -s '\00' ' '| grep data/file |
149 data/file.i 128 |
155 data/file.i data/journal.backup.file.i 0 |
|
156 data/file.i.s 0 |
|
157 |
|
158 recover is rolling the split back, the fncache is still valid |
|
159 |
150 $ hg recover |
160 $ hg recover |
151 rolling back interrupted transaction |
161 rolling back interrupted transaction |
152 (verify step skipped, run `hg verify` to check your repository content) |
162 (verify step skipped, run `hg verify` to check your repository content) |
153 $ f -s .hg/store/data/file* |
163 $ f -s .hg/store/data/file* |
154 .hg/store/data/file.d: size=1046 |
164 .hg/store/data/file.i: size=1174 |
155 .hg/store/data/file.i: size=128 |
|
156 $ hg tip |
165 $ hg tip |
157 changeset: 1:cfa8d6e60429 |
166 changeset: 1:cfa8d6e60429 |
158 tag: tip |
167 tag: tip |
159 user: test |
168 user: test |
160 date: Thu Jan 01 00:00:00 1970 +0000 |
169 date: Thu Jan 01 00:00:00 1970 +0000 |
161 summary: b |
170 summary: b |
162 |
171 |
163 $ hg verify -q |
172 $ hg verify -q |
164 warning: revlog 'data/file.d' not in fncache! |
|
165 1 warnings encountered! |
|
166 hint: run "hg debugrebuildfncache" to recover from corrupt fncache |
|
167 $ hg debugrebuildfncache --only-data |
173 $ hg debugrebuildfncache --only-data |
168 adding data/file.d |
174 fncache already up to date |
169 1 items added, 0 removed from fncache |
|
170 $ hg verify -q |
175 $ hg verify -q |
171 $ cd .. |
176 $ cd .. |
172 |
177 |
173 Test a hard crash right before the index is move into place |
178 Test a hard crash right before the index is move into place |
174 =========================================================== |
179 =========================================================== |
187 .hg/store/data/file.i: size=1174 |
192 .hg/store/data/file.i: size=1174 |
188 |
193 |
189 $ cat > .hg/hgrc <<EOF |
194 $ cat > .hg/hgrc <<EOF |
190 > [extensions] |
195 > [extensions] |
191 > intercept_rename = $TESTTMP/intercept_before_rename.py |
196 > intercept_rename = $TESTTMP/intercept_before_rename.py |
192 > [hooks] |
|
193 > pretxnchangegroup = python:$TESTTMP/killme.py:killme |
|
194 > EOF |
197 > EOF |
195 #if chg |
198 #if chg |
196 $ hg pull ../troffset-computation |
199 $ hg pull ../troffset-computation |
197 pulling from ../troffset-computation |
200 pulling from ../troffset-computation |
|
201 searching for changes |
|
202 adding changesets |
|
203 adding manifests |
|
204 adding file changes |
198 [255] |
205 [255] |
199 #else |
206 #else |
200 $ hg pull ../troffset-computation |
207 $ hg pull ../troffset-computation |
201 pulling from ../troffset-computation |
208 pulling from ../troffset-computation |
|
209 searching for changes |
|
210 adding changesets |
|
211 adding manifests |
|
212 adding file changes |
202 Killed |
213 Killed |
203 [137] |
214 [137] |
204 #endif |
215 #endif |
205 |
216 |
206 The data file is created, but the revlog is still inline |
217 The inline revlog still exist, but a split version exist next to it |
207 |
218 |
208 $ f -s .hg/store/data/file* |
219 $ f -s .hg/store/data/file* |
209 .hg/store/data/file.d: size=132139 |
220 .hg/store/data/file.d: size=132139 |
210 .hg/store/data/file.i: size=132395 |
221 .hg/store/data/file.i: size=132395 |
|
222 .hg/store/data/file.i.s: size=256 |
211 |
223 |
212 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file |
224 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file |
213 data/file.i 1174 |
225 data/file.i 1174 |
214 data/file.d 0 |
226 data/file.d 0 |
215 data/file.d 1046 |
227 |
|
228 recover is rolling the split back, the fncache is still valid |
216 |
229 |
217 $ hg recover |
230 $ hg recover |
218 rolling back interrupted transaction |
231 rolling back interrupted transaction |
219 (verify step skipped, run `hg verify` to check your repository content) |
232 (verify step skipped, run `hg verify` to check your repository content) |
220 $ f -s .hg/store/data/file* |
233 $ f -s .hg/store/data/file* |
221 .hg/store/data/file.d: size=1046 |
|
222 .hg/store/data/file.i: size=1174 |
234 .hg/store/data/file.i: size=1174 |
223 $ hg tip |
235 $ hg tip |
224 changeset: 1:cfa8d6e60429 |
236 changeset: 1:cfa8d6e60429 |
225 tag: tip |
237 tag: tip |
226 user: test |
238 user: test |
247 .hg/store/data/file.i: size=1174 |
257 .hg/store/data/file.i: size=1174 |
248 |
258 |
249 $ cat > .hg/hgrc <<EOF |
259 $ cat > .hg/hgrc <<EOF |
250 > [extensions] |
260 > [extensions] |
251 > intercept_rename = $TESTTMP/intercept_after_rename.py |
261 > intercept_rename = $TESTTMP/intercept_after_rename.py |
252 > [hooks] |
|
253 > pretxnchangegroup = python:$TESTTMP/killme.py:killme |
|
254 > EOF |
262 > EOF |
255 #if chg |
263 #if chg |
256 $ hg pull ../troffset-computation |
264 $ hg pull ../troffset-computation |
257 pulling from ../troffset-computation |
265 pulling from ../troffset-computation |
|
266 searching for changes |
|
267 adding changesets |
|
268 adding manifests |
|
269 adding file changes |
258 [255] |
270 [255] |
259 #else |
271 #else |
260 $ hg pull ../troffset-computation |
272 $ hg pull ../troffset-computation |
261 pulling from ../troffset-computation |
273 pulling from ../troffset-computation |
|
274 searching for changes |
|
275 adding changesets |
|
276 adding manifests |
|
277 adding file changes |
262 Killed |
278 Killed |
263 [137] |
279 [137] |
264 #endif |
280 #endif |
265 |
281 |
266 the revlog has been split on disk |
282 The inline revlog was over written on disk |
267 |
283 |
268 $ f -s .hg/store/data/file* |
284 $ f -s .hg/store/data/file* |
269 .hg/store/data/file.d: size=132139 |
285 .hg/store/data/file.d: size=132139 |
270 .hg/store/data/file.i: size=256 |
286 .hg/store/data/file.i: size=256 |
271 |
287 |
272 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file |
288 $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file |
273 data/file.i 1174 |
289 data/file.i 1174 |
274 data/file.d 0 |
290 data/file.d 0 |
275 data/file.d 1046 |
291 |
|
292 recover is rolling the split back, the fncache is still valid |
276 |
293 |
277 $ hg recover |
294 $ hg recover |
278 rolling back interrupted transaction |
295 rolling back interrupted transaction |
279 abort: attempted to truncate data/file.i to 1174 bytes, but it was already 256 bytes |
296 (verify step skipped, run `hg verify` to check your repository content) |
280 |
297 $ f -s .hg/store/data/file* |
281 [255] |
298 .hg/store/data/file.i: size=1174 |
282 $ f -s .hg/store/data/file* |
|
283 .hg/store/data/file.d: size=1046 |
|
284 .hg/store/data/file.i: size=256 |
|
285 $ hg tip |
299 $ hg tip |
286 changeset: 1:cfa8d6e60429 |
300 changeset: 1:cfa8d6e60429 |
287 tag: tip |
301 tag: tip |
288 user: test |
302 user: test |
289 date: Thu Jan 01 00:00:00 1970 +0000 |
303 date: Thu Jan 01 00:00:00 1970 +0000 |
290 summary: b |
304 summary: b |
291 |
305 |
292 $ hg verify -q |
306 $ hg verify -q |
293 abandoned transaction found - run hg recover |
|
294 warning: revlog 'data/file.d' not in fncache! |
|
295 file@0: data length off by -131093 bytes |
|
296 file@2: unpacking fa1120531cc1: partial read of revlog data/file.d; expected 21 bytes from offset 1046, got 0 |
|
297 file@3: unpacking a631378adaa3: partial read of revlog data/file.d; expected 131072 bytes from offset 1067, got -21 |
|
298 file@?: rev 2 points to nonexistent changeset 2 |
|
299 (expected ) |
|
300 file@?: fa1120531cc1 not in manifests |
|
301 file@?: rev 3 points to nonexistent changeset 3 |
|
302 (expected ) |
|
303 file@?: a631378adaa3 not in manifests |
|
304 not checking dirstate because of previous errors |
|
305 3 warnings encountered! |
|
306 hint: run "hg debugrebuildfncache" to recover from corrupt fncache |
|
307 7 integrity errors encountered! |
|
308 (first damaged changeset appears to be 0) |
|
309 [1] |
|
310 $ cd .. |
307 $ cd .. |
311 |
308 |
312 Have the transaction rollback itself without any hard crash |
309 Have the transaction rollback itself without any hard crash |
313 =========================================================== |
310 =========================================================== |
314 |
311 |
330 transaction abort! |
327 transaction abort! |
331 rollback completed |
328 rollback completed |
332 abort: pretxnchangegroup hook exited with status 1 |
329 abort: pretxnchangegroup hook exited with status 1 |
333 [40] |
330 [40] |
334 |
331 |
335 File are still split on disk, with the expected size. |
332 The split was rollback |
336 |
333 |
337 $ f -s .hg/store/data/file* |
334 $ f -s .hg/store/data/file* |
338 .hg/store/data/file.d: size=1046 |
335 .hg/store/data/file.d: size=0 |
339 .hg/store/data/file.i: size=128 |
336 .hg/store/data/file.i: size=1174 |
|
337 |
340 |
338 |
341 $ hg tip |
339 $ hg tip |
342 changeset: 1:cfa8d6e60429 |
340 changeset: 1:cfa8d6e60429 |
343 tag: tip |
341 tag: tip |
344 user: test |
342 user: test |
345 date: Thu Jan 01 00:00:00 1970 +0000 |
343 date: Thu Jan 01 00:00:00 1970 +0000 |
346 summary: b |
344 summary: b |
347 |
345 |
348 $ hg verify -q |
346 $ hg verify -q |
349 warning: revlog 'data/file.d' not in fncache! |
|
350 1 warnings encountered! |
|
351 hint: run "hg debugrebuildfncache" to recover from corrupt fncache |
|
352 $ cd .. |
347 $ cd .. |
353 |
348 |
354 Read race |
349 Read race |
355 ========= |
350 ========= |
356 |
351 |