/dev/vg/backuppc is a VLM volume with 330310176 blocks (cleanly
unmounted, read as a device with read only permission)
ext3grep version 6.0
kernel version 2.4.27
Debian 3.1, e2fslibs-dev_1.39+1.40-WIP-2006
My situation is the following, I had the files in one tree with
hardlinks to the "actual" contents in another tree. The first tree
had the real names and directory structure, but the second tree is
almost flat and all files have an md5sum string as name. (That is
backuppc, that allows for multiple linking of the same file across
many backups).
After accidentally erasing the tree that held the names, all I have
now are the files with the md5 names.
So, I'm trying to recover the filenames and make them point to the
mdsum names so that I don't have to go every file to know what it is
and how to name it, and so that I don't lose the directory hierarchy.
I guess this is pretty easy for ext3grep, if I get it to work. Any
ideas on how to overcome the error below?
NOTICE : Entering run_program()
Inodes count: 41959424
Blocks count: 83894272
Reserved blocks count: 1677885
Free blocks count: 8118556
Free inodes count: 41093528
First Data Block: 0
Block size: 4096
Fragment size: 4096
Number of blocks per group: 32768
Number of fragments per group: 32768
Number of inodes per group: 16384
Mount time: Sun Apr 6 17:08:58 2008
Write time: Tue May 13 19:14:27 2008
Mount count: 17
Maximal mount count: 21
Magic signature: 0xef53
File system state: 'Unmounted cleanly'
Size of inode structure: 128
Block group # of this superblock: 0
compatible feature set: HAS_JOURNAL
incompatible feature set: FILETYPE
readonly-compatible feature set: SPARSE_SUPER LARGE_FILE
Per group desc for online growth: 0
UUID of journal superblock: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Inode number of journal file: 8
Device number of journal file: 0
Start of list of inodes to delete: 0
First metablock block group: 0
/src/svn/ext3grep-read-only-objdir$ gdb src/ext3grep
GNU gdb 6.3-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "i386-linux"...Using host libthread_db
library "/lib/libthread_db.so.1".
NOTICE : Entering run_program()
Inodes count: 41959424
Blocks count: 83894272
Reserved blocks count: 1677885
Free blocks count: 8118556
Free inodes count: 41093528
First Data Block: 0
Block size: 4096
Fragment size: 4096
Number of blocks per group: 32768
Number of fragments per group: 32768
Number of inodes per group: 16384
Mount time: Sun Apr 6 17:08:58 2008
Write time: Tue May 13 19:14:27 2008
Mount count: 17
Maximal mount count: 21
Magic signature: 0xef53
File system state: 'Unmounted cleanly'
Size of inode structure: 128
Block group # of this superblock: 0
compatible feature set: HAS_JOURNAL
incompatible feature set: FILETYPE
readonly-compatible feature set: SPARSE_SUPER LARGE_FILE
Per group desc for online growth: 0
UUID of journal superblock: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Inode number of journal file: 8
Device number of journal file: 0
Start of list of inodes to delete: 0
First metablock block group: 0
Program received signal SIGSEGV, Segmentation fault.
0x40356428 in vtable for __cxxabiv1::__si_class_type_info ()
from /usr/lib/libstdc++.so.6
(gdb) bt
#0 0x40356428 in vtable for __cxxabiv1::__si_class_type_info ()
from /usr/lib/libstdc++.so.6
#1 0x400b8b38 in std::basic_ios<char, std::char_traits<char> >::widen
()
from /usr/lib/libstdc++.so.5
#2 0x400e4761 in std::ostream::operator<< () from /usr/lib/libstdc+
+.so.5
#3 0x400e4c1d in std::ostream::operator<< () from /usr/lib/libstdc+
+.so.5
#4 0x08081fa9 in inode_mmap (group=0)
at ../../ext3grep-read-only/src/ext3grep.cc:467
#5 0x0809ff3a in get_inode (inode=8)
at ../../ext3grep-read-only/src/ext3grep.cc:578
#6 0x08083f00 in run_program ()
at ../../ext3grep-read-only/src/ext3grep.cc:1382
#7 0x08087131 in main (argc=1, argv=0xbffffd5c)
at ../../ext3grep-read-only/src/ext3grep.cc:2090
Hmm, a core dump in operator<< of a Dout() call.. must be some memory corruption somewhere. I have no clue what caused that or where that happened.
In order to find this one would need to start to add a LOT of extra (range checking) tests until you find where something is wrong.
A logical first step would be to configure libcwd with --enable-glibcxx_debug (and recompile+reinstall, and then recompile ext3grep). And if that doesn't tell anything (probably not) then run ext3grep inside valgrind to see if that sees where some memory error happens. Not that I think this will help, but it's simply the first thing to try.
Note that one reason that ext3grep starts doing very weird things is when your stage1/stage2 files aren't up to date (ie, if the filesystem changed since you created them). So... I suppose it would also make sense to at least delete those once again and rerun ext3grep to generate them again, on the same and UNmounted partition.
I'm going to try to follow your steps. In the meantime I did a strace
on the execution, --list --inode 2 and, right before the segfault (and
right after printing "sorting...") I found an llseek with a huge
number. That llseek fails.
I copy part of the trace (without the gettimeofday and brk calls),
maybe that rings a bell or maybe you can tell me more or less where to
check in the code ...
On Thu, May 15, 2008 at 05:40:39AM -0700, eduardo wrote: > I'm going to try to follow your steps. In the meantime I did a strace > on the execution, --list --inode 2 and, right before the segfault (and > right after printing "sorting...") I found an llseek with a huge > number. That llseek fails.
Good idea... A device.good() fails assertion is probably always a wrong seek. My guess would be that this is the seekg in get_block. This would always be a value returned by block_to_offset, called with a block number that is out of range. I suppose I should add an assertion there that would have avoided this search.
Thus, change
static inline off_t block_to_offset(int block) { #ifdef CWDEBUG if (block > 83894272) // Out of range for your case. Debug(attach_gdb()); // Open window with debugger. #endif off_t offset = block; offset <<= block_size_log_; return offset;
}
Using attach_gdb() requires that your .libcwdrc file is correctly setup. I'm using this:
in which case you need to have gnome-terminal installed (if you are running gnome thus). [This only works if extgrep is NOT running inside gdb already: if you want to skip a break point like this you have to quit, rather than continue gdb.]
Of course, you can also run ext3grep inside gdb and set the breakpoint yourself, ie:
(gdb) b block_to_offset (gdb) cond 1 block > 83894272 (gdb) r --arguments here ...
I had not noticed this error message while linking:
/usr/bin/ld: warning: libstdc++.so.6, needed by /usr/lib/gcc-lib/i486-
linux-gnu/3.3.6/../../../libcwd.so, may conflict with libstdc++.so.5
Since libcwd was already packaged, I downloaded g++-4.1 and recompiled
and ... voilą, it works! That's why there was an error on Dout. It
seems that gcc3 links against libstdc++.so.5 and gcc4 against libstdc+
+.so.6, you cannot choose the library.
Maybe you could add a notice about it, I don't know ...
Thanks for your time. Now it's time to see if I finally can recover
the information I need. And, by the way, your document on ext3 is
impressive, great work, it should be linked from the ext3 FAQ.