Arik Hadas has uploaded a new change for review.

Change subject: core: [WIP] ram snapshots related changes in bll project
......................................................................

core: [WIP] ram snapshots related changes in bll project

Change-Id: Ifbb28efda1b63e506233a88399488a256e6ab1c8
Signed-off-by: Arik Hadas <[email protected]>
---
M backend/manager/dbscripts/snapshots_sp.sql
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CreateAllSnapshotsFromVmCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/snapshots/SnapshotsManager.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CreateAllSnapshotsFromVmParameters.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDao.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDaoDbFacadeImpl.java
6 files changed, 212 insertions(+), 32 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/91/14291/1

diff --git a/backend/manager/dbscripts/snapshots_sp.sql 
b/backend/manager/dbscripts/snapshots_sp.sql
index 0392b17..6ea0304 100644
--- a/backend/manager/dbscripts/snapshots_sp.sql
+++ b/backend/manager/dbscripts/snapshots_sp.sql
@@ -154,6 +154,24 @@
 LANGUAGE plpgsql;
 
 
+Create or replace FUNCTION GetSnapshotByVmIdAndTypeAndStatus(
+    v_vm_id UUID,
+    v_snapshot_type VARCHAR(32),
+    v_status VARCHAR(32))
+RETURNS SETOF snapshots
+AS $procedure$
+BEGIN
+    RETURN QUERY
+    SELECT *
+    FROM   snapshots
+    WHERE  vm_id = v_vm_id
+    AND    snapshot_type = v_snapshot_type
+    AND    status = v_status
+    ORDER BY creation_date ASC
+    LIMIT 1;
+END; $procedure$
+LANGUAGE plpgsql;
+
 
 
 
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CreateAllSnapshotsFromVmCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CreateAllSnapshotsFromVmCommand.java
index 3a2893c..5e82346 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CreateAllSnapshotsFromVmCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CreateAllSnapshotsFromVmCommand.java
@@ -6,6 +6,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.ovirt.engine.core.bll.job.ExecutionHandler;
 import org.ovirt.engine.core.bll.quota.QuotaConsumptionParameter;
@@ -14,10 +15,12 @@
 import org.ovirt.engine.core.bll.snapshots.SnapshotsManager;
 import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
 import org.ovirt.engine.core.bll.storage.StoragePoolValidator;
+import org.ovirt.engine.core.bll.utils.ClusterUtils;
 import org.ovirt.engine.core.bll.validator.DiskImagesValidator;
 import org.ovirt.engine.core.bll.validator.MultipleStorageDomainsValidator;
 import org.ovirt.engine.core.bll.validator.VmValidator;
 import org.ovirt.engine.core.common.AuditLogType;
+import org.ovirt.engine.core.common.FeatureSupported;
 import org.ovirt.engine.core.common.VdcObjectType;
 import org.ovirt.engine.core.common.action.CreateAllSnapshotsFromVmParameters;
 import org.ovirt.engine.core.common.action.ImagesActionsParametersBase;
@@ -30,18 +33,25 @@
 import org.ovirt.engine.core.common.businessentities.Snapshot;
 import org.ovirt.engine.core.common.businessentities.Snapshot.SnapshotStatus;
 import org.ovirt.engine.core.common.businessentities.Snapshot.SnapshotType;
+import org.ovirt.engine.core.common.businessentities.StorageDomain;
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VMStatus;
 import org.ovirt.engine.core.common.businessentities.VmExitStatus;
+import org.ovirt.engine.core.common.businessentities.VolumeFormat;
+import org.ovirt.engine.core.common.businessentities.VolumeType;
 import org.ovirt.engine.core.common.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
 import org.ovirt.engine.core.common.errors.VdcBLLException;
+import org.ovirt.engine.core.common.errors.VdcBllErrors;
 import org.ovirt.engine.core.common.locks.LockingGroup;
 import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.common.validation.group.CreateEntity;
+import 
org.ovirt.engine.core.common.vdscommands.CreateImageVDSCommandParameters;
 import org.ovirt.engine.core.common.vdscommands.SnapshotVDSCommandParameters;
 import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
+import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
 import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.compat.NGuid;
 import org.ovirt.engine.core.compat.TransactionScopeOption;
 import org.ovirt.engine.core.dal.VdcBllMessages;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
@@ -105,8 +115,10 @@
 
         setActionReturnValue(createdSnapshotId);
 
-        addSnapshotToDB(createdSnapshotId);
+        MemoryImageBuilder memoryImageBuilder = createMemoryImageBuilder();
+        addSnapshotToDB(createdSnapshotId, memoryImageBuilder);
         createSnapshotsForDisks(newActiveSnapshotId);
