add cache storage

This commit is contained in:
Edison Su 2013-04-11 11:01:29 -07:00
parent e5bf38ed05
commit 1c448cd6e3
9 changed files with 93 additions and 25 deletions

View File

@ -21,4 +21,5 @@ package org.apache.cloudstack.engine.subsystem.api.storage;
public interface StorageCacheManager { public interface StorageCacheManager {
public DataStore getCacheStorage(Scope scope); public DataStore getCacheStorage(Scope scope);
public DataObject createCacheObject(DataObject data, Scope scope);
} }

View File

@ -24,6 +24,8 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
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.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
@ -34,6 +36,8 @@ import com.cloud.utils.component.Manager;
public class StorageCacheManagerImpl implements StorageCacheManager, Manager { public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
@Inject @Inject
List<StorageCacheAllocator> storageCacheAllocator; List<StorageCacheAllocator> storageCacheAllocator;
@Inject
DataMotionService dataMotionSvr;
@Override @Override
public DataStore getCacheStorage(Scope scope) { public DataStore getCacheStorage(Scope scope) {
for (StorageCacheAllocator allocator : storageCacheAllocator) { for (StorageCacheAllocator allocator : storageCacheAllocator) {
@ -97,4 +101,14 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return true; return true;
} }
@Override
public DataObject createCacheObject(DataObject data, Scope scope) {
DataStore cacheStore = this.getCacheStorage(scope);
DataObject objOnCacheStore = cacheStore.create(data);
//AsyncCallFuture<>
//dataMotionSvr.copyAsync(data, objOnCacheStore, callback);
// TODO Auto-generated method stub
return null;
}
} }

View File

@ -63,7 +63,7 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory {
SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId); SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId);
SnapshotObject so = null; SnapshotObject so = null;
if (snapshot.getState() == Snapshot.State.BackedUp) { if (snapshot.getState() == Snapshot.State.BackedUp) {
DataStore store = objMap.findStore(snapshot.getUuid(), DataObjectType.SNAPSHOT, DataStoreRole.Image); DataStore store = objMap.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image);
so = SnapshotObject.getSnapshotObject(snapshot, store); so = SnapshotObject.getSnapshotObject(snapshot, store);
} else { } else {
VolumeInfo volume = this.volumeFactory.getVolume(snapshot.getVolumeId()); VolumeInfo volume = this.volumeFactory.getVolume(snapshot.getVolumeId());

View File

@ -470,7 +470,7 @@ public class AncientSnapshotStrategy implements SnapshotStrategy {
@DB @DB
protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { protected boolean destroySnapshotBackUp(SnapshotVO snapshot) {
DataStore store = objInStoreMgr.findStore(snapshot.getUuid(), DataObjectType.SNAPSHOT, DataStoreRole.Image); DataStore store = objInStoreMgr.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image);
if (store == null) { if (store == null) {
s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store");
return false; return false;

View File

@ -32,5 +32,5 @@ public interface ObjectInDataStoreManager {
DataObjectInStore findObject(long objId, DataObjectType type, DataObjectInStore findObject(long objId, DataObjectType type,
long dataStoreId, DataStoreRole role); long dataStoreId, DataStoreRole role);
DataObjectInStore findObject(DataObject obj, DataStore store); DataObjectInStore findObject(DataObject obj, DataStore store);
DataStore findStore(String objUuid, DataObjectType type, DataStoreRole role); DataStore findStore(long objId, DataObjectType type, DataStoreRole role);
} }

View File

@ -35,6 +35,7 @@ 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.cloudstack.storage.datastore.db.VolumeDataStoreDao; 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.db.ObjectInDataStoreDao;
import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.cloudstack.storage.db.ObjectInDataStoreVO;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -69,6 +70,8 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
VMTemplatePoolDao templatePoolDao; VMTemplatePoolDao templatePoolDao;
@Inject @Inject
SnapshotDataFactory snapshotFactory; SnapshotDataFactory snapshotFactory;
@Inject
ObjectInDataStoreDao objInStoreDao;
protected StateMachine2<State, Event, DataObjectInStore> stateMachines; protected StateMachine2<State, Event, DataObjectInStore> stateMachines;
public ObjectInDataStoreManagerImpl() { public ObjectInDataStoreManagerImpl() {
@ -110,6 +113,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId()); VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId());
vo = templatePoolDao.persist(vo); vo = templatePoolDao.persist(vo);
} }
} else if (dataStore.getRole() == DataStoreRole.ImageCache) {
ObjectInDataStoreVO vo = new ObjectInDataStoreVO();
vo.setDataStoreRole(dataStore.getRole());
vo.setDataStoreId(dataStore.getId());
vo.setObjectType(obj.getType());
vo.setObjectId(obj.getId());
vo = objInStoreDao.persist(vo);
} else { } else {
// Image store // Image store
switch ( obj.getType()){ switch ( obj.getType()){
@ -212,6 +222,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
} }
} else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) { } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) {
vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId); vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId);
} else if (role == DataStoreRole.ImageCache) {
SearchCriteriaService<ObjectInDataStoreVO, ObjectInDataStoreVO> sc = SearchCriteria2.create(ObjectInDataStoreVO.class);
sc.addAnd(sc.getEntity().getObjectId(), Op.EQ, objId);
sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type);
sc.addAnd(sc.getEntity().getDataStoreId(), Op.EQ, dataStoreId);
sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role);
vo = sc.find();
} else { } else {
s_logger.debug("Invalid data or store type: " + type + " " + role); s_logger.debug("Invalid data or store type: " + type + " " + role);
throw new CloudRuntimeException("Invalid data or store type: " + type + " " + role); throw new CloudRuntimeException("Invalid data or store type: " + type + " " + role);
@ -222,16 +239,16 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager {
} }
@Override @Override
public DataStore findStore(String objUuid, DataObjectType type, DataStoreRole role) { public DataStore findStore(long objId, DataObjectType type, DataStoreRole role) {
DataStore store = null; DataStore store = null;
if (role == DataStoreRole.Image) { if (role == DataStoreRole.Image) {
SearchCriteriaService<ObjectInDataStoreVO, ObjectInDataStoreVO> sc = SearchCriteria2.create(ObjectInDataStoreVO.class); SearchCriteriaService<ObjectInDataStoreVO, ObjectInDataStoreVO> sc = SearchCriteria2.create(ObjectInDataStoreVO.class);
sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role); sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role);
sc.addAnd(sc.getEntity().getObjectUuid(), Op.EQ, objUuid); sc.addAnd(sc.getEntity().getObjectId(), Op.EQ, objId);
sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type); sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type);
ObjectInDataStoreVO vo = sc.find(); ObjectInDataStoreVO vo = sc.find();
if (vo != null) { if (vo != null) {
store = this.storeMgr.getDataStore(vo.getDataStoreUuid(), vo.getDataStoreRole()); store = this.storeMgr.getDataStore(vo.getDataStoreId(), vo.getDataStoreRole());
} }
} }
return store; return store;

