Як змінити розмір файлу img, створеного з dd?


19

У мене є зображення DD із SD-картки 4 Гб, яка має два розділи, ці два розділи використовують лише близько 800 Мб, і як такий я хочу зменшити розмір файлу img.

Хтось знає про спосіб видалення "вільного місця" з файлу img?


ви можете додати бажаний результат. тобто: повернення зображення до картки для зберігання на компакт-диску.
Уейн

Відповіді:


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: Де саме я пропоную обрізати зображення?
користувач1686

1
@ValerioSantinelli: Використовуючи відповідний інструмент зміни розміру файлової системи для вашої файлової системи, наприклад, resize2fsабо ntfsresize(у Linux немає інструменту для FAT), перед тим, як записати його на менший пристрій, або створивши свіжу файлову систему та скопіювавши лише файли.
користувач1686

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 (2 Гб).

Працювали бездоганно для мене.


1
Дивовижно, працювало бездоганно і для мене, стискаючи образ Raspbian. повністю працює!
ffleandro

Ну, все працює, проте після завантаження біг df -hпоказує оригінальний розмір. Як це можливо?
ffleandro

Мабуть, qemu-img не містить таблицю розділів, тож як він стискає .img?
ffleandro

Я можу змінити розмір .img диска до 1М, що безумовно порушує зображення диска. Будь-яка ідея зробити розмір більш безпечним?
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.