mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-25 22:15:20 +00:00
parallels: make device addressing consistent
In Parallels we do not support device name hints aka <target dev=../> option and full-fledged device disk device addressing through <address type=.. controller=.. bus=.. target=.. unit=../> and have only one index instead. In this situation to be consistent we can only take one-to-one mapping from some reasonable subset of full address. Values outside this subset are invalid to create Parallels VMs. Reasonable mapping is default one defined in virDomainDiskDefAssignAddress. Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@parallels.com>
This commit is contained in:
parent
21f62d60f6
commit
6b7b677a0e
@ -462,7 +462,7 @@ prlsdkGetDiskInfo(PRL_HANDLE prldisk,
|
|||||||
PRL_UINT32 emulatedType;
|
PRL_UINT32 emulatedType;
|
||||||
PRL_UINT32 ifType;
|
PRL_UINT32 ifType;
|
||||||
PRL_UINT32 pos;
|
PRL_UINT32 pos;
|
||||||
PRL_UINT32 prldiskIndex;
|
virDomainDeviceDriveAddressPtr address;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
pret = PrlVmDev_GetEmulatedType(prldisk, &emulatedType);
|
pret = PrlVmDev_GetEmulatedType(prldisk, &emulatedType);
|
||||||
@ -499,15 +499,32 @@ prlsdkGetDiskInfo(PRL_HANDLE prldisk,
|
|||||||
|
|
||||||
pret = PrlVmDev_GetIfaceType(prldisk, &ifType);
|
pret = PrlVmDev_GetIfaceType(prldisk, &ifType);
|
||||||
prlsdkCheckRetGoto(pret, cleanup);
|
prlsdkCheckRetGoto(pret, cleanup);
|
||||||
|
|
||||||
|
pret = PrlVmDev_GetStackIndex(prldisk, &pos);
|
||||||
|
prlsdkCheckRetGoto(pret, cleanup);
|
||||||
|
|
||||||
|
address = &disk->info.addr.drive;
|
||||||
switch (ifType) {
|
switch (ifType) {
|
||||||
case PMS_IDE_DEVICE:
|
case PMS_IDE_DEVICE:
|
||||||
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
||||||
|
disk->dst = virIndexToDiskName(pos, "hd");
|
||||||
|
address->bus = pos / 2;
|
||||||
|
address->target = 0;
|
||||||
|
address->unit = pos % 2;
|
||||||
break;
|
break;
|
||||||
case PMS_SCSI_DEVICE:
|
case PMS_SCSI_DEVICE:
|
||||||
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
|
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
|
||||||
|
disk->dst = virIndexToDiskName(pos, "sd");
|
||||||
|
address->bus = 0;
|
||||||
|
address->target = 0;
|
||||||
|
address->unit = pos;
|
||||||
break;
|
break;
|
||||||
case PMS_SATA_DEVICE:
|
case PMS_SATA_DEVICE:
|
||||||
disk->bus = VIR_DOMAIN_DISK_BUS_SATA;
|
disk->bus = VIR_DOMAIN_DISK_BUS_SATA;
|
||||||
|
disk->dst = virIndexToDiskName(pos, "sd");
|
||||||
|
address->bus = 0;
|
||||||
|
address->target = 0;
|
||||||
|
address->unit = pos;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -516,17 +533,10 @@ prlsdkGetDiskInfo(PRL_HANDLE prldisk,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pret = PrlVmDev_GetStackIndex(prldisk, &pos);
|
if (!disk->dst)
|
||||||
prlsdkCheckRetGoto(pret, cleanup);
|
goto cleanup;
|
||||||
|
|
||||||
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
||||||
disk->info.addr.drive.target = pos;
|
|
||||||
|
|
||||||
pret = PrlVmDev_GetIndex(prldisk, &prldiskIndex);
|
|
||||||
prlsdkCheckRetGoto(pret, cleanup);
|
|
||||||
|
|
||||||
if (!(disk->dst = virIndexToDiskName(prldiskIndex, "sd")))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
@ -2850,6 +2860,7 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk, bool bootD
|
|||||||
virDomainDeviceDriveAddressPtr drive;
|
virDomainDeviceDriveAddressPtr drive;
|
||||||
PRL_UINT32 devIndex;
|
PRL_UINT32 devIndex;
|
||||||
PRL_DEVICE_TYPE devType;
|
PRL_DEVICE_TYPE devType;
|
||||||
|
char *dst = NULL;
|
||||||
|
|
||||||
if (prlsdkCheckDiskUnsupportedParams(disk) < 0)
|
if (prlsdkCheckDiskUnsupportedParams(disk) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -2907,22 +2918,50 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk, bool bootD
|
|||||||
/* We have only one controller of each type */
|
/* We have only one controller of each type */
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid drive "
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid drive "
|
||||||
"address of disk %s, Parallels Cloud Server has "
|
"address of disk %s, Parallels Cloud Server has "
|
||||||
"only one controller."), disk->src->path);
|
"only one controller."), disk->dst);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drive->target > 0) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid drive "
|
||||||
|
"address of disk %s, Parallels Cloud Server has "
|
||||||
|
"only target 0."), disk->dst);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (disk->bus) {
|
switch (disk->bus) {
|
||||||
case VIR_DOMAIN_DISK_BUS_IDE:
|
case VIR_DOMAIN_DISK_BUS_IDE:
|
||||||
|
if (drive->unit > 1) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid drive "
|
||||||
|
"address of disk %s, Parallels Cloud Server has "
|
||||||
|
"only units 0-1 for IDE bus."), disk->dst);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
sdkbus = PMS_IDE_DEVICE;
|
sdkbus = PMS_IDE_DEVICE;
|
||||||
idx = 2 * drive->bus + drive->unit;
|
idx = 2 * drive->bus + drive->unit;
|
||||||
|
dst = virIndexToDiskName(idx, "hd");
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DISK_BUS_SCSI:
|
case VIR_DOMAIN_DISK_BUS_SCSI:
|
||||||
|
if (drive->bus > 0) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid drive "
|
||||||
|
"address of disk %s, Parallels Cloud Server has "
|
||||||
|
"only bus 0 for SCSI bus."), disk->dst);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
sdkbus = PMS_SCSI_DEVICE;
|
sdkbus = PMS_SCSI_DEVICE;
|
||||||
idx = drive->unit;
|
idx = drive->unit;
|
||||||
|
dst = virIndexToDiskName(idx, "sd");
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DISK_BUS_SATA:
|
case VIR_DOMAIN_DISK_BUS_SATA:
|
||||||
|
if (drive->bus > 0) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid drive "
|
||||||
|
"address of disk %s, Parallels Cloud Server has "
|
||||||
|
"only bus 0 for SATA bus."), disk->dst);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
sdkbus = PMS_SATA_DEVICE;
|
sdkbus = PMS_SATA_DEVICE;
|
||||||
idx = drive->unit;
|
idx = drive->unit;
|
||||||
|
dst = virIndexToDiskName(idx, "sd");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
@ -2931,6 +2970,16 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk, bool bootD
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dst)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (STRNEQ(dst, disk->dst)) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid drive "
|
||||||
|
"address of disk %s, Parallels Cloud Server supports "
|
||||||
|
"only defaults address to logical device name."), disk->dst);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
pret = PrlVmDev_SetIfaceType(sdkdisk, sdkbus);
|
pret = PrlVmDev_SetIfaceType(sdkdisk, sdkbus);
|
||||||
prlsdkCheckRetGoto(pret, cleanup);
|
prlsdkCheckRetGoto(pret, cleanup);
|
||||||
|
|
||||||
@ -2966,6 +3015,7 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk, bool bootD
|
|||||||
return 0;
|
return 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
PrlHandle_Free(sdkdisk);
|
PrlHandle_Free(sdkdisk);
|
||||||
|
VIR_FREE(dst);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user