среда, 1 января 2014 г.

Восстановление WD My Book Live с сохранением данных

Часть 1. Подготовка.
  1. Скачать отсюда образ UBUNTU Live CD (или использовать другой debian-подобный linux). Записать его на CD или изготовить загрузочную флешку.
  2. Разобрать  MBL, и достать из него жесткий диск.
  3. Подключить жесткий диск к материнской плате вашего компьютера.


Часть 2. Процедура.

  1. Загружаемся с UBUNTU Live CD.
  2. После того, как Ubuntu Linux загрузился, следует настроить интернет. У меня он настроился автоматом, так как в роутере ip-адреса раздаются по DHCP.
  3. Открываем эту статью и копируем код скрипта ниже. В домашнем каталоге /home/ubuntu/ создаем новый документ (правый клик мышью, в контекстном меню: Create New Document —> Empty Document). Даем имя документу: debricker.sh, открываем и вставляем туда содержимое, которое мы скопировали. Сохраняем и закрываем. (В принципе код скрипта можете заранее приготовить на флешке и сохранить в Блокноте, но файл debricker.sh нужно создавать принципиально в Linux’е, иначе он не запустится!)

Дайте новому документу имя debricker.sh
Вставьте скопированное содержимое в файл debricker.sh





#!/bin/bash
#
# The purpose of the script is to reinstall the operating system (debrick) on
# a harddrive that has been extracted from the housing of a WD MyBook Live.
#

