Skip to content

Commit 50b5e2e

Browse files
author
Mike Tutkowski
committed
CLOUDSTACK-6170
1 parent 2700821 commit 50b5e2e

3 files changed

Lines changed: 79 additions & 0 deletions

File tree

engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Map;
2222
import java.util.Set;
2323

24+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
2425
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
2526

2627
import com.cloud.agent.api.to.VirtualMachineTO;
@@ -94,6 +95,8 @@ VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId,
9495

9596
void cleanupVolumes(long vmId) throws ConcurrentOperationException;
9697

98+
void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore);
99+
97100
void disconnectVolumesFromHost(long vmId, long hostId);
98101

99102
void migrateVolumes(VirtualMachine vm, VirtualMachineTO vmTo, Host srcHost, Host destHost, Map<Volume, StoragePool> volumeToPool);

engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@
3737
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
3838
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
3939
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
40+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
4041
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
4142
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
43+
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
4244
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
4345
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
4446
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
@@ -831,6 +833,15 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
831833
}
832834
}
833835

836+
@Override
837+
public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) {
838+
DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
839+
840+
if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
841+
((PrimaryDataStoreDriver)dataStoreDriver).disconnectVolumeFromHost(volumeInfo, host, dataStore);
842+
}
843+
}
844+
834845
@Override
835846
public void disconnectVolumesFromHost(long vmId, long hostId) {
836847
HostVO host = _hostDao.findById(hostId);

server/src/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
7171
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
7272
import org.apache.cloudstack.engine.service.api.OrchestrationService;
73+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
74+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
7375
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
7476
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
7577
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
@@ -81,11 +83,13 @@
8183
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
8284
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
8385
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
86+
import org.apache.cloudstack.storage.command.DettachCommand;
8487
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
8588
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
8689

8790
import com.cloud.agent.AgentManager;
8891
import com.cloud.agent.api.Answer;
92+
import com.cloud.agent.api.Command;
8993
import com.cloud.agent.api.GetVmDiskStatsAnswer;
9094
import com.cloud.agent.api.GetVmDiskStatsCommand;
9195
import com.cloud.agent.api.GetVmStatsAnswer;
@@ -94,6 +98,8 @@
9498
import com.cloud.agent.api.StartAnswer;
9599
import com.cloud.agent.api.VmDiskStatsEntry;
96100
import com.cloud.agent.api.VmStatsEntry;
101+
import com.cloud.agent.api.to.DataTO;
102+
import com.cloud.agent.api.to.DiskTO;
97103
import com.cloud.agent.api.to.NicTO;
98104
import com.cloud.agent.api.to.VirtualMachineTO;
99105
import com.cloud.agent.manager.Commands;
@@ -199,6 +205,7 @@
199205
import com.cloud.storage.Storage;
200206
import com.cloud.storage.Storage.ImageFormat;
201207
import com.cloud.storage.Storage.TemplateType;
208+
import com.cloud.storage.DataStoreRole;
202209
import com.cloud.storage.StorageManager;
203210
import com.cloud.storage.StoragePool;
204211
import com.cloud.storage.StoragePoolStatus;
@@ -448,6 +455,8 @@ public enum UserVmCloneType {
448455
DeploymentPlanningManager _planningMgr;
449456
@Inject
450457
VolumeApiService _volumeService;
458+
@Inject
459+
DataStoreManager _dataStoreMgr;
451460

452461
protected ScheduledExecutorService _executor = null;
453462
protected int _expungeInterval;
@@ -4651,6 +4660,9 @@ public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId)
46514660
/* Detach and destory the old root volume */
46524661

46534662
_volsDao.detachVolume(root.getId());
4663+
4664+
handleManagedStorage(vm, root);
4665+
46544666
volumeMgr.destroyVolume(root);
46554667

46564668
// 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 UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId)
46984710

46994711
}
47004712

4713+
private void handleManagedStorage(UserVmVO vm, VolumeVO root) {
4714+
StoragePoolVO storagePool = _storagePoolDao.findById(root.getPoolId());
4715+
4716+
if (storagePool.isManaged()) {
4717+
Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId();
4718+
4719+
if (hostId != null) {
4720+
DataTO volTO = volFactory.getVolume(root.getId()).getTO();
4721+
DiskTO disk = new DiskTO(volTO, root.getDeviceId(), root.getPath(), root.getVolumeType());
4722+
4723+
// it's OK in this case to send a detach command to the host for a root volume as this
4724+
// will simply lead to the SR that supports the root volume being removed
4725+
DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
4726+
4727+
cmd.setManaged(true);
4728+
4729+
cmd.setStorageHost(storagePool.getHostAddress());
4730+
cmd.setStoragePort(storagePool.getPort());
4731+
4732+
cmd.set_iScsiName(root.get_iScsiName());
4733+
4734+
Commands cmds = new Commands(Command.OnError.Stop);
4735+
4736+
cmds.addCommand(cmd);
4737+
4738+
try {
4739+
_agentMgr.send(hostId, cmds);
4740+
}
4741+
catch (Exception ex) {
4742+
throw new CloudRuntimeException(ex.getMessage());
4743+
}
4744+
4745+
if (!cmds.isSuccessful()) {
4746+
for (Answer answer : cmds.getAnswers()) {
4747+
if (!answer.getResult()) {
4748+
s_logger.warn("Failed to reset vm due to: " + answer.getDetails());
4749+
4750+
throw new CloudRuntimeException("Unable to reset " + vm + " due to " + answer.getDetails());
4751+
}
4752+
}
4753+
}
4754+
4755+
if (hostId != null) {
4756+
// root.getPoolId() should be null if the VM we are attaching the disk to has never been started before
4757+
DataStore dataStore = root.getPoolId() != null ? _dataStoreMgr.getDataStore(root.getPoolId(), DataStoreRole.Primary) : null;
4758+
Host host = this._hostDao.findById(hostId);
4759+
4760+
volumeMgr.disconnectVolumeFromHost(volFactory.getVolume(root.getId()), host, dataStore);
4761+
}
4762+
}
4763+
}
4764+
}
4765+
47014766
@Override
47024767
public void prepareStop(VirtualMachineProfile profile) {
47034768
UserVmVO vm = _vmDao.findById(profile.getId());

0 commit comments

Comments
 (0)