CLOUDSTACK-4324: delete snapshot_store_ref, if create snapshot failed on primary storage

This commit is contained in:
Edison Su 2013-08-19 15:22:52 -07:00
parent d89667ed47
commit 4fd09cb344
7 changed files with 433 additions and 9 deletions

View File

@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cloudstack.storage.test;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
import org.apache.cloudstack.storage.datastore.provider.CloudStackPrimaryDataStoreProviderImpl;
import org.apache.cloudstack.storage.datastore.type.DataStoreType;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
import java.util.HashSet;
import java.util.Set;
public class FakeDriverTestConfiguration extends ChildTestConfiguration{
@Bean
public CloudStackPrimaryDataStoreProviderImpl dataStoreProvider() {
CloudStackPrimaryDataStoreProviderImpl provider = Mockito.mock(CloudStackPrimaryDataStoreProviderImpl.class);
return provider;
}
}

View File

@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cloudstack.storage.test;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
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.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
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.VolumeInfo;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
import java.util.UUID;
public class FakePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
boolean snapshotResult = true;
@Override
public ChapInfo getChapInfo(VolumeInfo volumeInfo) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
CreateCmdResult result = new CreateCmdResult(null, null);
if (snapshotResult) {
SnapshotObjectTO newSnap = new SnapshotObjectTO();
newSnap.setPath(UUID.randomUUID().toString());
CreateObjectAnswer answer = new CreateObjectAnswer(newSnap);
result.setAnswer(answer);
} else {
result.setResult("Failed to create snapshot");
}
callback.complete(result);
return;
}
public void makeTakeSnapshotSucceed(boolean success) {
snapshotResult = success;
}
@Override
public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CommandResult> callback) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public DataTO getTO(DataObject data) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public DataStoreTO getStoreTO(DataStore store) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void createAsync(DataStore store, DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void deleteAsync(DataStore store, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
CommandResult result = new CommandResult();
result.setSuccess(true);
callback.complete(result);
return;
}
@Override
public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean canCopy(DataObject srcData, DataObject destData) {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
//To change body of implemented methods use File | Settings | File Templates.
}
}

View File