#help screen
if [ $# = 1 -a "$1" = "--help" ]; then
echo "
standard use of script is:
sudo ./debricker.sh the script will find out what disk to use, it will not
touch the partition tables and therefore perserves data.
it will look what the newest version of the firmware is
via internet and then search for it in current folder or
subfolders. if none is found it will download one.

possible options are:
/dev/sd? path to the disk from mybook live. if not given, the script
will figure it out on its own.
/*/*.img path to the firmware that will be written to the disk. if
not given, the script will search for and then download it.
destroy script will rewrite the partition table of disk,
this will not perserve data, must match /dev/sd?.

example
sudo ./debricker.sh /dev/sda /firmwares/mine.img destroy
"
exit 1
fi

echo

#check that requirements are fullfilled
if [ "$(id -u)" != "0" ]; then
echo -e "this script must be run as root.\n"
exit 1
fi
if ! which mdadm > /dev/null; then
echo -e "this script requires the mdadm package.\n"
exit 1
fi

#making sure the mountpoint is available
rootfsMount=/mnt/md0
if [ -e ${rootfsMount} ]; then
if mountpoint -q ${rootfsMount}; then
echo "${rootfsMount} needs to be unmounted."
exit 1;
fi
fi
test -d "./mnt" || mkdir -p "/mnt"
test -d "$rootfsMount" || mkdir -p "$rootfsMount"

#making sure that there is no raid unit running
rootfsRaid=/dev/md0
if [ -e $rootfsRaid ]; then
echo -e "\n$rootfsRaid already exists! you need to stop and remove it.\n"
exit 1;
fi

#standard choices
disk=notset
image_img=notset
destroy=false

#handles the arguments and sets options
for (( arg=1; arg<=${#}; arg++ ))
do
case ${!arg} in
/dev/sd?) disk=${!arg};;
*.img) image_img=${!arg};;
"destroy") destroy=true;;
*) echo "unknown argument: ${!arg}"
exit 1
esac
done

echo "********************** DISK **********************"
echo

#figure out what disk to use
if [ $disk = "notset" ]; then
for x in {a..z}
do
#avoid a to literal matching in order to avoid incompability.
if [ -e /dev/sd${x} ]; then
diskTest=$(parted --script /dev/sd${x} print)
if [ ! -e /dev/sd${x}0 -a ! -e /dev/sd${x}5 ]; then
if [[ $diskTest = *WD??EARS* ]]; then
if [[ $diskTest = *??00GB* ]]; then
if [[ $diskTest = *3*B*B*5??MB*primary* ]]; then
if [[ $diskTest = *1*B*B*2???MB*ext3*primary*raid* ]]; then
if [[ $diskTest = *2*B*B*2???MB*ext3*primary*raid* ]]; then
if [[ $diskTest = *4*B*B*GB*ext4*primary* ]]; then
if [ $disk != notset ]; then
echo "multiple disk founds, you must enter the path manually:"
echo " sudo ./debricker.sh /dev/sd?"
exit 1;
fi
disk=/dev/sd${x}
fi; fi; fi; fi; fi; fi; fi; fi
done

if [ $disk == notset ]; then
echo "script could not find a matching sd unit connected to system."
exit 1
fi
else
if [ ! -e $disk ]; then
echo "$disk does not exist."
exit 1;
fi
fi

echo -e "script will use the following disk: \n"
parted --script $disk print
read -p "is this REALLY the disk you want? [y] " -n 1
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "\nuser did not confirm, nothing was done.\n"
exit 1;
fi
echo
diskRoot1=${disk}1
diskRoot2=${disk}2
diskSwap=${disk}3
diskData=${disk}4

echo
echo "********************** IMAGE **********************"
echo

#the image was not given as parameter
if [ $image_img = notset ]; then
#find out what the latest version of firmware is
if ! which curl > /dev/null; then
echo -e "\nthis script requires the curl package, either install it or specify image file.\n"
exit 1
fi
wdc_homepage="http://websupport.wdc.com/firmware/list.asp"
wdc_latestfirmware=$(curl "${wdc_homepage}?type=AP1NC&fw=01.03.03" 2> /dev/null | awk ' {
if ( match($0, "upgrade file" ) != 0 ) {
split($0, http, "\"");
print http[2];
exit 1;
}
}')
latestversion_simple=$(echo $wdc_latestfirmware | cut -d'-' -f 2)
latestversion_pattern=$(echo $latestversion_simple | sed 's/../&*/g;s/:$//')
if [ "$latestversion_simple" == "" -o "$latestversion_pattern" == "" ]; then
echo -e "\ncould not fetch the latest version!\n"
exit 1;
fi
echo "checking: ${latestversion_simple}"
echo "searching: ./*/*${latestversion_pattern}.img"
image_img=$(find ./ -type f -name "*${latestversion_pattern}.img" -print; 2>/dev/null)

#get the latest firmware either from subdirs or internet
case `echo $image_img | wc -w` in
0) echo "searching: ./*/*${latestversion_pattern}.deb"
test -d "./firmware" || mkdir -p "./firmware"
image_deb=$(find ./ -type f -name "*${latestversion_pattern}.deb" -print; 2>/dev/null)
image_img="./firmware/rootfs_$latestversion_simple.img"
if ! [ `echo $image_deb | wc -w` == 1 ]; then
image_deb="./firmware/rootfs_$latestversion_simple.deb"
echo
echo "downloading: $image_deb"
read -p "confirm [y]: " -n 1
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
echo
curl $wdc_latestfirmware > $image_deb
if [ $? != 0 ]; then
echo -e "\ndownloading encountered problems.\n"
exit 1;
fi
fi
echo
echo "will extract: $image_deb"
read -p "confirm [y]: " -n 1
echo
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
echo "extracting: ./firmware/rootfs_${latestversion_simple}.img"
ar p $image_deb data.tar.lzma | unlzma | tar -x -C ./firmware
if [ $? != 0 ]; then
echo -e "\nextraction encountered problems.\n"
exit 1;
fi
mv ./firmware/CacheVolume/upgrade/rootfs.img ./firmware/rootfs_${latestversion_simple}.img
rm -rf ./firmware/CacheVolume;;
1) echo "found: $image_img";;
*) echo -e "\nmultiple image_img files was found."
exit 1
esac
else
if [ ! -e $image_img ]; then
echo "$image_img does not exist."
exit 1;
fi
fi

#construct the swap program
echo "\
#include
#include
#include
#include
#include

#define MD_RESERVED_BYTES (64 * 1024)
#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)

#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS)

