You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Steinar Bang <sb...@dod.no> on 2011/05/14 10:58:12 UTC

fsverify.py unable to fix invalid svndiff header

Platform:
  debian 6.0.1 "squeeze",
  subversion 1.6.16dfsg-1+b1,
  fsfsverify.py from http://svn.apache.org/repos/asf/subversion/trunk/contrib/server-side
  python 2.6.6-3+squeeze6

(information about the repository at the end of this mesage)

Yesterday I discovered that my subversion repository is broken.  Trying
to do "svnadmin dump" breaks at revision 683:
 sb@somehost:/tmp/svnrepo$ svnadmin dump /tmp/svnrepo/svn/ >/dev/null
 * Dumped revision 0.
 * Dumped revision 1.
 ...
 * Dumped revision 681.
 * Dumped revision 682.
 svnadmin: Decompression of svndiff data failed


I found some threads on this list of people with the same error message
suggesting to use fsfsverify.py.  I assumed that the trunk version from
the repository would be the newest and most stable so that's the version
I've tried.

I've done all of my experiments with fsfsverify.py, and one attempt at
using fsfsfixer, on a copy of the repository, created with the command:
 (cd /tmp/svnrepo; rm -rf svn; cp -a /usr/local/svn/ .)


The first run of fsfverify.py /tmp/svnrepo/svn/db/revs/0/683 reports the
following: 
 ...
 NodeRev Id: 4-683.0.r683/12232
  type: file
  text: DELTA 683 1910 890 1548 30aadd70339eb7b41ab6eb20a6220202
  prop: PLAIN 683 12138 81 0 685faf6a4230ea531a31a12e4b3cb565
  cpath: /trunk/someprog/metamodeller/Makefile.msvc
  copyroot: 0 /
   <Svndiff so: 1916 ver: 1>

 Error InvalidCompressedStream: Invalid compressed data stream at offset 2247 (Error -3 while decompressing: incorrect data check, <Window wo:1920 so:0 sl:0 tl:1548 cil: 317 cdl: 561 il:315 dl:729 whl:8 wl:886>)

 Try running with -f to fix the revision


When I run fsfsverify.py -f /tmp/svnrepo/svn/db/revs/0/683 I see:
 ...
 NodeRev Id: 4-683.0.r683/12232
  type: file
  text: DELTA 683 1910 890 1548 30aadd70339eb7b41ab6eb20a6220202
  prop: PLAIN 683 12138 81 0 685faf6a4230ea531a31a12e4b3cb565
  cpath: /trunk/someprog/metamodeller/Makefile.msvc
  copyroot: 0 /
   <Svndiff so: 1916 ver: 1>
 Copy 893 bytes from offset 1920
 Write 893 bytes at offset 1916
 Fixed? :-)  Re-run fsfsverify without the -f option


Which looks good.  However, fsfverify.py /tmp/svnrepo/svn/db/revs/0/683
reports: 
 ...
 NodeRev Id: 4-683.0.r683/12232
  type: file
  text: DELTA 683 1910 890 1548 30aadd70339eb7b41ab6eb20a6220202
  prop: PLAIN 683 12138 81 0 685faf6a4230ea531a31a12e4b3cb565
  cpath: /trunk/someprog/metamodeller/Makefile.msvc
  copyroot: 0 /
 Traceback (most recent call last):
   File "/tmp/scripts/fsfsverify.py", line 1190, in <module>
     options.dumpWindows)
   File "/tmp/scripts/fsfsverify.py", line 581, in verify
     svndiff = Svndiff(f, self.length)
   File "/tmp/scripts/fsfsverify.py", line 472, in __init__
     (self.startingOffset)
 __main__.InvalidSvndiffHeader: Invalid svndiff header at offset 1916


This is also the same error message I get on all subsequent runs of
fsfverify -f.  I have tried 15 runs (all with the same output), since
the author of fsfsverify.py, said in an article on this list, that he
once had to run it 14 times.

All assistance on this issue will be welcome.

Thanks!


- Steinar


Some information on the repository:
  - The size of the repository is 22MB
  - The repository has 1794 revisions
  - The repository was converted from CVS to a BDB svn repository, with
    cvs2svn in May 2007
  - In february I discovered that the repository was BDB (I had assumed
    it was FSFS) because of a BDB upgrade problem
	nntp://news.gmane.org/gmane.comp.version-control.subversion.user/86556
	http://thread.gmane.org/gmane.comp.version-control.subversion.user/86556
  - According to the articles in the above thread, I was able to dump the
    repository, and create a new FSFS repository in February 2009
  - I have used svnmerge to track merges between different branches
  - The server installation of svn has been whatever has been on debian
    stable for the repository's entire lifetime
  - The clients have been a multitude of different svn clients, with
    different versions on different platforms
  - I have also used many different versions of svnmerge, with many
    different versions of python
  - svnmerge has not been used on the parts of the repository that has
    problems 
  - Revision 683 is from December 2005, ie. well before the transition
    from CVS to subversion (has been through the transition from CVS to
    svn, and the 2009 transition from BDB to FSFS)
  - The svn checkouts outside of the problem area seems to work just
    fine
  - The area that has the problem isn't important to me (I can't even
    remember what it was about), but history both before and after,
    outside of the problem area, is (it's the history of my home
    directory config files, ie. .bashrc, .emacs and the like)


Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Stefan Sperling wrote on Wed, May 18, 2011 at 12:29:41 +0200:
> On Wed, May 18, 2011 at 12:18:54PM +0200, Daniel Shahaf wrote:
> > > There doesn't seem to be a duplicated block. The revision file itself seems
> > > to be fine, expect that one of the lengths of the bad rev doesn't seem to
> > 
> > Huh?  Are you referring to the two 'length' attributes in the text: and
> > data: attributes of a node-revision?  In what way is it wrong?
> 
> I don't remember exactly.
> I'll need a bit of time to dig into the file again before I can give a
> precise answer.

Okay.

Julian and I's discussion today raised improper memory accesses as one
potential cause --- and it could easily account for bogus rep-size (and
rep-expanded-size) issues as well.

[There was also a suggestion to get whoever can reproduce corruptions to
run mod_dav_svn under valgrind :-).]


Re: fsverify.py unable to fix invalid svndiff header

Posted by Stefan Sperling <st...@elego.de>.
On Wed, May 18, 2011 at 12:18:54PM +0200, Daniel Shahaf wrote:
> > There doesn't seem to be a duplicated block. The revision file itself seems
> > to be fine, expect that one of the lengths of the bad rev doesn't seem to
> 
> Huh?  Are you referring to the two 'length' attributes in the text: and
> data: attributes of a node-revision?  In what way is it wrong?

