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


19

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

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


Вы можете добавить желаемый результат. т.е.: изображение обратно на карту, для хранения на 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

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


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 файл изображения.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.