26
26
import com .cloud .hypervisor .Hypervisor ;
27
27
import com .cloud .offering .DiskOffering ;
28
28
import com .cloud .resource .ResourceManager ;
29
+ import com .cloud .storage .DataStoreRole ;
29
30
import com .cloud .storage .ScopeType ;
30
31
import com .cloud .storage .Storage ;
31
32
import com .cloud .storage .StoragePoolHostVO ;
49
50
50
51
import org .apache .cloudstack .backup .dao .BackupDao ;
51
52
import org .apache .cloudstack .backup .dao .BackupRepositoryDao ;
53
+ import org .apache .cloudstack .engine .subsystem .api .storage .DataStore ;
54
+ import org .apache .cloudstack .engine .subsystem .api .storage .DataStoreManager ;
52
55
import org .apache .cloudstack .framework .config .ConfigKey ;
53
56
import org .apache .cloudstack .framework .config .Configurable ;
54
57
import org .apache .cloudstack .storage .datastore .db .PrimaryDataStoreDao ;
55
58
import org .apache .cloudstack .storage .datastore .db .StoragePoolVO ;
59
+ import org .apache .cloudstack .storage .to .PrimaryDataStoreTO ;
56
60
import org .apache .logging .log4j .Logger ;
57
61
import org .apache .logging .log4j .LogManager ;
58
62
@@ -97,6 +101,9 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
97
101
@ Inject
98
102
private PrimaryDataStoreDao primaryDataStoreDao ;
99
103
104
+ @ Inject
105
+ DataStoreManager dataStoreMgr ;
106
+
100
107
@ Inject
101
108
private AgentManager agentManager ;
102
109
@@ -179,7 +186,8 @@ public Pair<Boolean, Backup> takeBackup(final VirtualMachine vm, Boolean quiesce
179
186
if (VirtualMachine .State .Stopped .equals (vm .getState ())) {
180
187
List <VolumeVO > vmVolumes = volumeDao .findByInstance (vm .getId ());
181
188
vmVolumes .sort (Comparator .comparing (Volume ::getDeviceId ));
182
- List <String > volumePaths = getVolumePaths (vmVolumes );
189
+ Pair <List <PrimaryDataStoreTO >, List <String >> volumePoolsAndPaths = getVolumePoolsAndPaths (vmVolumes );
190
+ List <String > volumePaths = volumePoolsAndPaths .second ();
183
191
command .setVolumePaths (volumePaths );
184
192
}
185
193
@@ -279,7 +287,9 @@ private boolean restoreVMBackup(VirtualMachine vm, Backup backup) {
279
287
restoreCommand .setMountOptions (backupRepository .getMountOptions ());
280
288
restoreCommand .setVmName (vm .getName ());
281
289
restoreCommand .setBackupVolumesUUIDs (backedVolumesUUIDs );
282
- restoreCommand .setRestoreVolumePaths (getVolumePaths (restoreVolumes ));
290
+ Pair <List <PrimaryDataStoreTO >, List <String >> volumePoolsAndPaths = getVolumePoolsAndPaths (restoreVolumes );
291
+ restoreCommand .setRestoreVolumePools (volumePoolsAndPaths .first ());
292
+ restoreCommand .setRestoreVolumePaths (volumePoolsAndPaths .second ());
283
293
restoreCommand .setVmExists (vm .getRemoved () == null );
284
294
restoreCommand .setVmState (vm .getState ());
285
295
@@ -294,32 +304,42 @@ private boolean restoreVMBackup(VirtualMachine vm, Backup backup) {
294
304
return answer .getResult ();
295
305
}
296
306
297
- private List <String > getVolumePaths (List <VolumeVO > volumes ) {
307
+ private Pair <List <PrimaryDataStoreTO >, List <String >> getVolumePoolsAndPaths (List <VolumeVO > volumes ) {
308
+ List <PrimaryDataStoreTO > volumePools = new ArrayList <>();
298
309
List <String > volumePaths = new ArrayList <>();
299
310
for (VolumeVO volume : volumes ) {
300
311
StoragePoolVO storagePool = primaryDataStoreDao .findById (volume .getPoolId ());
301
312
if (Objects .isNull (storagePool )) {
302
313
throw new CloudRuntimeException ("Unable to find storage pool associated to the volume" );
303
314
}
304
- String volumePathPrefix ;
305
- if (ScopeType .HOST .equals (storagePool .getScope ())) {
306
- volumePathPrefix = storagePool .getPath ();
307
- } else if (Storage .StoragePoolType .SharedMountPoint .equals (storagePool .getPoolType ())) {
308
- volumePathPrefix = storagePool .getPath ();
309
- } else {
310
- volumePathPrefix = String .format ("/mnt/%s" , storagePool .getUuid ());
311
- }
315
+ String volumePathPrefix = getVolumePathPrefix (storagePool );
316
+ DataStore dataStore = dataStoreMgr .getDataStore (storagePool .getId (), DataStoreRole .Primary );
317
+ volumePools .add (dataStore != null ? (PrimaryDataStoreTO )dataStore .getTO () : null );
312
318
volumePaths .add (String .format ("%s/%s" , volumePathPrefix , volume .getPath ()));
313
319
}
314
- return volumePaths ;
320
+ return new Pair <>(volumePools , volumePaths );
321
+ }
322
+
323
+ private String getVolumePathPrefix (StoragePoolVO storagePool ) {
324
+ String volumePathPrefix ;
325
+ if (ScopeType .HOST .equals (storagePool .getScope ()) ||
326
+ Storage .StoragePoolType .SharedMountPoint .equals (storagePool .getPoolType ()) ||
327
+ Storage .StoragePoolType .RBD .equals (storagePool .getPoolType ())) {
328
+ volumePathPrefix = storagePool .getPath ();
329
+ } else {
330
+ // Should be Storage.StoragePoolType.NetworkFilesystem
331
+ volumePathPrefix = String .format ("/mnt/%s" , storagePool .getUuid ());
332
+ }
333
+ return volumePathPrefix ;
315
334
}
316
335
317
336
@ Override
318
337
public Pair <Boolean , String > restoreBackedUpVolume (Backup backup , Backup .VolumeInfo backupVolumeInfo , String hostIp , String dataStoreUuid , Pair <String , VirtualMachine .State > vmNameAndState ) {
319
338
final VolumeVO volume = volumeDao .findByUuid (backupVolumeInfo .getUuid ());
320
339
final DiskOffering diskOffering = diskOfferingDao .findByUuid (backupVolumeInfo .getDiskOfferingId ());
321
- final StoragePoolHostVO dataStore = storagePoolHostDao .findByUuid (dataStoreUuid );
340
+ final StoragePoolVO pool = primaryDataStoreDao .findByUuid (dataStoreUuid );
322
341
final HostVO hostVO = hostDao .findByIp (hostIp );
342
+ final StoragePoolHostVO storagePoolHost = storagePoolHostDao .findByPoolHost (pool .getId (), hostVO .getId ());
323
343
324
344
LOG .debug ("Restoring vm volume {} from backup {} on the NAS Backup Provider" , backupVolumeInfo , backup );
325
345
BackupRepository backupRepository = getBackupRepository (backup );
@@ -335,10 +355,14 @@ public Pair<Boolean, String> restoreBackedUpVolume(Backup backup, Backup.VolumeI
335
355
restoredVolume .setUuid (volumeUUID );
336
356
restoredVolume .setRemoved (null );
337
357
restoredVolume .setDisplayVolume (true );
338
- restoredVolume .setPoolId (dataStore .getPoolId ());
358
+ restoredVolume .setPoolId (pool .getId ());
359
+ restoredVolume .setPoolType (pool .getPoolType ());
339
360
restoredVolume .setPath (restoredVolume .getUuid ());
340
361
restoredVolume .setState (Volume .State .Copying );
341
362
restoredVolume .setFormat (Storage .ImageFormat .QCOW2 );
363
+ if (pool .getPoolType () == Storage .StoragePoolType .RBD ) {
364
+ restoredVolume .setFormat (Storage .ImageFormat .RAW );
365
+ }
342
366
restoredVolume .setSize (backupVolumeInfo .getSize ());
343
367
restoredVolume .setDiskOfferingId (diskOffering .getId ());
344
368
@@ -347,7 +371,9 @@ public Pair<Boolean, String> restoreBackedUpVolume(Backup backup, Backup.VolumeI
347
371
restoreCommand .setBackupRepoType (backupRepository .getType ());
348
372
restoreCommand .setBackupRepoAddress (backupRepository .getAddress ());
349
373
restoreCommand .setVmName (vmNameAndState .first ());
350
- restoreCommand .setRestoreVolumePaths (Collections .singletonList (String .format ("%s/%s" , dataStore .getLocalPath (), volumeUUID )));
374
+ restoreCommand .setRestoreVolumePaths (Collections .singletonList (String .format ("%s%s" , storagePoolHost != null ? storagePoolHost .getLocalPath () + "/" : "" , volumeUUID )));
375
+ DataStore dataStore = dataStoreMgr .getDataStore (pool .getId (), DataStoreRole .Primary );
376
+ restoreCommand .setRestoreVolumePools (Collections .singletonList (dataStore != null ? (PrimaryDataStoreTO )dataStore .getTO () : null ));
351
377
restoreCommand .setDiskType (backupVolumeInfo .getType ().name ().toLowerCase (Locale .ROOT ));
352
378
restoreCommand .setMountOptions (backupRepository .getMountOptions ());
353
379
restoreCommand .setVmExists (null );
0 commit comments