@ -0,0 +1,194 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cloudstack.storage.test;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Snapshot;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.utils.component.ComponentContext;
import junit.framework.Assert;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
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.PrimaryDataStoreProvider;
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.SnapshotResult;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
import org.apache.cloudstack.storage.datastore.PrimaryDataStore;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.inject.Inject;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/fakeDriverTestContext.xml" })
public class SnapshotTestWithFakeData {
@Inject
SnapshotService snapshotService;
@Inject
SnapshotDao snapshotDao;
@Inject
PrimaryDataStoreDao primaryDataStoreDao;
@Inject
DataStoreManager dataStoreManager;
@Inject
SnapshotDataFactory snapshotDataFactory;
@Inject
PrimaryDataStoreProvider primaryDataStoreProvider;
@Inject
SnapshotDataStoreDao snapshotDataStoreDao;
@Inject
VolumeDao volumeDao;
@Inject
VolumeService volumeService;
@Inject
VolumeDataFactory volumeDataFactory;
FakePrimaryDataStoreDriver driver = new FakePrimaryDataStoreDriver();
@Before
public void setUp() {
Mockito.when(primaryDataStoreProvider.configure(Mockito.anyMap())).thenReturn(true);
Set<DataStoreProvider.DataStoreProviderType> types = new HashSet<DataStoreProvider.DataStoreProviderType>();
types.add(DataStoreProvider.DataStoreProviderType.PRIMARY);
Mockito.when(primaryDataStoreProvider.getTypes()).thenReturn(types);
Mockito.when(primaryDataStoreProvider.getName()).thenReturn(DataStoreProvider.DEFAULT_PRIMARY);
Mockito.when(primaryDataStoreProvider.getDataStoreDriver()).thenReturn(driver);
ComponentContext.initComponentsLifeCycle();
}
private SnapshotVO createSnapshotInDb() {
Snapshot.Type snapshotType = Snapshot.Type.MANUAL;
SnapshotVO snapshotVO = new SnapshotVO(1, 2, 1, 1L, 1L, UUID.randomUUID()
.toString(), (short) snapshotType.ordinal(), snapshotType.name(), 100,
Hypervisor.HypervisorType.XenServer);
return this.snapshotDao.persist(snapshotVO);
}
private VolumeInfo createVolume(Long templateId, DataStore store) {
VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), 1L, 1L, 1L, 1L, 1000, 0L, 0L, "");
;
volume.setPoolId(store.getId());
volume = volumeDao.persist(volume);
VolumeInfo volumeInfo = volumeDataFactory.getVolume(volume.getId(), store);
volumeInfo.stateTransit(Volume.Event.CreateRequested);
volumeInfo.stateTransit(Volume.Event.OperationSucceeded);
return volumeInfo;
}
private DataStore createDataStore() throws URISyntaxException {
StoragePoolVO pool = new StoragePoolVO();
pool.setClusterId(1L);
pool.setDataCenterId(1);
URI uri = new URI("nfs://jfkdkf/fjdkfj");
pool.setHostAddress(uri.getHost());
pool.setPath(uri.getPath());
pool.setPort(0);
pool.setName(UUID.randomUUID().toString());
pool.setUuid(UUID.randomUUID().toString());
pool.setStatus(StoragePoolStatus.Up);
pool.setPoolType(Storage.StoragePoolType.NetworkFilesystem);
pool.setPodId(1L);
pool.setScope(ScopeType.CLUSTER);
pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY);
pool = this.primaryDataStoreDao.persist(pool);
DataStore store = this.dataStoreManager.getPrimaryDataStore(pool.getId());
return store;
}
@Test
public void testTakeSnapshot() throws URISyntaxException {
SnapshotVO snapshotVO = createSnapshotInDb();
DataStore store = createDataStore();
try {
SnapshotInfo snapshotInfo = snapshotDataFactory.getSnapshot(snapshotVO.getId(), store);
SnapshotResult result = snapshotService.takeSnapshot(snapshotInfo);
Assert.assertTrue(result.isSuccess());
SnapshotDataStoreVO storeRef = snapshotDataStoreDao.findByStoreSnapshot(store.getRole(), store.getId(), snapshotVO.getId());
Assert.assertTrue(storeRef != null);
Assert.assertTrue(storeRef.getState() == ObjectInDataStoreStateMachine.State.Ready);
snapshotInfo = result.getSnashot();
boolean deletResult = snapshotService.deleteSnapshot(snapshotInfo);
Assert.assertTrue(deletResult);
snapshotDataStoreDao.expunge(storeRef.getId());
} finally {
snapshotDao.expunge(snapshotVO.getId());
primaryDataStoreDao.remove(store.getId());
}
}
@Test
public void testTakeSnapshotWithFailed() throws URISyntaxException {
SnapshotVO snapshotVO = createSnapshotInDb();
DataStore store = null;
try {
store = createDataStore();
FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
dataStoreDriver.makeTakeSnapshotSucceed(false);
SnapshotInfo snapshotInfo = snapshotDataFactory.getSnapshot(snapshotVO.getId(), store);
SnapshotResult result = snapshotService.takeSnapshot(snapshotInfo);
Assert.assertFalse(result.isSuccess());
SnapshotDataStoreVO storeRef = snapshotDataStoreDao.findByStoreSnapshot(store.getRole(), store.getId(), snapshotVO.getId());
Assert.assertTrue(storeRef == null);
} finally {
snapshotDao.expunge(snapshotVO.getId());
if (store != null) {
primaryDataStoreDao.remove(store.getId());
}
}
}
@Test
public void testTakeSnapshotFromVolume() throws URISyntaxException {
DataStore store = createDataStore();
FakePrimaryDataStoreDriver dataStoreDriver = (FakePrimaryDataStoreDriver)store.getDriver();
dataStoreDriver.makeTakeSnapshotSucceed(false);
VolumeInfo volumeInfo = createVolume(1L, store);
Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
SnapshotInfo result = volumeService.takeSnapshot(volumeInfo);
Assert.assertTrue(volumeInfo.getState() == Volume.State.Ready);
Assert.assertTrue(result == null);
}
}

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for additional
information regarding copyright ownership. The ASF licenses this file to
you under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License. -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<bean id="componentContext" class="com.cloud.utils.component.ComponentContext" />
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
<bean id="actionEventInterceptor" class="com.cloud.event.ActionEventInterceptor" />
<bean class="org.apache.cloudstack.storage.test.FakeDriverTestConfiguration" />
<bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
<property name="Interceptors">
<list>
<ref bean="transactionContextBuilder" />
<ref bean="actionEventInterceptor" />
</list>
</property>
</bean>
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl" />
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl" />
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
<bean id="volumeDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.VolumeDataStoreDaoImpl" />
<bean id="objectInDataStoreDaoImpl" class="org.apache.cloudstack.storage.db.ObjectInDataStoreDaoImpl" />
<bean id="primaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl" />
<bean id="primaryDataStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.volume.db.PrimaryDataStoreDetailsDaoImpl" />
<bean id="templatePrimaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.volume.db.TemplatePrimaryDataStoreDaoImpl" />
<bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator"/>
<bean id="clusterScopeStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ClusterScopeStoragePoolAllocator" />
<bean id="zoneWideStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.ZoneWideStoragePoolAllocator" />
<bean id="dataStoreProviderManagerImpl" class="org.apache.cloudstack.storage.datastore.provider.DataStoreProviderManagerImpl" />
<bean id="ancientDataMotionStrategy" class="org.apache.cloudstack.storage.motion.AncientDataMotionStrategy" />
<bean id="storageCacheManagerImpl" class="org.apache.cloudstack.storage.cache.manager.StorageCacheManagerImpl" />
<bean id="storageCacheRandomAllocator" class="org.apache.cloudstack.storage.cache.allocator.StorageCacheRandomAllocator" />
<bean id="xenserverSnapshotStrategy" class="org.apache.cloudstack.storage.snapshot.XenserverSnapshotStrategy" />
<bean id="bAREMETAL" class="org.apache.cloudstack.storage.image.format.BAREMETAL" />
<bean id="dataMotionServiceImpl" class="org.apache.cloudstack.storage.motion.DataMotionServiceImpl" />
<bean id="dataObjectManagerImpl" class="org.apache.cloudstack.storage.datastore.DataObjectManagerImpl" />
<bean id="dataStoreManagerImpl" class="org.apache.cloudstack.storage.datastore.DataStoreManagerImpl" />
<bean id="primaryDataStoreProviderManagerImpl" class="org.apache.cloudstack.storage.datastore.manager.PrimaryDataStoreProviderManagerImpl" />
<bean id="imageStoreProviderManagerImpl" class="org.apache.cloudstack.storage.image.manager.ImageStoreProviderManagerImpl" />
<bean id="iSCSI" class="org.apache.cloudstack.storage.datastore.type.ISCSI" />
<bean id="ISO" class="org.apache.cloudstack.storage.image.format.ISO" />
<bean id="templateDataFactoryImpl" class="org.apache.cloudstack.storage.image.TemplateDataFactoryImpl" />
<bean id="imageStoreHelper" class="org.apache.cloudstack.storage.image.datastore.ImageStoreHelper" />
<bean id="imageFormatHelper" class="org.apache.cloudstack.storage.image.format.ImageFormatHelper" />
<bean id="templateServiceImpl" class="org.apache.cloudstack.storage.image.TemplateServiceImpl" />
<bean id="networkFileSystem" class="org.apache.cloudstack.storage.datastore.type.NetworkFileSystem" />
<bean id="OVA" class="org.apache.cloudstack.storage.image.format.OVA" />
<bean id="objectInDataStoreManagerImpl" class="org.apache.cloudstack.storage.datastore.ObjectInDataStoreManagerImpl" />
<bean id="primaryDataStoreHelper" class="org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper" />
<bean id="QCOW2" class="org.apache.cloudstack.storage.image.format.QCOW2" />
<bean id="snapshotDataFactoryImpl" class="org.apache.cloudstack.storage.snapshot.SnapshotDataFactoryImpl" />
<bean id="snapshotServiceImpl" class="org.apache.cloudstack.storage.snapshot.SnapshotServiceImpl" />
<bean id="snapshotStateMachineManagerImpl" class="org.apache.cloudstack.storage.snapshot.SnapshotStateMachineManagerImpl" />
<bean id="unknown" class="org.apache.cloudstack.storage.image.format.Unknown" />
<bean id="VHD" class="org.apache.cloudstack.storage.image.format.VHD" />
<bean id="volumeDataFactoryImpl" class="org.apache.cloudstack.storage.volume.VolumeDataFactoryImpl" />
<bean id="volumeServiceImpl" class="org.apache.cloudstack.storage.volume.VolumeServiceImpl" />
<bean id="cloudStackImageStoreProviderImpl" class="org.apache.cloudstack.storage.datastore.provider.CloudStackImageStoreProviderImpl" />
<bean id="s3ImageStoreProviderImpl" class="org.apache.cloudstack.storage.datastore.provider.S3ImageStoreProviderImpl" />
<bean id="swiftImageStoreProviderImpl" class="org.apache.cloudstack.storage.datastore.provider.SwiftImageStoreProviderImpl" />
<bean id="BAREMETAL" class="org.apache.cloudstack.storage.image.format.BAREMETAL" />
<bean id="storagePoolAutomationImpl" class="com.cloud.storage.StoragePoolAutomationImpl" />
<bean id="AccountGuestVlanMapDaoImpl" class="com.cloud.network.dao.AccountGuestVlanMapDaoImpl" />
<bean id="StorageCacheReplacementAlgorithm" class="org.apache.cloudstack.storage.cache.manager.StorageCacheReplacementAlgorithmLRU" />
<bean id="ServiceOfferingDetailsDao" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl" />
</beans>

