Modern technology gives us many things.

Восстановление данных с M.2 NVMe SSD. Скрипт ddrescue-loop v0.2

66

Уровень сложности Простой Время на прочтение 13 мин Количество просмотров 12K Настройка Linux *Восстановление данных *Компьютерное железо Накопители DIY или Сделай сам Туториал

Речь пойдет о способе извлечения данных с неисправного SSD для случаев когда после попытки чтения любого сбойного сектора — SSD совсем перестает отдавать данные и помогает только отключение включение питания.

Представляю доработанную версию скрипта ddrescue-loop с поддержкой управления USB реле и uhubctl.

Для прерывания питания SSD задействовал простое и дешевое решение USB Relay Module LCUS-1 CH340 которые доступны на Aliexpress. И подключение через док станцию AgeStar 31CBNV1C на основе USB-NVMe моста JMicron JMS583.

Рассмотрим процесс восстановления на примере случая с неисправными M.2 NVMe SSD производства Kimtigo на контроллере Maxio MAP1202.

ddrescue-loop v0.2.1

ddrescue-loop v0.2.1

ddrescue-loop-v0.2.1.gz

#!/bin/sh #ddrescue-loop script writen by gumanzoy <gumanzoy@gmail.com> # Compatible only with Linux, not with other *nix! # Depends on udev /dev and sysfs /sys kernel interfaces # For SATA requires AHCI compatible motherboard # For all Intel and modern AMD platforms (AM4 and newer), check the UEFI Setup # SATA settings to ensure Port Hot Plug is enabled # For USB requires lsusb from usbutils package # And optional uhubctl for power off/on cycle # Or hardware USB Relay Module LCUS-1 CH340 # [RU] forum thread. Обсуждение # https://forum.ixbt.com/topic.cgi?id=11:47589-31 # /* This program is free software. It comes without any warranty, to # * the extent permitted by applicable law. You can redistribute it # * and/or modify it under the terms of the Do What The Fuck You Want # * To Public License, Version 2, as published by Sam Hocevar. See # * http://www.wtfpl.net/ for more details. */ VERSION=0.2.1 showhelp () { echo «ddrescue-loop v»»$VERSION»» перезапускает процесс ddrescue в случае его завершения» echo «Внимание следует соблюдать очередность аргументов» echo «Указывать ключи в произвольном порядке нельзя!» echo «Числовые значения аргументов обязательно через пробел» echo -n «n» echo «# —— SATA —— SATA —— SATA —— SATA —— SATA ——» echo «# Остановить/запустить диск на SATA порту:» echo «-ata <n> -stop»» «»остановить диск на SATA порту <n>» echo «-ata <n> -scan»» «»сканировать SATA порт <n>» echo -n «n» echo «# Запустить восстановление c SATA:» echo «ddrescue-loop -ata <n> [-loop <n>] [-pwc] [-wait <n>] [-act <n>] outfile mapfile [ddrescue options]» echo -n «n» echo «# Укажите номер SATA порта к которому подключен диск источник:» echo -n «-ata <n>»» «»Номер SATA порта <n> цифра (смотрите вывод dmesg)» echo -n «n»» «»#: «; ls /sys/class/ata_port echo -n «n» echo «# Функция циклической остановки/перезапуска диска на SATA порту:» echo «-loop <n>»» «»<n> предельное число попыток» echo -n «n» echo «# Таймер ожидания остановки/перезапуска диска:» echo «-wait <n>»» «»Время в секундах <n> [10]» echo -n «n» echo «# Переопределить таймаут ожидания исполнения ATA команд:» echo «-act <n>»» «»Время в секундах <n> [30]» echo -n «n» echo «# —— USB —— USB —— USB —— USB —— USB ——» echo «# Отключить/включить питание USB устройства <ID>, методом <hub/rle>:» echo «-usb <ID> -pwc hub»» «»Использовать uhubctl —search <ID>» echo «-usb <ID> -pwc rle»» «»Использовать USB реле LCUS-1 CH340 RLETTY=»»$RLETTY» echo -n «n» echo «# Запустить восстановление c USB:» echo «ddrescue-loop -usb <ID> [-loop <n>] [-pwc <hub/rle>] [-wait <n>] outfile mapfile [ddrescue options]» echo -n «n» echo «# Укажите Hex идентификаторы VID:PID USB устройства источника:» echo «-usb <ID>»» «»<VID:PID> через двоеточие (смотрите вывод lsusb)» echo -n «n» echo «# Функция циклического перезапуска ddrescue:» echo «-loop <n>»» «»<n> предельное число попыток» echo -n «n» echo «# Основные:» echo «outfile»» «»Устройство приемник данных / файл образа» echo «mapfile»» «»ddrescue map/log файл (обязательно)» echo -n «n» echo «# В конце после mapfile можно указать опции запуска ddrescue через пробел» echo «# Поддержка зависит от версии. Полный список опций в мануале. Важные:» echo «-P [<n>]»» «»Предпросмотр данных [число строк] по умолчанию 3» echo «-b 4096″» «»<bytes> размер сектора (физического блока) [default 512]» echo «-c <n>»» «»Размер кластера <n> секторов за раз [default 128]» echo «-O»» #Рекомендую! «»После каждой ошибки заново открывать файл устройства» echo «-J»» #Опционален «»При ошибке перечитать последний не сбойный сектор» echo «-r <n> #ИЛИ -r -1″» «»<n> число повторных проходов до перехода к trim» echo «-m <domain.mapfile>»» «»Ограничить область чтения доменом <file> ddru_ntfsbitmap» } get_ata_host () { until SCSIHOST=`readlink -f /sys/class/ata_port/ata»$1″/device/host?/scsi_host/host?/` && test -d «$SCSIHOST»; do sleep 1; done } get_ata_target () { until SYSFSTGT=`readlink -f /sys/class/ata_port/ata»$1″/device/host?/target?:?:?/?:?:?:?/` && test -d «$SYSFSTGT»; do sleep 1; done } get_ata_dev () { until INDEV=`readlink -f /dev/disk/by-path/pci-*-ata-«$1″` && test -b «$INDEV»; do sleep 1; done } device_delete () { while test -f «$SYSFSTGT»/delete; do echo 1 > «$SYSFSTGT»/delete; sleep 1; done } get_usb_dev_by_path () { INDEV=»/dev/»`basename «$1″` SYSFSTGT=»$1″»/device/» } get_usb_dev_by_id () { IDVID=`echo -n «$1» | cut -d «:» -f1` IDPID=`echo -n «$1» | cut -d «:» -f2` until get_usb_dev_by_path `udevadm trigger -v -n -s block -p ID_VENDOR_ID=»$IDVID» -p ID_MODEL_ID=»$IDPID»` && test -b «$INDEV»; do sleep 1; done } power_cycle () { if [ -n «$USBID» ] && [ «$PWRCTL» = hub ]; then uhubctl —search «$USBID» —action cycle —delay «$LOOPWAIT» elif [ «$PWRCTL» = rle ]; then /bin/echo -en «xA0x01x01xA2» > «$RLETTY» && sleep «$LOOPWAIT» && /bin/echo -en «xA0x01x00xA1» > «$RLETTY» fi } if [ «$1» = «-h» -o «$1» = «—help» ]; then showhelp exit; fi if [ «`whoami`» != «root» ]; then echo Exit. This script should be run as root ! exit 1; fi if [ -z «$RLETTY» ] && test -c /dev/ttyUSB0; then RLETTY=»/dev/ttyUSB0″ elif [ -n «$RLETTY» ] && ! test -c «$RLETTY»; then echo «RLETTY=»»$RLETTY»» control device not found»; exit 1; fi if [ -n «$1» ] && [ «$1» = «-ata» ]; then if [ -n «$2″ ] && test -d /sys/class/ata_port/ata»$2″; then SATAP=»$2»; get_ata_host «$SATAP»; shift; shift else echo -n «Please enter correct port number: «; ls /sys/class/ata_port; exit 1; fi fi if [ -n «$1» ] && [ «$1» = «-stop» ] && [ -n «$SATAP» ]; then get_ata_target «$SATAP»; device_delete; exit; fi if [ -n «$1» ] && [ «$1» = «-scan» ] && [ -n «$SATAP» ]; then echo ‘0 0 0’ > «$SCSIHOST»/scan; exit; fi if [ -n «$1» ] && [ «$1» = «-usb» ] && [ -z «$SATAP» ]; then if [ -n «$2» ] && lsusb -d «$2″; then USBID=»$2»; get_usb_dev_by_id «$USBID»; shift; shift else echo «Please enter correct USB Device ID:» lsusb | cut -d «:» -f2,3 | grep -vi hub exit 1; fi fi if [ -n «$1» ] && [ «$1» = «-loop» ]; then if [ -n «$2» ] && [ «$2″ -gt 0 ]; then DDLOOP=»$2»; shift; shift; fi else DDLOOP=0 fi if [ -n «$1» ] && [ «$1» = «-pwc» ]; then if [ -n «$USBID» ] && [ -n «$2» ] && [ «$2» = «hub» -o «$2» = «rle» ]; then PWRCTL=»$2″; echo «PWRCTL=»»$2»; shift; shift elif [ -n «$RLETTY» ]; then PWRCTL=»rle»; echo «PWRCTL=rle»; shift; fi fi if [ -n «$1» ] && [ «$1» = «-wait» ]; then if [ -n «$2» ] && [ «$2″ -gt 0 ]; then LOOPWAIT=»$2»; shift; shift; fi else LOOPWAIT=10 fi if [ -n «$1» ] && [ «$1» = «-act» ]; then if [ -n «$2» ] && [ «$2″ -gt 0 ]; then ATACMDT=»$2»; shift; shift; fi fi if [ -n «$RLETTY» ] && [ «$PWRCTL» = rle ]; then stty -F «$RLETTY» 9600 -echo && echo «RLETTY=»»$RLETTY»; fi if [ «$DDLOOP» = 0 ]; then if [ -n «$USBID» ] && [ «$PWRCTL» = hub ]; then power_cycle; exit elif [ -n «$RLETTY» ] && [ «$PWRCTL» = rle ]; then power_cycle; exit; fi fi if [ -z «$SATAP» ] && [ -z «$USBID» ]; then showhelp exit; fi OUTFILE=»$1″; shift MAPFILE=»$1″; shift DDOPTS=»$@» DONE=X LOOPCOUNT=0 until [ «$DONE» = 0 ]; do if [ -n «$SATAP» ]; then get_ata_target «$SATAP»; get_ata_dev «$SATAP» elif [ «$LOOPCOUNT» -gt 0 ] && [ -n «$USBID» ]; then get_usb_dev_by_id «$USBID» fi if [ -n «$ATACMDT» ]; then echo «$ATACMDT» > «$SYSFSTGT»/timeout fi echo ddrescue «-fd» «$INDEV» «$OUTFILE» «$MAPFILE» «$DDOPTS» ddrescue «-fd» «$INDEV» «$OUTFILE» «$MAPFILE» $DDOPTS DONE=»$?» if [ «$DONE» != 0 ] && [ «$DDLOOP» -gt 0 ]; then device_delete & sleep «$LOOPWAIT» if [ -n «$PWRCTL» ]; then power_cycle elif [ -n «$SATAP» ]; then while test -d «$SYSFSTGT»; do sleep «$LOOPWAIT»; done; fi if [ -n «$SATAP» ]; then sleep «$LOOPWAIT» echo ‘0 0 0’ > «$SCSIHOST»/scan; fi DDLOOP=$(($DDLOOP-1)) LOOPCOUNT=$(($LOOPCOUNT+1)) echo «n33[1mDDLOOP #»»$LOOPCOUNT»; tput sgr0 date; echo -n «n» sleep «$LOOPWAIT» else DONE=0 fi done

