Convert a Parallels Virtual Machine to VirtualBox

As user of a more recent version of Parallels Desktop, 12 at the time of writing, you might have heard about the famous “Parallels Image Tool”.

This tool appears in various place on the web when it comes to the question on how to convert a Parallels virtual machine to something VirtualBox or a VMware product can understand. As you know, the Parallels PVM file is a classic OS X package that contains HDD files representing the virtual disks. A HDD file can be read by VirtualBox for instance, but only under the condition that it is expanded to a simple flat representation of the disk. Converting an optimized “expanding” Parallels HDD to a flat file is an operation that the “Parallels Image Tools” could do. Unfortunately, this application is not available anymore.

There are however another tools that are delivered as part of the Parallels Desktop application package. These are command line tools and located inside of the Parallels Desktop OS X application package, and we can use them to expand our HDD file to a plain flat data file:

nat@ATREIDES:~$ ls -la /Applications/Parallels\ Desktop.app/Contents/MacOS
total 118648
drwxr-xr-x  37 root  wheel           1.2K Oct  1 20:14 ./
drwxr-xr-x  13 root  wheel           442B Oct  1 20:14 ../
-rwxr-xr-x   1 root  wheel           505K Oct  1 20:14 7z*
-rw-r--r--   1 root  wheel           1.7M Oct  1 20:14 7z.dylib
-rwxr-xr-x   1 root  wheel            28K Oct  1 20:14 Parallels Installer*
-rwsr-sr-x   1 root  accessibility    29K Oct  1 20:14 Parallels Service*
drwxr-xr-x   3 root  wheel           102B Oct  1 20:14 Parallels Service.app/
drwxr-xr-x   3 root  wheel           102B Oct  1 20:14 Parallels VM.app/
-rwxr-xr-x@  1 root  wheel            14K Oct  1 20:14 Uninstaller*
-rwxr-xr-x@  1 root  wheel           3.2K Oct  1 20:14 add_safari_ext*
-rwxr-xr-x@  1 root  wheel           3.4K Oct  1 20:14 agent*
-rwxr-xr-x@  1 root  wheel            25K Oct  1 20:14 inittool*
-rwxr-xr-x@  1 root  wheel            11K Oct  1 20:14 launchd_setup*
-rwxr-xr-x@  1 root  wheel           4.0K Oct  1 20:14 launcher*
-rwxr-xr-x   1 root  wheel           1.2M Oct  1 20:14 libMonitor.dylib*
-rwxr-xr-x@  1 root  wheel           3.8K Oct  1 20:14 parallels_wrapper*
-rwxr-xr-x   1 root  wheel            36M Oct  1 20:14 prl_client_app*
-rwxr-xr-x   1 root  wheel           3.0M Oct  1 20:14 prl_convert*
-rwxr-xr-x   1 root  wheel           3.1M Oct  1 20:14 prl_deactivation_id*
-rwxr-xr-x   1 root  wheel           1.4M Oct  1 20:14 prl_disk_tool*
-rwxr-sr-x   1 root  accessibility    75K Oct  1 20:14 prl_event_tap*
-rwxr-xr-x   1 root  wheel            22K Oct  1 20:14 prl_graphics_switcher*
-rwxr-xr-x   1 root  wheel           405K Oct  1 20:14 prl_mkiso*
-rwxr-xr-x   1 root  wheel           1.0M Oct  1 20:14 prl_naptd*
-rwxr-xr-x   1 root  wheel           794K Oct  1 20:14 prl_net_start*
-rwxr-xr-x   1 root  wheel            55K Oct  1 20:14 prl_perf_ctl*
-rwxr-xr-x   1 root  wheel           5.1M Oct  1 20:14 prl_updater_ctl*
-rwxr-xr-x   1 root  wheel            31K Oct  1 20:14 prl_vmarchiver*
-rwxr-xr-x   1 root  wheel           1.0M Oct  1 20:14 prlauth*
-rwxr-xr-x   1 root  wheel           157K Oct  1 20:14 prlcore2dmp*
-rwxr-xr-x   1 root  wheel           975K Oct  1 20:14 prlctl*
-rwxr-xr-x@  1 root  wheel           2.7K Oct  1 20:14 prlexec*
-rwxr-xr-x   1 root  wheel           975K Oct  1 20:14 prlsrvctl*
-rwxr-xr-x@  1 root  wheel            13K Oct  1 20:14 service*
-rwxr-xr-x@  1 root  wheel           1.1K Oct  1 20:14 shapp_plist_fixer.py*
-rwxr-xr-x   1 root  wheel           224K Oct  1 20:14 unrar*
-rwxr-xr-x@  1 root  wheel           3.2K Oct  1 20:14 watchdog* 