View File

@ -213,11 +213,6 @@ public class SnapshotServiceImpl implements SnapshotService {
try {
result = future.get();
if (result.isFailed()) {
snapshot.processEvent(Snapshot.Event.OperationFailed);
snapshot.processEvent(Event.OperationFailed);
throw new CloudRuntimeException(result.getResult());
}
return result;
} catch (InterruptedException e) {
s_logger.debug("Failed to create snapshot", e);
@ -225,9 +220,6 @@ public class SnapshotServiceImpl implements SnapshotService {
} catch (ExecutionException e) {
s_logger.debug("Failed to create snapshot", e);
throw new CloudRuntimeException("Failed to create snapshot", e);
} catch (NoTransitionException e) {
s_logger.debug("Failed to create snapshot", e);
throw new CloudRuntimeException("Failed to create snapshot", e);
}
}

View File

@ -245,6 +245,12 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
s_logger.warn("Template " + objId + " is not found on storage pool " + dataStore.getId() + ", so no need to delete");
return true;
}
} else if (dataObj.getType() == DataObjectType.SNAPSHOT) {
SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getRole(), dataStore.getId(), objId);
if (destSnapshotStore != null && destSnapshotStore.getState() != ObjectInDataStoreStateMachine.State.Ready) {
snapshotDataStoreDao.remove(destSnapshotStore.getId());
}
return true;
}
} else {
// Image store

View File

@ -1266,7 +1266,7 @@ public class VolumeServiceImpl implements VolumeService {
try {
snapshot = snapshotMgr.takeSnapshot(volume);
} catch (Exception e) {
s_logger.debug("Take snapshot: " + volume.getId() + " failed: " + e.toString());
s_logger.debug("Take snapshot: " + volume.getId() + " failed", e);
} finally {
if (snapshot != null) {
vol.stateTransit(Volume.Event.OperationSucceeded);