CLOUDSTACK-4641: fix create volume from snapshot timeout issue

This commit is contained in:
Edison Su 2013-09-11 18:07:47 -07:00
parent 5950d37e9f
commit c08254bc70
8 changed files with 65 additions and 53 deletions

View File

@ -80,4 +80,8 @@ public final class CopyCommand extends Command implements StorageSubSystemComman
this.cacheTO = cacheTO;
}
public int getWaitInMillSeconds() {
return this.getWait() * 1000;
}
}

View File

@ -1367,7 +1367,7 @@ ServerResource {
secondaryStorageUrl
+ volumeDestPath);
_storagePoolMgr.copyPhysicalDisk(volume,
destVolumeName,secondaryStoragePool);
destVolumeName,secondaryStoragePool, 0);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
} else {
volumePath = "/volumes/" + cmd.getVolumeId() + File.separator;
@ -1377,7 +1377,7 @@ ServerResource {
KVMPhysicalDisk volume = secondaryStoragePool
.getPhysicalDisk(cmd.getVolumePath() + ".qcow2");
_storagePoolMgr.copyPhysicalDisk(volume, volumeName,
primaryPool);
primaryPool, 0);
return new CopyVolumeAnswer(cmd, true, null, null, volumeName);
}
} catch (CloudRuntimeException e) {
@ -1463,7 +1463,7 @@ ServerResource {
} else {
BaseVol = primaryPool.getPhysicalDisk(cmd.getTemplateUrl());
vol = _storagePoolMgr.createDiskFromTemplate(BaseVol, UUID
.randomUUID().toString(), primaryPool);
.randomUUID().toString(), primaryPool, 0);
}
if (vol == null) {
return new Answer(cmd, false,
@ -1524,7 +1524,7 @@ ServerResource {
/* Copy volume to primary storage */
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), primaryPool);
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), primaryPool, 0);
return primaryVol;
} catch (CloudRuntimeException e) {
s_logger.error("Failed to download template to primary storage",e);
@ -2381,7 +2381,7 @@ ServerResource {
primaryUuid);
String volUuid = UUID.randomUUID().toString();
KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot,
volUuid, primaryPool);
volUuid, primaryPool, 0);
return new CreateVolumeFromSnapshotAnswer(cmd, true, "",
disk.getName());
} catch (CloudRuntimeException e) {
@ -2532,7 +2532,7 @@ ServerResource {
QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + cmd.getUniqueName() + ".qcow2");
destFile.setFormat(PhysicalDiskFormat.QCOW2);
QemuImg q = new QemuImg();
QemuImg q = new QemuImg(0);
try {
q.convert(srcFile, destFile);
} catch (QemuImgException e) {
@ -2635,7 +2635,7 @@ ServerResource {
cmd.getPoolUuid());
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(
tmplVol, UUID.randomUUID().toString(), primaryPool);
tmplVol, UUID.randomUUID().toString(), primaryPool, 0);
return new PrimaryStorageDownloadAnswer(primaryVol.getName(),
primaryVol.getSize());

View File

@ -206,25 +206,25 @@ public class KVMStoragePoolManager {
}
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name,
KVMStoragePool destPool) {
KVMStoragePool destPool, int timeout) {
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
// LibvirtStorageAdaptor-specific statement
if (destPool.getType() == StoragePoolType.RBD) {
return adaptor.createDiskFromTemplate(template, name,
PhysicalDiskFormat.RAW, template.getSize(), destPool);
PhysicalDiskFormat.RAW, template.getSize(), destPool, timeout);
} else if (destPool.getType() == StoragePoolType.CLVM) {
return adaptor.createDiskFromTemplate(template, name,
PhysicalDiskFormat.RAW, template.getSize(),
destPool);
destPool, timeout);
} else if (template.getFormat() == PhysicalDiskFormat.DIR) {
return adaptor.createDiskFromTemplate(template, name,
PhysicalDiskFormat.DIR,
template.getSize(), destPool);
template.getSize(), destPool, timeout);
} else {
return adaptor.createDiskFromTemplate(template, name,
PhysicalDiskFormat.QCOW2,
template.getSize(), destPool);
template.getSize(), destPool, timeout);
}
}
@ -237,9 +237,9 @@ public class KVMStoragePoolManager {
}
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name,
KVMStoragePool destPool) {
KVMStoragePool destPool, int timeout) {
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
return adaptor.copyPhysicalDisk(disk, name, destPool);
return adaptor.copyPhysicalDisk(disk, name, destPool, timeout);
}
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,