main(int argc, char *argv[])
{
int fd, i;
unsigned long size;
unsigned long long offset;
char super[4096];
if (argc != 2) {
fprintf(stderr, \"Usage: swap_super device\\n\");
exit(1);
}
fd = open(argv[1], O_RDWR);
if (fd<0 data-blogger-escaped-0="" data-blogger-escaped-0ll="" data-blogger-escaped-4096="" data-blogger-escaped-512ll="" data-blogger-escaped-and="" data-blogger-escaped-argv="" data-blogger-escaped-blkgetsize="" data-blogger-escaped-char="" data-blogger-escaped-counters="" data-blogger-escaped-cp_events_hi="" data-blogger-escaped-cp_events_lo="" data-blogger-escaped-events="" data-blogger-escaped-events_hi="" data-blogger-escaped-events_lo="" data-blogger-escaped-exit="" data-blogger-escaped-fd="" data-blogger-escaped-for="" data-blogger-escaped-i="" data-blogger-escaped-if="" data-blogger-escaped-ioctl="" data-blogger-escaped-lseek64="" data-blogger-escaped-offset="" data-blogger-escaped-perror="" data-blogger-escaped-read="" data-blogger-escaped-size="" data-blogger-escaped-super="" data-blogger-escaped-swap="" data-blogger-escaped-t="" data-blogger-escaped-the="" data-blogger-escaped-u64="" data-blogger-escaped-write="">./swap.c
gcc swap.c -o swap
rm swap.c

echo
echo "********************** IMPLEMENTATION **********************"

echo -e "
everything is now prepared!
device: $disk
image_img: $image_img
destroy: $destroy\n"

read -p "this is the point of no return, continue? [y] " -n 1
echo
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
exit 1;
fi
echo

#rewrite the partition table
if [ $destroy = true ]; then
backgroundPattern="${backgroundPattern:-0}"

dd if=/dev/zero of=$diskRoot1 bs=1M count=32
dd if=/dev/zero of=$diskRoot2 bs=1M count=32
dd if=/dev/zero of=$diskSwap bs=1M count=32
dd if=/dev/zero of=$diskData bs=1M count=32
badblocks -swf -b 1048576 -t ${backgroundPattern} ${disk} 16 0

sync
sleep 2

parted $disk --align optimal < $rootfsMount/etc/nas/service_startup/ssh sync
sync
sync
umount $rootfsMount
rmdir $rootfsMount
mdadm --stop $rootfsRaid
./swap $diskRoot1
./swap $diskRoot2
rm ./swap

echo
echo "all done! device should be debricked!"
echo



  1. Теперь нужно запустить терминал. В верхнем правом углу нажимаем значок Ubuntu. В появившемся окне в строке поиска набираем terminal, ниже появится ярлык, который и следует запустить (достаточно одного клика)
  2. Далее нам нужно получить права «суперадмина». Набираем в консоли:
    sudo -i
  3. Запускаем скрипт. Набираем в терминале:
    bash /home/ubuntu/debricker.sh
  4. Скрипт должен автоматом найти жесткий диск MBL и если нет никаких проблем, то попросит согласие на запуск, на что мы жмем клавишу “Y”. В процессе будет загружена последняя прошивка с оффсайта, так же у вас несколько раз спросят согласие, где вы должны нажать вышеуказанную клавишу. Все должно кончиться сообщением: “all done! device should be debricked!”, что значит, процедура раскирпичивания прошла успешно.
  5. Выключаем компьютер, снимаем жесткий диск и возвращаем на место. Запускаем MBL, настраиваем и радуемся жизни:).
Часть 3. F.A.Q.
Вопрос: При запуске скрипта выводится сообщение: “this script requires the mdadm package, either install it or specify image file” или “this script requires the curl package, either install it or specify image file”.
Ответ: Не установлены пакеты mdadm и curl. В терминале нужно набрать следующую команду (требуется интернет):
apt-get install mdadm
apt-get install curl
Вопрос: В процессе работы скрипта выводится сообщение о нехватке места.
Ответ: Скачать прошивку с оффсайта или здесь, распаковать файл rootfs.img с помощью 7-zip в Windows или встроенным архиватором в Linux на флешку. В терминале запустить скрипт с указанием пути до распакованной прошивки:
bash /home/ubuntu/debricker.sh /media/storage/rootfs.img
Вопрос: При запуске скрипта выводится сообщение: «script could not find a matching sd unit connected to system»
Ответ: Добавьте к команде запуска скрипта путь к диску, предварительно определив его командой fdisk -l, пример ниже (где знак «вопроса» подставляем букву, которую вы узнали с помощью команды fdisk -l):
bash /home/ubuntu/debricker.sh /dev/sd?
P.S. Хочу остановиться подробно на самом скрипте. Этим же скриптом можно установить прошивку, допустим если у вас полетел хард. Экспериментировал с хардом 160! гигабайт. Все встало отлично, правда места маловато будет :) . Процедура та же самая. Единственное, при запуске скрипта нужно добавить ключ destroy и явно указать жесткий диск, команда будет выглядеть примерно так:
bash /home/ubuntu/debricker.sh /dev/sd? /media/storage/rootfs.img destroy
Там где знак вопроса нужно указать соответствующую букву, которую можно узнать набрав в консоли fdisk -l, в таблице, которую выдаст программа, нужно найти свой хард и там же посмотреть букву.
На этом урок окончен, буду рад если данная статья поможет вам.
Подготовлен по материалам форума IXBT.com
Страница скрипта.

Оригинальная статья tandp.subankulov.com

1 комментарий: