read error produces null-byte-filled destination file

Todd Stansell tjs at tellme.com
Mon May 10 21:45:15 GMT 2004


I've run into a bug in the IO handling when reading a file.  Suppose I
have a file that lives on an NFS filesystem.  That filesystem is NOT
being exported with auth=0 permissions.  So, if I try to access a file
as root, it successfully opens the file, but subsequent reads fail with
EACCES.  This produces a destination file full of null bytes.  I
noticed this with 2.5.7, but checked 2.6.2 as well.  2.6.2 now produces
an error message, but still also produces the corrupted destination
file.  I can only guess that the same situation would occur with any
other sort of read error while transferring a file.

# sum /some/filename
64880 2 /some/filename
# ls -l /some/filename
-rw-------   1 user     group     540 Oct  9  2000 /some/filename
# ls -l /tmp/test/filename
/tmp/test/filename: No such file or directory
# rsync-2.6.2 -av /some/filename /tmp/test/
building file list ... done
filename
read errors mapping "/some/filename": (13) Permission denied

wrote 661 bytes  read 40 bytes  1402.00 bytes/sec
total size is 540  speedup is 0.77
rsync error: some files could not be transferred (code 23) at main.c(633)
# ls -l /tmp/test/filename 
-rw-------   1 user     group     540 Oct  9  2000 /tmp/test/filename
# sum /tmp/test/filename
0 2 /tmp/test/filename
# cat -etv /tmp/test/filename
^@^@^@^@^@^@^@(...continued throughout the file...)^@^@^@^@

Here is a snippet of truss output from the read failure:

    open64("/some/filename", O_RDONLY)              = 5
    fstat64(5, 0x08047938)                          = 0
    poll(0x0803F274, 1, 60000)                      = 1
    write(4, "\0\0\0\0", 4)                         = 4
    poll(0x0803F244, 1, 60000)                      = 1
    write(4, "\0\0\0\0", 4)                         = 4
    poll(0x0803F234, 1, 60000)                      = 1
    write(4, "\0\0\0\0", 4)                         = 4
    poll(0x0803F244, 1, 60000)                      = 1
    write(4, "\0\0\0\0", 4)                         = 4
    poll(0x0803F244, 1, 60000)                      = 1
    write(4, "\0\0\0\0", 4)                         = 4
    write(1, " f i l e n a m e\n", 9)               = 9
    poll(0x0803F134, 1, 60000)                      = 1
    write(4, "1C02\0\0", 4)                         = 4
    read(5, 0x080856C0, 540)                        Err#13 EACCES
    poll(0x0803F134, 1, 60000)                      = 1
    write(4, "\0\0\0\0\0\0\0\0\0\0\0\0".., 540)     = 540
    poll(0x0803F134, 1, 60000)                      = 1
    write(4, "\0\0\0\0", 4)                         = 4
    poll(0x0803F234, 1, 60000)                      = 1
    write(4, "C6 @C5 p i1DFC8E eAF 9 E".., 16)      = 16
    fstat64(2, 0x0803EE64)                          = 0
    write(2, " r e a d   e r r o r s  ".., 71)      = 71
    close(5)                                        = 0

Subsequent rsyncs will succeed without any errors as long as the -c
option isn't used.  You'd never know the file was corrupted, since the
size and timestamp are both correct on the destination file.

Todd


More information about the rsync mailing list