There should be a primary (main) GUID Partition Table at the beginning and a secondary (backup) one at the end of the raw file created by
dd. Truncating the file destroys the secondary one. There is a way to fix it.
Let's start with your untruncated file with free space at the end. Run
gdisk -l myfile.raw. Notice the logical sector size (
512B probably). Find the maximal end sector (the one for the last partition probably, but partition entries may not be in order, so look carefully for the maximal one). Sectors are numbered from
0, therefore you need (sector size)*(maximal end sector + 1) bytes to store all the partitions.
Additionally you need at least 33 full sectors of free space at the end to store new secondary GPT. See this picture from Wikipedia.
Altogether you need (sector size)*(maximal end sector + 34) bytes of your file. Truncate the file to this or bigger size:
truncate -s <new_size> myfile.raw
You will get (among other things):
Warning! Disk size is smaller than the main header indicates!
Caution: invalid backup GPT header, but valid main header; regenerating
backup header from main header.
w, hit Enter to write correct partition tables. You will see a caution because secondary GPT is about to be moved. You have enough free space at the end of the file, so there is nothing to worry about. Confirm when asked.
q, Enter. Run
gdisk again – there should be no warnings. GPT is fixed.
In case you need to use
gparted with your image, I have some hints.
sudo gparted myfile.raw expects files
myfile.raw2 etc. to exist and correspond with partitions inside
myfile.raw. If it was special file like
udev would take care of
/dev/sdb2… It is not the case with regular file. Many
gparted features will fail if there are no
To create such files use
sudo kpartx -av myfile.raw
Observe its output (which
loopXpY devices were created) and create symlinks to all partitions. The first one may be:
ln -s /dev/mapper/loop0p1 myfile.raw1
gparted should run and operate on those partitions. There is a pitfall though: when partition changes (e.g. it is moved/resized) the mapping created by
kpartx is not updated. Normally
gparted would call
partprobe or something to update
/dev/sd*; this won't work in our case. You should destroy the mappings and recreate them. While moving/resizing partitions run one
gparted task, close program, fix the mappings, run
gparted with second task and so on.
To destroy the mappings invoke
sudo kpartx -dv myfile.raw. Delete orphaned symlinks at the very end.