From 3fad1b41f91b7a1ecc45414410707446607a5f29 Mon Sep 17 00:00:00 2001 From: div8cn <35140268+div8cn@users.noreply.github.com> Date: Tue, 10 Mar 2020 23:04:18 +0800 Subject: [PATCH 1/2] Update AncientDataMotionStrategy.java fix When secondary storage usage is> 90%, VOLUME migration across primary storage will cause the migration to fail and lose VOLUME --- .../cloudstack/storage/motion/AncientDataMotionStrategy.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 9c8f4df3b6e2..9e3cf2f279a9 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -486,6 +486,9 @@ public void copyAsync(DataObject srcData, DataObject destData, Host destHost, As if (answer != null && !answer.getResult()) { errMsg = answer.getDetails(); } + if (answer == null) { + errMsg = "answer is null, set to error for CopyCommandResult"; + } } catch (Exception e) { s_logger.debug("copy failed", e); errMsg = e.toString(); From 2814a86db8d47d2ba36217ed36282ab4ba6079fe Mon Sep 17 00:00:00 2001 From: div8cn <35140268+div8cn@users.noreply.github.com> Date: Wed, 22 Apr 2020 19:49:51 +0800 Subject: [PATCH 2/2] Update AncientDataMotionStrategy.java Volume is migrated across Primary storage. If no secondary storage is available(Or used capacity> 90% ), the migration is canceled. Before modification, if secondary storage cannot be found, copyVolumeBetweenPools return NUll copyAsync considers answer = null to be a sign of successful task execution, so it deletes the VOLUME on the old primary storage. This is the root cause of data loss, because VOLUME did not perform the migration at all. --- .../storage/motion/AncientDataMotionStrategy.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 9e3cf2f279a9..51d8214fd49f 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -348,8 +348,10 @@ protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) // directly to s3 ImageStoreEntity imageStore = (ImageStoreEntity)dataStoreMgr.getImageStoreWithFreeCapacity(destScope.getScopeId()); if (imageStore == null || !imageStore.getProtocol().equalsIgnoreCase("nfs") && !imageStore.getProtocol().equalsIgnoreCase("cifs")) { - s_logger.debug("can't find a nfs (or cifs) image store to satisfy the need for a staging store"); - return null; + //s_logger.debug("can't find a nfs (or cifs) image store to satisfy the need for a staging store"); + String errMsg = "can't find a nfs (or cifs) image store to satisfy the need for a staging store"; + Answer answer = new Answer(null, false, errMsg); + return answer; } DataObject objOnImageStore = imageStore.create(srcData); @@ -486,9 +488,6 @@ public void copyAsync(DataObject srcData, DataObject destData, Host destHost, As if (answer != null && !answer.getResult()) { errMsg = answer.getDetails(); } - if (answer == null) { - errMsg = "answer is null, set to error for CopyCommandResult"; - } } catch (Exception e) { s_logger.debug("copy failed", e); errMsg = e.toString();