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 gziplub 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.
resize2fsLub 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 resize2fsjest 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.imgaby ustawić plik obrazu jako urządzenie pętli. następnie uruchom, lsblkaby znaleźć partycje urządzenia pętli.
resize2fsdotyczy tylko extNpartycji 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.imgaby uczynić go 2G (2 GB).
Działa dla mnie bezbłędnie.
df -hpokazuje 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 lsblkktó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.