Skip to content

Commit 53eb2c5

Browse files
JoaoJandreJoão Jandrewinterhazel
authored
File-based disk-only VM snapshot with KVM as hypervisor (#10632)
Co-authored-by: João Jandre <[email protected]> Co-authored-by: Fabricio Duarte <[email protected]>
1 parent bb75abc commit 53eb2c5

File tree

41 files changed

+2412
-167
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2412
-167
lines changed

agent/src/main/java/com/cloud/agent/properties/AgentProperties.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ public class AgentProperties{
155155
*/
156156
public static final Property<Integer> CMDS_TIMEOUT = new Property<>("cmds.timeout", 7200);
157157

158+
/**
159+
* The timeout (in seconds) for the snapshot merge operation, mainly used for classic volume snapshots and disk-only VM snapshots on file-based storage.<br>
160+
* This configuration is only considered if libvirt.events.enabled is also true. <br>
161+
* Data type: Integer.<br>
162+
* Default value: <code>259200</code>
163+
*/
164+
public static final Property<Integer> QCOW2_DELTA_MERGE_TIMEOUT = new Property<>("qcow2.delta.merge.timeout", 60 * 60 * 72);
165+
158166
/**
159167
* This parameter sets the VM migration speed (in mbps). The default value is -1,<br>
160168
* which means that the agent will try to guess the speed of the guest network and consume all possible bandwidth.<br>

api/src/main/java/com/cloud/storage/VolumeApiService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ Volume updateVolume(long volumeId, String path, String state, Long storageId,
137137

138138
void updateDisplay(Volume volume, Boolean displayVolume);
139139

140-
Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName) throws ResourceAllocationException;
140+
Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName, Long vmSnapshotId) throws ResourceAllocationException;
141141

142142
/**
143143
* Checks if the storage pool supports the disk offering tags.

api/src/main/java/com/cloud/vm/snapshot/VMSnapshot.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public interface VMSnapshot extends ControlledEntity, Identity, InternalIdentity
3131
enum State {
3232
Allocated("The VM snapshot is allocated but has not been created yet."), Creating("The VM snapshot is being created."), Ready(
3333
"The VM snapshot is ready to be used."), Reverting("The VM snapshot is being used to revert"), Expunging("The volume is being expunging"), Removed(
34-
"The volume is destroyed, and can't be recovered."), Error("The volume is in error state, and can't be recovered");
34+
"The volume is destroyed, and can't be recovered."), Error("The volume is in error state, and can't be recovered"),
35+
Hidden("The VM snapshot is hidden from the user and cannot be recovered.");
3536

3637
String _description;
3738

@@ -60,6 +61,8 @@ public String getDescription() {
6061
s_fsm.addTransition(Expunging, Event.ExpungeRequested, Expunging);
6162
s_fsm.addTransition(Expunging, Event.OperationSucceeded, Removed);
6263
s_fsm.addTransition(Expunging, Event.OperationFailed, Error);
64+
s_fsm.addTransition(Expunging, Event.Hide, Hidden);
65+
s_fsm.addTransition(Hidden, Event.ExpungeRequested, Expunging);
6366
}
6467
}
6568

@@ -68,7 +71,7 @@ enum Type {
6871
}
6972

7073
enum Event {
71-
CreateRequested, OperationFailed, OperationSucceeded, RevertRequested, ExpungeRequested,
74+
CreateRequested, OperationFailed, OperationSucceeded, RevertRequested, ExpungeRequested, Hide,
7275
}
7376

7477
@Override

api/src/main/java/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotFromVMSnapshotCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public ApiCommandResourceType getApiResourceType() {
153153

154154
@Override
155155
public void create() throws ResourceAllocationException {
156-
Snapshot snapshot = this._volumeService.allocSnapshotForVm(getVmId(), getVolumeId(), getSnapshotName());
156+
Snapshot snapshot = this._volumeService.allocSnapshotForVm(getVmId(), getVolumeId(), getSnapshotName(), getVMSnapshotId());
157157
if (snapshot != null) {
158158
this.setEntityId(snapshot.getId());
159159
this.setEntityUuid(snapshot.getUuid());
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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 com.cloud.agent.api.storage;
20+
21+
import com.cloud.agent.api.Answer;
22+
import com.cloud.agent.api.Command;
23+
import com.cloud.utils.Pair;
24+
25+
import java.util.Map;
26+
27+
public class CreateDiskOnlyVmSnapshotAnswer extends Answer {
28+
29+
protected Map<String, Pair<Long, String>> mapVolumeToSnapshotSizeAndNewVolumePath;
30+
31+
public CreateDiskOnlyVmSnapshotAnswer(Command command, boolean success, String details, Map<String, Pair<Long, String>> mapVolumeToSnapshotSizeAndNewVolumePath) {
32+
super(command, success, details);
33+
this.mapVolumeToSnapshotSizeAndNewVolumePath = mapVolumeToSnapshotSizeAndNewVolumePath;
34+
}
35+
36+
public Map<String, Pair<Long, String>> getMapVolumeToSnapshotSizeAndNewVolumePath() {
37+
return mapVolumeToSnapshotSizeAndNewVolumePath;
38+
}
39+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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 com.cloud.agent.api.storage;
20+
21+
22+
import com.cloud.agent.api.VMSnapshotBaseCommand;
23+
import com.cloud.agent.api.VMSnapshotTO;
24+
import com.cloud.vm.VirtualMachine;
25+
import org.apache.cloudstack.storage.to.VolumeObjectTO;
26+
27+
import java.util.List;
28+
29+
public class CreateDiskOnlyVmSnapshotCommand extends VMSnapshotBaseCommand {
30+
31+
protected VirtualMachine.State vmState;
32+
33+
public CreateDiskOnlyVmSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeObjectTO> volumeTOs, String guestOSType, VirtualMachine.State vmState) {
34+
super(vmName, snapshot, volumeTOs, guestOSType);
35+
this.vmState = vmState;
36+
}
37+
38+
public VirtualMachine.State getVmState() {
39+
return vmState;
40+
}
41+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 com.cloud.agent.api.storage;
20+
21+
import com.cloud.agent.api.Command;
22+
23+
import com.cloud.agent.api.to.DataTO;
24+
25+
26+
import java.util.List;
27+
28+
public class DeleteDiskOnlyVmSnapshotCommand extends Command {
29+
30+
List<DataTO> snapshots;
31+
32+
public DeleteDiskOnlyVmSnapshotCommand(List<DataTO> snapshots) {
33+
this.snapshots = snapshots;
34+
}
35+
36+
public List<DataTO> getSnapshots() {
37+
return snapshots;
38+
}
39+
40+
@Override
41+
public boolean executeInSequence() {
42+
return false;
43+
}
44+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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 com.cloud.agent.api.storage;
20+
21+
import com.cloud.agent.api.Command;
22+
import com.cloud.vm.VirtualMachine;
23+
24+
import java.util.List;
25+
26+
public class MergeDiskOnlyVmSnapshotCommand extends Command {
27+
28+
private List<SnapshotMergeTreeTO> snapshotMergeTreeToList;
29+
private VirtualMachine.State vmState;
30+
private String vmName;
31+
32+
public MergeDiskOnlyVmSnapshotCommand(List<SnapshotMergeTreeTO> snapshotMergeTreeToList, VirtualMachine.State vmState, String vmName) {
33+
this.snapshotMergeTreeToList = snapshotMergeTreeToList;
34+
this.vmState = vmState;
35+
this.vmName = vmName;
36+
}
37+
38+
public List<SnapshotMergeTreeTO> getSnapshotMergeTreeToList() {
39+
return snapshotMergeTreeToList;
40+
}
41+
42+
public VirtualMachine.State getVmState() {
43+
return vmState;
44+
}
45+
46+
public String getVmName() {
47+
return vmName;
48+
}
49+
50+
@Override
51+
public boolean executeInSequence() {
52+
return false;
53+
}
54+
55+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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 com.cloud.agent.api.storage;
20+
21+
import com.cloud.agent.api.Answer;
22+
import com.cloud.agent.api.Command;
23+
import org.apache.cloudstack.storage.to.VolumeObjectTO;
24+
25+
import java.util.List;
26+
27+
public class RevertDiskOnlyVmSnapshotAnswer extends Answer {
28+
List<VolumeObjectTO> volumeObjectTos;
29+
30+
public RevertDiskOnlyVmSnapshotAnswer(Command cmd, List<VolumeObjectTO> volumeObjectTos) {
31+
super(cmd, true, null);
32+
this.volumeObjectTos = volumeObjectTos;
33+
}
34+
35+
public List<VolumeObjectTO> getVolumeObjectTos() {
36+
return volumeObjectTos;
37+
}
38+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 com.cloud.agent.api.storage;
20+
21+
import com.cloud.agent.api.Command;
22+
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
23+
24+
import java.util.List;
25+
26+
public class RevertDiskOnlyVmSnapshotCommand extends Command {
27+
28+
private List<SnapshotObjectTO> snapshotObjectTos;
29+
private String vmName;
30+
31+
public RevertDiskOnlyVmSnapshotCommand(List<SnapshotObjectTO> snapshotObjectTos, String vmName) {
32+
super();
33+
this.snapshotObjectTos = snapshotObjectTos;
34+
this.vmName = vmName;
35+
}
36+
37+
public List<SnapshotObjectTO> getSnapshotObjectTos() {
38+
return snapshotObjectTos;
39+
}
40+
41+
public String getVmName() {
42+
return vmName;
43+
}
44+
45+
@Override
46+
public boolean executeInSequence() {
47+
return false;
48+
}
49+
50+
}

0 commit comments

Comments
 (0)