I don't remember exactly.
I'll need a bit of time to dig into the file again before I can give a
precise answer.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Stefan Sperling <st...@elego.de>.
On Wed, May 18, 2011 at 12:18:54PM +0200, Daniel Shahaf wrote:
> > There doesn't seem to be a duplicated block. The revision file itself seems
> > to be fine, expect that one of the lengths of the bad rev doesn't seem to
> 
> Huh?  Are you referring to the two 'length' attributes in the text: and
> data: attributes of a node-revision?  In what way is it wrong?

I don't remember exactly.
I'll need a bit of time to dig into the file again before I can give a
precise answer.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Stefan Sperling wrote on Wed, May 18, 2011 at 12:12:48 +0200:
> On Wed, May 18, 2011 at 10:53:13AM +0200, Daniel Shahaf wrote:
> > What came out of this thread?  Is this one of the known corruption kinds?
> 
> It doesn't seem to be known.
> It could be a flipped bits on the hard drive for all we know.
> 
> > Is this is a case of a data block being written partially in one place
> > and fully in another, or a case of a corrupt or truncated data block?
> 
> Steinar shared the bad revision file privately.
> Philip Martin and myself spent a few hours at the Apache Retreat looking
> at the file but we got nowhere.
> 
> There doesn't seem to be a duplicated block. The revision file itself seems
> to be fine, expect that one of the lengths of the bad rev doesn't seem to

Huh?  Are you referring to the two 'length' attributes in the text: and
data: attributes of a node-revision?  In what way is it wrong?

> make sense. The bad representation we extracted from the file fails to
> decompress with zlib (which is what fsfsverify reported).
> 
> We could get the revision to verify fine by referring the node revision
> to a different representation but that is cheating and might break
> subseuent revs.
> 
> Steinar, I'm sorry we can't help quickly here. At the moment I have no time
> to look at this further. I hope you have a good backup you can restore from.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Steinar Bang wrote on Sun, May 22, 2011 at 00:41:14 +0200:
> >>>>> Steinar Bang <sb...@dod.no>:
> 
> >>>>> Steinar Bang <sb...@dod.no>:
> >> I tried adding this to /svn/conf/authz:
> 
> >> [/trunk/someprog]
> >> * =
> 
> >> (everything else in the file are comments)
> [snip!]
> > So I uncommented this line in the sample svnserve.conf:
> > # authz-db = authz
> 
> > And then svnsync pulled the entire repo.  Or at least: it didn't stop at
> > revision 683.
> 
> > But the resulting repo doesn't seem to be functional:
> >  sb@edwards:~$ svn ls file:///tmp/newrepo/svn/
> >  sb@edwards:~$ svn ls file:///tmp/newrepo/svn/trunk
> >  svn: URL 'file:///tmp/newrepo/svn/trunk' non-existent in that revision
> 
> More fine print I didn't read, in:
>  http://svnbook.red-bean.com/nightly/en/svn.serverconfig.pathbasedauthz.html
> 
>   "By default, nobody has any access to the repository at all. That
>    means that if you're starting with an empty file, you'll probably
>    want to give at least read permission to all users at the root of the
>    repository."
> 
> So now the /svn/conf/authz file contains:
> [/]
> * = r
> 
> [/trunk/someprog]
> * =
> 
> And then I'm able to see contents in the cloned repository:
>  sb@edwards:~$ svn ls file:///tmp/newrepo/svn/
>  branches/
>  tags/
>  trunk/
> 
> Thanks, Daniel!
> 

Welcome. :-)

Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:

>>>>> Steinar Bang <sb...@dod.no>:
>> I tried adding this to /svn/conf/authz:

>> [/trunk/someprog]
>> * =

>> (everything else in the file are comments)
[snip!]
> So I uncommented this line in the sample svnserve.conf:
> # authz-db = authz

> And then svnsync pulled the entire repo.  Or at least: it didn't stop at
> revision 683.

> But the resulting repo doesn't seem to be functional:
>  sb@edwards:~$ svn ls file:///tmp/newrepo/svn/
>  sb@edwards:~$ svn ls file:///tmp/newrepo/svn/trunk
>  svn: URL 'file:///tmp/newrepo/svn/trunk' non-existent in that revision

More fine print I didn't read, in:
 http://svnbook.red-bean.com/nightly/en/svn.serverconfig.pathbasedauthz.html

  "By default, nobody has any access to the repository at all. That
   means that if you're starting with an empty file, you'll probably
   want to give at least read permission to all users at the root of the
   repository."

So now the /svn/conf/authz file contains:
[/]
* = r

[/trunk/someprog]
* =

And then I'm able to see contents in the cloned repository:
 sb@edwards:~$ svn ls file:///tmp/newrepo/svn/
 branches/
 tags/
 trunk/

Thanks, Daniel!


Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:

> I tried adding this to /svn/conf/authz:

> [/trunk/someprog]
> * =

> (everything else in the file are comments)

> But both tools still break at revision 683, which is in the path
> /trunk/someprog/metamodeller.
[snip!]
> I was using the svn+ssh method to access the repo.  Do I need http
> access to get the effect you were suggesting?

No I don't.  svn+ssh works fine for this.

But I forgot the little part at the start of this page:
 http://svnbook.red-bean.com/nightly/en/svn.serverconfig.pathbasedauthz.html

  "If you're using svnserve, you need to make the authz-db variable
   (within svnserve.conf) point to your access rules file."

So I uncommented this line in the sample svnserve.conf:
# authz-db = authz

And then svnsync pulled the entire repo.  Or at least: it didn't stop at
revision 683.

But the resulting repo doesn't seem to be functional:
 sb@edwards:~$ svn ls file:///tmp/newrepo/svn/
 sb@edwards:~$ svn ls file:///tmp/newrepo/svn/trunk
 svn: URL 'file:///tmp/newrepo/svn/trunk' non-existent in that revision


Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Daniel Shahaf <d....@daniel.shahaf.name>:
> Steinar Bang wrote on Sat, May 21, 2011 at 18:26:30 +0200:

[snip! svnsync and svnrdump]
>> .., it would have been nice if it was possible to tell these tools to
>> make a clone of a particular part of the repository into a new
>> repository (or a dumpfile for that matter).

> You should be able to use either of them if you install authz on your
> repository such that *any* paths touched in r683 are unreadable by the
> user svnsync/svnrdump connect as.

I tried adding this to /svn/conf/authz:

[/trunk/someprog]
* =

(everything else in the file are comments)

But both tools still break at revision 683, which is in the path
/trunk/someprog/metamodeller.

svnsync breaks with:
 ...
 Committed revision 681.
 Copied properties for revision 681.
 Transmitting file data .
 Committed revision 682.
 Copied properties for revision 682.
 Transmitting file data ....svnsync: Error while replaying commit