+        memoryImageBuilder.build();
 
         if (getTaskIdList().isEmpty()) {
             getParameters().setTaskGroupSuccess(true);
@@ -115,23 +127,37 @@
         setSucceeded(true);
     }
 
-    private Snapshot addSnapshotToDB(Guid snapshotId) {
-        if (getDisksList().isEmpty()) {
-            return new SnapshotsManager().addSnapshot(snapshotId,
-                    getParameters().getDescription(),
-                    SnapshotStatus.OK,
-                    getParameters().getSnapshotType(),
-                    getVm(),
-                    true,
-                    getCompensationContext());
+    private Guid _storageDomainId = Guid.Empty;
+
+    @Override
+    public NGuid getStorageDomainId() {
+        if (_storageDomainId.equals(Guid.Empty) && getVm() != null) {
+            long sizeNeeded = getVm().getImageSizeInBytes() / BYTES_IN_GB;
+            StorageDomain storageDomain = 
VmHandler.findStorageDomainForMemory(getVm().getStoragePoolId(), sizeNeeded);
+            if (storageDomain != null) {
+                _storageDomainId = storageDomain.getId();
+            }
         }
-        else {
-            return new SnapshotsManager().addSnapshot(snapshotId,
-                    getParameters().getDescription(),
-                    getParameters().getSnapshotType(),
-                    getVm(),
-                    getCompensationContext());
-        }
+        return _storageDomainId;
+    }
+
+    private MemoryImageBuilder createMemoryImageBuilder() {
+        return 
FeatureSupported.memorySnapshot(ClusterUtils.getCompatilibilyVersion(getVm()))
+                && getParameters().isSaveMemory() ?
+                        new DefaultMemoryImageBuilder() :
+                            new NullableImageBuilder();
+    }
+
+    private Snapshot addSnapshotToDB(Guid snapshotId, MemoryImageBuilder 
memoryImageBuilder) {
+        boolean taskExists = !getDisksList().isEmpty() || 
!memoryImageBuilder.getVolumeStringRepresentation().isEmpty();
+        return new SnapshotsManager().addSnapshot(snapshotId,
+                getParameters().getDescription(),
+                taskExists ? SnapshotStatus.LOCKED : SnapshotStatus.OK,
+                getParameters().getSnapshotType(),
+                getVm(),
+                true,
+                memoryImageBuilder.getVolumeStringRepresentation(),
+                getCompensationContext());
     }
 
     private void createSnapshotsForDisks(Guid vmSnapshotId) {
@@ -149,6 +175,17 @@
                         "CreateAllSnapshotsFromVmCommand::executeVmCommand: 
Failed to create snapshot!");
             }
         }
+    }
+
+    /**
+     * Returns whether to use Sparse or Preallocation. If the storage type is 
file system devices ,it would be more
+     * efficient to use Sparse allocation. Otherwise for block devices we 
should use Preallocated for faster allocation.
+     *
+     * @return - VolumeType of allocation type to use.
+     */
+    private VolumeType getVolumeType() {
+        return (getStoragePool().getstorage_pool_type().isFileDomain()) ? 
VolumeType.Sparse
+                : VolumeType.Preallocated;
     }
 
     private ImagesActionsParametersBase 
