I've copied the USB drive to an .img file using dd:
dd if=/dev/sdc of=myimage.img
I want to reduce the size of the partition in the image. I've tried several methods and always end up with a loopback-mounted image whose partition is still the full size of the USB.
How do I modify
myimage.imgto have a smaller partition once loopback-mounted?Do I need to copy zeros into the empty part of the partition before doing so?
Do I need to defragment so that when I reduce the image size, I'm deleting empty bytes? (From what I've read, Linux spreads out into the whole partition so I have no expectation that all of the data at the end of the image are zero bytes. Even writing all zeros will just consume the empty bytes wherever they lie.)
NOTE: I'm not trying to save disk space, so zipping doesn't help me.
BACKGROUND
I have Linux installed on a USB drive using ext4. I intend to duplicate the install for multiple devices. I've done so successfully but would like to create on the same USB drive a read-only partition with the system and a small partition that allows persistent storage. Rather than break my USB, I'm trying to modify a copy of the USB. I hope we don't get distracted by this background.
In short, I've done the following:
# Create mount point in current directory
sudo mkdir mnt
# Loopback mount the image
fdisk -l myimage.img
sudo mount -o offset=<partion_block_start * block_size> myimage.img mnt
# Copy all zeros to remaining space of the image
cd mnt
sudo dd if=/dev/zero of=filler conv=fsync bs=1M
rm filler
cd ..
First, I tried to use parted as described in this SuperUser answer and qemu-img as described in this other SuperUser answer.
sudo umount mnt
parted myimage.img
# At parted command prompt
(parted) resizepart 1
# Entered my end <target size>. Note that parted uses zero-based
# indexing. This could be your final image size. In my case, the way the
# Linux installer worked, the partition started at 1M.
(parted) print
# I see that the partition is now sized as I expect
(parted) exit
# Just another sanity check
sudo parted -m esp3_007.img unit B print
# I see that the partition is now sized as I expect
When I try to mount the image again, it works fine but df still shows the partition as the same size. So then I tried
qemu-img resize myimage.img <target_size>
And now, when I try to mount the image, I get the "mount: wrong fs type, bad option, bad superblock..." error message.
Then I tried using gparted as described in this off-site post. The GUI showed a full partition unless I ran parted in the first place. Even then, the GUI wouldn't let me resize the partition.
For trying to force the partition size to be smaller, and starting with a fresh copy of myimage.img I tried fdisk described in this AskUbuntu answer
sudo fdisk myimage.img
Command (m for help): d
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4, default 1): 1
# defaults on the rest seemed to be correct in my case.
When I mounted the partition, it still showed as the same size.