[libvirt] [PATCH v2 0/7] vz: add disk and controller check in domainPostParse phase

Changes from v1 =============== A new patch moving prlsdkCheckDiskUnsupportedParams to vz_utils.c added. Commit messages reworded. Minor formatting issues fixed. Maxim Nestratov (1): vz: move prlsdkCheckDiskUnsupportedParams to vz_utils.c Mikhail Feoktistov (6): vz: save vz version in connection structure vz: add vzCapabilities to connection structure vz: check supported disk format and bus vz: report correct disk format in domainGetXMLDesc vz: check supported controllers vz: set default SCSI model src/vz/vz_driver.c | 61 +++-------- src/vz/vz_sdk.c | 203 +++++++--------------------------- src/vz/vz_sdk.h | 2 +- src/vz/vz_utils.c | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vz/vz_utils.h | 24 ++++ 5 files changed, 397 insertions(+), 207 deletions(-) -- 2.4.3

From: Mikhail Feoktistov <mfeoktistov@virtuozzo.com> Move code from connectGetVersion callback to vzInitVersion function --- src/vz/vz_driver.c | 50 +++++++------------------------------------------- src/vz/vz_utils.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/vz/vz_utils.h | 3 +++ 3 files changed, 57 insertions(+), 43 deletions(-) diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c index 6de7cb9..5d48d7e 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -62,7 +62,6 @@ VIR_LOG_INIT("parallels.parallels_driver"); #define PRLCTL "prlctl" -#define PRLSRVCTL "prlsrvctl" static int vzConnectClose(virConnectPtr conn); @@ -234,6 +233,9 @@ vzOpenDefault(virConnectPtr conn) if (prlsdkConnect(privconn) < 0) goto err_free; + if (vzInitVersion(privconn) < 0) + goto error; + if (!(privconn->caps = vzBuildCapabilities())) goto error; @@ -345,49 +347,11 @@ vzConnectClose(virConnectPtr conn) } static int -vzConnectGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *hvVer) +vzConnectGetVersion(virConnectPtr conn, unsigned long *hvVer) { - char *output, *sVer, *tmp; - const char *searchStr = "prlsrvctl version "; - int ret = -1; - - output = vzGetOutput(PRLSRVCTL, "--help", NULL); - - if (!output) { - vzParseError(); - goto cleanup; - } - - if (!(sVer = strstr(output, searchStr))) { - vzParseError(); - goto cleanup; - } - - sVer = sVer + strlen(searchStr); - - /* parallels server has versions number like 6.0.17977.782218, - * so libvirt can handle only first two numbers. */ - if (!(tmp = strchr(sVer, '.'))) { - vzParseError(); - goto cleanup; - } - - if (!(tmp = strchr(tmp + 1, '.'))) { - vzParseError(); - goto cleanup; - } - - tmp[0] = '\0'; - if (virParseVersionString(sVer, hvVer, true) < 0) { - vzParseError(); - goto cleanup; - } - - ret = 0; - - cleanup: - VIR_FREE(output); - return ret; + vzConnPtr privconn = conn->privateData; + *hvVer = privconn->vzVersion; + return 0; } diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c index a1ddad0..cf37597 100644 --- a/src/vz/vz_utils.c +++ b/src/vz/vz_utils.c @@ -34,6 +34,7 @@ #include "datatypes.h" #define VIR_FROM_THIS VIR_FROM_PARALLELS +#define PRLSRVCTL "prlsrvctl" /** * vzDomObjFromDomain: @@ -178,3 +179,49 @@ vzNewDomain(vzConnPtr privconn, char *name, const unsigned char *uuid) VIR_FREE(pdom); return NULL; } + +int +vzInitVersion(vzConnPtr privconn) +{ + char *output, *sVer, *tmp; + const char *searchStr = "prlsrvctl version "; + int ret = -1; + + output = vzGetOutput(PRLSRVCTL, "--help", NULL); + + if (!output) { + vzParseError(); + goto cleanup; + } + + if (!(sVer = strstr(output, searchStr))) { + vzParseError(); + goto cleanup; + } + + sVer = sVer + strlen(searchStr); + + /* parallels server has versions number like 6.0.17977.782218 or 7.0.0, + * In libvirt we handle only first two numbers. */ + if (!(tmp = strchr(sVer, '.'))) { + vzParseError(); + goto cleanup; + } + + if (!(tmp = strchr(tmp + 1, '.'))) { + vzParseError(); + goto cleanup; + } + + tmp[0] = '\0'; + if (virParseVersionString(sVer, &(privconn->vzVersion), true) < 0) { + vzParseError(); + goto cleanup; + } + + ret = 0; + + cleanup: + VIR_FREE(output); + return ret; +} diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h index ed100ac..fbade2e 100644 --- a/src/vz/vz_utils.h +++ b/src/vz/vz_utils.h @@ -62,6 +62,7 @@ struct _vzConn { const char *drivername; /* Immutable pointer, self-locking APIs */ virConnectCloseCallbackDataPtr closeCallback; + unsigned long vzVersion; }; typedef struct _vzConn vzConn; @@ -97,6 +98,8 @@ virDomainObjPtr vzNewDomain(vzConnPtr privconn, char *name, const unsigned char *uuid); +int +vzInitVersion(vzConnPtr privconn); # define PARALLELS_BLOCK_STATS_FOREACH(OP) \ OP(rd_req, VIR_DOMAIN_BLOCK_STATS_READ_REQ, "read_requests") \ -- 2.4.3

