Skip to content

Commit 00febb2

Browse files
committed
<fix>[storage]: optimize snapshot group creation and deletion logic
Resolves: ZSV-9792 Change-Id: I6b65736e646e7163777a7872667077756771726d
1 parent 41a8df2 commit 00febb2

1 file changed

Lines changed: 97 additions & 20 deletions

File tree

storage/src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupBase.java

Lines changed: 97 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import org.zstack.core.thread.ChainTask;
1616
import org.zstack.core.thread.SyncTaskChain;
1717
import org.zstack.core.thread.ThreadFacade;
18+
import org.zstack.core.workflow.ShareFlow;
19+
import org.zstack.core.workflow.ShareFlowChain;
1820
import org.zstack.core.workflow.SimpleFlowChain;
1921
import org.zstack.header.core.NoErrorCompletion;
2022
import org.zstack.header.core.WhileDoneCompletion;
@@ -31,6 +33,8 @@
3133
import org.zstack.header.storage.snapshot.group.*;
3234
import org.zstack.header.vm.RestoreVmInstanceMsg;
3335
import org.zstack.header.vm.VmInstanceConstant;
36+
import org.zstack.header.vm.VmInstanceVO;
37+
import org.zstack.header.vm.VmInstanceVO_;
3438
import org.zstack.header.vm.devices.VmInstanceResourceMetadataManager;
3539
import org.zstack.header.volume.VolumeType;
3640
import org.zstack.header.volume.VolumeVO;
@@ -209,28 +213,101 @@ private void handle(DeleteVolumeSnapshotGroupInnerMsg msg) {
209213
logger.debug(String.format("skip snapshots not belong to origin vm[uuid:%s]", self.getVmInstanceUuid()));
210214
}
211215

212-
new While<>(snapshots).all((snapshot, compl) -> {
213-
DeleteVolumeSnapshotMsg rmsg = new DeleteVolumeSnapshotMsg();
214-
rmsg.setSnapshotUuid(snapshot.getUuid());
215-
rmsg.setVolumeUuid(snapshot.getVolumeUuid());
216-
rmsg.setTreeUuid(snapshot.getTreeUuid());
217-
rmsg.setDeletionMode(msg.getDeletionMode());
218-
rmsg.setScope(msg.getScope());
219-
rmsg.setDirection(msg.getDirection());
220-
bus.makeTargetServiceIdByResourceUuid(rmsg, VolumeSnapshotConstant.SERVICE_ID, getResourceIdToRouteMsg(snapshot));
221-
bus.send(rmsg, new CloudBusCallBack(compl) {
222-
@Override
223-
public void run(MessageReply r) {
224-
reply.addResult(new DeleteSnapshotGroupResult(rmsg.getSnapshotUuid(), rmsg.getVolumeUuid(), r.getError()));
225-
compl.done();
226-
}
227-
});
228-
}).run(new WhileDoneCompletion(msg) {
216+
String vmUuid = self.getVmInstanceUuid();
217+
String rootVolumeUuid = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, vmUuid)
218+
.select(VmInstanceVO_.rootVolumeUuid).findValue();
219+
220+
VolumeSnapshotVO rootVolumeSnapshot = snapshots.stream().filter(s -> s.getVolumeUuid().equals(rootVolumeUuid)).findFirst().orElse(null);
221+
snapshots.removeIf(s -> s.getVolumeUuid().equals(rootVolumeUuid));
222+
223+
FlowChain chain = new ShareFlowChain();
224+
chain.then(new ShareFlow() {
225+
boolean skipDeleteRootVolumeSnapshot = false;
226+
229227
@Override
230-
public void done(ErrorCodeList errorCodeList) {
231-
bus.reply(msg, reply);
228+
public void setup() {
229+
flow(new NoRollbackFlow() {
230+
String __name__ = "delete-data-volume-snapshots";
231+
232+
@Override
233+
public void run(FlowTrigger trigger, Map data) {
234+
new While<>(snapshots).all((snapshot, compl) -> {
235+
DeleteVolumeSnapshotMsg rmsg = buildDeleteVolumeSnapshotMsg(snapshot, msg);
236+
bus.makeTargetServiceIdByResourceUuid(rmsg, VolumeSnapshotConstant.SERVICE_ID, getResourceIdToRouteMsg(snapshot));
237+
bus.send(rmsg, new CloudBusCallBack(compl) {
238+
@Override
239+
public void run(MessageReply r) {
240+
if (r.getError() != null) {
241+
skipDeleteRootVolumeSnapshot = true;
242+
}
243+
reply.addResult(new DeleteSnapshotGroupResult(rmsg.getSnapshotUuid(), rmsg.getVolumeUuid(), r.getError()));
244+
compl.done();
245+
}
246+
});
247+
}).run(new WhileDoneCompletion(msg) {
248+
@Override
249+
public void done(ErrorCodeList errorCodeList) {
250+
trigger.next();
251+
}
252+
});
253+
}
254+
});
255+
256+
flow(new NoRollbackFlow() {
257+
String __name__ = "delete-root-volume-snapshot";
258+
259+
@Override
260+
public void run(FlowTrigger trigger, Map data) {
261+
if (rootVolumeSnapshot == null) {
262+
trigger.next();
263+
return;
264+
}
265+
266+
if (skipDeleteRootVolumeSnapshot) {
267+
// skip delete root volume snapshot if delete data volume snapshot failed
268+
logger.debug(String.format("skip delete root volume snapshot[uuid:%s] if delete data volume snapshot failed", rootVolumeSnapshot.getUuid()));
269+
trigger.next();
270+
return;
271+
}
272+
273+
DeleteVolumeSnapshotMsg rmsg = buildDeleteVolumeSnapshotMsg(rootVolumeSnapshot, msg);
274+
bus.makeTargetServiceIdByResourceUuid(rmsg, VolumeSnapshotConstant.SERVICE_ID, getResourceIdToRouteMsg(rootVolumeSnapshot));
275+
bus.send(rmsg, new CloudBusCallBack(trigger) {
276+
@Override
277+
public void run(MessageReply r) {
278+
reply.addResult(new DeleteSnapshotGroupResult(rmsg.getSnapshotUuid(), rmsg.getVolumeUuid(), r.getError()));
279+
trigger.next();
280+
}
281+
});
282+
}
283+
});
284+
285+
done(new FlowDoneHandler(msg) {
286+
@Override
287+
public void handle(Map data) {
288+
bus.reply(msg, reply);
289+
}
290+
});
291+
292+
error(new FlowErrorHandler(msg) {
293+
@Override
294+
public void handle(ErrorCode errCode, Map data) {
295+
bus.reply(msg, reply);
296+
}
297+
});
232298
}
233-
});
299+
300+
private DeleteVolumeSnapshotMsg buildDeleteVolumeSnapshotMsg(VolumeSnapshotVO snapshot, DeleteVolumeSnapshotGroupInnerMsg msg) {
301+
DeleteVolumeSnapshotMsg rmsg = new DeleteVolumeSnapshotMsg();
302+
rmsg.setSnapshotUuid(snapshot.getUuid());
303+
rmsg.setVolumeUuid(snapshot.getVolumeUuid());
304+
rmsg.setTreeUuid(snapshot.getTreeUuid());
305+
rmsg.setDeletionMode(msg.getDeletionMode());
306+
rmsg.setScope(msg.getScope());
307+
rmsg.setDirection(msg.getDirection());
308+
return rmsg;
309+
}
310+
}).start();
234311
}
235312

236313
private void handle(APIRevertVmFromSnapshotGroupMsg msg) {

0 commit comments

Comments
 (0)