INN commit: trunk/storage/buffindexed (buffindexed.c)
INN Commit
Russ_Allbery at isc.org
Sat Nov 29 10:39:08 UTC 2008
Date: Saturday, November 29, 2008 @ 02:39:08
Author: iulius
Revision: 8194
Rollback for the case of error during group expiration.
This fix requires a long description. Expiration process for
buffindexed method is straightforward -- retrieve full chain of indexes,
sort, look through the chain and COPY data and indexes to keep in new
location (in other words create a new chain of indexes); update group
description with new chain location and free all blocks allocated for
old chain. This means it must be enough space to copy all group's
indexes and headers.
For the case of error, for example not enough room available, blocks
allocated for old chain are freed, group description remains unchanged
and blocks allocated for new chain are still allocated, but not linked
to any group. Such a failure have a very interesting outcomes. According
to group description, first block of a group exists and is valid, but in
reality it is unallocated and server free to write a header into it.
And when occasionally server writes a header into this location,
expiration process dumps a following error message:
Nov 6 04:29:48 andromeda expireover[23091]: buffindexed: ovgroupmmap ovbuff is null(ovindex is 12854, ovblock is 808793140
where the number of buffer is 12854, but it is not possible for a server
with buffers numbers 0, 1, 2 and 3.
This patch changes error processing as follows: free just allocated
chain, keep old chain and group description as it was before expiration.
Patch from Kirill Berezin.
Modified:
trunk/storage/buffindexed/buffindexed.c
---------------+
buffindexed.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
Modified: buffindexed.c
===================================================================
--- buffindexed.c 2008-11-29 10:29:29 UTC (rev 8193)
+++ buffindexed.c 2008-11-29 10:39:08 UTC (rev 8194)
@@ -2139,10 +2139,20 @@
#else
if (!ovaddrec(&newge, artnum, token, data, len, arrived, expires)) {
#endif /* OV_DEBUG */
- ovclosesearch(handle, true);
+ /* Old group cannot be freed. */
+ ovclosesearch(handle, false);
ge->expired = time(NULL);
GROUPlock(gloc, INN_LOCK_UNLOCK);
- warn("buffindexed: could not add new overview for '%s'", group);
+ warn("buffindexed: not enough room to expire overview for group '%s'",
+ group);
+ /* Clean just reserved overview entries. */
+ if (!ovgroupmmap(&newge, newge.low, newge.high, true)) {
+ warn("buffindexed: cannot prepare free operation");
+ return false;
+ }
+ freegroupblock();
+ ovgroupunmap();
+
return false;
}
}
More information about the inn-committers
mailing list