]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/internal-snapshot.patch
use qemu_savevm_state instead of qemu_savevm_state_complete
[pve-qemu-kvm.git] / debian / patches / internal-snapshot.patch
1 Index: new/qapi-schema.json
2 ===================================================================
3 --- new.orig/qapi-schema.json 2012-09-04 12:52:21.000000000 +0200
4 +++ new/qapi-schema.json 2012-09-04 12:53:35.000000000 +0200
5 @@ -2493,3 +2493,10 @@
6 # Since: 1.2.0
7 ##
8 { 'command': 'query-target', 'returns': 'TargetInfo' }
9 +
10 +
11 +{ 'command': 'snapshot-start' 'data': { 'statefile': 'str' } }
12 +
13 +{ 'command': 'snapshot-drive', 'data': { 'device': 'str', 'name': 'str' } }
14 +
15 +{ 'command': 'snapshot-end' }
16 Index: new/qmp.c
17 ===================================================================
18 --- new.orig/qmp.c 2012-09-04 12:52:21.000000000 +0200
19 +++ new/qmp.c 2012-09-05 10:34:10.000000000 +0200
20 @@ -479,3 +479,155 @@
21 return arch_query_cpu_definitions(errp);
22 }
23
24 +static struct SnapshotState {
25 + int in_progress;
26 + int saved_vm_running;
27 +} snap_state;
28 +
29 +void qmp_snapshot_start(const char *statefile, Error **errp)
30 +{
31 + QEMUFile *f;
32 + int ret;
33 +
34 + if (snap_state.in_progress) {
35 + error_set(errp, ERROR_CLASS_GENERIC_ERROR,
36 + "VM snapshot already started\n");
37 + return;
38 + }
39 +
40 + snap_state.in_progress = 1;
41 +
42 + snap_state.saved_vm_running = runstate_is_running();
43 +
44 + vm_stop(RUN_STATE_SAVE_VM);
45 +
46 + f = qemu_fopen(statefile, "wb");
47 + if (!f) {
48 + error_set(errp, QERR_OPEN_FILE_FAILED, statefile);
49 + goto restart;
50 + }
51 +
52 + ret = qemu_savevm_state(f);
53 + qemu_fclose(f);
54 + if (ret < 0) {
55 + error_set(errp, ERROR_CLASS_GENERIC_ERROR,
56 + "Error %d while writing VM state\n", ret);
57 + goto restart;
58 + }
59 +
60 + return;
61 +
62 +restart:
63 +
64 + snap_state.in_progress = 0;
65 +
66 + if (snap_state.saved_vm_running) {
67 + vm_start();
68 + }
69 +}
70 +
71 +void qmp_snapshot_end(Error **errp)
72 +{
73 + if (!snap_state.in_progress) {
74 + error_set(errp, ERROR_CLASS_GENERIC_ERROR,
75 + "VM snapshot not started\n");
76 + return;
77 + }
78 + snap_state.in_progress = 0;
79 +
80 + if (snap_state.saved_vm_running) {
81 + vm_start();
82 + }
83 +}
84 +
85 +/* Fixme: Copied from savevm */
86 +static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
87 + const char *name)
88 +{
89 + QEMUSnapshotInfo *sn_tab, *sn;
90 + int nb_sns, i, ret;
91 +
92 + ret = -ENOENT;
93 + nb_sns = bdrv_snapshot_list(bs, &sn_tab);
94 + if (nb_sns < 0)
95 + return ret;
96 + for(i = 0; i < nb_sns; i++) {
97 + sn = &sn_tab[i];
98 + if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
99 + *sn_info = *sn;
100 + ret = 0;
101 + break;
102 + }
103 + }
104 + g_free(sn_tab);
105 + return ret;
106 +}
107 +
108 +void qmp_snapshot_drive(const char *device, const char *name, Error **errp)
109 +{
110 + BlockDriverState *bs;
111 + QEMUSnapshotInfo sn1, *sn = &sn1;
112 + int ret;
113 +#ifdef _WIN32
114 + struct _timeb tb;
115 +#else
116 + struct timeval tv;
117 +#endif
118 +
119 + if (!snap_state.in_progress) {
120 + error_set(errp, ERROR_CLASS_GENERIC_ERROR,
121 + "VM snapshot not started\n");
122 + return;
123 + }
124 +
125 + bs = bdrv_find(device);
126 + if (!bs) {
127 + error_set(errp, QERR_DEVICE_NOT_FOUND, device);
128 + return;
129 + }
130 +
131 + if (!bdrv_is_inserted(bs)) {
132 + error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
133 + return;
134 + }
135 +
136 + if (bdrv_is_read_only(bs)) {
137 + error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
138 + return;
139 + }
140 +
141 + if (!bdrv_can_snapshot(bs)) {
142 + error_set(errp, QERR_NOT_SUPPORTED);
143 + return;
144 + }
145 +
146 + if (bdrv_snapshot_find(bs, sn, name) >= 0) {
147 + error_set(errp, ERROR_CLASS_GENERIC_ERROR,
148 + "snapshot '%s' already exists", name);
149 + return;
150 + }
151 +
152 + sn = &sn1;
153 + memset(sn, 0, sizeof(*sn));
154 +
155 +#ifdef _WIN32
156 + _ftime(&tb);
157 + sn->date_sec = tb.time;
158 + sn->date_nsec = tb.millitm * 1000000;
159 +#else
160 + gettimeofday(&tv, NULL);
161 + sn->date_sec = tv.tv_sec;
162 + sn->date_nsec = tv.tv_usec * 1000;
163 +#endif
164 + sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
165 +
166 + pstrcpy(sn->name, sizeof(sn->name), name);
167 +
168 + sn->vm_state_size = 0; /* do not save state */
169 +
170 + ret = bdrv_snapshot_create(bs, sn);
171 + if (ret < 0) {
172 + error_set(errp, ERROR_CLASS_GENERIC_ERROR, "Error while creating snapshot on '%s'\n", device);
173 + return;
174 + }
175 +}
176 Index: new/qmp-commands.hx
177 ===================================================================
178 --- new.orig/qmp-commands.hx 2012-09-04 12:52:21.000000000 +0200
179 +++ new/qmp-commands.hx 2012-09-04 12:53:35.000000000 +0200
180 @@ -2514,3 +2514,21 @@
181 .args_type = "",
182 .mhandler.cmd_new = qmp_marshal_input_query_target,
183 },
184 +
185 + {
186 + .name = "snapshot-start",
187 + .args_type = "statefile:s",
188 + .mhandler.cmd_new = qmp_marshal_input_snapshot_start,
189 + },
190 +
191 + {
192 + .name = "snapshot-drive",
193 + .args_type = "device:s,name:s",
194 + .mhandler.cmd_new = qmp_marshal_input_snapshot_drive,
195 + },
196 +
197 + {
198 + .name = "snapshot-end",
199 + .args_type = "",
200 + .mhandler.cmd_new = qmp_marshal_input_snapshot_end,
201 + },
202 Index: new/hmp.c
203 ===================================================================
204 --- new.orig/hmp.c 2012-09-04 12:52:21.000000000 +0200
205 +++ new/hmp.c 2012-09-04 12:53:35.000000000 +0200
206 @@ -1102,3 +1102,30 @@
207 qmp_closefd(fdname, &errp);
208 hmp_handle_error(mon, &errp);
209 }
210 +
211 +void hmp_snapshot_start(Monitor *mon, const QDict *qdict)
212 +{
213 + Error *errp = NULL;
214 + const char *statefile = qdict_get_str(qdict, "statefile");
215 +
216 + qmp_snapshot_start(statefile, &errp);
217 + hmp_handle_error(mon, &errp);
218 +}
219 +
220 +void hmp_snapshot_drive(Monitor *mon, const QDict *qdict)
221 +{
222 + Error *errp = NULL;
223 + const char *name = qdict_get_str(qdict, "name");
224 + const char *device = qdict_get_str(qdict, "device");
225 +
226 + qmp_snapshot_drive(device, name, &errp);
227 + hmp_handle_error(mon, &errp);
228 +}
229 +
230 +void hmp_snapshot_end(Monitor *mon, const QDict *qdict)
231 +{
232 + Error *errp = NULL;
233 +
234 + qmp_snapshot_end(&errp);
235 + hmp_handle_error(mon, &errp);
236 +}
237 Index: new/hmp.h
238 ===================================================================
239 --- new.orig/hmp.h 2012-09-04 12:52:21.000000000 +0200
240 +++ new/hmp.h 2012-09-04 12:53:35.000000000 +0200
241 @@ -71,5 +71,8 @@
242 void hmp_netdev_del(Monitor *mon, const QDict *qdict);
243 void hmp_getfd(Monitor *mon, const QDict *qdict);
244 void hmp_closefd(Monitor *mon, const QDict *qdict);
245 +void hmp_snapshot_start(Monitor *mon, const QDict *qdict);
246 +void hmp_snapshot_drive(Monitor *mon, const QDict *qdict);
247 +void hmp_snapshot_end(Monitor *mon, const QDict *qdict);
248
249 #endif
250 Index: new/hmp-commands.hx
251 ===================================================================
252 --- new.orig/hmp-commands.hx 2012-09-04 12:52:21.000000000 +0200
253 +++ new/hmp-commands.hx 2012-09-04 12:53:35.000000000 +0200
254 @@ -1494,3 +1494,28 @@
255 STEXI
256 @end table
257 ETEXI
258 +
259 + {
260 + .name = "snapshot-start",
261 + .args_type = "statefile:s",
262 + .params = "statefile",
263 + .help = "Prepare for snapshot and halt VM. Save VM state to statefile.",
264 + .mhandler.cmd = hmp_snapshot_start,
265 + },
266 +
267 +
268 + {
269 + .name = "snapshot-drive",
270 + .args_type = "device:s,name:s",
271 + .params = "device name",
272 + .help = "Create internal snapshot.",
273 + .mhandler.cmd = hmp_snapshot_drive,
274 + },
275 +
276 + {
277 + .name = "snapshot-end",
278 + .args_type = "",
279 + .params = "",
280 + .help = "Resume VM after snaphot.",
281 + .mhandler.cmd = hmp_snapshot_end,
282 + },
283 Index: new/savevm.c
284 ===================================================================
285 --- new.orig/savevm.c 2012-09-05 10:27:37.000000000 +0200
286 +++ new/savevm.c 2012-09-05 10:27:44.000000000 +0200
287 @@ -1724,7 +1724,7 @@
288 }
289 }
290
291 -static int qemu_savevm_state(QEMUFile *f)
292 +int qemu_savevm_state(QEMUFile *f)
293 {
294 int ret;
295 MigrationParams params = {
296 Index: new/sysemu.h
297 ===================================================================
298 --- new.orig/sysemu.h 2012-09-05 10:30:42.000000000 +0200
299 +++ new/sysemu.h 2012-09-05 10:30:58.000000000 +0200
300 @@ -83,6 +83,7 @@
301 int qemu_savevm_state_iterate(QEMUFile *f);
302 int qemu_savevm_state_complete(QEMUFile *f);
303 void qemu_savevm_state_cancel(QEMUFile *f);
304 +int qemu_savevm_state(QEMUFile *f);
305 int qemu_loadvm_state(QEMUFile *f);
306
307 /* SLIRP */