dd_rescue vs GNU ddrescue: зачем нужен клон, когда есть оригинал

    В статье Копирование разделов жёсткого диска средствами GNU/Linux: как обойтись загрузочной флешкой там, где раньше нужен был Акронис, я посоветовал для копирования потенциально испорченных дисков использовать GNU ddrescue, а не оригинал, который назвал устаревшим. Но в комментариях nerfur указал мне, что dd_rescue регулярно обновляется и умеет на лету сжимать данные для последующей передачи по ssh. Так как эта задача GNU ddrescue не под силу, слухи об устаревании dd_rescue как видно сильно преувеличены.

    Понятное дело — надо немедленно выяснить, чем современный вариант dd_rescue отличается от GNU ddrescue, что умеет и, возможно, убрать рекомендацию избегать использования оригинала из статьи. А также написать новую статью — про отличия этих двух программ, чем я и занялся.

    Для тех, кто хочет побыстрее узнать чем кончилось дело и не интересуется душераздирающими подробностями сразу скажу, что после изучения вопроса моё мнение не изменилось — я всё ещё рекомендую пользоваться GNU ddrescue, но теперь уже по другой, гораздо более вменяемой причине — GNU ddrescue сначала сохраняет хорошо читаемые области диска и уже потом приступает к остальным. dd_rescue этого не умеет by design.

    Историческая справка


    dd


    Традиционно для создания бинарных копий физических накопителей в *nix системах использовалась программа dd, читавшая диск кусками заранее заданного размера. Она хорошо справлялась с задачей, когда речь шла о копировании данных с исправных устройств, но за обращение с частично неисправными дисками dd заслуженно получила прозвище disk destroyer.

    dd_rescue


    Для снятия данных с повреждённой поверхности Kurt Garloff написал утилиту, которая работала примерно как dd, но при встрече с битыми секторами не зачитывала диск до смерти и не игнорировала ошибки, а, уменьшив скорость до минимально возможной, спасала всё, что можно спасти.

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

    Кроме того, во время медленного и вдумчивого чтения дышащих на ладан секторов все остальные (нормально читаемые на момент запуска программы) вполне могли отбросить копыта, потому что пришло их время. Если бы их прочитали минутой или двумя раньше — всё бы было хорошо, а так — момент упущен — такое случается.

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

    dd_rhelp


    Как известно если гора не идёт к Магомету, то Магомет вполне может подойти к ней самостоятельно. Я думаю, как-то так и рассуждал LAB Valentin, когда принял решение написать баш скрипт, использующий dd_rescue для реализации оптимальной стратегии копирования повреждённых файлов.

    В конце концов автор dd_rescue включил этот скрипт, получивший название dd_rhelp, в официальную версию основной программы.

    GNU ddrescue


    dd_rhelp в связке с dd_rescue существенно упростил процесс, но у него был один фатальный недостаток — он не был написал на C работал ужасно медленно.

    Не будучи в силах с этим смириться Антонио Диаз решил запилить свою программу с алгоритмом и константами, которую назвал — сюрприз — GNU ddrescue.

    Вот как среагировал на это автор dd_rhelp.
    Какое-то время dd_rhelp был единственным инструментом, который мог выполнять работy такого рода, но вот уже несколько лет как это не так: Антонио Диаз написал идеальную замену для моего инструмента: GNU 'ddrescue'.

    Да, назвать инструмент тем же именем, что и 'dd_rescue' Курта Гарлоффа было не очень умно (вот вы улавливаете тонкое отличие между 'GNU ddrescue' и 'dd_rescue'?), но кажется это было сделано намерено, поскольку мы предупредили Антонио Диаза, что это наверняка внесёт сумятицу в миниатюрный мир инструментов восстановления жёстких дисков.

    Тем не менее, если этот инструмент решает ваши задачи (а так и должно быть) я призываю вас использовать именно его. Почему? Сначала надо разобраться что мы сравниваем:
    — dd_rhelp (грязный баш скрипт) + dd_rescue (Си) одной стороны
    — GNU ddrescue (Си) с другой /* вообще-то GNU ddrescue написана на С++ */

    dd_rhelp был задуман как быстрый хак для реализации того, что dd_rescue не делала и что на тот момент вообще нельзя было осуществить.

    Возможно, есть случаи в которых GNU ddrescue не работает и это основная причина по которой я продолжаю поддерживать dd_rhelp. О таких случаях очень важно сообщать мне и Антонио Диазу.

    Оригинал
    For some times, dd_rhelp was the only tool (AFAIK) that did this type of job, but since a few years, it is not true anymore: Antonio Diaz did write a ideal replacement for my tool: GNU 'ddrescue'.

    Yes, this is not very clever to have called a tool the same name that 'dd_rescue' from Kurt Garloff (catch the subtle difference between 'GNU ddrescue' and 'dd_rescue' ?), but it seems that it was done by intent as we warned Antonio Diaz from the fact it would probably mess users in this tiny world of hard drive recovery tools.

    Nevertheless, I really encourage you to use this replacement tool if it works for you (and it should be the case). Why? Understand first what we are comparing:
    — dd_rhelp (in dirty bash script) + dd_rescue (in C) in one hand
    — GNU ddrescue (in C) in the other.

    dd_rhelp was meant as a quick hack to implement what dd_rescue didn't do, and what couldn't be done at that time (AFAIK).

    It could be some cases where GNU ddrescue won't work, and this is the major reason why I keep maintaining dd_rhelp. It is important to tell me and Antonio Diaz when these cases occur.


    Настоящее время


    Как уже сказано, dd_rescue и GNU ddrescue до сих пор периодически обновляются, а вот dd_rhelp заморожен на уровне 2008 года и это похоже навсегда. Обновление 2012 года, правда внесло какие-то косметические изменения, но это мало что изменило.

    Как же быть простому пользователю


    Использовать GNU ddrescue для создания копий заведомо проблемных дисков


    Там, где нужна функциональность dd_rhelp, лучше воспользоваться GNU ddrescue. Как показано выше, dd_rescue может заменить GNU ddrescue только в связке с dd_rhelp, автор которого рекомендует своим детищем по возможности не пользоваться.

    Использовать dd_rescue когда нужен улучшенный вариант dd


    С другой стороны, если для вас функционал dd_rhelp избыточен, то у dd_rescue есть в рукаве пара трюков, которыми GNU ddrescue не владеет. Прежде всего, dd_rescue может перенаправить вывод в пайп, что просто незаменимо например при копировании по ssh. Кроме того там есть плагинный механизм с помощью которого поддерживается сжатие и разжатие на лету, а также различные алгоритмы подсчёта хешей. dd_rescue хорошо подойдёт там, где нужен заменитель простого dd с расширенным функционалом и страховкой на случай наличия ошибок, исправляемых повторным чтением. А ещё в документации сказано, что она рисует прогресс бар :).

    Для создания резевной копии диска — при прочих равных используйте GNU ddrescue


    По моему мнению, если речь идёт о снятии образа диска, и сохранении его на другом диске, непосредственно подключенном к тому же компьютеру, нет никаких причин отказываться от GNU ddrescue в пользу dd_rescue или dd, а вот использование оптимальной стратегии копирования данных, которая в них не реализована, может быть хорошей страховкой и избавит пользователя от многих неожиданных неприятностей.
    Поделиться публикацией
    Комментарии 13
      0
      Очень полезно — спасибо! Вообще не знал что есть две разные утилиты с почти одинаковыми именами.
        0
        Я сам удивился, когда узнал. А уж когда выснилось, что они обе активно развиваются — любопытству моему не было предела. Приятно, что вопрос интересен не только мне одному :).
        0
        Для копирования по ssh при помощи dd можно использовать специальный тип файла — FIFO.

        [nekit@localhost fifo_test]$ mkfifo pipe
        [nekit@localhost fifo_test]$ ls -l
        итого 0
        prw-r--r-- 1 nekit nekit 0 Сен 16 13:28 pipe|
        [nekit@localhost fifo_test]$ dd if=/dev/urandom of=./pipe
        [nekit@localhost fifo_test]$ cat pipe | ssh user@my.host "cat > random_data"
        
          +1
          dd и так отлично умеет отдавать в stdout:
          # man dd | grep -A 1 of=FILE
                 of=FILE
                        write to FILE instead of stdout
          


          А вот если этого не умеет ddrescue — то это уже design failure

          Кроме там есть плагинный механизм с помощью которого поддерживается сжатие и разжатие на лету
          — это уже не UNIX way, правильно это делается через
          dd if=file | bzip2 | ssh 'cat >file.bz2'
          


          А сжимать трафик и сам ssh умеет — «ssh -C»
            +2
            To, что ddrescue не умеет отдавать данные в stdout не design failure, а осознанное решение, принятое из-за того, что передача данных в pipe несовместима с чтением
            данных с устройства в несколько проходов.
            — это уже не UNIX way, правильно это делается через
            dd if=file | bzip2 | ssh 'cat >file.bz2'

            Не всё, что UNIX way правильно и наоборот. Но на всякий случай отмечу, что UNIX way dd_rescue тоже умеет, то есть его спокойно можно встроить в конвейр. Однако если мы знаем какие данные жмём это позволяет сжимать более эффективно, а также внедрить фичи недоступные при использовании инструментов общего назначения. Что собственно и делает dd_rescue через плагинный механизм.
              0
              Да, ошибочка. ddrescue так использовать не получится, только dd.
                0
                GNU ddrescue не умеет отдавать данные в пайп. А dd_rescue вполне себе может.
              0
              Когда я охарактеризовал dd_rescue как улучшенный вариан dd я имел в виду, прежде всего его способность копировать повреждённые диски :). dd действительно умеет достаточно много и, в том числе, как показано ниже — отдавать вывод в stdout.

              Но то, что вы тут показали лично мне любопытно. Скажите, команда dd if=/dev/urandom of=./pipe передаст управление дальше и будет скармливать новые данные в пайп только по мере их вычитки cat? Или я неправильно всё понял?
                0
                Тут я немного упростил. ssh я запускал в отдельном шелле. Но можно для dd поставить в конце & — тогда команда уйдет в бэкграунд и можно в том же шелле запустить ssh.
                А вот насчет данных — да, будет писать по мере вычитки.
                  0
                  О как! Я не знал, что так можно, спасибо.
                    0
                    «Мера вычитки», насколько мне известно, зависит от опций bs/ibs/obs: они указывают, с какими блоками работать/какими блоками читать/какими блоками писать («какими блоками» = какого размера блоки использовать).
              0
              А что, контроллеры современных жёстких дисков ещё дают какое-то подобие низкоуровневого доступа? Там и геометрия уже давно «виртуальная», да и всё остальное наверное тоже.
                0
                Таки дают. Ну то есть можно попросить вернуть определённый кусок диска в 512 байт. И диск представлен в линуксе блочным устройством с линейной адресацией.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое