diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 391fb2c70fea81b2d17b57f48cdab98efbf2c561..7506895b3f3772b2a4ef6a6faeec4f0ed03c8157 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1018,26 +1018,28 @@ qemuGetSharedDeviceKey(const char *device_path) return key; } -/* Check if a shared device's setting conflicts with the conf - * used by other domain(s). Currently only checks the sgio - * setting. Note that this should only be called for disk with - * block source if the device type is disk. +/* + * Make necessary checks for the need to check and for the current setting + * of the 'unpriv_sgio' value for the device_path passed. * - * Returns 0 if no conflicts, otherwise returns -1. + * Returns: + * 0 - Success + * -1 - Some failure which would already have been messaged + * -2 - Mismatch with the "shared" sgio setting - needs to be messaged + * by caller since it has context of which type of disk resource is + * being used and in the future the hostdev information. */ static int -qemuCheckSharedDisk(virHashTablePtr sharedDevices, - virDomainDiskDefPtr disk) +qemuCheckUnprivSGIO(virHashTablePtr sharedDevices, + const char *device_path, + int sgio) { char *sysfs_path = NULL; char *key = NULL; int val; int ret = -1; - if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) - return 0; - - if (!(sysfs_path = virGetUnprivSGIOSysfsPath(disk->src->path, NULL))) + if (!(sysfs_path = virGetUnprivSGIOSysfsPath(device_path, NULL))) goto cleanup; /* It can't be conflict if unpriv_sgio is not supported by kernel. */ @@ -1046,7 +1048,7 @@ qemuCheckSharedDisk(virHashTablePtr sharedDevices, goto cleanup; } - if (!(key = qemuGetSharedDeviceKey(disk->src->path))) + if (!(key = qemuGetSharedDeviceKey(device_path))) goto cleanup; /* It can't be conflict if no other domain is sharing it. */ @@ -1055,27 +1057,18 @@ qemuCheckSharedDisk(virHashTablePtr sharedDevices, goto cleanup; } - if (virGetDeviceUnprivSGIO(disk->src->path, NULL, &val) < 0) + if (virGetDeviceUnprivSGIO(device_path, NULL, &val) < 0) goto cleanup; + /* Error message on failure needs to be handled in caller + * since there is more specific knowledge of device + */ if (!((val == 0 && - (disk->sgio == VIR_DOMAIN_DEVICE_SGIO_FILTERED || - disk->sgio == VIR_DOMAIN_DEVICE_SGIO_DEFAULT)) || + (sgio == VIR_DOMAIN_DEVICE_SGIO_FILTERED || + sgio == VIR_DOMAIN_DEVICE_SGIO_DEFAULT)) || (val == 1 && - disk->sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED))) { - - if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_VOLUME) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("sgio of shared disk 'pool=%s' 'volume=%s' conflicts " - "with other active domains"), - disk->src->srcpool->pool, - disk->src->srcpool->volume); - } else { - virReportError(VIR_ERR_OPERATION_INVALID, - _("sgio of shared disk '%s' conflicts with other " - "active domains"), disk->src->path); - } - + sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED))) { + ret = -2; goto cleanup; } @@ -1088,6 +1081,45 @@ qemuCheckSharedDisk(virHashTablePtr sharedDevices, } +/* Check if a shared device's setting conflicts with the conf + * used by other domain(s). Currently only checks the sgio + * setting. Note that this should only be called for disk with + * block source if the device type is disk. + * + * Returns 0 if no conflicts, otherwise returns -1. + */ +static int +qemuCheckSharedDisk(virHashTablePtr sharedDevices, + virDomainDiskDefPtr disk) +{ + int ret; + + if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) + return 0; + + if ((ret = qemuCheckUnprivSGIO(sharedDevices, disk->src->path, + disk->sgio)) < 0) { + if (ret == -2) { + if (virDomainDiskGetType(disk) == VIR_STORAGE_TYPE_VOLUME) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("sgio of shared disk 'pool=%s' 'volume=%s' " + "conflicts with other active domains"), + disk->src->srcpool->pool, + disk->src->srcpool->volume); + } else { + virReportError(VIR_ERR_OPERATION_INVALID, + _("sgio of shared disk '%s' conflicts with " + "other active domains"), + disk->src->path); + } + } + return -1; + } + + return 0; +} + + bool qemuSharedDeviceEntryDomainExists(qemuSharedDeviceEntryPtr entry, const char *name,