cache issue
John Keeping
john at keeping.me.uk
Tue Mar 3 10:31:24 CET 2015
On Sun, Mar 01, 2015 at 07:36:00PM +0000, John Keeping wrote:
> On Sun, Mar 01, 2015 at 06:43:17PM +0000, Bertrand Jacquin wrote:
> > On 28/02/2015 12:37, John Keeping wrote:
> > > On Sat, Feb 28, 2015 at 12:06:41PM +0000, Bertrand Jacquin wrote:
> > >> We are still experiencing the issue. Is there any fixes with newer
> > >> releases ?
> > >
> > > I have just tried to reproduce this with the latest version and have
> > > not
> > > been able to do so, but I'm not aware of any changes that should have
> > > an
> > > effect on this (there is one cache change, 6ceba45 Skip cache slot when
> > > time-to-live is zero, but that only applies if you set one of the *-ttl
> > > values to zero).
> > >
> > > The cache timeout logic relies on the mtime of the cache file, so this
> > > could be affected by your filesystem, but it sounds like the problem is
> > > that the .lock files are not being cleaned up.
> >
> > The filesystem here is a ext4 with no specific option except noatime
> > which quiet common.
> >
> > > When CGit finds a .lock
> > > file for a cache slot it is trying to use it will just serve the stale
> > > content, on the assumption that is has only just been replaced.
> >
> > So there is so assumption the .lock can be obsolete ?
> >
> > > I can't see many ways that you can end up with stale lock files; the
> > > only options are:
> > >
> > > 1) CGit crashes, in which case there should be some evidence in the
> > > system log.
> >
> > That might happend, the cgi can in this case be killed after 60 seconds.
>
> I wonder if we should be doing something like this (which is probably 3
> patches if cleaned up, but shows the idea):
Having thought about this a bit more, maybe this is the safer way to do
it, since this will detect stale .lock files no matter how they're
caused.
-- >8 --
diff --git a/cache.c b/cache.c
index 801e63f..dbfa6a9 100644
--- a/cache.c
+++ b/cache.c
@@ -161,10 +161,24 @@ static int close_lock(struct cache_slot *slot)
*/
static int lock_slot(struct cache_slot *slot)
{
- slot->lock_fd = open(slot->lock_name, O_RDWR | O_CREAT | O_EXCL,
+ struct flock lock = {
+ .l_type = F_WRLCK,
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = 0,
+ };
+
+ slot->lock_fd = open(slot->lock_name, O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR);
if (slot->lock_fd == -1)
return errno;
+ if (fcntl(slot->lock_fd, F_SETLK, &lock) < 0) {
+ int saved_errno = errno;
+ fprintf(stderr, "failed to lock slot!");
+ close(slot->lock_fd);
+ slot->lock_fd = -1;
+ return saved_errno;
+ }
if (xwrite(slot->lock_fd, slot->key, slot->keylen + 1) < 0)
return errno;
return 0;
More information about the CGit
mailing list