View File

@ -46,15 +46,15 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
long id; long id;
@Column(name = "datastore_uuid") @Column(name = "datastore_id")
private String dataStoreUuid; private long dataStoreId;
@Column(name = "datastore_role") @Column(name = "datastore_role")
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private DataStoreRole dataStoreRole; private DataStoreRole dataStoreRole;
@Column(name = "object_uuid") @Column(name = "object_id")
String objectUuid; long objectId;
@Column(name = "object_type") @Column(name = "object_type")
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@ -117,14 +117,6 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
return this.id; return this.id;
} }
public String getDataStoreUuid() {
return this.dataStoreUuid;
}
public void setDataStoreUuid(String uuid) {
this.dataStoreUuid = uuid;
}
public DataStoreRole getDataStoreRole() { public DataStoreRole getDataStoreRole() {
return this.dataStoreRole; return this.dataStoreRole;
} }
@ -133,12 +125,12 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
this.dataStoreRole = role; this.dataStoreRole = role;
} }
public String getObjectUuid() { public long getObjectId() {
return this.objectUuid; return this.objectId;
} }
public void setObjectUuid(String uuid) { public void setObjectId(long id) {
this.objectUuid = uuid; this.objectId = id;
} }
public DataObjectType getObjectType() { public DataObjectType getObjectType() {
@ -189,4 +181,12 @@ public class ObjectInDataStoreVO implements StateObject<ObjectInDataStoreStateMa
public void setUpdated(Date updated) { public void setUpdated(Date updated) {
this.updated = updated; this.updated = updated;
} }
public long getDataStoreId() {
return dataStoreId;
}
public void setDataStoreId(long dataStoreId) {
this.dataStoreId = dataStoreId;
}
} }

