Skip to content

Commit 010dfee

Browse files
Fixed the PowerFlex/ScaleIO volume name inconsistency issue in the volume path after migration, due to rename failure
1 parent dc91003 commit 010dfee

File tree

2 files changed

+47
-26
lines changed

2 files changed

+47
-26
lines changed

plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/client/ScaleIOGatewayClientImpl.java

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ public boolean renameVolume(final String volumeId, final String newName) {
376376
checkResponseOK(response);
377377
return true;
378378
} catch (final IOException e) {
379-
LOG.error("Failed to rename PowerFlex volume due to:", e);
379+
LOG.error("Failed to rename PowerFlex volume due to: ", e);
380380
checkResponseTimeOut(e);
381381
} finally {
382382
if (response != null) {
@@ -786,7 +786,6 @@ public boolean migrateVolume(final String srcVolumeId, final String destPoolId,
786786
Preconditions.checkArgument(!Strings.isNullOrEmpty(destPoolId), "dest pool id cannot be null");
787787
Preconditions.checkArgument(timeoutInSecs > 0, "timeout must be greater than 0");
788788

789-
HttpResponse response = null;
790789
try {
791790
Volume volume = getVolume(srcVolumeId);
792791
if (volume == null || Strings.isNullOrEmpty(volume.getVtreeId())) {
@@ -798,10 +797,21 @@ public boolean migrateVolume(final String srcVolumeId, final String destPoolId,
798797
LOG.debug("Migrating the volume: " + srcVolumeId + " on the src pool: " + srcPoolId + " to the dest pool: " + destPoolId +
799798
" in the same PowerFlex cluster");
800799

801-
response = post(
802-
"/instances/Volume::" + srcVolumeId + "/action/migrateVTree",
803-
String.format("{\"destSPId\":\"%s\"}", destPoolId));
804-
checkResponseOK(response);
800+
HttpResponse response = null;
801+
try {
802+
response = post(
803+
"/instances/Volume::" + srcVolumeId + "/action/migrateVTree",
804+
String.format("{\"destSPId\":\"%s\"}", destPoolId));
805+
checkResponseOK(response);
806+
} catch (final IOException e) {
807+
LOG.error("Unable to migrate PowerFlex volume due to: ", e);
808+
checkResponseTimeOut(e);
809+
throw e;
810+
} finally {
811+
if (response != null) {
812+
EntityUtils.consumeQuietly(response.getEntity());
813+
}
814+
}
805815

806816
LOG.debug("Wait until the migration is complete for the volume: " + srcVolumeId);
807817
long migrationStartTime = System.currentTimeMillis();
@@ -844,28 +854,27 @@ public boolean migrateVolume(final String srcVolumeId, final String destPoolId,
844854
}
845855
}
846856
}
847-
} catch (final IOException e) {
848-
LOG.error("Failed to migrate PowerFlex volume due to:", e);
849-
checkResponseTimeOut(e);
850-
} finally {
851-
if (response != null) {
852-
EntityUtils.consumeQuietly(response.getEntity());
853-
}
857+
} catch (final Exception e) {
858+
LOG.error("Failed to migrate PowerFlex volume due to: " + e.getMessage(), e);
859+
throw new CloudRuntimeException("Failed to migrate PowerFlex volume due to: " + e.getMessage());
854860
}
861+
855862
LOG.debug("Migration failed for the volume: " + srcVolumeId);
856863
return false;
857864
}
858865

859-
private boolean waitForVolumeMigrationToComplete(final String volumeTreeId, int waitTimeInSec) {
866+
private boolean waitForVolumeMigrationToComplete(final String volumeTreeId, int waitTimeoutInSecs) {
860867
LOG.debug("Waiting for the migration to complete for the volume-tree " + volumeTreeId);
861868
if (Strings.isNullOrEmpty(volumeTreeId)) {
862869
LOG.warn("Invalid volume-tree id, unable to check the migration status of the volume-tree " + volumeTreeId);
863870
return false;
864871
}
865872

866-
while (waitTimeInSec > 0) {
873+
int delayTimeInSecs = 3;
874+
while (waitTimeoutInSecs > 0) {
867875
try {
868-
Thread.sleep(1000); // Try every sec and return after migration is complete
876+
// Wait and try after few secs (reduce no. of client API calls to check the migration status) and return after migration is complete
877+
Thread.sleep(delayTimeInSecs * 1000);
869878

870879
VTreeMigrationInfo.MigrationStatus migrationStatus = getVolumeTreeMigrationStatus(volumeTreeId);
871880
if (migrationStatus != null && migrationStatus == VTreeMigrationInfo.MigrationStatus.NotInMigration) {
@@ -876,7 +885,7 @@ private boolean waitForVolumeMigrationToComplete(final String volumeTreeId, int
876885
LOG.warn("Exception while checking for migration status of the volume-tree: " + volumeTreeId + " - " + ex.getLocalizedMessage());
877886
// don't do anything
878887
} finally {
879-
waitTimeInSec--;
888+
waitTimeoutInSecs = waitTimeoutInSecs - delayTimeInSecs;
880889
}
881890
}
882891

@@ -925,10 +934,10 @@ private boolean rollbackVolumeMigration(final String srcVolumeId) {
925934
pauseVolumeMigration(srcVolumeId, true); // Pause forcefully
926935
// Wait few secs for volume migration to change to Paused state
927936
boolean paused = false;
928-
int retryCount = 5;
937+
int retryCount = 3;
929938
while (retryCount > 0) {
930939
try {
931-
Thread.sleep(1000); // Try every sec
940+
Thread.sleep(3000); // Try after few secs
932941
migrationStatus = getVolumeTreeMigrationStatus(volume.getVtreeId()); // Get updated migration status
933942
if (migrationStatus != null && migrationStatus == VTreeMigrationInfo.MigrationStatus.Paused) {
934943
LOG.debug("Migration for the volume: " + srcVolumeId + " paused");

plugins/storage/volume/scaleio/src/main/java/org/apache/cloudstack/storage/datastore/driver/ScaleIOPrimaryDataStoreDriver.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -677,21 +677,29 @@ private Answer migrateVolume(DataObject srcData, DataObject destData) {
677677
long destPoolId = destStore.getId();
678678

679679
final ScaleIOGatewayClient client = getScaleIOClient(srcPoolId);
680-
final String srcVolumeId = ScaleIOUtil.getVolumePath(((VolumeInfo) srcData).getPath());
680+
final String srcVolumePath = ((VolumeInfo) srcData).getPath();
681+
final String srcVolumeId = ScaleIOUtil.getVolumePath(srcVolumePath);
681682
final StoragePoolVO destStoragePool = storagePoolDao.findById(destPoolId);
682683
final String destStoragePoolId = destStoragePool.getPath();
683684
int migrationTimeout = StorageManager.KvmStorageOfflineMigrationWait.value();
684685
boolean migrateStatus = client.migrateVolume(srcVolumeId, destStoragePoolId, migrationTimeout);
685686
if (migrateStatus) {
686687
String newVolumeName = String.format("%s-%s-%s-%s", ScaleIOUtil.VOLUME_PREFIX, destData.getId(),
687688
destStoragePool.getUuid().split("-")[0].substring(4), ManagementServerImpl.customCsIdentifier.value());
688-
client.renameVolume(srcVolumeId, newVolumeName);
689+
boolean renamed = client.renameVolume(srcVolumeId, newVolumeName);
689690

690691
if (srcData.getId() != destData.getId()) {
691692
VolumeVO destVolume = volumeDao.findById(destData.getId());
692-
String newVolumePath = ScaleIOUtil.updatedPathWithVolumeName(srcVolumeId, newVolumeName);
693-
destVolume.set_iScsiName(newVolumePath);
694-
destVolume.setPath(newVolumePath);
693+
// Volume Id in the PowerFlex/ScaleIO pool remains the same after the migration
694+
// Update PowerFlex volume name only after it is renamed, to maintain the consistency
695+
if (renamed) {
696+
String newVolumePath = ScaleIOUtil.updatedPathWithVolumeName(srcVolumeId, newVolumeName);
697+
destVolume.set_iScsiName(newVolumePath);
698+
destVolume.setPath(newVolumePath);
699+
} else {
700+
destVolume.set_iScsiName(srcVolumePath);
701+
destVolume.setPath(srcVolumePath);
702+
}
695703
volumeDao.update(destData.getId(), destVolume);
696704

697705
VolumeVO srcVolume = volumeDao.findById(srcData.getId());
@@ -719,10 +727,14 @@ private Answer migrateVolume(DataObject srcData, DataObject destData) {
719727
String snapshotVolumeId = ScaleIOUtil.getVolumePath(snapshotStore.getInstallPath());
720728
String newSnapshotName = String.format("%s-%s-%s-%s", ScaleIOUtil.SNAPSHOT_PREFIX, snapshot.getId(),
721729
destStoragePool.getUuid().split("-")[0].substring(4), ManagementServerImpl.customCsIdentifier.value());
722-
client.renameVolume(snapshotVolumeId, newSnapshotName);
730+
renamed = client.renameVolume(snapshotVolumeId, newSnapshotName);
723731

724732
snapshotStore.setDataStoreId(destPoolId);
725-
snapshotStore.setInstallPath(ScaleIOUtil.updatedPathWithVolumeName(snapshotVolumeId, newSnapshotName));
733+
// Snapshot Id in the PowerFlex/ScaleIO pool remains the same after the migration
734+
// Update PowerFlex snapshot name only after it is renamed, to maintain the consistency
735+
if (renamed) {
736+
snapshotStore.setInstallPath(ScaleIOUtil.updatedPathWithVolumeName(snapshotVolumeId, newSnapshotName));
737+
}
726738
snapshotDataStoreDao.update(snapshotStore.getId(), snapshotStore);
727739
}
728740
}

0 commit comments

Comments
 (0)