svnrdump breaks with:
 ...
 * Dumped revision 680.
 * Dumped revision 681.
 * Dumped revision 682.
 svnrdump: E210008: Error while replaying commit

I was using the svn+ssh method to access the repo.  Do I need http
access to get the effect you were suggesting?

The box at the bottom of this web page would seem to indicate that I
need the http method:
 http://svnbook.red-bean.com/nightly/en/svn.serverconfig.pathbasedauthz.html

>From that box:
 "As the server generates the large response, there's no way it can
  resend an authentication challenge when it reaches the special
  subdirectory; thus the subdirectory is skipped altogether"


Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
svnsync,svnrdump use the svn_ra_* API, not the svn_client_* API.

You should be able to use either of them if you install authz on your
repository such that *any* paths touched in r683 are unreadable by the
user svnsync/svnrdump connect as.

Steinar Bang wrote on Sat, May 21, 2011 at 18:26:30 +0200:
> >>>>> Steinar Bang <sb...@dod.no>:
> 
> > I've been looking to see if there are any tools that can slurp out the
> > history of a repository, using the svn client API.  But all repository
> > conversion seems to be based on "svnadmin dump".  And "svnadmin dump"
> > croaks on all revisions later than 682...:-/
> 
> svnsync and svnrdump, sounds like if they implement part of this: they
> use the client API to pull down revisions for dump or export
>  http://svnbook.red-bean.com/nightly/en/svn.reposadmin.maint.html#svn.reposadmin.maint.tk.svnsync
>  http://thread.gmane.org/gmane.comp.version-control.subversion.user/99717
>  nntp://news.gmane.org/gmane.comp.version-control.subversion.user/99717
> 
> But they both stop on revision 683, and they refuse to start on any
> revision succeeding it. :-/
> 
> Since it is possible to check out the parts/paths in the repository that
> are interesting to me (my home directory and its branches), it would
> have been nice if it was possible to tell these tools to make a clone of
> a particular part of the repository into a new repository (or a dumpfile
> for that matter).
> 
> I don't care if revision numbers are preserved or not, only that the
> history is preserved (and preferrably with the branching information
> preserved).
> 
> Failing that, is it possible to make all of the dump/export programs
> work on revisions following 683?
> 
> I saw something in one of the google hits about "truncating the
> revision", and I tried to do so in one experiment.  But as far as I can
> recall dumping later versions than 683 still failed.
> 
> (I don't need that part of the repository tree that is in 683 and
> surrounding revisions, so any fix that loses it and lets me recover what
> is important to me, is ok by me)
> 
> Thanks!
> 

Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:

> I've been looking to see if there are any tools that can slurp out the
> history of a repository, using the svn client API.  But all repository
> conversion seems to be based on "svnadmin dump".  And "svnadmin dump"
> croaks on all revisions later than 682...:-/

svnsync and svnrdump, sounds like if they implement part of this: they
use the client API to pull down revisions for dump or export
 http://svnbook.red-bean.com/nightly/en/svn.reposadmin.maint.html#svn.reposadmin.maint.tk.svnsync
 http://thread.gmane.org/gmane.comp.version-control.subversion.user/99717
 nntp://news.gmane.org/gmane.comp.version-control.subversion.user/99717

But they both stop on revision 683, and they refuse to start on any
revision succeeding it. :-/

Since it is possible to check out the parts/paths in the repository that
are interesting to me (my home directory and its branches), it would
have been nice if it was possible to tell these tools to make a clone of
a particular part of the repository into a new repository (or a dumpfile
for that matter).

I don't care if revision numbers are preserved or not, only that the
history is preserved (and preferrably with the branching information
preserved).

Failing that, is it possible to make all of the dump/export programs
work on revisions following 683?

I saw something in one of the google hits about "truncating the
revision", and I tried to do so in one experiment.  But as far as I can
recall dumping later versions than 683 still failed.

(I don't need that part of the repository tree that is in 683 and
surrounding revisions, so any fix that loses it and lets me recover what
is important to me, is ok by me)

Thanks!


Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Stefan Sperling <st...@elego.de>:

> Steinar, I'm sorry we can't help quickly here. At the moment I have no time
> to look at this further. I hope you have a good backup you can restore from.

No luck there I'm afraid.

I have backups, but either they are too old to be of interest, or they
are corrupted as well.  The corruption isn't new.

The repository was created by converting an existing CVS repository in
May 2007, the repository was converted from BDB to FSFS in February 2009
(using svnadmin dump and load), and the corrupted revision is from
December 2005.

See repository history and details the end of the original article:
 http://thread.gmane.org/gmane.comp.version-control.subversion.user/104232
 nntp://news.gmane.org/gmane.comp.version-control.subversion.user/104232

Anyway, from the history of the repository, I'm guessing the svnadmin
load of February 2009 is the most likely culprit...?  I don't know if
that helps anything.

I've been looking to see if there are any tools that can slurp out the
history of a repository, using the svn client API.  But all repository
conversion seems to be based on "svnadmin dump".  And "svnadmin dump"
croaks on all revisions later than 682...:-/


Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Stefan Sperling wrote on Wed, May 18, 2011 at 12:12:48 +0200:
> On Wed, May 18, 2011 at 10:53:13AM +0200, Daniel Shahaf wrote:
> > What came out of this thread?  Is this one of the known corruption kinds?
> 
> It doesn't seem to be known.
> It could be a flipped bits on the hard drive for all we know.
> 
> > Is this is a case of a data block being written partially in one place
> > and fully in another, or a case of a corrupt or truncated data block?
> 
> Steinar shared the bad revision file privately.
> Philip Martin and myself spent a few hours at the Apache Retreat looking
> at the file but we got nowhere.
> 
> There doesn't seem to be a duplicated block. The revision file itself seems
> to be fine, expect that one of the lengths of the bad rev doesn't seem to

Huh?  Are you referring to the two 'length' attributes in the text: and
data: attributes of a node-revision?  In what way is it wrong?

> make sense. The bad representation we extracted from the file fails to
> decompress with zlib (which is what fsfsverify reported).
> 
> We could get the revision to verify fine by referring the node revision
> to a different representation but that is cheating and might break
> subseuent revs.
> 
> Steinar, I'm sorry we can't help quickly here. At the moment I have no time
> to look at this further. I hope you have a good backup you can restore from.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Stefan Sperling <st...@elego.de>.
On Wed, May 18, 2011 at 10:53:13AM +0200, Daniel Shahaf wrote:
> What came out of this thread?  Is this one of the known corruption kinds?

It doesn't seem to be known.
It could be a flipped bits on the hard drive for all we know.

> Is this is a case of a data block being written partially in one place
> and fully in another, or a case of a corrupt or truncated data block?

