Skip to content

Commit b85267b

Browse files
Support take NAS backup for stopped instances with volumes on Ceph storage pool(s)
1 parent 1cc9e27 commit b85267b

File tree

4 files changed

+41
-4
lines changed

4 files changed

+41
-4
lines changed

core/src/main/java/org/apache/cloudstack/backup/TakeBackupCommand.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import com.cloud.agent.api.Command;
2323
import com.cloud.agent.api.LogLevel;
24+
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
2425

2526
import java.util.List;
2627

@@ -29,6 +30,7 @@ public class TakeBackupCommand extends Command {
2930
private String backupPath;
3031
private String backupRepoType;
3132
private String backupRepoAddress;
33+
private List<PrimaryDataStoreTO> volumePools;
3234
private List<String> volumePaths;
3335
private Boolean quiesce;
3436
@LogLevel(LogLevel.Log4jLevel.Off)
@@ -80,6 +82,14 @@ public void setMountOptions(String mountOptions) {
8082
this.mountOptions = mountOptions;
8183
}
8284

85+
public List<PrimaryDataStoreTO> getVolumePools() {
86+
return volumePools;
87+
}
88+
89+
public void setVolumePools(List<PrimaryDataStoreTO> volumePools) {
90+
this.volumePools = volumePools;
91+
}
92+
8393
public List<String> getVolumePaths() {
8494
return volumePaths;
8595
}

plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ public Pair<Boolean, Backup> takeBackup(final VirtualMachine vm, Boolean quiesce
210210
List<VolumeVO> vmVolumes = volumeDao.findByInstance(vm.getId());
211211
vmVolumes.sort(Comparator.comparing(Volume::getDeviceId));
212212
Pair<List<PrimaryDataStoreTO>, List<String>> volumePoolsAndPaths = getVolumePoolsAndPaths(vmVolumes);
213-
List<String> volumePaths = volumePoolsAndPaths.second();
214-
command.setVolumePaths(volumePaths);
213+
command.setVolumePools(volumePoolsAndPaths.first());
214+
command.setVolumePaths(volumePoolsAndPaths.second());
215215
}
216216

217217
BackupAnswer answer;

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtTakeBackupCommandWrapper.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,17 @@
2222
import com.amazonaws.util.CollectionUtils;
2323
import com.cloud.agent.api.Answer;
2424
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
25+
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
26+
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
27+
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
2528
import com.cloud.resource.CommandWrapper;
2629
import com.cloud.resource.ResourceWrapper;
30+
import com.cloud.storage.Storage;
2731
import com.cloud.utils.Pair;
2832
import com.cloud.utils.script.Script;
2933
import org.apache.cloudstack.backup.BackupAnswer;
3034
import org.apache.cloudstack.backup.TakeBackupCommand;
35+
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
3136

3237
import java.util.ArrayList;
3338
import java.util.Arrays;
@@ -44,7 +49,22 @@ public Answer execute(TakeBackupCommand command, LibvirtComputingResource libvir
4449
final String backupRepoType = command.getBackupRepoType();
4550
final String backupRepoAddress = command.getBackupRepoAddress();
4651
final String mountOptions = command.getMountOptions();
47-
final List<String> diskPaths = command.getVolumePaths();
52+
List<PrimaryDataStoreTO> volumePools = command.getVolumePools();
53+
final List<String> volumePaths = command.getVolumePaths();
54+
KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
55+
56+
List<String> diskPaths = new ArrayList<>();
57+
for (int idx = 0; idx < volumePaths.size(); idx++) {
58+
PrimaryDataStoreTO volumePool = volumePools.get(idx);
59+
String volumePath = volumePaths.get(idx);
60+
if (volumePool.getPoolType() != Storage.StoragePoolType.RBD) {
61+
diskPaths.add(volumePath);
62+
} else {
63+
KVMStoragePool volumeStoragePool = storagePoolMgr.getStoragePool(volumePool.getPoolType(), volumePool.getUuid());
64+
String rbdDestVolumeFile = KVMPhysicalDisk.RBDStringBuilder(volumeStoragePool, volumePath);
65+
diskPaths.add(rbdDestVolumeFile);
66+
}
67+
}
4868

4969
List<String[]> commands = new ArrayList<>();
5070
commands.add(new String[]{

scripts/vm/hypervisor/kvm/nasbackup.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,14 @@ backup_stopped_vm() {
165165

166166
name="root"
167167
for disk in $DISK_PATHS; do
168-
volUuid="${disk##*/}"
168+
if [[ "$disk" == rbd:* ]]; then
169+
# disk for rbd => rbd:<pool>/<uuid>:mon_host=<monitor_host>...
170+
# sample: rbd:cloudstack/53d5c355-d726-4d3e-9422-046a503a0b12:mon_host=10.0.1.2...
171+
beforeUuid="${disk#*/}" # Remove up to first slash after rbd:
172+
volUuid="${beforeUuid%%:*}" # Remove everything after colon to get the uuid
173+
else
174+
volUuid="${disk##*/}"
175+
fi
169176
output="$dest/$name.$volUuid.qcow2"
170177
if ! qemu-img convert -O qcow2 "$disk" "$output" > "$logFile" 2> >(cat >&2); then
171178
echo "qemu-img convert failed for $disk $output"

0 commit comments

Comments
 (0)