Читать на TechLife:  Nvidia не против заполучить третьего партнёра для производства своих GPU, и это намёк на Intel

Восстановление данных с M.2 NVMe SSD. Скрипт ddrescue-loop v0.2

This program is free software. It comes without any warranty, to the extent permitted by applicable law. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2

Как пользоваться. Параметры запуска

Использование с SATA устройствами разобрано в моей первой статье. Если не читали, то рекомендую сначала ознакомится с ней.

Так как я не слишком искушен в sh скриптинге, и вообще не программист — с разбором параметров особо не мудрствовал. Поэтому есть некоторые важные ограничения!

Следует соблюдать очередность аргументов. Указывать ключи в произвольном порядке нельзя!
Числовые значения аргументов обязательно через пробел.

ddrescue-loop -usb <ID> [-loop N] [-pwc <hub/rle>] [-wait N] outfile mapfile [ddrescue options]

Укажите Hex идентификаторы VID:PID USB устройства источника:
-usb <ID> VID:PID через двоеточие (смотрите вывод lsusb)

Функция циклической остановки/перезапуска ddrescue:
-loop N Предельное число попыток N целое число. Указывать обязательно.

Функция прерывания питания устройства:
-pwc hub Использовать uhubctl —search <ID>
-pwc rle Использовать USB реле LCUS-1 CH340