Steinar shared the bad revision file privately.
Philip Martin and myself spent a few hours at the Apache Retreat looking
at the file but we got nowhere.

There doesn't seem to be a duplicated block. The revision file itself seems
to be fine, expect that one of the lengths of the bad rev doesn't seem to
make sense. The bad representation we extracted from the file fails to
decompress with zlib (which is what fsfsverify reported).

We could get the revision to verify fine by referring the node revision
to a different representation but that is cheating and might break
subseuent revs.

Steinar, I'm sorry we can't help quickly here. At the moment I have no time
to look at this further. I hope you have a good backup you can restore from.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
[ CC += julianf ]

What came out of this thread?  Is this one of the known corruption kinds?

Is this is a case of a data block being written partially in one place
and fully in another, or a case of a corrupt or truncated data block?

-- 
Daniel
(at hackathon room)

Steinar Bang wrote on Sat, May 14, 2011 at 19:54:12 +0200:
> >>>>> Stefan Sperling <st...@elego.de>:
> 
> > The script probably took a wrong guess.
> 
> > Hopefully this is the known corruption problem with a duplicate block of
> > data in the revision file.
> 
> > Can you check if the original revision file (i.e. not modified by
> > fsfsverify.py) somewhere contains a data block which contains data
> > that matches the data around byte offset 1916?
> 
> "offset 1916", is that "byte number 1916 in the 683 ref file"?
> Is that 1916 decimal, or hexadecimal?   I'm assuming decimal for now. 
> 
> > Usually the spot where the corruption appears (offset 1916 in your case)
> > contains an incomplete representation, but the representation data in the
> > duplicated block is good.
> 
> > One of way of locating the duplicate block is to open the file in a
> > hex editor and search the entire file for hex strings that occur
> > around or after 1916.
> 
> Ok, opening the file in emacs hexl mode:
>  `M-x hexl-find-file /tmp/svnrepo/svn/db/revs/0/683 RET'
> 
> > Try to locate boundaries of representations, which look as follows:
> 
> > https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_fs_fs/structure
> >   A representation begins with a line containing either "PLAIN\n" or
> >   "DELTA\n" or "DELTA <rev> <offset> <length>\n", where <rev>, <offset>,
> >   and <length> give the location of the delta base of the representation
> >   and the amount of data it contains (not counting the header or
> >   trailer).  If no base location is given for a delta, the base is the
> >   empty stream.  After the initial line comes raw svndiff data, followed
> >   by a cosmetic trailer "ENDREP\n".
> 
> `M-j 1916 RET', takes me here:
> 00000770: 4e44 5245 500a 4445 4c54 410a 5356 4e01  NDREP.DELTA.SVN.
> 00000780: 0000 8c0c 823d 8431 823b 8140 4c00 8844  .....=.1.;.@L..D
> 00000790: 4ca8 404e 0048 8100 bf45 820d 9945 820d  L.@N.H...E...E..
> ...
> 
> The cursor is positioned on the "5" starting "5356" in the first line,
> and on the "S" of "SVN". 
> 
> Does that make sense?
> 
> So I should search for "ENDREP.DELTA.SVN"?  The 683 revfile contains 15
> istances of that string, but I have no idea of which ones are relevant
> or not.
> 
> > So if you find a duplicated block of data you should be able to fix this
> > problem by copying representation data from the duplicate block to the
> > corrupted location.
> 
> So what I'm looking for isn't exactly "ENDREP.DELTA.SVN", but what
> follows this text...?
> 
> I tried searching for "x^.Rmo.@", but the one at the cursor is the only
> occurrence in the file.  At least the only aligned so that search will
> find it.  Doesn't look like hexl-mode has the possibility to search for
> a byte sequence.  Maybe I should get myself a proper hex editor?
> 
> > DO NOT change any byte offsets in the file while doing this. If you
> > cannot squeeze the data in because it would overlap with subsequent
> > data you're out of luck but I've never seen this happen.  Usually
> > there is enough room to fit the data, but you might have to add
> > padding. Any dummy byte will do, I usually use 0x42.
> 
> The meaning of life, the universe and everything?  I thought that was 42
> decimal...? :-)
> 
> > Another possibility is that offset 2247 is wrong. In this case the
> > expected svndiff data is probably located elsewhere and the offset
> > in the representation header should be adjusted.
> 
> Right... that's the first error that fsfsverify.py tries to fix?
> 
> `M-j 2247 RET' takes the cursor over the "7" in "5878" in the first
> line: 
> 000008c0: 8550 8b57 8585 5978 5e1d 526d 6fda 400c  .P.W..Yx^.Rmo.@.
> 000008d0: fe1c ff0a 17f8 00d5 12fa a27d 4145 2a90  ...........}AE*.
> 000008e0: 8466 0da4 2361 6353 2414 ee0e b871 89a3  .f..#acS$....q..
> 
> That wasn't as easily recognizable, as the 1916 one, though.  Not as
> recognizable as a boundary at least.
> 
> What are the things I should look for a duplicate of?  The bytes
> following the troublesome position?  And how many?
> 
> > This is of course not an easy task and it is unfortunate that people
> > keep running into this problem. The source of the problem is not yet
> > known :(  If you have any further questions just ask. If you cannot
> > get it fixed at all but can share the revision file privately I will
> > have a go at it.
> 
> I think I need help with this one.  I'll send you the revision file
> privately.
> 
> Thanks!
> 
> 
> - Steinar
> 

Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <da...@apache.org>.

On Sat, 14 May 2011 22:46 +0300, "Daniel Shahaf" <da...@apache.org> wrote:
> You probably don't need to know anything at all about svndiff --- if previous instances of the bug are representative, then you're free to treat consider the svndiff stream an opaque binary data.
> 
> That is, previously what happened is that fsfs wrote
> 
> A_1 A_2 B_1 B_2 C_1 C_1 C_2 D_1 D_2 E_1 E_2
> 

instead of the correct

A_1 A_2 B_1 B_2 C_1 C_2 D_1 D_2 E_1 E_2

where again A_i,B_i don't stand for anything in particular other than "portions of the rev file that should be written in sequence".


Daniel
(since when does shift+enter send in the webmail?)

> On Sat, 14 May 2011 21:24 +0200, "Steinar Bang" <sb...@dod.no> wrote:
> > >>>>> Steinar Bang <sb...@dod.no>:
> > 
> > >>>>> Steinar Bang <sb...@dod.no>:
> > >>>>> Stefan Sperling <st...@elego.de>:
> > 
> > >>> Try to locate boundaries of representations, which look as follows:
> > 
> > >>> https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_fs_fs/structure
> > >>> A representation begins with a line containing either "PLAIN\n" or
> > >>> "DELTA\n" or "DELTA <rev> <offset> <length>\n", where <rev>, <offset>,
> > >>> and <length> give the location of the delta base of the representation
> > >>> and the amount of data it contains (not counting the header or
> > >>> trailer).  If no base location is given for a delta, the base is the
> > >>> empty stream.  After the initial line comes raw svndiff data, followed
> > >>> by a cosmetic trailer "ENDREP\n".
> > 
> > >> `M-j 1916 RET', takes me here:
> > >> 00000770: 4e44 5245 500a 4445 4c54 410a 5356 4e01  NDREP.DELTA.SVN.
> > >> 00000780: 0000 8c0c 823d 8431 823b 8140 4c00 8844  .....=.1.;.@L..D
> > >> 00000790: 4ca8 404e 0048 8100 bf45 820d 9945 820d  L.@N.H...E...E..
> > >> ...
> > 
> > > So... trying to interpret this with the description that Stefan gave,
> > > and that Daniel referred to.  Here we have "DELTA\n" (the "0A" is "\n"),
> > > which begins a representation according to the above description.
> > 
> > > But this is where I get a bit lost.
> > 
> > Just analyzing a little bit further from the /subversion/notes/svndiff
> > description that Daniel mentioned.
> > 
> > The first part after "DELTA\n" is "SVN" followed by a one byte format
> > version number, in this case 0x01.
> > 
> > And then comes the hard part:
> >  After the header come one or more windows, until the document ends.
> >  (So the decoder must have external context indicating when there is no
> >  more svndiff data.)
> > 
> > Then comes the description of a window, and that is, as Daniel said,
> > probably not human readable, or even recognizable in a hex editor,
> > because the window may be zlib compressed (or so I understand it).
> > 
> > Hm... hard this is.  The dark side strong in this one.
> > 
> > 
> 

Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <da...@apache.org>.
You probably don't need to know anything at all about svndiff --- if previous instances of the bug are representative, then you're free to treat consider the svndiff stream an opaque binary data.

