Diese Antwort untersucht das Verhalten ddrescue
der Hauptfrage. Wenn Sie nicht an einem Testverfahren interessiert sind, können Sie am Ende zu meinen Schlussfolgerungen und Interpretationen gehen.
Testbed
$ uname -a Linux foo 4.2.0-27-generic #32~14.04.1-Ubuntu SMP Fri Jan 22 15:32:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/issue Ubuntu 14.04.5 LTS \n \l $ ddrescue -V GNU ddrescue 1.17 …
Das Dateisystem ist btrfs. Es sollte jedoch keine Rolle spielen, solange es spärliche Dateien unterstützt.
Testen
Zuerst bekam ich 8 MB zufällige Daten:
dd if=/dev/urandom of=random.chunk bs=1M count=8
Dann machte ich es zu einem Loopback-Gerät und erinnerte mich an seinen Namen:
loopdev=`sudo losetup -f --show random.chunk`
Als Nächstes habe ich ein weiteres Gerät erstellt, das aus bestand
- Chunk 0: nicht lesbar, 1 MiB
- Block 1: Nullen, 2 MiB
- Block 2: nicht lesbar, 4 MiB
- Block 3: Daten von
random.chunk
, 8 MiB - Block 4: nicht lesbar, 16 MiB
Der Code (es verwendet hier Dokumentsyntax ):
sudo dmsetup create mydevice << EOF 0 2048 error 2048 4096 zero 6144 8192 error 14336 16384 linear $loopdev 0 30720 32768 error EOF
Ich bestätigte damit, gdisk -l /dev/mapper/mydevice
dass die Gesamtgröße 31 MiB beträgt, wie es sein sollte.
Das eigentliche Lesen erfolgt mit:
ddrescue /dev/mapper/mydevice normal.raw normal.log ddrescue -R /dev/mapper/mydevice normalR.raw normalR.log ddrescue -S /dev/mapper/mydevice sparse.raw sparse.log ddrescue -RS /dev/mapper/mydevice sparseR.raw sparseR.log
Und die Ergebnisse von ls -hls *.raw
sind
10M -rw-rw-r-- 1 kamil kamil 15M Sep 10 00:37 normal.raw 10M -rw-rw-r-- 1 kamil kamil 15M Sep 10 00:37 normalR.raw 8.0M -rw-rw-r-- 1 kamil kamil 15M Sep 10 00:37 sparse.raw 8.0M -rw-rw-r-- 1 kamil kamil 15M Sep 10 00:37 sparseR.raw
To be sure, I confirmed with cmp
that all four files are identical when you read them. Four logfiles contained the same map of erroneous and healthy sectors.
Notice that
- 15 MiB means the last chunk is missing;
- 10 MiB indicates chunk 1 and chunk 3;
- 8 MiB indicates chunk 3 only.
Cleaning
sudo dmsetup remove mydevice sudo losetup -d $loopdev unset loopdev rm random.chunk normal.raw normal.log normalR.raw normalR.log sparse.raw sparse.log sparseR.raw sparseR.log
Conclusions
- When it comes to file size, it doesn't matter whether you read in reverse (
-R
) or not. - Unreadable chunk at the very end of the input file doesn't contribute to the overall size of the output file.
- Unreadable chunks that do contribute to overall file size are always sparse (if target filesystem supports this, of course).
- The
-S
option only affects blocks of zeros that were actually read from the input file.
Interpretation
Above there were facts. This section is more like my opinion.
It appears ddrescue
tries to save you diskspace whenever it can do this without additional work. When you use -S
the tool has to do some computations to check if a given data block is all zeros. If there's a read error it doesn't need to compute anything, it can make the fragment sparse in the output file with no cost.
Solution
You wrote:
using the
-R
switch (“reverse”) at the beginning, figuring that it would allocate the whole size of the input HDD right away
We just saw it's a false assumption. In fact you described what -p
does. ddrescue -p
will preallocate space on disk for output file. When I did this during my tests the output file had 31 MiB and was not sparse (even with -S
).