Previous page

Next page

Locate page in Contents

Adding an Existing Virtual Machine

A host may have virtual machines that are not registered with the Parallels Service. This can happen if a virtual machine was previously removed from the Parallels Service registry or if the virtual machine files were manually copied from a different location. If you know the location of such a virtual machine, you can easily register it with the Parallels Service using the PrlSrv_RegisterVm function. The function accepts a server handle, name and path of the directory containing the virtual machine files, and registers the machine.

Note: The PrlSrv_RegisterVm function does NOT generate new MAC addresses for the virtual network adapters that already exist in the virtual machine. If the machine is a copy of another virtual machine then you should set new MAC addresses for its network adapters after you register it. The example at the end of this section demonstrates how this can be accomplished. For more information on modifying an existing virtual machine, please see the Modifying Virtual Machine Configuration section.

The following sample function demonstrates how to add an existing virtual machine to the Parallels Service. The function takes a handle of type PHT_SERVER and a string specifying the name and path of the virtual machine directory. It registers the virtual machine with the Service and then modifies the MAC address of every virtual network adapter installed in it.

PRL_RESULT RegisterExistingVM(PRL_HANDLE hServer, PRL_CONST_STR sVmDirectory)

{

    PRL_HANDLE hJob = PRL_INVALID_HANDLE;

    PRL_HANDLE hJobResult = PRL_INVALID_HANDLE;

  

    PRL_RESULT ret = PRL_ERR_UNINITIALIZED;

    PRL_RESULT nJobRetCode = PRL_ERR_UNINITIALIZED;

  

    // Register the virtual machine.

    hJob = PrlSrv_RegisterVm(

        hServer,

        sVmDirectory,

        PRL_TRUE);  // Using non-interactive mode.

  

    ret = PrlJob_Wait(hJob, 10000);

    

    // Check the return code of PrlSrv_RegisterVm.

    PrlJob_GetRetCode(hJob, &nJobRetCode);

    if (PRL_FAILED(nJobRetCode))

    {

        printf("PrlSrv_RegisterVm returned error: %s\n",

            prl_result_to_string(nJobRetCode));

        PrlHandle_Free(hJob);

        return -1;            

    }

  

    // Obtain the virtual machine handle from the job object.

    // We will use the handle later to modify the virtual machine

    // configuration.

    PRL_HANDLE hVm = PRL_INVALID_HANDLE;

    ret = PrlJob_GetResult(hJob, &hJobResult);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return ret;

    }

  

    ret = PrlResult_GetParam(hJobResult, &hVm);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return ret;

    }

  

    PrlHandle_Free(hJob);

    PrlHandle_Free(hJobResult);

  

    printf("Virtual machine '%s' was successfully registered.",

            sVmDirectory);

  

    // The following code will generate and set a new MAC address

    // for every virtual network adapter that exists in the virtual machine.

    // This step is optional and should normally be performed when the virtual

    // machine is a copy of another virtual machine.

  

    PRL_HANDLE hJobBeginEdit = PRL_INVALID_HANDLE;

    PRL_HANDLE hJobCommit = PRL_INVALID_HANDLE;

  

    // Begin the virtual machine editing operation.

    hJobBeginEdit = PrlVm_BeginEdit(hVm);

    ret = PrlJob_Wait(hJobBeginEdit, 10000);

    PrlJob_GetRetCode(hJobBeginEdit, &nJobRetCode);

    if (PRL_FAILED(nJobRetCode))

    {

        fprintf(stderr, "Error: %s\n", prl_result_to_string(nJobRetCode));

        PrlHandle_Free(hJobBeginEdit);

        return nJobRetCode;

    }

    

    // Obtain a handle of type PHT_VM_CONFIGURATION containing the

    // virtual machine configuration data.

    PRL_HANDLE hVmCfg = PRL_INVALID_HANDLE;

    ret = PrlVm_GetConfig(hVm, &hVmCfg);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return ret;

    }

  

    // Determine the number of the network adapters

    // installed in the machine.

    PRL_UINT32 nCount = PRL_ERR_UNINITIALIZED;

    ret = PrlVmCfg_GetNetAdaptersCount(hVmCfg, &nCount);

    if (PRL_FAILED(ret))

    {

        // Handle the error...

        return ret;

    }

  

    // Itereate through the adapter list.

    PRL_HANDLE hNetAdapter = PRL_INVALID_HANDLE;

    for (PRL_UINT32 i = 0; i < nCount; ++i)

    {

        ret = PrlVmCfg_GetNetAdapter(hVmCfg, i, &hNetAdapter);

        if (PRL_FAILED(ret))

        {

            // Handle the error...

            return ret;

        }

  

        // Automatically generate new MAC address for the current adapter.

        // The address will be updated in the configuration object.

        ret = PrlVmDevNet_GenerateMacAddr(hNetAdapter);

        if (PRL_FAILED(ret))

        {

            // Handle the error...

            return ret;

        }

    }

  

    // Commit the changes to the virtual machine.

    hJobCommit = PrlVm_Commit(hVm);

  

    // Check the results of the commit operation.

    ret = PrlJob_Wait(hJobCommit, 10000);

    PrlJob_GetRetCode(hJobCommit, &nJobRetCode);

    if (PRL_FAILED(nJobRetCode))

    {

        fprintf(stderr, "Commit error: %s\n", prl_result_to_string(nJobRetCode));

        PrlHandle_Free(hJobCommit);

        return nJobRetCode;

    }

  

    PrlHandle_Free(hNetAdapter);

    PrlHandle_Free(hVm);

    PrlHandle_Free(hVmCfg);

    PrlHandle_Free(hJobCommit);

    PrlHandle_Free(hJobBeginEdit);

  

    return 0;

}