That is, previously what happened is that fsfs wrote

A_1 A_2 B_1 B_2 C_1 C_1 C_2 D_1 D_2 E_1 E_2

On Sat, 14 May 2011 21:24 +0200, "Steinar Bang" <sb...@dod.no> wrote:
> >>>>> Steinar Bang <sb...@dod.no>:
> 
> >>>>> Steinar Bang <sb...@dod.no>:
> >>>>> Stefan Sperling <st...@elego.de>:
> 
> >>> Try to locate boundaries of representations, which look as follows:
> 
> >>> https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_fs_fs/structure
> >>> A representation begins with a line containing either "PLAIN\n" or
> >>> "DELTA\n" or "DELTA <rev> <offset> <length>\n", where <rev>, <offset>,
> >>> and <length> give the location of the delta base of the representation
> >>> and the amount of data it contains (not counting the header or
> >>> trailer).  If no base location is given for a delta, the base is the
> >>> empty stream.  After the initial line comes raw svndiff data, followed
> >>> by a cosmetic trailer "ENDREP\n".
> 
> >> `M-j 1916 RET', takes me here:
> >> 00000770: 4e44 5245 500a 4445 4c54 410a 5356 4e01  NDREP.DELTA.SVN.
> >> 00000780: 0000 8c0c 823d 8431 823b 8140 4c00 8844  .....=.1.;.@L..D
> >> 00000790: 4ca8 404e 0048 8100 bf45 820d 9945 820d  L.@N.H...E...E..
> >> ...
> 
> > So... trying to interpret this with the description that Stefan gave,
> > and that Daniel referred to.  Here we have "DELTA\n" (the "0A" is "\n"),
> > which begins a representation according to the above description.
> 
> > But this is where I get a bit lost.
> 
> Just analyzing a little bit further from the /subversion/notes/svndiff
> description that Daniel mentioned.
> 
> The first part after "DELTA\n" is "SVN" followed by a one byte format
> version number, in this case 0x01.
> 
> And then comes the hard part:
>  After the header come one or more windows, until the document ends.
>  (So the decoder must have external context indicating when there is no
>  more svndiff data.)
> 
> Then comes the description of a window, and that is, as Daniel said,
> probably not human readable, or even recognizable in a hex editor,
> because the window may be zlib compressed (or so I understand it).
> 
> Hm... hard this is.  The dark side strong in this one.
> 
> 

Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:

>>>>> Steinar Bang <sb...@dod.no>:
>>>>> Stefan Sperling <st...@elego.de>:

>>> Try to locate boundaries of representations, which look as follows:

>>> https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_fs_fs/structure
>>> A representation begins with a line containing either "PLAIN\n" or
>>> "DELTA\n" or "DELTA <rev> <offset> <length>\n", where <rev>, <offset>,
>>> and <length> give the location of the delta base of the representation
>>> and the amount of data it contains (not counting the header or
>>> trailer).  If no base location is given for a delta, the base is the
>>> empty stream.  After the initial line comes raw svndiff data, followed
>>> by a cosmetic trailer "ENDREP\n".

>> `M-j 1916 RET', takes me here:
>> 00000770: 4e44 5245 500a 4445 4c54 410a 5356 4e01  NDREP.DELTA.SVN.
>> 00000780: 0000 8c0c 823d 8431 823b 8140 4c00 8844  .....=.1.;.@L..D
>> 00000790: 4ca8 404e 0048 8100 bf45 820d 9945 820d  L.@N.H...E...E..
>> ...

> So... trying to interpret this with the description that Stefan gave,
> and that Daniel referred to.  Here we have "DELTA\n" (the "0A" is "\n"),
> which begins a representation according to the above description.

> But this is where I get a bit lost.

Just analyzing a little bit further from the /subversion/notes/svndiff
description that Daniel mentioned.

The first part after "DELTA\n" is "SVN" followed by a one byte format
version number, in this case 0x01.

And then comes the hard part:
 After the header come one or more windows, until the document ends.
 (So the decoder must have external context indicating when there is no
 more svndiff data.)

Then comes the description of a window, and that is, as Daniel said,
probably not human readable, or even recognizable in a hex editor,
because the window may be zlib compressed (or so I understand it).

Hm... hard this is.  The dark side strong in this one.


Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:

>>>>> Stefan Sperling <st...@elego.de>:

>> Try to locate boundaries of representations, which look as follows:

>> https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_fs_fs/structure
>>    A representation begins with a line containing either "PLAIN\n" or
>>    "DELTA\n" or "DELTA <rev> <offset> <length>\n", where <rev>, <offset>,
>>    and <length> give the location of the delta base of the representation
>>    and the amount of data it contains (not counting the header or
>>    trailer).  If no base location is given for a delta, the base is the
>>    empty stream.  After the initial line comes raw svndiff data, followed
>>    by a cosmetic trailer "ENDREP\n".

