2.3.9 mod time bug
Bron Gondwana
brong at fastmail.fm
Fri Aug 31 23:38:31 EDT 2007
On Fri, Aug 31, 2007 at 08:19:58PM -0400, John Capo wrote:
> For as long as I can remember I have sent the file modtime to the
> sync_server in the protocol stream. Keeping the modtimes on the
> master and the replica in sync becomes important when doing rsync
> snapshots to a backup machine from the replica. When switching to
> the replica and then doing backups from the new replica (old master),
> out of sync modtimes causes rather large data transfers to the
> backup machine. :-(
Ahh - this isn't an issue for us because we parse the index files
and only sync new files. Cyrus spool files never change - or if
they do it's a bug! We optimise that case away and will only
refetch if the UUID has changed (with md5uuid, this means only
if the message content has changed)
> So I though I would try the new internaldate scheme in 2.3.9 for
> setting modtimes instead of my scheme but it does not work right
> on FreeBSD 4.11 and probably not on other BSD systems. Dunno about
> Linux.
I'm not sure about to-a-second accuracy. A few seconds either side
didn't really worry me.
> The calls to utime() (obsolete on BSD) in cmd_upload() set the
> modtime OK but some data written with fwrite() is still buffered
> in the stdio buffers. The buffered data is not flushed to disk
> till an fclose() call which may be a few to many seconds later.
> The data written with fclose() sets the modtime overwriting the
> time set to the internaldate with utime().
Yeah, I have to admit - now that we parse the internaldate from
the Received headers anyway we don't care so much so I haven't
been maintaining and testing this patch.
I'd be happy to abstract out this section and put in a test in
configure.in for the BSD equivalent for utime if it's going to
be necessary in the near future. Depends how "obsolete" it is!
> Another thing, the fsync()/fclose() calls in this loop in
> sync_message_fsync() should be reversed, at least on on BSD systems.
>
> /* fsync() files in reverse order: ReiserFS FAQ indicates that this
> * gives best potential for optimisation */
> for (i = (l->file_count-1) ; i >= 0 ; i--) {
> fsync(fileno(l->file[i]));
> fclose(l->file[i]);
> l->file[i] = NULL;
> }
Presumably this would solve your issue completely, since there would
be nothing left to flush?
> fsync() is a system call on BSD systems. It will flush the system
> I/O buffers but the stdio buffers may still contain unwritten data.
> fsync() may be hooked into stdio on Linux but not on BSD.
I'm not sure to be honest - though I imagine this was originally
designed on Solaris anyway?
Bron.
More information about the Cyrus-devel
mailing list