diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index ac507cf4629..3e5a5466fd0 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -158,8 +158,9 @@ public class VolumeServiceImpl implements VolumeService { return null; } + @Override public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { - DataStoreDriver dataStoreDriver = dataStore.getDriver(); + DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null; if (dataStoreDriver instanceof PrimaryDataStoreDriver) { return ((PrimaryDataStoreDriver)dataStoreDriver).connectVolumeToHost(volumeInfo, host, dataStore); @@ -168,8 +169,9 @@ public class VolumeServiceImpl implements VolumeService { return false; } + @Override public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { - DataStoreDriver dataStoreDriver = dataStore.getDriver(); + DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null; if (dataStoreDriver instanceof PrimaryDataStoreDriver) { ((PrimaryDataStoreDriver)dataStoreDriver).disconnectVolumeFromHost(volumeInfo, host, dataStore); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java index 4f21a021b75..529e26125f3 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java @@ -108,7 +108,11 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru if (volume.getVolumeType() == Volume.Type.DATADISK) { StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId()); - if (storagePool.isManaged()) { + // storagePool should be null if we are expunging a volume that was never + // attached to a VM that was started (the "trick" for storagePool to be null + // is that none of the VMs this volume may have been attached to were ever started, + // so the volume was never assigned to a storage pool) + if (storagePool != null && storagePool.isManaged()) { DataTO volTO = _volFactory.getVolume(volume.getId()).getTO(); DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType()); diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index ac0c438aab9..8d475dd2cee 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -1482,12 +1482,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } } - DataStore dataStore = dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary); - if (!sendCommand || (answer != null && answer.getResult())) { // Mark the volume as detached _volsDao.detachVolume(volume.getId()); + // volume.getPoolId() should be null if the VM we are attaching the disk to has never been started before + DataStore dataStore = volume.getPoolId() != null ? dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary) : null; + volService.disconnectVolumeFromHost(volFactory.getVolume(volume.getId()), host, dataStore); return _volsDao.findById(volumeId); @@ -1955,10 +1956,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } } - DataStore dataStore = dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary); + // volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before + DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null; boolean queryForChap = true; + // if we don't have a host, the VM we are attaching the disk to has never been started before if (host != null) { try { // if connectVolumeToHost returns true, then we do not want to use CHAP because the volume is already connected to the host(s)