> `M-j 1916 RET', takes me here:
> 00000770: 4e44 5245 500a 4445 4c54 410a 5356 4e01  NDREP.DELTA.SVN.
> 00000780: 0000 8c0c 823d 8431 823b 8140 4c00 8844  .....=.1.;.@L..D
> 00000790: 4ca8 404e 0048 8100 bf45 820d 9945 820d  L.@N.H...E...E..
> ...

So... trying to interpret this with the description that Stefan gave,
and that Daniel referred to.  Here we have "DELTA\n" (the "0A" is "\n"),
which begins a representation according to the above description.

But this is where I get a bit lost.  Is what I'm looking for what is
between the "0A" and the next "ENDREP"?  (and what will I do with it
once I've got it?  (but that's for later.  let's first try to find it)).

Anyway, the 10 byte sequence that Daniel gave: 53564e0100008c0c823d
only has a single occurrence in that file, according to ghex.

What now?


Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <da...@apache.org>.

On Sat, 14 May 2011 21:10 +0300, "Daniel Shahaf" <da...@apache.org> wrote:
> 
> 
> On Sat, 14 May 2011 19:54 +0200, "Steinar Bang" <sb...@dod.no> wrote:
> > >>>>> Stefan Sperling <st...@elego.de>:
> > 
> > > The script probably took a wrong guess.
> > 
> > > Hopefully this is the known corruption problem with a duplicate block of
> > > data in the revision file.
> > 
> > > Can you check if the original revision file (i.e. not modified by
> > > fsfsverify.py) somewhere contains a data block which contains data
> > > that matches the data around byte offset 1916?
> > 
> > "offset 1916", is that "byte number 1916 in the 683 ref file"?
> > Is that 1916 decimal, or hexadecimal?   I'm assuming decimal for now. 
> > 
> 
> Yes.
> 

"Yes, it's decimal".  Because the node-rev indicated offset 1910 (decimal) and fsfsverify spoke about offset 1916, which corresponds to '1910 + strlen("DELTA\n")' (and to the 0x77C offset of the "SVN\1" in your hex dump) so well that I'm not going to bother check that fsfsverify doesn't print offsets in hex. :-)

Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:

>>>>> Steinar Bang <sb...@dod.no>:
>> Um... how do one determine the length of the sequence?  You are using
>> 10 bytes I guess...?

> Never mind.  It's from that structure description you posted.

Er sorry!  Not you, but Stefan Sperling.  I didn't look at the From
headers of the emails.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:

> Um... how do one determine the length of the sequence?  You are using
> 10 bytes I guess...?

Never mind.  It's from that structure description you posted.

I'll study that some more.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <da...@apache.org>.
Daniel Shahaf wrote on Sat, May 14, 2011 at 22:05:59 +0300:
> an svndiff1 stream

Documented in: ^/subversion/trunk/notes/svndiff

Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <da...@apache.org>.
Steinar Bang wrote on Sat, May 14, 2011 at 20:37:42 +0200:
> >>>>> Daniel Shahaf <da...@apache.org>:
> 
> > No, you should be looking for the sequence of bytes starting at offset
> > 1916.  So, the bytes are:
> 
> > 53564e0100008c0c823d
> 
> > (for example, 'xxd -s 1916 -l 10 -ps' will tell you that)
> 
> Um... how do one determine the length of the sequence?  You are using 10
> bytes I guess...?
> 

No, I wasn't using "10" bytes, I was using an arbitrary number of bytes.
"10" is not a magic number in this context.

> Anyway, the sequence you are showing about, starting at 1916 is the only
> one in the file, both when searching forward and backwards, in ghex.
> 
> > And please don't try searching for the text representation on the
> > right hand side of the hex view!  (You've been here long enough that I
> > assume you know that, but you said 'search for "ENDREP.DELTA.SVN"',
> > which is incorrect in so many ways...)
> 
> Yes, I was just trying my way around hexl-mode, and it proved to have
> too limited search capabilities.  And I was also hoping that there would
> be human readable strings that could be used to identify the contents.
> 

The thing starting with bytes 0x53564e01 is an svndiff1 stream ---
a zlib-compressed binary delta.  (Those four bytes are three magic bytes
and one format-number byte.)  It's probably the least human-readable
part in Subversion...

> Re: 2247
> 
> >> I tried searching for "x^.Rmo.@", but the one at the cursor is the only
> >> occurrence in the file.  At least the only aligned so that search will
> >> find it.  Doesn't look like hexl-mode has the possibility to search for
> >> a byte sequence.  Maybe I should get myself a proper hex editor?
> 
> I installed ghex, and there I've searched for "78 5E 1D 52 6D 6F DA",
> and there is only one occurrence of that strng in the file.

Hmm.  I'm assuming Stefan will have a look, but if for some reason he
doesn't then I'll have a look at your original mail and see if
I mis-advised you regarding what duplication to look for.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Daniel Shahaf <da...@apache.org>:

> No, you should be looking for the sequence of bytes starting at offset
> 1916.  So, the bytes are:

> 53564e0100008c0c823d

> (for example, 'xxd -s 1916 -l 10 -ps' will tell you that)

Um... how do one determine the length of the sequence?  You are using 10
bytes I guess...?

Anyway, the sequence you are showing about, starting at 1916 is the only
one in the file, both when searching forward and backwards, in ghex.

> And please don't try searching for the text representation on the
> right hand side of the hex view!  (You've been here long enough that I
> assume you know that, but you said 'search for "ENDREP.DELTA.SVN"',
> which is incorrect in so many ways...)

Yes, I was just trying my way around hexl-mode, and it proved to have
too limited search capabilities.  And I was also hoping that there would
be human readable strings that could be used to identify the contents.

Re: 2247

>> I tried searching for "x^.Rmo.@", but the one at the cursor is the only
>> occurrence in the file.  At least the only aligned so that search will
>> find it.  Doesn't look like hexl-mode has the possibility to search for
>> a byte sequence.  Maybe I should get myself a proper hex editor?

I installed ghex, and there I've searched for "78 5E 1D 52 6D 6F DA",
and there is only one occurrence of that strng in the file.

Re: fsverify.py unable to fix invalid svndiff header

Posted by Daniel Shahaf <da...@apache.org>.

On Sat, 14 May 2011 19:54 +0200, "Steinar Bang" <sb...@dod.no> wrote:
> >>>>> Stefan Sperling <st...@elego.de>:
> 
> > The script probably took a wrong guess.
> 
> > Hopefully this is the known corruption problem with a duplicate block of
> > data in the revision file.
> 
> > Can you check if the original revision file (i.e. not modified by
> > fsfsverify.py) somewhere contains a data block which contains data
> > that matches the data around byte offset 1916?
> 
> "offset 1916", is that "byte number 1916 in the 683 ref file"?
> Is that 1916 decimal, or hexadecimal?   I'm assuming decimal for now. 
> 

Yes.

> > Usually the spot where the corruption appears (offset 1916 in your case)
> > contains an incomplete representation, but the representation data in the
> > duplicated block is good.
> 
> > One of way of locating the duplicate block is to open the file in a
> > hex editor and search the entire file for hex strings that occur
> > around or after 1916.
> 
> Ok, opening the file in emacs hexl mode:
>  `M-x hexl-find-file /tmp/svnrepo/svn/db/revs/0/683 RET'
> 
> > Try to locate boundaries of representations, which look as follows:
> 
> > https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_fs_fs/structure
> >   A representation begins with a line containing either "PLAIN\n" or
> >   "DELTA\n" or "DELTA <rev> <offset> <length>\n", where <rev>, <offset>,
> >   and <length> give the location of the delta base of the representation
> >   and the amount of data it contains (not counting the header or
> >   trailer).  If no base location is given for a delta, the base is the
> >   empty stream.  After the initial line comes raw svndiff data, followed
> >   by a cosmetic trailer "ENDREP\n".
> 
> `M-j 1916 RET', takes me here:
> 00000770: 4e44 5245 500a 4445 4c54 410a 5356 4e01  NDREP.DELTA.SVN.
> 00000780: 0000 8c0c 823d 8431 823b 8140 4c00 8844  .....=.1.;.@L..D
> 00000790: 4ca8 404e 0048 8100 bf45 820d 9945 820d  L.@N.H...E...E..
> ...
> 
> The cursor is positioned on the "5" starting "5356" in the first line,
> and on the "S" of "SVN". 
> 
> Does that make sense?
> 
> So I should search for "ENDREP.DELTA.SVN"?  The 683 revfile contains 15
> istances of that string, but I have no idea of which ones are relevant
> or not.
> 

No, you should be looking for the sequence of bytes starting at offset 1916.  So, the bytes are:

53564e0100008c0c823d

(for example, 'xxd -s 1916 -l 10 -ps' will tell you that)

And please don't try searching for the text representation on the right hand side of the hex view!  (You've been here long enough that I assume you know that, but you said 'search for "ENDREP.DELTA.SVN"', which is incorrect in so many ways...)

> > So if you find a duplicated block of data you should be able to fix this
> > problem by copying representation data from the duplicate block to the
> > corrupted location.
> 
> So what I'm looking for isn't exactly "ENDREP.DELTA.SVN", but what
> follows this text...?
> 
> I tried searching for "x^.Rmo.@", but the one at the cursor is the only
> occurrence in the file.  At least the only aligned so that search will
> find it.  Doesn't look like hexl-mode has the possibility to search for
> a byte sequence.  Maybe I should get myself a proper hex editor?
> 
> > DO NOT change any byte offsets in the file while doing this. If you
> > cannot squeeze the data in because it would overlap with subsequent
> > data you're out of luck but I've never seen this happen.  Usually
> > there is enough room to fit the data, but you might have to add
> > padding. Any dummy byte will do, I usually use 0x42.
> 
> The meaning of life, the universe and everything?  I thought that was 42
> decimal...? :-)
> 
> > Another possibility is that offset 2247 is wrong. In this case the
> > expected svndiff data is probably located elsewhere and the offset
> > in the representation header should be adjusted.
> 
> Right... that's the first error that fsfsverify.py tries to fix?
> 
> `M-j 2247 RET' takes the cursor over the "7" in "5878" in the first
> line: 
> 000008c0: 8550 8b57 8585 5978 5e1d 526d 6fda 400c  .P.W..Yx^.Rmo.@.
> 000008d0: fe1c ff0a 17f8 00d5 12fa a27d 4145 2a90  ...........}AE*.
> 000008e0: 8466 0da4 2361 6353 2414 ee0e b871 89a3  .f..#acS$....q..
> 
> That wasn't as easily recognizable, as the 1916 one, though.  Not as
> recognizable as a boundary at least.
> 
> What are the things I should look for a duplicate of?  The bytes
> following the troublesome position?  And how many?
> 
> > This is of course not an easy task and it is unfortunate that people
> > keep running into this problem. The source of the problem is not yet
> > known :(  If you have any further questions just ask. If you cannot
> > get it fixed at all but can share the revision file privately I will
> > have a go at it.
> 
> I think I need help with this one.  I'll send you the revision file
> privately.
> 
> Thanks!
> 
> 
> - Steinar
> 
> 

Good luck,

Daniel

Re: fsverify.py unable to fix invalid svndiff header

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Stefan Sperling <st...@elego.de>:

> The script probably took a wrong guess.

> Hopefully this is the known corruption problem with a duplicate block of
> data in the revision file.

> Can you check if the original revision file (i.e. not modified by
> fsfsverify.py) somewhere contains a data block which contains data
> that matches the data around byte offset 1916?

"offset 1916", is that "byte number 1916 in the 683 ref file"?
Is that 1916 decimal, or hexadecimal?   I'm assuming decimal for now. 

> Usually the spot where the corruption appears (offset 1916 in your case)
> contains an incomplete representation, but the representation data in the
> duplicated block is good.

> One of way of locating the duplicate block is to open the file in a
> hex editor and search the entire file for hex strings that occur
> around or after 1916.

Ok, opening the file in emacs hexl mode:
 `M-x hexl-find-file /tmp/svnrepo/svn/db/revs/0/683 RET'

> Try to locate boundaries of representations, which look as follows:

> https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_fs_fs/structure
>   A representation begins with a line containing either "PLAIN\n" or
>   "DELTA\n" or "DELTA <rev> <offset> <length>\n", where <rev>, <offset>,
>   and <length> give the location of the delta base of the representation
>   and the amount of data it contains (not counting the header or
>   trailer).  If no base location is given for a delta, the base is the
>   empty stream.  After the initial line comes raw svndiff data, followed
>   by a cosmetic trailer "ENDREP\n".

`M-j 1916 RET', takes me here:
00000770: 4e44 5245 500a 4445 4c54 410a 5356 4e01  NDREP.DELTA.SVN.
00000780: 0000 8c0c 823d 8431 823b 8140 4c00 8844  .....=.1.;.@L..D
00000790: 4ca8 404e 0048 8100 bf45 820d 9945 820d  L.@N.H...E...E..
...

The cursor is positioned on the "5" starting "5356" in the first line,
and on the "S" of "SVN". 

Does that make sense?

So I should search for "ENDREP.DELTA.SVN"?  The 683 revfile contains 15
istances of that string, but I have no idea of which ones are relevant
or not.

> So if you find a duplicated block of data you should be able to fix this
> problem by copying representation data from the duplicate block to the
> corrupted location.

So what I'm looking for isn't exactly "ENDREP.DELTA.SVN", but what
follows this text...?

I tried searching for "x^.Rmo.@", but the one at the cursor is the only
occurrence in the file.  At least the only aligned so that search will
find it.  Doesn't look like hexl-mode has the possibility to search for
a byte sequence.  Maybe I should get myself a proper hex editor?

> DO NOT change any byte offsets in the file while doing this. If you
> cannot squeeze the data in because it would overlap with subsequent
> data you're out of luck but I've never seen this happen.  Usually
> there is enough room to fit the data, but you might have to add
> padding. Any dummy byte will do, I usually use 0x42.

The meaning of life, the universe and everything?  I thought that was 42
decimal...? :-)

