Mam obraz DD z karty SD o pojemności 4 GB, która ma dwie partycje, te dwie partycje zużywają tylko około 800 MB i dlatego chcę zmniejszyć rozmiar obrazu.
Czy ktoś zna sposób na usunięcie „wolnego miejsca” z pliku img?
Mam obraz DD z karty SD o pojemności 4 GB, która ma dwie partycje, te dwie partycje zużywają tylko około 800 MB i dlatego chcę zmniejszyć rozmiar obrazu.
Czy ktoś zna sposób na usunięcie „wolnego miejsca” z pliku img?
Odpowiedzi:
Najpierw upewnij się, że wolne miejsce jest faktycznie puste i nie zawiera resztek usuniętych plików. Najłatwiejszym sposobem na osiągnięcie tego jest utworzenie na dysku ogromnego pliku zawierającego tylko bajty zerowe, a następnie usunięcie go.
# 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
Następnie skompresuj go za pomocą narzędzia takiego jak gzip
lub xz
. Nawet przy najniższych poziomach kompresji długa seria zer dobrze kompresuje:
# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz
Pamiętaj, że musisz rozpakować obraz podczas zapisywania go z powrotem na dysk. Spowoduje to rozpakowanie go „na żywo”:
# cat foo.img.gz | gunzip | dd of=/dev/sda
Należy pamiętać, że urządzenie wyjściowe (sda) musi mieć wystarczający rozmiar, aby pasował do oryginalnego obrazu, w przeciwnym razie dane zostaną utracone lub uszkodzone.
Alternatywną metodą, jeśli chcesz nadal używać obrazu - np. Na maszynie wirtualnej - jest konwersja surowego obrazu na jeden z formatów obrazów używanych przez oprogramowanie do wirtualizacji; np. qcow2 dla Qemu, VDI dla VirtualBox lub VMDK dla VMware.
Pamiętaj, że nadal wymaga to przygotowania obrazu poprzez wyczyszczenie wolnego miejsca za pomocą powyższej metody.
# qemu-img convert -f raw -O qcow2 foo.img foo.qcow
# qemu-img convert -f raw -O vmdk foo.img foo.vmdk
Ale jeśli będzie on ponownie zapisany na prawdziwym dysku, musisz przekonwertować go z powrotem na surowy obraz.
resize2fs
Lub ntfsresize
(Linux nie ma narzędzia do FAT), przed zapisaniem go na mniejszym urządzeniu lub przez utworzenie nowego systemu plików i skopiowanie tylko plików.
Korzystanie resize2fs
jest znacznie łatwiejsze
resize2fs -M xxx.img
najpierw zostaniesz poproszony o e2fsck - więc:
e2fsck -f -y xxx.img
(obraz NIE MOŻE być montowany!)
Uwaga: zadziała to tylko wtedy, gdy obraz składa się z jednej partycji, jeśli jest to całe urządzenie blokowe z wieloma partycjami patrz powyższa odpowiedź ...
losetup --find --partscan xxx.img
aby ustawić plik obrazu jako urządzenie pętli. następnie uruchom, lsblk
aby znaleźć partycje urządzenia pętli.
resize2fs
dotyczy tylko extN
partycji typu. Inne typy partycji będą wymagały innych narzędzi.
Próbowałem też z qemu-img i działało to jak urok:
qemu-img resize test.img 2G
Zmieniamy rozmiar, test.img
aby uczynić go 2G (2 GB).
Działa dla mnie bezbłędnie.
df -h
pokazuje oryginalny rozmiar. Jak to jest możliwe?
W moim komputerze Ubuntu 16.10 zastosowałem podejście gparted:
1) Zamapuj plik img na następnej dostępnej partycji pętli losetup
, jak opisano w poprzednich postach, jak powyżej
2) Sprawdź, na lsblk
którym napędzie pętli jest mapowany plik obrazu, np/dev/loop0
3) Wykonaj sudo gparted /dev/loop0
4) Zmniejsz partycje pętli, jeśli uzna to za stosowne; upewnij się, że te partycje są odmontowane.
5) Wykonaj fdisk /dev/loop0
, a następnie wprowadź p
, to pokaże rozmiar bloku i końcowy numer bloku różnych partycji.
6) wykonywanie dd if=/dev/loop0 of=shrunk_image_file.img
, stosuje się do tego polecenia opcje bs=[BlockSize]
i count=[EndBlockNumberOfLastLoopPartition+1]
i trzeba będzie skurczył i Rightsizing plik obrazu.