дд на весь диск, но не хочу пустой порции

33

У меня есть диск, скажем / dev / sda.

Вот fdisk -l:

 Disk /dev/sda: 64.0 GB, 64023257088 bytes
255 heads, 63 sectors/track, 7783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000e4b5

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          27      209920   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              27         525     4000768    5  Extended
Partition 2 does not end on cylinder boundary.
/dev/sda5              27         353     2621440   83  Linux
/dev/sda6             353         405      416768   83  Linux
/dev/sda7             405         490      675840   83  Linux
/dev/sda8             490         525      282624   83  Linux

Мне нужно создать образ для хранения на нашем файловом сервере, чтобы использовать его для перепрошивки других устройств, которые мы производим, поэтому мне нужно только используемое пространство (только около 4 ГБ). Я хочу сохранить mbr и т. Д., Поскольку это устройство должно быть готово к загрузке, как только копия будет завершена.

Любые идеи? Раньше я использовал dd if=/dev/sda of=[//fileserver/file], но в то время, моя мастер-копия была на 4 ГБ флэш-памяти.

Джонатан Хенсон
источник
2
Все ответы ниже неправильны, кроме @sudoer. Правильный ответ заключается в использовании dd conv=sparse.
Багамат
@bahamat, нет, лучше gzip, поскольку он сжимает данные.
Псуси
1
Это не то же самое, что разреженный.
Багамат
@bahamat, вопрос не задает специально для sprase; как заставить изображение занимать меньше места.
Псуси

Ответы:

37

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

dd if=/dev/zero of=asdf.txt, Подождите, пока он не умрет. Удалить asdf.txt.

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

Теперь возьмите образ диска и запустите его через gzip. Вуаля, редкий образ.

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

Вы можете сделать снимок диска rsync на другом томе, обнулить его и затем получить этот образ диска.

Примечание: это может быть опасно для SSD, пользователь должен рассмотреть эту операцию перед фиксацией.

Роб Бос
источник
если я запусту его через gzip, придется ли мне распаковывать его перед использованием? И, запустив его через gzip, могу ли я просто передать его во время процесса dd?
Джонатан Хенсон
3
Да. dd if=sda2.gz | gunzip > /dev/sda2иdd if=/dev/sda2 | gzip > sda2.gz
Роб Бос
3
Msgstr "Вы только что записали нули во все свободное место на устройстве". Я имею в виду раздел, а не устройство. Таким образом, вам нужно будет выполнить эту команду с ofпутем для каждого раздела.
Jiggunjer
Если физическим носителем является SSD, он может подумать, что использовался каждый сектор устройства. Это даст SSD меньше запасных секторов для работы и, возможно, снизит производительность. Если драйвер и прошивка имеют поддержку TRIM, это условие будет действовать только до тех пор, пока вы снова не удалите файл. Если вы сохраните файл на месте во время создания изображения, вам придется снова удалить файл после восстановления изображения. Это может быть полезно, если образ восстанавливается на SSD.
Касперд
Есть несколько дополнительных проблем, о которых следует помнить. Поскольку этот метод требует, чтобы файловая система была смонтирована для чтения и записи, существует риск того, что изменения в базовой файловой системе в процессе копирования приведут к несовместимому образу. В одном случае я видел, что полученная копия была настолько несовместимой, что fsck на самом деле мог вызвать ошибку при попытке исправить несоответствия в копии. Также заполнение устройства может вызвать сбой других процессов, нуждающихся в записи на носитель.
Касперд
17

Предполагая , что вы хотите сохранить /dev/sdXNдо /tgtfs/image.rawи вы корень:

  1. mkdir /srcfs && mount /dev/sdXN /srcfs

  2. Используйте zerofill или просто: dd if=/dev/zero of=/srcfs/tmpzero.txtчтобы заполнить неиспользуемые блоки нулями (затем дождитесь полного заполнения файловой системы rm /srcfs/tmpzero.txt)

  3. Возьмите изображение с помощью dd и используйте conv = sparse, чтобы пробивать нули на лету: dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

Если вы хотите использовать сжатие, вам не нужно пробивать нули с помощью dd, поскольку нулевые блоки очень сжимаемы:

dd if=/dev/sdxn | gz -c | dd of=/tgtfs/image.raw

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

Sudoer
источник
5
Это правильный ответ. Использование dd conv=sparse.
Багамат
1
Что не так с флэш-накопителем?
Дан
2
@Dan (в зависимости от конструкции и конфигурации аппаратного и программного обеспечения) может привести к интенсивной записи на ваш SSD и сократить срок его службы. и в целом, это нормально для перемещения данных со старого диска на новый (или то, что хотел сделать OP), но резервное копирование на уровне диска / раздела не является хорошим решением для регулярного резервного копирования и восстановления даже на жестких дисках. Резервное копирование на уровне файлов (т. е. копирование файлов из одной файловой системы в другую) или резервное копирование на уровне файловой системы (с файловыми системами, такими как BTRFS с инструментами btrfs snapshotи btrfs sendинструментами) - лучшее решение ИМХО.
Судо
Подсказка: Если у вас нет gzна вашем PATH(как я не сделал, на GParted Live), вы можете использовать gzip -cвместо этого.
XtraSimplicity
11

Используйте dd с опцией count.

В вашем случае вы использовали fdisk, поэтому я воспользуюсь этим подходом. Ваш "sudo fdisk -l" произвел:

    Disk /dev/sda: 64.0 GB, 64023257088 bytes
    255 heads, 63 sectors/track, 7783 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x0000e4b5

    Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *           1          27      209920   83  Linux
    Partition 1 does not end on cylinder boundary.
    /dev/sda2              27         525     4000768    5  Extended
    Partition 2 does not end on cylinder boundary.
    /dev/sda5              27         353     2621440   83  Linux
    /dev/sda6             353         405      416768   83  Linux
    /dev/sda7             405         490      675840   83  Linux
    /dev/sda8             490         525      282624   83  Linux

Следует обратить внимание на две вещи: 1) размер блока и 2) столбец «Конец». В вашем случае у вас есть цилиндры, которые равны 8225280 байт. В столбце «Конец» sda8 заканчивается на 525 (что составляет 525 [единиц] * 16065 * 512 = ~ 4,3 ГБ)

