diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 8660259ed0..bbc26ef183 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -1987,6 +1987,69 @@ static int prlsdkClearDevices(PRL_HANDLE sdkdom) return ret; } +static int +prlsdkRemoveBootDevices(PRL_HANDLE sdkdom) +{ + PRL_RESULT pret; + PRL_UINT32 i, devCount; + PRL_HANDLE dev = PRL_INVALID_HANDLE; + PRL_DEVICE_TYPE devType; + + pret = PrlVmCfg_GetBootDevCount(sdkdom, &devCount); + prlsdkCheckRetGoto(pret, error); + + for (i = 0; i < devCount; i++) { + + /* always get device by index 0, because device list resort after delete */ + pret = PrlVmCfg_GetBootDev(sdkdom, 0, &dev); + prlsdkCheckRetGoto(pret, error); + + pret = PrlBootDev_GetType(dev, &devType); + prlsdkCheckRetGoto(pret, error); + + pret = PrlBootDev_Remove(dev); + prlsdkCheckRetGoto(pret, error); + } + + return 0; + + error: + return -1; +} + +static int +prlsdkAddDeviceToBootList(PRL_HANDLE sdkdom, + PRL_UINT32 devIndex, + PRL_DEVICE_TYPE devType, + PRL_UINT32 bootSequence) +{ + PRL_RESULT pret; + PRL_HANDLE bootDev = PRL_INVALID_HANDLE; + + pret = PrlVmCfg_CreateBootDev(sdkdom, &bootDev); + prlsdkCheckRetGoto(pret, error); + + pret = PrlBootDev_SetIndex(bootDev, devIndex); + prlsdkCheckRetGoto(pret, error); + + pret = PrlBootDev_SetType(bootDev, devType); + prlsdkCheckRetGoto(pret, error); + + pret = PrlBootDev_SetSequenceIndex(bootDev, bootSequence); + prlsdkCheckRetGoto(pret, error); + + pret = PrlBootDev_SetInUse(bootDev, PRL_TRUE); + prlsdkCheckRetGoto(pret, error); + + return 0; + + error: + if (bootDev != PRL_INVALID_HANDLE) + PrlBootDev_Remove(bootDev); + + return -1; +} + static int prlsdkCheckGraphicsUnsupportedParams(virDomainDefPtr def) { virDomainGraphicsDefPtr gr; @@ -2601,7 +2664,7 @@ static int prlsdkAddNet(PRL_HANDLE sdkdom, virDomainNetDefPtr net) return ret; } -static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk) +static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk, bool bootDisk) { PRL_RESULT pret; PRL_HANDLE sdkdisk = PRL_INVALID_HANDLE; @@ -2610,14 +2673,18 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk) PRL_MASS_STORAGE_INTERFACE_TYPE sdkbus; int idx; virDomainDeviceDriveAddressPtr drive; + PRL_UINT32 devIndex; + PRL_DEVICE_TYPE devType; if (prlsdkCheckDiskUnsupportedParams(disk) < 0) return -1; if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) - pret = PrlVmCfg_CreateVmDev(sdkdom, PDE_HARD_DISK, &sdkdisk); + devType = PDE_HARD_DISK; else - pret = PrlVmCfg_CreateVmDev(sdkdom, PDE_OPTICAL_DISK, &sdkdisk); + devType = PDE_OPTICAL_DISK; + + pret = PrlVmCfg_CreateVmDev(sdkdom, devType, &sdkdisk); prlsdkCheckRetGoto(pret, cleanup); pret = PrlVmDev_SetEnabled(sdkdisk, 1); @@ -2713,6 +2780,14 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk) goto cleanup; } + if (bootDisk == true) { + pret = PrlVmDev_GetIndex(sdkdisk, &devIndex); + prlsdkCheckRetGoto(pret, cleanup); + + if (prlsdkAddDeviceToBootList(sdkdom, devIndex, devType, 0) < 0) + goto cleanup; + } + return 0; cleanup: PrlHandle_Free(sdkdisk); @@ -2766,6 +2841,7 @@ prlsdkDoApplyConfig(PRL_HANDLE sdkdom, PRL_RESULT pret; size_t i; char uuidstr[VIR_UUID_STRING_BUFLEN + 2]; + bool needBoot = true; if (prlsdkCheckUnsupportedParams(sdkdom, def) < 0) return -1; @@ -2796,6 +2872,9 @@ prlsdkDoApplyConfig(PRL_HANDLE sdkdom, if (prlsdkClearDevices(sdkdom) < 0) goto error; + if (prlsdkRemoveBootDevices(sdkdom) < 0) + goto error; + if (prlsdkApplyGraphicsParams(sdkdom, def) < 0) goto error; @@ -2813,7 +2892,15 @@ prlsdkDoApplyConfig(PRL_HANDLE sdkdom, } for (i = 0; i < def->ndisks; i++) { - if (prlsdkAddDisk(sdkdom, def->disks[i]) < 0) + bool bootDisk = false; + + if (needBoot == true && + def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) { + + needBoot = false; + bootDisk = true; + } + if (prlsdkAddDisk(sdkdom, def->disks[i], bootDisk) < 0) goto error; }