LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   Rescuing data from a Windows Vista disk (http://www.linuxquestions.org/questions/linux-general-1/rescuing-data-from-a-windows-vista-disk-883029/)

deesto 05-27-2011 09:15 AM

Rescuing data from a Windows Vista disk
 
I'm trying to help out a Windows Vista user by rescuing their data from a failing hard disk. When their laptop stopped booting, I immediately pulled the disk to get as much as I could off of it using another Windows box, but the process took days and ultimately choked on multiple bad sectors and stopped responding.

I then hooked it up to my Ubuntu box via a USB disk dock and ran a ddrescue on the Windows partition. The operation took a week, then seemed to get stuck for another week on the "splitting failed blocks" phase. So I have an dd image and a log to go back to, but when I resume that process it still seems to use the disk and I don't see much progress.

I then tried a plain `dd` on the disk with `conv=noerror,sync` options, and that has been running for a few days now, but with input/ouput error messages every few seconds and seemingly no records going in or out. I think that's a bad sign.

What's the best, and fastest, way to get the most data off the disk as possible and into an image file, and then perform any necessary operations on the image file so that the disk is no longer needed (since it seems to be just about dead)?

Er, just realized I'd put "Windows 7" in the post title, but this is a Vista partition, and I can't change the title. They're pretty similar, with one OS being much less useful than the other, but I thought I'd better acknowledge my mistake.

never say never 05-27-2011 11:55 AM

Sounds like a nice mess.


Depending on the nature of the failing drive I have had some success with SpinRite, to allow you to read (and re-write) bad sectors. It's not free, and can take a long time to run on a drive. Additionally, if the problem is a physical one, it may actually cause the drive to fail completely. If the drive was dropped and the alignment is just off, or subjected to a magnetic field it does a pretty remarkable job of recovering drives.

Many years ago I would take the platters out of a failing drive and put them in another drive (same Model) and recover data that way, but that takes a lot of patients, a really clean area...

Now I do defense in depth and have multiple backups in multiple formats of everything.

H_TeXMeX_H 05-27-2011 12:01 PM

ddrescue is the best way to get an image before the drive dies completely. There is no better way that I know of. After you get the image, use testdisk or foremost to recover partitions or carve data out.

deesto 05-27-2011 12:08 PM

never say never: agreed that backups are the best defense, but in this case it's clear that it's not an option, but I hope it will be a lesson to be learned for them. I've already told them recovery would be best-effort and without any guarantee, but I'd like to give it all I can think of before giving up.

H_TeXMeX_H: how long would you wait out a `ddrescue` that was in the splitting phase for over a week? The command I was using (which I could resume it it's worth waiting for the splitting phase) was:
Code:

sudo ddrescue --no-split --direct --retrim -r5 [partition] [image-file] [log-file]
Anything you would change to fix or speed up the recovery, or the split phase?

H_TeXMeX_H 05-27-2011 01:49 PM

What is slowing it down is a bad HDD. Normally you could speed up dd by using a larger block size (-b), but I'm not sure that will help here, because it just keeps re-trying to get data that it cannot access.

deesto 05-27-2011 01:58 PM

Quote:

Originally Posted by H_TeXMeX_H (Post 4368843)
What is slowing it down is a bad HDD. Normally you could speed up dd by using a larger block size (-b), but I'm not sure that will help here, because it just keeps re-trying to get data that it cannot access.

Right. Should I cut out the retries? Is there anything I can do to stop the bad block splitting and just start working on the data that's present in the image file? Or do you think it's just SOL at this point?

BTW, the separate `dd` I mentioned earlier is still running, has been running for a few days, and is at 6 GB out of a 140+GB partition with no visible I/O records. I'm either running out of time or completely out.

H_TeXMeX_H 05-27-2011 02:23 PM

If dd no longer has I/O, the drive may be dead. However, maybe ddrescue can still recover something, because it is more resilient to errors. Any I/O with ddrescue ? If not, the drive is dead. Next time backup and run scheduled SMART long tests.

deesto 05-27-2011 04:00 PM

Quote:

Originally Posted by H_TeXMeX_H (Post 4368865)
If dd no longer has I/O, the drive may be dead. However, maybe ddrescue can still recover something, because it is more resilient to errors. Any I/O with ddrescue ? If not, the drive is dead. Next time backup and run scheduled SMART long tests.

I'm now running a ddrescue in reverse, and it's running ok so far, so though the disk is on its last legs it's not quite dead, and the bad sectors must be at the beginning of the disk. That's still running now. But again, in case it ends up failing: is there anything I can do with the previous image file I'd created with ddrescue but was stuck in splitting block mode: can I recover anything from that image if the splitting mode doesn't get to finish running (and if so how)?

PTrenholme 05-27-2011 04:19 PM

For what it's worth, here's a script I keep around to help with reading old CDs.
Code:

#!/bin/bash
if [ -e $1.iso ]
then
  echo \"$1\" already exists. Please chose a different name.
  exit 1
fi
echo WARNING: The following commands may take several days to run . . .
echo ddrescue -nv -b2048 /dev/sr0 $1.iso $1.log
ddrescue -nv -b2048 /dev/sr0 $1.iso $1.log
echo ddrescue -dv -b2048 /dev/sr0 $1.iso $1.log
ddrescue -dv -b2048 /dev/sr0 $1.iso $1.log
sudo mount -t iso9660 -o ro,defaults,loop $1.iso /mnt
cp --nopreserve=mode /mnt/* $2
sudo umount /dev/loop0
chmod -R u=rwx $2

The 2048 block size is fairly specific to the ISO9660 format, but the rest might be relevant.

H_TeXMeX_H 05-28-2011 04:26 AM

Quote:

Originally Posted by deesto (Post 4368929)
I'm now running a ddrescue in reverse, and it's running ok so far, so though the disk is on its last legs it's not quite dead, and the bad sectors must be at the beginning of the disk. That's still running now. But again, in case it ends up failing: is there anything I can do with the previous image file I'd created with ddrescue but was stuck in splitting block mode: can I recover anything from that image if the splitting mode doesn't get to finish running (and if so how)?

You still can probably carve some data out of that part, but probably no partitions or anything. You can try to leave it running, but it may take too long.

deesto 05-31-2011 08:55 AM

I left ddrescue running over the long weekend and after getting through about 5 GB (of a 160 GB disk and ~140 GB partition), it looks like it's pretty much leveled out at 0 B/s. Unless someone has any ideas on what to try (including any available desperate measures), I guess the disk is dead.

H_TeXMeX_H: how would you go about getting any possible available data out of the somewhat incomplete partitions I'd managed to get from ddrescue earlier?

PTrenholme 05-31-2011 10:27 AM

If you're rich enough, there are companies that can do a good job recovering data from disks. I've never been able to afford them, so I can't suggest any. (The last time I looked, the "going rate" was ~$1000 just to look at your problem, and it went up from there to actually do anything about recovering the data.)

As a cheaper solution, I usually start ddrescue with the "fill from file", no retry, options to get an image with the problem areas filled in with zeros. Then I run foremost on the result to see what, if anything, I get.

Here's another script - again, for a simpler problem. In this case, I had a lot of floppy disks from which I wanted to recover what I could before I retired my last computer with a floppy disk drive installed. But look at the section I highlighted, where ddrescue first tries to image the disk. If that fails, it re-runs ddrescue, retrying each bad spot three times in both the forward and reverse directions, and then zero-fills any remaining bad spots. A similar strategy might get you farther along.
Code:

#!/bin/bash
#############################################################################
#
# Copy the contents of a floppy disk to a sub-directory of Documents
# called Floppy/<Label> where <label> is the disk label. If the disk is
# not labeled, the contents will be copied to "disk_n" where n is incremented
# by one from the last floppy so copied.
#
# Empty floppies will be skipped.
#
#############################################################################
#
# Function to print help message
#
help()
{
  cat <<EOF >>/dev/stderr

$0:        {-h | --help} : Print this message and exit.
                {-o | --output_directory } : Parent directory for output. (Default: $(pwd))
                {-i | --image=}image_file_name : Use floppy image (Wild cards permitted.)
                {-r | --read=}device_name : Read from device (Default: /dev/fd0)

Input options may be repeated as often as wished.

EOF
  exit $1
}
########################
#
# Get or create the output directory
getOutputDir()
{
# Argument: $1=device or image name
# Get the label text, if any
  label=$(echo "$(dosfslabel ${1})" | sed 's/^[[:space:]]//;s/[[:space:]]*$//')
  [ -z "$label" ] && label="Floppy"
  [ "$label" = "NO NAME" ] && label="Floppy"
  [ "$label" = "(null)" ] && label="Floppy"
# See if the label has alread been used
  [ -z "${dir}" ] && dir="$(pwd)"
  ret="${dir}/${label}"
# Create the output directory
  if [ -d "${ret}" ] || [ "$label" = "Floppy" ];then
    [ -d "${ret}" ] && mv "${ret}" "${ret}_0"
    n=0
    while [ -d "${ret}_${n}" ]
    do
      n=$(($n + 1))
    done
    ret="${ret}_${n}"
  fi
  mkdir -p "${ret}"
# Return the output directory name
  echo "${ret}"
}
########################
#
# Return Y or N
#
# Arguments: $1 = Question
#            $2 = Default answer (Must be "Y" or "N")
ask_yes_no()
{
  [ "${2}" != "Y" ] && [ "${2}" != "N" ] && echo $0: Default must be \"Y\" or \"N\" > /dev/stderr && exit 2
  if [ $2 = Y ]; then
    question="${1} (Y/n)"
  else
    question="${1} (y/N)"
  fi
  read -p "${question}" resp
  echo "${resp}" |sed 's/^[[:space:]]*$/'$2'/;s/^[[:space:]]*//;s/^[nN].*$/N/;s/^[yY].*$/'$2'/'
}
########################
#
# Copy from an input device
#
copy_from()
{
  device="${1}"
  fini="Y"
  while [ "${fini}" = "Y" ]
  do
    out="$(getOutputDir "${device}")"
# Use ddrescue to create an image of the floppy disk
    image="${out}/disk.img"
    log="${out}/disk.log"
    echo
    echo "Creating ${image} from ${device}."
    echo ddrescue -nb 1024 "${device}" "${image}" "${log}"
    ddrescue -nb 1024 "${device}" "${image}" "${log}"
    if [ $? -ne 0 ]
    then
      echo ddrescue -nb 1024 "${device}" "${image}" "${log}" failed.
      echo Removing "${image}", "${log}" and "${out}"
      [ -e "${image}" ] && rm -f "${image}"
      [ -e "${log}" ] && rm -f "${log}"
      [ -e "${out}" ] && rm -rf "${out}"
    else
      if [ -n "$(grep "-" "${log}")" ]
      then
        echo ddrescue -dr 3 "${device}" "${image}" "${log}"
        ddrescue -dr 3 "${device}" "${image}" "${log}"
        echo -n 0$'\x00' > zero
        [ -n "$(grep "-" "${log}")" ] && echo "ddrescue --fill=- zero "${image}" "${log}"" && ddrescue --fill=- zero "${image}" "${log}"
        rm -f zero
      fi

      echo Copying the contents of \"${image}\" to \"${out}/\"
      opt="ro,users"
      [ -f "${image}" ] && opt="loop,${opt}"
      sudo mount -t vfat "${image}" /mnt/floppy -o $opt
      stat /mnt/floppy/* &>/dev/null
      if [ "$?" -ne 0 ]
      then
        echo "Failed to mount ${image} as a FAT file system."
      else
        cp -rbv /mnt/floppy/* "${out}"
        sudo umount /mnt/floppy &>/dev/null
      fi
    fi
    if [ -b "${device}" ]
    then
      echo "Remove the floppy disk from the drive. Insert the next one, if any."
      fini=$(ask_yes_no "Continue?" Y)
      [ "${fini}" != "Y" ] && break
    else
      break
    fi
  done
}
#############################################################
#
# Main Program
#
#########################
#
# Make sure that the mount point exists
[ -d /mnt/floppy ] || sudo mkdir -p /mnt/floppy
#########################
#
# Parse the arguments
#
dir="$(pwd)"
temp=$(getopt -n $0 -oho:i::r: -lhelp -loutput_directory -limage -lread -- "$@")
[ $? -ne 0 ] && help 1
eval set -- "$temp"
while true
do
  case "$1" in
    -h|--help)
        help 0;;
    -o|--output_directory)
        dir=$(dirname "$2"/./)
        shift 2
        if [ -d "$dir" ]
        then
          echo Output will be created in "$dir"
        else
          mkdir -p "$dir"
          [ $? -ne 0 ] && echo Could not create directory "$dir" > /dev/stderr && exit 3
          echo Output will be created in "$dir"
        fi;;
    -r|--read)
        case "$2" in
            "") shift;
                copy_from /dev/fd0;;
            *) device="$2";
                shift 2;
                copy_from $device;;
        esac;;
    --) shift;
        break;;
    *) echo "Internal setopt error! ("$@")" >> /dev/stderr;
      exit 1;;
  esac
done
if [ $# -ne 0 ]
then
  echo $0: $# unrecognized arguments: \""$@"\" >> /dev/stderr
  echo >> /dev/stderr
  help 2
fi
exit 0

Note: I'm working on a Win 7 system right now, so, if you copy from that code block, you might find that your file is in MSDOS format, not UNIX. (I.e., contains unneeded \r characters.)

onebuck 05-31-2011 11:09 AM

Moved: This thread is more suitable in <General> and has been moved accordingly to help your thread/question get the exposure it deserves. Not a Gnu/Linux hardware issue. Sure Data recovery utilizing Gnu/Linux tools on a Microsoft Vista OS disk. Most posts of this type will be moved to General.

onebuck 05-31-2011 11:10 AM

@OP to edit title you can edit in Advanced mode.

H_TeXMeX_H 05-31-2011 02:13 PM

Quote:

Originally Posted by deesto (Post 4371860)
I left ddrescue running over the long weekend and after getting through about 5 GB (of a 160 GB disk and ~140 GB partition), it looks like it's pretty much leveled out at 0 B/s. Unless someone has any ideas on what to try (including any available desperate measures), I guess the disk is dead.

H_TeXMeX_H: how would you go about getting any possible available data out of the somewhat incomplete partitions I'd managed to get from ddrescue earlier?

If ddrescue is at 0 IO then the drive is dead. So, now you can use testdisk and/or foremost to carve out data. Only testdisk care recover partitions, so you can try that first, even tho it probably won't work.


All times are GMT -5. The time now is 04:41 PM.