From: Mikhail Feoktistov <mfeoktistov@virtuozzo.com> As far as Virtuozzo6 and Virtuozzo7 support different disk types for virtual machines (ploop and qcow2 respectively) and different buses (vz6: IDE, SCSI, SATA; vz7: IDE SCSI) we add vzCapabilities structure to help undestand which disk formats and buses are supported in the context of a current connection. When a new connection opens, we select proper capabilities in accordance to current Virtuozzo version. --- src/vz/vz_utils.c | 24 ++++++++++++++++++++++++ src/vz/vz_utils.h | 10 ++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c index cf37597..d8a95ac 100644 --- a/src/vz/vz_utils.c +++ b/src/vz/vz_utils.c @@ -36,6 +36,15 @@ #define VIR_FROM_THIS VIR_FROM_PARALLELS #define PRLSRVCTL "prlsrvctl" +static virDomainDiskBus vz6DiskBuses[] = {VIR_DOMAIN_DISK_BUS_IDE, + VIR_DOMAIN_DISK_BUS_SCSI, + VIR_DOMAIN_DISK_BUS_SATA, + VIR_DOMAIN_DISK_BUS_LAST}; + +static virDomainDiskBus vz7DiskBuses[] = {VIR_DOMAIN_DISK_BUS_IDE, + VIR_DOMAIN_DISK_BUS_SCSI, + VIR_DOMAIN_DISK_BUS_LAST}; + /** * vzDomObjFromDomain: * @domain: Domain pointer that has to be looked up @@ -180,6 +189,20 @@ vzNewDomain(vzConnPtr privconn, char *name, const unsigned char *uuid) return NULL; } +static void +vzInitCaps(unsigned long vzVersion, vzCapabilities *vzCaps) +{ + if (vzVersion < VIRTUOZZO_VER_7) { + vzCaps->ctDiskFormat = VIR_STORAGE_FILE_PLOOP; + vzCaps->vmDiskFormat = VIR_STORAGE_FILE_PLOOP; + vzCaps->diskBuses = vz6DiskBuses; + } else { + vzCaps->ctDiskFormat = VIR_STORAGE_FILE_PLOOP; + vzCaps->vmDiskFormat = VIR_STORAGE_FILE_QCOW2; + vzCaps->diskBuses = vz7DiskBuses; + } +} + int vzInitVersion(vzConnPtr privconn) { @@ -219,6 +242,7 @@ vzInitVersion(vzConnPtr privconn) goto cleanup; } + vzInitCaps(privconn->vzVersion, &privconn->vzCaps); ret = 0; cleanup: diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h index fbade2e..e0b0105 100644 --- a/src/vz/vz_utils.h +++ b/src/vz/vz_utils.h @@ -48,6 +48,15 @@ # define PARALLELS_DOMAIN_ROUTED_NETWORK_NAME "Routed" # define PARALLELS_DOMAIN_BRIDGED_NETWORK_NAME "Bridged" +# define VIRTUOZZO_VER_7 ((unsigned long) 7000000) + +struct _vzCapabilities { + virStorageFileFormat vmDiskFormat; + virStorageFileFormat ctDiskFormat; + virDomainDiskBus *diskBuses; +}; +typedef struct _vzCapabilities vzCapabilities; +typedef struct _vzCapabilities *vzCapabilitiesPtr; struct _vzConn { virMutex lock; @@ -63,6 +72,7 @@ struct _vzConn { /* Immutable pointer, self-locking APIs */ virConnectCloseCallbackDataPtr closeCallback; unsigned long vzVersion; + vzCapabilities vzCaps; }; typedef struct _vzConn vzConn; -- 2.4.3

