1

It is possible to convert a raw image to a VMDK image with qemu-img like this:

qemu-img convert -O vmdk "$_raw" "$_vmdk"

I know it is possible to set UUID of the generated VMDK image with:

VBoxManage internalcommands sethduuid "$_vmdk" "$_uuid"

Is there a way to set the UUID of the disk as it is being converted with qemu-img (would be great if the solution worked on FreeBSD)?

1

This answer is from the top of my head and is not tested. If you test it feel free to update the answer.

Unfortunately the question have very little context to explain why we are doing this. At face value we could just refer to qemu-img and give the answer: No.

But that would be boring. Let us instead make some wild assumptions and run with it.

What you describe as a solution is possible on FreeBSD with qemu-img from emulators/qemu-utils and vboxmanage from emulators/virtualbox-ose. Maybe this is what you are doing? But you do not state why this is a problem (Maybe just want to use one less tool?).

The interesting thing is then what is only implied: You are using a GUID Partition table (GPT) on your disk. qemu-img does not really care what is on the disk whereas vboxmanage is nice enough to have a helper function.

As a disk

So if you have the full original copy of /dev/ada0 as ada0.dd (or just a raw file born in Qemu) - then you can use the image as a virtual memory disk:

# mdconfig -a -t vnode -u 0 -f /home/johndoe/ada0.dd

This will give us /dev/md0 which should be your full disk.

You can then check everything looks good.

# fdisk /dev/md0

This should look exactly like your old disk.

# glabel status

When working with GPT you might prefer using gpart

# gpart create -s gpt /dev/md0

The UUID is created automatically with this command. I do not know if it actually touches the entries in the partition table. In that case make a backup first. Maybe destroy the full table - create and then restore? You will need to do some testing here. But the point is that you now have full access to the drive.

You can mount the filesystem using this method as well

As a file

When we examine the GUID Partition Table Schematics from Wikipedia we are told that we find the Disk GUID in mixed endian in the partition table header at offset 56.

GUID Partition Table Scheme

So rather than mounting the disk image we can simply treat them as a bunch of bytes. I assume that you are using 512 byte sectors but you may need to adjust for 4K sectors. The header is then at LBA 1 and we are interested in offset 56 - thus 512 + 56 = 568

$ hexdump -v -s 568 -n 16 -e '1/1 "%.2x\n"' /home/johndoe/ada0.dd

We can then simply change the needed bytes. Hexdump is not quite enough for this and you should have a look at xxd which comes with editors/vim. uuidgen can help you generate a proper GUID.

If you go down this route then please observe:

  • Make your script resilliant by checking for the signature "EFI PART" before writing anything
  • Remember that you have the secondary copy of the header which needs to be corrected as well (Find it via offset 32)

That would be a fun little script to write.

Streaming

I have a sneaky suspicion that what you really want is to keep the original raw image pristine and do things on the fly. We are partly there as xxd supports both stdin and stdout so we could pipe trough it. Unfortunately it does not look like qemu-img supports stdin.

Then we have to have a file on disk. The pragmatic solution would be to have the original file as backup and a new copy used for modifications. This will only have the cost of added diskspace.

But as you are on FreeBSD you have a screaming fast way to save the diskspace and avoid doing a copy. You can use ZFS to your advantage. Simply create a new dataset where you place your raw image files and do a snapshot. Then you can modify the file directly but it will only affect the bytes changed (or rather the changed sectors). When done you quickly revert those sectors by rolling back the snapshot.

As we do not want to snapshot everything we create a specific dataset

# zfs create zroot/rawfiles

We place whatever data we need into /rawfiles and create a snapshot for our clean state.

# zfs snapshot zroot/rawfiles@cleanstate

We can then modify a few bytes in our potentially large image files. When we want to get back to our clean state the we roll back.

# zfs rollback zroot/rawfiles@cleanstate

If you have space contraints then this is a fast and viable option. If you do something like this then beware of race conditions if you keep rolling back.

If you do it as a backup "just in case" then you can skip creating a seperate dataset and just do zfs snapshot zroot@hailmary. If things blow up then just cp /.zfs/snapshot/hailmary/......

Manually

If you have influence on the image creation process we have some fun options as well.

We can use qemu-img to create a new image, mount it and create the GPT (with a new GUID)

# qemu-img create -f raw VM10G.raw 10G
# mdconfig -a -t vnode -u 0 -f VM10G.raw
# gpart create -s gpt /dev/md0

But as it is just a file we do not need qemu-img.

# truncate -s 10g VM10G.raw
# mdconfig -a -t vnode -u 0 -f VM10G.raw
# gpart create -s gpt /dev/md0

See building a UFS bootable image from scratch

Why am I showing this? Well, maybe you are doing something along those lines. Then we have a pretty neat trick when on FreeBSD: mkimg(1).

With this you can create disk images on FreeBSD and it supports QCOW, QCOW2, Dynamic VHD, Fixed VHD, VMDK and RAW. This mean that you can go directly to VMDK.

mkimg -f vmdk -s gpt -b /boot/pmbr -p freebsd-boot:=/boot/gptboot -p freebsd-ufs:=root-file-system.ufs -p freebsd-swap::1G -o gpt.vmdk

The example is FreeBSD centric but it is using raw partitions. So if you change your source from the raw full disk image to just partition images you should have a viable route.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.