diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index 6f6a29e47b1..0895e84c551 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -57,6 +57,7 @@ import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -95,6 +96,7 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.template.TemplateManager; @@ -141,6 +143,10 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati @Inject protected VolumeDao _volumeDao; @Inject + protected SnapshotDao _snapshotDao; + @Inject + protected SnapshotDataStoreDao _snapshotDataStoreDao; + @Inject protected ResourceLimitService _resourceLimitMgr; @Inject VolumeDetailsDao _volDetailDao; @@ -916,8 +922,14 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati try { VolumeApiResult result = future.get(); if (result.isFailed()) { - s_logger.error("migrate volume failed:" + result.getResult()); - throw new StorageUnavailableException("migrate volume failed: " + result.getResult(), destPool.getId()); + s_logger.error("Migrate volume failed:" + result.getResult()); + throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.getId()); + } else { + // update the volumeId for snapshots on secondary + if (!_snapshotDao.listByVolumeId(vol.getId()).isEmpty()) { + _snapshotDao.updateVolumeIds(vol.getId(), result.getVolume().getId()); + _snapshotDataStoreDao.updateVolumeIds(vol.getId(), result.getVolume().getId()); + } } return result.getVolume(); } catch (InterruptedException e) { diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java index f55352b2ef2..ff2e4457441 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java @@ -57,4 +57,6 @@ public interface SnapshotDao extends GenericDao, StateDao listAllByStatus(Snapshot.State... status); + void updateVolumeIds(long oldVolId, long newVolId); + } diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java index 204447c6909..84a92d7bf0d 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -41,6 +41,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -326,4 +327,13 @@ public class SnapshotDaoImpl extends GenericDaoBase implements return true; } + @Override + public void updateVolumeIds(long oldVolId, long newVolId) { + SearchCriteria sc = VolumeIdSearch.create(); + sc.setParameters("volumeId", oldVolId); + SnapshotVO snapshot = createForUpdate(); + snapshot.setVolumeId(newVolId); + UpdateBuilder ub = getUpdateBuilder(snapshot); + update(ub, sc, null); + } } diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index e24c0351e46..231b241408b 100644 --- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java +++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -56,4 +56,8 @@ public interface SnapshotDataStoreDao extends GenericDao= deltaSnap) { - fullBackup = true; - } else { - fullBackup = false; + for (i = 1; i < deltaSnap; i++) { + Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId(); + if (prevBackupId == 0) { + break; + } + parentSnapshotOnBackupStore = snapshotStoreDao.findBySnapshot(prevBackupId, DataStoreRole.Image); + if (parentSnapshotOnBackupStore == null) { + break; + } + } + + if (i >= deltaSnap) { + fullBackup = true; + } else { + fullBackup = false; + } + } else { + // if there is an snapshot entry for previousPool(primary storage) of migrated volume, delete it becasue CS created one more snapshot entry for current pool + snapshotStoreDao.remove(oldestSnapshotOnPrimary.getId()); + } } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index 28d65981065..ea73ecd7e33 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -54,6 +54,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase snapshotSearch; private SearchBuilder storeSnapshotSearch; private SearchBuilder snapshotIdSearch; + private SearchBuilder volumeIdSearch; private final String parentSearch = "select store_id, store_role, snapshot_id from cloud.snapshot_store_ref where store_id = ? " + " and store_role = ? and volume_id = ? and state = 'Ready'" + " order by created DESC " + " limit 1"; @@ -61,6 +62,10 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase params) throws ConfigurationException { @@ -110,6 +115,10 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = volumeIdSearch.create(); + sc.setParameters("volume_id", oldVolId); + SnapshotDataStoreVO snapshot = createForUpdate(); + snapshot.setVolumeId(newVolId); + UpdateBuilder ub = getUpdateBuilder(snapshot); + update(ub, sc, null); + } }