Daniel Erez has uploaded a new change for review. Change subject: core: introducing virtio-scsi support ......................................................................
core: introducing virtio-scsi support A new DiskInterface type: VirtIO_SCSI * Available for both DiskImage and LunDisk * Supported for Cluster 3.3 and above - Added 'VirtIoScsiEnabled' ConfigValue * OS Guest support - Added 'VirtIoScsiUnsupportedOsList' ConfigValue * VmInfoBuilder - adapting to VDSM API - Interface attribute: iface='scsi' - Controller element is sent when required (if there's at least one disk with virtio-scsi interface) SGIO [1] * Avaiable for DirectLUN disks with VirtIO-SCSI interface * Added ScsiGenericIO enum: filtered/unfiltered * Added 'sgio' column to 'base_disks' table - Updated relevant views: vm_images_storage_domains_view, images_storage_domain_view storage_for_image_view, all_disks * Should be restricted by MLA permissions - A new ActionGroup: CONFIGURE_SCSI_GENERIC_IO - Granted to DataCenterAdmin and SuperUser roles - Verified on AddDiskCommand and UpdateVmDiskCommand * VmInfoBuilder - adapting to VDSM API - 'sgio' attribute on disk element [1] 'sgio': SCSI Generic IO - filtered/unfiltered (indicates whether the OS kernel will filter unprivileged SG_IO commands for the disk). * Feature page: http://www.ovirt.org/Features/Virtio-SCSI Change-Id: Ie572b8106b3fe5becec69c140546db81bc671c96 Signed-off-by: Daniel Erez <[email protected]> --- M backend/manager/dbscripts/base_disks_sp.sql M backend/manager/dbscripts/create_views.sql A backend/manager/dbscripts/upgrade/03_03_0160_add_base_disks_sgio_column.sql A backend/manager/dbscripts/upgrade/03_03_0170_add_permission_to_configure_sgio.sql M backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AttachDiskToVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmDiskCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java M backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ActionGroup.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/BaseDisk.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/DiskInterface.java A backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ScsiGenericIO.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/VmDeviceType.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/AbstractBaseDiskRowMapper.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDiskDaoDbFacadeImpl.java M backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties M backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/BaseDiskDaoTest.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VmInfoBuilder.java 26 files changed, 272 insertions(+), 34 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/06/14906/1 diff --git a/backend/manager/dbscripts/base_disks_sp.sql b/backend/manager/dbscripts/base_disks_sp.sql index 25fc34c..940ed74 100644 --- a/backend/manager/dbscripts/base_disks_sp.sql +++ b/backend/manager/dbscripts/base_disks_sp.sql @@ -15,7 +15,8 @@ v_disk_alias VARCHAR(50), v_disk_description VARCHAR(500), v_shareable BOOLEAN, - v_boot BOOLEAN) + v_boot BOOLEAN, + v_sgio INTEGER) RETURNS VOID AS $procedure$ BEGIN @@ -27,7 +28,8 @@ disk_alias, disk_description, shareable, - boot) + boot, + sgio) VALUES( v_disk_id, v_disk_interface, @@ -36,7 +38,8 @@ v_disk_alias, v_disk_description, v_shareable, - v_boot); + v_boot, + v_sgio); END; $procedure$ LANGUAGE plpgsql; @@ -52,7 +55,8 @@ v_disk_alias VARCHAR(50), v_disk_description VARCHAR(500), v_shareable BOOLEAN, - v_boot BOOLEAN) + v_boot BOOLEAN, + v_sgio INTEGER) RETURNS VOID AS $procedure$ BEGIN @@ -63,7 +67,8 @@ disk_alias = v_disk_alias, disk_description = v_disk_description, shareable = v_shareable, - boot = v_boot + boot = v_boot, + sgio = v_sgio WHERE disk_id = v_disk_id; END; $procedure$ LANGUAGE plpgsql; diff --git a/backend/manager/dbscripts/create_views.sql b/backend/manager/dbscripts/create_views.sql index aa27228..f2f9d5a 100644 --- a/backend/manager/dbscripts/create_views.sql +++ b/backend/manager/dbscripts/create_views.sql @@ -62,6 +62,7 @@ base_disks.wipe_after_delete as wipe_after_delete, base_disks.propagate_errors, base_disks.boot as boot, + base_disks.sgio as sgio, images.quota_id as quota_id, quota.quota_name as quota_name, storage_pool.quota_enforcement_type, @@ -128,7 +129,7 @@ images_storage_domain_view.app_list as app_list, images_storage_domain_view.vm_snapshot_id as vm_snapshot_id, images_storage_domain_view.volume_type as volume_type, images_storage_domain_view.image_group_id as image_group_id, images_storage_domain_view.active as active, images_storage_domain_view.volume_format as volume_format, - images_storage_domain_view.disk_interface as disk_interface, images_storage_domain_view.boot as boot, images_storage_domain_view.wipe_after_delete as wipe_after_delete, images_storage_domain_view.propagate_errors as propagate_errors, + images_storage_domain_view.disk_interface as disk_interface, images_storage_domain_view.boot as boot, images_storage_domain_view.wipe_after_delete as wipe_after_delete, images_storage_domain_view.propagate_errors as propagate_errors, images_storage_domain_view.sgio as sgio, images_storage_domain_view.entity_type as entity_type,images_storage_domain_view.number_of_vms as number_of_vms,images_storage_domain_view.vm_names as vm_names, images_storage_domain_view.quota_id as quota_id, images_storage_domain_view.quota_name as quota_name, images_storage_domain_view.quota_enforcement_type, images_storage_domain_view.disk_id, images_storage_domain_view.disk_alias as disk_alias, images_storage_domain_view.disk_description as disk_description,images_storage_domain_view.shareable as shareable @@ -148,7 +149,8 @@ bd.disk_alias, bd.disk_description, bd.shareable, - bd.boot + bd.boot, + bd.sgio FROM ( SELECT 0 AS disk_storage_type, @@ -951,7 +953,7 @@ vm_images_view.imagestatus, vm_images_view.lastmodified, vm_images_view.app_list, vm_images_view.vm_snapshot_id, vm_images_view.volume_type, vm_images_view.image_group_id, vm_images_view.active, vm_images_view.volume_format, vm_images_view.disk_interface, vm_images_view.boot, vm_images_view.wipe_after_delete, vm_images_view.propagate_errors, vm_images_view.entity_type, vm_images_view.number_of_vms, vm_images_view.vm_names, vm_images_view.quota_id, - vm_images_view.quota_name, vm_images_view.disk_alias, vm_images_view.disk_description, + vm_images_view.quota_name, vm_images_view.disk_alias, vm_images_view.disk_description, vm_images_view.sgio, storage_domains_with_hosts_view.id, storage_domains_with_hosts_view.storage, storage_domains_with_hosts_view.storage_name, storage_domains_with_hosts_view.available_disk_size, storage_domains_with_hosts_view.used_disk_size, storage_domains_with_hosts_view.commited_disk_size, storage_domains_with_hosts_view.storage_type, diff --git a/backend/manager/dbscripts/upgrade/03_03_0160_add_base_disks_sgio_column.sql b/backend/manager/dbscripts/upgrade/03_03_0160_add_base_disks_sgio_column.sql new file mode 100644 index 0000000..9837279 --- /dev/null +++ b/backend/manager/dbscripts/upgrade/03_03_0160_add_base_disks_sgio_column.sql @@ -0,0 +1 @@ +select fn_db_add_column('base_disks', 'sgio', 'SMALLINT DEFAULT NULL'); diff --git a/backend/manager/dbscripts/upgrade/03_03_0170_add_permission_to_configure_sgio.sql b/backend/manager/dbscripts/upgrade/03_03_0170_add_permission_to_configure_sgio.sql new file mode 100644 index 0000000..31ec3a8 --- /dev/null +++ b/backend/manager/dbscripts/upgrade/03_03_0170_add_permission_to_configure_sgio.sql @@ -0,0 +1,4 @@ +-- Add CONFIGURE_SCSI_GENERIC_IO action_group to DataCenterAdmin role +select fn_db_add_action_group_to_role('def00002-0000-0000-0000-def000000002', 1105); +-- Add CONFIGURE_SCSI_GENERIC_IO action_group to SuperUser role +select fn_db_add_action_group_to_role('00000000-0000-0000-0000-000000000001', 1105); \ No newline at end of file diff --git a/backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql b/backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql index 14779e6..3e35cb5 100644 --- a/backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql +++ b/backend/manager/dbscripts/upgrade/pre_upgrade/0000_config.sql @@ -169,6 +169,11 @@ select fn_db_add_config_value('MigrationNetworkEnabled','false','3.1'); select fn_db_add_config_value('MigrationNetworkEnabled','false','3.2'); select fn_db_add_config_value('MigrationNetworkEnabled','true','3.3'); +select fn_db_add_config_value('VirtIoScsiEnabled','false','3.0'); +select fn_db_add_config_value('VirtIoScsiEnabled','false','3.1'); +select fn_db_add_config_value('VirtIoScsiEnabled','false','3.2'); +select fn_db_add_config_value('VirtIoScsiEnabled','true','3.3'); +select fn_db_add_config_value('VirtIoScsiUnsupportedOsList','WindowsXP,RHEL5,RHEL5x64,RHEL4,RHEL4x64,RHEL3,RHEL3x64','general'); -- by default use no proxy select fn_db_add_config_value('SpiceProxyDefault','','general'); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java index 40cf672..587092a 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AbstractDiskVmCommand.java @@ -128,6 +128,46 @@ VmHandler.updateDisksFromDb(getVm()); } + protected boolean validateVirtIoScsi(Disk oldDisk, Disk newDisk) { + if (DiskInterface.VirtIO_SCSI != newDisk.getDiskInterface()) { + return true; + } + + if (!isVersionSupportedForVirtIoScsi(oldDisk, getVm().getVdsGroupCompatibilityVersion().getValue())) { + addCanDoActionMessage(VdcBllMessages.ACTION_NOT_SUPPORTED_FOR_CLUSTER_POOL_LEVEL); + return false; + } + + if (!isOsSupportedForVirtIoScsi()) { + return false; + } + + if (newDisk.getSgio() != null) { + if (DiskStorageType.IMAGE == oldDisk.getDiskStorageType()) { + addCanDoActionMessage(VdcBllMessages.SCSI_GENERIC_IO_IS_NOT_SUPPORTED_FOR_IMAGE_DISK); + return false; + } + } + + return true; + } + + protected boolean isOsSupportedForVirtIoScsi() { + String vmOs = getVm().getOs().name(); + String[] unsupportedOSs = Config.<String> GetValue(ConfigValues.VirtIoScsiUnsupportedOsList).split(","); + for (String os : unsupportedOSs) { + if (os.equalsIgnoreCase(vmOs)) { + addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_GUEST_OS_VERSION_IS_NOT_SUPPORTED); + return false; + } + } + return true; + } + + protected boolean isVersionSupportedForVirtIoScsi(Disk disk, String clusterVersion) { + return Config.<Boolean> GetValue(ConfigValues.VirtIoScsiEnabled, clusterVersion); + } + protected boolean isVersionSupportedForShareable(Disk disk, String compVersion) { if (disk.getDiskStorageType() == DiskStorageType.IMAGE) { return Config.<Boolean> GetValue(ConfigValues.ShareableDiskEnabled, compVersion); @@ -165,7 +205,7 @@ } protected boolean isInterfaceSupportedForPlugUnPlug(Disk disk) { - if (!DiskInterface.VirtIO.equals(disk.getDiskInterface())) { + if (!(DiskInterface.VirtIO.equals(disk.getDiskInterface()) || DiskInterface.VirtIO_SCSI.equals(disk.getDiskInterface()))) { addCanDoActionMessage(VdcBllMessages.HOT_PLUG_DISK_IS_NOT_VIRTIO); return false; } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java index 410125f..af06d28 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AddDiskCommand.java @@ -29,6 +29,7 @@ import org.ovirt.engine.core.common.businessentities.DiskLunMap; import org.ovirt.engine.core.common.businessentities.LUNs; import org.ovirt.engine.core.common.businessentities.LunDisk; +import org.ovirt.engine.core.common.businessentities.ScsiGenericIO; import org.ovirt.engine.core.common.businessentities.Snapshot.SnapshotType; import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.StoragePool; @@ -131,6 +132,10 @@ return false; } + if (!validateVirtIoScsi(getParameters().getDiskInfo(), getParameters().getDiskInfo())) { + return false; + } + return true; } @@ -143,7 +148,8 @@ checkImageConfiguration() && hasFreeSpace(getStorageDomain()) && checkExceedingMaxBlockDiskSize() && - canAddShareableDisk(); + canAddShareableDisk() && + validateVirtIoScsi(getParameters().getDiskInfo(), getParameters().getDiskInfo()); if (returnValue && vm != null) { StoragePool sp = getStoragePool(); // Note this is done according to the VM's spId. @@ -306,6 +312,11 @@ listPermissionSubjects.add(new PermissionSubject(Guid.SYSTEM, VdcObjectType.System, ActionGroup.CREATE_DISK)); + if (getParameters().getDiskInfo().getSgio() == ScsiGenericIO.UNFILTERED) { + listPermissionSubjects.add(new PermissionSubject(Guid.SYSTEM, + VdcObjectType.System, + ActionGroup.CONFIGURE_SCSI_GENERIC_IO)); + } } else { listPermissionSubjects.add(new PermissionSubject(getParameters().getStorageDomainId(), VdcObjectType.Storage, diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AttachDiskToVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AttachDiskToVmCommand.java index 941b2bf..f15ec24 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AttachDiskToVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/AttachDiskToVmCommand.java @@ -95,6 +95,10 @@ return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_POOL_NOT_MATCH); } + if (!validateVirtIoScsi(disk, disk)) { + return false; + } + if (!isVmNotInPreviewSnapshot()) { return false; } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmDiskCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmDiskCommand.java index b0f9db2..fd5b9c4 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmDiskCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/UpdateVmDiskCommand.java @@ -83,7 +83,7 @@ // Set disk alias name in the disk retrieved from the parameters. ImagesHandler.setDiskAlias(newDisk, getVm()); - return validateShareableDisk(); + return validateShareableDisk() && validateVirtIoScsi(oldDisk, newDisk); } @@ -223,6 +223,12 @@ listPermissionSubjects.add(new PermissionSubject(diskId, VdcObjectType.Disk, ActionGroup.EDIT_DISK_PROPERTIES)); + + if (oldDisk != null && newDisk != null && oldDisk.getSgio() != newDisk.getSgio()) { + listPermissionSubjects.add(new PermissionSubject(diskId, + VdcObjectType.Disk, + ActionGroup.CONFIGURE_SCSI_GENERIC_IO)); + } } return listPermissionSubjects; } @@ -240,6 +246,7 @@ oldDisk.setDiskAlias(newDisk.getDiskAlias()); oldDisk.setDiskDescription(newDisk.getDiskDescription()); oldDisk.setShareable(newDisk.isShareable()); + oldDisk.setSgio(newDisk.getSgio()); getBaseDiskDao().update(oldDisk); if (oldDisk.getDiskStorageType() == DiskStorageType.IMAGE) { DiskImage diskImage = (DiskImage) oldDisk; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java index 9bdb2ef..d21cc7d 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java @@ -127,10 +127,18 @@ pciInUse += LinqUtils.filter(disks, new Predicate<T>() { @Override public boolean eval(T a) { - return a.getDiskInterface() != DiskInterface.IDE; + return a.getDiskInterface() == DiskInterface.VirtIO; } }).size(); + // VirtIO SCSI controller requires one PCI slot + pciInUse += LinqUtils.filter(disks, new Predicate<T>() { + @Override + public boolean eval(T a) { + return a.getDiskInterface() == DiskInterface.VirtIO_SCSI; + } + }).isEmpty() ? 0 : 1; + if (pciInUse > MAX_PCI_SLOTS) { result = false; messages.add(VdcBllMessages.ACTION_TYPE_FAILED_EXCEEDED_MAX_PCI_SLOTS.name()); diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java index 8ceecb6..dcb0e70 100644 --- a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java @@ -28,8 +28,10 @@ import org.ovirt.engine.core.common.businessentities.DiskInterface; import org.ovirt.engine.core.common.businessentities.LUNs; import org.ovirt.engine.core.common.businessentities.LunDisk; +import org.ovirt.engine.core.common.businessentities.ScsiGenericIO; import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.StorageDomainStatus; +import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMap; import org.ovirt.engine.core.common.businessentities.StoragePoolIsoMapId; import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; @@ -37,9 +39,9 @@ import org.ovirt.engine.core.common.businessentities.StorageType; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; +import org.ovirt.engine.core.common.businessentities.VmOsType; import org.ovirt.engine.core.common.businessentities.VolumeFormat; import org.ovirt.engine.core.common.businessentities.VolumeType; -import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.Version; @@ -64,7 +66,10 @@ public static MockConfigRule mcr = new MockConfigRule( mockConfig(ConfigValues.MaxBlockDiskSize, MAX_BLOCK_SIZE), mockConfig(ConfigValues.FreeSpaceCriticalLowInGB, FREE_SPACE_CRITICAL_LOW_IN_GB), - mockConfig(ConfigValues.ShareableDiskEnabled, Version.v3_1.toString(), true) + mockConfig(ConfigValues.ShareableDiskEnabled, Version.v3_1.toString(), true), + mockConfig(ConfigValues.VirtIoScsiEnabled, Version.v3_3.toString(), true), + mockConfig(ConfigValues.VirtIoScsiUnsupportedOsList, + "WindowsXP,RHEL5,RHEL5x64,RHEL4,RHEL4x64,RHEL3,RHEL3x64") ); @Mock @@ -473,6 +478,12 @@ return image; } + private static DiskImage createVirtIoScsiDiskImage() { + DiskImage image = new DiskImage(); + image.setDiskInterface(DiskInterface.VirtIO_SCSI); + return image; + } + private static LunDisk createISCSILunDisk() { LunDisk disk = new LunDisk(); LUNs lun = new LUNs(); @@ -597,7 +608,61 @@ vm.getDiskMap().put(Guid.NewGuid(), disk); CanDoActionTestUtils.runAndAssertCanDoActionFailure(command, VdcBllMessages.ACTION_TYPE_FAILED_EXCEEDED_MAX_PCI_SLOTS); + } + @Test + public void testVirtIoScsiNotSupportedByOs() { + DiskImage disk = createVirtIoScsiDiskImage(); + AddDiskParameters parameters = createParameters(); + parameters.setDiskInfo(disk); + + Guid storageId = Guid.NewGuid(); + initializeCommand(storageId, parameters); + mockStorageDomain(storageId); + mockStoragePoolIsoMap(); + + VM vm = mockVm(); + vm.setVdsGroupCompatibilityVersion(Version.v3_3); + vm.setVmOs(VmOsType.RHEL5); + + CanDoActionTestUtils.runAndAssertCanDoActionFailure(command, + VdcBllMessages.ACTION_TYPE_FAILED_GUEST_OS_VERSION_IS_NOT_SUPPORTED); + } + + @Test + public void testLunDiskWithSgioCanBeAdded() { + DiskImage disk = createVirtIoScsiDiskImage(); + disk.setSgio(ScsiGenericIO.UNFILTERED); + + AddDiskParameters parameters = createParameters(); + parameters.setDiskInfo(disk); + + Guid storageId = Guid.NewGuid(); + initializeCommand(storageId, parameters); + mockStorageDomain(storageId); + mockStoragePoolIsoMap(); + + VM vm = mockVm(); + vm.setVdsGroupCompatibilityVersion(Version.v3_3); + + CanDoActionTestUtils.runAndAssertCanDoActionFailure(command, + VdcBllMessages.SCSI_GENERIC_IO_IS_NOT_SUPPORTED_FOR_IMAGE_DISK); + } + + @Test + public void testDiskImageWithSgioCantBeAdded() { + LunDisk disk = createISCSILunDisk(); + disk.setDiskInterface(DiskInterface.VirtIO_SCSI); + disk.setSgio(ScsiGenericIO.UNFILTERED); + + AddDiskParameters parameters = createParameters(); + parameters.setDiskInfo(disk); + initializeCommand(Guid.NewGuid(), parameters); + + VM vm = mockVm(); + vm.setVdsGroupCompatibilityVersion(Version.v3_3); + + CanDoActionTestUtils.runAndAssertCanDoActionSuccess(command); } private void fillDiskMap(LunDisk disk, VM vm, int expectedMapSize) { diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ActionGroup.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ActionGroup.java index 8711769..3d66cf3 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ActionGroup.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ActionGroup.java @@ -101,6 +101,7 @@ EDIT_DISK_PROPERTIES(1102, RoleType.USER, VdcObjectType.Disk, true, ApplicationMode.VirtOnly), CONFIGURE_DISK_STORAGE(1103, RoleType.USER, VdcObjectType.Disk, true, ApplicationMode.VirtOnly), DELETE_DISK(1104, RoleType.USER, VdcObjectType.Disk, true, ApplicationMode.VirtOnly), + CONFIGURE_SCSI_GENERIC_IO(1105, RoleType.ADMIN, VdcObjectType.Disk, true, ApplicationMode.VirtOnly), // Network PORT_MIRRORING(1200, RoleType.ADMIN, VdcObjectType.Network, true, ApplicationMode.VirtOnly), diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/BaseDisk.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/BaseDisk.java index be9e773..facbc82 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/BaseDisk.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/BaseDisk.java @@ -71,6 +71,8 @@ private boolean boot; + private ScsiGenericIO sgio; + public BaseDisk() { } @@ -81,7 +83,8 @@ String diskAlias, String diskDescription, boolean shareable, - boolean boot) { + boolean boot, + ScsiGenericIO sgio) { super(); this.id = id; this.diskInterface = diskInterface; @@ -91,6 +94,7 @@ this.diskDescription = diskDescription; this.shareable = shareable; this.boot = boot; + this.sgio = sgio; } @Override @@ -172,6 +176,14 @@ boot = value; } + public ScsiGenericIO getSgio() { + return sgio; + } + + public void setSgio(ScsiGenericIO sgio) { + this.sgio = sgio; + } + @Override public int hashCode() { final int prime = 31; @@ -184,6 +196,7 @@ result = prime * result + (shareable ? 1231 : 1237); result = prime * result + (isWipeAfterDelete() ? 1231 : 1237); result = prime * result + (boot ? 1231 : 1237); + result = prime * result + ((sgio == null) ? 0 : sgio.hashCode()); return result; } @@ -206,6 +219,7 @@ && propagateErrors == other.propagateErrors && shareable == other.shareable && isWipeAfterDelete() == other.isWipeAfterDelete() - && boot == other.boot); + && boot == other.boot) + && sgio == other.sgio; } } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/DiskInterface.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/DiskInterface.java index 3244c1b..5eaf749 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/DiskInterface.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/DiskInterface.java @@ -5,28 +5,29 @@ public enum DiskInterface { - IDE(0), - VirtIO(2); + IDE("ide"), + VirtIO_SCSI("scsi"), + VirtIO("virtio"); - private int intValue; - private static Map<Integer, DiskInterface> mappings; + private String name; + private static Map<String, DiskInterface> mappings; static { - mappings = new HashMap<Integer, DiskInterface>(); + mappings = new HashMap<String, DiskInterface>(); for (DiskInterface error : values()) { - mappings.put(error.getValue(), error); + mappings.put(error.getName(), error); } } - private DiskInterface(int value) { - intValue = value; + private DiskInterface(String name) { + this.name = name; } - public int getValue() { - return intValue; + public String getName() { + return name; } - public static DiskInterface forValue(int value) { - return mappings.get(value); + public static DiskInterface forValue(String name) { + return mappings.get(name); } } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ScsiGenericIO.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ScsiGenericIO.java new file mode 100644 index 0000000..120971e --- /dev/null +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/ScsiGenericIO.java @@ -0,0 +1,31 @@ +package org.ovirt.engine.core.common.businessentities; + +import java.util.HashMap; +import java.util.Map; + +public enum ScsiGenericIO { + FILTERED(1), + UNFILTERED(2); + + private int intValue; + private static Map<Integer, ScsiGenericIO> mappings; + + static { + mappings = new HashMap<Integer, ScsiGenericIO>(); + for (ScsiGenericIO error : values()) { + mappings.put(error.getValue(), error); + } + } + + private ScsiGenericIO(int value) { + intValue = value; + } + + public int getValue() { + return intValue; + } + + public static ScsiGenericIO forValue(int value) { + return mappings.get(value); + } +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java index cd57c1c..3349073 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java @@ -1333,6 +1333,15 @@ @DefaultValueAttribute("0.5") DelayResetPerVmInSeconds(504), + @TypeConverterAttribute(Boolean.class) + @DefaultValueAttribute("false") + VirtIoScsiEnabled(505), + + @Reloadable + @TypeConverterAttribute(String.class) + @DefaultValueAttribute("") + VirtIoScsiUnsupportedOsList(506), + Invalid(65535); private int intValue; diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java index fc2dd12..2efeae1 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java @@ -84,7 +84,8 @@ MigrationSupportForNativeUsb(ConfigAuthType.User), MigrationNetworkEnabled, VncKeyboardLayout(ConfigAuthType.User), - VncKeyboardLayoutValidValues(ConfigAuthType.User) + VncKeyboardLayoutValidValues(ConfigAuthType.User), + VirtIoScsiEnabled(ConfigAuthType.User), ; public static enum ConfigAuthType { diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/VmDeviceType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/VmDeviceType.java index a466960..1447b6d 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/VmDeviceType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/utils/VmDeviceType.java @@ -3,6 +3,7 @@ public enum VmDeviceType { FLOPPY("floppy", "14"), DISK("disk", "17"), + LUN("lun"), CDROM("cdrom", "15"), INTERFACE("interface", "10"), BRIDGE("bridge", "3"), diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java index 0487595..7b644bc 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java @@ -651,6 +651,7 @@ ERROR_CANNOT_DETACH_DISK_WITH_SNAPSHOT, DISK_IS_ALREADY_SHARED_BETWEEN_VMS, VM_CANNOT_RUN_FROM_DISK_WITHOUT_PLUGGED_DISK, + SCSI_GENERIC_IO_IS_NOT_SUPPORTED_FOR_IMAGE_DISK, ACTION_TYPE_FAILED_QUOTA_NOT_EXIST, ACTION_TYPE_FAILED_QUOTA_IS_NOT_VALID, ACTION_TYPE_FAILED_NO_QUOTA_SET_FOR_DOMAIN, diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/AbstractBaseDiskRowMapper.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/AbstractBaseDiskRowMapper.java index 6d23d12..95e8902 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/AbstractBaseDiskRowMapper.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/AbstractBaseDiskRowMapper.java @@ -7,6 +7,7 @@ import org.ovirt.engine.core.common.businessentities.BaseDisk; import org.ovirt.engine.core.common.businessentities.DiskInterface; import org.ovirt.engine.core.common.businessentities.PropagateErrors; +import org.ovirt.engine.core.common.businessentities.ScsiGenericIO; import org.ovirt.engine.core.compat.Guid; import org.springframework.jdbc.core.RowMapper; @@ -32,6 +33,7 @@ disk.setShareable(rs.getBoolean("shareable")); disk.setBoot(rs.getBoolean("boot")); + disk.setSgio(ScsiGenericIO.forValue(rs.getInt("sgio"))); return disk; } diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDiskDaoDbFacadeImpl.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDiskDaoDbFacadeImpl.java index dfd8fa5..2edf016 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDiskDaoDbFacadeImpl.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/BaseDiskDaoDbFacadeImpl.java @@ -26,7 +26,8 @@ .addValue("wipe_after_delete", entity.isWipeAfterDelete()) .addValue("propagate_errors", EnumUtils.nameOrNull(entity.getPropagateErrors())) .addValue("shareable", entity.isShareable()) - .addValue("boot", entity.isBoot()); + .addValue("boot", entity.isBoot()) + .addValue("sgio", entity.getSgio()); } @Override diff --git a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties index e4b886c..9941fa3 100644 --- a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties +++ b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties @@ -758,6 +758,7 @@ SHAREABLE_DISK_IS_NOT_SUPPORTED_BY_VOLUME_FORMAT=Cannot ${action} ${type}. Disk's volume format is not supported for shareable disk. ERROR_CANNOT_DETACH_DISK_WITH_SNAPSHOT=Cannot ${action} ${type}. The disk is already configured in a snapshot. In order to detach it, remove the disk's snapshots. DISK_IS_ALREADY_SHARED_BETWEEN_VMS=Cannot ${action} ${type}. Disk is shared between vms and cannot become unshareable . Detach the disk from the rest of the vms it is attached to and then update the disk to be unshareable. +SCSI_GENERIC_IO_IS_NOT_SUPPORTED_FOR_IMAGE_DISk="Cannot ${action} ${type}. SCSI Generic IO is not supported for image disk." #Suspected (not in use?) USER_PASSWORD_EXPIRED=Cannot Login. User Password has expired, Please change your password. diff --git a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/BaseDiskDaoTest.java b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/BaseDiskDaoTest.java index a05e0a8..10be184 100644 --- a/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/BaseDiskDaoTest.java +++ b/backend/manager/modules/dal/src/test/java/org/ovirt/engine/core/dao/BaseDiskDaoTest.java @@ -7,6 +7,7 @@ import org.ovirt.engine.core.common.businessentities.BaseDisk; import org.ovirt.engine.core.common.businessentities.DiskInterface; import org.ovirt.engine.core.common.businessentities.PropagateErrors; +import org.ovirt.engine.core.common.businessentities.ScsiGenericIO; import org.ovirt.engine.core.compat.Guid; /** @@ -35,7 +36,7 @@ PropagateErrors.Off, "DiskName", "", - false, false); + false, false, ScsiGenericIO.FILTERED); } @Override diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java index dd0e5b4..c5f8139 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HotPlugDiskVDSCommand.java @@ -10,6 +10,7 @@ import org.ovirt.engine.core.common.businessentities.PropagateErrors; import org.ovirt.engine.core.common.businessentities.VmDevice; import org.ovirt.engine.core.common.businessentities.VolumeFormat; +import org.ovirt.engine.core.common.utils.VmDeviceType; import org.ovirt.engine.core.common.vdscommands.HotPlugDiskVDSParameters; import org.ovirt.engine.core.vdsbroker.xmlrpc.XmlRpcStringUtils; @@ -38,10 +39,9 @@ Disk disk = getParameters().getDisk(); VmDevice vmDevice = getParameters().getVmDevice(); - drive.put(VdsProperties.Type, "disk"); - drive.put(VdsProperties.Device, "disk"); + drive.put(VdsProperties.Type, VmDeviceType.DISK.getName()); addAddress(drive, getParameters().getVmDevice().getAddress()); - drive.put(VdsProperties.INTERFACE, disk.getDiskInterface().toString().toLowerCase()); + drive.put(VdsProperties.INTERFACE, disk.getDiskInterface().getName()); drive.put(VdsProperties.Shareable, String.valueOf(disk.isShareable())); drive.put(VdsProperties.Optional, Boolean.FALSE.toString()); drive.put(VdsProperties.ReadOnly, String.valueOf(vmDevice.getIsReadOnly())); @@ -49,6 +49,7 @@ if (disk.getDiskStorageType() == DiskStorageType.IMAGE) { DiskImage diskImage = (DiskImage) disk; + drive.put(VdsProperties.Device, VmDeviceType.DISK.getName()); drive.put(VdsProperties.Format, diskImage.getVolumeFormat().toString().toLowerCase()); drive.put(VdsProperties.DomainId, diskImage.getStorageIds().get(0).toString()); drive.put(VdsProperties.PoolId, diskImage.getStoragePoolId().toString()); @@ -57,6 +58,7 @@ drive.put(VdsProperties.PropagateErrors, disk.getPropagateErrors().toString().toLowerCase()); } else { LunDisk lunDisk = (LunDisk) disk; + drive.put(VdsProperties.Device, VmDeviceType.LUN.getName()); drive.put(VdsProperties.Guid, lunDisk.getLun().getLUN_id()); drive.put(VdsProperties.Format, VolumeFormat.RAW.toString().toLowerCase()); drive.put(VdsProperties.PropagateErrors, PropagateErrors.Off.toString() diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java index a0f714c..d73fd9e 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java @@ -235,6 +235,9 @@ public static final String Optional = "optional"; public static final String ReadOnly = "readonly"; public static final String Virtio = "virtio"; + public static final String VirtioScsi = "virtio-scsi"; + public static final String Scsi = "scsi"; + public static final String Sgio = "sgio"; public static final String Path = "path"; public static final String Ide = "ide"; public static final String Fdc = "fdc"; diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VmInfoBuilder.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VmInfoBuilder.java index 102d17b..75322c2 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VmInfoBuilder.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VmInfoBuilder.java @@ -226,6 +226,7 @@ @Override protected void buildVmDrives() { + boolean containsVirtioScsiDisk = false; List<Disk> disks = getSortedDisks(); for (Disk disk : disks) { Map<String, Object> struct = new HashMap<String, Object>(); @@ -247,6 +248,14 @@ break; case VirtIO: struct.put(VdsProperties.INTERFACE, VdsProperties.Virtio); + break; + case VirtIO_SCSI: + struct.put(VdsProperties.INTERFACE, VdsProperties.Scsi); + if (disk.getDiskStorageType() == DiskStorageType.LUN) { + struct.put(VdsProperties.Device, VmDeviceType.LUN.getName()); + struct.put(VdsProperties.Sgio, disk.getSgio().toString().toLowerCase()); + } + containsVirtioScsiDisk = true; break; default: logUnsupportedInterfaceType(); @@ -285,6 +294,14 @@ addToManagedDevices(vmDevice); } } + + if (containsVirtioScsiDisk) { + Map<String, Object> struct = new HashMap<String, Object>(); + struct.put(VdsProperties.Type, VmDeviceType.CONTROLLER.getName()); + struct.put(VdsProperties.Device, VdsProperties.Scsi); + struct.put(VdsProperties.Model, VdsProperties.VirtioScsi); + devices.add(struct); + } } @Override -- To view, visit http://gerrit.ovirt.org/14906 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie572b8106b3fe5becec69c140546db81bc671c96 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Daniel Erez <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
