mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Fix primary storage count when deleting volumes (#2629)
* Primary Storage count for an account does not decrease when a Data Disk is deleted When a data disk is created and not attached in a running VM, the "deleteVolume" will not decrement the count for used primary storage in the VMs accounting information. The property that is not being decremented is called "primarystoragetotal"; this information can be retrieved via "listAccounts" API method. Steps to reproduce this issue: 1 - Create an account, deploy a VM in it 2 - Check the primary storage count for the account with listAccounts API 3 - Create a data disk 4 - Check the primary storage count for the account with listAccounts API 5 - Delete the Data disk 6 - Check the primary storage count for the account with listAccounts API - It is the same as before deleting the data disk (it should not be the same as the value in step 2!) * formatting and cleanups * fix imports that were wrongly changed during rebase
This commit is contained in:
parent
d893fb5b00
commit
b9ed42bd29
@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.cloud.storage;
|
package com.cloud.storage;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
||||||
@ -26,13 +28,10 @@ import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd
|
|||||||
import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
||||||
import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
|
import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
|
||||||
|
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
|
||||||
import com.cloud.exception.ResourceAllocationException;
|
|
||||||
import com.cloud.user.Account;
|
|
||||||
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
|
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
|
||||||
public interface VolumeApiService {
|
public interface VolumeApiService {
|
||||||
/**
|
/**
|
||||||
@ -76,13 +75,14 @@ public interface VolumeApiService {
|
|||||||
|
|
||||||
GetUploadParamsResponse uploadVolume(GetUploadParamsForVolumeCmd cmd) throws ResourceAllocationException, MalformedURLException;
|
GetUploadParamsResponse uploadVolume(GetUploadParamsForVolumeCmd cmd) throws ResourceAllocationException, MalformedURLException;
|
||||||
|
|
||||||
boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException;
|
boolean deleteVolume(long volumeId, Account caller);
|
||||||
|
|
||||||
Volume attachVolumeToVM(AttachVolumeCmd command);
|
Volume attachVolumeToVM(AttachVolumeCmd command);
|
||||||
|
|
||||||
Volume detachVolumeFromVM(DetachVolumeCmd cmd);
|
Volume detachVolumeFromVM(DetachVolumeCmd cmd);
|
||||||
|
|
||||||
Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup) throws ResourceAllocationException;
|
Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account, boolean quiescevm, Snapshot.LocationType locationType, boolean asyncBackup)
|
||||||
|
throws ResourceAllocationException;
|
||||||
|
|
||||||
Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException;
|
Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException;
|
||||||
|
|
||||||
@ -92,10 +92,8 @@ public interface VolumeApiService {
|
|||||||
* Extracts the volume to a particular location.
|
* Extracts the volume to a particular location.
|
||||||
*
|
*
|
||||||
* @param cmd
|
* @param cmd
|
||||||
* the command specifying url (where the volume needs to be extracted to), zoneId (zone where the volume
|
* the command specifying url (where the volume needs to be extracted to), zoneId (zone where the volume exists),
|
||||||
* exists),
|
|
||||||
* id (the id of the volume)
|
* id (the id of the volume)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
String extractVolume(ExtractVolumeCmd cmd);
|
String extractVolume(ExtractVolumeCmd cmd);
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import com.cloud.storage.Volume;
|
|||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
|
||||||
public interface VolumeInfo extends DataObject, Volume {
|
public interface VolumeInfo extends DataObject, Volume {
|
||||||
|
|
||||||
boolean isAttachedVM();
|
boolean isAttachedVM();
|
||||||
|
|
||||||
void addPayload(Object data);
|
void addPayload(Object data);
|
||||||
@ -36,6 +37,7 @@ public interface VolumeInfo extends DataObject, Volume {
|
|||||||
Long getLastPoolId();
|
Long getLastPoolId();
|
||||||
|
|
||||||
String getAttachedVmName();
|
String getAttachedVmName();
|
||||||
|
|
||||||
VirtualMachine getAttachedVM();
|
VirtualMachine getAttachedVM();
|
||||||
|
|
||||||
void processEventOnly(ObjectInDataStoreStateMachine.Event event);
|
void processEventOnly(ObjectInDataStoreStateMachine.Event event);
|
||||||
|
|||||||
@ -20,16 +20,15 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
|
import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
|
||||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||||
import org.apache.cloudstack.storage.command.CommandResult;
|
import org.apache.cloudstack.storage.command.CommandResult;
|
||||||
|
|
||||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||||
import com.cloud.offering.DiskOffering;
|
import com.cloud.offering.DiskOffering;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
|
|
||||||
public interface VolumeService {
|
public interface VolumeService {
|
||||||
class VolumeApiResult extends CommandResult {
|
class VolumeApiResult extends CommandResult {
|
||||||
@ -54,38 +53,24 @@ public interface VolumeService {
|
|||||||
/**
|
/**
|
||||||
* Creates the volume based on the given criteria
|
* Creates the volume based on the given criteria
|
||||||
*
|
*
|
||||||
* @param cmd
|
|
||||||
*
|
|
||||||
* @return the volume object
|
* @return the volume object
|
||||||
*/
|
*/
|
||||||
AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore store);
|
AsyncCallFuture<VolumeApiResult> createVolumeAsync(VolumeInfo volume, DataStore store);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete volume
|
* Delete volume
|
||||||
*
|
|
||||||
* @param volumeId
|
|
||||||
* @return
|
|
||||||
* @throws ConcurrentOperationException
|
|
||||||
*/
|
*/
|
||||||
AsyncCallFuture<VolumeApiResult> expungeVolumeAsync(VolumeInfo volume);
|
AsyncCallFuture<VolumeApiResult> expungeVolumeAsync(VolumeInfo volume);
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
boolean cloneVolume(long volumeId, long baseVolId);
|
boolean cloneVolume(long volumeId, long baseVolId);
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(VolumeInfo volume, DataStore store, SnapshotInfo snapshot);
|
AsyncCallFuture<VolumeApiResult> createVolumeFromSnapshot(VolumeInfo volume, DataStore store, SnapshotInfo snapshot);
|
||||||
|
|
||||||
VolumeEntity getVolumeEntity(long volumeId);
|
VolumeEntity getVolumeEntity(long volumeId);
|
||||||
|
|
||||||
AsyncCallFuture<VolumeApiResult> createManagedStorageVolumeFromTemplateAsync(VolumeInfo volumeInfo, long destDataStoreId,
|
AsyncCallFuture<VolumeApiResult> createManagedStorageVolumeFromTemplateAsync(VolumeInfo volumeInfo, long destDataStoreId, TemplateInfo srcTemplateInfo, long destHostId);
|
||||||
TemplateInfo srcTemplateInfo, long destHostId);
|
|
||||||
|
|
||||||
AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId,
|
AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, TemplateInfo template);
|
||||||
TemplateInfo template);
|
|
||||||
|
|
||||||
AsyncCallFuture<VolumeApiResult> copyVolume(VolumeInfo srcVolume, DataStore destStore);
|
AsyncCallFuture<VolumeApiResult> copyVolume(VolumeInfo srcVolume, DataStore destStore);
|
||||||
|
|
||||||
@ -93,11 +78,11 @@ public interface VolumeService {
|
|||||||
|
|
||||||
AsyncCallFuture<CommandResult> migrateVolumes(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost);
|
AsyncCallFuture<CommandResult> migrateVolumes(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost);
|
||||||
|
|
||||||
boolean destroyVolume(long volumeId) throws ConcurrentOperationException;
|
void destroyVolume(long volumeId);
|
||||||
|
|
||||||
AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store);
|
AsyncCallFuture<VolumeApiResult> registerVolume(VolumeInfo volume, DataStore store);
|
||||||
|
|
||||||
public Pair<EndPoint,DataObject> registerVolumeForPostUpload(VolumeInfo volume, DataStore store);
|
public Pair<EndPoint, DataObject> registerVolumeForPostUpload(VolumeInfo volume, DataStore store);
|
||||||
|
|
||||||
AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume);
|
AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume);
|
||||||
|
|
||||||
@ -108,5 +93,4 @@ public interface VolumeService {
|
|||||||
SnapshotInfo takeSnapshot(VolumeInfo volume);
|
SnapshotInfo takeSnapshot(VolumeInfo volume);
|
||||||
|
|
||||||
VolumeInfo updateHypervisorSnapshotReserveForVolume(DiskOffering diskOffering, long volumeId, HypervisorType hyperType);
|
VolumeInfo updateHypervisorSnapshotReserveForVolume(DiskOffering diskOffering, long volumeId, HypervisorType hyperType);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -30,8 +30,6 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
|
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.ChapInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||||
@ -67,6 +65,7 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.agent.api.to.DataTO;
|
import com.cloud.agent.api.to.DataTO;
|
||||||
import com.cloud.agent.api.to.DiskTO;
|
import com.cloud.agent.api.to.DiskTO;
|
||||||
@ -225,8 +224,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
|
|
||||||
// Find a destination storage pool with the specified criteria
|
// Find a destination storage pool with the specified criteria
|
||||||
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
|
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
|
||||||
DiskProfile dskCh = new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(),
|
DiskProfile dskCh = new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(),
|
||||||
diskOffering.getTagsArray(), diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null);
|
diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null);
|
||||||
dskCh.setHyperType(dataDiskHyperType);
|
dskCh.setHyperType(dataDiskHyperType);
|
||||||
storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
|
storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
|
||||||
|
|
||||||
@ -249,17 +248,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
}
|
}
|
||||||
|
|
||||||
public VolumeVO allocateDuplicateVolumeVO(Volume oldVol, Long templateId) {
|
public VolumeVO allocateDuplicateVolumeVO(Volume oldVol, Long templateId) {
|
||||||
VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(),
|
VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), oldVol.getName(), oldVol.getDataCenterId(), oldVol.getDomainId(), oldVol.getAccountId(), oldVol.getDiskOfferingId(),
|
||||||
oldVol.getName(),
|
oldVol.getProvisioningType(), oldVol.getSize(), oldVol.getMinIops(), oldVol.getMaxIops(), oldVol.get_iScsiName());
|
||||||
oldVol.getDataCenterId(),
|
|
||||||
oldVol.getDomainId(),
|
|
||||||
oldVol.getAccountId(),
|
|
||||||
oldVol.getDiskOfferingId(),
|
|
||||||
oldVol.getProvisioningType(),
|
|
||||||
oldVol.getSize(),
|
|
||||||
oldVol.getMinIops(),
|
|
||||||
oldVol.getMaxIops(),
|
|
||||||
oldVol.get_iScsiName());
|
|
||||||
if (templateId != null) {
|
if (templateId != null) {
|
||||||
newVol.setTemplateId(templateId);
|
newVol.setTemplateId(templateId);
|
||||||
} else {
|
} else {
|
||||||
@ -398,8 +388,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
|
DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
|
||||||
SnapshotInfo snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
|
SnapshotInfo snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
|
||||||
|
|
||||||
|
if (snapInfo == null && dataStoreRole == DataStoreRole.Image) {
|
||||||
if(snapInfo == null && dataStoreRole == DataStoreRole.Image) {
|
|
||||||
// snapshot is not backed up to secondary, let's do that now.
|
// snapshot is not backed up to secondary, let's do that now.
|
||||||
snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
|
snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
|
||||||
|
|
||||||
@ -480,8 +469,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + dc.getId());
|
throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + dc.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), ss.getSize(), diskOffering.getTagsArray(),
|
return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), ss.getSize(), diskOffering.getTagsArray(), diskOffering.getUseLocalStorage(),
|
||||||
diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), Storage.ImageFormat.ISO != template.getFormat() ? template.getId() : null);
|
diskOffering.isRecreatable(), Storage.ImageFormat.ISO != template.getFormat() ? template.getId() : null);
|
||||||
} else {
|
} else {
|
||||||
return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(),
|
return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), diskOffering.getDiskSize(), diskOffering.getTagsArray(),
|
||||||
diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null);
|
diskOffering.getUseLocalStorage(), diskOffering.isRecreatable(), null);
|
||||||
@ -489,8 +478,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DB
|
@DB
|
||||||
public VolumeInfo copyVolumeFromSecToPrimary(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId,
|
public VolumeInfo copyVolumeFromSecToPrimary(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering,
|
||||||
ServiceOffering offering, DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) throws NoTransitionException {
|
DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) throws NoTransitionException {
|
||||||
|
|
||||||
final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
|
final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
|
||||||
DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
|
DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
|
||||||
@ -519,8 +508,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DB
|
@DB
|
||||||
public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering,
|
public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering, DiskOffering diskOffering,
|
||||||
DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) {
|
List<StoragePool> avoids, long size, HypervisorType hyperType) {
|
||||||
// update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
|
// update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
|
||||||
volume = volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
|
volume = volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
|
||||||
|
|
||||||
@ -656,12 +645,13 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected DiskProfile toDiskProfile(Volume vol, DiskOffering offering) {
|
protected DiskProfile toDiskProfile(Volume vol, DiskOffering offering) {
|
||||||
return new DiskProfile(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(),
|
return new DiskProfile(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(), offering.isRecreatable(),
|
||||||
offering.isRecreatable(), vol.getTemplateId());
|
vol.getTemplateId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner, Long deviceId) {
|
public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
|
||||||
|
Long deviceId) {
|
||||||
if (size == null) {
|
if (size == null) {
|
||||||
size = offering.getDiskSize();
|
size = offering.getDiskSize();
|
||||||
} else {
|
} else {
|
||||||
@ -671,17 +661,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
minIops = minIops != null ? minIops : offering.getMinIops();
|
minIops = minIops != null ? minIops : offering.getMinIops();
|
||||||
maxIops = maxIops != null ? maxIops : offering.getMaxIops();
|
maxIops = maxIops != null ? maxIops : offering.getMaxIops();
|
||||||
|
|
||||||
VolumeVO vol = new VolumeVO(type,
|
VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), offering.getProvisioningType(), size, minIops, maxIops, null);
|
||||||
name,
|
|
||||||
vm.getDataCenterId(),
|
|
||||||
owner.getDomainId(),
|
|
||||||
owner.getId(),
|
|
||||||
offering.getId(),
|
|
||||||
offering.getProvisioningType(),
|
|
||||||
size,
|
|
||||||
minIops,
|
|
||||||
maxIops,
|
|
||||||
null);
|
|
||||||
if (vm != null) {
|
if (vm != null) {
|
||||||
vol.setInstanceId(vm.getId());
|
vol.setInstanceId(vm.getId());
|
||||||
}
|
}
|
||||||
@ -719,11 +699,12 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm, Account owner) {
|
public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
|
||||||
|
Account owner) {
|
||||||
assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
|
assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
|
||||||
|
|
||||||
Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
|
Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
|
||||||
if (rootDisksize != null ) {
|
if (rootDisksize != null) {
|
||||||
rootDisksize = rootDisksize * 1024 * 1024 * 1024;
|
rootDisksize = rootDisksize * 1024 * 1024 * 1024;
|
||||||
if (rootDisksize > size) {
|
if (rootDisksize > size) {
|
||||||
s_logger.debug("Using root disk size of " + rootDisksize + " Bytes for volume " + name);
|
s_logger.debug("Using root disk size of " + rootDisksize + " Bytes for volume " + name);
|
||||||
@ -736,17 +717,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
minIops = minIops != null ? minIops : offering.getMinIops();
|
minIops = minIops != null ? minIops : offering.getMinIops();
|
||||||
maxIops = maxIops != null ? maxIops : offering.getMaxIops();
|
maxIops = maxIops != null ? maxIops : offering.getMaxIops();
|
||||||
|
|
||||||
VolumeVO vol = new VolumeVO(type,
|
VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), offering.getProvisioningType(), size, minIops, maxIops, null);
|
||||||
name,
|
|
||||||
vm.getDataCenterId(),
|
|
||||||
owner.getDomainId(),
|
|
||||||
owner.getId(),
|
|
||||||
offering.getId(),
|
|
||||||
offering.getProvisioningType(),
|
|
||||||
size,
|
|
||||||
minIops,
|
|
||||||
maxIops,
|
|
||||||
null);
|
|
||||||
vol.setFormat(getSupportedImageFormatForCluster(template.getHypervisorType()));
|
vol.setFormat(getSupportedImageFormatForCluster(template.getHypervisorType()));
|
||||||
if (vm != null) {
|
if (vm != null) {
|
||||||
vol.setInstanceId(vm.getId());
|
vol.setInstanceId(vm.getId());
|
||||||
@ -767,7 +738,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
vol.setDisplayVolume(userVm.isDisplayVm());
|
vol.setDisplayVolume(userVm.isDisplayVm());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vol = _volsDao.persist(vol);
|
vol = _volsDao.persist(vol);
|
||||||
|
|
||||||
// Create event and update resource count for volumes if vm is a user vm
|
// Create event and update resource count for volumes if vm is a user vm
|
||||||
@ -817,16 +787,15 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private VolumeInfo copyVolume(StoragePool rootDiskPool, VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate rootDiskTmplt, DataCenter dcVO, Pod pod,
|
private VolumeInfo copyVolume(StoragePool rootDiskPool, VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate rootDiskTmplt, DataCenter dcVO, Pod pod, DiskOffering diskVO,
|
||||||
DiskOffering diskVO, ServiceOffering svo, HypervisorType rootDiskHyperType) throws NoTransitionException {
|
ServiceOffering svo, HypervisorType rootDiskHyperType) throws NoTransitionException {
|
||||||
|
|
||||||
if (!isSupportedImageFormatForCluster(volume, rootDiskHyperType)) {
|
if (!isSupportedImageFormatForCluster(volume, rootDiskHyperType)) {
|
||||||
throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " + volume.getFormat().getFileExtension()
|
throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " + volume.getFormat().getFileExtension() + " is not compatible with the vm hypervisor type");
|
||||||
+ " is not compatible with the vm hypervisor type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VolumeInfo volumeOnPrimary = copyVolumeFromSecToPrimary(volume, vm, rootDiskTmplt, dcVO, pod, rootDiskPool.getClusterId(), svo, diskVO, new ArrayList<StoragePool>(),
|
VolumeInfo volumeOnPrimary = copyVolumeFromSecToPrimary(volume, vm, rootDiskTmplt, dcVO, pod, rootDiskPool.getClusterId(), svo, diskVO, new ArrayList<StoragePool>(), volume.getSize(),
|
||||||
volume.getSize(), rootDiskHyperType);
|
rootDiskHyperType);
|
||||||
|
|
||||||
return volumeOnPrimary;
|
return volumeOnPrimary;
|
||||||
}
|
}
|
||||||
@ -871,8 +840,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
long vmTemplateId = vm.getTemplateId();
|
long vmTemplateId = vm.getTemplateId();
|
||||||
if (volTemplateId != null && volTemplateId.longValue() != vmTemplateId) {
|
if (volTemplateId != null && volTemplateId.longValue() != vmTemplateId) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("switchVolume: Old Volume's templateId: " + volTemplateId + " does not match the VM's templateId: " + vmTemplateId
|
s_logger.debug("switchVolume: Old Volume's templateId: " + volTemplateId + " does not match the VM's templateId: " + vmTemplateId + ", updating templateId in the new Volume");
|
||||||
+ ", updating templateId in the new Volume");
|
|
||||||
}
|
}
|
||||||
templateIdToUse = vmTemplateId;
|
templateIdToUse = vmTemplateId;
|
||||||
}
|
}
|
||||||
@ -1108,8 +1076,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
for (VolumeVO vol : vols) {
|
for (VolumeVO vol : vols) {
|
||||||
VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
|
VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
|
||||||
DataTO volTO = volumeInfo.getTO();
|
DataTO volTO = volumeInfo.getTO();
|
||||||
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(),
|
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
|
||||||
vm.getServiceOfferingId(), vol.getDiskOfferingId());
|
|
||||||
DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
|
DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
|
||||||
|
|
||||||
disk.setDetails(getDetails(volumeInfo, dataStore));
|
disk.setDetails(getDetails(volumeInfo, dataStore));
|
||||||
@ -1217,7 +1184,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
} else {
|
} else {
|
||||||
storageMigrationEnabled = StorageMigrationEnabled.value();
|
storageMigrationEnabled = StorageMigrationEnabled.value();
|
||||||
}
|
}
|
||||||
if(storageMigrationEnabled){
|
if (storageMigrationEnabled) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Shared volume " + vol + " will be migrated on storage pool " + assignedPool + " assigned by deploymentPlanner");
|
s_logger.debug("Shared volume " + vol + " will be migrated on storage pool " + assignedPool + " assigned by deploymentPlanner");
|
||||||
}
|
}
|
||||||
@ -1237,8 +1204,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (vol.getPoolId() == null) {
|
if (vol.getPoolId() == null) {
|
||||||
throw new StorageUnavailableException("Volume has no pool associate and also no storage pool assigned in DeployDestination, Unable to create " + vol,
|
throw new StorageUnavailableException("Volume has no pool associate and also no storage pool assigned in DeployDestination, Unable to create " + vol, Volume.class, vol.getId());
|
||||||
Volume.class, vol.getId());
|
|
||||||
}
|
}
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("No need to recreate the volume: " + vol + ", since it already has a pool assigned: " + vol.getPoolId() + ", adding disk to VM");
|
s_logger.debug("No need to recreate the volume: " + vol + ", since it already has a pool assigned: " + vol.getPoolId() + ", adding disk to VM");
|
||||||
@ -1319,8 +1285,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
long hostId = vm.getVirtualMachine().getHostId();
|
long hostId = vm.getVirtualMachine().getHostId();
|
||||||
|
|
||||||
future = volService.createManagedStorageVolumeFromTemplateAsync(volume, destPool.getId(), templ, hostId);
|
future = volService.createManagedStorageVolumeFromTemplateAsync(volume, destPool.getId(), templ, hostId);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
future = volService.createVolumeFromTemplateAsync(volume, destPool.getId(), templ);
|
future = volService.createVolumeFromTemplateAsync(volume, destPool.getId(), templ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1398,7 +1363,6 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
|
|
||||||
if (oldHostId != hostId) {
|
if (oldHostId != hostId) {
|
||||||
Host oldHost = _hostDao.findById(oldHostId);
|
Host oldHost = _hostDao.findById(oldHostId);
|
||||||
Host host = _hostDao.findById(hostId);
|
|
||||||
DataStore storagePool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
|
DataStore storagePool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
|
||||||
|
|
||||||
storageMgr.removeStoragePoolFromCluster(oldHostId, vol.get_iScsiName(), pool);
|
storageMgr.removeStoragePoolFromCluster(oldHostId, vol.get_iScsiName(), pool);
|
||||||
@ -1417,8 +1381,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
|
|
||||||
VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
|
VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
|
||||||
DataTO volTO = volumeInfo.getTO();
|
DataTO volTO = volumeInfo.getTO();
|
||||||
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(),
|
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
|
||||||
vm.getServiceOfferingId(), vol.getDiskOfferingId());
|
|
||||||
DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
|
DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
|
||||||
|
|
||||||
disk.setDetails(getDetails(volumeInfo, dataStore));
|
disk.setDetails(getDetails(volumeInfo, dataStore));
|
||||||
@ -1434,13 +1397,12 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
cloneType = UserVmCloneType.full;
|
cloneType = UserVmCloneType.full;
|
||||||
}
|
}
|
||||||
UserVmCloneSettingVO cloneSettingVO = _vmCloneSettingDao.findByVmId(vm.getId());
|
UserVmCloneSettingVO cloneSettingVO = _vmCloneSettingDao.findByVmId(vm.getId());
|
||||||
if (cloneSettingVO != null){
|
if (cloneSettingVO != null) {
|
||||||
if (! cloneSettingVO.getCloneType().equals(cloneType.toString())){
|
if (!cloneSettingVO.getCloneType().equals(cloneType.toString())) {
|
||||||
cloneSettingVO.setCloneType(cloneType.toString());
|
cloneSettingVO.setCloneType(cloneType.toString());
|
||||||
_vmCloneSettingDao.update(cloneSettingVO.getVmId(), cloneSettingVO);
|
_vmCloneSettingDao.update(cloneSettingVO.getVmId(), cloneSettingVO);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(vm.getId(), cloneType.toString());
|
UserVmCloneSettingVO vmCloneSettingVO = new UserVmCloneSettingVO(vm.getId(), cloneType.toString());
|
||||||
_vmCloneSettingDao.persist(vmCloneSettingVO);
|
_vmCloneSettingDao.persist(vmCloneSettingVO);
|
||||||
}
|
}
|
||||||
@ -1465,8 +1427,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final ConfigKey<Long> MaxVolumeSize = new ConfigKey<Long>(Long.class, "storage.max.volume.size", "Storage", "2000", "The maximum size for a volume (in GB).",
|
public static final ConfigKey<Long> MaxVolumeSize = new ConfigKey<Long>(Long.class, "storage.max.volume.size", "Storage", "2000", "The maximum size for a volume (in GB).", true);
|
||||||
true);
|
|
||||||
|
|
||||||
public static final ConfigKey<Boolean> RecreatableSystemVmEnabled = new ConfigKey<Boolean>(Boolean.class, "recreate.systemvm.enabled", "Advanced", "false",
|
public static final ConfigKey<Boolean> RecreatableSystemVmEnabled = new ConfigKey<Boolean>(Boolean.class, "recreate.systemvm.enabled", "Advanced", "false",
|
||||||
"If true, will recreate system vm root disk whenever starting system vm", true);
|
"If true, will recreate system vm root disk whenever starting system vm", true);
|
||||||
@ -1478,8 +1439,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
"Enable/disable storage migration across primary storage", true);
|
"Enable/disable storage migration across primary storage", true);
|
||||||
|
|
||||||
static final ConfigKey<Boolean> VolumeUrlCheck = new ConfigKey<Boolean>("Advanced", Boolean.class, "volume.url.check", "true",
|
static final ConfigKey<Boolean> VolumeUrlCheck = new ConfigKey<Boolean>("Advanced", Boolean.class, "volume.url.check", "true",
|
||||||
"Check the url for a volume before downloading it from the management server. Set to flase when you managment has no internet access.",
|
"Check the url for a volume before downloading it from the management server. Set to flase when you managment has no internet access.", true);
|
||||||
true);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConfigKey<?>[] getConfigKeys() {
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
@ -1507,9 +1467,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
_volsDao.remove(volume.getId());
|
_volsDao.remove(volume.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(volume.getState().equals(Volume.State.Attaching)) {
|
if (volume.getState().equals(Volume.State.Attaching)) {
|
||||||
s_logger.warn("Vol: " + volume.getName() + " failed to attach to VM: " + _userVmDao.findById(vmId).getHostName() +
|
s_logger.warn("Vol: " + volume.getName() + " failed to attach to VM: " + _userVmDao.findById(vmId).getHostName() + " on last mgt server stop, changing state back to Ready");
|
||||||
" on last mgt server stop, changing state back to Ready");
|
|
||||||
volume.setState(Volume.State.Ready);
|
volume.setState(Volume.State.Ready);
|
||||||
_volsDao.update(volumeId, volume);
|
_volsDao.update(volumeId, volume);
|
||||||
}
|
}
|
||||||
@ -1549,8 +1508,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
@Override
|
@Override
|
||||||
public void cleanupStorageJobs() {
|
public void cleanupStorageJobs() {
|
||||||
//clean up failure jobs related to volume
|
//clean up failure jobs related to volume
|
||||||
List<AsyncJobVO> jobs = _jobMgr.findFailureAsyncJobs(VmWorkAttachVolume.class.getName(),
|
List<AsyncJobVO> jobs = _jobMgr.findFailureAsyncJobs(VmWorkAttachVolume.class.getName(), VmWorkMigrateVolume.class.getName(), VmWorkTakeVolumeSnapshot.class.getName());
|
||||||
VmWorkMigrateVolume.class.getName(), VmWorkTakeVolumeSnapshot.class.getName());
|
|
||||||
|
|
||||||
for (AsyncJobVO job : jobs) {
|
for (AsyncJobVO job : jobs) {
|
||||||
try {
|
try {
|
||||||
@ -1592,8 +1550,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
}
|
}
|
||||||
// FIXME - All this is boiler plate code and should be done as part of state transition. This shouldn't be part of orchestrator.
|
// FIXME - All this is boiler plate code and should be done as part of state transition. This shouldn't be part of orchestrator.
|
||||||
// publish usage event for the volume
|
// publish usage event for the volume
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(),
|
||||||
Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
|
volume.getUuid(), volume.isDisplayVolume());
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
|
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplay());
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
|
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.isDisplay(), new Long(volume.getSize()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -1619,13 +1577,16 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
VolumeVO vol = _volsDao.findById(volumeId);
|
VolumeVO vol = _volsDao.findById(volumeId);
|
||||||
boolean needUpdate = false;
|
boolean needUpdate = false;
|
||||||
// Volume path is not getting updated in the DB, need to find reason and fix the issue.
|
// Volume path is not getting updated in the DB, need to find reason and fix the issue.
|
||||||
if (vol.getPath() == null)
|
if (vol.getPath() == null) {
|
||||||
return;
|
return;
|
||||||
if (!vol.getPath().equalsIgnoreCase(path))
|
}
|
||||||
|
if (!vol.getPath().equalsIgnoreCase(path)) {
|
||||||
needUpdate = true;
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (chainInfo != null && (vol.getChainInfo() == null || !chainInfo.equalsIgnoreCase(vol.getChainInfo())))
|
if (chainInfo != null && (vol.getChainInfo() == null || !chainInfo.equalsIgnoreCase(vol.getChainInfo()))) {
|
||||||
needUpdate = true;
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (needUpdate) {
|
if (needUpdate) {
|
||||||
s_logger.info("Update volume disk chain info. vol: " + vol.getId() + ", " + vol.getPath() + " -> " + path + ", " + vol.getChainInfo() + " -> " + chainInfo);
|
s_logger.info("Update volume disk chain info. vol: " + vol.getId() + ", " + vol.getPath() + " -> " + path + ", " + vol.getChainInfo() + " -> " + chainInfo);
|
||||||
|
|||||||
@ -85,7 +85,6 @@ import com.cloud.configuration.Resource.ResourceType;
|
|||||||
import com.cloud.dc.dao.ClusterDao;
|
import com.cloud.dc.dao.ClusterDao;
|
||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
import com.cloud.event.UsageEventUtils;
|
import com.cloud.event.UsageEventUtils;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
|
||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.host.Host;
|
import com.cloud.host.Host;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
@ -110,6 +109,7 @@ import com.cloud.storage.Volume.State;
|
|||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||||
import com.cloud.storage.dao.VolumeDao;
|
import com.cloud.storage.dao.VolumeDao;
|
||||||
|
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||||
import com.cloud.storage.snapshot.SnapshotManager;
|
import com.cloud.storage.snapshot.SnapshotManager;
|
||||||
import com.cloud.storage.template.TemplateProp;
|
import com.cloud.storage.template.TemplateProp;
|
||||||
import com.cloud.user.AccountManager;
|
import com.cloud.user.AccountManager;
|
||||||
@ -119,8 +119,6 @@ import com.cloud.utils.Pair;
|
|||||||
import com.cloud.utils.db.DB;
|
import com.cloud.utils.db.DB;
|
||||||
import com.cloud.utils.db.GlobalLock;
|
import com.cloud.utils.db.GlobalLock;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.cloud.storage.dao.VolumeDetailsDao;
|
|
||||||
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class VolumeServiceImpl implements VolumeService {
|
public class VolumeServiceImpl implements VolumeService {
|
||||||
@ -420,8 +418,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
if (!supportsStorageSystemSnapshots) {
|
if (!supportsStorageSystemSnapshots) {
|
||||||
_snapshotStoreDao.remove(snapStoreVo.getId());
|
_snapshotStoreDao.remove(snapStoreVo.getId());
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_snapshotStoreDao.remove(snapStoreVo.getId());
|
_snapshotStoreDao.remove(snapStoreVo.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -453,8 +450,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
private final TemplateInfo _templateInfo;
|
private final TemplateInfo _templateInfo;
|
||||||
private final AsyncCallFuture<VolumeApiResult> _future;
|
private final AsyncCallFuture<VolumeApiResult> _future;
|
||||||
|
|
||||||
public ManagedCreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volumeInfo,
|
public ManagedCreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volumeInfo, PrimaryDataStore primaryDatastore, TemplateInfo templateInfo,
|
||||||
PrimaryDataStore primaryDatastore, TemplateInfo templateInfo, AsyncCallFuture<VolumeApiResult> future) {
|
AsyncCallFuture<VolumeApiResult> future) {
|
||||||
super(callback);
|
super(callback);
|
||||||
|
|
||||||
_volumeInfo = volumeInfo;
|
_volumeInfo = volumeInfo;
|
||||||
@ -488,8 +485,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
final DataObject destObj;
|
final DataObject destObj;
|
||||||
long templatePoolId;
|
long templatePoolId;
|
||||||
|
|
||||||
public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateInfo srcTemplate,
|
public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateInfo srcTemplate, AsyncCallFuture<VolumeApiResult> future,
|
||||||
AsyncCallFuture<VolumeApiResult> future, DataObject destObj, long templatePoolId) {
|
DataObject destObj, long templatePoolId) {
|
||||||
super(callback);
|
super(callback);
|
||||||
this.volume = volume;
|
this.volume = volume;
|
||||||
this.dataStore = datastore;
|
this.dataStore = datastore;
|
||||||
@ -549,13 +546,11 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
throw new CloudRuntimeException("Failed to find template " + template.getUniqueName() + " in storage pool " + dataStore.getId());
|
throw new CloudRuntimeException("Failed to find template " + template.getUniqueName() + " in storage pool " + dataStore.getId());
|
||||||
} else {
|
} else {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Found template " + template.getUniqueName() + " in storage pool " + dataStore.getId() + " with VMTemplateStoragePool id: " +
|
s_logger.debug("Found template " + template.getUniqueName() + " in storage pool " + dataStore.getId() + " with VMTemplateStoragePool id: " + templatePoolRef.getId());
|
||||||
templatePoolRef.getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long templatePoolRefId = templatePoolRef.getId();
|
long templatePoolRefId = templatePoolRef.getId();
|
||||||
CreateBaseImageContext<CreateCmdResult> context =
|
CreateBaseImageContext<CreateCmdResult> context = new CreateBaseImageContext<CreateCmdResult>(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId);
|
||||||
new CreateBaseImageContext<CreateCmdResult>(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId);
|
|
||||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||||
caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)).setContext(context);
|
caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)).setContext(context);
|
||||||
|
|
||||||
@ -571,8 +566,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
|
templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
|
||||||
if (templatePoolRef != null && templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
|
if (templatePoolRef != null && templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
|
||||||
s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() +
|
s_logger.info(
|
||||||
" is already copied to primary storage, skip copying");
|
"Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() + " is already copied to primary storage, skip copying");
|
||||||
createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future);
|
createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -606,8 +601,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Void managedCopyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback,
|
protected Void managedCopyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, ManagedCreateBaseImageContext<VolumeApiResult> context) {
|
||||||
ManagedCreateBaseImageContext<VolumeApiResult> context) {
|
|
||||||
CopyCommandResult result = callback.getResult();
|
CopyCommandResult result = callback.getResult();
|
||||||
VolumeInfo volumeInfo = context.getVolumeInfo();
|
VolumeInfo volumeInfo = context.getVolumeInfo();
|
||||||
VolumeApiResult res = new VolumeApiResult(volumeInfo);
|
VolumeApiResult res = new VolumeApiResult(volumeInfo);
|
||||||
@ -626,8 +620,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
volDao.update(volume.getId(), volume);
|
volDao.update(volume.getId(), volume);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
volumeInfo.processEvent(Event.DestroyRequested);
|
volumeInfo.processEvent(Event.DestroyRequested);
|
||||||
|
|
||||||
res.setResult(result.getResult());
|
res.setResult(result.getResult());
|
||||||
@ -652,8 +645,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
((TemplateObject)templateOnPrimaryStoreObj).setInstallPath(result.getPath());
|
((TemplateObject)templateOnPrimaryStoreObj).setInstallPath(result.getPath());
|
||||||
templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
|
templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
|
templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,8 +665,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
|
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
|
templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
|
templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,8 +699,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
private final DataObject templateOnStore;
|
private final DataObject templateOnStore;
|
||||||
private final SnapshotInfo snapshot;
|
private final SnapshotInfo snapshot;
|
||||||
|
|
||||||
public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, DataObject vo, DataStore primaryStore, DataObject templateOnStore,
|
public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, DataObject vo, DataStore primaryStore, DataObject templateOnStore, AsyncCallFuture<VolumeApiResult> future,
|
||||||
AsyncCallFuture<VolumeApiResult> future, SnapshotInfo snapshot) {
|
SnapshotInfo snapshot) {
|
||||||
super(callback);
|
super(callback);
|
||||||
this.vo = vo;
|
this.vo = vo;
|
||||||
this.future = future;
|
this.future = future;
|
||||||
@ -727,8 +718,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
DataObject volumeOnPrimaryStorage = pd.create(volume);
|
DataObject volumeOnPrimaryStorage = pd.create(volume);
|
||||||
volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested);
|
volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested);
|
||||||
|
|
||||||
CreateVolumeFromBaseImageContext<VolumeApiResult> context =
|
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null);
|
||||||
new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null);
|
|
||||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||||
caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null));
|
caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null));
|
||||||
caller.setContext(context);
|
caller.setContext(context);
|
||||||
@ -738,8 +728,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DB
|
@DB
|
||||||
protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback,
|
protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
|
||||||
CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
|
|
||||||
DataObject vo = context.vo;
|
DataObject vo = context.vo;
|
||||||
DataObject tmplOnPrimary = context.templateOnStore;
|
DataObject tmplOnPrimary = context.templateOnStore;
|
||||||
CopyCommandResult result = callback.getResult();
|
CopyCommandResult result = callback.getResult();
|
||||||
@ -771,7 +760,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
|
|
||||||
_tmpltPoolDao.update(templatePoolRefId, templatePoolRef);
|
_tmpltPoolDao.update(templatePoolRefId, templatePoolRef);
|
||||||
}
|
}
|
||||||
}finally {
|
} finally {
|
||||||
_tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
|
_tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -838,8 +827,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
if (result.isFailed()) {
|
if (result.isFailed()) {
|
||||||
String errMesg = result.getResult();
|
String errMesg = result.getResult();
|
||||||
|
|
||||||
throw new CloudRuntimeException("Unable to create template " + templateOnPrimary.getId() +
|
throw new CloudRuntimeException("Unable to create template " + templateOnPrimary.getId() + " on primary storage " + destPrimaryDataStore.getId() + ":" + errMesg);
|
||||||
" on primary storage " + destPrimaryDataStore.getId() + ":" + errMesg);
|
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
s_logger.debug("Failed to create template volume on storage", e);
|
s_logger.debug("Failed to create template volume on storage", e);
|
||||||
@ -847,8 +835,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
templateOnPrimary.processEvent(Event.OperationFailed);
|
templateOnPrimary.processEvent(Event.OperationFailed);
|
||||||
|
|
||||||
throw new CloudRuntimeException(e.getMessage());
|
throw new CloudRuntimeException(e.getMessage());
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
_tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
|
_tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -866,9 +853,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
* @param destPrimaryDataStore The managed primary storage
|
* @param destPrimaryDataStore The managed primary storage
|
||||||
* @param destHost The host that we will use for the copy
|
* @param destHost The host that we will use for the copy
|
||||||
*/
|
*/
|
||||||
private void copyTemplateToManagedTemplateVolume(TemplateInfo srcTemplateInfo, TemplateInfo templateOnPrimary, VMTemplateStoragePoolVO templatePoolRef,
|
private void copyTemplateToManagedTemplateVolume(TemplateInfo srcTemplateInfo, TemplateInfo templateOnPrimary, VMTemplateStoragePoolVO templatePoolRef, PrimaryDataStore destPrimaryDataStore,
|
||||||
PrimaryDataStore destPrimaryDataStore, Host destHost)
|
Host destHost) {
|
||||||
{
|
|
||||||
AsyncCallFuture<VolumeApiResult> copyTemplateFuture = new AsyncCallFuture<>();
|
AsyncCallFuture<VolumeApiResult> copyTemplateFuture = new AsyncCallFuture<>();
|
||||||
int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
|
int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
|
||||||
long templatePoolRefId = templatePoolRef.getId();
|
long templatePoolRefId = templatePoolRef.getId();
|
||||||
@ -890,10 +876,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// copy the template from sec storage to the created volume
|
// copy the template from sec storage to the created volume
|
||||||
CreateBaseImageContext<CreateCmdResult> copyContext = new CreateBaseImageContext<>(
|
CreateBaseImageContext<CreateCmdResult> copyContext = new CreateBaseImageContext<>(null, null, destPrimaryDataStore, srcTemplateInfo, copyTemplateFuture, templateOnPrimary,
|
||||||
null, null, destPrimaryDataStore, srcTemplateInfo,
|
templatePoolRefId);
|
||||||
copyTemplateFuture, templateOnPrimary, templatePoolRefId
|
|
||||||
);
|
|
||||||
|
|
||||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> copyCaller = AsyncCallbackDispatcher.create(this);
|
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> copyCaller = AsyncCallbackDispatcher.create(this);
|
||||||
copyCaller.setCallback(copyCaller.getTarget().copyManagedTemplateCallback(null, null)).setContext(copyContext);
|
copyCaller.setCallback(copyCaller.getTarget().copyManagedTemplateCallback(null, null)).setContext(copyContext);
|
||||||
@ -930,8 +914,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
motionSrv.copyAsync(srcTemplateInfo, templateOnPrimary, destHost, copyCaller);
|
motionSrv.copyAsync(srcTemplateInfo, templateOnPrimary, destHost, copyCaller);
|
||||||
|
|
||||||
result = copyTemplateFuture.get();
|
result = copyTemplateFuture.get();
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
revokeAccess(templateOnPrimary, destHost, destPrimaryDataStore);
|
revokeAccess(templateOnPrimary, destHost, destPrimaryDataStore);
|
||||||
|
|
||||||
if (HypervisorType.VMware.equals(destHost.getHypervisorType())) {
|
if (HypervisorType.VMware.equals(destHost.getHypervisorType())) {
|
||||||
@ -946,21 +929,18 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result.isFailed()) {
|
if (result.isFailed()) {
|
||||||
throw new CloudRuntimeException("Failed to copy template " + templateOnPrimary.getId() +
|
throw new CloudRuntimeException("Failed to copy template " + templateOnPrimary.getId() + " to primary storage " + destPrimaryDataStore.getId() + ": " + result.getResult());
|
||||||
" to primary storage " + destPrimaryDataStore.getId() + ": " + result.getResult());
|
|
||||||
// XXX: I find it is useful to destroy the volume on primary storage instead of another thread trying the copy again because I've seen
|
// XXX: I find it is useful to destroy the volume on primary storage instead of another thread trying the copy again because I've seen
|
||||||
// something weird happens to the volume (XenServer creates an SR, but the VDI copy can fail).
|
// something weird happens to the volume (XenServer creates an SR, but the VDI copy can fail).
|
||||||
// For now, I just retry the copy.
|
// For now, I just retry the copy.
|
||||||
}
|
}
|
||||||
}
|
} catch (Throwable e) {
|
||||||
catch (Throwable e) {
|
|
||||||
s_logger.debug("Failed to create a template on primary storage", e);
|
s_logger.debug("Failed to create a template on primary storage", e);
|
||||||
|
|
||||||
templateOnPrimary.processEvent(Event.OperationFailed);
|
templateOnPrimary.processEvent(Event.OperationFailed);
|
||||||
|
|
||||||
throw new CloudRuntimeException(e.getMessage());
|
throw new CloudRuntimeException(e.getMessage());
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
_tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
|
_tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -983,8 +963,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
String msg = "Unable to get an answer to the modify targets command";
|
String msg = "Unable to get an answer to the modify targets command";
|
||||||
|
|
||||||
s_logger.warn(msg);
|
s_logger.warn(msg);
|
||||||
}
|
} else if (!answer.getResult()) {
|
||||||
else if (!answer.getResult()) {
|
|
||||||
String msg = "Unable to modify target on the following host: " + hostId;
|
String msg = "Unable to modify target on the following host: " + hostId;
|
||||||
|
|
||||||
s_logger.warn(msg);
|
s_logger.warn(msg);
|
||||||
@ -999,8 +978,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
* @param destPrimaryDataStore Primary storage of the volume
|
* @param destPrimaryDataStore Primary storage of the volume
|
||||||
* @param future For async
|
* @param future For async
|
||||||
*/
|
*/
|
||||||
private void createManagedVolumeCloneTemplateAsync(VolumeInfo volumeInfo, TemplateInfo templateOnPrimary, PrimaryDataStore destPrimaryDataStore,
|
private void createManagedVolumeCloneTemplateAsync(VolumeInfo volumeInfo, TemplateInfo templateOnPrimary, PrimaryDataStore destPrimaryDataStore, AsyncCallFuture<VolumeApiResult> future) {
|
||||||
AsyncCallFuture<VolumeApiResult> future) {
|
|
||||||
VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
|
VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
|
||||||
|
|
||||||
if (templatePoolRef == null) {
|
if (templatePoolRef == null) {
|
||||||
@ -1015,8 +993,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
try {
|
try {
|
||||||
volumeInfo.processEvent(Event.CreateOnlyRequested);
|
volumeInfo.processEvent(Event.CreateOnlyRequested);
|
||||||
|
|
||||||
CreateVolumeFromBaseImageContext<VolumeApiResult> context =
|
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<>(null, volumeInfo, destPrimaryDataStore, templateOnPrimary, future, null);
|
||||||
new CreateVolumeFromBaseImageContext<>(null, volumeInfo, destPrimaryDataStore, templateOnPrimary, future, null);
|
|
||||||
|
|
||||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||||
|
|
||||||
@ -1033,8 +1010,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createManagedVolumeCopyTemplateAsync(VolumeInfo volumeInfo, PrimaryDataStore primaryDataStore, TemplateInfo srcTemplateInfo, Host destHost,
|
private void createManagedVolumeCopyTemplateAsync(VolumeInfo volumeInfo, PrimaryDataStore primaryDataStore, TemplateInfo srcTemplateInfo, Host destHost, AsyncCallFuture<VolumeApiResult> future) {
|
||||||
AsyncCallFuture<VolumeApiResult> future) {
|
|
||||||
try {
|
try {
|
||||||
// Create a volume on managed storage.
|
// Create a volume on managed storage.
|
||||||
|
|
||||||
@ -1050,8 +1026,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
// Refresh the volume info from the DB.
|
// Refresh the volume info from the DB.
|
||||||
volumeInfo = volFactory.getVolume(volumeInfo.getId(), primaryDataStore);
|
volumeInfo = volFactory.getVolume(volumeInfo.getId(), primaryDataStore);
|
||||||
|
|
||||||
ManagedCreateBaseImageContext<CreateCmdResult> context = new ManagedCreateBaseImageContext<CreateCmdResult>(null, volumeInfo,
|
ManagedCreateBaseImageContext<CreateCmdResult> context = new ManagedCreateBaseImageContext<CreateCmdResult>(null, volumeInfo, primaryDataStore, srcTemplateInfo, future);
|
||||||
primaryDataStore, srcTemplateInfo, future);
|
|
||||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||||
|
|
||||||
caller.setCallback(caller.getTarget().managedCopyBaseImageCallback(null, null)).setContext(context);
|
caller.setCallback(caller.getTarget().managedCopyBaseImageCallback(null, null)).setContext(context);
|
||||||
@ -1081,8 +1056,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
motionSrv.copyAsync(srcTemplateInfo, destTemplateInfo, destHost, caller);
|
motionSrv.copyAsync(srcTemplateInfo, destTemplateInfo, destHost, caller);
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
revokeAccess(volumeInfo, destHost, primaryDataStore);
|
revokeAccess(volumeInfo, destHost, primaryDataStore);
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@ -1098,8 +1072,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
if (expungeVolumeResult.isFailed()) {
|
if (expungeVolumeResult.isFailed()) {
|
||||||
errMsg += " : Failed to expunge a volume that was created";
|
errMsg += " : Failed to expunge a volume that was created";
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch (Exception ex) {
|
|
||||||
errMsg += " : " + ex.getMessage();
|
errMsg += " : " + ex.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,8 +1085,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncCallFuture<VolumeApiResult> createManagedStorageVolumeFromTemplateAsync(VolumeInfo volumeInfo, long destDataStoreId,
|
public AsyncCallFuture<VolumeApiResult> createManagedStorageVolumeFromTemplateAsync(VolumeInfo volumeInfo, long destDataStoreId, TemplateInfo srcTemplateInfo, long destHostId) {
|
||||||
TemplateInfo srcTemplateInfo, long destHostId) {
|
|
||||||
PrimaryDataStore destPrimaryDataStore = dataStoreMgr.getPrimaryDataStore(destDataStoreId);
|
PrimaryDataStore destPrimaryDataStore = dataStoreMgr.getPrimaryDataStore(destDataStoreId);
|
||||||
Host destHost = _hostDao.findById(destHostId);
|
Host destHost = _hostDao.findById(destHostId);
|
||||||
|
|
||||||
@ -1121,9 +1093,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
throw new CloudRuntimeException("Destination host should not be null.");
|
throw new CloudRuntimeException("Destination host should not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean storageCanCloneVolume = new Boolean(
|
Boolean storageCanCloneVolume = new Boolean(destPrimaryDataStore.getDriver().getCapabilities().get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString()));
|
||||||
destPrimaryDataStore.getDriver().getCapabilities().get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString())
|
|
||||||
);
|
|
||||||
|
|
||||||
boolean computeSupportsVolumeClone = computeSupportsVolumeClone(destHost.getDataCenterId(), destHost.getHypervisorType());
|
boolean computeSupportsVolumeClone = computeSupportsVolumeClone(destHost.getDataCenterId(), destHost.getHypervisorType());
|
||||||
|
|
||||||
@ -1146,10 +1116,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
|
VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
|
||||||
|
|
||||||
if (templatePoolRef == null) {
|
if (templatePoolRef == null) {
|
||||||
throw new CloudRuntimeException("Failed to find template " +
|
throw new CloudRuntimeException("Failed to find template " + srcTemplateInfo.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
|
||||||
srcTemplateInfo.getUniqueName() + " in storage pool " +
|
|
||||||
destPrimaryDataStore.getId()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (templatePoolRef.getDownloadState() == Status.NOT_DOWNLOADED) {
|
if (templatePoolRef.getDownloadState() == Status.NOT_DOWNLOADED) {
|
||||||
@ -1190,8 +1157,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
|
|
||||||
Collections.shuffle(clusters, new Random(System.nanoTime()));
|
Collections.shuffle(clusters, new Random(System.nanoTime()));
|
||||||
|
|
||||||
clusters:
|
clusters: for (Cluster cluster : clusters) {
|
||||||
for (Cluster cluster : clusters) {
|
|
||||||
if (cluster.getAllocationState() == AllocationState.Enabled) {
|
if (cluster.getAllocationState() == AllocationState.Enabled) {
|
||||||
List<HostVO> hosts = _hostDao.findByClusterId(cluster.getId());
|
List<HostVO> hosts = _hostDao.findByClusterId(cluster.getId());
|
||||||
|
|
||||||
@ -1203,13 +1169,11 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
if (computeClusterMustSupportResign) {
|
if (computeClusterMustSupportResign) {
|
||||||
if (clusterDao.getSupportsResigning(cluster.getId())) {
|
if (clusterDao.getSupportsResigning(cluster.getId())) {
|
||||||
return host;
|
return host;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// no other host in the cluster in question should be able to satisfy our requirements here, so move on to the next cluster
|
// no other host in the cluster in question should be able to satisfy our requirements here, so move on to the next cluster
|
||||||
continue clusters;
|
continue clusters;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1237,17 +1201,15 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@DB
|
@DB
|
||||||
public boolean destroyVolume(long volumeId) throws ConcurrentOperationException {
|
@Override
|
||||||
|
public void destroyVolume(long volumeId) {
|
||||||
// mark volume entry in volumes table as destroy state
|
// mark volume entry in volumes table as destroy state
|
||||||
VolumeInfo vol = volFactory.getVolume(volumeId);
|
VolumeInfo vol = volFactory.getVolume(volumeId);
|
||||||
vol.stateTransit(Volume.Event.DestroyRequested);
|
vol.stateTransit(Volume.Event.DestroyRequested);
|
||||||
snapshotMgr.deletePoliciesForVolume(volumeId);
|
snapshotMgr.deletePoliciesForVolume(volumeId);
|
||||||
|
|
||||||
vol.stateTransit(Volume.Event.OperationSucceeded);
|
vol.stateTransit(Volume.Event.OperationSucceeded);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1259,8 +1221,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
volumeOnStore.processEvent(Event.CreateOnlyRequested);
|
volumeOnStore.processEvent(Event.CreateOnlyRequested);
|
||||||
_volumeDetailsDao.addDetail(volume.getId(), SNAPSHOT_ID, Long.toString(snapshot.getId()), false);
|
_volumeDetailsDao.addDetail(volume.getId(), SNAPSHOT_ID, Long.toString(snapshot.getId()), false);
|
||||||
|
|
||||||
CreateVolumeFromBaseImageContext<VolumeApiResult> context =
|
CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volume, store, volumeOnStore, future, snapshot);
|
||||||
new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volume, store, volumeOnStore, future, snapshot);
|
|
||||||
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||||
caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)).setContext(context);
|
caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)).setContext(context);
|
||||||
motionSrv.copyAsync(snapshot, volumeOnStore, caller);
|
motionSrv.copyAsync(snapshot, volumeOnStore, caller);
|
||||||
@ -1274,8 +1235,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback,
|
protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
|
||||||
CreateVolumeFromBaseImageContext<VolumeApiResult> context) {
|
|
||||||
CopyCommandResult result = callback.getResult();
|
CopyCommandResult result = callback.getResult();
|
||||||
VolumeInfo volume = (VolumeInfo)context.templateOnStore;
|
VolumeInfo volume = (VolumeInfo)context.templateOnStore;
|
||||||
SnapshotInfo snapshot = context.snapshot;
|
SnapshotInfo snapshot = context.snapshot;
|
||||||
@ -1332,8 +1292,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
final VolumeInfo destVolume;
|
final VolumeInfo destVolume;
|
||||||
final AsyncCallFuture<VolumeApiResult> future;
|
final AsyncCallFuture<VolumeApiResult> future;
|
||||||
|
|
||||||
public CopyVolumeContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<VolumeApiResult> future, VolumeInfo srcVolume, VolumeInfo destVolume,
|
public CopyVolumeContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<VolumeApiResult> future, VolumeInfo srcVolume, VolumeInfo destVolume, DataStore destStore) {
|
||||||
DataStore destStore) {
|
|
||||||
super(callback);
|
super(callback);
|
||||||
this.srcVolume = srcVolume;
|
this.srcVolume = srcVolume;
|
||||||
this.destVolume = destVolume;
|
this.destVolume = destVolume;
|
||||||
@ -1370,8 +1329,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Void
|
protected Void copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
|
||||||
copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
|
|
||||||
VolumeInfo srcVolume = context.srcVolume;
|
VolumeInfo srcVolume = context.srcVolume;
|
||||||
VolumeInfo destVolume = context.destVolume;
|
VolumeInfo destVolume = context.destVolume;
|
||||||
CopyCommandResult result = callback.getResult();
|
CopyCommandResult result = callback.getResult();
|
||||||
@ -1424,8 +1382,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Void
|
protected Void copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
|
||||||
copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, CopyVolumeContext<VolumeApiResult> context) {
|
|
||||||
VolumeInfo srcVolume = context.srcVolume;
|
VolumeInfo srcVolume = context.srcVolume;
|
||||||
VolumeInfo destVolume = context.destVolume;
|
VolumeInfo destVolume = context.destVolume;
|
||||||
CopyCommandResult result = callback.getResult();
|
CopyCommandResult result = callback.getResult();
|
||||||
@ -1542,8 +1499,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
/**
|
/**
|
||||||
* @param callback
|
* @param callback
|
||||||
*/
|
*/
|
||||||
public MigrateVolumeContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<VolumeApiResult> future, VolumeInfo srcVolume, VolumeInfo destVolume,
|
public MigrateVolumeContext(AsyncCompletionCallback<T> callback, AsyncCallFuture<VolumeApiResult> future, VolumeInfo srcVolume, VolumeInfo destVolume, DataStore destStore) {
|
||||||
DataStore destStore) {
|
|
||||||
super(callback);
|
super(callback);
|
||||||
this.srcVolume = srcVolume;
|
this.srcVolume = srcVolume;
|
||||||
this.destVolume = destVolume;
|
this.destVolume = destVolume;
|
||||||
@ -1654,8 +1610,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Void
|
protected Void migrateVmWithVolumesCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, MigrateVmWithVolumesContext<CommandResult> context) {
|
||||||
migrateVmWithVolumesCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, MigrateVmWithVolumesContext<CommandResult> context) {
|
|
||||||
Map<VolumeInfo, DataStore> volumeToPool = context.volumeToPool;
|
Map<VolumeInfo, DataStore> volumeToPool = context.volumeToPool;
|
||||||
CopyCommandResult result = callback.getResult();
|
CopyCommandResult result = callback.getResult();
|
||||||
AsyncCallFuture<CommandResult> future = context.future;
|
AsyncCallFuture<CommandResult> future = context.future;
|
||||||
@ -1715,7 +1670,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<EndPoint,DataObject> registerVolumeForPostUpload(VolumeInfo volume, DataStore store) {
|
public Pair<EndPoint, DataObject> registerVolumeForPostUpload(VolumeInfo volume, DataStore store) {
|
||||||
|
|
||||||
EndPoint ep = _epSelector.select(store);
|
EndPoint ep = _epSelector.select(store);
|
||||||
if (ep == null) {
|
if (ep == null) {
|
||||||
@ -1724,7 +1679,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
throw new CloudRuntimeException(errorMessage);
|
throw new CloudRuntimeException(errorMessage);
|
||||||
}
|
}
|
||||||
DataObject volumeOnStore = store.create(volume);
|
DataObject volumeOnStore = store.create(volume);
|
||||||
return new Pair<>(ep,volumeOnStore);
|
return new Pair<>(ep, volumeOnStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Void registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
|
protected Void registerVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CreateCmdResult> callback, CreateVolumeContext<VolumeApiResult> context) {
|
||||||
@ -1751,21 +1706,20 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
if (volStore != null) {
|
if (volStore != null) {
|
||||||
physicalSize = volStore.getPhysicalSize();
|
physicalSize = volStore.getPhysicalSize();
|
||||||
} else {
|
} else {
|
||||||
s_logger.warn("No entry found in volume_store_ref for volume id: " + vo.getId() + " and image store id: " + ds.getId() +
|
s_logger.warn("No entry found in volume_store_ref for volume id: " + vo.getId() + " and image store id: " + ds.getId() + " at the end of uploading volume!");
|
||||||
" at the end of uploading volume!");
|
|
||||||
}
|
}
|
||||||
Scope dsScope = ds.getScope();
|
Scope dsScope = ds.getScope();
|
||||||
if (dsScope.getScopeType() == ScopeType.ZONE) {
|
if (dsScope.getScopeType() == ScopeType.ZONE) {
|
||||||
if (dsScope.getScopeId() != null) {
|
if (dsScope.getScopeId() != null) {
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), dsScope.getScopeId(), vo.getId(), vo.getName(), null,
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), dsScope.getScopeId(), vo.getId(), vo.getName(), null, null, physicalSize, vo.getSize(),
|
||||||
null, physicalSize, vo.getSize(), Volume.class.getName(), vo.getUuid());
|
Volume.class.getName(), vo.getUuid());
|
||||||
} else {
|
} else {
|
||||||
s_logger.warn("Zone scope image store " + ds.getId() + " has a null scope id");
|
s_logger.warn("Zone scope image store " + ds.getId() + " has a null scope id");
|
||||||
}
|
}
|
||||||
} else if (dsScope.getScopeType() == ScopeType.REGION) {
|
} else if (dsScope.getScopeType() == ScopeType.REGION) {
|
||||||
// publish usage event for region-wide image store using a -1 zoneId for 4.2, need to revisit post-4.2
|
// publish usage event for region-wide image store using a -1 zoneId for 4.2, need to revisit post-4.2
|
||||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), -1, vo.getId(), vo.getName(), null, null, physicalSize,
|
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), -1, vo.getId(), vo.getName(), null, null, physicalSize, vo.getSize(),
|
||||||
vo.getSize(), Volume.class.getName(), vo.getUuid());
|
Volume.class.getName(), vo.getUuid());
|
||||||
|
|
||||||
_resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize());
|
_resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize());
|
||||||
}
|
}
|
||||||
@ -1829,8 +1783,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
if (ep != null) {
|
if (ep != null) {
|
||||||
VolumeVO volume = volDao.findById(volumeId);
|
VolumeVO volume = volDao.findById(volumeId);
|
||||||
PrimaryDataStore primaryDataStore = this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
|
PrimaryDataStore primaryDataStore = this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
|
||||||
ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(volume.getPath(), new StorageFilerTO(primaryDataStore),
|
ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(volume.getPath(), new StorageFilerTO(primaryDataStore), volume.getSize(), newSize, true, instanceName,
|
||||||
volume.getSize(), newSize, true, instanceName, primaryDataStore.isManaged(), volume.get_iScsiName());
|
primaryDataStore.isManaged(), volume.get_iScsiName());
|
||||||
|
|
||||||
answer = ep.sendMessage(resizeCmd);
|
answer = ep.sendMessage(resizeCmd);
|
||||||
} else {
|
} else {
|
||||||
@ -1903,8 +1857,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
for (VolumeDataStoreVO volumeStore : dbVolumes) {
|
for (VolumeDataStoreVO volumeStore : dbVolumes) {
|
||||||
VolumeVO volume = volDao.findById(volumeStore.getVolumeId());
|
VolumeVO volume = volDao.findById(volumeStore.getVolumeId());
|
||||||
if (volume == null) {
|
if (volume == null) {
|
||||||
s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId +
|
s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId
|
||||||
", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed");
|
+ ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed");
|
||||||
volumeStore.setDestroyed(true);
|
volumeStore.setDestroyed(true);
|
||||||
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
|
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
|
||||||
continue;
|
continue;
|
||||||
@ -1929,7 +1883,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
|
VolumeObject volObj = (VolumeObject)volFactory.getVolume(volume.getId());
|
||||||
volObj.processEvent(Event.OperationFailed);
|
volObj.processEvent(Event.OperationFailed);
|
||||||
} else if (volumeStore.getDownloadUrl() == null) {
|
} else if (volumeStore.getDownloadUrl() == null) {
|
||||||
msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + " is corrupted, please check in image store: " + volumeStore.getDataStoreId();
|
msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + " is corrupted, please check in image store: "
|
||||||
|
+ volumeStore.getDataStoreId();
|
||||||
s_logger.warn(msg);
|
s_logger.warn(msg);
|
||||||
} else {
|
} else {
|
||||||
s_logger.info("Removing volume_store_ref entry for corrupted volume " + volume.getName());
|
s_logger.info("Removing volume_store_ref entry for corrupted volume " + volume.getName());
|
||||||
@ -1959,8 +1914,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
|
|
||||||
if (volInfo.getSize() > 0) {
|
if (volInfo.getSize() > 0) {
|
||||||
try {
|
try {
|
||||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
|
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), com.cloud.configuration.Resource.ResourceType.secondary_storage,
|
||||||
com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize());
|
volInfo.getSize() - volInfo.getPhysicalSize());
|
||||||
} catch (ResourceAllocationException e) {
|
} catch (ResourceAllocationException e) {
|
||||||
s_logger.warn(e.getMessage());
|
s_logger.warn(e.getMessage());
|
||||||
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage());
|
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage());
|
||||||
@ -2021,7 +1976,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete volumes which are not present on DB.
|
// Delete volumes which are not present on DB.
|
||||||
for (Map.Entry<Long,TemplateProp> entry : volumeInfos.entrySet()) {
|
for (Map.Entry<Long, TemplateProp> entry : volumeInfos.entrySet()) {
|
||||||
Long uniqueName = entry.getKey();
|
Long uniqueName = entry.getKey();
|
||||||
TemplateProp tInfo = entry.getValue();
|
TemplateProp tInfo = entry.getValue();
|
||||||
|
|
||||||
@ -2091,7 +2046,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
s_logger.error("Take snapshot: " + volume.getId() + " failed", cre);
|
s_logger.error("Take snapshot: " + volume.getId() + " failed", cre);
|
||||||
throw cre;
|
throw cre;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if(s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("unknown exception while taking snapshot for volume " + volume.getId() + " was caught", e);
|
s_logger.debug("unknown exception while taking snapshot for volume " + volume.getId() + " was caught", e);
|
||||||
}
|
}
|
||||||
throw new CloudRuntimeException("Failed to take snapshot", e);
|
throw new CloudRuntimeException("Failed to take snapshot", e);
|
||||||
|
|||||||
@ -38,12 +38,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
|
||||||
@ -64,11 +59,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
|
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
|
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
|
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
|
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.SnapshotInfo;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
|
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
||||||
@ -82,8 +79,8 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
|||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
import org.apache.cloudstack.framework.config.Configurable;
|
import org.apache.cloudstack.framework.config.Configurable;
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.storage.command.DettachCommand;
|
|
||||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||||
|
import org.apache.cloudstack.storage.command.DettachCommand;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
@ -98,6 +95,9 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
|||||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||||
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
|
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
|
||||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
@ -176,7 +176,6 @@ import com.cloud.user.dao.UserDao;
|
|||||||
import com.cloud.utils.DateUtil;
|
import com.cloud.utils.DateUtil;
|
||||||
import com.cloud.utils.NumbersUtil;
|
import com.cloud.utils.NumbersUtil;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.StringUtils;
|
|
||||||
import com.cloud.utils.UriUtils;
|
import com.cloud.utils.UriUtils;
|
||||||
import com.cloud.utils.component.ComponentContext;
|
import com.cloud.utils.component.ComponentContext;
|
||||||
import com.cloud.utils.component.ManagerBase;
|
import com.cloud.utils.component.ManagerBase;
|
||||||
@ -467,7 +466,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
public boolean configure(String name, Map<String, Object> params) {
|
||||||
|
|
||||||
Map<String, String> configs = _configDao.getConfiguration("management-server", params);
|
Map<String, String> configs = _configDao.getConfiguration("management-server", params);
|
||||||
|
|
||||||
@ -476,8 +475,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
_agentMgr.registerForHostEvents(new StoragePoolMonitor(this, _storagePoolDao, _dataStoreProviderMgr), true, false, true);
|
_agentMgr.registerForHostEvents(new StoragePoolMonitor(this, _storagePoolDao, _dataStoreProviderMgr), true, false, true);
|
||||||
|
|
||||||
s_logger.info("Storage cleanup enabled: " + StorageCleanupEnabled.value() + ", interval: " + StorageCleanupInterval.value() + ", delay: " + StorageCleanupDelay.value() +
|
s_logger.info("Storage cleanup enabled: " + StorageCleanupEnabled.value() + ", interval: " + StorageCleanupInterval.value() + ", delay: " + StorageCleanupDelay.value()
|
||||||
", template cleanup enabled: " + TemplateCleanupEnabled.value());
|
+ ", template cleanup enabled: " + TemplateCleanupEnabled.value());
|
||||||
|
|
||||||
String cleanupInterval = configs.get("extract.url.cleanup.interval");
|
String cleanupInterval = configs.get("extract.url.cleanup.interval");
|
||||||
_downloadUrlCleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200);
|
_downloadUrlCleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200);
|
||||||
@ -525,7 +524,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getStoragePoolTags(long poolId) {
|
public String getStoragePoolTags(long poolId) {
|
||||||
return StringUtils.listToCsvTags(_storagePoolDao.searchForStoragePoolTags(poolId));
|
return com.cloud.utils.StringUtils.listToCsvTags(_storagePoolDao.searchForStoragePoolTags(poolId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -586,8 +585,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
if (pool == null) {
|
if (pool == null) {
|
||||||
//the path can be different, but if they have the same uuid, assume they are the same storage
|
//the path can be different, but if they have the same uuid, assume they are the same storage
|
||||||
pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), hostAddress, null,
|
pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), hostAddress, null, pInfo.getUuid());
|
||||||
pInfo.getUuid());
|
|
||||||
if (pool != null) {
|
if (pool != null) {
|
||||||
s_logger.debug("Found a storage pool: " + pInfo.getUuid() + ", but with different hostpath " + pInfo.getHostPath() + ", still treat it as the same pool");
|
s_logger.debug("Found a storage pool: " + pInfo.getUuid() + ", but with different hostpath " + pInfo.getHostPath() + ", still treat it as the same pool");
|
||||||
}
|
}
|
||||||
@ -628,8 +626,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException,
|
public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException {
|
||||||
ResourceUnavailableException {
|
|
||||||
String providerName = cmd.getStorageProviderName();
|
String providerName = cmd.getStorageProviderName();
|
||||||
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
|
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
|
||||||
|
|
||||||
@ -675,7 +672,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
} else {
|
} else {
|
||||||
throw new InvalidParameterValueException("Missing parameter hypervisor. Hypervisor type is required to create zone wide primary storage.");
|
throw new InvalidParameterValueException("Missing parameter hypervisor. Hypervisor type is required to create zone wide primary storage.");
|
||||||
}
|
}
|
||||||
if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Hyperv && hypervisorType != HypervisorType.LXC && hypervisorType != HypervisorType.Any) {
|
if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.VMware && hypervisorType != HypervisorType.Hyperv && hypervisorType != HypervisorType.LXC
|
||||||
|
&& hypervisorType != HypervisorType.Any) {
|
||||||
throw new InvalidParameterValueException("zone wide storage pool is not supported for hypervisor type " + hypervisor);
|
throw new InvalidParameterValueException("zone wide storage pool is not supported for hypervisor type " + hypervisor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -716,7 +714,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
lifeCycle.attachZone(store, zoneScope, hypervisorType);
|
lifeCycle.attachZone(store, zoneScope, hypervisorType);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.debug("Failed to add data store: "+e.getMessage(), e);
|
s_logger.debug("Failed to add data store: " + e.getMessage(), e);
|
||||||
try {
|
try {
|
||||||
// clean up the db, just absorb the exception thrown in deletion with error logged, so that user can get error for adding data store
|
// clean up the db, just absorb the exception thrown in deletion with error logged, so that user can get error for adding data store
|
||||||
// not deleting data store.
|
// not deleting data store.
|
||||||
@ -726,7 +724,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
s_logger.debug("Failed to clean up storage pool: " + ex.getMessage());
|
s_logger.debug("Failed to clean up storage pool: " + ex.getMessage());
|
||||||
}
|
}
|
||||||
throw new CloudRuntimeException("Failed to add data store: "+e.getMessage(), e);
|
throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
|
return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
|
||||||
@ -752,8 +750,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
@ActionEvent(eventType = EventTypes.EVENT_DISABLE_PRIMARY_STORAGE, eventDescription = "disable storage pool")
|
@ActionEvent(eventType = EventTypes.EVENT_DISABLE_PRIMARY_STORAGE, eventDescription = "disable storage pool")
|
||||||
private void disablePrimaryStoragePool(StoragePoolVO primaryStorage) {
|
private void disablePrimaryStoragePool(StoragePoolVO primaryStorage) {
|
||||||
if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up)) {
|
if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up)) {
|
||||||
throw new InvalidParameterValueException("Primary storage with id " + primaryStorage.getId() + " cannot be disabled. Storage pool state : " +
|
throw new InvalidParameterValueException("Primary storage with id " + primaryStorage.getId() + " cannot be disabled. Storage pool state : " + primaryStorage.getStatus().toString());
|
||||||
primaryStorage.getStatus().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
|
DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
|
||||||
@ -765,8 +762,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
@ActionEvent(eventType = EventTypes.EVENT_ENABLE_PRIMARY_STORAGE, eventDescription = "enable storage pool")
|
@ActionEvent(eventType = EventTypes.EVENT_ENABLE_PRIMARY_STORAGE, eventDescription = "enable storage pool")
|
||||||
private void enablePrimaryStoragePool(StoragePoolVO primaryStorage) {
|
private void enablePrimaryStoragePool(StoragePoolVO primaryStorage) {
|
||||||
if (!primaryStorage.getStatus().equals(StoragePoolStatus.Disabled)) {
|
if (!primaryStorage.getStatus().equals(StoragePoolStatus.Disabled)) {
|
||||||
throw new InvalidParameterValueException("Primary storage with id " + primaryStorage.getId() + " cannot be enabled. Storage pool state : " +
|
throw new InvalidParameterValueException("Primary storage with id " + primaryStorage.getId() + " cannot be enabled. Storage pool state : " + primaryStorage.getStatus().toString());
|
||||||
primaryStorage.getStatus().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
|
DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
|
||||||
@ -863,8 +859,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
final Answer answer = _agentMgr.easySend(hostId, cmd);
|
final Answer answer = _agentMgr.easySend(hostId, cmd);
|
||||||
|
|
||||||
if (answer == null || !answer.getResult()) {
|
if (answer == null || !answer.getResult()) {
|
||||||
String errMsg = "Error interacting with host (related to DeleteStoragePoolCommand)" +
|
String errMsg = "Error interacting with host (related to DeleteStoragePoolCommand)" + (StringUtils.isNotBlank(answer.getDetails()) ? ": " + answer.getDetails() : "");
|
||||||
(StringUtils.isNotBlank(answer.getDetails()) ? ": " + answer.getDetails() : "");
|
|
||||||
|
|
||||||
s_logger.error(errMsg);
|
s_logger.error(errMsg);
|
||||||
|
|
||||||
@ -965,8 +960,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
// All this is for the inaccuracy of floats for big number multiplication.
|
// All this is for the inaccuracy of floats for big number multiplication.
|
||||||
BigDecimal overProvFactor = getStorageOverProvisioningFactor(storagePool.getId());
|
BigDecimal overProvFactor = getStorageOverProvisioningFactor(storagePool.getId());
|
||||||
totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(storagePool.getCapacityBytes())).longValue();
|
totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(storagePool.getCapacityBytes())).longValue();
|
||||||
s_logger.debug("Found storage pool " + storagePool.getName() + " of type " + storagePool.getPoolType().toString() + " with overprovisioning factor "
|
s_logger.debug("Found storage pool " + storagePool.getName() + " of type " + storagePool.getPoolType().toString() + " with overprovisioning factor " + overProvFactor.toString());
|
||||||
+ overProvFactor.toString());
|
|
||||||
s_logger.debug("Total over provisioned capacity calculated is " + overProvFactor + " * " + storagePool.getCapacityBytes());
|
s_logger.debug("Total over provisioned capacity calculated is " + overProvFactor + " * " + storagePool.getCapacityBytes());
|
||||||
} else {
|
} else {
|
||||||
s_logger.debug("Found storage pool " + storagePool.getName() + " of type " + storagePool.getPoolType().toString());
|
s_logger.debug("Found storage pool " + storagePool.getName() + " of type " + storagePool.getPoolType().toString());
|
||||||
@ -992,18 +986,17 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
if (storagePool.getScope() == ScopeType.HOST) {
|
if (storagePool.getScope() == ScopeType.HOST) {
|
||||||
List<StoragePoolHostVO> stoargePoolHostVO = _storagePoolHostDao.listByPoolId(storagePool.getId());
|
List<StoragePoolHostVO> stoargePoolHostVO = _storagePoolHostDao.listByPoolId(storagePool.getId());
|
||||||
|
|
||||||
if(stoargePoolHostVO != null && !stoargePoolHostVO.isEmpty()){
|
if (stoargePoolHostVO != null && !stoargePoolHostVO.isEmpty()) {
|
||||||
HostVO host = _hostDao.findById(stoargePoolHostVO.get(0).getHostId());
|
HostVO host = _hostDao.findById(stoargePoolHostVO.get(0).getHostId());
|
||||||
|
|
||||||
if(host != null){
|
if (host != null) {
|
||||||
capacityState = (host.getResourceState() == ResourceState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
|
capacityState = (host.getResourceState() == ResourceState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (capacities.size() == 0) {
|
if (capacities.size() == 0) {
|
||||||
CapacityVO capacity =
|
CapacityVO capacity = new CapacityVO(storagePool.getId(), storagePool.getDataCenterId(), storagePool.getPodId(), storagePool.getClusterId(), allocated, totalOverProvCapacity,
|
||||||
new CapacityVO(storagePool.getId(), storagePool.getDataCenterId(), storagePool.getPodId(), storagePool.getClusterId(), allocated, totalOverProvCapacity,
|
|
||||||
capacityType);
|
capacityType);
|
||||||
capacity.setCapacityState(capacityState);
|
capacity.setCapacityState(capacityState);
|
||||||
_capacityDao.persist(capacity);
|
_capacityDao.persist(capacity);
|
||||||
@ -1016,8 +1009,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
_capacityDao.update(capacity.getId(), capacity);
|
_capacityDao.update(capacity.getId(), capacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s_logger.debug("Successfully set Capacity - " + totalOverProvCapacity + " for capacity type - " + capacityType + " , DataCenterId - " +
|
s_logger.debug("Successfully set Capacity - " + totalOverProvCapacity + " for capacity type - " + capacityType + " , DataCenterId - " + storagePool.getDataCenterId() + ", HostOrPoolId - "
|
||||||
storagePool.getDataCenterId() + ", HostOrPoolId - " + storagePool.getId() + ", PodId " + storagePool.getPodId());
|
+ storagePool.getId() + ", PodId " + storagePool.getPodId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1045,8 +1038,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
hostIds.removeAll(hostIdsToAvoid);
|
hostIds.removeAll(hostIdsToAvoid);
|
||||||
}
|
}
|
||||||
if (hostIds == null || hostIds.isEmpty()) {
|
if (hostIds == null || hostIds.isEmpty()) {
|
||||||
throw new StorageUnavailableException("Unable to send command to the pool " + pool.getId() + " due to there is no enabled hosts up in this cluster",
|
throw new StorageUnavailableException("Unable to send command to the pool " + pool.getId() + " due to there is no enabled hosts up in this cluster", pool.getId());
|
||||||
pool.getId());
|
|
||||||
}
|
}
|
||||||
for (Long hostId : hostIds) {
|
for (Long hostId : hostIds) {
|
||||||
try {
|
try {
|
||||||
@ -1088,20 +1080,19 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool);
|
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool);
|
||||||
s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " +
|
s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName());
|
||||||
pool.getName());
|
|
||||||
for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
|
for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
|
||||||
if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
|
if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
|
||||||
s_logger.debug("Storage pool garbage collector is skipping template with ID: " + templatePoolVO.getTemplateId() +
|
s_logger.debug("Storage pool garbage collector is skipping template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId()
|
||||||
" on pool " + templatePoolVO.getPoolId() + " because it is not completely downloaded.");
|
+ " because it is not completely downloaded.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!templatePoolVO.getMarkedForGC()) {
|
if (!templatePoolVO.getMarkedForGC()) {
|
||||||
templatePoolVO.setMarkedForGC(true);
|
templatePoolVO.setMarkedForGC(true);
|
||||||
_vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO);
|
_vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO);
|
||||||
s_logger.debug("Storage pool garbage collector has marked template with ID: " + templatePoolVO.getTemplateId() +
|
s_logger.debug("Storage pool garbage collector has marked template with ID: " + templatePoolVO.getTemplateId() + " on pool " + templatePoolVO.getPoolId()
|
||||||
" on pool " + templatePoolVO.getPoolId() + " for garbage collection.");
|
+ " for garbage collection.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,7 +1106,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
//destroy snapshots in destroying state in snapshot_store_ref
|
//destroy snapshots in destroying state in snapshot_store_ref
|
||||||
List<SnapshotDataStoreVO> ssSnapshots = _snapshotStoreDao.listByState(ObjectInDataStoreStateMachine.State.Destroying);
|
List<SnapshotDataStoreVO> ssSnapshots = _snapshotStoreDao.listByState(ObjectInDataStoreStateMachine.State.Destroying);
|
||||||
for(SnapshotDataStoreVO ssSnapshotVO : ssSnapshots){
|
for (SnapshotDataStoreVO ssSnapshotVO : ssSnapshots) {
|
||||||
try {
|
try {
|
||||||
_snapshotService.deleteSnapshot(snapshotFactory.getSnapshot(ssSnapshotVO.getSnapshotId(), DataStoreRole.Image));
|
_snapshotService.deleteSnapshot(snapshotFactory.getSnapshot(ssSnapshotVO.getSnapshotId(), DataStoreRole.Image));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -1125,7 +1116,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
cleanupSecondaryStorage(recurring);
|
cleanupSecondaryStorage(recurring);
|
||||||
|
|
||||||
List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed(new Date(System.currentTimeMillis() - ((long) StorageCleanupDelay.value() << 10)));
|
List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed(new Date(System.currentTimeMillis() - ((long)StorageCleanupDelay.value() << 10)));
|
||||||
for (VolumeVO vol : vols) {
|
for (VolumeVO vol : vols) {
|
||||||
try {
|
try {
|
||||||
// If this fails, just log a warning. It's ideal if we clean up the host-side clustered file
|
// If this fails, just log a warning. It's ideal if we clean up the host-side clustered file
|
||||||
@ -1179,10 +1170,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
Host host = _hostDao.findById(ep.getId());
|
Host host = _hostDao.findById(ep.getId());
|
||||||
if (host != null && host.getManagementServerId() != null) {
|
if (host != null && host.getManagementServerId() != null) {
|
||||||
if (_serverId == host.getManagementServerId().longValue()) {
|
if (_serverId == host.getManagementServerId().longValue()) {
|
||||||
if (!volService.destroyVolume(volume.getId())) {
|
volService.destroyVolume(volume.getId());
|
||||||
s_logger.warn("Unable to destroy uploaded volume " + volume.getUuid());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// decrement volume resource count
|
// decrement volume resource count
|
||||||
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
|
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
|
||||||
// expunge volume from secondary if volume is on image store
|
// expunge volume from secondary if volume is on image store
|
||||||
@ -1286,8 +1274,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
if (cluster.getHypervisorType() == HypervisorType.KVM) {
|
if (cluster.getHypervisorType() == HypervisorType.KVM) {
|
||||||
volService.revokeAccess(volumeInfo, host, volumeInfo.getDataStore());
|
volService.revokeAccess(volumeInfo, host, volumeInfo.getDataStore());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
|
DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
|
||||||
DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
|
DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
|
||||||
|
|
||||||
@ -1367,8 +1354,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
try {
|
try {
|
||||||
long storeId = store.getId();
|
long storeId = store.getId();
|
||||||
List<TemplateDataStoreVO> destroyedTemplateStoreVOs = _templateStoreDao.listDestroyed(storeId);
|
List<TemplateDataStoreVO> destroyedTemplateStoreVOs = _templateStoreDao.listDestroyed(storeId);
|
||||||
s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateStoreVOs.size() +
|
s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateStoreVOs.size() + " templates to cleanup on template_store_ref for store: " + store.getName());
|
||||||
" templates to cleanup on template_store_ref for store: " + store.getName());
|
|
||||||
for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) {
|
for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Deleting template store DB entry: " + destroyedTemplateStoreVO);
|
s_logger.debug("Deleting template store DB entry: " + destroyedTemplateStoreVO);
|
||||||
@ -1384,8 +1370,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
for (DataStore store : imageStores) {
|
for (DataStore store : imageStores) {
|
||||||
try {
|
try {
|
||||||
List<SnapshotDataStoreVO> destroyedSnapshotStoreVOs = _snapshotStoreDao.listDestroyed(store.getId());
|
List<SnapshotDataStoreVO> destroyedSnapshotStoreVOs = _snapshotStoreDao.listDestroyed(store.getId());
|
||||||
s_logger.debug("Secondary storage garbage collector found " + destroyedSnapshotStoreVOs.size() +
|
s_logger.debug("Secondary storage garbage collector found " + destroyedSnapshotStoreVOs.size() + " snapshots to cleanup on snapshot_store_ref for store: " + store.getName());
|
||||||
" snapshots to cleanup on snapshot_store_ref for store: " + store.getName());
|
|
||||||
for (SnapshotDataStoreVO destroyedSnapshotStoreVO : destroyedSnapshotStoreVOs) {
|
for (SnapshotDataStoreVO destroyedSnapshotStoreVO : destroyedSnapshotStoreVOs) {
|
||||||
// check if this snapshot has child
|
// check if this snapshot has child
|
||||||
SnapshotInfo snap = snapshotFactory.getSnapshot(destroyedSnapshotStoreVO.getSnapshotId(), store);
|
SnapshotInfo snap = snapshotFactory.getSnapshot(destroyedSnapshotStoreVO.getSnapshotId(), store);
|
||||||
@ -1416,8 +1401,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
for (DataStore store : imageStores) {
|
for (DataStore store : imageStores) {
|
||||||
try {
|
try {
|
||||||
List<VolumeDataStoreVO> destroyedStoreVOs = _volumeStoreDao.listDestroyed(store.getId());
|
List<VolumeDataStoreVO> destroyedStoreVOs = _volumeStoreDao.listDestroyed(store.getId());
|
||||||
s_logger.debug("Secondary storage garbage collector found " + destroyedStoreVOs.size() + " volumes to cleanup on volume_store_ref for store: " +
|
s_logger.debug("Secondary storage garbage collector found " + destroyedStoreVOs.size() + " volumes to cleanup on volume_store_ref for store: " + store.getName());
|
||||||
store.getName());
|
|
||||||
for (VolumeDataStoreVO destroyedStoreVO : destroyedStoreVOs) {
|
for (VolumeDataStoreVO destroyedStoreVO : destroyedStoreVOs) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Deleting volume store DB entry: " + destroyedStoreVO);
|
s_logger.debug("Deleting volume store DB entry: " + destroyedStoreVO);
|
||||||
@ -1459,8 +1443,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up) && !primaryStorage.getStatus().equals(StoragePoolStatus.ErrorInMaintenance)) {
|
if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up) && !primaryStorage.getStatus().equals(StoragePoolStatus.ErrorInMaintenance)) {
|
||||||
throw new InvalidParameterValueException("Primary storage with id " + primaryStorageId + " is not ready for migration, as the status is:" +
|
throw new InvalidParameterValueException("Primary storage with id " + primaryStorageId + " is not ready for migration, as the status is:" + primaryStorage.getStatus().toString());
|
||||||
primaryStorage.getStatus().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
|
DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
|
||||||
@ -1486,8 +1469,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (primaryStorage.getStatus().equals(StoragePoolStatus.Up) || primaryStorage.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)) {
|
if (primaryStorage.getStatus().equals(StoragePoolStatus.Up) || primaryStorage.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)) {
|
||||||
throw new StorageUnavailableException("Primary storage with id " + primaryStorageId + " is not ready to complete migration, as the status is:" +
|
throw new StorageUnavailableException("Primary storage with id " + primaryStorageId + " is not ready to complete migration, as the status is:" + primaryStorage.getStatus().toString(),
|
||||||
primaryStorage.getStatus().toString(), primaryStorageId);
|
primaryStorageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
|
DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
|
||||||
@ -1498,7 +1481,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
|
return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected class StorageGarbageCollector extends ManagedContextRunnable {
|
protected class StorageGarbageCollector extends ManagedContextRunnable {
|
||||||
|
|
||||||
public StorageGarbageCollector() {
|
public StorageGarbageCollector() {
|
||||||
@ -1533,9 +1515,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
for (Long poolId : poolIds) {
|
for (Long poolId : poolIds) {
|
||||||
StoragePoolVO pool = _storagePoolDao.findById(poolId);
|
StoragePoolVO pool = _storagePoolDao.findById(poolId);
|
||||||
// check if pool is in an inconsistent state
|
// check if pool is in an inconsistent state
|
||||||
if (pool != null &&
|
if (pool != null && (pool.getStatus().equals(StoragePoolStatus.ErrorInMaintenance) || pool.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)
|
||||||
(pool.getStatus().equals(StoragePoolStatus.ErrorInMaintenance) || pool.getStatus().equals(StoragePoolStatus.PrepareForMaintenance) || pool.getStatus()
|
|| pool.getStatus().equals(StoragePoolStatus.CancelMaintenance))) {
|
||||||
.equals(StoragePoolStatus.CancelMaintenance))) {
|
|
||||||
_storagePoolWorkDao.removePendingJobsOnMsRestart(vo.getMsid(), poolId);
|
_storagePoolWorkDao.removePendingJobsOnMsRestart(vo.getMsid(), poolId);
|
||||||
pool.setStatus(StoragePoolStatus.ErrorInMaintenance);
|
pool.setStatus(StoragePoolStatus.ErrorInMaintenance);
|
||||||
_storagePoolDao.update(poolId, pool);
|
_storagePoolDao.update(poolId, pool);
|
||||||
@ -1740,13 +1721,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
if (stats != null) {
|
if (stats != null) {
|
||||||
double usedPercentage = ((double)stats.getByteUsed() / (double)totalSize);
|
double usedPercentage = ((double)stats.getByteUsed() / (double)totalSize);
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Checking pool " + pool.getId() + " for storage, totalSize: " + pool.getCapacityBytes() + ", usedBytes: " + stats.getByteUsed() +
|
s_logger.debug("Checking pool " + pool.getId() + " for storage, totalSize: " + pool.getCapacityBytes() + ", usedBytes: " + stats.getByteUsed() + ", usedPct: " + usedPercentage
|
||||||
", usedPct: " + usedPercentage + ", disable threshold: " + storageUsedThreshold);
|
+ ", disable threshold: " + storageUsedThreshold);
|
||||||
}
|
}
|
||||||
if (usedPercentage >= storageUsedThreshold) {
|
if (usedPercentage >= storageUsedThreshold) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Insufficient space on pool: " + pool.getId() + " since its usage percentage: " + usedPercentage +
|
s_logger.debug("Insufficient space on pool: " + pool.getId() + " since its usage percentage: " + usedPercentage + " has crossed the pool.storage.capacity.disablethreshold: "
|
||||||
" has crossed the pool.storage.capacity.disablethreshold: " + storageUsedThreshold);
|
+ storageUsedThreshold);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1804,7 +1785,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocated space includes templates
|
// allocated space includes templates
|
||||||
if(s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Destination pool id: " + pool.getId());
|
s_logger.debug("Destination pool id: " + pool.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1853,12 +1834,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
if (pool.getPoolType().supportsOverProvisioning()) {
|
if (pool.getPoolType().supportsOverProvisioning()) {
|
||||||
BigDecimal overProvFactor = getStorageOverProvisioningFactor(pool.getId());
|
BigDecimal overProvFactor = getStorageOverProvisioningFactor(pool.getId());
|
||||||
|
|
||||||
totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(pool.getCapacityBytes())).longValue();
|
totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(pool.getCapacityBytes())).longValue();
|
||||||
|
|
||||||
s_logger.debug("Found storage pool " + poolVO.getName() + " of type " + pool.getPoolType().toString() + " with over-provisioning factor " +
|
s_logger.debug("Found storage pool " + poolVO.getName() + " of type " + pool.getPoolType().toString() + " with overprovisioning factor " + overProvFactor.toString());
|
||||||
overProvFactor.toString());
|
s_logger.debug("Total over provisioned capacity calculated is " + overProvFactor + " * " + pool.getCapacityBytes());
|
||||||
s_logger.debug("Total over-provisioned capacity calculated is " + overProvFactor + " * " + pool.getCapacityBytes());
|
|
||||||
} else {
|
} else {
|
||||||
totalOverProvCapacity = pool.getCapacityBytes();
|
totalOverProvCapacity = pool.getCapacityBytes();
|
||||||
|
|
||||||
@ -1869,31 +1848,20 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
double storageAllocatedThreshold = CapacityManager.StorageAllocatedCapacityDisableThreshold.valueIn(pool.getDataCenterId());
|
double storageAllocatedThreshold = CapacityManager.StorageAllocatedCapacityDisableThreshold.valueIn(pool.getDataCenterId());
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
s_logger.debug("Checking pool: " + pool.getId() + " for volume allocation " + volumes.toString() + ", maxSize : " + totalOverProvCapacity + ", totalAllocatedSize : "
|
||||||
s_logger.debug("Checking pool with ID " + pool.getId() + " for volume allocation " + volumes.toString() + ", maxSize: " +
|
+ allocatedSizeWithTemplate + ", askingSize : " + totalAskingSize + ", allocated disable threshold: " + storageAllocatedThreshold);
|
||||||
totalOverProvCapacity + ", totalAllocatedSize: " + allocatedSizeWithTemplate + ", askingSize: " + totalAskingSize +
|
|
||||||
", allocated disable threshold: " + storageAllocatedThreshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
double usedPercentage = (allocatedSizeWithTemplate + totalAskingSize) / (double)(totalOverProvCapacity);
|
double usedPercentage = (allocatedSizeWithTemplate + totalAskingSize) / (double)(totalOverProvCapacity);
|
||||||
|
|
||||||
if (usedPercentage > storageAllocatedThreshold) {
|
if (usedPercentage > storageAllocatedThreshold) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
s_logger.debug("Insufficient un-allocated capacity on: " + pool.getId() + " for volume allocation: " + volumes.toString() + " since its allocated percentage: " + usedPercentage
|
||||||
s_logger.debug("Insufficient un-allocated capacity on the pool with ID " + pool.getId() + " for volume allocation: " + volumes.toString() +
|
+ " has crossed the allocated pool.storage.allocated.capacity.disablethreshold: " + storageAllocatedThreshold + ", skipping this pool");
|
||||||
" since its allocated percentage " + usedPercentage + " has crossed the allocated pool.storage.allocated.capacity.disablethreshold " +
|
|
||||||
storageAllocatedThreshold + ", skipping this pool");
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalOverProvCapacity < (allocatedSizeWithTemplate + totalAskingSize)) {
|
if (totalOverProvCapacity < (allocatedSizeWithTemplate + totalAskingSize)) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
s_logger.debug("Insufficient un-allocated capacity on: " + pool.getId() + " for volume allocation: " + volumes.toString() + ", not enough storage, maxSize : " + totalOverProvCapacity
|
||||||
s_logger.debug("Insufficient un-allocated capacity on the pool with ID " + pool.getId() + " for volume allocation: " + volumes.toString() +
|
+ ", totalAllocatedSize : " + allocatedSizeWithTemplate + ", askingSize : " + totalAskingSize);
|
||||||
"; not enough storage, maxSize: " + totalOverProvCapacity + ", totalAllocatedSize: " + allocatedSizeWithTemplate + ", askingSize: " +
|
|
||||||
totalAskingSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2007,8 +1975,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageStore discoverImageStore(String name, String url, String providerName, Long zoneId, Map details) throws IllegalArgumentException, DiscoveryException,
|
public ImageStore discoverImageStore(String name, String url, String providerName, Long zoneId, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
|
||||||
InvalidParameterValueException {
|
|
||||||
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
|
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
|
||||||
|
|
||||||
if (storeProvider == null) {
|
if (storeProvider == null) {
|
||||||
@ -2056,10 +2023,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
Account account = CallContext.current().getCallingAccount();
|
Account account = CallContext.current().getCallingAccount();
|
||||||
if (Grouping.AllocationState.Disabled == zone.getAllocationState()
|
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
|
||||||
&& !_accountMgr.isRootAdmin(account.getId())) {
|
PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
|
||||||
PermissionDeniedException ex = new PermissionDeniedException(
|
|
||||||
"Cannot perform this operation, Zone with specified id is currently disabled");
|
|
||||||
ex.addProxyObject(zone.getUuid(), "dcId");
|
ex.addProxyObject(zone.getUuid(), "dcId");
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
@ -2080,7 +2045,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
try {
|
try {
|
||||||
store = lifeCycle.initialize(params);
|
store = lifeCycle.initialize(params);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if(s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Failed to add data store: " + e.getMessage(), e);
|
s_logger.debug("Failed to add data store: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
|
throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
|
||||||
@ -2106,8 +2071,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageStore migrateToObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException,
|
public ImageStore migrateToObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException {
|
||||||
InvalidParameterValueException {
|
|
||||||
// check if current cloud is ready to migrate, we only support cloud with only NFS secondary storages
|
// check if current cloud is ready to migrate, we only support cloud with only NFS secondary storages
|
||||||
List<ImageStoreVO> imgStores = _imageStoreDao.listImageStores();
|
List<ImageStoreVO> imgStores = _imageStoreDao.listImageStores();
|
||||||
List<ImageStoreVO> nfsStores = new ArrayList<ImageStoreVO>();
|
List<ImageStoreVO> nfsStores = new ArrayList<ImageStoreVO>();
|
||||||
@ -2261,8 +2225,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
Account account = CallContext.current().getCallingAccount();
|
Account account = CallContext.current().getCallingAccount();
|
||||||
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
|
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
|
||||||
PermissionDeniedException ex = new PermissionDeniedException(
|
PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
|
||||||
"Cannot perform this operation, Zone with specified id is currently disabled");
|
|
||||||
ex.addProxyObject(zone.getUuid(), "dcId");
|
ex.addProxyObject(zone.getUuid(), "dcId");
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
@ -2281,8 +2244,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
try {
|
try {
|
||||||
store = lifeCycle.initialize(params);
|
store = lifeCycle.initialize(params);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.debug("Failed to add data store: "+e.getMessage(), e);
|
s_logger.debug("Failed to add data store: " + e.getMessage(), e);
|
||||||
throw new CloudRuntimeException("Failed to add data store: "+e.getMessage(), e);
|
throw new CloudRuntimeException("Failed to add data store: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache);
|
return (ImageStore)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache);
|
||||||
@ -2351,18 +2314,18 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanupDownloadUrls(){
|
public void cleanupDownloadUrls() {
|
||||||
|
|
||||||
// Cleanup expired volume URLs
|
// Cleanup expired volume URLs
|
||||||
List<VolumeDataStoreVO> volumesOnImageStoreList = _volumeStoreDao.listVolumeDownloadUrls();
|
List<VolumeDataStoreVO> volumesOnImageStoreList = _volumeStoreDao.listVolumeDownloadUrls();
|
||||||
HashSet<Long> expiredVolumeIds = new HashSet<Long>();
|
HashSet<Long> expiredVolumeIds = new HashSet<Long>();
|
||||||
HashSet<Long> activeVolumeIds = new HashSet<Long>();
|
HashSet<Long> activeVolumeIds = new HashSet<Long>();
|
||||||
for(VolumeDataStoreVO volumeOnImageStore : volumesOnImageStoreList){
|
for (VolumeDataStoreVO volumeOnImageStore : volumesOnImageStoreList) {
|
||||||
|
|
||||||
long volumeId = volumeOnImageStore.getVolumeId();
|
long volumeId = volumeOnImageStore.getVolumeId();
|
||||||
try {
|
try {
|
||||||
long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), volumeOnImageStore.getExtractUrlCreated());
|
long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), volumeOnImageStore.getExtractUrlCreated());
|
||||||
if(downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval){ // URL hasnt expired yet
|
if (downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval) { // URL hasnt expired yet
|
||||||
activeVolumeIds.add(volumeId);
|
activeVolumeIds.add(volumeId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2370,19 +2333,17 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
s_logger.debug("Removing download url " + volumeOnImageStore.getExtractUrl() + " for volume id " + volumeId);
|
s_logger.debug("Removing download url " + volumeOnImageStore.getExtractUrl() + " for volume id " + volumeId);
|
||||||
|
|
||||||
// Remove it from image store
|
// Remove it from image store
|
||||||
ImageStoreEntity secStore = (ImageStoreEntity) _dataStoreMgr.getDataStore(volumeOnImageStore.getDataStoreId(), DataStoreRole.Image);
|
ImageStoreEntity secStore = (ImageStoreEntity)_dataStoreMgr.getDataStore(volumeOnImageStore.getDataStoreId(), DataStoreRole.Image);
|
||||||
secStore.deleteExtractUrl(volumeOnImageStore.getInstallPath(), volumeOnImageStore.getExtractUrl(), Upload.Type.VOLUME);
|
secStore.deleteExtractUrl(volumeOnImageStore.getInstallPath(), volumeOnImageStore.getExtractUrl(), Upload.Type.VOLUME);
|
||||||
|
|
||||||
// Now expunge it from DB since this entry was created only for download purpose
|
// Now expunge it from DB since this entry was created only for download purpose
|
||||||
_volumeStoreDao.expunge(volumeOnImageStore.getId());
|
_volumeStoreDao.expunge(volumeOnImageStore.getId());
|
||||||
}catch(Throwable th){
|
} catch (Throwable th) {
|
||||||
s_logger.warn("Caught exception while deleting download url " +volumeOnImageStore.getExtractUrl() +
|
s_logger.warn("Caught exception while deleting download url " + volumeOnImageStore.getExtractUrl() + " for volume id " + volumeOnImageStore.getVolumeId(), th);
|
||||||
" for volume id " + volumeOnImageStore.getVolumeId(), th);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(Long volumeId : expiredVolumeIds)
|
for (Long volumeId : expiredVolumeIds) {
|
||||||
{
|
if (activeVolumeIds.contains(volumeId)) {
|
||||||
if(activeVolumeIds.contains(volumeId)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Volume volume = _volumeDao.findById(volumeId);
|
Volume volume = _volumeDao.findById(volumeId);
|
||||||
@ -2393,27 +2354,26 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
|
|
||||||
// Cleanup expired template URLs
|
// Cleanup expired template URLs
|
||||||
List<TemplateDataStoreVO> templatesOnImageStoreList = _templateStoreDao.listTemplateDownloadUrls();
|
List<TemplateDataStoreVO> templatesOnImageStoreList = _templateStoreDao.listTemplateDownloadUrls();
|
||||||
for(TemplateDataStoreVO templateOnImageStore : templatesOnImageStoreList){
|
for (TemplateDataStoreVO templateOnImageStore : templatesOnImageStoreList) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), templateOnImageStore.getExtractUrlCreated());
|
long downloadUrlCurrentAgeInSecs = DateUtil.getTimeDifference(DateUtil.now(), templateOnImageStore.getExtractUrlCreated());
|
||||||
if(downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval){ // URL hasnt expired yet
|
if (downloadUrlCurrentAgeInSecs < _downloadUrlExpirationInterval) { // URL hasnt expired yet
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_logger.debug("Removing download url " + templateOnImageStore.getExtractUrl() + " for template id " + templateOnImageStore.getTemplateId());
|
s_logger.debug("Removing download url " + templateOnImageStore.getExtractUrl() + " for template id " + templateOnImageStore.getTemplateId());
|
||||||
|
|
||||||
// Remove it from image store
|
// Remove it from image store
|
||||||
ImageStoreEntity secStore = (ImageStoreEntity) _dataStoreMgr.getDataStore(templateOnImageStore.getDataStoreId(), DataStoreRole.Image);
|
ImageStoreEntity secStore = (ImageStoreEntity)_dataStoreMgr.getDataStore(templateOnImageStore.getDataStoreId(), DataStoreRole.Image);
|
||||||
secStore.deleteExtractUrl(templateOnImageStore.getInstallPath(), templateOnImageStore.getExtractUrl(), Upload.Type.TEMPLATE);
|
secStore.deleteExtractUrl(templateOnImageStore.getInstallPath(), templateOnImageStore.getExtractUrl(), Upload.Type.TEMPLATE);
|
||||||
|
|
||||||
// Now remove download details from DB.
|
// Now remove download details from DB.
|
||||||
templateOnImageStore.setExtractUrl(null);
|
templateOnImageStore.setExtractUrl(null);
|
||||||
templateOnImageStore.setExtractUrlCreated(null);
|
templateOnImageStore.setExtractUrlCreated(null);
|
||||||
_templateStoreDao.update(templateOnImageStore.getId(), templateOnImageStore);
|
_templateStoreDao.update(templateOnImageStore.getId(), templateOnImageStore);
|
||||||
}catch(Throwable th){
|
} catch (Throwable th) {
|
||||||
s_logger.warn("caught exception while deleting download url " +templateOnImageStore.getExtractUrl() +
|
s_logger.warn("caught exception while deleting download url " + templateOnImageStore.getExtractUrl() + " for template id " + templateOnImageStore.getTemplateId(), th);
|
||||||
" for template id " +templateOnImageStore.getTemplateId(), th);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2504,7 +2464,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
public DiskTO getDiskWithThrottling(final DataTO volTO, final Volume.Type volumeType, final long deviceId, final String path, final long offeringId, final long diskOfferingId) {
|
public DiskTO getDiskWithThrottling(final DataTO volTO, final Volume.Type volumeType, final long deviceId, final String path, final long offeringId, final long diskOfferingId) {
|
||||||
DiskTO disk = null;
|
DiskTO disk = null;
|
||||||
if (volTO != null && volTO instanceof VolumeObjectTO) {
|
if (volTO != null && volTO instanceof VolumeObjectTO) {
|
||||||
VolumeObjectTO volumeTO = (VolumeObjectTO) volTO;
|
VolumeObjectTO volumeTO = (VolumeObjectTO)volTO;
|
||||||
ServiceOffering offering = _entityMgr.findById(ServiceOffering.class, offeringId);
|
ServiceOffering offering = _entityMgr.findById(ServiceOffering.class, offeringId);
|
||||||
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, diskOfferingId);
|
DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, diskOfferingId);
|
||||||
if (volumeType == Volume.Type.ROOT) {
|
if (volumeType == Volume.Type.ROOT) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user