Summary: Direct template imaging for CLVM, bypass copy template to primary

Detail: Because of the way most other primary storage types work with cloudstack
   (i.e. backing stores) CLVM actually copies the template to a local logical
   volume on primary storage, then uses that. This causes all of your primary
   storage to be littered with a copy of every template used. Since we're not
   using these, dump the template direct to the newly created logical volume.
   This is faster as well since the template is sparse; we're not creating a fat
   template on primary storage and then copying that to a logical volume when we
   deploy from template.

BUG-ID: CLOUDSTACK-508
Bugfix-for: 4.1
Signed-off-by: Marcus Sorensen <marcus@betterservers.com> 1353221260 -0700
This commit is contained in:
Marcus Sorensen 2012-11-17 23:47:39 -07:00
parent bbb2a56acb
commit 88180fc139
2 changed files with 89 additions and 13 deletions

View File

@ -1190,11 +1190,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements
disksize = dskch.getSize();
if (cmd.getTemplateUrl() != null) {
BaseVol = primaryPool.getPhysicalDisk(cmd.getTemplateUrl());
vol = _storagePoolMgr.createDiskFromTemplate(BaseVol, UUID
if(primaryPool.getType() == StoragePoolType.CLVM) {
vol = templateToPrimaryDownload(cmd.getTemplateUrl(),primaryPool);
} else {
BaseVol = primaryPool.getPhysicalDisk(cmd.getTemplateUrl());
vol = _storagePoolMgr.createDiskFromTemplate(BaseVol, UUID
.randomUUID().toString(), primaryPool);
}
if (vol == null) {
return new Answer(cmd, false,
" Can't create storage volume on storage pool");
@ -1213,6 +1215,55 @@ public class LibvirtComputingResource extends ServerResourceBase implements
}
}
// this is much like PrimaryStorageDownloadCommand, but keeping it separate
protected KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool) {
int index = templateUrl.lastIndexOf("/");
String mountpoint = templateUrl.substring(0, index);
String templateName = null;
if (index < templateUrl.length() - 1) {
templateName = templateUrl.substring(index + 1);
}
KVMPhysicalDisk templateVol = null;
KVMStoragePool secondaryPool = null;
try {
secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint);
/* Get template vol */
if (templateName == null) {
secondaryPool.refresh();
List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
if (disks == null || disks.isEmpty()) {
s_logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid());
return null;
}
for (KVMPhysicalDisk disk : disks) {
if (disk.getName().endsWith("qcow2")) {
templateVol = disk;
break;
}
}
if (templateVol == null) {
s_logger.error("Failed to get template from pool: " + secondaryPool.getUuid());
return null;
}
} else {
templateVol = secondaryPool.getPhysicalDisk(templateName);
}
/* Copy volume to primary storage */
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), primaryPool);
return primaryVol;
} catch (CloudRuntimeException e) {
s_logger.error("Failed to download template to primary storage",e);
return null;
} finally {
if (secondaryPool != null) {
secondaryPool.delete();
}
}
}
public Answer execute(DestroyCommand cmd) {
VolumeTO vol = cmd.getVolume();

View File

@ -835,11 +835,23 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
for (int i = 0; i < 2; i++) {
if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
if (tmpltStoredOn == null) {
continue;
if (pool.getPoolType() == StoragePoolType.CLVM) {
//prepareISOForCreate does what we need, which is to tell us where the template is
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
if (tmpltHostOn == null) {
continue;
}
HostVO secondaryStorageHost = _hostDao.findById(tmpltHostOn.getHostId());
String tmpltHostUrl = secondaryStorageHost.getStorageUrl();
String fullTmpltUrl = tmpltHostUrl + "/" + tmpltHostOn.getInstallPath();
cmd = new CreateCommand(dskCh, fullTmpltUrl, new StorageFilerTO(pool));
} else {
tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
if (tmpltStoredOn == null) {
continue;
}
cmd = new CreateCommand(dskCh, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
}
cmd = new CreateCommand(dskCh, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
} else {
if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO == template.getFormat()) {
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
@ -3434,12 +3446,25 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
for (int i = 0; i < 2; i++) {
if (template != null && template.getFormat() != Storage.ImageFormat.ISO) {
tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
if (tmpltStoredOn == null) {
s_logger.debug("Cannot use this pool " + pool + " because we can't propagate template " + template);
return null;
if (pool.getPoolType() == StoragePoolType.CLVM) {
//prepareISOForCreate does what we need, which is to tell us where the template is
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
if (tmpltHostOn == null) {
s_logger.debug("cannot find template " + template.getId() + " " + template.getName());
return null;
}
HostVO secondaryStorageHost = _hostDao.findById(tmpltHostOn.getHostId());
String tmpltHostUrl = secondaryStorageHost.getStorageUrl();
String fullTmpltUrl = tmpltHostUrl + "/" + tmpltHostOn.getInstallPath();
cmd = new CreateCommand(diskProfile, fullTmpltUrl, new StorageFilerTO(pool));
} else {
tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
if (tmpltStoredOn == null) {
s_logger.debug("Cannot use this pool " + pool + " because we can't propagate template " + template);
return null;
}
cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
}
cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
} else {
if (template != null && Storage.ImageFormat.ISO == template.getFormat()) {
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);