Таймер ожидания остановки/перезапуска диска:
-wait N Время в секундах. 10 по умолчанию.

В конце после mapfile можно указать опции запуска ddrescue. Их обрабатывает уже сама ddrescue, можно указывать все как обычно.

Демонстрация работы. Записи вывода терминала

Восстановление данных с M.2 NVMe SSD. Скрипт ddrescue-loop v0.2

https://asciinema.org/a/628786
Запись вывода терминала ddrescue-loop

Восстановление данных с M.2 NVMe SSD. Скрипт ddrescue-loop v0.2

https://asciinema.org/a/628787
Запись вывода терминала dmesg -Wt

При ошибке чтения сектора и после сообщений в dmesg
uas_eh_device_reset_handler start
uas_eh_device_reset_handler success
Device offlined — not ready after error recovery
I/O error, dev sdd, sector 8985600
Устройство перестает отдавать данные, процесс ddrescue завершается
Can’t reopen input file: No such device or address
Скрипт подает команду на включение реле, затем перезапускает ddrescue и чтение продолжается.

Как это работает

Так как имена устройств sda sdb sdc не постоянны и буква меняется в зависимости от очередности подключения к системе. Применил вот такое решение: скрипт принимает на вход ID VID:PID USB устройства источника. Их отображает lsusb. В скрипте код получает адрес блочного устройства /dev/sdX И делает это каждый раз после отключения питания диска перед перезапуском процесса ddrescue