View File

@ -194,7 +194,7 @@ public class KVMStorageProcessor implements StorageProcessor {
primaryStore.getUuid());
KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(),
primaryPool);
primaryPool, cmd.getWaitInMillSeconds());
DataTO data = null;
@ -232,7 +232,7 @@ public class KVMStorageProcessor implements StorageProcessor {
}
// this is much like PrimaryStorageDownloadCommand, but keeping it separate
private KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool) {
private KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool, int timeout) {
int index = templateUrl.lastIndexOf("/");
String mountpoint = templateUrl.substring(0, index);
String templateName = null;
@ -269,7 +269,7 @@ public class KVMStorageProcessor implements StorageProcessor {
/* Copy volume to primary storage */
KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(),
primaryPool);
primaryPool, timeout);
return primaryVol;
} catch (CloudRuntimeException e) {
s_logger.error("Failed to download template to primary storage", e);
@ -300,14 +300,14 @@ public class KVMStorageProcessor implements StorageProcessor {
if (primaryPool.getType() == StoragePoolType.CLVM) {
templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
vol = templateToPrimaryDownload(templatePath, primaryPool);
vol = templateToPrimaryDownload(templatePath, primaryPool, cmd.getWaitInMillSeconds());
} else {
if (templatePath.contains("/mnt")) {
//upgrade issue, if the path contains path, need to extract the volume uuid from path
templatePath = templatePath.substring(templatePath.lastIndexOf(File.separator) + 1);
}
BaseVol = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath);
vol = storagePoolMgr.createDiskFromTemplate(BaseVol, UUID.randomUUID().toString(), BaseVol.getPool());
vol = storagePoolMgr.createDiskFromTemplate(BaseVol, UUID.randomUUID().toString(), BaseVol.getPool(), cmd.getWaitInMillSeconds());
}
if (vol == null) {
return new CopyCmdAnswer(" Can't create storage volume on storage pool");
@ -378,7 +378,7 @@ public class KVMStorageProcessor implements StorageProcessor {
.getPhysicalDisk(srcVolumeName);
volume.setFormat(PhysicalDiskFormat.valueOf(srcFormat.toString()));
KVMPhysicalDisk newDisk = storagePoolMgr.copyPhysicalDisk(volume, volumeName,
primaryPool);
primaryPool, cmd.getWaitInMillSeconds());
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setFormat(ImageFormat.valueOf(newDisk.getFormat().toString().toUpperCase()));
newVol.setPath(volumeName);
@ -425,7 +425,7 @@ public class KVMStorageProcessor implements StorageProcessor {
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(
secondaryStorageUrl + File.separator + destVolumePath);
storagePoolMgr.copyPhysicalDisk(volume,
destVolumeName,secondaryStoragePool);
destVolumeName,secondaryStoragePool, cmd.getWaitInMillSeconds());
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(destVolumePath + File.separator + destVolumeName);
newVol.setFormat(destFormat);
@ -443,7 +443,7 @@ public class KVMStorageProcessor implements StorageProcessor {
public Answer createTemplateFromVolume(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
DataTO destData = cmd.getDestTO();
int wait = cmd.getWait();
int wait = cmd.getWaitInMillSeconds();
TemplateObjectTO template = (TemplateObjectTO) destData;
DataStoreTO imageStore = template.getDataStore();
VolumeObjectTO volume = (VolumeObjectTO) srcData;
@ -469,7 +469,7 @@ public class KVMStorageProcessor implements StorageProcessor {
String templateName = UUID.randomUUID().toString();
if (primary.getType() != StoragePoolType.RBD) {
Script command = new Script(_createTmplPath, wait * 1000, s_logger);
Script command = new Script(_createTmplPath, wait, s_logger);
command.add("-f", disk.getPath());
command.add("-t", tmpltPath);
command.add("-n", templateName + ".qcow2");
@ -490,7 +490,7 @@ public class KVMStorageProcessor implements StorageProcessor {
QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + templateName + ".qcow2");
destFile.setFormat(PhysicalDiskFormat.QCOW2);
QemuImg q = new QemuImg();
QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
try {
q.convert(srcFile, destFile);
} catch (QemuImgException e) {
@ -618,7 +618,7 @@ public class KVMStorageProcessor implements StorageProcessor {
SnapshotObjectTO snapshotOnCacheStore = (SnapshotObjectTO)answer.getNewData();
snapshotOnCacheStore.setDataStore(cacheStore);
((SnapshotObjectTO) destData).setDataStore(imageStore);
CopyCommand newCpyCmd = new CopyCommand(snapshotOnCacheStore, destData, cmd.getWait(), cmd.executeInSequence());
CopyCommand newCpyCmd = new CopyCommand(snapshotOnCacheStore, destData, cmd.getWaitInMillSeconds(), cmd.executeInSequence());
return copyToObjectStore(newCpyCmd);
}
@Override
@ -722,7 +722,7 @@ public class KVMStorageProcessor implements StorageProcessor {
return new CopyCmdAnswer(e.toString());
}
} else {
Script command = new Script(_manageSnapshotPath, cmd.getWait() * 1000, s_logger);
Script command = new Script(_manageSnapshotPath, cmd.getWaitInMillSeconds(), s_logger);
command.add("-b", snapshotDisk.getPath());
command.add("-n", snapshotName);
command.add("-p", snapshotDestPath);
@ -1184,7 +1184,7 @@ public class KVMStorageProcessor implements StorageProcessor {
String primaryUuid = pool.getUuid();
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getPoolType(), primaryUuid);
String volUuid = UUID.randomUUID().toString();
KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, volUuid, primaryPool);
KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, volUuid, primaryPool, cmd.getWaitInMillSeconds());
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(disk.getName());
newVol.setSize(disk.getVirtualSize());

View File

@ -766,7 +766,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
*/
@Override
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool) {
String name, PhysicalDiskFormat format, long size, KVMStoragePool destPool, int timeout) {
String newUuid = UUID.randomUUID().toString();
KVMStoragePool srcPool = template.getPool();
@ -783,20 +783,20 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
if (destPool.getType() != StoragePoolType.RBD) {
disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize());
if (template.getFormat() == PhysicalDiskFormat.TAR) {
Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath());
Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath(), timeout);
} else if (template.getFormat() == PhysicalDiskFormat.DIR) {
Script.runSimpleBashScript("mkdir -p " + disk.getPath());
Script.runSimpleBashScript("chmod 755 " + disk.getPath());
Script.runSimpleBashScript("cp -p -r " + template.getPath() + "/* " + disk.getPath());
Script.runSimpleBashScript("cp -p -r " + template.getPath() + "/* " + disk.getPath(), timeout);
} else if (format == PhysicalDiskFormat.QCOW2) {
QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
QemuImgFile destFile = new QemuImgFile(disk.getPath());
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(timeout);
qemu.create(destFile, backingFile);
} else if (format == PhysicalDiskFormat.RAW) {
QemuImgFile sourceFile = new QemuImgFile(template.getPath(), template.getFormat());
QemuImgFile destFile = new QemuImgFile(disk.getPath(), PhysicalDiskFormat.RAW);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(timeout);
qemu.convert(sourceFile, destFile);
}
} else {
@ -806,7 +806,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
disk.setSize(template.getVirtualSize());
disk.setVirtualSize(disk.getSize());
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(timeout);
QemuImgFile srcFile;
QemuImgFile destFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(),
destPool.getSourcePort(),
@ -960,7 +960,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
*/
@Override
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name,
KVMStoragePool destPool) {
KVMStoragePool destPool, int timeout) {
/**
With RBD you can't run qemu-img convert with an existing RBD image as destination
@ -999,24 +999,27 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
String destPath = newDisk.getPath();
PhysicalDiskFormat destFormat = newDisk.getFormat();
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(timeout);
QemuImgFile srcFile = null;
QemuImgFile destFile = null;
if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
if (sourceFormat == PhysicalDiskFormat.TAR) {
Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath);
Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath, timeout);
} else if (sourceFormat == PhysicalDiskFormat.DIR) {
Script.runSimpleBashScript("mkdir -p " + destPath);
Script.runSimpleBashScript("chmod 755 " + destPath);
Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath);
Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath, timeout);
} else {
srcFile = new QemuImgFile(sourcePath, sourceFormat);
try {
Map<String, String> info = qemu.info(srcFile);
String backingFile = info.get(new String("backing_file"));
if (sourceFormat.equals(destFormat) && backingFile == null) {
Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath);
String result = Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath, timeout);
if (result != null) {
throw new CloudRuntimeException("Failed to create disk: " + result);
}
} else {
destFile = new QemuImgFile(destPath, destFormat);
try {

View File

@ -40,7 +40,7 @@ public interface StorageAdaptor {
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
String name, PhysicalDiskFormat format, long size,
KVMStoragePool destPool);
KVMStoragePool destPool, int timeout);
public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk,
String name, PhysicalDiskFormat format, long size,
@ -50,7 +50,7 @@ public interface StorageAdaptor {
KVMStoragePool pool);
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name,
KVMStoragePool destPools);
KVMStoragePool destPools, int timeout);
public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot,
String snapshotName, String name, KVMStoragePool destPool);

View File

@ -31,6 +31,7 @@ public class QemuImg {
/* The qemu-img binary. We expect this to be in $PATH */
public String _qemuImgPath = "qemu-img";
private int timeout;
/* Shouldn't we have KVMPhysicalDisk and LibvirtVMDef read this? */
public static enum PhysicalDiskFormat {
@ -46,8 +47,12 @@ public class QemuImg {
}
}
public QemuImg() {
public QemuImg(int timeout) {
this.timeout = timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
/**
@ -84,7 +89,7 @@ public class QemuImg {
* @return void
*/
public void create(QemuImgFile file, QemuImgFile backingFile, Map<String, String> options) throws QemuImgException {
Script s = new Script(_qemuImgPath);
Script s = new Script(_qemuImgPath, timeout);
s.add("create");
if (options != null && !options.isEmpty()) {
@ -181,7 +186,7 @@ public class QemuImg {
* @return void
*/
public void convert(QemuImgFile srcFile, QemuImgFile destFile, Map<String, String> options) throws QemuImgException {
Script s = new Script(_qemuImgPath);
Script s = new Script(_qemuImgPath, timeout);
s.add("convert");
s.add("-f");
s.add(srcFile.getFormat().toString());

View File

@ -38,7 +38,7 @@ public class QemuImgTest {
long size = 10995116277760l;
QemuImgFile file = new QemuImgFile(filename, size, PhysicalDiskFormat.QCOW2);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
Map<String, String> info = qemu.info(file);
@ -69,7 +69,7 @@ public class QemuImgTest {
options.put("cluster_size", clusterSize);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file, options);
Map<String, String> info = qemu.info(file);
@ -96,7 +96,7 @@ public class QemuImgTest {
QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.QCOW2);
try {
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
qemu.resize(file, endSize);
Map<String, String> info = qemu.info(file);
@ -125,7 +125,7 @@ public class QemuImgTest {
QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.RAW);
try {
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
qemu.resize(file, increment, true);
Map<String, String> info = qemu.info(file);
@ -153,7 +153,7 @@ public class QemuImgTest {
QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.RAW);
try {
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
qemu.resize(file, increment, true);
Map<String, String> info = qemu.info(file);
@ -182,7 +182,7 @@ public class QemuImgTest {
long endSize = -1;
QemuImgFile file = new QemuImgFile(filename, startSize, PhysicalDiskFormat.QCOW2);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
try {
qemu.create(file);
qemu.resize(file, endSize);
@ -199,7 +199,7 @@ public class QemuImgTest {
long startSize = 20480;
QemuImgFile file = new QemuImgFile(filename, 20480, PhysicalDiskFormat.QCOW2);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(file);
qemu.resize(file, 0);
@ -216,7 +216,7 @@ public class QemuImgTest {
QemuImgFile firstFile = new QemuImgFile(firstFileName, 20480, PhysicalDiskFormat.QCOW2);
QemuImgFile secondFile = new QemuImgFile(secondFileName, PhysicalDiskFormat.QCOW2);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(firstFile);
qemu.create(secondFile, firstFile);
@ -240,7 +240,7 @@ public class QemuImgTest {
QemuImgFile srcFile = new QemuImgFile(srcFileName, srcSize);
QemuImgFile destFile = new QemuImgFile(destFileName);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(srcFile);
qemu.convert(srcFile, destFile);
Map<String, String> info = qemu.info(destFile);
@ -267,7 +267,7 @@ public class QemuImgTest {
QemuImgFile srcFile = new QemuImgFile(srcFileName, srcSize, srcFormat);
QemuImgFile destFile = new QemuImgFile(destFileName, destFormat);
QemuImg qemu = new QemuImg();
QemuImg qemu = new QemuImg(0);
qemu.create(srcFile);
qemu.convert(srcFile, destFile);