Here is the tool we are looking for: prl_disk_tool

nat@ATREIDES:~$ /Applications/Parallels\ Desktop.app/Contents/MacOS/prl_disk_tool --help

Usage:
    prl_disk_tool <operation> [<arguments>...]
<operation> :
    resize .................. resize disk image.
        mandatory arguments:
        --split               split the virtual hard disk by 2 GB.
        --size <size>[M|G]    sets the virtual hard disk size in MB (by default) or GB.
        --hdd <path to *.hdd> path to the virtual hard disk image file.
        optional arguments:
        --resize_partition    resize the last partition while resizing the disk.
        --force               forcibly drop the suspended state before resizing the disk.
        --force-hybrid-shutdown ignore shutdownState inside disks if vm is in Hybrid Shutdown state.

    resize -i, --info ....... get information about the disk capacity and its file size without resizing it.
        mandatory arguments:
        -i, --info
        --hdd <path to *.hdd> path to the virtual hard disk image file.
        optional arguments:
        --units K|M|G         show the disk size in KB, MB, or GB.

    compact ................. compact the disk image by removing unused sectors.
        mandatory arguments:
        --hdd <path to *.hdd> path to the virtual hard disk image file.
        optional arguments:
        -a, --all-leafs       estimate comact for all snapshot leafs.
        -x, --exclude <uid>   skip snapshot leafs with specified uid.
        --buildmap            build the bitmap of used blocks by scanning the disk.
        --exclude-pagefile    remove the page file from the disk.
                              Do nothing if --buildmap option is used.
        --force               forcibly drop the suspended state before compacting the disk.

    compact -i, --info ...... show the estimated disk size after the compaction without compacting the disk.
        mandatory arguments:
        -i, --info
        --hdd <path to *.hdd> path to the virtual hard disk image file.
        optional arguments:
        -a, --all-leafs       estimate comact for all snapshot leafs.
        -x, --exclude <uid>   skip snapshot leafs with specified uid.
        --buildmap            build the bitmap of used blocks by scanning the disk.

    merge ................... merge all snapshots of the virtual hard disk.
        mandatory arguments:
        --hdd <path to *.hdd> path to the virtual hard disk image file.

    validate ............... validates the operating system on the virtual hard disk.
        mandatory arguments:
        --hdd <path to *.hdd> path to the *.hdd file containing the operating system to be validated.

    configure ............... configure the operating system on the virtual hard disk.
        mandatory arguments:
        --hdd <path to *.hdd> path to the *.hdd file containing the operating system to be configured.
        optional arguments:
        --para <path to the paravirt driver>
        --boot <path to the boot helper driver>
        --toolsag <path to the PTIAgent.exe file>
        --force               forcibly configure Boot Camp even if it was
                              configured in the previous version.

    convert -i, --info ...... show information about the virtual hard disk.
        mandatory arguments:
        -i, --info
        --hdd <path to *.hdd> path to the virtual hard disk image file.

    convert .................. convert the virtual hard disk into another format
                              or change the way the data is organized.
        mandatory arguments:
        --hdd <path to *.hdd> path to the virtual hard disk image file.
        optional arguments:
        --extend              convert an expandable disk to support disk
                              with size more than 2TB (current limit for expanded disk)
        --expanding           reduce the size of a plain disk to the actual
                              amount of data stored on it and make it
                              expandable allowing it to grow in size as the
                              amount of data grows.
        --plain               convert an expandable disk to a disk of fixed
                              capacity that cannot grow in size.
        --split               split the data stored on the virtual hard disk
                              into smaller parts of 2 GB each, and improve the
                              virtual machine performance.
        --merge               merge all parts of a split disk into one file.

    encrypt ................. encrypt data on the specified virtual hard disk image.
        mandatory arguments:
        --hdd <path to *.hdd> path to the virtual hard disk image file.
        optional arguments:
        --force               forcibly encrypt the virtual hard disk even when it
                              is already encrypted.

    decrypt ................. decrypt data on the specified virtual hard disk.
        mandatory arguments:
        --hdd <path to *.hdd> path to the virtual hard disk image file.

    check ................... check and fix disk consistency.
        mandatory arguments:
        --hdd <path to *.hdd> path to the virtual hard disk image file.

    --password-type <plain|hashed|no> the way caller specifies a password
    --json                    write output information in JSON format.
    --help, --usage ......... print this usage information.

