You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mt...@apache.org on 2014/03/21 07:07:45 UTC
git commit: updated refs/heads/master to 7629d6f
Repository: cloudstack
Updated Branches:
refs/heads/master ea2ee1521 -> 7629d6f12
CLOUDSTACK-6170
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7629d6f1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7629d6f1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7629d6f1
Branch: refs/heads/master
Commit: 7629d6f1297d8a609368a378ad5c179e9606ee1d
Parents: ea2ee15
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Thu Mar 20 12:15:27 2014 -0600
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Thu Mar 20 23:54:53 2014 -0600
----------------------------------------------------------------------
.../service/VolumeOrchestrationService.java | 3 +
.../orchestration/VolumeOrchestrator.java | 11 ++++
server/src/com/cloud/vm/UserVmManagerImpl.java | 65 ++++++++++++++++++++
server/test/com/cloud/vm/UserVmManagerTest.java | 29 +++++++++
4 files changed, 108 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7629d6f1/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
index 095d954..3b555e5 100644
--- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
@@ -21,6 +21,7 @@ package org.apache.cloudstack.engine.orchestration.service;
import java.util.Map;
import java.util.Set;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import com.cloud.agent.api.to.VirtualMachineTO;
@@ -94,6 +95,8 @@ public interface VolumeOrchestrationService {
void cleanupVolumes(long vmId) throws ConcurrentOperationException;
+ void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore);
+
void disconnectVolumesFromHost(long vmId, long hostId);
void migrateVolumes(VirtualMachine vm, VirtualMachineTO vmTo, Host srcHost, Host destHost, Map<Volume, StoragePool> volumeToPool);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7629d6f1/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
index a74d79c..4ebde04 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -37,8 +37,10 @@ import org.apache.log4j.Logger;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
@@ -832,6 +834,15 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
}
@Override
+ public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) {
+ DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
+
+ if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
+ ((PrimaryDataStoreDriver)dataStoreDriver).disconnectVolumeFromHost(volumeInfo, host, dataStore);
+ }
+ }
+
+ @Override
public void disconnectVolumesFromHost(long vmId, long hostId) {
HostVO host = _hostDao.findById(hostId);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7629d6f1/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index b4888a8..f92eaca 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -70,6 +70,8 @@ import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.service.api.OrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
@@ -81,11 +83,13 @@ import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.storage.command.DettachCommand;
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.GetVmDiskStatsAnswer;
import com.cloud.agent.api.GetVmDiskStatsCommand;
import com.cloud.agent.api.GetVmStatsAnswer;
@@ -94,6 +98,8 @@ import com.cloud.agent.api.PvlanSetupCommand;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.VmDiskStatsEntry;
import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.Commands;
@@ -199,6 +205,7 @@ import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType;
+import com.cloud.storage.DataStoreRole;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolStatus;
@@ -448,6 +455,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
DeploymentPlanningManager _planningMgr;
@Inject
VolumeApiService _volumeService;
+ @Inject
+ DataStoreManager _dataStoreMgr;
protected ScheduledExecutorService _executor = null;
protected int _expungeInterval;
@@ -4651,6 +4660,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
/* Detach and destory the old root volume */
_volsDao.detachVolume(root.getId());
+
+ handleManagedStorage(vm, root);
+
volumeMgr.destroyVolume(root);
// For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage
@@ -4698,6 +4710,59 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
+ private void handleManagedStorage(UserVmVO vm, VolumeVO root) {
+ StoragePoolVO storagePool = _storagePoolDao.findById(root.getPoolId());
+
+ if (storagePool.isManaged()) {
+ Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
+
+ if (hostId != null) {
+ DataTO volTO = volFactory.getVolume(root.getId()).getTO();
+ DiskTO disk = new DiskTO(volTO, root.getDeviceId(), root.getPath(), root.getVolumeType());
+
+ // it's OK in this case to send a detach command to the host for a root volume as this
+ // will simply lead to the SR that supports the root volume being removed
+ DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
+
+ cmd.setManaged(true);
+
+ cmd.setStorageHost(storagePool.getHostAddress());
+ cmd.setStoragePort(storagePool.getPort());
+
+ cmd.set_iScsiName(root.get_iScsiName());
+
+ Commands cmds = new Commands(Command.OnError.Stop);
+
+ cmds.addCommand(cmd);
+
+ try {
+ _agentMgr.send(hostId, cmds);
+ }
+ catch (Exception ex) {
+ throw new CloudRuntimeException(ex.getMessage());
+ }
+
+ if (!cmds.isSuccessful()) {
+ for (Answer answer : cmds.getAnswers()) {
+ if (!answer.getResult()) {
+ s_logger.warn("Failed to reset vm due to: " + answer.getDetails());
+
+ throw new CloudRuntimeException("Unable to reset " + vm + " due to " + answer.getDetails());
+ }
+ }
+ }
+
+ if (hostId != null) {
+ // root.getPoolId() should be null if the VM we are attaching the disk to has never been started before
+ DataStore dataStore = root.getPoolId() != null ? _dataStoreMgr.getDataStore(root.getPoolId(), DataStoreRole.Primary) : null;
+ Host host = this._hostDao.findById(hostId);
+
+ volumeMgr.disconnectVolumeFromHost(volFactory.getVolume(root.getId()), host, dataStore);
+ }
+ }
+ }
+ }
+
@Override
public void prepareStop(VirtualMachineProfile profile) {
UserVmVO vm = _vmDao.findById(profile.getId());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7629d6f1/server/test/com/cloud/vm/UserVmManagerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/test/com/cloud/vm/UserVmManagerTest.java
index 43010a3..b67c164 100755
--- a/server/test/com/cloud/vm/UserVmManagerTest.java
+++ b/server/test/com/cloud/vm/UserVmManagerTest.java
@@ -50,6 +50,8 @@ import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.ConfigurationManager;
@@ -141,6 +143,8 @@ public class UserVmManagerTest {
EntityManager _entityMgr;
@Mock
ResourceLimitService _resourceLimitMgr;
+ @Mock
+ PrimaryDataStoreDao _storagePoolDao;
@Before
public void setup() {
@@ -162,6 +166,7 @@ public class UserVmManagerTest {
_userVmMgr._resourceLimitMgr = _resourceLimitMgr;
_userVmMgr._scaleRetry = 2;
_userVmMgr._entityMgr = _entityMgr;
+ _userVmMgr._storagePoolDao = _storagePoolDao;
doReturn(3L).when(_account).getId();
doReturn(8L).when(_vmMock).getAccountId();
@@ -214,6 +219,12 @@ public class UserVmManagerTest {
Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid");
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+ StoragePoolVO storagePool = new StoragePoolVO();
+
+ storagePool.setManaged(false);
+
+ when(_storagePoolDao.findById(anyLong())).thenReturn(storagePool);
+
CallContext.register(user, account);
try {
_userVmMgr.restoreVMInternal(_account, _vmMock, null);
@@ -245,6 +256,12 @@ public class UserVmManagerTest {
Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid");
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+ StoragePoolVO storagePool = new StoragePoolVO();
+
+ storagePool.setManaged(false);
+
+ when(_storagePoolDao.findById(anyLong())).thenReturn(storagePool);
+
CallContext.register(user, account);
try {
_userVmMgr.restoreVMInternal(_account, _vmMock, null);
@@ -282,6 +299,12 @@ public class UserVmManagerTest {
Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid");
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+ StoragePoolVO storagePool = new StoragePoolVO();
+
+ storagePool.setManaged(false);
+
+ when(_storagePoolDao.findById(anyLong())).thenReturn(storagePool);
+
CallContext.register(user, account);
try {
_userVmMgr.restoreVMInternal(_account, _vmMock, 14L);
@@ -321,6 +344,12 @@ public class UserVmManagerTest {
Account account = new AccountVO("testaccount", 1L, "networkdomain", (short)0, "uuid");
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+ StoragePoolVO storagePool = new StoragePoolVO();
+
+ storagePool.setManaged(false);
+
+ when(_storagePoolDao.findById(anyLong())).thenReturn(storagePool);
+
CallContext.register(user, account);
try {
_userVmMgr.restoreVMInternal(_account, _vmMock, 14L);