> Another possibility is that offset 2247 is wrong. In this case the
> expected svndiff data is probably located elsewhere and the offset
> in the representation header should be adjusted.

Right... that's the first error that fsfsverify.py tries to fix?

`M-j 2247 RET' takes the cursor over the "7" in "5878" in the first
line: 
000008c0: 8550 8b57 8585 5978 5e1d 526d 6fda 400c  .P.W..Yx^.Rmo.@.
000008d0: fe1c ff0a 17f8 00d5 12fa a27d 4145 2a90  ...........}AE*.
000008e0: 8466 0da4 2361 6353 2414 ee0e b871 89a3  .f..#acS$....q..

That wasn't as easily recognizable, as the 1916 one, though.  Not as
recognizable as a boundary at least.

What are the things I should look for a duplicate of?  The bytes
following the troublesome position?  And how many?

> This is of course not an easy task and it is unfortunate that people
> keep running into this problem. The source of the problem is not yet
> known :(  If you have any further questions just ask. If you cannot
> get it fixed at all but can share the revision file privately I will
> have a go at it.

I think I need help with this one.  I'll send you the revision file
privately.

Thanks!


- Steinar


Re: fsverify.py unable to fix invalid svndiff header

Posted by Stefan Sperling <st...@elego.de>.
On Sat, May 14, 2011 at 10:58:12AM +0200, Steinar Bang wrote:
> Platform:
>   debian 6.0.1 "squeeze",
>   subversion 1.6.16dfsg-1+b1,
>   fsfsverify.py from http://svn.apache.org/repos/asf/subversion/trunk/contrib/server-side
>   python 2.6.6-3+squeeze6
> 
> (information about the repository at the end of this mesage)
> 
> Yesterday I discovered that my subversion repository is broken.  Trying
> to do "svnadmin dump" breaks at revision 683:
>  sb@somehost:/tmp/svnrepo$ svnadmin dump /tmp/svnrepo/svn/ >/dev/null
>  * Dumped revision 0.
>  * Dumped revision 1.
>  ...
>  * Dumped revision 681.
>  * Dumped revision 682.
>  svnadmin: Decompression of svndiff data failed
> 
> 
> I found some threads on this list of people with the same error message
> suggesting to use fsfsverify.py.  I assumed that the trunk version from
> the repository would be the newest and most stable so that's the version
> I've tried.
> 
> I've done all of my experiments with fsfsverify.py, and one attempt at
> using fsfsfixer, on a copy of the repository, created with the command:
>  (cd /tmp/svnrepo; rm -rf svn; cp -a /usr/local/svn/ .)
> 
> 
> The first run of fsfverify.py /tmp/svnrepo/svn/db/revs/0/683 reports the
> following: 
>  ...
>  NodeRev Id: 4-683.0.r683/12232
>   type: file
>   text: DELTA 683 1910 890 1548 30aadd70339eb7b41ab6eb20a6220202
>   prop: PLAIN 683 12138 81 0 685faf6a4230ea531a31a12e4b3cb565
>   cpath: /trunk/someprog/metamodeller/Makefile.msvc
>   copyroot: 0 /
>    <Svndiff so: 1916 ver: 1>
> 
>  Error InvalidCompressedStream: Invalid compressed data stream at offset 2247 (Error -3 while decompressing: incorrect data check, <Window wo:1920 so:0 sl:0 tl:1548 cil: 317 cdl: 561 il:315 dl:729 whl:8 wl:886>)
> 
>  Try running with -f to fix the revision
> 
> 
> When I run fsfsverify.py -f /tmp/svnrepo/svn/db/revs/0/683 I see:
>  ...
>  NodeRev Id: 4-683.0.r683/12232
>   type: file
>   text: DELTA 683 1910 890 1548 30aadd70339eb7b41ab6eb20a6220202
>   prop: PLAIN 683 12138 81 0 685faf6a4230ea531a31a12e4b3cb565
>   cpath: /trunk/someprog/metamodeller/Makefile.msvc
>   copyroot: 0 /
>    <Svndiff so: 1916 ver: 1>
>  Copy 893 bytes from offset 1920
>  Write 893 bytes at offset 1916
>  Fixed? :-)  Re-run fsfsverify without the -f option
> 
> 
> Which looks good.  However, fsfverify.py /tmp/svnrepo/svn/db/revs/0/683
> reports: 

The script probably took a wrong guess.

Hopefully this is the known corruption problem with a duplicate block of
data in the revision file.

Can you check if the original revision file (i.e. not modified by
fsfsverify.py) somewhere contains a data block which contains data
that matches the data around byte offset 1916?

Usually the spot where the corruption appears (offset 1916 in your case)
contains an incomplete representation, but the representation data in the
duplicated block is good.

One of way of locating the duplicate block is to open the file in a hex
editor and search the entire file for hex strings that occur around or
after 1916. Try to locate boundaries of representations, which look as
follows:

https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_fs_fs/structure
  A representation begins with a line containing either "PLAIN\n" or
  "DELTA\n" or "DELTA <rev> <offset> <length>\n", where <rev>, <offset>,
  and <length> give the location of the delta base of the representation
  and the amount of data it contains (not counting the header or
  trailer).  If no base location is given for a delta, the base is the
  empty stream.  After the initial line comes raw svndiff data, followed
  by a cosmetic trailer "ENDREP\n".

So if you find a duplicated block of data you should be able to fix this
problem by copying representation data from the duplicate block to the
corrupted location. DO NOT change any byte offsets in the file while doing
this. If you cannot squeeze the data in because it would overlap with
subsequent data you're out of luck but I've never seen this happen.
Usually there is enough room to fit the data, but you might have to add
padding. Any dummy byte will do, I usually use 0x42.

Another possibility is that offset 2247 is wrong. In this case the
expected svndiff data is probably located elsewhere and the offset
in the representation header should be adjusted.

This is of course not an easy task and it is unfortunate that people
keep running into this problem. The source of the problem is not yet
known :(  If you have any further questions just ask. If you cannot
get it fixed at all but can share the revision file privately I will
have a go at it.

Good luck!