You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by wi...@apache.org on 2013/08/13 16:25:38 UTC
[1/2] git commit: updated refs/heads/master to 227509b
Updated Branches:
refs/heads/master 4d48d9603 -> 227509be4
CLOUDSTACK-4114: Use RAW disk images for RBD instead of QCOW2
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/04f378bc
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/04f378bc
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/04f378bc
Branch: refs/heads/master
Commit: 04f378bcff90c9a3ab3bb3c92c5ec1145aab45c4
Parents: 4d48d96
Author: Wido den Hollander <wi...@widodh.nl>
Authored: Tue Aug 6 16:25:55 2013 +0200
Committer: Wido den Hollander <wi...@widodh.nl>
Committed: Tue Aug 13 16:14:45 2013 +0200
----------------------------------------------------------------------
.../com/cloud/upgrade/dao/Upgrade410to420.java | 11 ++++++
.../cloudstack/storage/image/format/RAW.java | 32 +++++++++++++++
.../cloudstack/storage/volume/VolumeObject.java | 6 +++
.../kvm/storage/KVMStorageProcessor.java | 41 +++++++++++++++++++-
.../kvm/storage/LibvirtStorageAdaptor.java | 1 +
5 files changed, 90 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/04f378bc/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java
index 7ab7ab7..fd4f2a7 100644
--- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java
+++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java
@@ -105,6 +105,7 @@ public class Upgrade410to420 implements DbUpgrade {
fixRouterKeys(conn);
encryptSite2SitePSK(conn);
migrateDatafromIsoIdInVolumesTable(conn);
+ setRAWformatForRBDVolumes(conn);
}
private void fixBaremetalForeignKeys(Connection conn) {
@@ -2180,6 +2181,16 @@ public class Upgrade410to420 implements DbUpgrade {
}catch (SQLException e) {
//implies iso_id1 is not present, so do nothing.
}
+ }
+ protected void setRAWformatForRBDVolumes(Connection conn) {
+ PreparedStatement pstmt = null;
+ try {
+ s_logger.debug("Setting format to RAW for all volumes on RBD primary storage pools");
+ pstmt = conn.prepareStatement("UPDATE volumes SET format = 'RAW' WHERE pool_id IN(SELECT id FROM storage_pool WHERE pool_type = 'RBD')");
+ pstmt.executeQuery();
+ } catch (SQLException e) {
+ throw new CloudRuntimeException("Failed to update volume format to RAW for volumes on RBD pools");
+ }
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/04f378bc/engine/storage/src/org/apache/cloudstack/storage/image/format/RAW.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/format/RAW.java b/engine/storage/src/org/apache/cloudstack/storage/image/format/RAW.java
new file mode 100644
index 0000000..84adff2
--- /dev/null
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/format/RAW.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.image.format;
+
+import org.apache.cloudstack.storage.BaseType;
+import org.springframework.stereotype.Component;
+
+@Component("imageformat_raw")
+public class RAW extends BaseType implements ImageFormat {
+ private final String type = "RAW";
+
+ @Override
+ public String toString() {
+ return type;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/04f378bc/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
index 5058dba..b24b715 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -474,6 +474,9 @@ public class VolumeObject implements VolumeInfo {
if (newVol.getSize() != null) {
vol.setSize(newVol.getSize());
}
+ if (newVol.getFormat() != null) {
+ vol.setFormat(newVol.getFormat());
+ }
vol.setPoolId(this.getDataStore().getId());
volumeDao.update(vol.getId(), vol);
} else if (answer instanceof CreateObjectAnswer) {
@@ -485,6 +488,9 @@ public class VolumeObject implements VolumeInfo {
vol.setSize(newVol.getSize());
}
vol.setPoolId(this.getDataStore().getId());
+ if (newVol.getFormat() != null) {
+ vol.setFormat(newVol.getFormat());
+ }
volumeDao.update(vol.getId(), vol);
}
} else {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/04f378bc/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index d813eb9..8f46c22 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -199,7 +199,16 @@ public class KVMStorageProcessor implements StorageProcessor {
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(primaryVol.getName());
- newTemplate.setFormat(ImageFormat.QCOW2);
+
+ /**
+ * Force the ImageFormat for RBD templates to RAW
+ *
+ */
+ if (primaryPool.getType() == StoragePoolType.RBD) {
+ newTemplate.setFormat(ImageFormat.RAW);
+ } else {
+ newTemplate.setFormat(ImageFormat.QCOW2);
+ }
return new CopyCmdAnswer(newTemplate);
} catch (CloudRuntimeException e) {
return new CopyCmdAnswer(e.toString());
@@ -291,6 +300,12 @@ public class KVMStorageProcessor implements StorageProcessor {
newVol.setPath(vol.getName());
newVol.setSize(volume.getSize());
+ if (vol.getFormat() == PhysicalDiskFormat.RAW) {
+ newVol.setFormat(ImageFormat.RAW);
+ } else if (vol.getFormat() == PhysicalDiskFormat.QCOW2) {
+ newVol.setFormat(ImageFormat.QCOW2);
+ }
+
return new CopyCmdAnswer(newVol);
} catch (CloudRuntimeException e) {
s_logger.debug("Failed to create volume: " + e.toString());
@@ -985,6 +1000,15 @@ public class KVMStorageProcessor implements StorageProcessor {
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(vol.getName());
newVol.setSize(volume.getSize());
+
+ /**
+ * Volumes on RBD are always in RAW format
+ * Hardcode this to RAW since there is no other way right now
+ */
+ if (primaryPool.getType() == StoragePoolType.RBD) {
+ newVol.setFormat(ImageFormat.RAW);
+ }
+
return new CreateObjectAnswer(newVol);
} catch (Exception e) {
s_logger.debug("Failed to create volume: " + e.toString());
@@ -1120,6 +1144,7 @@ public class KVMStorageProcessor implements StorageProcessor {
DataTO destData = cmd.getDestTO();
PrimaryDataStoreTO pool = (PrimaryDataStoreTO) destData.getDataStore();
DataStoreTO imageStore = srcData.getDataStore();
+ VolumeObjectTO volume = snapshot.getVolume();
if (!(imageStore instanceof NfsTO)) {
return new CopyCmdAnswer("unsupported protocol");
@@ -1135,6 +1160,12 @@ public class KVMStorageProcessor implements StorageProcessor {
+ snapshotPath);
KVMPhysicalDisk snapshotDisk = secondaryPool.getPhysicalDisk(snapshotName);
+ if (volume.getFormat() == ImageFormat.RAW) {
+ snapshotDisk.setFormat(PhysicalDiskFormat.RAW);
+ } else if (volume.getFormat() == ImageFormat.QCOW2) {
+ snapshotDisk.setFormat(PhysicalDiskFormat.QCOW2);
+ }
+
String primaryUuid = pool.getUuid();
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getPoolType(), primaryUuid);
String volUuid = UUID.randomUUID().toString();
@@ -1142,6 +1173,14 @@ public class KVMStorageProcessor implements StorageProcessor {
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(disk.getName());
newVol.setSize(disk.getVirtualSize());
+
+ /**
+ * We have to force the format of RBD volumes to RAW
+ */
+ if (primaryPool.getType() == StoragePoolType.RBD) {
+ newVol.setFormat(ImageFormat.RAW);
+ }
+
return new CopyCmdAnswer(newVol);
} catch (CloudRuntimeException e) {
return new CopyCmdAnswer(e.toString());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/04f378bc/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
index 262343a..28cfd42 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
@@ -787,6 +787,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
qemu.convert(sourceFile, destFile);
}
} else {
+ format = PhysicalDiskFormat.RAW;
disk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + newUuid, newUuid, destPool);
disk.setFormat(format);
disk.setSize(template.getVirtualSize());
[2/2] git commit: updated refs/heads/master to 227509b
Posted by wi...@apache.org.
Remove .java.orig file
Left over from somebodies editor?
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/227509be
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/227509be
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/227509be
Branch: refs/heads/master
Commit: 227509be46f765b724c1d2d858dc8b244bdbf330
Parents: 04f378b
Author: Wido den Hollander <wi...@widodh.nl>
Authored: Tue Aug 13 16:25:09 2013 +0200
Committer: Wido den Hollander <wi...@widodh.nl>
Committed: Tue Aug 13 16:25:09 2013 +0200
----------------------------------------------------------------------
.../vm/snapshot/VMSnapshotManagerImpl.java.orig | 913 -------------------
1 file changed, 913 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/227509be/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java.orig
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java.orig b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java.orig
deleted file mode 100644
index b258fa7..0000000
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java.orig
+++ /dev/null
@@ -1,913 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.vm.snapshot;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.CreateVMSnapshotAnswer;
-import com.cloud.agent.api.CreateVMSnapshotCommand;
-import com.cloud.agent.api.DeleteVMSnapshotAnswer;
-import com.cloud.agent.api.DeleteVMSnapshotCommand;
-import com.cloud.agent.api.RevertToVMSnapshotAnswer;
-import com.cloud.agent.api.RevertToVMSnapshotCommand;
-import com.cloud.agent.api.VMSnapshotTO;
-import com.cloud.agent.api.to.VolumeTO;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.projects.Project.ListProjectResourcesCriteria;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Ternary;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-
-@Component
-@Local(value = { VMSnapshotManager.class, VMSnapshotService.class })
-public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotManager, VMSnapshotService {
- private static final Logger s_logger = Logger.getLogger(VMSnapshotManagerImpl.class);
- String _name;
- @Inject VMSnapshotDao _vmSnapshotDao;
- @Inject VolumeDao _volumeDao;
- @Inject AccountDao _accountDao;
- @Inject VMInstanceDao _vmInstanceDao;
- @Inject UserVmDao _userVMDao;
- @Inject HostDao _hostDao;
- @Inject UserDao _userDao;
- @Inject AgentManager _agentMgr;
- @Inject HypervisorGuruManager _hvGuruMgr;
- @Inject AccountManager _accountMgr;
- @Inject GuestOSDao _guestOSDao;
- @Inject PrimaryDataStoreDao _storagePoolDao;
- @Inject SnapshotDao _snapshotDao;
- @Inject VirtualMachineManager _itMgr;
- @Inject DataStoreManager dataStoreMgr;
- @Inject ConfigurationDao _configDao;
- @Inject HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
- @Inject DiskOfferingDao _diskOfferingDao;
- @Inject ServiceOfferingDao _serviceOfferingDao;
- int _vmSnapshotMax;
- int _wait;
- StateMachine2<VMSnapshot.State, VMSnapshot.Event, VMSnapshot> _vmSnapshottateMachine ;
-
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- _name = name;
- if (_configDao == null) {
- throw new ConfigurationException(
- "Unable to get the configuration dao.");
- }
-
- _vmSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("vmsnapshot.max"), VMSNAPSHOTMAX);
-
- String value = _configDao.getValue("vmsnapshot.create.wait");
- _wait = NumbersUtil.parseInt(value, 1800);
-
- _vmSnapshottateMachine = VMSnapshot.State.getStateMachine();
- return true;
- }
-
- @Override
- public boolean start() {
- return true;
- }
-
- @Override
- public boolean stop() {
- return true;
- }
-
- @Override
- public List<VMSnapshotVO> listVMSnapshots(ListVMSnapshotCmd cmd) {
- Account caller = getCaller();
- List<Long> permittedAccounts = new ArrayList<Long>();
-
- boolean listAll = cmd.listAll();
- Long id = cmd.getId();
- Long vmId = cmd.getVmId();
-
- String state = cmd.getState();
- String keyword = cmd.getKeyword();
- String name = cmd.getVmSnapshotName();
- String accountName = cmd.getAccountName();
-
- Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
- cmd.getDomainId(), cmd.isRecursive(), null);
- _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll,
- false);
- Long domainId = domainIdRecursiveListProject.first();
- Boolean isRecursive = domainIdRecursiveListProject.second();
- ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-
- Filter searchFilter = new Filter(VMSnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
- SearchBuilder<VMSnapshotVO> sb = _vmSnapshotDao.createSearchBuilder();
- _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
- sb.and("vm_id", sb.entity().getVmId(), SearchCriteria.Op.EQ);
- sb.and("domain_id", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
- sb.and("status", sb.entity().getState(), SearchCriteria.Op.IN);
- sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
- sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
- sb.and("display_name", sb.entity().getDisplayName(), SearchCriteria.Op.EQ);
- sb.and("account_id", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
- sb.done();
-
- SearchCriteria<VMSnapshotVO> sc = sb.create();
- _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-
- if (accountName != null && cmd.getDomainId() != null) {
- Account account = _accountMgr.getActiveAccountByName(accountName, cmd.getDomainId());
- sc.setParameters("account_id", account.getId());
- }
-
- if (vmId != null) {
- sc.setParameters("vm_id", vmId);
- }
-
- if (domainId != null) {
- sc.setParameters("domain_id", domainId);
- }
-
- if (state == null) {
- VMSnapshot.State[] status = { VMSnapshot.State.Ready, VMSnapshot.State.Creating, VMSnapshot.State.Allocated,
- VMSnapshot.State.Error, VMSnapshot.State.Expunging, VMSnapshot.State.Reverting };
- sc.setParameters("status", (Object[]) status);
- } else {
- sc.setParameters("state", state);
- }
-
- if (name != null) {
- sc.setParameters("display_name", name);
- }
-
- if (keyword != null) {
- SearchCriteria<VMSnapshotVO> ssc = _vmSnapshotDao.createSearchCriteria();
- ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("display_name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
- sc.addAnd("name", SearchCriteria.Op.SC, ssc);
- }
-
- if (id != null) {
- sc.setParameters("id", id);
- }
-
- return _vmSnapshotDao.search(sc, searchFilter);
-
- }
-
- protected Account getCaller(){
- return CallContext.current().getCallingAccount();
- }
-
- @Override
- public VMSnapshot allocVMSnapshot(Long vmId, String vsDisplayName, String vsDescription, Boolean snapshotMemory)
- throws ResourceAllocationException {
-
- Account caller = getCaller();
-
- // check if VM exists
- UserVmVO userVmVo = _userVMDao.findById(vmId);
- if (userVmVo == null) {
- throw new InvalidParameterValueException("Creating VM snapshot failed due to VM:" + vmId + " is a system VM or does not exist");
- }
-
- // check hypervisor capabilities
- if(!_hypervisorCapabilitiesDao.isVmSnapshotEnabled(userVmVo.getHypervisorType(), "default"))
- throw new InvalidParameterValueException("VM snapshot is not enabled for hypervisor type: " + userVmVo.getHypervisorType());
-
- // parameter length check
- if(vsDisplayName != null && vsDisplayName.length()>255)
- throw new InvalidParameterValueException("Creating VM snapshot failed due to length of VM snapshot vsDisplayName should not exceed 255");
- if(vsDescription != null && vsDescription.length()>255)
- throw new InvalidParameterValueException("Creating VM snapshot failed due to length of VM snapshot vsDescription should not exceed 255");
-
- // VM snapshot display name must be unique for a VM
- String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT);
- String vmSnapshotName = userVmVo.getInstanceName() + "_VS_" + timeString;
- if (vsDisplayName == null) {
- vsDisplayName = vmSnapshotName;
- }
- if(_vmSnapshotDao.findByName(vmId,vsDisplayName) != null){
- throw new InvalidParameterValueException("Creating VM snapshot failed due to VM snapshot with name" + vsDisplayName + " already exists");
- }
-
- // check VM state
- if (userVmVo.getState() != VirtualMachine.State.Running && userVmVo.getState() != VirtualMachine.State.Stopped) {
- throw new InvalidParameterValueException("Creating vm snapshot failed due to VM:" + vmId + " is not in the running or Stopped state");
- }
-
- if(snapshotMemory && userVmVo.getState() == VirtualMachine.State.Stopped){
- throw new InvalidParameterValueException("Can not snapshot memory when VM is in stopped state");
- }
-
- // for KVM, only allow snapshot with memory when VM is in running state
- if(userVmVo.getHypervisorType() == HypervisorType.KVM && userVmVo.getState() == State.Running && !snapshotMemory){
- throw new InvalidParameterValueException("KVM VM does not allow to take a disk-only snapshot when VM is in running state");
- }
-
- // check access
- _accountMgr.checkAccess(caller, null, true, userVmVo);
-
- // check max snapshot limit for per VM
- if (_vmSnapshotDao.findByVm(vmId).size() >= _vmSnapshotMax) {
- throw new CloudRuntimeException("Creating vm snapshot failed due to a VM can just have : " + _vmSnapshotMax
- + " VM snapshots. Please delete old ones");
- }
-
- // check if there are active volume snapshots tasks
- List<VolumeVO> listVolumes = _volumeDao.findByInstance(vmId);
- for (VolumeVO volume : listVolumes) {
- List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating,
- Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
- if (activeSnapshots.size() > 0) {
- throw new CloudRuntimeException(
- "There is other active volume snapshot tasks on the instance to which the volume is attached, please try again later.");
- }
- }
-
- // check if there are other active VM snapshot tasks
- if (hasActiveVMSnapshotTasks(vmId)) {
- throw new CloudRuntimeException("There is other active vm snapshot tasks on the instance, please try again later");
- }
-
- VMSnapshot.Type vmSnapshotType = VMSnapshot.Type.Disk;
- if(snapshotMemory && userVmVo.getState() == VirtualMachine.State.Running)
- vmSnapshotType = VMSnapshot.Type.DiskAndMemory;
-
- try {
- VMSnapshotVO vmSnapshotVo = new VMSnapshotVO(userVmVo.getAccountId(), userVmVo.getDomainId(), vmId, vsDescription, vmSnapshotName,
- vsDisplayName, userVmVo.getServiceOfferingId(), vmSnapshotType, null);
- VMSnapshot vmSnapshot = _vmSnapshotDao.persist(vmSnapshotVo);
- if (vmSnapshot == null) {
- throw new CloudRuntimeException("Failed to create snapshot for vm: " + vmId);
- }
- return vmSnapshot;
- } catch (Exception e) {
- String msg = e.getMessage();
- s_logger.error("Create vm snapshot record failed for vm: " + vmId + " due to: " + msg);
- }
- return null;
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- @Override
- @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_CREATE, eventDescription = "creating VM snapshot", async = true)
- public VMSnapshot creatVMSnapshot(Long vmId, Long vmSnapshotId) {
- UserVmVO userVm = _userVMDao.findById(vmId);
- if (userVm == null) {
- throw new InvalidParameterValueException("Create vm to snapshot failed due to vm: " + vmId + " is not found");
- }
- VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
- if(vmSnapshot == null){
- throw new CloudRuntimeException("VM snapshot id: " + vmSnapshotId + " can not be found");
- }
- Long hostId = pickRunningHost(vmId);
- try {
- vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.CreateRequested);
- } catch (NoTransitionException e) {
- throw new CloudRuntimeException(e.getMessage());
- }
- return createVmSnapshotInternal(userVm, vmSnapshot, hostId);
- }
-
- protected VMSnapshot createVmSnapshotInternal(UserVmVO userVm, VMSnapshotVO vmSnapshot, Long hostId) {
-<<<<<<< HEAD
- try {
- CreateVMSnapshotAnswer answer = null;
-=======
- CreateVMSnapshotAnswer answer = null;
- try {
->>>>>>> acd2396... fix CLOUDSTACK-3591 add usage recording for VM snapshots
- GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
-
- // prepare snapshotVolumeTos
- List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId());
-
- // prepare target snapshotTO and its parent snapshot (current snapshot)
- VMSnapshotTO current = null;
- VMSnapshotVO currentSnapshot = _vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId());
- if (currentSnapshot != null)
- current = getSnapshotWithParents(currentSnapshot);
- VMSnapshotTO target = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(), null, vmSnapshot.getDescription(), false,
- current);
- if (current == null)
- vmSnapshot.setParent(null);
- else
- vmSnapshot.setParent(current.getId());
-
- CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(),target ,volumeTOs, guestOS.getDisplayName(),userVm.getState());
- ccmd.setWait(_wait);
-
- answer = (CreateVMSnapshotAnswer) sendToPool(hostId, ccmd);
- if (answer != null && answer.getResult()) {
- processAnswer(vmSnapshot, userVm, answer, hostId);
- s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
- }else{
-
- String errMsg = "Creating VM snapshot: " + vmSnapshot.getName() + " failed";
- if(answer != null && answer.getDetails() != null)
- errMsg = errMsg + " due to " + answer.getDetails();
- s_logger.error(errMsg);
- vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
- throw new CloudRuntimeException(errMsg);
- }
- return vmSnapshot;
- } catch (Exception e) {
- if(e instanceof AgentUnavailableException){
- try {
- vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
- } catch (NoTransitionException e1) {
- s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
- }
- }
- String msg = e.getMessage();
- s_logger.error("Create vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName() + " due to " + msg);
- throw new CloudRuntimeException(msg);
- } finally{
- if(vmSnapshot.getState() == VMSnapshot.State.Allocated){
- s_logger.warn("Create vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName());
- _vmSnapshotDao.remove(vmSnapshot.getId());
- }
- if(vmSnapshot.getState() == VMSnapshot.State.Ready && answer != null){
- for (VolumeTO volumeTo : answer.getVolumeTOs()){
- publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_CREATE,vmSnapshot,userVm,volumeTo);
- }
- }
- }
- }
-
- private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, VolumeTO volumeTo){
- VolumeVO volume = _volumeDao.findById(volumeTo.getId());
- Long diskOfferingId = volume.getDiskOfferingId();
- Long offeringId = null;
- if (diskOfferingId != null) {
- DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
- if (offering != null
- && (offering.getType() == DiskOfferingVO.Type.Disk)) {
- offeringId = offering.getId();
- }
- }
- UsageEventUtils.publishUsageEvent(
- type,
- vmSnapshot.getAccountId(),
- userVm.getDataCenterId(),
- userVm.getId(),
- vmSnapshot.getName(),
- offeringId,
- volume.getId(), // save volume's id into templateId field
- volumeTo.getChainSize(),
- VMSnapshot.class.getName(), vmSnapshot.getUuid());
- }
-
- protected List<VolumeTO> getVolumeTOList(Long vmId) {
- List<VolumeTO> volumeTOs = new ArrayList<VolumeTO>();
- List<VolumeVO> volumeVos = _volumeDao.findByInstance(vmId);
-
- for (VolumeVO volume : volumeVos) {
- StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
- VolumeTO volumeTO = new VolumeTO(volume, pool);
- volumeTOs.add(volumeTO);
- }
- return volumeTOs;
- }
-
- // get snapshot and its parents recursively
- private VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot) {
- Map<Long, VMSnapshotVO> snapshotMap = new HashMap<Long, VMSnapshotVO>();
- List<VMSnapshotVO> allSnapshots = _vmSnapshotDao.findByVm(snapshot.getVmId());
- for (VMSnapshotVO vmSnapshotVO : allSnapshots) {
- snapshotMap.put(vmSnapshotVO.getId(), vmSnapshotVO);
- }
-
- VMSnapshotTO currentTO = convert2VMSnapshotTO(snapshot);
- VMSnapshotTO result = currentTO;
- VMSnapshotVO current = snapshot;
- while (current.getParent() != null) {
- VMSnapshotVO parent = snapshotMap.get(current.getParent());
- currentTO.setParent(convert2VMSnapshotTO(parent));
- current = snapshotMap.get(current.getParent());
- currentTO = currentTO.getParent();
- }
- return result;
- }
-
- private VMSnapshotTO convert2VMSnapshotTO(VMSnapshotVO vo) {
- return new VMSnapshotTO(vo.getId(), vo.getName(), vo.getType(), vo.getCreated().getTime(), vo.getDescription(),
- vo.getCurrent(), null);
- }
-
- protected boolean vmSnapshotStateTransitTo(VMSnapshotVO vsnp, VMSnapshot.Event event) throws NoTransitionException {
- return _vmSnapshottateMachine.transitTo(vsnp, event, null, _vmSnapshotDao);
- }
-
- @DB
- protected void processAnswer(VMSnapshotVO vmSnapshot, UserVmVO userVm, Answer as, Long hostId) {
- final Transaction txn = Transaction.currentTxn();
- try {
- txn.start();
- if (as instanceof CreateVMSnapshotAnswer) {
- CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as;
- finalizeCreate(vmSnapshot, answer.getVolumeTOs());
- vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
- } else if (as instanceof RevertToVMSnapshotAnswer) {
- RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as;
- finalizeRevert(vmSnapshot, answer.getVolumeTOs());
- vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
- } else if (as instanceof DeleteVMSnapshotAnswer) {
- DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as;
- finalizeDelete(vmSnapshot, answer.getVolumeTOs());
- _vmSnapshotDao.remove(vmSnapshot.getId());
- }
- txn.commit();
- } catch (Exception e) {
- String errMsg = "Error while process answer: " + as.getClass() + " due to " + e.getMessage();
- s_logger.error(errMsg, e);
- txn.rollback();
- throw new CloudRuntimeException(errMsg);
- } finally {
- txn.close();
- }
- }
-
- protected void finalizeDelete(VMSnapshotVO vmSnapshot, List<VolumeTO> VolumeTOs) {
- // update volumes path
- updateVolumePath(VolumeTOs);
-
- // update children's parent snapshots
- List<VMSnapshotVO> children= _vmSnapshotDao.listByParent(vmSnapshot.getId());
- for (VMSnapshotVO child : children) {
- child.setParent(vmSnapshot.getParent());
- _vmSnapshotDao.persist(child);
- }
-
- // update current snapshot
- VMSnapshotVO current = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
- if(current != null && current.getId() == vmSnapshot.getId() && vmSnapshot.getParent() != null){
- VMSnapshotVO parent = _vmSnapshotDao.findById(vmSnapshot.getParent());
- parent.setCurrent(true);
- _vmSnapshotDao.persist(parent);
- }
- vmSnapshot.setCurrent(false);
- _vmSnapshotDao.persist(vmSnapshot);
- }
-
- protected void finalizeCreate(VMSnapshotVO vmSnapshot, List<VolumeTO> VolumeTOs) {
- // update volumes path
- updateVolumePath(VolumeTOs);
-
- vmSnapshot.setCurrent(true);
-
- // change current snapshot
- if (vmSnapshot.getParent() != null) {
- VMSnapshotVO previousCurrent = _vmSnapshotDao.findById(vmSnapshot.getParent());
- previousCurrent.setCurrent(false);
- _vmSnapshotDao.persist(previousCurrent);
- }
- _vmSnapshotDao.persist(vmSnapshot);
- }
-
- protected void finalizeRevert(VMSnapshotVO vmSnapshot, List<VolumeTO> volumeToList) {
- // update volumes path
- updateVolumePath(volumeToList);
-
- // update current snapshot, current snapshot is the one reverted to
- VMSnapshotVO previousCurrent = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
- if(previousCurrent != null){
- previousCurrent.setCurrent(false);
- _vmSnapshotDao.persist(previousCurrent);
- }
- vmSnapshot.setCurrent(true);
- _vmSnapshotDao.persist(vmSnapshot);
- }
-
- private void updateVolumePath(List<VolumeTO> volumeTOs) {
- for (VolumeTO volume : volumeTOs) {
- if (volume.getPath() != null) {
- VolumeVO volumeVO = _volumeDao.findById(volume.getId());
- volumeVO.setPath(volume.getPath());
- volumeVO.setVmSnapshotChainSize(volume.getChainSize());
- _volumeDao.persist(volumeVO);
- }
- }
- }
-
- public VMSnapshotManagerImpl() {
-
- }
-
- protected Answer sendToPool(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException {
- long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd);
- Answer answer = _agentMgr.send(targetHostId, cmd);
- return answer;
- }
-
- @Override
- public boolean hasActiveVMSnapshotTasks(Long vmId){
- List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(vmId,
- VMSnapshot.State.Creating, VMSnapshot.State.Expunging,VMSnapshot.State.Reverting,VMSnapshot.State.Allocated);
- return activeVMSnapshots.size() > 0;
- }
-
- @Override
- @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_DELETE, eventDescription = "delete vm snapshots", async=true)
- public boolean deleteVMSnapshot(Long vmSnapshotId) {
- Account caller = getCaller();
-
- VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
- if (vmSnapshot == null) {
- throw new InvalidParameterValueException("unable to find the vm snapshot with id " + vmSnapshotId);
- }
-
- _accountMgr.checkAccess(caller, null, true, vmSnapshot);
-
- // check VM snapshot states, only allow to delete vm snapshots in created and error state
- if (VMSnapshot.State.Ready != vmSnapshot.getState() && VMSnapshot.State.Expunging != vmSnapshot.getState() && VMSnapshot.State.Error != vmSnapshot.getState()) {
- throw new InvalidParameterValueException("Can't delete the vm snapshotshot " + vmSnapshotId + " due to it is not in Created or Error, or Expunging State");
- }
-
- // check if there are other active VM snapshot tasks
- if (hasActiveVMSnapshotTasks(vmSnapshot.getVmId())) {
- List<VMSnapshotVO> expungingSnapshots = _vmSnapshotDao.listByInstanceId(vmSnapshot.getVmId(), VMSnapshot.State.Expunging);
- if(expungingSnapshots.size() > 0 && expungingSnapshots.get(0).getId() == vmSnapshot.getId())
- s_logger.debug("Target VM snapshot already in expunging state, go on deleting it: " + vmSnapshot.getDisplayName());
- else
- throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
- }
-
- if(vmSnapshot.getState() == VMSnapshot.State.Allocated){
- return _vmSnapshotDao.remove(vmSnapshot.getId());
- }else{
- return deleteSnapshotInternal(vmSnapshot);
- }
- }
-
- @DB
- protected boolean deleteSnapshotInternal(VMSnapshotVO vmSnapshot) {
- UserVmVO userVm = _userVMDao.findById(vmSnapshot.getVmId());
- DeleteVMSnapshotAnswer answer = null;
- try {
- vmSnapshotStateTransitTo(vmSnapshot,VMSnapshot.Event.ExpungeRequested);
- Long hostId = pickRunningHost(vmSnapshot.getVmId());
-
- // prepare snapshotVolumeTos
- List<VolumeTO> volumeTOs = getVolumeTOList(vmSnapshot.getVmId());
-
- // prepare DeleteVMSnapshotCommand
- String vmInstanceName = userVm.getInstanceName();
- VMSnapshotTO parent = getSnapshotWithParents(vmSnapshot).getParent();
- VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(),
- vmSnapshot.getCreated().getTime(), vmSnapshot.getDescription(), vmSnapshot.getCurrent(), parent);
- GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
- DeleteVMSnapshotCommand deleteSnapshotCommand = new DeleteVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs,guestOS.getDisplayName());
-
- answer = (DeleteVMSnapshotAnswer) sendToPool(hostId, deleteSnapshotCommand);
-
- if (answer != null && answer.getResult()) {
- processAnswer(vmSnapshot, userVm, answer, hostId);
- s_logger.debug("Delete VM snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
- return true;
- } else {
- s_logger.error("Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + answer.getDetails());
- return false;
- }
- } catch (Exception e) {
- String msg = "Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + e.getMessage();
- s_logger.error(msg , e);
- throw new CloudRuntimeException(e.getMessage());
- } finally{
- if(answer != null && answer.getResult()){
- for (VolumeTO volumeTo : answer.getVolumeTOs()){
- publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_DELETE,vmSnapshot,userVm,volumeTo);
- }
- }
- }
- }
-
- @Override
- @ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_REVERT, eventDescription = "revert to VM snapshot", async = true)
- public UserVm revertToSnapshot(Long vmSnapshotId) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException {
-
- // check if VM snapshot exists in DB
- VMSnapshotVO vmSnapshotVo = _vmSnapshotDao.findById(vmSnapshotId);
- if (vmSnapshotVo == null) {
- throw new InvalidParameterValueException(
- "unable to find the vm snapshot with id " + vmSnapshotId);
- }
- Long vmId = vmSnapshotVo.getVmId();
- UserVmVO userVm = _userVMDao.findById(vmId);
- // check if VM exists
- if (userVm == null) {
- throw new InvalidParameterValueException("Revert vm to snapshot: "
- + vmSnapshotId + " failed due to vm: " + vmId
- + " is not found");
- }
-
- // check if there are other active VM snapshot tasks
- if (hasActiveVMSnapshotTasks(vmId)) {
- throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
- }
-
- Account caller = getCaller();
- _accountMgr.checkAccess(caller, null, true, vmSnapshotVo);
-
- // VM should be in running or stopped states
- if (userVm.getState() != VirtualMachine.State.Running
- && userVm.getState() != VirtualMachine.State.Stopped) {
- throw new InvalidParameterValueException(
- "VM Snapshot reverting failed due to vm is not in the state of Running or Stopped.");
- }
-
- // if snapshot is not created, error out
- if (vmSnapshotVo.getState() != VMSnapshot.State.Ready) {
- throw new InvalidParameterValueException(
- "VM Snapshot reverting failed due to vm snapshot is not in the state of Created.");
- }
-
- UserVmVO vm = null;
- Long hostId = null;
-
- // start or stop VM first, if revert from stopped state to running state, or from running to stopped
- if(userVm.getState() == VirtualMachine.State.Stopped && vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory){
- try {
-<<<<<<< HEAD
- _itMgr.advanceStart(userVm.getUuid(), new HashMap<VirtualMachineProfile.Param, Object>());
- vm = _userVMDao.findById(userVm.getId());
- hostId = vm.getHostId();
- } catch (Exception e) {
- s_logger.error("Start VM " + userVm.getInstanceName() + " before reverting failed due to " + e.getMessage());
- throw new CloudRuntimeException(e.getMessage());
- }
- }else {
- if(userVm.getState() == VirtualMachine.State.Running && vmSnapshotVo.getType() == VMSnapshot.Type.Disk){
- try {
- _itMgr.advanceStop(userVm.getUuid(), true);
-=======
- vm = _itMgr.advanceStart(userVm, new HashMap<VirtualMachineProfile.Param, Object>(), callerUser, owner);
- hostId = vm.getHostId();
- } catch (Exception e) {
- s_logger.error("Start VM " + userVm.getInstanceName() + " before reverting failed due to " + e.getMessage());
- throw new CloudRuntimeException(e.getMessage());
- }
- }else {
- if(userVm.getState() == VirtualMachine.State.Running && vmSnapshotVo.getType() == VMSnapshot.Type.Disk){
- try {
- _itMgr.advanceStop(userVm, true, callerUser, owner);
->>>>>>> acd2396... fix CLOUDSTACK-3591 add usage recording for VM snapshots
- } catch (Exception e) {
- s_logger.error("Stop VM " + userVm.getInstanceName() + " before reverting failed due to " + e.getMessage());
- throw new CloudRuntimeException(e.getMessage());
- }
- }
- hostId = pickRunningHost(userVm.getId());
- }
-
- if(hostId == null)
- throw new CloudRuntimeException("Can not find any host to revert snapshot " + vmSnapshotVo.getName());
-
- // check if there are other active VM snapshot tasks
- if (hasActiveVMSnapshotTasks(userVm.getId())) {
- throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
- }
-
- userVm = _userVMDao.findById(userVm.getId());
- try {
- vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.RevertRequested);
- } catch (NoTransitionException e) {
- throw new CloudRuntimeException(e.getMessage());
- }
- return revertInternal(userVm, vmSnapshotVo, hostId);
- }
-
- private UserVm revertInternal(UserVmVO userVm, VMSnapshotVO vmSnapshotVo, Long hostId) {
- try {
- VMSnapshotVO snapshot = _vmSnapshotDao.findById(vmSnapshotVo.getId());
- // prepare RevertToSnapshotCommand
- List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId());
- String vmInstanceName = userVm.getInstanceName();
- VMSnapshotTO parent = getSnapshotWithParents(snapshot).getParent();
-<<<<<<< HEAD
- VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(snapshot.getId(), snapshot.getName(), snapshot.getType(),
- snapshot.getCreated().getTime(), snapshot.getDescription(), snapshot.getCurrent(), parent);
-=======
- VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(snapshot.getId(), snapshot.getName(), snapshot.getType(),
- snapshot.getCreated().getTime(), snapshot.getDescription(), snapshot.getCurrent(), parent);
->>>>>>> acd2396... fix CLOUDSTACK-3591 add usage recording for VM snapshots
-
- GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
- RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName());
-
- RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) sendToPool(hostId, revertToSnapshotCommand);
- if (answer != null && answer.getResult()) {
- processAnswer(vmSnapshotVo, userVm, answer, hostId);
- s_logger.debug("RevertTo " + vmSnapshotVo.getName() + " succeeded for vm: " + userVm.getInstanceName());
- } else {
- String errMsg = "Revert VM: " + userVm.getInstanceName() + " to snapshot: "+ vmSnapshotVo.getName() + " failed";
- if(answer != null && answer.getDetails() != null)
- errMsg = errMsg + " due to " + answer.getDetails();
- s_logger.error(errMsg);
- // agent report revert operation fails
- vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.OperationFailed);
- throw new CloudRuntimeException(errMsg);
- }
- } catch (Exception e) {
- if(e instanceof AgentUnavailableException){
- try {
- vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.OperationFailed);
- } catch (NoTransitionException e1) {
- s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
- }
- }
- // for other exceptions, do not change VM snapshot state, leave it for snapshotSync
- String errMsg = "revert vm: " + userVm.getInstanceName() + " to snapshot " + vmSnapshotVo.getName() + " failed due to " + e.getMessage();
- s_logger.error(errMsg);
- throw new CloudRuntimeException(e.getMessage());
- }
- return userVm;
- }
-
-
- @Override
- public VMSnapshot getVMSnapshotById(Long id) {
- VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(id);
- return vmSnapshot;
- }
-
- protected Long pickRunningHost(Long vmId) {
- UserVmVO vm = _userVMDao.findById(vmId);
- // use VM's host if VM is running
- if(vm.getState() == State.Running)
- return vm.getHostId();
-
- // check if lastHostId is available
- if(vm.getLastHostId() != null){
- HostVO lastHost = _hostDao.findById(vm.getLastHostId());
- if(lastHost.getStatus() == com.cloud.host.Status.Up && !lastHost.isInMaintenanceStates())
- return lastHost.getId();
- }
-
- List<VolumeVO> listVolumes = _volumeDao.findByInstance(vmId);
- if (listVolumes == null || listVolumes.size() == 0) {
- throw new InvalidParameterValueException("vmInstance has no volumes");
- }
- VolumeVO volume = listVolumes.get(0);
- Long poolId = volume.getPoolId();
- if (poolId == null) {
- throw new InvalidParameterValueException("pool id is not found");
- }
- StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
- if (storagePool == null) {
- throw new InvalidParameterValueException("storage pool is not found");
- }
- List<HostVO> listHost = _hostDao.listAllUpAndEnabledNonHAHosts(Host.Type.Routing, storagePool.getClusterId(), storagePool.getPodId(),
- storagePool.getDataCenterId(), null);
- if (listHost == null || listHost.size() == 0) {
- throw new InvalidParameterValueException("no host in up state is found");
- }
- return listHost.get(0).getId();
- }
-
- @Override
- public VirtualMachine getVMBySnapshotId(Long id) {
- VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(id);
- if(vmSnapshot == null){
- throw new InvalidParameterValueException("unable to find the vm snapshot with id " + id);
- }
- Long vmId = vmSnapshot.getVmId();
- UserVmVO vm = _userVMDao.findById(vmId);
- return vm;
- }
-
- @Override
- public boolean deleteAllVMSnapshots(long vmId, VMSnapshot.Type type) {
- boolean result = true;
- List<VMSnapshotVO> listVmSnapshots = _vmSnapshotDao.findByVm(vmId);
- if (listVmSnapshots == null || listVmSnapshots.isEmpty()) {
- return true;
- }
- for (VMSnapshotVO snapshot : listVmSnapshots) {
- VMSnapshotVO target = _vmSnapshotDao.findById(snapshot.getId());
- if(type != null && target.getType() != type)
- continue;
- if (!deleteSnapshotInternal(target)) {
- result = false;
- break;
- }
- }
- return result;
- }
-
- @Override
- public boolean syncVMSnapshot(VMInstanceVO vm, Long hostId) {
- try{
-
- UserVmVO userVm = _userVMDao.findById(vm.getId());
- if(userVm == null)
- return false;
-
- List<VMSnapshotVO> vmSnapshotsInExpungingStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Reverting, VMSnapshot.State.Creating);
- for (VMSnapshotVO vmSnapshotVO : vmSnapshotsInExpungingStates) {
- if(vmSnapshotVO.getState() == VMSnapshot.State.Expunging){
- return deleteSnapshotInternal(vmSnapshotVO);
- }else if(vmSnapshotVO.getState() == VMSnapshot.State.Creating){
- return createVmSnapshotInternal(userVm, vmSnapshotVO, hostId) != null;
- }else if(vmSnapshotVO.getState() == VMSnapshot.State.Reverting){
- return revertInternal(userVm, vmSnapshotVO, hostId) != null;
- }
- }
- }catch (Exception e) {
- s_logger.error(e.getMessage(),e);
- if(_vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging).size() == 0)
- return true;
- else
- return false;
- }
- return false;
- }
-
-}