From: Mikhail Feoktistov <mfeoktistov@virtuozzo.com> Now we check disk parameters correctness in DomainPostParse. Signed-off-by: Maxim Nestratov <mnestratov@virtuozzo.com> --- src/vz/vz_driver.c | 6 +++++- src/vz/vz_sdk.c | 24 ++---------------------- src/vz/vz_utils.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/vz/vz_utils.h | 3 +++ 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c index 5d48d7e..4f52bc7 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -175,8 +175,11 @@ static int vzDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED, virCapsPtr caps ATTRIBUTE_UNUSED, unsigned int parseFlags ATTRIBUTE_UNUSED, - void *opaque ATTRIBUTE_UNUSED) + void *opaque) { + if (vzCheckUnsupportedDisks(def, opaque) < 0) + return -1; + return 0; } @@ -239,6 +242,7 @@ vzOpenDefault(virConnectPtr conn) if (!(privconn->caps = vzBuildCapabilities())) goto error; + vzDomainDefParserConfig.priv = &privconn->vzCaps; if (!(privconn->xmlopt = virDomainXMLOptionNew(&vzDomainDefParserConfig, NULL, NULL))) goto error; diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index f7d769b..bac8feb 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -3137,30 +3137,10 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, pret = PrlVmDev_SetConnected(sdkdisk, 1); prlsdkCheckRetGoto(pret, cleanup); - if (disk->src->type == VIR_STORAGE_TYPE_FILE) { - if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK && - virDomainDiskGetFormat(disk) != VIR_STORAGE_FILE_PLOOP) { - - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid format of " - "disk %s, vz driver supports only " - "images in ploop format."), disk->src->path); - goto cleanup; - } - + if (disk->src->type == VIR_STORAGE_TYPE_FILE) emutype = PDT_USE_IMAGE_FILE; - } else { - if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK && - (virDomainDiskGetFormat(disk) != VIR_STORAGE_FILE_RAW && - virDomainDiskGetFormat(disk) != VIR_STORAGE_FILE_NONE && - virDomainDiskGetFormat(disk) != VIR_STORAGE_FILE_AUTO)) { - - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid format " - "of disk %s, it should be either not set, or set " - "to raw or auto."), disk->src->path); - goto cleanup; - } + else emutype = PDT_USE_REAL_DEVICE; - } pret = PrlVmDev_SetEmulatedType(sdkdisk, emutype); prlsdkCheckRetGoto(pret, cleanup); diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c index d8a95ac..f949887 100644 --- a/src/vz/vz_utils.c +++ b/src/vz/vz_utils.c @@ -249,3 +249,53 @@ vzInitVersion(vzConnPtr privconn) VIR_FREE(output); return ret; } + +int +vzCheckUnsupportedDisks(virDomainDefPtr def, vzCapabilitiesPtr vzCaps) +{ + size_t i, j; + virDomainDiskDefPtr disk; + virStorageFileFormat diskFormat; + bool supported; + + for (i = 0; i < def->ndisks; i++) { + disk = def->disks[i]; + diskFormat = virDomainDiskGetFormat(disk); + supported = true; + if (disk->src->type == VIR_STORAGE_TYPE_FILE) { + if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK && + diskFormat != VIR_STORAGE_FILE_NONE) { + + if (IS_CT(def)) + supported = vzCaps->ctDiskFormat == diskFormat; + else + supported = vzCaps->vmDiskFormat == diskFormat; + } + } else { + if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { + supported = diskFormat == VIR_STORAGE_FILE_RAW || + diskFormat == VIR_STORAGE_FILE_NONE || + diskFormat == VIR_STORAGE_FILE_AUTO; + } + } + + if (!supported) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported format of disk %s"), + disk->src->path); + return -1; + } + for (j = 0; vzCaps->diskBuses[j] != VIR_DOMAIN_DISK_BUS_LAST; j++) { + if (disk->bus == vzCaps->diskBuses[j]) + break; + } + + if (vzCaps->diskBuses[j] == VIR_DOMAIN_DISK_BUS_LAST) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported disk bus type %s"), + virDomainDiskBusTypeToString(disk->bus)); + return -1; + } + } + return 0; +} diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h index e0b0105..851322f 100644 --- a/src/vz/vz_utils.h +++ b/src/vz/vz_utils.h @@ -110,6 +110,9 @@ vzNewDomain(vzConnPtr privconn, const unsigned char *uuid); int vzInitVersion(vzConnPtr privconn); +int +vzCheckUnsupportedDisks(virDomainDefPtr def, + vzCapabilitiesPtr vzCaps); # define PARALLELS_BLOCK_STATS_FOREACH(OP) \ OP(rd_req, VIR_DOMAIN_BLOCK_STATS_READ_REQ, "read_requests") \ -- 2.4.3

