Vitor de Lima has uploaded a new change for review. Change subject: core: Avoid too many IDE or sPAPR VSCSI devices ......................................................................
core: Avoid too many IDE or sPAPR VSCSI devices If there are any payload devices or cloud-init is enabled, it is possible to exceed the number of allowed sPAPR VSCSI (in ppc64) or IDE (in x86-64) devices by having the virtual CD, the payload device and a large number of disks in these interfaces. This patch warns the user if that is the case and prevent the VM from running. Change-Id: I86eee7c084d0278a8ee5b1d56612104db3a409ee Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1076488 Signed-off-by: Vitor de Lima <vdel...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmCommand.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/architecture/HasMaximumNumberOfDisks.java M backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java M backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java M frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties M frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties 9 files changed, 79 insertions(+), 1 deletion(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/64/34764/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java index 8498782..12cfe68 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommand.java @@ -9,6 +9,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; +import org.ovirt.engine.core.bll.architecture.HasMaximumNumberOfDisks; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.job.ExecutionContext; import org.ovirt.engine.core.bll.job.ExecutionHandler; @@ -64,6 +65,8 @@ import org.ovirt.engine.core.common.job.Job; import org.ovirt.engine.core.common.job.Step; import org.ovirt.engine.core.common.job.StepEnum; +import org.ovirt.engine.core.common.osinfo.OsRepository; +import org.ovirt.engine.core.common.utils.SimpleDependecyInjector; import org.ovirt.engine.core.common.utils.VmDeviceType; import org.ovirt.engine.core.common.validation.group.StartEntity; import org.ovirt.engine.core.common.vdscommands.CreateVmVDSCommandParameters; @@ -76,6 +79,7 @@ import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; import org.ovirt.engine.core.dal.job.ExecutionMessageDirector; import org.ovirt.engine.core.dao.SnapshotDao; +import org.ovirt.engine.core.utils.archstrategy.ArchStrategyFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -901,6 +905,15 @@ return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_RNG_SOURCE_NOT_SUPPORTED); } + boolean isWindowsOs = SimpleDependecyInjector.getInstance().get(OsRepository.class).isWindows(getVm().getVmOsId()); + + boolean isCloudInitEnabled = (!getVm().isInitialized() && hasVmInit() && !isWindowsOs) || + (getParameters().getInitializationType() == InitializationType.CloudInit); + + if ((getVm().getVmPayload() != null || isCloudInitEnabled) && hasMaximumNumberOfDisks()) { + return failCanDoAction(VdcBllMessages.VMPAYLOAD_CDROM_OR_CLOUD_INIT_MAXIMUM_DEVICES); + } + // Note: that we are setting the payload from database in the ctor. // // Checking if the user sent Payload and Sysprep/Cloud-init at the same media - @@ -918,6 +931,15 @@ return true; } + protected boolean hasVmInit() { + VmHandler.updateVmInitFromDB(getVm().getStaticData(), false); + + return getVm().getVmInit() != null; + } + + protected boolean hasMaximumNumberOfDisks() { + return ArchStrategyFactory.getStrategy(getVm().getClusterArch()).run(new HasMaximumNumberOfDisks(getVm().getId())).returnValue(); + } /** * Checks whether rng device of vm is required by cluster, which is requirement for running vm. 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 2aa7169..d96f32c 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 @@ -117,7 +117,7 @@ // The maximum number of sPAPR VSCSI disks that // can be detected by the Linux kernel of PPC64 guests - public final static int MAX_SPAPR_SCSI_DISKS = 8; + public final static int MAX_SPAPR_SCSI_DISKS = 7; private List<VmNic> interfaces; diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/architecture/HasMaximumNumberOfDisks.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/architecture/HasMaximumNumberOfDisks.java new file mode 100644 index 0000000..087900e --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/architecture/HasMaximumNumberOfDisks.java @@ -0,0 +1,44 @@ +package org.ovirt.engine.core.bll.architecture; + +import org.ovirt.engine.core.bll.VmCommand; +import org.ovirt.engine.core.common.businessentities.Disk; +import org.ovirt.engine.core.common.businessentities.DiskInterface; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.dal.dbbroker.DbFacade; +import org.ovirt.engine.core.utils.archstrategy.ArchCommand; +import org.ovirt.engine.core.utils.linq.LinqUtils; +import org.ovirt.engine.core.utils.linq.Predicate; + +import java.util.List; + +public class HasMaximumNumberOfDisks implements ArchCommand { + boolean hasMaximum; + List<Disk> allDisks; + + public HasMaximumNumberOfDisks(Guid vmId) { + allDisks = DbFacade.getInstance().getDiskDao().getAllForVm(vmId); + } + + private int countDisks(final DiskInterface diskType) { + return LinqUtils.filter(allDisks, new Predicate<Disk>() { + @Override + public boolean eval(Disk a) { + return a.getDiskInterface() == diskType; + } + }).size(); + } + + @Override + public void runForX86_64() { + hasMaximum = VmCommand.MAX_IDE_SLOTS == countDisks(DiskInterface.IDE); + } + + @Override + public void runForPPC64() { + hasMaximum = VmCommand.MAX_SPAPR_SCSI_DISKS == countDisks(DiskInterface.SPAPR_VSCSI); + } + + public boolean returnValue() { + return hasMaximum; + } +} diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java index 92715bc..8049bc3 100644 --- a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmCommandTest.java @@ -358,6 +358,7 @@ doReturn(vm).when(command).getVm(); doReturn(true).when(command).checkRngDeviceClusterCompatibility(); doReturn(true).when(command).checkPayload(any(VmPayload.class), anyString()); + doReturn(false).when(command).hasVmInit(); doReturn(new VDSGroup()).when(command).getVdsGroup(); assertTrue(command.canDoAction()); assertTrue(command.getReturnValue().getCanDoActionMessages().isEmpty()); @@ -400,6 +401,8 @@ doReturn(deviceDao).when(command).getVmDeviceDao(); + doReturn(false).when(command).hasVmInit(); + Assert.assertThat(command.canDoAction(), is(clusterReqSources.contains(vmRngSource))); } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java index 3e584fa..38ef695 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java @@ -670,6 +670,7 @@ VMPAYLOAD_FLOPPY_EXCEEDED(ErrorType.CONFLICT), VMPAYLOAD_FLOPPY_WITH_SYSPREP(ErrorType.CONFLICT), VMPAYLOAD_CDROM_WITH_CLOUD_INIT(ErrorType.CONFLICT), + VMPAYLOAD_CDROM_OR_CLOUD_INIT_MAXIMUM_DEVICES(ErrorType.CONFLICT), ACTION_TYPE_FAILED_BOOKMARK_NAME_ALREADY_EXISTS(ErrorType.CONFLICT), ACTION_TYPE_FAILED_BOOKMARK_INVALID_ID(ErrorType.BAD_PARAMETERS), 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 b4b1970..90e8503 100644 --- a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties +++ b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties @@ -1072,6 +1072,8 @@ VMPAYLOAD_FLOPPY_EXCEEDED=Payload Floppy cannot be used when using an additional Floppy VMPAYLOAD_FLOPPY_WITH_SYSPREP=Payload floppy deivce cannot be used with Sysprep via floppy device. VMPAYLOAD_CDROM_WITH_CLOUD_INIT=Payload cdrom deivce cannot be used with Cloud-Init via cdrom device. +VMPAYLOAD_CDROM_OR_CLOUD_INIT_MAXIMUM_DEVICES=CD-ROM Payload or Cloud-init is being used while there are too many devices using the IDE or the sPAPR VSCSI bus. + ACTION_TYPE_FAILED_GLUSTER_VOLUME_IS_UP=Cannot ${action} ${type}. Gluster volume ${volumeName} is up. ACTION_TYPE_FAILED_GLUSTER_VOLUME_IS_DOWN=Cannot ${action} ${type}. Gluster Volume is down. ACTION_TYPE_FAILED_CAN_NOT_REMOVE_ALL_BRICKS_FROM_VOLUME=Cannot ${action} ${type}. Cannot remove all the bricks from a Volume. diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java index 70cc80f..e633454 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java @@ -2806,6 +2806,9 @@ @DefaultStringValue("Payload cdrom deivce cannot be used with Cloud-Init via cdrom device.") String VMPAYLOAD_CDROM_WITH_CLOUD_INIT(); + @DefaultStringValue("CD-ROM Payload or Cloud-init is being used while there are too many devices using the IDE or the sPAPR VSCSI bus.") + String VMPAYLOAD_CDROM_OR_CLOUD_INIT_MAXIMUM_DEVICES(); + // Gluster Messages @DefaultStringValue("Cannot ${action} ${type}. Cluster ID is not valid.") String ACTION_TYPE_FAILED_CLUSTER_IS_NOT_VALID(); diff --git a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index 52c500e..56db8ef 100644 --- a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -969,6 +969,7 @@ VMPAYLOAD_FLOPPY_EXCEEDED=Payload Floppy cannot be used when using an additional Floppy VMPAYLOAD_FLOPPY_WITH_SYSPREP=Payload floppy deivce cannot be used with Sysprep via floppy device. VMPAYLOAD_CDROM_WITH_CLOUD_INIT=Payload cdrom deivce cannot be used with Cloud-Init via cdrom device. +VMPAYLOAD_CDROM_OR_CLOUD_INIT_MAXIMUM_DEVICES=CD-ROM Payload or Cloud-init is being used while there are too many devices using the IDE or the sPAPR VSCSI bus. ERROR_GET_STORAGE_DOMAIN_LIST=Cannot get Storage Domains list. ACTION_TYPE_FAILED_VDS_CLUSTER_DIFFERENT_ARCHITECTURES=Cannot ${action} ${type}. The host and the destination cluster architectures do not match. diff --git a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index 27f3aae..c99043a 100644 --- a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -1022,6 +1022,8 @@ VMPAYLOAD_FLOPPY_EXCEEDED=Payload Floppy cannot be used when using an additional Floppy VMPAYLOAD_FLOPPY_WITH_SYSPREP=Payload floppy deivce cannot be used with Sysprep via floppy device. VMPAYLOAD_CDROM_WITH_CLOUD_INIT=Payload cdrom deivce cannot be used with Cloud-Init via cdrom device. +VMPAYLOAD_CDROM_OR_CLOUD_INIT_MAXIMUM_DEVICES=CD-ROM Payload or Cloud-init is being used while there are too many devices using the IDE or the sPAPR VSCSI bus. + ERROR_GET_STORAGE_DOMAIN_LIST=Cannot get Storage Domains list. ERROR_GET_IMAGE_LIST=Cannot get list of images from Storage Domain '${sdName}'. Please try again later. ACTION_TYPE_FAILED_VDS_CLUSTER_DIFFERENT_ARCHITECTURES=Cannot ${action} ${type}. The host and the destination cluster architectures do not match. -- To view, visit http://gerrit.ovirt.org/34764 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I86eee7c084d0278a8ee5b1d56612104db3a409ee Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Vitor de Lima <vdel...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches