CLOUDSTACK-4618: fix CLVM

This commit is contained in:
Edison Su 2013-09-06 17:55:11 -07:00
parent d1a14fbf95
commit 4fb4593553
3 changed files with 80 additions and 12 deletions

View File

@ -147,8 +147,7 @@ public class KVMStorageProcessor implements StorageProcessor {
DataTO destData = cmd.getDestTO(); DataTO destData = cmd.getDestTO();
TemplateObjectTO template = (TemplateObjectTO) srcData; TemplateObjectTO template = (TemplateObjectTO) srcData;
DataStoreTO imageStore = template.getDataStore(); DataStoreTO imageStore = template.getDataStore();
TemplateObjectTO volume = (TemplateObjectTO) destData; PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) destData.getDataStore();
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) volume.getDataStore();
if (!(imageStore instanceof NfsTO)) { if (!(imageStore instanceof NfsTO)) {
return new CopyCmdAnswer("unsupported protocol"); return new CopyCmdAnswer("unsupported protocol");
@ -197,19 +196,32 @@ public class KVMStorageProcessor implements StorageProcessor {
KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(),
primaryPool); primaryPool);
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(primaryVol.getName());
DataTO data = null;
/** /**
* Force the ImageFormat for RBD templates to RAW * Force the ImageFormat for RBD templates to RAW
* *
*/ */
if (destData.getObjectType() == DataObjectType.TEMPLATE) {
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(primaryVol.getName());
if (primaryPool.getType() == StoragePoolType.RBD) { if (primaryPool.getType() == StoragePoolType.RBD) {
newTemplate.setFormat(ImageFormat.RAW); newTemplate.setFormat(ImageFormat.RAW);
} else { } else {
newTemplate.setFormat(ImageFormat.QCOW2); newTemplate.setFormat(ImageFormat.QCOW2);
} }
return new CopyCmdAnswer(newTemplate); data = newTemplate;
} else if (destData.getObjectType() == DataObjectType.VOLUME) {
VolumeObjectTO volumeObjectTO = new VolumeObjectTO();
volumeObjectTO.setPath(primaryVol.getName());
if (primaryVol.getFormat() == PhysicalDiskFormat.RAW)
volumeObjectTO.setFormat(ImageFormat.RAW);
else if (primaryVol.getFormat() == PhysicalDiskFormat.QCOW2) {
volumeObjectTO.setFormat(ImageFormat.QCOW2);
}
data = volumeObjectTO;
}
return new CopyCmdAnswer(data);
} catch (CloudRuntimeException e) { } catch (CloudRuntimeException e) {
return new CopyCmdAnswer(e.toString()); return new CopyCmdAnswer(e.toString());
} finally { } finally {
@ -287,6 +299,7 @@ public class KVMStorageProcessor implements StorageProcessor {
String templatePath = template.getPath(); String templatePath = template.getPath();
if (primaryPool.getType() == StoragePoolType.CLVM) { if (primaryPool.getType() == StoragePoolType.CLVM) {
templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
vol = templateToPrimaryDownload(templatePath, primaryPool); vol = templateToPrimaryDownload(templatePath, primaryPool);
} else { } else {
if (templatePath.contains("/mnt")) { if (templatePath.contains("/mnt")) {

View File

@ -25,9 +25,13 @@ import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.StorageUnavailableException; import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.ResizeVolumePayload; import com.cloud.storage.ResizeVolumePayload;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager; import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePool;
import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.DiskOfferingDao;
@ -35,20 +39,27 @@ import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDao;
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.template.TemplateManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.*; import org.apache.cloudstack.engine.subsystem.api.storage.*;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CommandResult;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.command.CreateObjectCommand;
import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DeleteCommand;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.cloudstack.storage.volume.VolumeObject;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.UUID;
public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreDriverImpl.class); private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreDriverImpl.class);
@ -74,7 +85,12 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
SnapshotManager snapshotMgr; SnapshotManager snapshotMgr;
@Inject @Inject
EndPointSelector epSelector; EndPointSelector epSelector;
@Inject
ConfigurationDao configDao;
@Inject
TemplateManager templateManager;
@Inject
TemplateDataFactory templateDataFactory;
@Override @Override
public DataTO getTO(DataObject data) { public DataTO getTO(DataObject data) {
return null; return null;
@ -165,10 +181,49 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
@Override @Override
public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) { public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
DataStore store = destData.getDataStore();
if (store.getRole() == DataStoreRole.Primary) {
if ((srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.TEMPLATE)) {
//For CLVM, we need to copy template to primary storage at all, just fake the copy result.
TemplateObjectTO templateObjectTO = new TemplateObjectTO();
templateObjectTO.setPath(UUID.randomUUID().toString());
templateObjectTO.setSize(srcdata.getSize());
templateObjectTO.setPhysicalSize(srcdata.getSize());
templateObjectTO.setFormat(Storage.ImageFormat.RAW);
CopyCmdAnswer answer = new CopyCmdAnswer(templateObjectTO);
CopyCommandResult result = new CopyCommandResult("", answer);
callback.complete(result);
} else if (srcdata.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) {
//For CLVM, we need to pass template on secondary storage to hypervisor
String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
int _primaryStorageDownloadWait = NumbersUtil.parseInt(value,
Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
DataStore imageStore = templateManager.getImageStore(storagePoolVO.getDataCenterId(), srcdata.getId());
DataObject srcData = templateDataFactory.getTemplate(srcdata.getId(), imageStore);
CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait, true);
EndPoint ep = epSelector.select(srcData, destData);
Answer answer = ep.sendMessage(cmd);
CopyCommandResult result = new CopyCommandResult("", answer);
callback.complete(result);
}
}
} }
@Override @Override
public boolean canCopy(DataObject srcData, DataObject destData) { public boolean canCopy(DataObject srcData, DataObject destData) {
//BUG fix for CLOUDSTACK-4618
DataStore store = destData.getDataStore();
if (store.getRole() == DataStoreRole.Primary) {
if ((srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.TEMPLATE) ||
(srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME)) {
StoragePoolVO storagePoolVO = primaryStoreDao.findById(store.getId());
if (storagePoolVO != null && storagePoolVO.getPoolType() == Storage.StoragePoolType.CLVM) {
return true;
}
}
}
return false; return false;
} }

View File

@ -42,11 +42,11 @@ fi
is_lv() { is_lv() {
# Must be a block device # Must be a block device
if [ -b "${1}" ]; then if [ -b "${1}" -o -L "{1}" ]; then
# But not a volume group or physical volume # But not a volume group or physical volume
lvm vgs "${1}" > /dev/null 2>&1 && return 1 lvm vgs "${1}" > /dev/null 2>&1 && return 1
# And a logical volume # And a logical volume
lvm lvs "${1}" > /dev/null 2>&1 && return 0 lvm lvs "${1}" > /dev/null 2>&1 && return 1
fi fi
return 0 return 0
} }