View File

@ -55,7 +55,7 @@ public class VolumeDataFactoryImpl implements VolumeDataFactory {
VolumeVO volumeVO = volumeDao.findById(volumeId); VolumeVO volumeVO = volumeDao.findById(volumeId);
VolumeObject vol = null; VolumeObject vol = null;
if (volumeVO.getPoolId() == null) { if (volumeVO.getPoolId() == null) {
DataStore store = objMap.findStore(volumeVO.getUuid(), DataObjectType.VOLUME, DataStoreRole.Image); DataStore store = objMap.findStore(volumeVO.getId(), DataObjectType.VOLUME, DataStoreRole.Image);
vol = VolumeObject.getVolumeObject(store, volumeVO); vol = VolumeObject.getVolumeObject(store, volumeVO);
} else { } else {
DataStore store = this.storeMgr.getDataStore(volumeVO.getPoolId(), DataStoreRole.Primary); DataStore store = this.storeMgr.getDataStore(volumeVO.getPoolId(), DataStoreRole.Primary);

View File

@ -44,6 +44,8 @@ import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConcurrentOperationException;
import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume; import com.cloud.storage.Volume;
@ -51,6 +53,7 @@ import com.cloud.storage.Volume.Type;
import com.cloud.storage.VolumeVO; import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
@ -75,6 +78,8 @@ public class VolumeServiceImpl implements VolumeService {
VolumeDataFactory volFactory; VolumeDataFactory volFactory;
@Inject SnapshotManager snapshotMgr; @Inject SnapshotManager snapshotMgr;
@Inject VMInstanceDao vmDao; @Inject VMInstanceDao vmDao;
@Inject
ConfigurationDao configDao;
public VolumeServiceImpl() { public VolumeServiceImpl() {
} }
@ -281,6 +286,24 @@ public class VolumeServiceImpl implements VolumeService {
} }
} }
private TemplateInfo waitForTemplateDownloaded(PrimaryDataStore store, TemplateInfo template) {
int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
int sleepTime = 120;
int tries = storagePoolMaxWaitSeconds/sleepTime;
while (tries > 0) {
TemplateInfo tmpl = store.getTemplate(template.getId());
if (tmpl != null) {
return tmpl;
}
try {
Thread.sleep(sleepTime * 1000);
} catch (InterruptedException e) {
s_logger.debug("waiting for template download been interrupted: " + e.toString());
}
tries--;
}
return null;
}
@DB @DB
protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) { protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
@ -293,7 +316,20 @@ public class VolumeServiceImpl implements VolumeService {
caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)) caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null))
.setContext(context); .setContext(context);
try {
templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested); templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested);
} catch (Exception e) {
try {
templateOnPrimaryStoreObj = waitForTemplateDownloaded(dataStore, template);
} finally {
if (templateOnPrimaryStoreObj == null) {
VolumeApiResult result = new VolumeApiResult(volume);
result.setResult(e.toString());
caller.complete(result);
return;
}
}
}
try { try {
motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller); motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller);