Как можно использовать `dd` для блоков данных с правом сдвига?

Рассмотрим простой блок-блок на 100 МБ. Это 204800 блоков по 512 байт на общую сумму 102760448 байт.

Задача состоит в том, чтобы перенести первые 98 МБ (блоки 200704), поэтому перед ним есть пробел в 2 МБ (4096 блоков). Для этого на месте требуется, чтобы ничто не записывалось в сектор, который не был прочитан. Один из способов добиться этого – ввести буфер:

$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096 

Ожидается, что mbuffer будет хранить 4096 блоков, прежде чем передавать что-либо писателю, тем самым гарантируя, что ничто не будет записано в область, которая не была прочитана, и что писатель отстает от читателя на размер буфера. Буфер должен позволять читателю и писателю работать как можно быстрее в пределах этих констриантов.

Однако, похоже, он не работает надежно. Я пытался использовать реальные устройства, но на них никогда не работает, тогда как эксперименты с файлом работали на моем 64-битном поле, но не на моем 32-битном поле.

Во-первых, некоторые приготовления:

 $ dd if=/dev/sdj2 count=200704 | md5sum 0f0727f6644dac7a6ec60ea98ffc6da9 $ dd if=/dev/sdj2 count=200704 of=testfile 

Это не работает:

 $ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=/dev/sdj2 seek=4096 summary: 98.0 MiByte in 4.4sec - average of 22.0 MiB/s md5 hash: 3cbf1ca59a250d19573285458e320ade 

Это работает на 64-битной системе, но не на 32-битной системе:

 $ dd if=testfile count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=testfile seek=4096 conv=notrunc summary: 98.0 MiByte in 0.9sec - average of 111 MiB/s md5 hash: 0f0727f6644dac7a6ec60ea98ffc6da9 

Как это можно сделать надежно?


заметки

Я прочитал другие вопросы о буферизации и посмотрел на pv , buffer и mbuffer . Я мог бы заставить последнего работать с требуемым размером буфера.

Использование промежуточного хранилища является очевидным решением проблемы, которая всегда работает, но это нецелесообразно, когда достаточная запасная емкость недоступна.

Испытательные платформы, на которых работает Arch Linux с версией mbuffer 20140302.

  • Что может привести к тому, что блок-устройство будет как-то меньше его разделов?
  • Можно ли распаковать zip-файл, содержащий образ диска, а затем сохранить его на SD-карту за один шаг?
  • Как я могу копировать три раздела моего диска с определенным началом и заканчивая использованием dd?
  • Как обрабатывать в реальном времени dd?
  • Для чего используются подписи для дисков GNU / Linux (дистрибутивы) / grub?
  • Можно ли использовать dd для клонирования только той части используемого жесткого диска?
  • Жесткий диск сообщает все 1 после расставания
  • Терминал: создать загрузочный USB из iso
  • 3 Solutions collect form web for “Как можно использовать `dd` для блоков данных с правом сдвига?”

    Без буфера вы могли бы вернуться назад, по одному блоку за раз.

     for i in $(seq 100 -1 0) do dd if=/dev/thing of=/dev/thing \ bs=1M skip=$i seek=$(($i+2)) count=1 done 

    Обратите внимание, что этот пример опасен из-за отсутствия проверки ошибок.

    Это также медленно из-за количества вызовов dd . Если у вас есть запасная память, вы можете использовать более крупный размер.

    С буфером, остерегайтесь ловушек . Недостаточно гарантировать 100% предварительную обработку. То, что вам нужно, является минимальным заполнением на протяжении всего процесса. Буфер никогда не должен опускаться ниже 2M потому что в противном случае вы снова перезапишите данные, которые еще не читаются.

    Поэтому, хотя теоретически вы можете обойтись без какого-либо буфера и просто цепочки dd :

     dd if=/dev/thing bs=1M | \ dd bs=1M iflag=fullblock | \ dd bs=1M iflag=fullblock | \ dd of=/dev/thing bs=1M seek=2 

    На практике это не работает надежно, потому что нет гарантии, что первый dd сумеет продолжать чтение данных, а последний dd2M «буфера» между ними) уже пишет.

    Вы можете значительно увеличить свои шансы, сделав промежуточный буфер значительно большим, но даже в этом случае он не является надежным.

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

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

    Инструмент ddrescue может работать в обратном направлении, но он отказывается работать с одинаковым входом и выходом. Однако это можно обмануть, дублируя узел устройства.

    Я провел несколько быстрых экспериментов и, похоже, работает. Командная строка:

     $ ddrescue -f -R -s 200704s -o 4096s /dev/sdj11 /dev/sdj11_copy 

    Аргументы:

    • -f требуется, чтобы заставить его записывать на существующее устройство вывода
    • -R говорит, что он работает в обратном направлении
    • -s сообщает, сколько копий ввода (я использовал суффикс s чтобы указать количество секторов)
    • -o сообщает, что он должен искать вперед в устройстве вывода перед записью (указанный в секторах снова с суффиксом s )
    • /dev/sdj11 является блочным устройством для чтения
    • /dev/sdj11_copy – это блок-устройство для записи

    Я создал /dev/sdj11_copy с mknod для соответствия параметрам /dev/sdj11 .

    Я сделал только очень быстрые тесты, но, похоже, работает нормально, чтобы скопировать исходное устройство. Он не работает над файлом (я не мог обмануть его в том, чтобы выходить за рамки того же файла)

    Это не отвечает на мой первоначальный вопрос, который спрашивает, как добиться этого с помощью dd но я думаю, прочитав другие ответы, ответ на этот вопрос заключается в том, что dd не может этого сделать.

    Вы читаете 4096 блоков, а затем записываете эти 4096 блоков в следующие 4096 блоков диска, тем самым перезаписывая второй 4096 блоков, прежде чем их можно будет прочитать. Вам нужно прочитать 8129 блоков, чтобы получить эти секунды 4096, прежде чем начинать писать, а затем вам нужно написать только 4096 блоков, прежде чем читать следующие 4096.

    Вы не указали, что это за файловая система. Если это ext [234], и у вас есть последняя версия e2fsprogs, вы можете использовать e2image -ra -O 512 /dev/sdj2 . Это также имеет дополнительное преимущество, чтобы быть достаточно умным, чтобы пропустить свободное пространство в томе.

    Interesting Posts

    Сервер Ubuntu переходит в режим ожидания

    Есть ли способ проверить пользовательский SSH-ключ, чтобы увидеть, является ли кодовая фраза пустой

    как сделать снимок экрана, который вы просматриваете через определенные промежутки времени?

    Vim gg = G (полный файл цели) без потери текущей позиции

    Могу ли я подключать stdout на одном сервере к stdin на другом сервере?

    Структура GNU / Linux

    Изменение чувствительности мыши (Debian)

    Плазменная сбой при переключении приложений с помощью панели задач

    В emacs существует ли способ Hex редактировать / просматривать буфер без потери информации об отмене?

    Использование lua rock, установленного с luarocks

    установка бита «x» (исполняемый) с использованием ACL

    Странный вход в мой домашний каталог

    Временные разрешения при установке DokuWiki?

    Каков правильный метод bash запроса пользователя на административный пароль перед резервным копированием данных USB на компьютер?

    Правило Удева было стерто после выполнения yum -y update

    Linux и Unix - лучшая ОС в мире.