diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index f73307be131..e9f7a64a905 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -930,7 +930,7 @@ public class KVMStorageProcessor implements StorageProcessor { final String secondaryStoragePoolUrl = nfsImageStore.getUrl(); // NOTE: snapshot name is encoded in snapshot path final int index = snapshot.getPath().lastIndexOf("/"); - final boolean isCreatedFromVmSnapshot = (index == -1) ? true: false; // -1 means the snapshot is created from existing vm snapshot + final boolean isCreatedFromVmSnapshot = index == -1; // -1 means the snapshot is created from existing vm snapshot final String snapshotName = snapshot.getPath().substring(index + 1); String descName = snapshotName; @@ -1002,7 +1002,7 @@ public class KVMStorageProcessor implements StorageProcessor { } } else { final Script command = new Script(_manageSnapshotPath, cmd.getWaitInMillSeconds(), s_logger); - command.add("-b", snapshot.getPath()); + command.add("-b", isCreatedFromVmSnapshot ? snapshotDisk.getPath() : snapshot.getPath()); command.add(NAME_OPTION, snapshotName); command.add("-p", snapshotDestPath); if (isCreatedFromVmSnapshot) { diff --git a/scripts/storage/qcow2/managesnapshot.sh b/scripts/storage/qcow2/managesnapshot.sh index b1bf73251a8..2daa768347f 100755 --- a/scripts/storage/qcow2/managesnapshot.sh +++ b/scripts/storage/qcow2/managesnapshot.sh @@ -226,14 +226,48 @@ backup_snapshot() { return 2 fi elif [ -f ${disk} ]; then + if [[ $disk == *"/snapshots/"* ]]; then + #Backup volume snapshot + cp "$disk" "${destPath}/${destName}" + ret_code=$? - cp "$disk" "${destPath}/${destName}" - ret_code=$? + if [ $ret_code -gt 0 ] + then + printf "Failed to backup $snapshotname for disk $disk to $destPath\n" >&2 + return 2 + fi + else + # Backup VM snapshot + qemuimg_ret=$($qemu_img snapshot $forceShareFlag -l $disk 2>&1) + ret_code=$? + if [ $ret_code -gt 0 ] && [[ $qemuimg_ret == *"snapshot: invalid option -- 'U'"* ]]; then + forceShareFlag="" + qemuimg_ret=$($qemu_img snapshot $forceShareFlag -l $disk) + ret_code=$? + fi - if [ $ret_code -gt 0 ] - then - printf "Failed to backup $snapshotname for disk $disk to $destPath\n" >&2 - return 2 + if [ $ret_code -gt 0 ] || [[ ! $qemuimg_ret == *"$snapshotname"* ]]; then + printf "there is no $snapshotname on disk $disk\n" >&2 + return 1 + fi + + qemuimg_ret=$($qemu_img convert $forceShareFlag -f qcow2 -O qcow2 -l snapshot.name=$snapshotname $disk $destPath/$destName 2>&1 > /dev/null) + ret_code=$? + if [ $ret_code -gt 0 ] && [[ $qemuimg_ret == *"convert: invalid option -- 'U'"* ]]; then + forceShareFlag="" + qemuimg_ret=$($qemu_img convert $forceShareFlag -f qcow2 -O qcow2 -l snapshot.name=$snapshotname $disk $destPath/$destName 2>&1 > /dev/null) + ret_code=$? + fi + + if [ $ret_code -gt 0 ] && [[ $qemuimg_ret == *"convert: invalid option -- 'l'"* ]]; then + $qemu_img convert $forceShareFlag -f qcow2 -O qcow2 -s $snapshotname $disk $destPath/$destName >& /dev/null + ret_code=$? + fi + + if [ $ret_code -gt 0 ]; then + printf "Failed to backup $snapshotname for disk $disk to $destPath\n" >&2 + return 2 + fi fi else printf "***Failed to backup snapshot $snapshotname, undefined type $disk\n" >&2