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
Next invoke
gdisk 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.
Type 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.
Quit with 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.
The command sudo gparted myfile.raw
expects files myfile.raw1
, myfile.raw2
etc. to exist and correspond with partitions inside myfile.raw
. If it was special file like /dev/sdb
then udev
would take care of /dev/sdb1
, /dev/sdb2
… It is not the case with regular file. Many gparted
features will fail if there are no myfile.rawN
files.
To create such files use kpartx
(or partx
+losetup
tandem):
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
Now 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.