As long as we have another function checking disk parameters correctness, let's have them in one place. Here we change prefix of the moved function and start to call it from vzCheckUnsupportedDisks rather than add disk. Signed-off-by: Maxim Nestratov <mnestratov@virtuozzo.com> --- src/vz/vz_sdk.c | 123 ----------------------------------------------------- src/vz/vz_utils.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 123 deletions(-) diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index bac8feb..d11e29f 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -2410,126 +2410,6 @@ static int prlsdkCheckNetUnsupportedParams(virDomainNetDefPtr net) return 0; } -static int prlsdkCheckDiskUnsupportedParams(virDomainDiskDefPtr disk) -{ - if (disk->device != VIR_DOMAIN_DISK_DEVICE_DISK && - disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) { - - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Only hard disks and cdroms are supported " - "by vz driver.")); - return -1; - } - - if (disk->blockio.logical_block_size || - disk->blockio.physical_block_size) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting disk block sizes is not " - "supported by vz driver.")); - return -1; - } - - if (disk->blkdeviotune.total_bytes_sec || - disk->blkdeviotune.read_bytes_sec || - disk->blkdeviotune.write_bytes_sec || - disk->blkdeviotune.total_iops_sec || - disk->blkdeviotune.read_iops_sec || - disk->blkdeviotune.write_iops_sec) { - - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting disk io limits is not " - "supported by vz driver yet.")); - return -1; - } - - if (disk->serial) { - VIR_INFO("%s", _("Setting disk serial number is not " - "supported by vz driver.")); - } - - if (disk->wwn) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting disk wwn id is not " - "supported by vz driver.")); - return -1; - } - - if (disk->vendor) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting disk vendor is not " - "supported by vz driver.")); - return -1; - } - - if (disk->product) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting disk product id is not " - "supported by vz driver.")); - return -1; - } - - if (disk->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_DEFAULT) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting disk error policy is not " - "supported by vz driver.")); - return -1; - } - - if (disk->iomode) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting disk io mode is not " - "supported by vz driver.")); - return -1; - } - - if (disk->copy_on_read) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Disk copy_on_read is not " - "supported by vz driver.")); - return -1; - } - - if (disk->startupPolicy != VIR_DOMAIN_STARTUP_POLICY_DEFAULT) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting up disk startup policy is not " - "supported by vz driver.")); - return -1; - } - - if (disk->transient) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Transient disks are not " - "supported by vz driver.")); - return -1; - } - - if (disk->discard) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting up disk discard parameter is not " - "supported by vz driver.")); - return -1; - } - - if (disk->iothread) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Setting up disk io thread # is not " - "supported by vz driver.")); - return -1; - } - - if (disk->src->type != VIR_STORAGE_TYPE_FILE && - disk->src->type != VIR_STORAGE_TYPE_BLOCK) { - - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Only disk and block storage types are " - "supported by vz driver.")); - return -1; - - } - - return 0; -} - static int prlsdkCheckFSUnsupportedParams(virDomainFSDefPtr fs) { if (fs->type != VIR_DOMAIN_FS_TYPE_FILE) { @@ -3120,9 +3000,6 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, PRL_DEVICE_TYPE devType; char *dst = NULL; - if (prlsdkCheckDiskUnsupportedParams(disk) < 0) - return -1; - if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) devType = PDE_HARD_DISK; else diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c index f949887..b616103 100644 --- a/src/vz/vz_utils.c +++ b/src/vz/vz_utils.c @@ -250,6 +250,127 @@ vzInitVersion(vzConnPtr privconn) return ret; } +static int +vzCheckDiskUnsupportedParams(virDomainDiskDefPtr disk) +{ + if (disk->device != VIR_DOMAIN_DISK_DEVICE_DISK && + disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) { + + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only hard disks and cdroms are supported " + "by vz driver.")); + return -1; + } + + if (disk->blockio.logical_block_size || + disk->blockio.physical_block_size) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting disk block sizes is not " + "supported by vz driver.")); + return -1; + } + + if (disk->blkdeviotune.total_bytes_sec || + disk->blkdeviotune.read_bytes_sec || + disk->blkdeviotune.write_bytes_sec || + disk->blkdeviotune.total_iops_sec || + disk->blkdeviotune.read_iops_sec || + disk->blkdeviotune.write_iops_sec) { + + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting disk io limits is not " + "supported by vz driver yet.")); + return -1; + } + + if (disk->serial) { + VIR_INFO("%s", _("Setting disk serial number is not " + "supported by vz driver.")); + } + + if (disk->wwn) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting disk wwn id is not " + "supported by vz driver.")); + return -1; + } + + if (disk->vendor) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting disk vendor is not " + "supported by vz driver.")); + return -1; + } + + if (disk->product) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting disk product id is not " + "supported by vz driver.")); + return -1; + } + + if (disk->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_DEFAULT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting disk error policy is not " + "supported by vz driver.")); + return -1; + } + + if (disk->iomode) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting disk io mode is not " + "supported by vz driver.")); + return -1; + } + + if (disk->copy_on_read) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Disk copy_on_read is not " + "supported by vz driver.")); + return -1; + } + + if (disk->startupPolicy != VIR_DOMAIN_STARTUP_POLICY_DEFAULT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting up disk startup policy is not " + "supported by vz driver.")); + return -1; + } + + if (disk->transient) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Transient disks are not " + "supported by vz driver.")); + return -1; + } + + if (disk->discard) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting up disk discard parameter is not " + "supported by vz driver.")); + return -1; + } + + if (disk->iothread) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting up disk io thread # is not " + "supported by vz driver.")); + return -1; + } + + if (disk->src->type != VIR_STORAGE_TYPE_FILE && + disk->src->type != VIR_STORAGE_TYPE_BLOCK) { + + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only disk and block storage types are " + "supported by vz driver.")); + return -1; + + } + + return 0; +} + int vzCheckUnsupportedDisks(virDomainDefPtr def, vzCapabilitiesPtr vzCaps) { @@ -260,6 +381,10 @@ vzCheckUnsupportedDisks(virDomainDefPtr def, vzCapabilitiesPtr vzCaps) for (i = 0; i < def->ndisks; i++) { disk = def->disks[i]; + + if (vzCheckDiskUnsupportedParams(disk) < 0) + return -1; + diskFormat = virDomainDiskGetFormat(disk); supported = true; if (disk->src->type == VIR_STORAGE_TYPE_FILE) { -- 2.4.3

