Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ public class SnapshotObjectTO extends DownloadableObjectTO implements DataTO {
private Long physicalSize = (long) 0;
private long accountId;


public SnapshotObjectTO() {

}

public SnapshotObjectTO(SnapshotInfo snapshot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,13 +358,16 @@ public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answe
if (answer instanceof CreateObjectAnswer) {
SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CreateObjectAnswer)answer).getData();
snapshotStore.setInstallPath(snapshotTO.getPath());
if (snapshotTO.getPhysicalSize() != null && snapshotTO.getPhysicalSize() > 0L) {
snapshotStore.setPhysicalSize(snapshotTO.getPhysicalSize());
}
snapshotStoreDao.update(snapshotStore.getId(), snapshotStore);
} else if (answer instanceof CopyCmdAnswer) {
SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CopyCmdAnswer)answer).getNewData();
snapshotStore.setInstallPath(snapshotTO.getPath());
if (snapshotTO.getPhysicalSize() != null) {
// For S3 delta snapshot, physical size is currently not set
snapshotStore.setPhysicalSize(snapshotTO.getPhysicalSize());
snapshotStore.setPhysicalSize(snapshotTO.getPhysicalSize());
}
if (snapshotTO.getParentSnapshotPath() == null) {
snapshotStore.setParentSnapshotId(0L);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,7 @@ protected static boolean isInterface(final String fname) {
for (final String ifNamePattern : ifNamePatterns) {
commonPattern.append("|(").append(ifNamePattern).append(".*)");
}
if(fname.matches(commonPattern.toString())) {
if (fname.matches(commonPattern.toString())) {
return true;
}
return false;
Expand Down Expand Up @@ -2128,11 +2128,10 @@ private String getBroadcastUriFromBridge(final String brName) {
final Pattern pattern = Pattern.compile("(\\D+)(\\d+)(\\D*)(\\d*)(\\D*)(\\d*)");
final Matcher matcher = pattern.matcher(pif);
LOGGER.debug("getting broadcast uri for pif " + pif + " and bridge " + brName);
if(matcher.find()) {
if (matcher.find()) {
if (brName.startsWith("brvx")){
return BroadcastDomainType.Vxlan.toUri(matcher.group(2)).toString();
}
else{
} else {
if (!matcher.group(6).isEmpty()) {
return BroadcastDomainType.Vlan.toUri(matcher.group(6)).toString();
} else if (!matcher.group(4).isEmpty()) {
Expand Down Expand Up @@ -3331,7 +3330,7 @@ public int compare(final DiskTO arg0, final DiskTO arg1) {
} else if (volume.getType() == Volume.Type.DATADISK) {
final KVMPhysicalDisk physicalDisk = storagePoolManager.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath());
final KVMStoragePool pool = physicalDisk.getPool();
if(StoragePoolType.RBD.equals(pool.getType())) {
if (StoragePoolType.RBD.equals(pool.getType())) {
final int devId = volume.getDiskSeq().intValue();
final String device = mapRbdDevice(physicalDisk);
if (device != null) {
Expand Down Expand Up @@ -4778,7 +4777,7 @@ protected long getMemoryFreeInKBs(Domain dm) throws LibvirtException {
}

for (int i = 0; i < memoryStats.length; i++) {
if(memoryStats[i].getTag() == UNUSEDMEMORY) {
if (memoryStats[i].getTag() == UNUSEDMEMORY) {
freeMemory = memoryStats[i].getValue();
break;
}
Expand Down Expand Up @@ -5244,12 +5243,12 @@ public HypervisorType getHypervisorType(){
return hypervisorType;
}

public String mapRbdDevice(final KVMPhysicalDisk disk){
public String mapRbdDevice(final KVMPhysicalDisk disk) {
final KVMStoragePool pool = disk.getPool();
//Check if rbd image is already mapped
final String[] splitPoolImage = disk.getPath().split("/");
String device = Script.runSimpleBashScript("rbd showmapped | grep \""+splitPoolImage[0]+"[ ]*"+splitPoolImage[1]+"\" | grep -o \"[^ ]*[ ]*$\"");
if(device == null) {
if (device == null) {
//If not mapped, map and return mapped device
Script.runSimpleBashScript("rbd map " + disk.getPath() + " --id " + pool.getAuthUserName());
device = Script.runSimpleBashScript("rbd showmapped | grep \""+splitPoolImage[0]+"[ ]*"+splitPoolImage[1]+"\" | grep -o \"[^ ]*[ ]*$\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@

import javax.naming.ConfigurationException;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.cloudstack.agent.directdownload.DirectDownloadAnswer;
import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
import org.apache.cloudstack.direct.download.DirectDownloadHelper;
Expand Down Expand Up @@ -305,7 +308,7 @@ public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
newTemplate.setPath(primaryVol.getName());
newTemplate.setSize(primaryVol.getSize());

if(List.of(
if (List.of(
StoragePoolType.RBD,
StoragePoolType.PowerFlex,
StoragePoolType.Linstor,
Expand Down Expand Up @@ -696,7 +699,7 @@ public Answer createTemplateFromVolume(final CopyCommand cmd) {
templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");


try(FileOutputStream templFo = new FileOutputStream(templateProp);){
try (FileOutputStream templFo = new FileOutputStream(templateProp);) {
templFo.write(templateContent.getBytes());
templFo.flush();
} catch (final IOException e) {
Expand Down Expand Up @@ -761,11 +764,9 @@ private Answer createTemplateFromVolumeOrSnapshot(CopyCommand cmd) {

if (srcData instanceof VolumeObjectTO) {
isVolume = true;
}
else if (srcData instanceof SnapshotObjectTO) {
} else if (srcData instanceof SnapshotObjectTO) {
isVolume = false;
}
else {
} else {
return new CopyCmdAnswer("unsupported object type");
}

Expand Down Expand Up @@ -831,8 +832,7 @@ else if (srcData instanceof SnapshotObjectTO) {

if (isVolume) {
templateContent += "volume.name=" + dateFormat.format(date) + System.getProperty("line.separator");
}
else {
} else {
templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");
}

Expand Down Expand Up @@ -870,8 +870,7 @@ else if (srcData instanceof SnapshotObjectTO) {
} catch (Exception ex) {
if (isVolume) {
logger.debug("Failed to create template from volume: ", ex);
}
else {
} else {
logger.debug("Failed to create template from snapshot: ", ex);
}

Expand Down Expand Up @@ -1034,7 +1033,7 @@ public Answer backupSnapshot(final CopyCommand cmd) {
q.convert(srcFile, destFile);

final File snapFile = new File(snapshotFile);
if(snapFile.exists()) {
if (snapFile.exists()) {
size = snapFile.length();
}

Expand Down Expand Up @@ -1067,7 +1066,7 @@ public Answer backupSnapshot(final CopyCommand cmd) {
return new CopyCmdAnswer(result);
}
final File snapFile = new File(snapshotDestPath + "/" + descName);
if(snapFile.exists()){
if (snapFile.exists()) {
size = snapFile.length();
}
}
Expand Down Expand Up @@ -1404,7 +1403,7 @@ protected synchronized void attachOrDetachDisk(final Connect conn, final boolean
if (resource.getHypervisorType() == Hypervisor.HypervisorType.LXC) {
final String device = resource.mapRbdDevice(attachingDisk);
if (device != null) {
logger.debug("RBD device on host is: "+device);
logger.debug("RBD device on host is: " + device);
attachingDisk.setPath(device);
}
}
Expand Down Expand Up @@ -1441,11 +1440,11 @@ protected synchronized void attachOrDetachDisk(final Connect conn, final boolean
}
diskdef.setSerial(serial);
if (attachingPool.getType() == StoragePoolType.RBD) {
if(resource.getHypervisorType() == Hypervisor.HypervisorType.LXC){
if (resource.getHypervisorType() == Hypervisor.HypervisorType.LXC) {
// For LXC, map image to host and then attach to Vm
final String device = resource.mapRbdDevice(attachingDisk);
if (device != null) {
logger.debug("RBD device on host is: "+device);
logger.debug("RBD device on host is: " + device);
diskdef.defBlockBasedDisk(device, devId, busT);
} else {
throw new InternalErrorException("Error while mapping disk "+attachingDisk.getPath()+" on host");
Expand Down Expand Up @@ -1515,7 +1514,7 @@ protected synchronized void attachOrDetachDisk(final Connect conn, final boolean
if ((iopsWriteRateMaxLength != null) && (iopsWriteRateMaxLength > 0)) {
diskdef.setIopsWriteRateMaxLength(iopsWriteRateMaxLength);
}
if(cacheMode != null) {
if (cacheMode != null) {
diskdef.setCacheMode(DiskDef.DiskCacheMode.valueOf(cacheMode.toUpperCase()));
}

Expand Down Expand Up @@ -1675,7 +1674,7 @@ public Answer createVolume(final CreateObjectCommand cmd) {
}

final VolumeObjectTO newVol = new VolumeObjectTO();
if(vol != null) {
if (vol != null) {
newVol.setPath(vol.getName());
if (vol.getQemuEncryptFormat() != null) {
newVol.setEncryptFormat(vol.getQemuEncryptFormat().toString());
Expand Down Expand Up @@ -1778,6 +1777,7 @@ public Answer createSnapshot(final CreateObjectCommand cmd) {

String diskPath = disk.getPath();
String snapshotPath = diskPath + File.separator + snapshotName;
Long snapshotSize = null;
if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) {

validateAvailableSizeOnPoolToTakeVolumeSnapshot(primaryPool, disk);
Expand Down Expand Up @@ -1838,6 +1838,11 @@ public Answer createSnapshot(final CreateObjectCommand cmd) {
logger.debug("Attempting to create RBD snapshot " + disk.getName() + "@" + snapshotName);
image.snapCreate(snapshotName);

long rbdSnapshotSize = getRbdSnapshotSize(primaryPool.getSourceDir(), disk.getName(), snapshotName, primaryPool.getSourceHost(), primaryPool.getAuthUserName(), primaryPool.getAuthSecret());
if (rbdSnapshotSize > 0) {
snapshotSize = rbdSnapshotSize;
}

rbd.close(image);
r.ioCtxDestroy(io);
} catch (final Exception e) {
Expand All @@ -1861,8 +1866,11 @@ public Answer createSnapshot(final CreateObjectCommand cmd) {
}

final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();

newSnapshot.setPath(snapshotPath);
if (snapshotSize != null) {
newSnapshot.setPhysicalSize(snapshotSize);
}

return new CreateObjectAnswer(newSnapshot);
} catch (CloudRuntimeException | LibvirtException | IOException ex) {
String errorMsg = String.format("Failed take snapshot for volume [%s], in VM [%s], due to [%s].", volume, vmName, ex.getMessage());
Expand All @@ -1873,6 +1881,31 @@ public Answer createSnapshot(final CreateObjectCommand cmd) {
}
}

private long getRbdSnapshotSize(String poolPath, String diskName, String snapshotName, String rbdMonitor, String authUser, String authSecret) {
logger.debug("Get RBD snapshot size for {}/{}@{}", poolPath, diskName, snapshotName);
//cmd: rbd du <pool>/<disk-name>@<snapshot-name> --format json --mon-host <monitor-host> --id <user> --key <key> 2>/dev/null
String snapshotDetailsInJson = Script.runSimpleBashScript(String.format("rbd du %s/%s@%s --format json --mon-host %s --id %s --key %s 2>/dev/null", poolPath, diskName, snapshotName, rbdMonitor, authUser, authSecret));
if (StringUtils.isNotBlank(snapshotDetailsInJson)) {
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode root = mapper.readTree(snapshotDetailsInJson);
for (JsonNode image : root.path("images")) {
if (snapshotName.equals(image.path("snapshot").asText())) {
long usedSizeInBytes = image.path("used_size").asLong();
logger.debug("RBD snapshot {}/{}@{} used size in bytes: {}", poolPath, diskName, snapshotName, usedSizeInBytes);
return usedSizeInBytes;
}
}
} catch (JsonProcessingException e) {
logger.error("Unable to get the RBD snapshot size, RBD snapshot cmd output: {}", snapshotDetailsInJson, e);
}
} else {
logger.warn("Failed to get RBD snapshot size for {}/{}@{} - no output for RBD snapshot cmd", poolPath, diskName, snapshotName);
}

return 0;
}

protected void deleteFullVmSnapshotAfterConvertingItToExternalDiskSnapshot(Domain vm, String snapshotName, VolumeObjectTO volume, String vmName) throws LibvirtException {
logger.debug(String.format("Deleting full Instance Snapshot [%s] of Instance [%s] as we already converted it to an external disk Snapshot of the volume [%s].", snapshotName, vmName,
volume));
Expand Down
Loading