IT
March 3, 2021

Бэкап usb флешки под linux (debian)

Статья перенесена из старого блога.

На так давно мне пришлось сделать бэкап usb флешки.

Поискав в интернете, я наткнулся на статьи по утилите dd. Попробовав её, я понял, что это не совсем правильно.

И решил вам рассказать о более действенном и правильном способе.

Сейчас я вам расскажу подробнее..

Правильный способ

Как вы наверное уже догадываетесь, добиться желаемого можно не одним и даже не двумя, остроумными и не очень способами, но правильнее и проще всего на мой взгляд, использовать утилиту ddrescue. Что существенно важно — имеется в виду GNU ddrescue, а не давно уже устаревший оригинал.

Она, также как и cp, занимается копированием файлов, но в случае нахождения ошибок, ddrescue не прервёт работу с радостным сообщением о том, что пациент скорее мёртв, чем жив, а запомнит место с ошибкой, чтобы вернуться к нему позже и попробовать прочитать заново. Теперь уже медленно и нежно.

Используется ddrescue следующим образом:
ddrescue <ключи> <файл который копируем> <новый файл, в который скопируем старый> <лог файл>

ddrescue не способна принимать входные данные с конвейра, или передавать на конвейр результат работы, что впрочем неудивительно. Возможность пропускать места с ошибками при первой итерации и возвращение к ним в последующих циклах подразумевает наличие файлов на выходе и входе.

Команда, которая выполнит операцию, аналогичную описанной выше, будет выглядеть так:

ddrescue /dev/sda2 win_c.img win_c.img.log

Кстати, в данный момент я молчаливо подразумеваю, что жёсткий диск, с которого мы снимаем копию более-менее исправен и фокусов не выкидывает. Если с диском есть серьёзные проблемы, то лучше предварительно ознакомиться с подробностями использования ddrescue, например тут. и применить эти знания при снятии образа.

Неправильный способ

Часто можно встретить рекомендации использовать для копирования файла устройства или раздела программу под названием dd. Как правило, для снятия образа предлагается сделать что-то вот такое:

dd if=/dev/sda2 of=win_c.img

Не делайте так! Хотя семантически подход верен (произойдёт копирование одного файла в другой), последствия могут быть очень печальны. Да, dd превосходит cp в том отношении, что при обнаружении ошибки cp прекратит работу, а dd не прекратит, но если на диске есть битые или просто плохо читаемые сектора, то dd будет продолжать попытки считать их содержимое пока из винчестера не повалит дым.

Да, у dd есть аргумент noerror, но при его использовании копирование может быть выполнено с ошибками, попыток восстановления которых предпринято не будет. ddrescue в аналогичной ситуации после первого прохода вернётся к пропущенным местам и попробует прочитать их маленькими кусочками. И оставит лог файл, с помощью которого можно будет продолжать попытки вычитать сбойные места в будущем.

Короче, используйте ddrescue. А если кроме dd ничего нет, не забывайте про аргумент noerror.

Описанная выше процедура может применяться например для того, чтобы сохранить образ диска с только что установленной операционной системой для последующего восстановления. Да, настоящий линуксоид так поступать не станет, но среди пользователей операционной системы с другим названием это достаточно распространённая практика. И для периодического вдумчивого ремонта регулярно ломающегося компьютера какой нибудь симпатичной девушки её смело могут применять даже любители пингвинов. А если девушек больше некоторого, сугубо индивидуального для каждого самоделкина, количества, то данный метод просто незаменим. Главное не перепутать названия файлов с образами.

Просмотр содержимого образа раздела (логического диска)

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

Итак, у нас уже есть образ, снятый с диска C: операционной системы Windows 7. Мы назвали образ win_c.img и хотим увидеть его содержимое в заранее созданной директории /mnt/win_c. Для этого надо ввести команду mount -o loop win_c.img /mnt/win_c.

Вот так можно убедиться, что образ, который вы собираетесь накатить на винчестер очередного розового ноутбука, является образом именного того диска C: который ожидается увидеть на данной конкретной машине. Ну, или можно просто скопировать с него файлы без которых никак нельзя обойтись и отправить этот образ во внешнюю тьму. А на ноутбук поставить последнюю Убунту или Федору.

But we can go deeper.

Просмотр содержимого образа физического диска

А вот с монтированием образа диска целиком всё не так просто. Ужасная правда состоит в том, что монтировать файлы из произвольного места файловой системы ядро не умеет и аргумент -o loop, команды mount, сигнализирует о том, что сначала надо связать образ с файлом виртуального устройства в директории /dev, и потом уже присоединить содержимое этого устройства к файловой системе.

Файлы виртуальных устройств создаются заранее (на этапе загрузки системы) и имеют названия loop0, loop1, loop2 и так далее по нарастающей.

Связать образ раздела с одним из этих файлов можно командой losetup. Команда mount из предыдущего раздела на самом деле эквивалентна следующим двум командам.

losetup /dev/loop0 win_c.img
mount /dev/loop0 /mnt/win_c

Но вот для того, чтобы посмотреть содержимое образа в котором есть несколько разделов, этого недостаточно. Дело в том, что если выполнить команду losetup для такого файла, то с устройством /dev/loop0 будет связан весь образ целиком. То есть это устройство будет эквивалентом /dev/sda, а нам нужны эквиваленты /dev/sda1 и /dev/sda2.

Обладатели свежих версий программы losetup (читай гентушники и арчеводы) могут выполнить losetup c аргументом --partscan, что приведёт к автоматическому созданию в директории /dev файлов, соответствующих разделам образа. То есть /dev/loop0p1, /dev/loop0p2 и так далее до самого горизонта. И вот уже эти файлы можно отдавать команде mount.

losetup --partscan /dev/loop0 drive.img
mount /dev/loop0p2 /mnt/win_c

Те же, кому не так повезло с дистрибутивом, могут воспользоваться программой kpartx, которая сделает то же самое, но положит файлы соотвествующие разделaм не в директорию /dev, а в директорию /dev/mapper, откуда их можно монтировать и просматривать.

kpartx -a /dev/loop0 drive.img
mount /dev/mapper/loop0p2 /mnt/win_c

But we can go even deeper than that…

Развёртывание образа на физический носитель

А теперь о том, как собственно накатить образ на другой диск. Как и раньше надо руководствоваться тем, что диски и разделы представлены в виде файлов. И если для снятия образа нужно было создать копию файла устройства или раздела, то для того, чтобы закатать этот образ обратно надо провести операцию копирования в обратную сторону. То есть вместо cp /dev/sda2 win_c.img написать cp win_c.img /dev/sda2. Ну и лучше помнить о советах, изложенных в руководстве по снятию образа. А именно пользоваться ddrescue и не пользоваться dd.

ddrescue --force win_c.img /dev/sda2 win_c_restore.img.log
Конечно следует помнить, что раздел в который мы восстанавливаем образ (в данном случае /dev/sda2) должен быть не меньше файла с образом. Eсли же раздел окажется больше этого файла, то проблем при восстановлении не будет, но в разделе останется неразмеченное пространство. И придётся либо смириться с этим фактом, либо увеличить размер файловой системы до размера раздела каким-нибудь специализированным софтом (увеличивать, впрочем, обычно гораздо проще и быстрее, чем уменьшать).

P.S. Если у вас загрузочная "флешка". То лучше воспользоваться утилитой бесплатной утилитой CloneZilla. Она делает полную копию раздела или диска, включая MBR (загрузочная область диска).

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