|
21 | 21 |
|
22 | 22 | import java.util.HashMap; |
23 | 23 |
|
| 24 | +import org.apache.cloudstack.utils.qemu.QemuImg; |
| 25 | +import org.apache.cloudstack.utils.qemu.QemuImgException; |
| 26 | +import org.apache.cloudstack.utils.qemu.QemuImgFile; |
| 27 | +import org.apache.commons.lang3.StringUtils; |
| 28 | +import org.apache.logging.log4j.Logger; |
24 | 29 | import org.libvirt.Connect; |
25 | 30 | import org.libvirt.LibvirtException; |
26 | 31 |
|
27 | 32 | import com.cloud.agent.api.Answer; |
| 33 | +import com.cloud.agent.api.GetVolumeStatsAnswer; |
| 34 | +import com.cloud.agent.api.GetVolumeStatsCommand; |
| 35 | +import com.cloud.agent.api.VolumeStatsEntry; |
28 | 36 | import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; |
29 | 37 | import com.cloud.hypervisor.kvm.resource.LibvirtConnection; |
30 | 38 | import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; |
|
33 | 41 | import com.cloud.resource.ResourceWrapper; |
34 | 42 | import com.cloud.storage.Storage.StoragePoolType; |
35 | 43 | import com.cloud.utils.exception.CloudRuntimeException; |
36 | | -import com.cloud.agent.api.GetVolumeStatsAnswer; |
37 | | -import com.cloud.agent.api.GetVolumeStatsCommand; |
38 | | -import com.cloud.agent.api.VolumeStatsEntry; |
| 44 | +import com.google.gson.JsonArray; |
| 45 | +import com.google.gson.JsonElement; |
| 46 | +import com.google.gson.JsonObject; |
| 47 | +import com.google.gson.JsonParser; |
39 | 48 |
|
40 | 49 | @ResourceWrapper(handles = GetVolumeStatsCommand.class) |
41 | 50 | public final class LibvirtGetVolumeStatsCommandWrapper extends CommandWrapper<GetVolumeStatsCommand, Answer, LibvirtComputingResource> { |
@@ -72,6 +81,61 @@ private VolumeStatsEntry getVolumeStat(final LibvirtComputingResource libvirtCom |
72 | 81 | return null; |
73 | 82 | } |
74 | 83 |
|
75 | | - return new VolumeStatsEntry(volumeUuid, sourceKVMVolume.getSize(), sourceKVMVolume.getVirtualSize()); |
| 84 | + VolumeStatsEntry entry = new VolumeStatsEntry(volumeUuid, sourceKVMVolume.getSize(), |
| 85 | + sourceKVMVolume.getVirtualSize()); |
| 86 | + entry.setTotalPhysicalSize(retrieveTotalPhysicalSize(volumeUuid, sourceKVMVolume.getPath(), logger)); |
| 87 | + |
| 88 | + return entry; |
| 89 | + } |
| 90 | + |
| 91 | + |
| 92 | + private static Long retrieveTotalPhysicalSize(String volumeUuid, String volumePath, Logger logger) { |
| 93 | + logger.trace("Retrieving total physical size for volume: {} with path: {}", volumeUuid, volumePath); |
| 94 | + Long totalPhysicalSize = null; |
| 95 | + try { |
| 96 | + QemuImg qemu = new QemuImg(10000); |
| 97 | + QemuImgFile file = new QemuImgFile(volumePath); |
| 98 | + String info = qemu.infoBackingJson(file); |
| 99 | + if (StringUtils.isBlank(info)) { |
| 100 | + logger.debug("Failed to get qemu info for volume: {} as the output is empty"); |
| 101 | + return null; |
| 102 | + } |
| 103 | + totalPhysicalSize = parseTotalActualSize(info, logger); |
| 104 | + if (totalPhysicalSize != null) { |
| 105 | + logger.trace("Total physical size for volume {} is: {}", volumeUuid, totalPhysicalSize); |
| 106 | + } |
| 107 | + } catch (LibvirtException | QemuImgException e) { |
| 108 | + logger.debug("Failed to get qemu info for volume: {} due to: {}", volumeUuid, e.getMessage()); |
| 109 | + } |
| 110 | + return totalPhysicalSize; |
| 111 | + } |
| 112 | + |
| 113 | + private static Long parseTotalActualSize(String json, Logger logger) { |
| 114 | + JsonElement root = JsonParser.parseString(json); |
| 115 | + |
| 116 | + Long total = null; |
| 117 | + |
| 118 | + if (root.isJsonArray()) { |
| 119 | + JsonArray arr = root.getAsJsonArray(); |
| 120 | + for (JsonElement elem : arr) { |
| 121 | + JsonObject obj = elem.getAsJsonObject(); |
| 122 | + if (!obj.has("actual-size")) { |
| 123 | + continue; |
| 124 | + } |
| 125 | + if (total == null) { |
| 126 | + total = 0L; |
| 127 | + } |
| 128 | + total += obj.get("actual-size").getAsLong(); |
| 129 | + } |
| 130 | + } else if (root.isJsonObject()) { |
| 131 | + JsonObject obj = root.getAsJsonObject(); |
| 132 | + if (obj.has("actual-size")) { |
| 133 | + total = obj.get("actual-size").getAsLong(); |
| 134 | + } |
| 135 | + } else { |
| 136 | + logger.debug("Unexpected JSON format when parsing qemu info: {}", json); |
| 137 | + } |
| 138 | + |
| 139 | + return total; |
76 | 140 | } |
77 | 141 | } |
0 commit comments