buildCreateSnapshotParameters(DiskImage image, Guid snapshotId) {
@@ -182,17 +219,16 @@
             @Override
             public Void runInTransaction() {
                 final boolean taskGroupSucceeded = 
getParameters().getTaskGroupSuccess();
-                Guid createdSnapshotId =
-                        getSnapshotDao().getId(getVmId(), 
getParameters().getSnapshotType(), SnapshotStatus.LOCKED);
+                Snapshot createdSnapshot = getSnapshotDao().get(getVmId(), 
getParameters().getSnapshotType(), SnapshotStatus.LOCKED);
                 if (taskGroupSucceeded) {
-                    getSnapshotDao().updateStatus(createdSnapshotId, 
SnapshotStatus.OK);
+                    getSnapshotDao().updateStatus(createdSnapshot.getId(), 
SnapshotStatus.OK);
 
-                    if (getParameters().getParentCommand() != 
VdcActionType.RunVm && getVm() != null && getVm().isRunning()
-                            && getVm().getRunOnVds() != null) {
-                        performLiveSnapshot(createdSnapshotId);
+                    if (getParameters().getParentCommand() != 
VdcActionType.RunVm && getVm() != null
+                            && getVm().isRunning() && getVm().getRunOnVds() != 
null) {
+                        performLiveSnapshot(createdSnapshot);
                     }
                 } else {
-                    revertToActiveSnapshot(createdSnapshotId);
+                    revertToActiveSnapshot(createdSnapshot.getId());
                 }
 
                 incrementVmGeneration();
@@ -244,22 +280,35 @@
      * @param createdSnapshotId
      *            Snapshot to revert to being active, in case of rollback.
      */
-    protected void performLiveSnapshot(Guid createdSnapshotId) {
+    protected void performLiveSnapshot(final Snapshot snapshot) {
         try {
             TransactionSupport.executeInScope(TransactionScopeOption.Suppress, 
new TransactionMethod<Void>() {
 
                 @Override
                 public Void runInTransaction() {
-                    List<Disk> pluggedDisks = 
getDiskDao().getAllForVm(getVm().getId(), true);
-                    runVdsCommand(VDSCommandType.Snapshot,
-                            new 
SnapshotVDSCommandParameters(getVm().getRunOnVds().getValue(),
-                                    getVm().getId(),
-                                    
ImagesHandler.filterImageDisks(pluggedDisks, false, true)));
+
+                    runVdsCommand(VDSCommandType.Snapshot, 
buildLiveSnapshotParameters(snapshot));
+
                     return null;
                 }
             });
         } catch (VdcBLLException e) {
             handleVdsLiveSnapshotFailure(e);
+        }
+    }
+
+    private SnapshotVDSCommandParameters buildLiveSnapshotParameters(Snapshot 
snapshot) {
+        List<Disk> pluggedDisks = getDiskDao().getAllForVm(getVm().getId(), 
true);
+        if 
(FeatureSupported.memorySnapshot(ClusterUtils.getCompatilibilyVersion(getVm())))
 {
+            return new 
SnapshotVDSCommandParameters(getVm().getRunOnVds().getValue(),
+                    getVm().getId(),
+                    ImagesHandler.filterImageDisks(pluggedDisks, false, true),
+                    snapshot.getMemoryVolume());
+        }
+        else {
+            return new 
SnapshotVDSCommandParameters(getVm().getRunOnVds().getValue(),
+                    getVm().getId(),
+                    ImagesHandler.filterImageDisks(pluggedDisks, false, true));
         }
     }
 
@@ -396,4 +445,77 @@
 
         return list;
     }
+
+    private interface MemoryImageBuilder {
+        void build();
+        String getVolumeStringRepresentation();
+    }
+
+    private class DefaultMemoryImageBuilder implements MemoryImageBuilder {
+        private Guid storageDomainId;
+        private Guid storagePoolId;
+        private Guid imageGroupId;
+        private Guid volumeId;
+
+        private DefaultMemoryImageBuilder() {
+            this.storageDomainId = getStorageDomainId().getValue();
+            this.storagePoolId = getVm().getStoragePoolId();
+            this.imageGroupId = Guid.NewGuid();
+            this.volumeId = Guid.NewGuid();
+        }
+
+        @Override
+        public void build() {
+            VDSReturnValue retVal =
+                    Backend
+                    .getInstance()
+                    .getResourceManager()
+                    .RunVdsCommand(
+                            VDSCommandType.CreateImage,
+                            new CreateImageVDSCommandParameters(
+                                    storagePoolId,
+                                    storageDomainId,
+                                    imageGroupId,
+                                    getVm().getImageSizeInBytes(),
+                                    getVolumeType(),
+                                    VolumeFormat.RAW,
+                                    volumeId,
+                                    "",
+                                    
getStoragePool().getcompatibility_version().toString()));
+
+            if (retVal.getSucceeded()) {
+                Guid guid =
+                        createTask(retVal.getCreationInfo(),
+                                VdcActionType.CreateAllSnapshotsFromVm,
+                                VdcObjectType.Storage,
+                                getStorageDomainId().getValue());
+                getTaskIdList().add(guid);
+            }
+            else {
+                throw new VdcBLLException(VdcBllErrors.VolumeCreationError,
+                        "CreateAllSnapshotsFromVmCommand::executeVmCommand: 
Failed to create image for memory!");
+            }
+        }
+
+        @Override
+        public String getVolumeStringRepresentation() {
+            return String.format("%1$s,%2$s,%3$s,%4$s",
+                    storageDomainId,
+                    storagePoolId,
+                    imageGroupId,
+                    volumeId);
+        }
+    }
+
+    private class NullableImageBuilder implements MemoryImageBuilder {
+        @Override
+        public void build() {
+            //no op
+        }
+
+        @Override
+        public String getVolumeStringRepresentation() {
+            return StringUtils.EMPTY;
+        }
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/snapshots/SnapshotsManager.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/snapshots/SnapshotsManager.java
index 66bbcc0..251b9da 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/snapshots/SnapshotsManager.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/snapshots/SnapshotsManager.java
@@ -94,6 +94,7 @@
                 SnapshotType.ACTIVE,
                 vm,
                 false,
+                StringUtils.EMPTY,
                 compensationContext);
     }
 
@@ -119,7 +120,8 @@
             SnapshotType snapshotType,
             VM vm,
             final CompensationContext compensationContext) {
-        return addSnapshot(snapshotId, description, SnapshotStatus.LOCKED, 
snapshotType, vm, true, compensationContext);
+        return addSnapshot(snapshotId, description, SnapshotStatus.LOCKED,
+                snapshotType, vm, true, StringUtils.EMPTY, 
compensationContext);
     }
 
     /**
@@ -147,6 +149,7 @@
             SnapshotType snapshotType,
             VM vm,
             boolean saveVmConfiguration,
+            String memoryVolume,
             final CompensationContext compensationContext) {
         final Snapshot snapshot = new Snapshot(snapshotId,
                 snapshotStatus,
@@ -156,7 +159,7 @@
                 description,
                 new Date(),
                 vm.getAppList(),
-                StringUtils.EMPTY);
+                memoryVolume);
 
         getSnapshotDao().save(snapshot);
         compensationContext.snapshotNewEntity(snapshot);
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CreateAllSnapshotsFromVmParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CreateAllSnapshotsFromVmParameters.java
index f6cc9eb..47f348b 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CreateAllSnapshotsFromVmParameters.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/CreateAllSnapshotsFromVmParameters.java
@@ -27,6 +27,9 @@
     /** Used to indicate the type of snapshot to take */
     private SnapshotType snapshotType;
 
+    /** Used to indicate whether the memory should be saved as part of this 
snapshot or not */
+    private boolean saveMemory = true;
+
     public CreateAllSnapshotsFromVmParameters() {
     }
 
@@ -59,6 +62,14 @@
         this.snapshotType = snapshotType;
     }
 
+    public boolean isSaveMemory() {
+        return saveMemory;
+    }
+
+    public void setSaveMemory(boolean saveMemory) {
+        this.saveMemory = saveMemory;
+    }
+
     public boolean isNeedsLocking() {
         return needsLocking;
     }
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDao.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDao.java
index 08d2d30..200a0cb 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDao.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDao.java
@@ -61,6 +61,20 @@
      */
     Snapshot get(Guid vmId, SnapshotType type);
 
+    /**
+     * Return the <b>first</b> {@link Snapshot} that matches the given 
parameters.<br>
+     * <b>Note:</b> If more than one snapshot answers to the parameters, only 
the first will be returned (oldest by
+     * creation date).
+     *
+     * @param vmId
+     *            The id of the VM to check for.
+     * @param type
+     *            The type of snapshot.
+     * @param status
+     *            The status of the snapshot.
+     * @return The snapshot, or <code>null</code> if it doesn't exist.
+     */
+    Snapshot get(Guid vmId, SnapshotType type, SnapshotStatus status);
 
     /**
      * Return the {@link Snapshot} <b>first</b> id that matches the given 
parameters.<br>
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDaoDbFacadeImpl.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDaoDbFacadeImpl.java
index 304635e..f3425c6 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDaoDbFacadeImpl.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dao/SnapshotDaoDbFacadeImpl.java
@@ -86,6 +86,18 @@
     }
 
     @Override
+    public Snapshot get(Guid vmId, SnapshotType type, SnapshotStatus status) {
+        MapSqlParameterSource parameterSource = 
getCustomMapSqlParameterSource()
+                .addValue("vm_id", vmId)
+                .addValue("snapshot_type", EnumUtils.nameOrNull(type))
+                .addValue("status", EnumUtils.nameOrNull(status));
+
+        return 
getCallsHandler().executeRead("GetSnapshotByVmIdAndTypeAndStatus",
+                createEntityRowMapper(),
+                parameterSource);
+    }
+
+    @Override
     public List<Snapshot> getAllWithConfiguration(Guid vmId) {
         return getAll(vmId, null, false, true);
     }


--
To view, visit http://gerrit.ovirt.org/14291
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifbb28efda1b63e506233a88399488a256e6ab1c8
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Arik Hadas <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to