[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: SVN repository possible race condition

From: John Szakmeister <john_at_szakmeister.net>
Date: Fri, 3 Oct 2008 06:03:32 -0400

On Tue, Sep 23, 2008 at 2:09 AM, Toby Collett
<tcollett+lists_at_plan9.net.nz> wrote:
[snip]
> stat("db/schemas/.svn/lock", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
>
> open("db/schemas/.svn/tmp", O_RDONLY|O_NONBLOCK|O_DIRECTORY|0x80000) = 3
> fstat(3, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
> fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
> brk(0x68f000) = 0x68f000
>
> getdents(3, /* 2 entries */, 16384) = 48
> getdents(3, /* 0 entries */, 16384) = 0
> brk(0x68b000) = 0x68b000
> close(3) = 0
> rmdir("db/schemas/.svn/tmp") = 0
>
> lstat("db/schemas/.svn/lock", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
> mkdir("db/schemas/.svn/tmp", 0777) = 0
> lstat("db/schemas/.svn/lock", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
>
>
> mkdir("db/schemas/.svn/tmp/text-base", 0777) = 0
>
> lstat("db/schemas/.svn/lock", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
> mkdir("db/schemas/.svn/tmp/prop-base", 0777) = 0
>
> lstat("db/schemas/.svn/lock", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
> mkdir("db/schemas/.svn/tmp/props", 0777) = 0
> unlink("db/schemas/.svn/lock") = 0
> lstat("db/.project", {st_mode=S_IFREG|0755, st_size=1960, ...}) = 0
>
> open("db/.svn/prop-base/.project.svn-base", O_RDONLY) = 3
> read(3, "K 14\nsvn:executable\nV 1\n*\nEND\n", 4096) = 30
> close(3) = 0
> open("db/.svn/prop-base/.project.svn-base", O_RDONLY) = 3
>
> read(3, "K 14\nsvn:executable\nV 1\n*\nEND\n", 4096) = 30
> close(3)
> .
> .
> .
> .
> .
> .
> .
> .
> .
> close(4) = 0
> lstat("db/config/.svn/lock", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
>
> open("db/config/.svn/tmp/entries", O_WRONLY|O_CREAT|O_EXCL, 0666) = 3
> write(3, "9\n\ndir\n3818\nhttps://svn/svn/kryt"..., 695) = 695
> close(3) = 0
> rename("db/config/.svn/tmp/entries", "db/config/.svn/entries") = 0
>
> lstat("db/config/.svn/entries", {st_mode=S_IFREG|0644, st_size=695, ...}) =
> 0
> chmod("db/config/.svn/entries", 0444) = 0
> open("db/config/.svn/KILLME", O_RDONLY) = -1 ENOENT (No such file or
>
> directory)
> lstat("db/config/.svn/log", 0x7fffca82ac70) = -1 ENOENT (No such file or
> directory)
> lstat("db/config/.svn", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
> lstat("db/config/.svn/lock", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
>
> open("db/config/.svn/tmp", O_RDONLY|O_NONBLOCK|O_DIRECTORY|0x80000) = 3
> fstat(3, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
> getdents(3, /* 5 entries */, 16384) = 144
> open("db/config/.svn/tmp/text-base",
>
> O_RDONLY|O_NONBLOCK|O_DIRECTORY|0x80000) = 4
> fstat(4, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
> getdents(4, /* 2 entries */, 16384) = 48
> getdents(4, /* 0 entries */, 16384) = 0
> close(4) = 0
>
> rmdir("db/config/.svn/tmp/text-base") = 0
> open("db/config/.svn/tmp/props", O_RDONLY|O_NONBLOCK|O_DIRECTORY|0x80000) =
> 4
> fstat(4, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
> getdents(4, /* 2 entries */, 16384) = 48
>
> getdents(4, /* 0 entries */, 16384) = 0
> close(4) = 0
> rmdir("db/config/.svn/tmp/props") = 0
> open("db/config/.svn/tmp/prop-base",
> O_RDONLY|O_NONBLOCK|O_DIRECTORY|0x80000) = 4
>
> fstat(4, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
> getdents(4, /* 2 entries */, 16384) = 48
> getdents(4, /* 0 entries */, 16384) = 0
> close(4) = 0
> rmdir("db/config/.svn/tmp/prop-base") = 0
>
> getdents(3, /* 0 entries */, 16384) = 0
> lseek(3, 0, SEEK_SET) = 0
> getdents(3, /* 5 entries */, 16384) = 144
> open("db/config/.svn/tmp/text-base",
> O_RDONLY|O_NONBLOCK|O_DIRECTORY|0x80000) = 4
>
> fstat(4, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
> getdents(4, 0x67f9b8, 16384) = -1 ENOTDIR (Not a directory)
> select(0, NULL, NULL, NULL, {1, 30417}) = 0 (Timeout)
> write(2, "svn: Can\'t read directory \'db/co"..., 74svn: Can't read
>
> directory 'db/config/.svn/tmp/text-base': Not a directory
> ) = 74
> close(4) = 0
> close(3) = 0
> exit_group(1) = ?
> Process 24312 detached

After staring at this for a while I think I know what the issue is...
although not technically Subversion's fault. Is your Samba share
hosted on Windows by chance? What I believe is happening is that
apr_dir_read() is returning the 'text-base' dir twice. Apparently
some implementations of readdir() are broken when you delete entries.
So on anything other than Windows, there is an attempt to rewind the
directory. This causes text-base to show up again, and it's a
directory when open() is called but has probably been removed by the
time getdents() is called. So we've managed to hit a race condition.
:-(

Unfortunately, I'm not sure what the best solution is here. We
already know that the entry we were trying to remove is a directory...
so maybe the best answer is to check for that and skip the entry if
the remove fails with ENOTDIR?

FWIW, not much of this has changed since 1.4... have you upgraded
whatever is hosting the share since then? Of course, if the workload
of the server has picked up, it could be that you were "winning" the
race and just not seeing the issue.

-John

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: users-help_at_subversion.tigris.org
Received on 2008-10-03 12:03:49 CEST

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.