Как можно использовать `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.

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 . Это также имеет дополнительное преимущество, чтобы быть достаточно умным, чтобы пропустить свободное пространство в томе.

  • Команда dd не выполняет ничего
  • Перемещение / загрузка и MBR на новый диск
  • Как кошка «знает» оптимальный размер блока для использования?
  • Как записать файл в другой
  • Отдельные данные dd с выхода через netcat для анализа вывода
  • как написать команду dd для замены резервной копии корневого раздела?
  • Быстрый способ рандомизировать HD?
  • Как я могу запустить 2 dd параллельно на одном устройстве
  • Какие места следует использовать для сброса флэш-памяти из электронных компонентов на жестких дисках?
  • Используйте резервный файл из dd для восстановления жесткого диска, а также извлеките файлы
  • Перегородки одинакового размера, но разные блоки
  • Как использовать pv с dd?
  • Interesting Posts

    Сколько ядер может обрабатывать ядро ​​Linux?

    Сценарий Python для выключения системы не работает в cron

    Обновление «Доступной версии» в .so

    Изящное завершение работы с возможностью сохранения файлов или отмены

    Как использовать справочные страницы, чтобы узнать, как использовать команды?

    Клон Virtualbox vboxmanage не отображается в списке виртуальных машин

    К какому файлу устройства относится конкретное устройство хранения данных?

    Как настроить w3m на использование прокси-сервера squid (или любого прокси-сервера) по умолчанию при вызове конкретного пользователя?

    Своеобразное поведение grep / heading трубопроводов

    Сценарий оболочки или команда для вырезания текста и двоичных файлов выдержки из больших файлов журнала

    Обновление клиентских драйверов I2C до новой модели привязки

    Удалите пространство перед вторым столбцом, чтобы поддерживать форматирование pdb

    Мониторинг активности жесткого диска

    Как подключить клавиатуру и мышь к другому экрану?

    Не удалось запустить графический интерфейс

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