To convert a Parallels HDD file, which we previously copied out of the PVM package, into a flat binary data file, the following command does what we need (scroll right). Note that the source file will be replaced by the new version.

Important: If you plan to import the file in VirtualBox as bootable VM, the best is to prepare the Parallels VM by removing the Parallels Tools (“sudo /usr/lib/parallels-tools/install -r“) and anything that is “special” (mounts, shared drives, etc).

nat@ATREIDES:/Volumes/HUGEDRIVE$ /Applications/Parallels\ Desktop.app/Contents/MacOS/prl_disk_tool convert --hdd my-parallels-disk1.hdd --plain
Operation progress 24 %

This takes time and more important – disk space. To estimate how much space is needed, we can check the VM option dialog:

Once, the HDD file is converted, it has replaced the original file and but still is an OS X package! Descending into this new package, either via command line “cd” or using the Finder “Show Package Content”, the precious data file is finally revealed. It has the file extension HDS.

After copying it out of the package into the “open” file system, we simply rename it to a HDD file, add it in VirtualBox as disk file to an “empty” VM and boot our system.

nat@ATREIDES:/Volumes/MYHUGEDRIVE$ file my-parallels-disk1.hdd.copy.0.\{5fbaabe3-1111-2222-3333-860a329aaf42\}.hds

my-parallels-disk1.hdd.copy.0.\{5fbaabe3-1111-2222-3333-860a329aaf42\}.hds: 
x86 boot sector; partition 1: ID=0x83, active, starthead 32, startsector 2048, 
515899392 sectors; partition 2: ID=0x5, starthead 254, startsector 515903486, 
8382466 sectors, code offset 0x63


nat@ATREIDES:/Volumes/MYHUGEDRIVE$ mv my-parallels-disk1.hdd.copy.0.\{5fbaabe3-1111-2222-3333-860a329aaf42\}.hds my-new-virtualbox-disk-file.hdd

nat@ATREIDES:/Volumes/MYHUGEDRIVE$ # Use the HDD file in VirtualBox to boot the VM

2 thoughts on “Convert a Parallels Virtual Machine to VirtualBox”

  1. Thanks for the writeup. It’s promising, but I still havent got it to work. I’m using Parallels 11, and there doesn’t seem to be any parallels folder in /usr/lib for me to use to remove the tools. Is that a new thing in version 12 ?

    Best regards
    Kent

    1. Hi :) I don’t know P11, but I’ve found this old article and it looks like the there should be one under Linux (http://kb.parallels.com/en/117044). I think you can do the entire thing as well without removing the tools. Probably they will simply not work, but hopefully not make any trouble when started under VB. Hope this helps!

Leave a Reply

Your email address will not be published. Required fields are marked *