Sunday, December 29, 2019

partitioning - Slightly shrink a DD image for cloning


I have read several of the proposed solutions that appear to say that shrinking a image created with dd is simple using resizefs, but they simply don't work.


I need to shrink an image by only about 200MB as it is slightly too big to fit on some CF cards which vary very slightly in their capacity, even thought they are all 8GB cards.


I have a 8GB image with a single 7.8GB partition that was created using dd, and using fdisk it appears that the image is fine:


fdisk DISK.img
Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p
Disk DISK.img: 7.8 GiB, 8375185920 bytes, 16357785 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb8342d9e
Device Boot Start End Sectors Size Id Type
DISK.img1 * 2048 14649343 14647296 7G 83 Linux

I need to shrink this down by about 250MB and have tried using resizefs, but that fails:


# resize2fs DISK.img 7.8G
resize2fs 1.44.5 (15-Dec-2018)
resize2fs: Bad magic number in super-block while trying to open DISK.img
Couldn't find valid filesystem superblock.

What am I doing wrong?


Answer



TL;DR


Write the image to any card that declares capacity of 8 GB and ignore no space left on device. Warning: this is not a general answer to all similar problems.




Answer to explicit question



What am I doing wrong?



You're trying to operate on the entire image, while the filesystem starts with offset (it lives within a partition within the image). Your DISK.img is like /dev/sdx, while you should invoke something like resize2fs /dev/sdx1 …; but for now you have no analogue of /dev/sdx1 in the directory tree.


In general you can shrink the filesystem by mapping the partition with tools like kpartx or losetup. But in your particular case there is nothing you need to do.




Explanation


The partition that holds the filesystem ends at the sector number 14649343. Numbering starts at 0 and the logical sector size is 512 bytes. The partition table lives in the MBR which is sector 0, and (contrary to GPT) there is no metadata at the end of the image. The initial stages of bootloader (if any) are in MBR and before the first partition. This means only the first 14649344 sectors (14649344 * 512 = 7500464128 bytes) matter; anything beyond may be lost, overwritten, truncated etc. (unless the unpartitioned space at the end does indeed hold some useful data; this would be very unusual though and if you don't know it's the case then it probably isn't).


So the image can be written to any device that is at least 7500464128 bytes big and all the useful data will fit. This is about 7.5 GB or 7 GiB. The number you used (7.8G) specifies 7.8 GiB (see man 8 resize2fs), so it's even bigger than the filesystem you already have (this means you wouldn't be shrinking in the first place).


Just check (e.g. with fdisk) if your target device has at least 14649344 (logical) sectors of 512 bytes. (Note: for a device with 4096-byte logical sectors you would need to translate the partition table; but this may be a problem with some large HDDs, not CF cards).


After you check the target device is large enough to hold the useful data, copy the image to it (with dd, cp, cat, …). If the device is smaller than DISK.img, you will get no space left on device, but this only indicates that the unused space at the end of the image doesn't entirely fit.


Or you can truncate the image first, so there is no unused space at the end at all:


truncate -s 7500464128 DISK.img

Then fdisk -l DISK.img will tell you there are exactly 14649344 sectors. The last sector (with number 14649343) will still be the last sector of the partition but there will be no space after the partition. Now if you write the image to a device large enough, you won't even get no space left on device.


In theory the filesystem may be even smaller than the partition, but it probably isn't. If it was then adjusting the partition to the filesystem and truncating further would be possible. I won't cover this case here. The image you already have should fit into any card that declares capacity of 8 GB.


No comments:

Post a Comment

hard drive - Leaving bad sectors in unformatted partition?

Laptop was acting really weird, and copy and seek times were really slow, so I decided to scan the hard drive surface. I have a couple hundr...