Skip to content

Commit 92344c0

Browse files
committed
CLOUDSTACK-5863: revert volume snapshot for KVM/QCOW2
1 parent e7ddbd4 commit 92344c0

23 files changed

Lines changed: 309 additions & 28 deletions

File tree

api/src/com/cloud/storage/Volume.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum State {
3939
Ready("The volume is ready to be used."),
4040
Migrating("The volume is migrating to other storage pool"),
4141
Snapshotting("There is a snapshot created on this volume, not backed up to secondary storage yet"),
42+
RevertSnapshotting("There is a snapshot created on this volume, the volume is being reverting from snapshot"),
4243
Resizing("The volume is being resized"),
4344
Expunging("The volume is being expunging"),
4445
Expunged("The volume has been expunged"),
@@ -91,6 +92,9 @@ public String getDescription() {
9192
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Ready, Event.SnapshotRequested, Snapshotting, null));
9293
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Snapshotting, Event.OperationSucceeded, Ready, null));
9394
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Snapshotting, Event.OperationFailed, Ready,null));
95+
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Ready, Event.RevertSnapshotRequested, RevertSnapshotting, null));
96+
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(RevertSnapshotting, Event.OperationSucceeded, Ready, null));
97+
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(RevertSnapshotting, Event.OperationFailed, Ready,null));
9498
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Allocated, Event.MigrationCopyRequested, Creating, null));
9599
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Creating, Event.MigrationCopyFailed, Allocated, null));
96100
s_fsm.addTransition(new StateMachine2.Transition<State, Event>(Creating, Event.MigrationCopySucceeded, Ready, Arrays.asList(new StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE})));
@@ -131,6 +135,7 @@ enum Event {
131135
MigrationCopySucceeded,
132136
MigrationCopyFailed,
133137
SnapshotRequested,
138+
RevertSnapshotRequested,
134139
DestroyRequested,
135140
ExpungingRequested,
136141
ResizeRequested,

api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,36 @@
3131
import org.apache.cloudstack.api.response.SnapshotResponse;
3232
import org.apache.cloudstack.api.response.SuccessResponse;
3333
import org.apache.cloudstack.context.CallContext;
34+
import org.apache.log4j.Logger;
3435

3536
import com.cloud.event.EventTypes;
3637
import com.cloud.storage.Snapshot;
3738
import com.cloud.user.Account;
3839

39-
@APICommand(name = "revertSnapshot", description = "revert a volume snapshot.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class},
40+
@APICommand(name = "revertSnapshot", description = "revert a volume snapshot.", responseObject = SuccessResponse.class, entityType = {Snapshot.class},
4041
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
4142
public class RevertSnapshotCmd extends BaseAsyncCmd {
43+
public static final Logger s_logger = Logger.getLogger(RevertSnapshotCmd.class.getName());
4244
private static final String s_name = "revertsnapshotresponse";
4345

46+
/////////////////////////////////////////////////////
47+
//////////////// API parameters /////////////////////
48+
/////////////////////////////////////////////////////
4449
@ACL(accessType = AccessType.OperateEntry)
4550
@Parameter(name= ApiConstants.ID, type= BaseCmd.CommandType.UUID, entityType = SnapshotResponse.class,
4651
required=true, description="The ID of the snapshot")
4752
private Long id;
4853

54+
/////////////////////////////////////////////////////
55+
/////////////////// Accessors ///////////////////////
56+
/////////////////////////////////////////////////////
4957
public Long getId() {
5058
return id;
5159
}
5260

61+
/////////////////////////////////////////////////////
62+
/////////////// API Implementation///////////////////
63+
/////////////////////////////////////////////////////
5364
@Override
5465
public String getCommandName() {
5566
return s_name;
@@ -91,7 +102,6 @@ public void execute() {
91102
boolean result = _snapshotService.revertSnapshot(getId());
92103
if (result) {
93104
SuccessResponse response = new SuccessResponse(getCommandName());
94-
response.setResponseName(getCommandName());
95105
setResponseObject(response);
96106
} else {
97107
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to revert snapshot");
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.cloudstack.storage.command;
20+
21+
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
22+
23+
public final class RevertSnapshotCommand extends StorageSubSystemCommand {
24+
private SnapshotObjectTO data;
25+
private boolean _executeInSequence = false;
26+
27+
public RevertSnapshotCommand(SnapshotObjectTO data) {
28+
super();
29+
this.data = data;
30+
}
31+
32+
protected RevertSnapshotCommand() {
33+
super();
34+
}
35+
36+
public SnapshotObjectTO getData() {
37+
return this.data;
38+
}
39+
40+
@Override
41+
public void setExecuteInSequence(final boolean executeInSequence) {
42+
_executeInSequence = executeInSequence;
43+
}
44+
45+
@Override
46+
public boolean executeInSequence() {
47+
return _executeInSequence;
48+
}
49+
}

engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,5 @@ public interface PrimaryDataStoreDriver extends DataStoreDriver {
4848

4949
public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback);
5050

51-
public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CommandResult> callback);
51+
public void revertSnapshot(SnapshotInfo snapshotOnImageStore, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback<CommandResult> callback);
5252
}

engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public interface SnapshotService {
2424

2525
boolean deleteSnapshot(SnapshotInfo snapshot);
2626

27-
boolean revertSnapshot(Long snapshotId);
27+
boolean revertSnapshot(SnapshotInfo snapshot);
2828

2929
void syncVolumeSnapshotsToRegionStore(long volumeId, DataStore store);
3030

engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ enum SnapshotOperation {
2929

3030
boolean deleteSnapshot(Long snapshotId);
3131

32-
boolean revertSnapshot(Long snapshotId);
32+
boolean revertSnapshot(SnapshotInfo snapshot);
3333

3434
StrategyPriority canHandle(Snapshot snapshot, SnapshotOperation op);
3535
}

engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,7 @@ public interface SnapshotDataStoreDao extends GenericDao<SnapshotDataStoreVO, Lo
6060
SnapshotDataStoreVO findOldestSnapshotForVolume(Long volumeId, DataStoreRole role);
6161

6262
void updateVolumeIds(long oldVolId, long newVolId);
63+
64+
SnapshotDataStoreVO findByVolume(long volumeId, DataStoreRole role);
65+
6366
}

engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ public SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role) {
7272
SnapshotVO snapshot = snapshotDao.findById(snapshotId);
7373
SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshotId, role);
7474
if (snapshotStore == null) {
75-
return null;
75+
snapshotStore = snapshotStoreDao.findByVolume(snapshot.getVolumeId(), role);
76+
if (snapshotStore == null) {
77+
return null;
78+
}
7679
}
7780
DataStore store = storeMgr.getDataStore(snapshotStore.getDataStoreId(), role);
7881
SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store);

engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,16 +407,16 @@ public boolean deleteSnapshot(SnapshotInfo snapInfo) {
407407
}
408408

409409
@Override
410-
public boolean revertSnapshot(Long snapshotId) {
411-
SnapshotInfo snapshot = _snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
412-
PrimaryDataStore store = (PrimaryDataStore)snapshot.getDataStore();
410+
public boolean revertSnapshot(SnapshotInfo snapshot) {
411+
SnapshotInfo snapshotOnPrimaryStore = _snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
412+
PrimaryDataStore store = (PrimaryDataStore)snapshotOnPrimaryStore.getDataStore();
413413

414414
AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
415415
RevertSnapshotContext<CommandResult> context = new RevertSnapshotContext<CommandResult>(null, snapshot, future);
416416
AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
417417
caller.setCallback(caller.getTarget().revertSnapshotCallback(null, null)).setContext(context);
418418

419-
((PrimaryDataStoreDriver)store.getDriver()).revertSnapshot(snapshot, caller);
419+
((PrimaryDataStoreDriver)store.getDriver()).revertSnapshot(snapshot, snapshotOnPrimaryStore, caller);
420420

421421
SnapshotResult result = null;
422422
try {

engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) {
3737
}
3838

3939
@Override
40-
public boolean revertSnapshot(Long snapshotId) {
41-
return snapshotSvr.revertSnapshot(snapshotId);
40+
public boolean revertSnapshot(SnapshotInfo snapshot) {
41+
return snapshotSvr.revertSnapshot(snapshot);
4242
}
4343
}

0 commit comments

Comments
 (0)