2.3.9 mod time bug

John Capo jc at irbs.com
Fri Aug 31 20:19:58 EDT 2007


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. :-(

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.

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().

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;
    }

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.

John Capo



More information about the Cyrus-devel mailing list