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

Reply via email to