Читать на TechLife:  Shazam спрогнозировал популярные песни на 2024 год

Восстановление данных с M.2 NVMe SSD. Скрипт ddrescue-loop v0.2

USB Relay Module LCUS-1 CH340

USB Relay Module LCUS-1 CH340
Вариант с USB Type-A
aliexpress.com/item/4001216792789.html
aliexpress.com/item/1005001993993906.html
Вариант с USB Type-C
aliexpress.com/item/1005004323626598.html
aliexpress.com/item/1005004347242232.html

Использование USB реле. Подразумевается подключение питания на USB/SATA диск через контакты реле COM и NC Чтобы в выключенном состоянии питание проходило. А при подаче команды на включение реле — питание отключалось. Скрипт управляет реле с помощью команд:

echo -en «xA0x01x01xA2» > «$RLETTY» sleep «$LOOPWAIT» echo -en «xA0x01x00xA1» > «$RLETTY»

По умолчанию RLETTY=/dev/ttyUSB0 можно переопределить передав переменную окружения перед запуском скрипта:
RLETTY=/dev/ttyUSB1 ddrescue-loop -pwc rle

Также добавил поддержку uhubctl. Теоретически можно использовать вместо реле, но у меня нет подходящего USB хаба. Возможно будет полезно для восстановления с флешек.
ddrescue-loop -usb <ID> -pwc hub

uhubctl —search «$USBID» —action cycle —delay «$LOOPWAIT»

Подключение реле к док станции

В док станции AgeStar 31CBNV1C есть переключатель для отключения питания. Я подключил реле вместо него.

Восстановление данных с M.2 NVMe SSD. Скрипт ddrescue-loop v0.2

Док станция AgeStar 31CBNV1C

У переключателя пять контактов. Крайние для крепления к плате. Припаиваться нужно ко второму и третьему слева. На фото отметил красным.

Выпаял переключатель совсем, впаял два провода, залудил обратные концы и убрал в термоусадку. Собрал док станцию обратно в корпус. Вот что получилось.

Восстановление данных с M.2 NVMe SSD. Скрипт ddrescue-loop v0.2

Док станция + реле

Непосредственно процесс восстановления

Данный раздел пишу в том числе в расчете на тех кто далек от Linux. Не уверен что у меня получится понятно объяснить, но попробую. По большей части все примечания такого рода убрал под спойлеры.

Использую ПК с GNU/Linux Debian 11 (еще не обновился до Debian 12 по причине лени).
Док станцию подключаю к USB3 порту. А к SATA подключено несколько 3.5″ жестких дисков.

Сохраняю образ в файл, на диск с файловой системой Ext4. Файл создается разреженный (sparse file) таким образом место расходуется только под фактический объем скопированного, а не под весь объем неисправного SSD. При этом файл монтирую в /dev/loopN это позволяет работать с ним так же как с физическим диском.

Для создания/подключения/отключения образов удобно использовать графический интерфейс gnome-disk-utility

gnome-disk-utility используется не только в среде Gnome. Зависимостей относительно не много.

Создавать образ нужно такого же или большего объема. Для того чтобы не ошибиться можно скопировать и указать размер диска в байтах (отображается в gnome-disks в правой панели вверху при выборе соответствующего диска).

В меню «гамбургер» пункт New Disk Image…, в открывшемся окне выбрать размер в байтах, вставить скопированное число в поле и удалить запятые. Указать имя и путь для сохранения. Нажать Attach new image…

Созданный образ подключится в свободный /dev/loopN в режиме чтение/запись. При выборе и подключении существующего файла образа он по умолчанию подключается в режиме только чтение. Не забывайте снимать галочку Set up read-only device

Если таблица разделов на SSD читается. То прежде чем запускать копирование можно построить файл домена с помощью утилиты ddru_ntfsbitmap (из состава ddrutility). Это позволяет для разделов с файловой системой NTFS ограничить объем копирования только занятым пространством.

К сожалению в случае с SSD это не позволяет ускорить процесс, а только экономит место под образ. Так как нули из не занятых блоков копируются на полной скорости и без ошибок. Сбойные же сектора располагаются там где были какие то файлы и именно на обработку диском ошибок тратится основная часть времени.

Создание файла домена с помощью ddru_ntfsbitmap

В приведенных ниже командах в /dev/sdX вместо X подставить соответствующую устройству букву (можно посмотреть в том же gnome-disk-utility).

Нужно создавать файл домена в привязке ко всему диску, а не к отдельному разделу. Поэтому нужно указывать в командах именно устройство /dev/sdX а не раздел /dev/sdXN

Для ddru_ntfsbitmap нужно вычислить и указать значение input offset (partition offset) ключ —inputoffset или коротко -i

Сначала нужно запустить sudo fdisk -l /dev/sdX
Найти в таблице нужный раздел NTFS, и скопировать значение из столбца Start
Затем запустить команду, куда вместо START подставить значение

sudo ddru_ntfsbitmap -i $((START*512)) -m mftdomain.map /dev/sdX domain.map

Будут созданы искомые файлы domain.map и mftdomain.map

А также еще несколько файлов, имена которых начинаются на __ (двойное нижнее подчеркивание). Они не нужны, их можно удалить.

Запуск процесса копирования

Скрипт ddrescue-loop для удобства запуска можно скопировать в /usr/local/bin/

Скопировать и выдать права на исполнение

sudo zcat ddrescue-loop-v0.2.1.gz > /usr/local/bin/ddrescue-loop sudo chmod +x /usr/local/bin/ddrescue-loop

Сначала в отдельном терминале запустить dmesg -Wt чтобы видеть что происходит с диском.

Читать на TechLife:  Как оптимизировать код на С для x86-процессоров: подсистема кэша и памяти, инструкции AVX-512

Запускать ddrescue-loop нужно с правами root. Также и dmesg, но только в дистрибутивах где по умолчанию включен kernel.dmesg_restrict=1 (Debian входит в их число). Для краткости команду sudo добавлять не буду, но она подразумевается.

ddrescue-loop -usb 152d:0583 -loop 9999 -pwc rle /dev/loopN mapfile.log -b 4096 -c 32 -O -J

Разберем приведенные параметры:

  • -usb 152d:0583 это ID VID:PID док станции (а точнее контроллера JMicron JMS583 USB-NVMe)
    Посмотреть список подключенных устройств можно запустив ddrescue-loop -usb

  • -loop 9999 -pwc rle предельное число попыток перезапуска в цикле и использовать USB реле.

  • /dev/loopN Где N заменить на соответствующую цифру. Предполагается что файл приемник создан и смонтирован (посмотреть можно в gnome-disk-utility)
    Вместо этого можете просто указать куда сохранить файл образ, тогда ddrescue создаст его сама.

  • mapfile.log имя ddrescue map/log файла указываем обязательно.

  • -b 4096 обязательно указываем реальный размер сектора (физического блока)
    По умолчанию 512 и это не соответствует современным накопителям как SSD так и HDD

  • -c 32 ограничиваем размер кластера (сколько секторов ddrescue будет пытаться читать за раз в обычном режиме до перехода к trimming). По умолчанию 128, а так как мы увеличили размер сектора то это уже чересчур.

  • -O обязательно указываем. Чтобы ddrescue после каждой ошибки пыталась заново открыть файл устройства. Это необходимо для того чтобы в случае невозможности дальнейшего чтения — процесс ddrescue завершался с ошибкой и скрипт задействовал метод остановки/перезапуска диска.

  • -J тоже указываем, это дополнительная проверка — при ошибке перечитывать последний не сбойный сектор.

