Как изменить размер файла img, созданного с помощью dd?

19

У меня есть изображение DD с SD-карты 4 ГБ, которая имеет два раздела, эти два раздела занимают всего около 800 МБ, и поэтому я хочу уменьшить размер img fie.

Кто-нибудь знает способ удаления "свободного места" из файла img?

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

Ответы:

8

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

# losetup --find --partscan foo.img
# lsblk
NAME      MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
loop0       7:0    0   4096M  0 loop 
├─loop0p1 259:0    0   2048M  0 loop 
└─loop0p2 259:1    0   2048M  0 loop 
# for part in /dev/loop0p*; do
    mount $part /mnt
    dd if=/dev/zero of=/mnt/filler conv=fsync bs=1M
    rm /mnt/filler
    umount /mnt
  done
dd: error writing ‘/mnt/filler’: No space left on device
dd: error writing ‘/mnt/filler’: No space left on device
# losetup --detach /dev/loop0

Затем сожмите его с помощью инструмента, как gzipили xz. Даже при самых низких уровнях сжатия длинная серия нулей будет хорошо сжиматься:

# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz

Обратите внимание, что вы должны распаковать изображение при записи его обратно на диск. Это распакует его «вживую»:

# cat foo.img.gz | gunzip | dd of=/dev/sda

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


Альтернативный метод, если вы хотите продолжать использовать образ - например, с виртуальной машиной - это преобразовать необработанный образ в один из форматов изображений, используемых программным обеспечением для виртуализации; например, qcow2 для Qemu, VDI для VirtualBox или VMDK для VMware.

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

# qemu-img convert -f raw -O qcow2 foo.img foo.qcow

# qemu-img convert -f raw -O vmdk foo.img foo.vmdk

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

user1686
источник
1
Как вы можете быть уверены, что все файлы, которые в данный момент хранятся в разделах, физически не разбросаны по диску?
Валерио Сантинелли
потому что я предполагаю, что файлы не записываются последовательно на диск, и если файл находится в конце хранилища, когда я уменьшу размер, я потеряю содержимое этого файла.
Валерио Сантинелли
Потому что ОП спрашивает, как сжать образ диска без потери данных. Если вы обрезаете изображение до определенного размера, вы не можете быть уверены, что данные будут сохранены.
Валерио Сантинелли
@ValerioSantinelli: где именно я предлагаю обрезать изображение?
user1686
1
@ValerioSantinelli: используя соответствующий инструмент изменения размера файловой системы для вашей файловой системы, например, resize2fsили ntfsresize(в Linux нет инструмента для FAT), перед записью его на маленькое устройство или созданием новой файловой системы и копированием только файлов.
user1686
22

Использовать resize2fsнамного проще

resize2fs -M xxx.img

Сначала вас попросят e2fsck - так:

e2fsck -f -y xxx.img

(изображение НЕ должно быть смонтировано!)

Примечание: это будет работать, только если изображение состоит из одного раздела, если это целое блочное устройство с несколькими разделами, см. Ответ выше ...

Серж Вагнер
источник
Просто примечание: для нескольких разделов используйте losetup --find --partscan xxx.imgдля настройки файла изображения в качестве устройства петли. затем запустите, lsblkчтобы найти разделы устройства цикла.
Yihui Xiong
Похоже, он не работает для образа ISO, который содержит операционную систему. После изменения размера система не загружается.
SR
@ SR операционная система Linux?
Рольф
1
Это очень хороший ответ, но resize2fsтолько для extNразделов типа. Другие типы перегородок потребуют других инструментов.
Рольф
2

Я также попробовал это с qemu-img , и это сработало как шарм:

qemu-img resize test.img 2G

Мы изменяем размеры, test.imgчтобы сделать его 2G (2GB).

Работал безупречно для меня.

Фил Роггенбак
источник
1
Удивительно, но для меня это тоже работало безупречно, сжимая распбианский образ. полностью работает!
ffleandro
Ну, все работает, однако после загрузки бег df -hпоказывает оригинальный размер. Как это возможно?
ffleandro
Очевидно, qemu-img не является таблицей разделов, так как же он сжимает .img?
ffleandro
Я могу изменить размер .img диска до 1M, что определенно нарушает образ диска. Есть идеи, чтобы сделать изменение размера безопаснее?
Lesca
1

Я использовал подход gparted с моим компьютером Ubuntu 16.10:

1) Сопоставьте файл img со следующим доступным разделом цикла с помощью losetup, как описано в предыдущих сообщениях, как указано выше.

2) Проверьте, с lsblkкаким контурным диском связан ваш файл изображения, например,/dev/loop0

3) Выполнить sudo gparted /dev/loop0

4) Сократите раздел (ы) петли, если считаете это необходимым; Пожалуйста, убедитесь, что эти разделы отключены.

5) Выполните fdisk /dev/loop0, затем введите p, это покажет вам размер блока и номер конечного блока различных разделов.

6) Выполнить dd if=/dev/loop0 of=shrunk_image_file.img, применить к этой команде параметров bs=[BlockSize]и , count=[EndBlockNumberOfLastLoopPartition+1]и вы будете иметь сжался и rightsized файл изображения.

VeryNoob
источник