[ILUG] Rescue file from damaged CDR?
Kenn Humborg
kenn at linux.ie
Thu Sep 14 23:57:28 IST 2000
On Thu, Sep 14, 2000 at 08:00:32PM +0100, Conor Daly wrote:
> Ideas anyone?
>
> Trying to rescue a ~28Mb file from a damaged CDR. I'm trying
>
> dd if=/mnt/cdrom/file of=first.out
>
> once I get an I/O error I get a count of blocks read by dd so I do it
> again using
>
> dd if=/mnt/cdrom/file of=seconf.out skip=<blocks already read>+1
>
> and so on until I run out of blocks to read. I'll then use a single block
> fragment to pad out to the original size and do a
>
> cat first.out block-fragment second.out block-fragment third.out ...... > recovered-file
>
> Will this work? Is there a better way?
You might be able to automate this with the noerror and sync options to dd:
dd if=/mnt/cdrom/file of=file bs=2048 noerror sync
'noerror' says continue after read errors. 'sync' says pad out all input
blocks with NULs.
However, I don't know the failed read results in an input block with zero
length that gets padded out and written, or results in that block not
being written _at_all_ to the output file.
To test it, use count=<num-blocks> to restrict the copy to the start of
the file up to just past the first damaged block. Then check if the
output file is num-blocks*2048, or smaller. If smaller, this won't work.
Alternatively, do it piecemeal:
#!/bin/sh
INFILE=/mnt/cdrom/file
OUTFILE=file
BLOCK_SIZE=2048
NUM_BLOCKS=14000 # 28MB/2048 - work this out exactly
# ...or better yet, work it out in code
for i in `seq 0 $[ $NUM_BLOCKS - 1 ] ` ; do
dd if=$INFILE of=$OUTFILE bs=$BLOCK_SIZE count=1 seek=$i skip=$i
done
If doesn't matter if dd writes a block of zeros or not for a bad block
here, because the next block will still be written at the correct
position (skip=$i), extending the file if necessary.
Later,
Kenn
More information about the ILUG
mailing list