527
518
TestStructTriv ar[AR_SIZE] = {};
528
519
TestArrayOfPtrToStuct obj = {.ar = {&ar[0], &ar[1], &ar[2], &ar[3]} };
530
uint8_t wire_sample[] = {
531
0x00, 0x00, 0x00, 0x00,
532
0x00, 0x00, 0x00, 0x01,
533
0x00, 0x00, 0x00, 0x02,
534
0x00, 0x00, 0x00, 0x03,
538
save_buffer(wire_sample, sizeof(wire_sample));
539
SUCCESS(load_vmstate_one(&vmsd_arps, &obj, 1,
540
wire_sample, sizeof(wire_sample)));
541
for (idx = 0; idx < AR_SIZE; ++idx) {
542
/* compare the target array ar with the ground truth array ar_gt */
543
g_assert_cmpint(ar_gt[idx].i, ==, ar[idx].i);
522
save_buffer(wire_arr_ptr_no0, sizeof(wire_arr_ptr_no0));
523
SUCCESS(load_vmstate_one(&vmsd_arps, &obj, 1,
524
wire_arr_ptr_no0, sizeof(wire_arr_ptr_no0)));
525
for (idx = 0; idx < AR_SIZE; ++idx) {
526
/* compare the target array ar with the ground truth array ar_gt */
527
g_assert_cmpint(ar_gt[idx].i, ==, ar[idx].i);
531
static uint8_t wire_arr_ptr_0[] = {
532
0x00, 0x00, 0x00, 0x00,
534
0x00, 0x00, 0x00, 0x02,
535
0x00, 0x00, 0x00, 0x03,
539
static void test_arr_ptr_str_0_save(void)
541
TestStructTriv ar[AR_SIZE] = {{.i = 0}, {.i = 1}, {.i = 2}, {.i = 3} };
542
TestArrayOfPtrToStuct sample = {.ar = {&ar[0], NULL, &ar[2], &ar[3]} };
544
save_vmstate(&vmsd_arps, &sample);
545
compare_vmstate(wire_arr_ptr_0, sizeof(wire_arr_ptr_0));
548
static void test_arr_ptr_str_0_load(void)
550
TestStructTriv ar_gt[AR_SIZE] = {{.i = 0}, {.i = 0}, {.i = 2}, {.i = 3} };
551
TestStructTriv ar[AR_SIZE] = {};
552
TestArrayOfPtrToStuct obj = {.ar = {&ar[0], NULL, &ar[2], &ar[3]} };
555
save_buffer(wire_arr_ptr_0, sizeof(wire_arr_ptr_0));
556
SUCCESS(load_vmstate_one(&vmsd_arps, &obj, 1,
557
wire_arr_ptr_0, sizeof(wire_arr_ptr_0)));
558
for (idx = 0; idx < AR_SIZE; ++idx) {
559
/* compare the target array ar with the ground truth array ar_gt */
560
g_assert_cmpint(ar_gt[idx].i, ==, ar[idx].i);
562
for (idx = 0; idx < AR_SIZE; ++idx) {
564
g_assert_cmpint((uintptr_t)(obj.ar[idx]), ==, 0);
566
g_assert_cmpint((uintptr_t)(obj.ar[idx]), !=, 0);
571
typedef struct TestArrayOfPtrToInt {
572
int32_t *ar[AR_SIZE];
573
} TestArrayOfPtrToInt;
575
const VMStateDescription vmsd_arpp = {
578
.minimum_version_id = 1,
579
.fields = (VMStateField[]) {
580
VMSTATE_ARRAY_OF_POINTER(ar, TestArrayOfPtrToInt,
581
AR_SIZE, 0, vmstate_info_int32, int32_t*),
582
VMSTATE_END_OF_LIST()
586
static void test_arr_ptr_prim_0_save(void)
588
int32_t ar[AR_SIZE] = {0 , 1, 2, 3};
589
TestArrayOfPtrToInt sample = {.ar = {&ar[0], NULL, &ar[2], &ar[3]} };
591
save_vmstate(&vmsd_arpp, &sample);
592
compare_vmstate(wire_arr_ptr_0, sizeof(wire_arr_ptr_0));
595
static void test_arr_ptr_prim_0_load(void)
597
int32_t ar_gt[AR_SIZE] = {0, 1, 2, 3};
598
int32_t ar[AR_SIZE] = {3 , 42, 1, 0};
599
TestArrayOfPtrToInt obj = {.ar = {&ar[0], NULL, &ar[2], &ar[3]} };
602
save_buffer(wire_arr_ptr_0, sizeof(wire_arr_ptr_0));
603
SUCCESS(load_vmstate_one(&vmsd_arpp, &obj, 1,
604
wire_arr_ptr_0, sizeof(wire_arr_ptr_0)));
605
for (idx = 0; idx < AR_SIZE; ++idx) {
606
/* compare the target array ar with the ground truth array ar_gt */
608
g_assert_cmpint(42, ==, ar[idx]);
610
g_assert_cmpint(ar_gt[idx], ==, ar[idx]);
615
/* test QTAILQ migration */
616
typedef struct TestQtailqElement TestQtailqElement;
618
struct TestQtailqElement {
621
QTAILQ_ENTRY(TestQtailqElement) next;
624
typedef struct TestQtailq {
626
QTAILQ_HEAD(TestQtailqHead, TestQtailqElement) q;
630
static const VMStateDescription vmstate_q_element = {
631
.name = "test/queue-element",
633
.minimum_version_id = 1,
634
.fields = (VMStateField[]) {
635
VMSTATE_BOOL(b, TestQtailqElement),
636
VMSTATE_UINT8(u8, TestQtailqElement),
637
VMSTATE_END_OF_LIST()
641
static const VMStateDescription vmstate_q = {
642
.name = "test/queue",
644
.minimum_version_id = 1,
645
.fields = (VMStateField[]) {
646
VMSTATE_INT16(i16, TestQtailq),
647
VMSTATE_QTAILQ_V(q, TestQtailq, 1, vmstate_q_element, TestQtailqElement,
649
VMSTATE_INT32(i32, TestQtailq),
650
VMSTATE_END_OF_LIST()
656
/* start of element 0 of q */ 0x01,
659
/* start of element 1 of q */ 0x01,
663
/* i32 */ 0x00, 0x01, 0x11, 0x70,
664
QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */
667
static void test_save_q(void)
674
TestQtailqElement obj_qe1 = {
679
TestQtailqElement obj_qe2 = {
684
QTAILQ_INIT(&obj_q.q);
685
QTAILQ_INSERT_TAIL(&obj_q.q, &obj_qe1, next);
686
QTAILQ_INSERT_TAIL(&obj_q.q, &obj_qe2, next);
688
save_vmstate(&vmstate_q, &obj_q);
689
compare_vmstate(wire_q, sizeof(wire_q));
692
static void test_load_q(void)
699
TestQtailqElement obj_qe1 = {
704
TestQtailqElement obj_qe2 = {
709
QTAILQ_INIT(&obj_q.q);
710
QTAILQ_INSERT_TAIL(&obj_q.q, &obj_qe1, next);
711
QTAILQ_INSERT_TAIL(&obj_q.q, &obj_qe2, next);
713
QEMUFile *fsave = open_test_file(true);
715
qemu_put_buffer(fsave, wire_q, sizeof(wire_q));
716
g_assert(!qemu_file_get_error(fsave));
719
QEMUFile *fload = open_test_file(false);
723
vmstate_load_state(fload, &vmstate_q, &tgt, 1);
724
char eof = qemu_get_byte(fload);
725
g_assert(!qemu_file_get_error(fload));
726
g_assert_cmpint(tgt.i16, ==, obj_q.i16);
727
g_assert_cmpint(tgt.i32, ==, obj_q.i32);
728
g_assert_cmpint(eof, ==, QEMU_VM_EOF);
730
TestQtailqElement *qele_from = QTAILQ_FIRST(&obj_q.q);
731
TestQtailqElement *qlast_from = QTAILQ_LAST(&obj_q.q, TestQtailqHead);
732
TestQtailqElement *qele_to = QTAILQ_FIRST(&tgt.q);
733
TestQtailqElement *qlast_to = QTAILQ_LAST(&tgt.q, TestQtailqHead);
736
g_assert_cmpint(qele_to->b, ==, qele_from->b);
737
g_assert_cmpint(qele_to->u8, ==, qele_from->u8);
738
if ((qele_from == qlast_from) || (qele_to == qlast_to)) {
741
qele_from = QTAILQ_NEXT(qele_from, next);
742
qele_to = QTAILQ_NEXT(qele_to, next);
745
g_assert_cmpint((uintptr_t) qele_from, ==, (uintptr_t) qlast_from);
746
g_assert_cmpint((uintptr_t) qele_to, ==, (uintptr_t) qlast_to);
749
TestQtailqElement *qele;
750
while (!QTAILQ_EMPTY(&tgt.q)) {
751
qele = QTAILQ_LAST(&tgt.q, TestQtailqHead);
752
QTAILQ_REMOVE(&tgt.q, qele, next);
759
typedef struct TmpTestStruct {
764
static void tmp_child_pre_save(void *opaque)
766
struct TmpTestStruct *tts = opaque;
768
tts->diff = tts->parent->b - tts->parent->a;
771
static int tmp_child_post_load(void *opaque, int version_id)
773
struct TmpTestStruct *tts = opaque;
775
tts->parent->b = tts->parent->a + tts->diff;
780
static const VMStateDescription vmstate_tmp_back_to_parent = {
781
.name = "test/tmp_child_parent",
782
.fields = (VMStateField[]) {
783
VMSTATE_UINT64(f, TestStruct),
784
VMSTATE_END_OF_LIST()
788
static const VMStateDescription vmstate_tmp_child = {
789
.name = "test/tmp_child",
790
.pre_save = tmp_child_pre_save,
791
.post_load = tmp_child_post_load,
792
.fields = (VMStateField[]) {
793
VMSTATE_INT64(diff, TmpTestStruct),
794
VMSTATE_STRUCT_POINTER(parent, TmpTestStruct,
795
vmstate_tmp_back_to_parent, TestStruct),
796
VMSTATE_END_OF_LIST()
800
static const VMStateDescription vmstate_with_tmp = {
801
.name = "test/with_tmp",
803
.fields = (VMStateField[]) {
804
VMSTATE_UINT32(a, TestStruct),
805
VMSTATE_UINT64(d, TestStruct),
806
VMSTATE_WITH_TMP(TestStruct, TmpTestStruct, vmstate_tmp_child),
807
VMSTATE_END_OF_LIST()
811
static void obj_tmp_copy(void *target, void *source)
813
memcpy(target, source, sizeof(TestStruct));
816
static void test_tmp_struct(void)
818
TestStruct obj, obj_clone;
820
uint8_t const wire_with_tmp[] = {
821
/* u32 a */ 0x00, 0x00, 0x00, 0x02,
822
/* u64 d */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
823
/* diff */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
824
/* u64 f */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
825
QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */
828
memset(&obj, 0, sizeof(obj));
833
save_vmstate(&vmstate_with_tmp, &obj);
835
compare_vmstate(wire_with_tmp, sizeof(wire_with_tmp));
837
memset(&obj, 0, sizeof(obj));
838
SUCCESS(load_vmstate(&vmstate_with_tmp, &obj, &obj_clone,
839
obj_tmp_copy, 1, wire_with_tmp,
840
sizeof(wire_with_tmp)));
841
g_assert_cmpint(obj.a, ==, 2); /* From top level vmsd */
842
g_assert_cmpint(obj.b, ==, 4); /* from the post_load */
843
g_assert_cmpint(obj.d, ==, 1); /* From top level vmsd */
844
g_assert_cmpint(obj.f, ==, 8); /* From the child->parent */
547
847
int main(int argc, char **argv)