Skip to content

Commit bdfddc3

Browse files
committed
CLOUDSTACK-4398: get physical size of template if the template is stored in S3
1 parent ae7ec64 commit bdfddc3

7 files changed

Lines changed: 106 additions & 1 deletion

File tree

core/src/com/cloud/storage/template/IsoProcessor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public FormatInfo process(String templatePath, ImageFormat format, String templa
5757
return info;
5858
}
5959

60+
@Override
61+
public Long getVirtualSize(File file) {
62+
return file.length();
63+
}
64+
6065
@Override
6166
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
6267
_storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);

core/src/com/cloud/storage/template/Processor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import com.cloud.storage.Storage.ImageFormat;
2121
import com.cloud.utils.component.Adapter;
2222

23+
import java.io.File;
24+
2325
/**
2426
* Generic interface to process different types of image formats
2527
* for templates downloaded and for conversion from one format
@@ -45,4 +47,7 @@ public static class FormatInfo {
4547
public String filename;
4648
public boolean isCorrupted;
4749
}
50+
51+
Long getVirtualSize(File file);
52+
4853
}

core/src/com/cloud/storage/template/QCOW2Processor.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,29 @@ public FormatInfo process(String templatePath, ImageFormat format,
8282
return info;
8383
}
8484

85+
public Long getVirtualSize(File file) {
86+
FileInputStream strm = null;
87+
byte[] b = new byte[8];
88+
try {
89+
strm = new FileInputStream(file);
90+
strm.skip(24);
91+
strm.read(b);
92+
} catch (Exception e) {
93+
s_logger.warn("Unable to read qcow2 file " + file, e);
94+
return null;
95+
} finally {
96+
if (strm != null) {
97+
try {
98+
strm.close();
99+
} catch (IOException e) {
100+
}
101+
}
102+
}
103+
104+
long templateSize = NumbersUtil.bytesToLong(b);
105+
return templateSize;
106+
}
107+
85108
@Override
86109
public boolean configure(String name, Map<String, Object> params)
87110
throws ConfigurationException {

core/src/com/cloud/storage/template/RawImageProcessor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,9 @@ public FormatInfo process(String templatePath, ImageFormat format,
6868
return info;
6969
}
7070

71+
@Override
72+
public Long getVirtualSize(File file) {
73+
return file.length();
74+
}
75+
7176
}

core/src/com/cloud/storage/template/VhdProcessor.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import javax.ejb.Local;
2626
import javax.naming.ConfigurationException;
2727

28+
import com.cloud.utils.exception.CloudRuntimeException;
2829
import org.apache.log4j.Logger;
2930

3031
import com.cloud.exception.InternalErrorException;
@@ -100,6 +101,33 @@ public FormatInfo process(String templatePath, ImageFormat format, String templa
100101
return info;
101102
}
102103

104+
@Override
105+
public Long getVirtualSize(File file) {
106+
FileInputStream strm = null;
107+
byte[] currentSize = new byte[8];
108+
byte[] creatorApp = new byte[4];
109+
try {
110+
strm = new FileInputStream(file);
111+
strm.skip(file.length() - vhd_footer_size + vhd_footer_creator_app_offset);
112+
strm.read(creatorApp);
113+
strm.skip(vhd_footer_current_size_offset - vhd_footer_creator_ver_offset);
114+
strm.read(currentSize);
115+
} catch (Exception e) {
116+
s_logger.warn("Unable to read vhd file " + file.getAbsolutePath(), e);
117+
throw new CloudRuntimeException("Unable to read vhd file " + file.getAbsolutePath() + ": " + e);
118+
} finally {
119+
if (strm != null) {
120+
try {
121+
strm.close();
122+
} catch (IOException e) {
123+
}
124+
}
125+
}
126+
127+
long templateSize = NumbersUtil.bytesToLong(currentSize);
128+
return templateSize;
129+
}
130+
103131
@Override
104132
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
105133
_name = name;

core/src/com/cloud/storage/template/VmdkProcessor.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ public FormatInfo process(String templatePath, ImageFormat format, String templa
8181
return info;
8282
}
8383

84+
@Override
85+
public Long getVirtualSize(File file) {
86+
try {
87+
long size = getTemplateVirtualSize(file.getParent(), file.getName());
88+
return size;
89+
} catch (Exception e) {
90+
91+
}
92+
return file.length();
93+
}
94+
8495
public long getTemplateVirtualSize(String templatePath, String templateName) throws InternalErrorException {
8596
// get the virtual size from the OVF file meta data
8697
long virtualSize=0;

services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, Strin
270270
newTemplTO.setPath(finalDownloadPath);
271271
newTemplTO.setName(finalFileName);
272272
newTemplTO.setSize(size);
273+
newTemplTO.setPhysicalSize(size);
273274
newDestTO = newTemplTO;
274275
} else {
275276
VolumeObjectTO newVolTO = new VolumeObjectTO();
@@ -505,6 +506,7 @@ protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
505506
TemplateObjectTO template = new TemplateObjectTO();
506507
template.setPath(swiftPath);
507508
template.setSize(templateFile.length());
509+
template.setPhysicalSize(template.getSize());
508510
SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
509511
template.setFormat(snapshot.getVolume().getFormat());
510512
return new CopyCmdAnswer(template);
@@ -718,6 +720,31 @@ private ImageFormat getTemplateFormat(String filePath) {
718720

719721
}
720722

723+
protected Long getVirtualSize(File file, ImageFormat format) {
724+
Processor processor = null;
725+
try {
726+
if (format == null) {
727+
return file.length();
728+
} else if (format == ImageFormat.QCOW2) {
729+
processor = new QCOW2Processor();
730+
} else if (format == ImageFormat.OVA) {
731+
processor = new VmdkProcessor();
732+
} else if (format == ImageFormat.VHD) {
733+
processor = new VhdProcessor();
734+
}
735+
736+
if (processor == null) {
737+
return file.length();
738+
}
739+
740+
processor.configure("template processor", new HashMap<String, Object>());
741+
return processor.getVirtualSize(file);
742+
} catch (Exception e) {
743+
s_logger.debug("Failed to get virtual size:" ,e);
744+
}
745+
return file.length();
746+
}
747+
721748
protected Answer copyFromNfsToS3(CopyCommand cmd) {
722749
final DataTO srcData = cmd.getSrcTO();
723750
final DataTO destData = cmd.getDestTO();
@@ -759,7 +786,8 @@ protected Answer copyFromNfsToS3(CopyCommand cmd) {
759786
if (destData.getObjectType() == DataObjectType.TEMPLATE) {
760787
TemplateObjectTO newTemplate = new TemplateObjectTO();
761788
newTemplate.setPath(key);
762-
newTemplate.setSize(srcFile.length());
789+
newTemplate.setSize(getVirtualSize(srcFile, format));
790+
newTemplate.setPhysicalSize(srcFile.length());
763791
newTemplate.setFormat(format);
764792
retObj = newTemplate;
765793
} else if (destData.getObjectType() == DataObjectType.VOLUME) {

0 commit comments

Comments
 (0)