@samitouri / QOSamiQemu / commits / c839600179

migration/vmstate-types: move to new migration APIs

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Reviewed-by: Peter Xu <peterx@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260304212303.667141-19-vsementsov@yandex-team.ru Signed-off-by: Fabiano Rosas <farosas@suse.de>

Vladimir Sementsov-Ogievskiy committed Mar 5, 2026 at 00:23 UTC c8396001792fd1ed2d3c1d85b1a12ebb8f736c49
2 files changed +327 -324
migration/trace-events
+12 -12
@@ -72,20 +72,20 @@ vmstate_subsection_save_top(const char *idstr) "%s"
72 vmstate_field_exists(const char *vmsd, const char *name, int field_version, int version, int result) "%s:%s field_version %d version %d result %d"
73
74 # vmstate-types.c
75 -get_qtailq(const char *name, int version_id) "%s v%d"
76 -get_qtailq_end(const char *name, const char *reason, int val) "%s %s/%d"
77 -put_qtailq(const char *name, int version_id) "%s v%d"
78 -put_qtailq_end(const char *name, const char *reason) "%s %s"
75 +load_qtailq(const char *name, int version_id) "%s v%d"
76 +load_qtailq_end(const char *name) "%s"
77 +save_qtailq(const char *name, int version_id) "%s v%d"
78 +save_qtailq_end(const char *name) "%s"
79
80 -get_gtree(const char *field_name, const char *key_vmsd_name, const char *val_vmsd_name, uint32_t nnodes) "%s(%s/%s) nnodes=%d"
81 -get_gtree_end(const char *field_name, const char *key_vmsd_name, const char *val_vmsd_name, int ret) "%s(%s/%s) %d"
82 -put_gtree(const char *field_name, const char *key_vmsd_name, const char *val_vmsd_name, uint32_t nnodes) "%s(%s/%s) nnodes=%d"
83 -put_gtree_end(const char *field_name, const char *key_vmsd_name, const char *val_vmsd_name, int ret) "%s(%s/%s) %d"
80 +load_gtree(const char *field_name, const char *key_vmsd_name, const char *val_vmsd_name, uint32_t nnodes) "%s(%s/%s) nnodes=%d"
81 +load_gtree_end(const char *field_name, const char *key_vmsd_name, const char *val_vmsd_name) "%s(%s/%s)"
82 +save_gtree(const char *field_name, const char *key_vmsd_name, const char *val_vmsd_name, uint32_t nnodes) "%s(%s/%s) nnodes=%d"
83 +save_gtree_end(const char *field_name, const char *key_vmsd_name, const char *val_vmsd_name) "%s(%s/%s)"
84
85 -get_qlist(const char *field_name, const char *vmsd_name, int version_id) "%s(%s v%d)"
86 -get_qlist_end(const char *field_name, const char *vmsd_name) "%s(%s)"
87 -put_qlist(const char *field_name, const char *vmsd_name, int version_id) "%s(%s v%d)"
88 -put_qlist_end(const char *field_name, const char *vmsd_name) "%s(%s)"
85 +load_qlist(const char *field_name, const char *vmsd_name, int version_id) "%s(%s v%d)"
86 +load_qlist_end(const char *field_name, const char *vmsd_name) "%s(%s)"
87 +save_qlist(const char *field_name, const char *vmsd_name, int version_id) "%s(%s v%d)"
88 +save_qlist_end(const char *field_name, const char *vmsd_name) "%s(%s)"
89
90 # qemu-file.c
91 qemu_file_fclose(void) ""
migration/vmstate-types.c
+315 -312
@@ -23,129 +23,135 @@
23
24 /* bool */
25
26 -static int get_bool(QEMUFile *f, void *pv, size_t size,
27 - const VMStateField *field)
26 +static bool load_bool(QEMUFile *f, void *pv, size_t size,
27 + const VMStateField *field, Error **errp)
28 {
29 bool *v = pv;
30 *v = qemu_get_byte(f);
31 - return 0;
31 + return true;
32 }
33
34 -static int put_bool(QEMUFile *f, void *pv, size_t size,
35 - const VMStateField *field, JSONWriter *vmdesc)
34 +static bool save_bool(QEMUFile *f, void *pv, size_t size,
35 + const VMStateField *field, JSONWriter *vmdesc,
36 + Error **errp)
37 {
38 bool *v = pv;
39 qemu_put_byte(f, *v);
39 - return 0;
40 + return true;
41 }
42
43 const VMStateInfo vmstate_info_bool = {
44 .name = "bool",
44 - .get = get_bool,
45 - .put = put_bool,
45 + .load = load_bool,
46 + .save = save_bool,
47 };
48
49 /* 8 bit int */
50
50 -static int get_int8(QEMUFile *f, void *pv, size_t size,
51 - const VMStateField *field)
51 +static bool load_int8(QEMUFile *f, void *pv, size_t size,
52 + const VMStateField *field, Error **errp)
53 {
54 int8_t *v = pv;
55 qemu_get_s8s(f, v);
55 - return 0;
56 + return true;
57 }
58
58 -static int put_int8(QEMUFile *f, void *pv, size_t size,
59 - const VMStateField *field, JSONWriter *vmdesc)
59 +static bool save_int8(QEMUFile *f, void *pv, size_t size,
60 + const VMStateField *field, JSONWriter *vmdesc,
61 + Error **errp)
62 {
63 int8_t *v = pv;
64 qemu_put_s8s(f, v);
63 - return 0;
65 + return true;
66 }
67
68 const VMStateInfo vmstate_info_int8 = {
69 .name = "int8",
68 - .get = get_int8,
69 - .put = put_int8,
70 + .load = load_int8,
71 + .save = save_int8,
72 };
73
74 /* 16 bit int */
75
74 -static int get_int16(QEMUFile *f, void *pv, size_t size,
75 - const VMStateField *field)
76 +static bool load_int16(QEMUFile *f, void *pv, size_t size,
77 + const VMStateField *field, Error **errp)
78 {
79 int16_t *v = pv;
80 qemu_get_sbe16s(f, v);
79 - return 0;
81 + return true;
82 }
83
82 -static int put_int16(QEMUFile *f, void *pv, size_t size,
83 - const VMStateField *field, JSONWriter *vmdesc)
84 +static bool save_int16(QEMUFile *f, void *pv, size_t size,
85 + const VMStateField *field, JSONWriter *vmdesc,
86 + Error **errp)
87 {
88 int16_t *v = pv;
89 qemu_put_sbe16s(f, v);
87 - return 0;
90 + return true;
91 }
92
93 const VMStateInfo vmstate_info_int16 = {
94 .name = "int16",
92 - .get = get_int16,
93 - .put = put_int16,
95 + .load = load_int16,
96 + .save = save_int16,
97 };
98
99 /* 32 bit int */
100
98 -static int get_int32(QEMUFile *f, void *pv, size_t size,
99 - const VMStateField *field)
101 +static bool load_int32(QEMUFile *f, void *pv, size_t size,
102 + const VMStateField *field, Error **errp)
103 {
104 int32_t *v = pv;
105 qemu_get_sbe32s(f, v);
103 - return 0;
106 + return true;
107 }
108
106 -static int put_int32(QEMUFile *f, void *pv, size_t size,
107 - const VMStateField *field, JSONWriter *vmdesc)
109 +static bool save_int32(QEMUFile *f, void *pv, size_t size,
110 + const VMStateField *field, JSONWriter *vmdesc,
111 + Error **errp)
112 {
113 int32_t *v = pv;
114 qemu_put_sbe32s(f, v);
111 - return 0;
115 + return true;
116 }
117
118 const VMStateInfo vmstate_info_int32 = {
119 .name = "int32",
116 - .get = get_int32,
117 - .put = put_int32,
120 + .load = load_int32,
121 + .save = save_int32,
122 };
123
124 /* 32 bit int. See that the received value is the same than the one
125 in the field */
126
123 -static int get_int32_equal(QEMUFile *f, void *pv, size_t size,
124 - const VMStateField *field)
127 +static bool load_int32_equal(QEMUFile *f, void *pv, size_t size,
128 + const VMStateField *field, Error **errp)
129 {
130 + ERRP_GUARD();
131 int32_t *v = pv;
132 int32_t v2;
133 qemu_get_sbe32s(f, &v2);
134
135 if (*v == v2) {
131 - return 0;
136 + return true;
137 }
133 - error_report("%" PRIx32 " != %" PRIx32, *v, v2);
134 - return -EINVAL;
138 +
139 + error_setg(errp, "%" PRIx32 " != %" PRIx32, *v, v2);
140 + return false;
141 }
142
143 const VMStateInfo vmstate_info_int32_equal = {
144 .name = "int32 equal",
139 - .get = get_int32_equal,
140 - .put = put_int32,
145 + .load = load_int32_equal,
146 + .save = save_int32,
147 };
148
149 /* 32 bit int. Check that the received value is non-negative
150 * and less than or equal to the one in the field.
151 */
152
147 -static int get_int32_le(QEMUFile *f, void *pv, size_t size,
148 - const VMStateField *field)
153 +static bool load_int32_le(QEMUFile *f, void *pv, size_t size,
154 + const VMStateField *field, Error **errp)
155 {
156 int32_t *cur = pv;
157 int32_t loaded;
@@ -153,348 +159,373 @@ static int get_int32_le(QEMUFile *f, void *pv, size_t size,
159
160 if (loaded >= 0 && loaded <= *cur) {
161 *cur = loaded;
156 - return 0;
162 + return true;
163 }
158 - error_report("Invalid value %" PRId32
159 - " expecting positive value <= %" PRId32,
160 - loaded, *cur);
161 - return -EINVAL;
164 +
165 + error_setg(errp, "Invalid value %" PRId32
166 + " expecting positive value <= %" PRId32,
167 + loaded, *cur);
168 + return false;
169 }
170
171 const VMStateInfo vmstate_info_int32_le = {
172 .name = "int32 le",
166 - .get = get_int32_le,
167 - .put = put_int32,
173 + .load = load_int32_le,
174 + .save = save_int32,
175 };
176
177 /* 64 bit int */
178
172 -static int get_int64(QEMUFile *f, void *pv, size_t size,
173 - const VMStateField *field)
179 +static bool load_int64(QEMUFile *f, void *pv, size_t size,
180 + const VMStateField *field, Error **errp)
181 {
182 int64_t *v = pv;
183 qemu_get_sbe64s(f, v);
177 - return 0;
184 + return true;
185 }
186
180 -static int put_int64(QEMUFile *f, void *pv, size_t size,
181 - const VMStateField *field, JSONWriter *vmdesc)
187 +static bool save_int64(QEMUFile *f, void *pv, size_t size,
188 + const VMStateField *field, JSONWriter *vmdesc,
189 + Error **errp)
190 {
191 int64_t *v = pv;
192 qemu_put_sbe64s(f, v);
185 - return 0;
193 + return true;
194 }
195
196 const VMStateInfo vmstate_info_int64 = {
197 .name = "int64",
190 - .get = get_int64,
191 - .put = put_int64,
198 + .load = load_int64,
199 + .save = save_int64,
200 };
201
202 /* 8 bit unsigned int */
203
196 -static int get_uint8(QEMUFile *f, void *pv, size_t size,
197 - const VMStateField *field)
204 +static bool load_uint8(QEMUFile *f, void *pv, size_t size,
205 + const VMStateField *field, Error **errp)
206 {
207 uint8_t *v = pv;
208 qemu_get_8s(f, v);
201 - return 0;
209 + return true;
210 }
211
204 -static int put_uint8(QEMUFile *f, void *pv, size_t size,
205 - const VMStateField *field, JSONWriter *vmdesc)
212 +static bool save_uint8(QEMUFile *f, void *pv, size_t size,
213 + const VMStateField *field, JSONWriter *vmdesc,
214 + Error **errp)
215 {
216 uint8_t *v = pv;
217 qemu_put_8s(f, v);
209 - return 0;
218 + return true;
219 }
220
221 const VMStateInfo vmstate_info_uint8 = {
222 .name = "uint8",
214 - .get = get_uint8,
215 - .put = put_uint8,
223 + .load = load_uint8,
224 + .save = save_uint8,
225 };
226
227 /* 16 bit unsigned int */
228
220 -static int get_uint16(QEMUFile *f, void *pv, size_t size,
221 - const VMStateField *field)
229 +static bool load_uint16(QEMUFile *f, void *pv, size_t size,
230 + const VMStateField *field, Error **errp)
231 {
232 uint16_t *v = pv;
233 qemu_get_be16s(f, v);
225 - return 0;
234 + return true;
235 }
236
228 -static int put_uint16(QEMUFile *f, void *pv, size_t size,
229 - const VMStateField *field, JSONWriter *vmdesc)
237 +static bool save_uint16(QEMUFile *f, void *pv, size_t size,
238 + const VMStateField *field, JSONWriter *vmdesc,
239 + Error **errp)
240 {
241 uint16_t *v = pv;
242 qemu_put_be16s(f, v);
233 - return 0;
243 + return true;
244 }
245
246 const VMStateInfo vmstate_info_uint16 = {
247 .name = "uint16",
238 - .get = get_uint16,
239 - .put = put_uint16,
248 + .load = load_uint16,
249 + .save = save_uint16,
250 };
251
252 /* 32 bit unsigned int */
253
244 -static int get_uint32(QEMUFile *f, void *pv, size_t size,
245 - const VMStateField *field)
254 +static bool load_uint32(QEMUFile *f, void *pv, size_t size,
255 + const VMStateField *field, Error **errp)
256 {
257 uint32_t *v = pv;
258 qemu_get_be32s(f, v);
249 - return 0;
259 + return true;
260 }
261
252 -static int put_uint32(QEMUFile *f, void *pv, size_t size,
253 - const VMStateField *field, JSONWriter *vmdesc)
262 +static bool save_uint32(QEMUFile *f, void *pv, size_t size,
263 + const VMStateField *field, JSONWriter *vmdesc,
264 + Error **errp)
265 {
266 uint32_t *v = pv;
267 qemu_put_be32s(f, v);
257 - return 0;
268 + return true;
269 }
270
271 const VMStateInfo vmstate_info_uint32 = {
272 .name = "uint32",
262 - .get = get_uint32,
263 - .put = put_uint32,
273 + .load = load_uint32,
274 + .save = save_uint32,
275 };
276
277 /* 32 bit uint. See that the received value is the same than the one
278 in the field */
279
269 -static int get_uint32_equal(QEMUFile *f, void *pv, size_t size,
270 - const VMStateField *field)
280 +static bool load_uint32_equal(QEMUFile *f, void *pv, size_t size,
281 + const VMStateField *field, Error **errp)
282 {
283 + ERRP_GUARD();
284 uint32_t *v = pv;
285 uint32_t v2;
286 qemu_get_be32s(f, &v2);
287
288 if (*v == v2) {
277 - return 0;
289 + return true;
290 }
279 - error_report("%" PRIx32 " != %" PRIx32, *v, v2);
280 - return -EINVAL;
291 +
292 + error_setg(errp, "%" PRIx32 " != %" PRIx32, *v, v2);
293 + return false;
294 }
295
296 const VMStateInfo vmstate_info_uint32_equal = {
297 .name = "uint32 equal",
285 - .get = get_uint32_equal,
286 - .put = put_uint32,
298 + .load = load_uint32_equal,
299 + .save = save_uint32,
300 };
301
302 /* 64 bit unsigned int */
303
291 -static int get_uint64(QEMUFile *f, void *pv, size_t size,
292 - const VMStateField *field)
304 +static bool load_uint64(QEMUFile *f, void *pv, size_t size,
305 + const VMStateField *field, Error **errp)
306 {
307 uint64_t *v = pv;
308 qemu_get_be64s(f, v);
296 - return 0;
309 + return true;
310 }
311
299 -static int put_uint64(QEMUFile *f, void *pv, size_t size,
300 - const VMStateField *field, JSONWriter *vmdesc)
312 +static bool save_uint64(QEMUFile *f, void *pv, size_t size,
313 + const VMStateField *field, JSONWriter *vmdesc,
314 + Error **errp)
315 {
316 uint64_t *v = pv;
317 qemu_put_be64s(f, v);
304 - return 0;
318 + return true;
319 }
320
321 const VMStateInfo vmstate_info_uint64 = {
322 .name = "uint64",
309 - .get = get_uint64,
310 - .put = put_uint64,
323 + .load = load_uint64,
324 + .save = save_uint64,
325 };
326
327 /* File descriptor communicated via SCM_RIGHTS */
328
315 -static int get_fd(QEMUFile *f, void *pv, size_t size,
316 - const VMStateField *field)
329 +static bool load_fd(QEMUFile *f, void *pv, size_t size,
330 + const VMStateField *field, Error **errp)
331 {
332 int32_t *v = pv;
333
334 if (migrate_mode() == MIG_MODE_CPR_EXEC) {
335 qemu_get_sbe32s(f, v);
322 - return 0;
336 + return true;
337 }
338
325 - return qemu_file_get_fd(f, v);
339 + return qemu_file_get_fd(f, v) >= 0;
340 }
341
328 -static int put_fd(QEMUFile *f, void *pv, size_t size,
329 - const VMStateField *field, JSONWriter *vmdesc)
342 +static bool save_fd(QEMUFile *f, void *pv, size_t size,
343 + const VMStateField *field, JSONWriter *vmdesc,
344 + Error **errp)
345 {
346 int32_t *v = pv;
347 +
348 if (migrate_mode() == MIG_MODE_CPR_EXEC) {
349 qemu_put_sbe32s(f, v);
334 - return 0;
350 + return true;
351 }
336 - return qemu_file_put_fd(f, *v);
352 +
353 + return qemu_file_put_fd(f, *v) >= 0;
354 }
355
356 const VMStateInfo vmstate_info_fd = {
357 .name = "fd",
341 - .get = get_fd,
342 - .put = put_fd,
358 + .load = load_fd,
359 + .save = save_fd,
360 };
361
345 -static int get_nullptr(QEMUFile *f, void *pv, size_t size,
346 - const VMStateField *field)
362 +static bool load_nullptr(QEMUFile *f, void *pv, size_t size,
363 + const VMStateField *field, Error **errp)
364
365 {
366 if (qemu_get_byte(f) == VMS_NULLPTR_MARKER) {
350 - return 0;
367 + return true;
368 }
352 - error_report("vmstate: get_nullptr expected VMS_NULLPTR_MARKER");
353 - return -EINVAL;
369 +
370 + error_setg(errp, "vmstate: load_nullptr expected VMS_NULLPTR_MARKER");
371 + return false;
372 }
373
356 -static int put_nullptr(QEMUFile *f, void *pv, size_t size,
357 - const VMStateField *field, JSONWriter *vmdesc)
374 +static bool save_nullptr(QEMUFile *f, void *pv, size_t size,
375 + const VMStateField *field, JSONWriter *vmdesc,
376 + Error **errp)
377
378 {
379 if (pv == NULL) {
380 qemu_put_byte(f, VMS_NULLPTR_MARKER);
362 - return 0;
381 + return true;
382 }
364 - error_report("vmstate: put_nullptr must be called with pv == NULL");
365 - return -EINVAL;
383 +
384 + error_setg(errp, "vmstate: save_nullptr must be called with pv == NULL");
385 + return false;
386 }
387
388 const VMStateInfo vmstate_info_nullptr = {
389 .name = "nullptr",
370 - .get = get_nullptr,
371 - .put = put_nullptr,
390 + .load = load_nullptr,
391 + .save = save_nullptr,
392 };
393
394 /* 64 bit unsigned int. See that the received value is the same than the one
395 in the field */
396
377 -static int get_uint64_equal(QEMUFile *f, void *pv, size_t size,
378 - const VMStateField *field)
397 +static bool load_uint64_equal(QEMUFile *f, void *pv, size_t size,
398 + const VMStateField *field, Error **errp)
399 {
400 + ERRP_GUARD();
401 uint64_t *v = pv;
402 uint64_t v2;
403 +
404 qemu_get_be64s(f, &v2);
405
406 if (*v == v2) {
385 - return 0;
407 + return true;
408 }
387 - error_report("%" PRIx64 " != %" PRIx64, *v, v2);
388 - return -EINVAL;
409 +
410 + error_setg(errp, "%" PRIx64 " != %" PRIx64, *v, v2);
411 + return false;
412 }
413
414 const VMStateInfo vmstate_info_uint64_equal = {
415 .name = "int64 equal",
393 - .get = get_uint64_equal,
394 - .put = put_uint64,
416 + .load = load_uint64_equal,
417 + .save = save_uint64,
418 };
419
420 /* 8 bit int. See that the received value is the same than the one
421 in the field */
422
400 -static int get_uint8_equal(QEMUFile *f, void *pv, size_t size,
401 - const VMStateField *field)
423 +static bool load_uint8_equal(QEMUFile *f, void *pv, size_t size,
424 + const VMStateField *field, Error **errp)
425 {
426 + ERRP_GUARD();
427 uint8_t *v = pv;
428 uint8_t v2;
429 +
430 qemu_get_8s(f, &v2);
431
432 if (*v == v2) {
408 - return 0;
433 + return true;
434 }
410 - error_report("%x != %x", *v, v2);
411 - return -EINVAL;
435 +
436 + error_setg(errp, "%x != %x", *v, v2);
437 + return false;
438 }
439
440 const VMStateInfo vmstate_info_uint8_equal = {
441 .name = "uint8 equal",
416 - .get = get_uint8_equal,
417 - .put = put_uint8,
442 + .load = load_uint8_equal,
443 + .save = save_uint8,
444 };
445
446 /* 16 bit unsigned int int. See that the received value is the same than the one
447 in the field */
448
423 -static int get_uint16_equal(QEMUFile *f, void *pv, size_t size,
424 - const VMStateField *field)
449 +static bool load_uint16_equal(QEMUFile *f, void *pv, size_t size,
450 + const VMStateField *field, Error **errp)
451 {
452 + ERRP_GUARD();
453 uint16_t *v = pv;
454 uint16_t v2;
455 +
456 qemu_get_be16s(f, &v2);
457
458 if (*v == v2) {
431 - return 0;
459 + return true;
460 }
433 - error_report("%x != %x", *v, v2);
434 - return -EINVAL;
461 +
462 + error_setg(errp, "%x != %x", *v, v2);
463 + return false;
464 }
465
466 const VMStateInfo vmstate_info_uint16_equal = {
467 .name = "uint16 equal",
439 - .get = get_uint16_equal,
440 - .put = put_uint16,
468 + .load = load_uint16_equal,
469 + .save = save_uint16,
470 };
471
472 /* CPU_DoubleU type */
473
445 -static int get_cpudouble(QEMUFile *f, void *pv, size_t size,
446 - const VMStateField *field)
474 +static bool load_cpudouble(QEMUFile *f, void *pv, size_t size,
475 + const VMStateField *field, Error **errp)
476 {
477 CPU_DoubleU *v = pv;
478 qemu_get_be32s(f, &v->l.upper);
479 qemu_get_be32s(f, &v->l.lower);
451 - return 0;
480 + return true;
481 }
482
454 -static int put_cpudouble(QEMUFile *f, void *pv, size_t size,
455 - const VMStateField *field, JSONWriter *vmdesc)
483 +static bool save_cpudouble(QEMUFile *f, void *pv, size_t size,
484 + const VMStateField *field, JSONWriter *vmdesc,
485 + Error **errp)
486 {
487 CPU_DoubleU *v = pv;
488 qemu_put_be32s(f, &v->l.upper);
489 qemu_put_be32s(f, &v->l.lower);
460 - return 0;
490 + return true;
491 }
492
493 const VMStateInfo vmstate_info_cpudouble = {
494 .name = "CPU_Double_U",
465 - .get = get_cpudouble,
466 - .put = put_cpudouble,
495 + .load = load_cpudouble,
496 + .save = save_cpudouble,
497 };
498
499 /* uint8_t buffers */
500
471 -static int get_buffer(QEMUFile *f, void *pv, size_t size,
472 - const VMStateField *field)
501 +static bool load_buffer(QEMUFile *f, void *pv, size_t size,
502 + const VMStateField *field, Error **errp)
503 {
504 uint8_t *v = pv;
505 qemu_get_buffer(f, v, size);
476 - return 0;
506 + return true;
507 }
508
479 -static int put_buffer(QEMUFile *f, void *pv, size_t size,
480 - const VMStateField *field, JSONWriter *vmdesc)
509 +static bool save_buffer(QEMUFile *f, void *pv, size_t size,
510 + const VMStateField *field, JSONWriter *vmdesc,
511 + Error **errp)
512 {
513 uint8_t *v = pv;
514 qemu_put_buffer(f, v, size);
484 - return 0;
515 + return true;
516 }
517
518 const VMStateInfo vmstate_info_buffer = {
519 .name = "buffer",
489 - .get = get_buffer,
490 - .put = put_buffer,
520 + .load = load_buffer,
521 + .save = save_buffer,
522 };
523
524 /* unused buffers: space that was used for some fields that are
525 not useful anymore */
526
496 -static int get_unused_buffer(QEMUFile *f, void *pv, size_t size,
497 - const VMStateField *field)
527 +static bool load_unused_buffer(QEMUFile *f, void *pv, size_t size,
528 + const VMStateField *field, Error **errp)
529 {
530 uint8_t buf[1024];
531 int block_len;
@@ -504,11 +535,13 @@ static int get_unused_buffer(QEMUFile *f, void *pv, size_t size,
535 size -= block_len;
536 qemu_get_buffer(f, buf, block_len);
537 }
507 - return 0;
538 +
539 + return true;
540 }
541
510 -static int put_unused_buffer(QEMUFile *f, void *pv, size_t size,
511 - const VMStateField *field, JSONWriter *vmdesc)
542 +static bool save_unused_buffer(QEMUFile *f, void *pv, size_t size,
543 + const VMStateField *field, JSONWriter *vmdesc,
544 + Error **errp)
545 {
546 static const uint8_t buf[1024];
547 int block_len;
@@ -519,13 +552,13 @@ static int put_unused_buffer(QEMUFile *f, void *pv, size_t size,
552 qemu_put_buffer(f, buf, block_len);
553 }
554
522 - return 0;
555 + return true;
556 }
557
558 const VMStateInfo vmstate_info_unused_buffer = {
559 .name = "unused_buffer",
527 - .get = get_unused_buffer,
528 - .put = put_unused_buffer,
560 + .load = load_unused_buffer,
561 + .save = save_unused_buffer,
562 };
563
564 /* vmstate_info_tmp, see VMSTATE_WITH_TMP, the idea is that we allocate
@@ -534,48 +567,34 @@ const VMStateInfo vmstate_info_unused_buffer = {
567 * in fields that don't really exist in the parent but need to be in the
568 * stream.
569 */
537 -static int get_tmp(QEMUFile *f, void *pv, size_t size,
538 - const VMStateField *field)
570 +static bool load_tmp(QEMUFile *f, void *pv, size_t size,
571 + const VMStateField *field, Error **errp)
572 {
540 - int ret;
541 - Error *local_err = NULL;
573 const VMStateDescription *vmsd = field->vmsd;
574 int version_id = field->version_id;
544 - void *tmp = g_malloc(size);
575 + g_autofree void *tmp = g_malloc(size);
576
577 /* Writes the parent field which is at the start of the tmp */
578 *(void **)tmp = pv;
548 - ret = vmstate_load_state(f, vmsd, tmp, version_id, &local_err);
549 - if (ret < 0) {
550 - error_report_err(local_err);
551 - }
552 - g_free(tmp);
553 - return ret;
579 + return vmstate_load_vmsd(f, vmsd, tmp, version_id, errp);
580 }
581
556 -static int put_tmp(QEMUFile *f, void *pv, size_t size,
557 - const VMStateField *field, JSONWriter *vmdesc)
582 +static bool save_tmp(QEMUFile *f, void *pv, size_t size,
583 + const VMStateField *field, JSONWriter *vmdesc,
584 + Error **errp)
585 {
586 const VMStateDescription *vmsd = field->vmsd;
560 - void *tmp = g_malloc(size);
561 - int ret;
562 - Error *local_err = NULL;
587 + g_autofree void *tmp = g_malloc(size);
588
589 /* Writes the parent field which is at the start of the tmp */
590 *(void **)tmp = pv;
566 - ret = vmstate_save_state(f, vmsd, tmp, vmdesc, &local_err);
567 - if (ret) {
568 - error_report_err(local_err);
569 - }
570 - g_free(tmp);
571 -
572 - return ret;
591 + return vmstate_save_vmsd(f, vmsd, tmp, vmdesc, errp);
592 }
593
594 const VMStateInfo vmstate_info_tmp = {
595 .name = "tmp",
577 - .get = get_tmp,
578 - .put = put_tmp,
596 + .load = load_tmp,
597 + .save = save_tmp,
598 };
599
600 /* bitmaps (as defined by bitmap.h). Note that size here is the size
@@ -585,11 +604,12 @@ const VMStateInfo vmstate_info_tmp = {
604 */
605 /* This is the number of 64 bit words sent over the wire */
606 #define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64)
588 -static int get_bitmap(QEMUFile *f, void *pv, size_t size,
589 - const VMStateField *field)
607 +static bool load_bitmap(QEMUFile *f, void *pv, size_t size,
608 + const VMStateField *field, Error **errp)
609 {
610 unsigned long *bmp = pv;
611 int i, idx = 0;
612 +
613 for (i = 0; i < BITS_TO_U64S(size); i++) {
614 uint64_t w = qemu_get_be64(f);
615 bmp[idx++] = w;
@@ -597,14 +617,17 @@ static int get_bitmap(QEMUFile *f, void *pv, size_t size,
617 bmp[idx++] = w >> 32;
618 }
619 }
600 - return 0;
620 +
621 + return true;
622 }
623
603 -static int put_bitmap(QEMUFile *f, void *pv, size_t size,
604 - const VMStateField *field, JSONWriter *vmdesc)
624 +static bool save_bitmap(QEMUFile *f, void *pv, size_t size,
625 + const VMStateField *field, JSONWriter *vmdesc,
626 + Error **errp)
627 {
628 unsigned long *bmp = pv;
629 int i, idx = 0;
630 +
631 for (i = 0; i < BITS_TO_U64S(size); i++) {
632 uint64_t w = bmp[idx++];
633 if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) {
@@ -613,23 +636,21 @@ static int put_bitmap(QEMUFile *f, void *pv, size_t size,
636 qemu_put_be64(f, w);
637 }
638
616 - return 0;
639 + return true;
640 }
641
642 const VMStateInfo vmstate_info_bitmap = {
643 .name = "bitmap",
621 - .get = get_bitmap,
622 - .put = put_bitmap,
644 + .load = load_bitmap,
645 + .save = save_bitmap,
646 };
647
648 /* get for QTAILQ
649 * meta data about the QTAILQ is encoded in a VMStateField structure
650 */
628 -static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size,
629 - const VMStateField *field)
651 +static bool load_qtailq(QEMUFile *f, void *pv, size_t unused_size,
652 + const VMStateField *field, Error **errp)
653 {
631 - int ret = 0;
632 - Error *local_err = NULL;
654 const VMStateDescription *vmsd = field->vmsd;
655 /* size of a QTAILQ element */
656 size_t size = field->size;
@@ -638,80 +659,76 @@ static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size,
659 int version_id = field->version_id;
660 void *elm;
661
641 - trace_get_qtailq(vmsd->name, version_id);
662 + trace_load_qtailq(vmsd->name, version_id);
663 if (version_id > vmsd->version_id) {
643 - error_report("%s %s", vmsd->name, "too new");
644 - trace_get_qtailq_end(vmsd->name, "too new", -EINVAL);
645 -
646 - return -EINVAL;
664 + error_setg(errp, "%s %s", vmsd->name, "too new");
665 + return false;
666 }
667 if (version_id < vmsd->minimum_version_id) {
649 - error_report("%s %s", vmsd->name, "too old");
650 - trace_get_qtailq_end(vmsd->name, "too old", -EINVAL);
651 - return -EINVAL;
668 + error_setg(errp, "%s %s", vmsd->name, "too old");
669 + return false;
670 }
671
672 while (qemu_get_byte(f)) {
673 elm = g_malloc(size);
656 - ret = vmstate_load_state(f, vmsd, elm, version_id, &local_err);
657 - if (ret) {
658 - error_report_err(local_err);
659 - return ret;
674 + if (!vmstate_load_vmsd(f, vmsd, elm, version_id, errp)) {
675 + g_free(elm);
676 + return false;
677 }
678 QTAILQ_RAW_INSERT_TAIL(pv, elm, entry_offset);
679 }
680
664 - trace_get_qtailq_end(vmsd->name, "end", ret);
665 - return ret;
681 + trace_load_qtailq_end(vmsd->name);
682 + return true;
683 }
684
668 -/* put for QTAILQ */
669 -static int put_qtailq(QEMUFile *f, void *pv, size_t unused_size,
670 - const VMStateField *field, JSONWriter *vmdesc)
685 +/* save for QTAILQ */
686 +static bool save_qtailq(QEMUFile *f, void *pv, size_t unused_size,
687 + const VMStateField *field, JSONWriter *vmdesc,
688 + Error **errp)
689 {
690 const VMStateDescription *vmsd = field->vmsd;
691 /* offset of the QTAILQ entry in a QTAILQ element*/
692 size_t entry_offset = field->start;
693 void *elm;
676 - int ret;
677 - Error *local_err = NULL;
694
679 - trace_put_qtailq(vmsd->name, vmsd->version_id);
695 + trace_save_qtailq(vmsd->name, vmsd->version_id);
696
697 QTAILQ_RAW_FOREACH(elm, pv, entry_offset) {
698 qemu_put_byte(f, true);
683 - ret = vmstate_save_state(f, vmsd, elm, vmdesc, &local_err);
684 - if (ret) {
685 - error_report_err(local_err);
686 - return ret;
699 + if (!vmstate_save_vmsd(f, vmsd, elm, vmdesc, errp)) {
700 + return false;
701 }
702 }
703 qemu_put_byte(f, false);
704
691 - trace_put_qtailq_end(vmsd->name, "end");
705 + trace_save_qtailq_end(vmsd->name);
706
693 - return 0;
707 + return true;
708 }
709 const VMStateInfo vmstate_info_qtailq = {
710 .name = "qtailq",
697 - .get = get_qtailq,
698 - .put = put_qtailq,
711 + .load = load_qtailq,
712 + .save = save_qtailq,
713 };
714
701 -struct put_gtree_data {
715 +struct save_gtree_data {
716 QEMUFile *f;
717 const VMStateDescription *key_vmsd;
718 const VMStateDescription *val_vmsd;
719 JSONWriter *vmdesc;
706 - int ret;
720 + Error **errp;
721 + bool failed;
722 };
723
709 -static gboolean put_gtree_elem(gpointer key, gpointer value, gpointer data)
724 +/*
725 + * save_gtree_elem - func for g_tree_foreach, return true to stop
726 + * iteration.
727 + */
728 +static gboolean save_gtree_elem(gpointer key, gpointer value, gpointer data)
729 {
711 - struct put_gtree_data *capsule = (struct put_gtree_data *)data;
730 + struct save_gtree_data *capsule = (struct save_gtree_data *)data;
731 QEMUFile *f = capsule->f;
713 - int ret;
714 - Error *local_err = NULL;
732
733 qemu_put_byte(f, true);
734
@@ -719,58 +736,56 @@ static gboolean put_gtree_elem(gpointer key, gpointer value, gpointer data)
736 if (!capsule->key_vmsd) {
737 qemu_put_be64(f, (uint64_t)(uintptr_t)(key)); /* direct key */
738 } else {
722 - ret = vmstate_save_state(f, capsule->key_vmsd, key, capsule->vmdesc,
723 - &local_err);
724 - if (ret) {
725 - error_report_err(local_err);
726 - capsule->ret = ret;
739 + if (!vmstate_save_vmsd(f, capsule->key_vmsd, key, capsule->vmdesc,
740 + capsule->errp)) {
741 + capsule->failed = true;
742 return true;
743 }
744 }
745
746 /* put the data */
732 - ret = vmstate_save_state(f, capsule->val_vmsd, value, capsule->vmdesc,
733 - &local_err);
734 - if (ret) {
735 - error_report_err(local_err);
736 - capsule->ret = ret;
747 + if (!vmstate_save_vmsd(f, capsule->val_vmsd, value, capsule->vmdesc,
748 + capsule->errp)) {
749 + capsule->failed = true;
750 return true;
751 }
752 return false;
753 }
754
742 -static int put_gtree(QEMUFile *f, void *pv, size_t unused_size,
743 - const VMStateField *field, JSONWriter *vmdesc)
755 +static bool save_gtree(QEMUFile *f, void *pv, size_t unused_size,
756 + const VMStateField *field, JSONWriter *vmdesc,
757 + Error **errp)
758 {
759 bool direct_key = (!field->start);
760 const VMStateDescription *key_vmsd = direct_key ? NULL : &field->vmsd[1];
761 const VMStateDescription *val_vmsd = &field->vmsd[0];
762 const char *key_vmsd_name = direct_key ? "direct" : key_vmsd->name;
749 - struct put_gtree_data capsule = {
763 + struct save_gtree_data capsule = {
764 .f = f,
765 .key_vmsd = key_vmsd,
766 .val_vmsd = val_vmsd,
767 .vmdesc = vmdesc,
754 - .ret = 0};
768 + .errp = errp,
769 + .failed = false};
770 GTree **pval = pv;
771 GTree *tree = *pval;
772 uint32_t nnodes = g_tree_nnodes(tree);
758 - int ret;
773
760 - trace_put_gtree(field->name, key_vmsd_name, val_vmsd->name, nnodes);
774 + trace_save_gtree(field->name, key_vmsd_name, val_vmsd->name, nnodes);
775 qemu_put_be32(f, nnodes);
762 - g_tree_foreach(tree, put_gtree_elem, (gpointer)&capsule);
776 + g_tree_foreach(tree, save_gtree_elem, (gpointer)&capsule);
777 qemu_put_byte(f, false);
764 - ret = capsule.ret;
765 - if (ret) {
766 - error_report("%s : failed to save gtree (%d)", field->name, ret);
778 + if (capsule.failed) {
779 + trace_save_gtree_end(field->name, key_vmsd_name, val_vmsd->name);
780 + return false;
781 }
768 - trace_put_gtree_end(field->name, key_vmsd_name, val_vmsd->name, ret);
769 - return ret;
782 +
783 + trace_save_gtree_end(field->name, key_vmsd_name, val_vmsd->name);
784 + return true;
785 }
786
772 -static int get_gtree(QEMUFile *f, void *pv, size_t unused_size,
773 - const VMStateField *field)
787 +static bool load_gtree(QEMUFile *f, void *pv, size_t unused_size,
788 + const VMStateField *field, Error **errp)
789 {
790 bool direct_key = (!field->start);
791 const VMStateDescription *key_vmsd = direct_key ? NULL : &field->vmsd[1];
@@ -783,107 +798,97 @@ static int get_gtree(QEMUFile *f, void *pv, size_t unused_size,
798 GTree **pval = pv;
799 GTree *tree = *pval;
800 void *key, *val;
786 - int ret = 0;
787 - Error *local_err = NULL;
801
802 /* in case of direct key, the key vmsd can be {}, ie. check fields */
803 if (!direct_key && version_id > key_vmsd->version_id) {
791 - error_report("%s %s", key_vmsd->name, "too new");
792 - return -EINVAL;
804 + error_setg(errp, "%s %s", key_vmsd->name, "too new");
805 + return false;
806 }
807 if (!direct_key && version_id < key_vmsd->minimum_version_id) {
795 - error_report("%s %s", key_vmsd->name, "too old");
796 - return -EINVAL;
808 + error_setg(errp, "%s %s", key_vmsd->name, "too old");
809 + return false;
810 }
811 if (version_id > val_vmsd->version_id) {
799 - error_report("%s %s", val_vmsd->name, "too new");
800 - return -EINVAL;
812 + error_setg(errp, "%s %s", val_vmsd->name, "too new");
813 + return false;
814 }
815 if (version_id < val_vmsd->minimum_version_id) {
803 - error_report("%s %s", val_vmsd->name, "too old");
804 - return -EINVAL;
816 + error_setg(errp, "%s %s", val_vmsd->name, "too old");
817 + return false;
818 }
819
820 nnodes = qemu_get_be32(f);
808 - trace_get_gtree(field->name, key_vmsd_name, val_vmsd->name, nnodes);
821 + trace_load_gtree(field->name, key_vmsd_name, val_vmsd->name, nnodes);
822
823 while (qemu_get_byte(f)) {
824 if ((++count) > nnodes) {
812 - ret = -EINVAL;
825 break;
826 }
827 if (direct_key) {
828 key = (void *)(uintptr_t)qemu_get_be64(f);
829 } else {
830 key = g_malloc0(key_size);
819 - ret = vmstate_load_state(f, key_vmsd, key, version_id, &local_err);
820 - if (ret) {
821 - error_report_err(local_err);
831 + if (!vmstate_load_vmsd(f, key_vmsd, key, version_id, errp)) {
832 goto key_error;
833 }
834 }
835 val = g_malloc0(val_size);
826 - ret = vmstate_load_state(f, val_vmsd, val, version_id, &local_err);
827 - if (ret) {
828 - error_report_err(local_err);
836 + if (!vmstate_load_vmsd(f, val_vmsd, val, version_id, errp)) {
837 goto val_error;
838 }
839 g_tree_insert(tree, key, val);
840 }
841 if (count != nnodes) {
834 - error_report("%s inconsistent stream when loading the gtree",
835 - field->name);
836 - return -EINVAL;
842 + error_setg(errp, "%s inconsistent stream when loading the gtree",
843 + field->name);
844 + return false;
845 }
838 - trace_get_gtree_end(field->name, key_vmsd_name, val_vmsd->name, ret);
839 - return ret;
846 +
847 + trace_load_gtree_end(field->name, key_vmsd_name, val_vmsd->name);
848 + return true;
849 +
850 val_error:
851 g_free(val);
852 +
853 key_error:
854 if (!direct_key) {
855 g_free(key);
856 }
846 - trace_get_gtree_end(field->name, key_vmsd_name, val_vmsd->name, ret);
847 - return ret;
857 + return false;
858 }
859
860
861 const VMStateInfo vmstate_info_gtree = {
862 .name = "gtree",
853 - .get = get_gtree,
854 - .put = put_gtree,
863 + .load = load_gtree,
864 + .save = save_gtree,
865 };
866
857 -static int put_qlist(QEMUFile *f, void *pv, size_t unused_size,
858 - const VMStateField *field, JSONWriter *vmdesc)
867 +static bool save_qlist(QEMUFile *f, void *pv, size_t unused_size,
868 + const VMStateField *field, JSONWriter *vmdesc,
869 + Error **errp)
870 {
871 const VMStateDescription *vmsd = field->vmsd;
872 /* offset of the QTAILQ entry in a QTAILQ element*/
873 size_t entry_offset = field->start;
874 void *elm;
864 - int ret;
865 - Error *local_err = NULL;
875
867 - trace_put_qlist(field->name, vmsd->name, vmsd->version_id);
876 + trace_save_qlist(field->name, vmsd->name, vmsd->version_id);
877 QLIST_RAW_FOREACH(elm, pv, entry_offset) {
878 qemu_put_byte(f, true);
870 - ret = vmstate_save_state(f, vmsd, elm, vmdesc, &local_err);
871 - if (ret) {
872 - error_report_err(local_err);
873 - return ret;
879 + if (!vmstate_save_vmsd(f, vmsd, elm, vmdesc, errp)) {
880 + return false;
881 }
882 }
883 qemu_put_byte(f, false);
877 - trace_put_qlist_end(field->name, vmsd->name);
884 + trace_save_qlist_end(field->name, vmsd->name);
885
879 - return 0;
886 + return true;
887 }
888
882 -static int get_qlist(QEMUFile *f, void *pv, size_t unused_size,
883 - const VMStateField *field)
889 +static bool load_qlist(QEMUFile *f, void *pv, size_t unused_size,
890 + const VMStateField *field, Error **errp)
891 {
885 - int ret = 0;
886 - Error *local_err = NULL;
892 const VMStateDescription *vmsd = field->vmsd;
893 /* size of a QLIST element */
894 size_t size = field->size;
@@ -892,23 +897,21 @@ static int get_qlist(QEMUFile *f, void *pv, size_t unused_size,
897 int version_id = field->version_id;
898 void *elm, *prev = NULL;
899
895 - trace_get_qlist(field->name, vmsd->name, vmsd->version_id);
900 + trace_load_qlist(field->name, vmsd->name, vmsd->version_id);
901 if (version_id > vmsd->version_id) {
897 - error_report("%s %s", vmsd->name, "too new");
898 - return -EINVAL;
902 + error_setg(errp, "%s %s", vmsd->name, "too new");
903 + return false;
904 }
905 if (version_id < vmsd->minimum_version_id) {
901 - error_report("%s %s", vmsd->name, "too old");
902 - return -EINVAL;
906 + error_setg(errp, "%s %s", vmsd->name, "too old");
907 + return false;
908 }
909
910 while (qemu_get_byte(f)) {
911 elm = g_malloc(size);
907 - ret = vmstate_load_state(f, vmsd, elm, version_id, &local_err);
908 - if (ret) {
909 - error_report_err(local_err);
912 + if (!vmstate_load_vmsd(f, vmsd, elm, version_id, errp)) {
913 g_free(elm);
911 - return ret;
914 + return false;
915 }
916 if (!prev) {
917 QLIST_RAW_INSERT_HEAD(pv, elm, entry_offset);
@@ -917,13 +920,13 @@ static int get_qlist(QEMUFile *f, void *pv, size_t unused_size,
920 }
921 prev = elm;
922 }
920 - trace_get_qlist_end(field->name, vmsd->name);
923 + trace_load_qlist_end(field->name, vmsd->name);
924
922 - return ret;
925 + return true;
926 }
927
928 const VMStateInfo vmstate_info_qlist = {
929 .name = "qlist",
927 - .get = get_qlist,
928 - .put = put_qlist,
930 + .load = load_qlist,
931 + .save = save_qlist,
932 };