diff --git a/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java b/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java index 10ced67244f..8ee0c4a5955 100644 --- a/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java @@ -266,6 +266,11 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, return this.state; } + //TODO: this should be revisited post-4.2 to completely use state transition machine + public void setState(ObjectInDataStoreStateMachine.State state) { + this.state = state; + } + public long getUpdatedCount() { return this.updatedCount; } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 07ae6a9f0e3..0c2eaee677b 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -25,48 +25,37 @@ import java.util.Map; import javax.inject.Inject; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.amazonaws.services.storagegateway.model.ChapInfo; + import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; -import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.storage.command.CommandResult; -import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; - -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; +import org.apache.cloudstack.storage.datastore.VolumeDataFactory; +import org.apache.cloudstack.storage.endpoint.EndPointSelector; +import org.apache.cloudstack.storage.image.TemplateInfo; +import org.apache.cloudstack.storage.motion.DataMotionService; +import org.apache.cloudstack.storage.snapshot.SnapshotInfo; +import org.apache.cloudstack.storage.volume.db.VolumeVO; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.storage.ListVolumeAnswer; -import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; import com.cloud.configuration.Resource.ResourceType; import com.cloud.event.EventTypes; @@ -74,19 +63,12 @@ import com.cloud.event.UsageEventUtils; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.Host; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePool; -import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.Volume.State; import com.cloud.storage.Volume; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.Volume.State; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.NumbersUtil; @@ -504,6 +486,7 @@ public class VolumeServiceImpl implements VolumeService { AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { DataObject vo = context.vo; + DataObject tmplOnPrimary = context.templateOnStore; CopyCommandResult result = callback.getResult(); VolumeApiResult volResult = new VolumeApiResult((VolumeObject) vo); @@ -512,8 +495,32 @@ public class VolumeServiceImpl implements VolumeService { } else { vo.processEvent(Event.OperationFailed); volResult.setResult(result.getResult()); + // hack for Vmware: host is down, previously download template to the host needs to be re-downloaded, so we need to reset + // template_spool_ref entry here to NOT_DOWNLOADED and Allocated state + Answer ans = result.getAnswer(); + if ( ans != null && ans instanceof CopyCmdAnswer && ans.getDetails().contains("request template reload")){ + if (tmplOnPrimary != null){ + s_logger.info("Reset template_spool_ref entry so that vmware template can be reloaded in next try"); + VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(tmplOnPrimary.getDataStore().getId(), tmplOnPrimary.getId()); + if (templatePoolRef != null) { + long templatePoolRefId = templatePoolRef.getId(); + templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, 1200); + if (templatePoolRef == null) { + s_logger.warn("Reset Template State On Pool failed - unable to lock TemplatePoolRef " + templatePoolRefId); + } + + try { + templatePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED); + templatePoolRef.setState(ObjectInDataStoreStateMachine.State.Allocated); + _tmpltPoolDao.update(templatePoolRefId, templatePoolRef); + } finally { + _tmpltPoolDao.releaseFromLockTable(templatePoolRefId); + } + } + } + } } - + AsyncCallFuture future = context.getFuture(); future.complete(volResult); return null;