Если создавали файл домена то первый проход запускаем с добавлением в конец строки запуска -m mftdomain.map
Затем когда вычитали весь MFT то читаем все остальные задействованные файловой системой сектора -m domain.map

Тонкая подстройка в процессе

Если останавливали ddrescue по Ctrl+C для изменения параметров то перед перезапуском можно задействовать реле или uhubctl (если используем хаб вместо реле)
ddrescue-loop -pwc rle или ddrescue-loop -usb <ID> -pwc hub

На начальном этапе можно (но не обязательно) стараться вычитывать в первую очередь крупные беспроблемные участки. Для этого можно перепрыгивать скопления бэдов, добавляя в конце опцию -i Например -i 30G если чтение в прямом направлении. И можно читать задом наперед, для этого указывать -R и -s Например -R -s 40G

ddrescue-loop -usb 152d:0583 -loop 9999 -pwc rle -wait 4 -act 23 /dev/loopN mapfile.log -b 4096 -c 32 -O -J -m domain.map

Здесь добавлены -wait 4 то есть уменьшен таймер ожидания с 10 до 4
-act 23 таймаут ожидания исполнения ATA команд уменьшен с 30 до 23

Эти параметры подбирал экспериментально для описываемого случая для того чтобы постараться уменьшить время ожидания пере-подключения при ошибках SSD.

Значение -act подбирал с оглядкой на кол-во сообщений uas_eh_device_reset_handler start uas_eh_device_reset_handler success в dmesg после каждого сбойного сектора. При 30 ядро успевало делать две попытки reset’a. При 22 уже три reset’a — а это выходит дольше. Оптимальным оказалось значение 23.

Когда основные стадии процесса вычитки завершены, то в режиме scraping для ускорения можно увеличить размер блока, при этом качество пострадает.
Например указать -b 16Ki -c 1 или -b 32Ki -c 1 вместо -b 4096 -c 32

Когда процесс близится к завершению

В данном случае вычитка одного SSD включая trimming заняла около 14 суток. Но scraping еще не завершен.

Восстановление данных с M.2 NVMe SSD. Скрипт ddrescue-loop v0.2

Промежуточный / на 98.51% финальный результат

Файловые системы с разделов получившегося образа можно монтировать средствами ядра Linux сразу из /dev/loopNpP, где P — номер раздела. Это можно делать с помощью gnome-disk-utility. При этом обязательно только в режиме чтения. Надежнее отключить образ и пере-подключить в режиме только чтение.

Но для улучшения результатов, поисков фрагментов MFT и файлов по сигнатурам лучше использовать специализированный софт. Из свободных TestDisk/PhotoRec.

Я уже давно пользуюсь Linux версией DMDE. К сожалению исходники закрыты, это платное ПО. Однако в бесплатной версии (только для личного не коммерческого использования) ограничено только кол-во одновременно восстанавливаемых файлов, но не их размер. Это отлично подходит для оценки возможности восстановления нужных файлов.

Использование такого ПО и разбор разных нюансов с этим связанных точно не поместится в данную статью. Да и мои знания об устройстве файловых систем совсем поверхностные.

Заключение

Восстановление в данном случае считаю успешным. Пользовательские файлы извлечены и читаются. Справедливости ради нужно заметить что не все конечно, но дальше пытаться выцарапывать вряд ли имеет смысл. Так как остались только проблемные области общим объемом 1.54GB и вполне возможно 90% из них не читаемые.

Надеюсь мой опыт и скрипт кому нибудь еще пригодятся. Думаю что потребности в восстановлении данных с SSD меньше не становится. Не забывайте напоминать пользователям о бэкапах.

Благодарю за внимание! И удачных экспериментов!

Теги:

  • ddrescue-loop
  • ddrescue
  • ssd
  • nvme
  • usb
  • linux

Хабы:

  • Настройка Linux
  • Восстановление данных
  • Компьютерное железо
  • Накопители
  • DIY или Сделай сам

Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку Задонатить
Источник

Оставьте ответ

Ваш электронный адрес не будет опубликован.

©Купоно-Мания.ру