@Override
public Answer backupSnapshot(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
DataTO destData = cmd.getDestTO();
SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshot.getDataStore();
SnapshotObjectTO destSnapshot = (SnapshotObjectTO)destData;
DataStoreTO imageStore = destData.getDataStore();
if (!(imageStore instanceof NfsTO)) {
return backupSnapshotForObjectStore(cmd);
}
NfsTO nfsImageStore = (NfsTO)imageStore;
String secondaryStoragePoolUrl = nfsImageStore.getUrl();
// NOTE: snapshot name is encoded in snapshot path
int index = snapshot.getPath().lastIndexOf("/");
String snapshotName = snapshot.getPath().substring(index + 1);
String volumePath = snapshot.getVolume().getPath();
String snapshotDestPath = null;
String snapshotRelPath = null;
String vmName = snapshot.getVmName();
KVMStoragePool secondaryStoragePool = null;
Connect conn = null;
KVMPhysicalDisk snapshotDisk = null;
KVMStoragePool primaryPool = null;
try {
conn = LibvirtConnection.getConnectionByVmName(vmName);
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
String ssPmountPath = secondaryStoragePool.getLocalPath();
snapshotRelPath = destSnapshot.getPath();
snapshotDestPath = ssPmountPath + File.separator + snapshotRelPath;
snapshotDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volumePath);
primaryPool = snapshotDisk.getPool();
long size = 0;
/**
* Since Ceph version Dumpling (0.67.X) librbd / Qemu supports converting RBD
* snapshots to RAW/QCOW2 files directly.
*
* This reduces the amount of time and storage it takes to back up a snapshot dramatically
*/
if (primaryPool.getType() == StoragePoolType.RBD) {
String rbdSnapshot = snapshotDisk.getPath() + "@" + snapshotName;
String snapshotFile = snapshotDestPath + "/" + snapshotName;
try {
s_logger.debug("Attempting to backup RBD snapshot " + rbdSnapshot);
File snapDir = new File(snapshotDestPath);
s_logger.debug("Attempting to create " + snapDir.getAbsolutePath() + " recursively for snapshot storage");
FileUtils.forceMkdir(snapDir);
QemuImgFile srcFile =
new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primaryPool.getSourceHost(), primaryPool.getSourcePort(), primaryPool.getAuthUserName(),
primaryPool.getAuthSecret(), rbdSnapshot));
srcFile.setFormat(PhysicalDiskFormat.RAW);
QemuImgFile destFile = new QemuImgFile(snapshotFile);
destFile.setFormat(snapshotDisk.getFormat());
s_logger.debug("Backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile);
QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
q.convert(srcFile, destFile);
File snapFile = new File(snapshotFile);
if(snapFile.exists()) {
size = snapFile.length();
}
s_logger.debug("Finished backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile + " Snapshot size: " + size);
} catch (FileNotFoundException e) {
s_logger.error("Failed to open " + snapshotDestPath + ". The error was: " + e.getMessage());
return new CopyCmdAnswer(e.toString());
} catch (IOException e) {
s_logger.error("Failed to create " + snapshotDestPath + ". The error was: " + e.getMessage());
return new CopyCmdAnswer(e.toString());
} catch (QemuImgException e) {
s_logger.error("Failed to backup the RBD snapshot from " + rbdSnapshot +
" to " + snapshotFile + " the error was: " + e.getMessage());
return new CopyCmdAnswer(e.toString());
}
} else {
Script command = new Script(_manageSnapshotPath, cmd.getWaitInMillSeconds(), s_logger);
command.add("-b", snapshotDisk.getPath());
command.add("-n", snapshotName);
command.add("-p", snapshotDestPath);
command.add("-t", snapshotName);
String result = command.execute();
if (result != null) {
s_logger.debug("Failed to backup snaptshot: " + result);
return new CopyCmdAnswer(result);
}
File snapFile = new File(snapshotDestPath + "/" + snapshotName);
if(snapFile.exists()){
size = snapFile.length();
}
}
SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
newSnapshot.setPath(snapshotRelPath + File.separator + snapshotName);
newSnapshot.setPhysicalSize(size);
return new CopyCmdAnswer(newSnapshot);
} catch (LibvirtException e) {
s_logger.debug("Failed to backup snapshot: " + e.toString());
return new CopyCmdAnswer(e.toString());
} catch (CloudRuntimeException e) {