mirror of https://github.com/apache/cloudstack.git
Merge 905335ec2d into bce3e54a7e
This commit is contained in:
commit
0de590ca75
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -358,13 +358,16 @@ public class SnapshotObject implements SnapshotInfo {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -1836,7 +1836,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
for (final String ifNamePattern : ifNamePatterns) {
|
||||
commonPattern.append("|(").append(ifNamePattern).append(".*)");
|
||||
}
|
||||
if(fname.matches(commonPattern.toString())) {
|
||||
if (fname.matches(commonPattern.toString())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -2128,11 +2128,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
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()) {
|
||||
|
|
@ -3331,7 +3330,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
} 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) {
|
||||
|
|
@ -4778,7 +4777,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
}
|
||||
|
||||
for (int i = 0; i < memoryStats.length; i++) {
|
||||
if(memoryStats[i].getTag() == UNUSEDMEMORY) {
|
||||
if (memoryStats[i].getTag() == UNUSEDMEMORY) {
|
||||
freeMemory = memoryStats[i].getValue();
|
||||
break;
|
||||
}
|
||||
|
|
@ -5244,12 +5243,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||
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 \"[^ ]*[ ]*$\"");
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ import java.util.stream.Collectors;
|
|||
|
||||
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;
|
||||
|
|
@ -305,7 +308,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
newTemplate.setPath(primaryVol.getName());
|
||||
newTemplate.setSize(primaryVol.getSize());
|
||||
|
||||
if(List.of(
|
||||
if (List.of(
|
||||
StoragePoolType.RBD,
|
||||
StoragePoolType.PowerFlex,
|
||||
StoragePoolType.Linstor,
|
||||
|
|
@ -696,7 +699,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
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) {
|
||||
|
|
@ -761,11 +764,9 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
@ -831,8 +832,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
|
||||
if (isVolume) {
|
||||
templateContent += "volume.name=" + dateFormat.format(date) + System.getProperty("line.separator");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator");
|
||||
}
|
||||
|
||||
|
|
@ -870,8 +870,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
} 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);
|
||||
}
|
||||
|
||||
|
|
@ -1034,7 +1033,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
q.convert(srcFile, destFile);
|
||||
|
||||
final File snapFile = new File(snapshotFile);
|
||||
if(snapFile.exists()) {
|
||||
if (snapFile.exists()) {
|
||||
size = snapFile.length();
|
||||
}
|
||||
|
||||
|
|
@ -1067,7 +1066,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
return new CopyCmdAnswer(result);
|
||||
}
|
||||
final File snapFile = new File(snapshotDestPath + "/" + descName);
|
||||
if(snapFile.exists()){
|
||||
if (snapFile.exists()) {
|
||||
size = snapFile.length();
|
||||
}
|
||||
}
|
||||
|
|
@ -1404,7 +1403,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1441,11 +1440,11 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
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");
|
||||
|
|
@ -1515,7 +1514,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
if ((iopsWriteRateMaxLength != null) && (iopsWriteRateMaxLength > 0)) {
|
||||
diskdef.setIopsWriteRateMaxLength(iopsWriteRateMaxLength);
|
||||
}
|
||||
if(cacheMode != null) {
|
||||
if (cacheMode != null) {
|
||||
diskdef.setCacheMode(DiskDef.DiskCacheMode.valueOf(cacheMode.toUpperCase()));
|
||||
}
|
||||
|
||||
|
|
@ -1675,7 +1674,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
|
||||
final VolumeObjectTO newVol = new VolumeObjectTO();
|
||||
if(vol != null) {
|
||||
if (vol != null) {
|
||||
newVol.setPath(vol.getName());
|
||||
if (vol.getQemuEncryptFormat() != null) {
|
||||
newVol.setEncryptFormat(vol.getQemuEncryptFormat().toString());
|
||||
|
|
@ -1778,6 +1777,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
|
||||
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);
|
||||
|
|
@ -1838,6 +1838,11 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
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) {
|
||||
|
|
@ -1861,8 +1866,11 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
|
||||
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());
|
||||
|
|
@ -1873,6 +1881,31 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
|
|
|||
Loading…
Reference in New Issue