From: Mikhail Feoktistov <mfeoktistov@virtuozzo.com> We should report correct disk format depending on vz version and domain type. Since we support only one disk format for each domain type, we can take it from vzCapabilities structure. --- src/vz/vz_sdk.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index d11e29f..eac6fb7 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -458,7 +458,8 @@ prlsdkAddDomainVideoInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) } static int -prlsdkGetDiskInfo(PRL_HANDLE prldisk, +prlsdkGetDiskInfo(vzConnPtr privconn, + PRL_HANDLE prldisk, virDomainDiskDefPtr disk, bool isCdrom, bool isCt) @@ -476,10 +477,14 @@ prlsdkGetDiskInfo(PRL_HANDLE prldisk, prlsdkCheckRetGoto(pret, cleanup); if (emulatedType == PDT_USE_IMAGE_FILE) { virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE); - if (isCdrom) + if (isCdrom) { virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW); - else - virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_PLOOP); + } else { + if (isCt) + virDomainDiskSetFormat(disk, privconn->vzCaps.ctDiskFormat); + else + virDomainDiskSetFormat(disk, privconn->vzCaps.vmDiskFormat); + } } else { virDomainDiskSetType(disk, VIR_STORAGE_TYPE_BLOCK); virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW); @@ -607,7 +612,7 @@ prlsdkGetFSInfo(PRL_HANDLE prldisk, } static int -prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) +prlsdkAddDomainHardDisksInfo(vzConnPtr privconn, PRL_HANDLE sdkdom, virDomainDefPtr def) { PRL_RESULT pret; PRL_UINT32 hddCount; @@ -647,7 +652,7 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) if (!(disk = virDomainDiskDefNew(NULL))) goto error; - if (prlsdkGetDiskInfo(hdd, disk, false, IS_CT(def)) < 0) + if (prlsdkGetDiskInfo(privconn, hdd, disk, false, IS_CT(def)) < 0) goto error; if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0) @@ -669,7 +674,7 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) } static int -prlsdkAddDomainOpticalDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) +prlsdkAddDomainOpticalDisksInfo(vzConnPtr privconn, PRL_HANDLE sdkdom, virDomainDefPtr def) { PRL_RESULT pret; PRL_UINT32 cdromsCount; @@ -687,7 +692,7 @@ prlsdkAddDomainOpticalDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) if (!(disk = virDomainDiskDefNew(NULL))) goto error; - if (prlsdkGetDiskInfo(cdrom, disk, true, IS_CT(def)) < 0) + if (prlsdkGetDiskInfo(privconn, cdrom, disk, true, IS_CT(def)) < 0) goto error; PrlHandle_Free(cdrom); @@ -950,16 +955,16 @@ prlsdkAddSerialInfo(PRL_HANDLE sdkdom, static int -prlsdkAddDomainHardware(PRL_HANDLE sdkdom, virDomainDefPtr def) +prlsdkAddDomainHardware(vzConnPtr privconn, PRL_HANDLE sdkdom, virDomainDefPtr def) { if (!IS_CT(def)) if (prlsdkAddDomainVideoInfo(sdkdom, def) < 0) goto error; - if (prlsdkAddDomainHardDisksInfo(sdkdom, def) < 0) + if (prlsdkAddDomainHardDisksInfo(privconn, sdkdom, def) < 0) goto error; - if (prlsdkAddDomainOpticalDisksInfo(sdkdom, def) < 0) + if (prlsdkAddDomainOpticalDisksInfo(privconn, sdkdom, def) < 0) goto error; if (prlsdkAddDomainNetInfo(sdkdom, def) < 0) @@ -1312,7 +1317,7 @@ prlsdkLoadDomain(vzConnPtr privconn, virDomainObjPtr dom) if (prlsdkConvertDomainType(sdkdom, def) < 0) goto error; - if (prlsdkAddDomainHardware(sdkdom, def) < 0) + if (prlsdkAddDomainHardware(privconn, sdkdom, def) < 0) goto error; if (prlsdkAddVNCInfo(sdkdom, def) < 0) -- 2.4.3

From: Mikhail Feoktistov <mfeoktistov@virtuozzo.com> Because Vz6 supports SCSI(BUSLOGIC), IDE and SATA controllers only and Vz7 supports SCSI(VIRTIO_SCSI) and IDE only we add list of supported controllers and scsi models to vzCapabilities structure. When a new connection opens, we select proper capabilities values according to Virtuozzo version and check them in XMLPostParse. Signed-off-by: Maxim Nestratov <mnestratov@virtuozzo.com> --- src/vz/vz_driver.c | 3 +++ src/vz/vz_utils.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/vz/vz_utils.h | 5 +++++ 3 files changed, 56 insertions(+) diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c index 4f52bc7..74e1f5d 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -180,6 +180,9 @@ vzDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED, if (vzCheckUnsupportedDisks(def, opaque) < 0) return -1; + if (vzCheckUnsupportedControllers(def, opaque) < 0) + return -1; + return 0; } diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c index b616103..a0fdc6c 100644 --- a/src/vz/vz_utils.c +++ b/src/vz/vz_utils.c @@ -45,6 +45,15 @@ static virDomainDiskBus vz7DiskBuses[] = {VIR_DOMAIN_DISK_BUS_IDE, VIR_DOMAIN_DISK_BUS_SCSI, VIR_DOMAIN_DISK_BUS_LAST}; +static virDomainControllerType vz6ControllerTypes[] = {VIR_DOMAIN_CONTROLLER_TYPE_SCSI, + VIR_DOMAIN_CONTROLLER_TYPE_IDE, + VIR_DOMAIN_CONTROLLER_TYPE_SATA, + VIR_DOMAIN_CONTROLLER_TYPE_LAST}; + +static virDomainControllerType vz7ControllerTypes[] = {VIR_DOMAIN_CONTROLLER_TYPE_SCSI, + VIR_DOMAIN_CONTROLLER_TYPE_IDE, + VIR_DOMAIN_CONTROLLER_TYPE_LAST}; + /** * vzDomObjFromDomain: * @domain: Domain pointer that has to be looked up @@ -196,10 +205,14 @@ vzInitCaps(unsigned long vzVersion, vzCapabilities *vzCaps) vzCaps->ctDiskFormat = VIR_STORAGE_FILE_PLOOP; vzCaps->vmDiskFormat = VIR_STORAGE_FILE_PLOOP; vzCaps->diskBuses = vz6DiskBuses; + vzCaps->controllerTypes = vz6ControllerTypes; + vzCaps->scsiControllerModel = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC; } else { vzCaps->ctDiskFormat = VIR_STORAGE_FILE_PLOOP; vzCaps->vmDiskFormat = VIR_STORAGE_FILE_QCOW2; vzCaps->diskBuses = vz7DiskBuses; + vzCaps->controllerTypes = vz7ControllerTypes; + vzCaps->scsiControllerModel = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI; } } @@ -424,3 +437,38 @@ vzCheckUnsupportedDisks(virDomainDefPtr def, vzCapabilitiesPtr vzCaps) } return 0; } + +int +vzCheckUnsupportedControllers(virDomainDefPtr def, vzCapabilitiesPtr vzCaps) +{ + size_t i, j; + virDomainControllerDefPtr controller; + + for (i = 0; i < def->ncontrollers; i++) { + controller = def->controllers[i]; + + for (j = 0; vzCaps->controllerTypes[j] != VIR_DOMAIN_CONTROLLER_TYPE_LAST; j++) { + if (controller->type == vzCaps->controllerTypes[j]) + break; + } + + if (vzCaps->controllerTypes[j] == VIR_DOMAIN_CONTROLLER_TYPE_LAST) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported controller type %s"), + virDomainControllerTypeToString(controller->type)); + return -1; + } + + if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + controller->model != -1 && + controller->model != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO && + controller->model != vzCaps->scsiControllerModel) { + + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported SCSI controller model %s"), + virDomainControllerModelSCSITypeToString(controller->model)); + return -1; + } + } + return 0; +} diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h index 851322f..88e74fc 100644 --- a/src/vz/vz_utils.h +++ b/src/vz/vz_utils.h @@ -54,6 +54,8 @@ struct _vzCapabilities { virStorageFileFormat vmDiskFormat; virStorageFileFormat ctDiskFormat; virDomainDiskBus *diskBuses; + virDomainControllerType *controllerTypes; + virDomainControllerModelSCSI scsiControllerModel; }; typedef struct _vzCapabilities vzCapabilities; typedef struct _vzCapabilities *vzCapabilitiesPtr; @@ -113,6 +115,9 @@ vzInitVersion(vzConnPtr privconn); int vzCheckUnsupportedDisks(virDomainDefPtr def, vzCapabilitiesPtr vzCaps); +int +vzCheckUnsupportedControllers(virDomainDefPtr def, + vzCapabilitiesPtr vzCaps); # define PARALLELS_BLOCK_STATS_FOREACH(OP) \ OP(rd_req, VIR_DOMAIN_BLOCK_STATS_READ_REQ, "read_requests") \ -- 2.4.3

From: Mikhail Feoktistov <mfeoktistov@virtuozzo.com> Each version of virtuozzo supports only one type of SCSI controller So if we add disk on SCSI bus, we should set SCSI controller model. We can take it from vzCapabilities structure. --- src/vz/vz_driver.c | 2 +- src/vz/vz_sdk.c | 27 +++++++++++++++++++++++---- src/vz/vz_sdk.h | 2 +- src/vz/vz_utils.c | 20 ++++++++++++++++++++ src/vz/vz_utils.h | 3 +++ 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c index 74e1f5d..b02e59f 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -1080,7 +1080,7 @@ static int vzDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: - ret = prlsdkAttachVolume(privdom, dev->data.disk); + ret = prlsdkAttachVolume(privconn, privdom, dev->data.disk); if (ret) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("disk attach failed")); diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index eac6fb7..1473866 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -2989,7 +2989,8 @@ static int prlsdkDelDisk(PRL_HANDLE sdkdom, int idx) return ret; } -static int prlsdkAddDisk(PRL_HANDLE sdkdom, +static int prlsdkAddDisk(vzConnPtr privconn, + PRL_HANDLE sdkdom, virDomainDiskDefPtr disk, bool bootDisk, bool isCt) @@ -3003,6 +3004,7 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDeviceDriveAddressPtr drive; PRL_UINT32 devIndex; PRL_DEVICE_TYPE devType; + PRL_CLUSTERED_DEVICE_SUBTYPE scsiModel; char *dst = NULL; if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) @@ -3100,6 +3102,13 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, goto cleanup; } + if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) { + if (vzGetDefaultSCSIModel(privconn, &scsiModel) < 0) + goto cleanup; + pret = PrlVmDev_SetSubType(sdkdisk, scsiModel); + prlsdkCheckRetGoto(pret, cleanup); + } + pret = PrlVmDev_SetIfaceType(sdkdisk, sdkbus); prlsdkCheckRetGoto(pret, cleanup); @@ -3147,7 +3156,9 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, } int -prlsdkAttachVolume(virDomainObjPtr dom, virDomainDiskDefPtr disk) +prlsdkAttachVolume(vzConnPtr privconn, + virDomainObjPtr dom, + virDomainDiskDefPtr disk) { int ret = -1; vzDomObjPtr privdom = dom->privateData; @@ -3157,7 +3168,11 @@ prlsdkAttachVolume(virDomainObjPtr dom, virDomainDiskDefPtr disk) if (PRL_FAILED(waitJob(job))) goto cleanup; - ret = prlsdkAddDisk(privdom->sdkdom, disk, false, IS_CT(dom->def)); + ret = prlsdkAddDisk(privconn, + privdom->sdkdom, + disk, + false, + IS_CT(dom->def)); if (ret == 0) { job = PrlVm_CommitEx(privdom->sdkdom, PVCF_DETACH_HDD_BUNDLE); if (PRL_FAILED(waitJob(job))) { @@ -3388,7 +3403,11 @@ prlsdkDoApplyConfig(virConnectPtr conn, needBoot = false; bootDisk = true; } - if (prlsdkAddDisk(sdkdom, def->disks[i], bootDisk, IS_CT(def)) < 0) + if (prlsdkAddDisk(conn->privateData, + sdkdom, + def->disks[i], + bootDisk, + IS_CT(def)) < 0) goto error; } diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h index c2d9cb4..8a38797 100644 --- a/src/vz/vz_sdk.h +++ b/src/vz/vz_sdk.h @@ -63,7 +63,7 @@ prlsdkUnregisterDomain(vzConnPtr privconn, virDomainObjPtr dom, unsigned int fla int prlsdkDomainManagedSaveRemove(virDomainObjPtr dom); int -prlsdkAttachVolume(virDomainObjPtr dom, virDomainDiskDefPtr disk); +prlsdkAttachVolume(vzConnPtr privconn, virDomainObjPtr dom, virDomainDiskDefPtr disk); int prlsdkDetachVolume(virDomainObjPtr dom, virDomainDiskDefPtr disk); int diff --git a/src/vz/vz_utils.c b/src/vz/vz_utils.c index a0fdc6c..7c5ae2a 100644 --- a/src/vz/vz_utils.c +++ b/src/vz/vz_utils.c @@ -472,3 +472,23 @@ vzCheckUnsupportedControllers(virDomainDefPtr def, vzCapabilitiesPtr vzCaps) } return 0; } + +int vzGetDefaultSCSIModel(vzConnPtr privconn, + PRL_CLUSTERED_DEVICE_SUBTYPE *scsiModel) +{ + switch (privconn->vzCaps.scsiControllerModel) { + case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: + *scsiModel = PCD_VIRTIO_SCSI; + break; + case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC: + *scsiModel = PCD_BUSLOGIC; + break; + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown SCSI controller model %s"), + virDomainControllerModelSCSITypeToString( + privconn->vzCaps.scsiControllerModel)); + return -1; + } + return 0; +} diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h index 88e74fc..f373850 100644 --- a/src/vz/vz_utils.h +++ b/src/vz/vz_utils.h @@ -118,6 +118,9 @@ vzCheckUnsupportedDisks(virDomainDefPtr def, int vzCheckUnsupportedControllers(virDomainDefPtr def, vzCapabilitiesPtr vzCaps); +int +vzGetDefaultSCSIModel(vzConnPtr privconn, + PRL_CLUSTERED_DEVICE_SUBTYPE *scsiModel); # define PARALLELS_BLOCK_STATS_FOREACH(OP) \ OP(rd_req, VIR_DOMAIN_BLOCK_STATS_READ_REQ, "read_requests") \ -- 2.4.3

ACK to the series, but please fix [patch 4/7] On 16.03.2016 17:21, Maxim Nestratov wrote:
Changes from v1 ===============
A new patch moving prlsdkCheckDiskUnsupportedParams to vz_utils.c added. Commit messages reworded. Minor formatting issues fixed.
Maxim Nestratov (1): vz: move prlsdkCheckDiskUnsupportedParams to vz_utils.c
Mikhail Feoktistov (6): vz: save vz version in connection structure vz: add vzCapabilities to connection structure vz: check supported disk format and bus vz: report correct disk format in domainGetXMLDesc vz: check supported controllers vz: set default SCSI model
src/vz/vz_driver.c | 61 +++-------- src/vz/vz_sdk.c | 203 +++++++--------------------------- src/vz/vz_sdk.h | 2 +- src/vz/vz_utils.c | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vz/vz_utils.h | 24 ++++ 5 files changed, 397 insertions(+), 207 deletions(-)
participants (2)
-
Maxim Nestratov
-
Mikhail Feoktistov