0

I was recently acquiring data from a networked instrument, saving results as text files. Unfortunately, I forgot to change the filename during one of my runs, and I managed to overwrite an important file.

Is it worth going through extreme lengths to restore this file? Sadly, yes. This data is an important part of an animal experiment that took several week to prepare for.

I was able to locate the deleted file on my raw disk (using the grep method). However, my system (btrfs) has LZO compression enabled, so only a few parts of the file are written in plain-text. If I can decompress this data, I can recover my file.

The challenge I am dealing with, is that btrfs uses a different header/footer for its LZO-compressed files than utilities like LZOP (as far as I can see). Thus, even though I have the full file and know how it is compressed, I cannot decode the results.

Two strategies I am looking into are:

1) Adapting the btrfs header/footer into a header that can be read by LZOP.

2) Using one of the btrfs tools to "re-discover" the deleted file, which is lost but not removed from the disk. Alternatively, it would be useful if I could somehow create a file in btrfs by explicitly feeding it the expected raw data.

The obstacles I am facing with both of these approaches are: that btrfs is complex, and that LZO is poorly documented. As such, researching a solution to such a non-standard problem has been challenging.

The raw, compressed, data that I need to recover is as follows:

^Q^@^@
^@^@^@^@^@^@^@"^@nerve1_cuff2_run1_phase6_rampA.csvªu^D^@^@^@^@^@­^u^D^@^@^@^@^@=   ^@^@^@^@^@^@=   ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@è^C^@^@d^@^@^@<80><81>^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@<83>'½Z^@^@^@^@ÜÑ<9a>37(½Z^@^@^@^@>Þ?(7(½Z^@^@^@^@>Þ?(<83>'½Z^@^@^@^@ÜÑ<9a>3©u^D^@^@^@^@^@=   ^@^@^@^@^@^@^B^@^@^@^@E^E^@^@=^E^@^@^@
^C^A^ATime,Voltage,Current^M
0.0`^@
e+00    -3.62291°^A^K6.74129e-07^M
3,<98>^@^B27144¸^D^D2.86341¹^D6,<98>^@^B19476ø^D^B96474¹^D9*<98>^@^D5.42908¸^D^M1.03390e-06^M
1.2Ì^S^G1   -5.46949ø^D^B78325ù^D5+<98>^@^A2152ø^D^A8254'<99>^@8(<98>^@^D7.35047¸^D^C2.8822l^S^C6^M
2.1*<98>^@^A0896À"^D3.18038³^N2.4*<98>^@^A2904Ä^]^C3.5740`"<95> 7(<98>^@^D9.13875°^N^D5.47206´  (x^E^F1 -9.0993Ä^]^D5.53632ù^D3*4^A^A0773Ü&^C5.5675Ç^]3.6(<98>^@^B1.093<8c>:^F1 -7.3989'Ñ^A9*  <98>^@^A1280|&<8c>-^A6748Á"4*^T^F^C1.1296|&^F1   -6.2602Ã"4.5*4^A^A3289l^S<90>^N^B78413ª^X4.)^T^F^B1.293<98>+<98>^^^A2548Ý&5*^T^F^G1.26543e+0<98>^D^A6356xR^A6^M
5*^T^F^C1.4376È^X^C1.1896q^N5x^D)^T^F^C1.4511(<9b>^@924^?M5^M
(÷
1   -v  47h?<90>^A^A1925d^]<98>^D)^T^F^C1.6172'7^A399<98>+<98>^D+^T^F^A6008Ü&^C1.4441x+<98>^D+^W^F594(4^A   45857e-05^M    
7,^T^F^A7608`p<8c>^S^A7039'<98>^@+^T^F^B75760¼&^C1.7120É^X7,^T^F^A7577(7^A166Í^S8,^T^F^A9248p\<90>^N^A9370Ù+8,^T^Fx^DÐ5^B1.977<94>W^B5^M
8.+^W^F914<8c><88>µ 8h2<84>^](p^P^F1    -2.0489la<90>^A^A3495h?^B5^M
9.)^T^F^A2.02'¤^C^C2.3412hf<98>^D)^T^F^B2.060øR^C2.3101hf<98>^D)^T^F^B2.216ø+^C2.5738if5d<92>^A0200e*2l^S^A2133À"^C2.5826×  1.0{0e+0º^D02<94>~<8b>^X627<84>k´                                  paø^D^A3522'7^A902<88><8d><99>^D1h<92>*<98>^@l<88><94>   ^A9069×01.1h<92>'<9a>^@67<98> »^D325Ã"1.1x0û^D669èf^B2.751(l^B`^]'§^C651<9c><9b><97>                                                  746<80>p<8d>^S2x0'6^A45<80><97>Ú^D47'A^D2x0û^D814<8c>¯<98>^D^A9919t~´ x0ø^D^A7883Ä^]^B3.031çk1.3p^S'<9b>^@950Äkz^D94Ía1l¼(³^F767ì^S^B4.036÷~1.3*^T^F^A6608x^^^F1  -4.1916'é^G4*^W^F909ð5^C3.   3969'¥^C4(^T^F^C3.0201Äk^C3.6643Ë<8d>1.4(^T^Fu¿9(^H^C^B71043µ~1'Q^U2wó003<81>å1p^A^A7286Ûy1.5(^U^F3a¾7'^H^C|H(4^A(^W^F3.0Üé<84>^]^A0770×~1.5(^T^Fy^D6(Ü^D^A1408'!  6(^T^F^D3.15811¨<8d>^C4.    4145'¥^C6(,^L^B3.108à¾^C4.7772'm^B6(^T^F^C3.0823Ъ^C4.8710'M^G7(^T^F<85>^]2Ä^]^C5.6715'5^A7,^U^F4ôW^B5.728<90>Ñ<9d>M7+^U^F2'$^W
5.71477e-05^M
^Q^@^@  ^@^@^@^@^@^@^@"^@nerve1_cuff2_run1_phase4_rampA.csv¨u^D^@^@^@^@^@©u^D^@^@^@^@^@=    ^@^@^@^@^@^@= ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@è^C^@^@d^@^@^@<80><81>^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@I%½Z^@^@^@^@^Y^^þ7ý%½Z^@^@^@^@¾n­^8ý%½Z^@^@^@^@¾n­^8I%½Z^@^@^@^@^Y^^þ7¨u^D^@^@^@^@^@^@p^@^@^@^@^@^@^B^@^@^@^A^@<80>´ m^@^@^@^@@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@p^@^@^@^@^@^@^H^@^@^@^@^@^@^@#^@nerve1_cuff2_run1_phase3_pulseA.csv§u^D^@^@^@^@^@¨u^D^@^@^@^@^@Ém^@^@^@^@^@^@^@p^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@è^C^@^@d^@^@^@<80><81>^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^W$½Z^@^@^@^@Ò<82>Å^LG%½Z^@^@^@^@í3ò&G%½Z^@^@^@^@í3ò&^W$½Z^@^@^@^@Ò<82>Å^L§u^D^@^@^@^@^@= ^@^@^@^@^@^@^B^@^@^@^@"^E^@^@^Z^E^@^@^@
--

I realize this is not very useful without the binary data, but it at least might give you an idea of what I am looking at. I am not exactly sure where the file begins and ends on the disk, so I included some additional lines. The first line of the file would correspond to: ^C^A^ATime,Voltage,Current^M.

The plain-text file would look something like this:

^C^A^ATime,Voltage,Current                                                                     
0.00000e+00 7.05295e-01 -2.87974e-06
2.99999e+00 6.91690e-01 -2.88057e-06
6.00000e+00 6.89945e-01 -2.87807e-06
9.00000e+00 5.05297e-01 -8.11195e-06
1.20000e+01 4.78072e-01 -8.09407e-06
1.50000e+01 4.54195e-01 -8.11017e-06
1.80000e+01 3.06597e-01 -1.34169e-05
2.10000e+01 2.93734e-01 -1.34169e-05
2.40000e+01 2.76573e-01 -1.34177e-05
2.70000e+01 8.67963e-02 -1.88397e-05
3.00000e+01 6.46639e-02 -1.88236e-05
3.30000e+01 8.51750e-02 -1.87974e-05
... (61 lines in total)

My disk is mounted with the following options:

UUID=XXXX   /home       btrfs       rw,nosuid,nodev,noatime,compress=lzo,ssd,space_cache,autodefrag,subvol=__active/home    0 0

Any help would be greatly appreciated!

  • Do you have a hexdump or other sane representation of that data? binwalk is able to extract some of these out of raw data with arbitrary offsets. Not sure if it would work for btrfs... you could try the relevant mailing list. – frostschutz Mar 31 '18 at 0:08
  • Your plain-text file starts with 3 non-text characters? – user41515 Mar 31 '18 at 0:24
1

I was able to solve my problem by taking the raw (compressed) data from the disk and writing a new header for it that LZOP could read.

Although LZOP itself has very little documentation on the contents of the header, I was able to use that from another author who needed this function for another purpose. If anyone else has this problem, see: https://github.com/MediaMath/go-lzop/blob/master/README.md

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.