7

I have a home directory in a disk that has a lot of corrupted files. I am trying to save most files as possible. I am trying to create a backup of my home directory on an external drive using

tar -cvf backup /home/myHome

and also have tried

rsync -vfh /home/myHome /media/backup

Both methods stop when they found a corrupt file. Is there a way to force one or the other to continue copying and ignore bad files, copying everything that is possible to copy and show me a log at the end of the files that were not copied?

Thanks.

Duck
  • 4,674
  • I have not enough time for full answer, but my approach would be mounting read-only the partition containing /home and then keeping a copy of the partition's image in a file with dd conv=noerror if=/dev/sdXY of=/media/backup/sdXY.dump. Then you can fsck the image file and mount it with -o loop. – forcefsck Jan 22 '12 at 20:54

5 Answers5

4

If you have enough room on your external drive, perform a full copy of the partition, skipping over irrecoverable sectors. Then make a copy of the copy, and call fsck on that.

For the copy of the partition from the failing drive, use myrescue, or if that's not flexible enough ddrescue or dd_rescue. All of these tools skip over unreadable regions or try to read them repeatedly; adjust depending on whether repeated reads have a chance of working (e.g. optical media or floppies) or on the contrary wear out the failing drive sooner (e.g. most hard disk failures). See also saving data from a failing drive, How to recover data from a bad SD card?

sudo myrescue /dev/sda42 >/media/backup/home.raw
cp /media/backup/home.raw /media/backup/home.recovering
/sbin/fsck -f /media/backup/home.recovering
sudo mount -o loop /media/backup/home.recovering /mnt
cp -a /mnt /media/backup/home.saved
3

I wrote a little script for that

#!/bin/bash
echo "copying from $1"

find $1 -type f -print0 | while read -d $'\0' -r file ; do
    echo Processing "$file"
    target="$2""$file"
    if (test -f "$target") then
        echo File Exists:  "$target"
    else
        echo copying to "$target"
        targetDir=`dirname "$target"`

        if (! [ -d "$targetDir" ]) then
            mkdir "$targetDir"
        fi

        ddrescue -e0 -r0 -v -n "$file" "$target"
        if ([ $? -ne 0 ]) then
            echo Copy failed, deleting "$target"
            rm -f "$target"
        fi
    fi
done
slm
  • 369,824
1

First, use rsync -aHv --- rsync -vfh makes no sense for what you're trying to do.

rsync has an --ignoring-existing flag that you can use. Run rsync -aHv --ignore-existing until it quits with an I/O error. Note the name of the file that failed and create an empty version of it on the external drive where it would have been copied if rsync had worked. Re-run the rsync command and --ignore-existing will cause it to not try to copy the file that failed. Hopefully rsync will copy everything else, but if it stops again, repeat this process. Repeat until rsync runs to completion.

Kyle Jones
  • 15,015
  • thanks, but this will be a pain because there are hundreds of corrupted files... :( – Duck Jan 22 '12 at 22:49
1

A different solution:

find /home/user -type f -print0 | xargs -0 -JXXX -n1 rsync --relative -lptgoHv XXX /external-disk

find generates a list of files and xargs calls rsync with them one at a time. --relative makes sure you get a tree on the external disk instead of a flat directory, so don't leave off that argument to rsync.

Kyle Jones
  • 15,015
  • thanks. care to explain the -JXXX and the other XXX at the end? thanks. Is this real XXX or do I need to put something else there? – Duck Jan 23 '12 at 14:30
  • -JXXX tells xargs to replace XXX in the arg list passed to rsync with a filename from the list find is providing. Without the -J xargs would put the filename at the end of the arg list. – Kyle Jones Jan 23 '12 at 15:11
  • I tried that and it says "error invalid argument -JXXX" – Duck Jan 23 '12 at 20:40
  • Wow, an xargs old enough to not accept -J. OK, try -IXXX instead of -JXXX ; it should work with same way. – Kyle Jones Jan 27 '12 at 00:44
  • no, typing man xargs I see that -J is an option, but it still gives me this message. I will try that one. – Duck Jan 28 '12 at 15:44
0

use cpio -ivd -H tar command

man page says that

This will retrieve the files archived in the file directory.cpio and place them in the present directory. The '-i' option extracts the archive and the '-v' shows the file names as they are extracted. If you are dealing with an archived directory tree, you need to use the '-d' option to create directories as necessary,

-H is for format

see this and this

  • no, I want to create a tar from my home directory, but the directory has loads of corrupted files. I want tar to backup all files that are good and create an archive. – Duck Jan 22 '12 at 22:51