dd может делать много вещей, таких как запуск после смещения или остановка после определенного количества блоков. Мы сделаем последнее, используя опцию count в dd. Команда будет выглядеть следующим образом:

    sudo dd if=/dev/sda of=/your_directory/image_name.iso bs=8225280 count=526

Где -bs - это размер блока (проще всего использовать единицу, которую использует fdisk, но любая единица будет делать это, пока в этих единицах объявлена ​​опция count), а count - это количество единиц, которые мы хотим скопировать (примечание что мы увеличиваем счет на 1, чтобы захватить последний блок).

Том Луби
источник
К вашему сведению: чтобы показать единицы в цилиндрах, используйтеfdisk -l -u=cylinders /dev/sda
xinthose
3
Почему это не принятый ответ? Кажется, это наименее навязчивый вариант, поскольку он не изменяет источник.
user33326
@ user33326, потому что этот ответ хорош для того, чтобы не копировать нераспределенное пространство на диске, а не неиспользуемое пространство внутри разделов, о чем заботится OP.
ГДорн
8

Несмотря /dev/zeroна то, что использование свободного дискового пространства и использование dd conv=sparse/ gz -cвозможно на больших дисках с пустым пространством, работающим в сотнях гигабайт, /dev/zeroзагрузка идет мучительно медленно - не говоря уже о том, что, как отмечали другие ответы, /dev/zeroиспользование SDD до EOF.

Вот что я сделал, когда столкнулся с этой ситуацией:

  • На компакт-диске lubuntu, который используется gpartedдля «сокращения» диска до минимально возможного размера, оставляя оставшееся пространство незанятым

  • Используется
    dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz для создания быстро сжатого образа (разумеется, вы можете пропустить сжатие, если у вас достаточно места для хранения необработанных данных (или иным образом склонны уменьшать нагрузку на процессор)

  • Используется
    dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY для копирования данных обратно на другой диск
  • Используется gpartedснова, чтобы «расширить» раздел

Я не пробовал его для нескольких разделов, но я полагаю, что описанный выше процесс можно адаптировать для копирования «разделов», если сначала создается таблица разделов на целевом диске и только данные, содержащиеся в разделе, копируются с помощью ddсмещений чтения / записи ( skip/ seekвариант dd, соответственно) будет необходимо по мере необходимости.

Ашиш Чопра
источник
1
это реальный ответ, просто используйте countпараметр
Горди
7

Ты не можешь ddэто инструмент очень низкого уровня, и он не имеет возможности различать файлы и пустое пространство.

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

C2H5OH
источник
7
Предполагая, что свободное пространство ранее не использовалось. Вы можете вначале заполнить нулевое свободное пространство, чтобы обеспечить правильную работу сжатия.
Sirex
1
Правда. И это только усложняет процесс и делает его еще дольше.
c2h5oh
6

Предполагая, что остальная часть диска пуста (все нули), вы можете передать свой DD через gzip, который должен довольно хорошо сжать пустое пространство. Вы можете использовать такой инструмент, как zerofree, чтобы убедиться, что ваше пустое пространство фактически пустое, поэтому оно хорошо сжимается.

Если вы используете такие инструменты, как partimage , clonezilla или некоторые другие инструменты клонирования linux, большинство из них будет обрабатывать для вас автоматически.

Zoredache
источник
partimage и clonezilla на самом деле достаточно умны, чтобы пропустить чтение свободного пространства, вместо того, чтобы полагаться на то, что вы записываете в него нули, а затем дд или gzip отбрасываете или
сжимаете
2

Принятый ответ не верен. Я согласен с комментарием выше. Я использую dd с параметром count для резервного копирования моего диска на регулярной основе. Просто замените BACKUP_FOLDER и букву вашего устройства на «X»:

Определите последний использованный блок диска:

ct=$(fdisk -l | awk '$1 == "/dev/sdX" { print $3 }')

Затем клонируем диск (исключая его пустое пространство):

dd if=/dev/sdX bs=512 count=$ct | gzip > BACKUP_FOLDER/sdX_$(date +"%Y-%m-%d").img.gz >>"$LOG"
Алоха Д
источник