VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstSSM.cpp@ 26224

Last change on this file since 26224 was 23593, checked in by vboxsync, 15 years ago

SSM: Fixed bug causing invalid/unnecessary directory entries. Made SSMR3Load also accept a stream method table.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 25.3 KB
Line 
1/* $Id: tstSSM.cpp 23593 2009-10-07 12:59:56Z vboxsync $ */
2/** @file
3 * Saved State Manager Testcase.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#include <VBox/ssm.h>
27#include "../VMInternal.h" /* createFakeVM */
28#include <VBox/vm.h>
29#include <VBox/uvm.h>
30#include <VBox/mm.h>
31#include <VBox/stam.h>
32
33#include <VBox/log.h>
34#include <VBox/sup.h>
35#include <VBox/err.h>
36#include <VBox/param.h>
37#include <iprt/assert.h>
38#include <iprt/initterm.h>
39#include <iprt/mem.h>
40#include <iprt/stream.h>
41#include <iprt/string.h>
42#include <iprt/time.h>
43#include <iprt/thread.h>
44#include <iprt/path.h>
45
46
47/*******************************************************************************
48* Defined Constants And Macros *
49*******************************************************************************/
50#define TSTSSM_BIG_CONFIG 1
51
52#ifdef TSTSSM_BIG_CONFIG
53# define TSTSSM_ITEM_SIZE (512*_1M)
54#else
55# define TSTSSM_ITEM_SIZE (5*_1M)
56#endif
57
58
59/*******************************************************************************
60* Global Variables *
61*******************************************************************************/
62const uint8_t gabPage[PAGE_SIZE] = {0};
63const char gachMem1[] = "sdfg\1asdfa\177hjkl;sdfghjkl;dfghjkl;dfghjkl;\0\0asdf;kjasdf;lkjasd;flkjasd;lfkjasd\0;lfk";
64#ifdef TSTSSM_BIG_CONFIG
65uint8_t gabBigMem[_1M];
66#else
67uint8_t gabBigMem[8*_1M];
68#endif
69
70
71/** initializes gabBigMem with some non zero stuff. */
72void initBigMem(void)
73{
74#if 0
75 uint32_t *puch = (uint32_t *)&gabBigMem[0];
76 uint32_t *puchEnd = (uint32_t *)&gabBigMem[sizeof(gabBigMem)];
77 uint32_t u32 = 0xdeadbeef;
78 for (; puch < puchEnd; puch++)
79 {
80 *puch = u32;
81 u32 += 19;
82 u32 = (u32 << 1) | (u32 >> 31);
83 }
84#else
85 uint8_t *pb = &gabBigMem[0];
86 uint8_t *pbEnd = &gabBigMem[sizeof(gabBigMem)];
87 for (; pb < pbEnd; pb += 16)
88 {
89 char szTmp[17];
90 RTStrPrintf(szTmp, sizeof(szTmp), "aaaa%08Xzzzz", (uint32_t)(uintptr_t)pb);
91 memcpy(pb, szTmp, 16);
92 }
93
94 /* add some zero pages */
95 memset(&gabBigMem[sizeof(gabBigMem) / 4], 0, PAGE_SIZE * 4);
96 memset(&gabBigMem[sizeof(gabBigMem) / 4 * 3], 0, PAGE_SIZE * 4);
97#endif
98}
99
100/**
101 * Execute state save operation.
102 *
103 * @returns VBox status code.
104 * @param pDevIns Device instance of the device which registered the data unit.
105 * @param pSSM SSM operation handle.
106 */
107DECLCALLBACK(int) Item01Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
108{
109 uint64_t u64Start = RTTimeNanoTS();
110
111 /*
112 * Test writing some memory block.
113 */
114 int rc = SSMR3PutMem(pSSM, gachMem1, sizeof(gachMem1));
115 if (RT_FAILURE(rc))
116 {
117 RTPrintf("Item01: #1 - SSMR3PutMem -> %Rrc\n", rc);
118 return rc;
119 }
120
121 /*
122 * Test writing a zeroterminated string.
123 */
124 rc = SSMR3PutStrZ(pSSM, "String");
125 if (RT_FAILURE(rc))
126 {
127 RTPrintf("Item01: #1 - SSMR3PutMem -> %Rrc\n", rc);
128 return rc;
129 }
130
131
132 /*
133 * Test the individual integer put functions to see that they all work.
134 * (Testcases are also known as "The Land of The Ugly Code"...)
135 */
136#define ITEM(suff,bits, val) \
137 rc = SSMR3Put##suff(pSSM, val); \
138 if (RT_FAILURE(rc)) \
139 { \
140 RTPrintf("Item01: #" #suff " - SSMR3Put" #suff "(," #val ") -> %Rrc\n", rc); \
141 return rc; \
142 }
143 /* copy & past with the load one! */
144 ITEM(U8, uint8_t, 0xff);
145 ITEM(U8, uint8_t, 0x0);
146 ITEM(U8, uint8_t, 1);
147 ITEM(U8, uint8_t, 42);
148 ITEM(U8, uint8_t, 230);
149 ITEM(S8, int8_t, -128);
150 ITEM(S8, int8_t, 127);
151 ITEM(S8, int8_t, 12);
152 ITEM(S8, int8_t, -76);
153 ITEM(U16, uint16_t, 0xffff);
154 ITEM(U16, uint16_t, 0x0);
155 ITEM(S16, int16_t, 32767);
156 ITEM(S16, int16_t, -32768);
157 ITEM(U32, uint32_t, 4294967295U);
158 ITEM(U32, uint32_t, 0);
159 ITEM(U32, uint32_t, 42);
160 ITEM(U32, uint32_t, 2342342344U);
161 ITEM(S32, int32_t, -2147483647-1);
162 ITEM(S32, int32_t, 2147483647);
163 ITEM(S32, int32_t, 42);
164 ITEM(S32, int32_t, 568459834);
165 ITEM(S32, int32_t, -58758999);
166 ITEM(U64, uint64_t, 18446744073709551615ULL);
167 ITEM(U64, uint64_t, 0);
168 ITEM(U64, uint64_t, 42);
169 ITEM(U64, uint64_t, 593023944758394234ULL);
170 ITEM(S64, int64_t, 9223372036854775807LL);
171 ITEM(S64, int64_t, -9223372036854775807LL - 1);
172 ITEM(S64, int64_t, 42);
173 ITEM(S64, int64_t, 21398723459873LL);
174 ITEM(S64, int64_t, -5848594593453453245LL);
175#undef ITEM
176
177 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
178 RTPrintf("tstSSM: Saved 1st item in %'RI64 ns\n", u64Elapsed);
179 return 0;
180}
181
182/**
183 * Prepare state load operation.
184 *
185 * @returns VBox status code.
186 * @param pDevIns Device instance of the device which registered the data unit.
187 * @param pSSM SSM operation handle.
188 * @param uVersion The data layout version.
189 * @param uPass The data pass.
190 */
191DECLCALLBACK(int) Item01Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
192{
193 if (uVersion != 0)
194 {
195 RTPrintf("Item01: uVersion=%#x, expected 0\n", uVersion);
196 return VERR_GENERAL_FAILURE;
197 }
198
199 /*
200 * Load the memory block.
201 */
202 char achTmp[sizeof(gachMem1)];
203 int rc = SSMR3GetMem(pSSM, achTmp, sizeof(gachMem1));
204 if (RT_FAILURE(rc))
205 {
206 RTPrintf("Item01: #1 - SSMR3GetMem -> %Rrc\n", rc);
207 return rc;
208 }
209
210 /*
211 * Load the string.
212 */
213 rc = SSMR3GetStrZ(pSSM, achTmp, sizeof(achTmp));
214 if (RT_FAILURE(rc))
215 {
216 RTPrintf("Item01: #2 - SSMR3GetStrZ -> %Rrc\n", rc);
217 return rc;
218 }
219
220 /*
221 * Test the individual integer put functions to see that they all work.
222 * (Testcases are also known as "The Land of The Ugly Code"...)
223 */
224#define ITEM(suff, type, val) \
225 do { \
226 type var = {0}; \
227 rc = SSMR3Get##suff(pSSM, &var); \
228 if (RT_FAILURE(rc)) \
229 { \
230 RTPrintf("Item01: #" #suff " - SSMR3Get" #suff "(," #val ") -> %Rrc\n", rc); \
231 return rc; \
232 } \
233 if (var != val) \
234 { \
235 RTPrintf("Item01: #" #suff " - SSMR3Get" #suff "(," #val ") -> %d returned wrong value!\n", rc); \
236 return VERR_GENERAL_FAILURE; \
237 } \
238 } while (0)
239 /* copy & past with the load one! */
240 ITEM(U8, uint8_t, 0xff);
241 ITEM(U8, uint8_t, 0x0);
242 ITEM(U8, uint8_t, 1);
243 ITEM(U8, uint8_t, 42);
244 ITEM(U8, uint8_t, 230);
245 ITEM(S8, int8_t, -128);
246 ITEM(S8, int8_t, 127);
247 ITEM(S8, int8_t, 12);
248 ITEM(S8, int8_t, -76);
249 ITEM(U16, uint16_t, 0xffff);
250 ITEM(U16, uint16_t, 0x0);
251 ITEM(S16, int16_t, 32767);
252 ITEM(S16, int16_t, -32768);
253 ITEM(U32, uint32_t, 4294967295U);
254 ITEM(U32, uint32_t, 0);
255 ITEM(U32, uint32_t, 42);
256 ITEM(U32, uint32_t, 2342342344U);
257 ITEM(S32, int32_t, -2147483647-1);
258 ITEM(S32, int32_t, 2147483647);
259 ITEM(S32, int32_t, 42);
260 ITEM(S32, int32_t, 568459834);
261 ITEM(S32, int32_t, -58758999);
262 ITEM(U64, uint64_t, 18446744073709551615ULL);
263 ITEM(U64, uint64_t, 0);
264 ITEM(U64, uint64_t, 42);
265 ITEM(U64, uint64_t, 593023944758394234ULL);
266 ITEM(S64, int64_t, 9223372036854775807LL);
267 ITEM(S64, int64_t, -9223372036854775807LL - 1);
268 ITEM(S64, int64_t, 42);
269 ITEM(S64, int64_t, 21398723459873LL);
270 ITEM(S64, int64_t, -5848594593453453245LL);
271#undef ITEM
272
273 return 0;
274}
275
276
277/**
278 * Execute state save operation.
279 *
280 * @returns VBox status code.
281 * @param pDevIns Device instance of the device which registered the data unit.
282 * @param pSSM SSM operation handle.
283 */
284DECLCALLBACK(int) Item02Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
285{
286 uint64_t u64Start = RTTimeNanoTS();
287
288 /*
289 * Put the size.
290 */
291 uint32_t cb = sizeof(gabBigMem);
292 int rc = SSMR3PutU32(pSSM, cb);
293 if (RT_FAILURE(rc))
294 {
295 RTPrintf("Item02: PutU32 -> %Rrc\n", rc);
296 return rc;
297 }
298
299 /*
300 * Put 8MB of memory to the file in 3 chunks.
301 */
302 uint8_t *pbMem = &gabBigMem[0];
303 uint32_t cbChunk = cb / 47;
304 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
305 if (RT_FAILURE(rc))
306 {
307 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
308 return rc;
309 }
310 cb -= cbChunk;
311 pbMem += cbChunk;
312
313 /* next piece. */
314 cbChunk *= 19;
315 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
316 if (RT_FAILURE(rc))
317 {
318 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
319 return rc;
320 }
321 cb -= cbChunk;
322 pbMem += cbChunk;
323
324 /* last piece. */
325 cbChunk = cb;
326 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
327 if (RT_FAILURE(rc))
328 {
329 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
330 return rc;
331 }
332
333 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
334 RTPrintf("tstSSM: Saved 2nd item in %'RI64 ns\n", u64Elapsed);
335 return 0;
336}
337
338/**
339 * Prepare state load operation.
340 *
341 * @returns VBox status code.
342 * @param pDevIns Device instance of the device which registered the data unit.
343 * @param pSSM SSM operation handle.
344 * @param uVersion The data layout version.
345 * @param uPass The data pass.
346 */
347DECLCALLBACK(int) Item02Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
348{
349 if (uVersion != 0)
350 {
351 RTPrintf("Item02: uVersion=%#x, expected 0\n", uVersion);
352 return VERR_GENERAL_FAILURE;
353 }
354
355 /*
356 * Load the size.
357 */
358 uint32_t cb;
359 int rc = SSMR3GetU32(pSSM, &cb);
360 if (RT_FAILURE(rc))
361 {
362 RTPrintf("Item02: SSMR3GetU32 -> %Rrc\n", rc);
363 return rc;
364 }
365 if (cb != sizeof(gabBigMem))
366 {
367 RTPrintf("Item02: loaded size doesn't match the real thing. %#x != %#x\n", cb, sizeof(gabBigMem));
368 return VERR_GENERAL_FAILURE;
369 }
370
371 /*
372 * Load the memory chunk by chunk.
373 */
374 uint8_t *pbMem = &gabBigMem[0];
375 char achTmp[16383];
376 uint32_t cbChunk = sizeof(achTmp);
377 while (cb > 0)
378 {
379 cbChunk -= 7;
380 if (cbChunk < 64)
381 cbChunk = sizeof(achTmp) - (cbChunk % 47);
382 if (cbChunk > cb)
383 cbChunk = cb;
384 rc = SSMR3GetMem(pSSM, &achTmp[0], cbChunk);
385 if (RT_FAILURE(rc))
386 {
387 RTPrintf("Item02: SSMR3GetMem(,,%#x) -> %d offset %#x\n", cbChunk, rc, pbMem - &gabBigMem[0]);
388 return rc;
389 }
390 if (memcmp(achTmp, pbMem, cbChunk))
391 {
392 RTPrintf("Item02: compare failed. mem offset=%#x cbChunk=%#x\n", pbMem - &gabBigMem[0], cbChunk);
393 return VERR_GENERAL_FAILURE;
394 }
395
396 /* next */
397 pbMem += cbChunk;
398 cb -= cbChunk;
399 }
400
401 return 0;
402}
403
404
405/**
406 * Execute state save operation.
407 *
408 * @returns VBox status code.
409 * @param pDevIns Device instance of the device which registered the data unit.
410 * @param pSSM SSM operation handle.
411 */
412DECLCALLBACK(int) Item03Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
413{
414 uint64_t u64Start = RTTimeNanoTS();
415
416 /*
417 * Put the size.
418 */
419 uint32_t cb = TSTSSM_ITEM_SIZE;
420 int rc = SSMR3PutU32(pSSM, cb);
421 if (RT_FAILURE(rc))
422 {
423 RTPrintf("Item03: PutU32 -> %Rrc\n", rc);
424 return rc;
425 }
426
427 /*
428 * Put 512 MB page by page.
429 */
430 const uint8_t *pu8Org = &gabBigMem[0];
431 while (cb > 0)
432 {
433 rc = SSMR3PutMem(pSSM, pu8Org, PAGE_SIZE);
434 if (RT_FAILURE(rc))
435 {
436 RTPrintf("Item03: PutMem(,%p,%#x) -> %Rrc\n", pu8Org, PAGE_SIZE, rc);
437 return rc;
438 }
439
440 /* next */
441 cb -= PAGE_SIZE;
442 pu8Org += PAGE_SIZE;
443 if (pu8Org > &gabBigMem[sizeof(gabBigMem)])
444 pu8Org = &gabBigMem[0];
445 }
446
447 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
448 RTPrintf("tstSSM: Saved 3rd item in %'RI64 ns\n", u64Elapsed);
449 return 0;
450}
451
452/**
453 * Prepare state load operation.
454 *
455 * @returns VBox status code.
456 * @param pDevIns Device instance of the device which registered the data unit.
457 * @param pSSM SSM operation handle.
458 * @param uVersion The data layout version.
459 * @param uPass The data pass.
460 */
461DECLCALLBACK(int) Item03Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
462{
463 if (uVersion != 123)
464 {
465 RTPrintf("Item03: uVersion=%#x, expected 123\n", uVersion);
466 return VERR_GENERAL_FAILURE;
467 }
468
469 /*
470 * Load the size.
471 */
472 uint32_t cb;
473 int rc = SSMR3GetU32(pSSM, &cb);
474 if (RT_FAILURE(rc))
475 {
476 RTPrintf("Item03: SSMR3GetU32 -> %Rrc\n", rc);
477 return rc;
478 }
479 if (cb != TSTSSM_ITEM_SIZE)
480 {
481 RTPrintf("Item03: loaded size doesn't match the real thing. %#x != %#x\n", cb, TSTSSM_ITEM_SIZE);
482 return VERR_GENERAL_FAILURE;
483 }
484
485 /*
486 * Load the memory page by page.
487 */
488 const uint8_t *pu8Org = &gabBigMem[0];
489 while (cb > 0)
490 {
491 char achPage[PAGE_SIZE];
492 rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
493 if (RT_FAILURE(rc))
494 {
495 RTPrintf("Item03: SSMR3GetMem(,,%#x) -> %Rrc offset %#x\n", PAGE_SIZE, rc, TSTSSM_ITEM_SIZE - cb);
496 return rc;
497 }
498 if (memcmp(achPage, pu8Org, PAGE_SIZE))
499 {
500 RTPrintf("Item03: compare failed. mem offset=%#x\n", TSTSSM_ITEM_SIZE - cb);
501 return VERR_GENERAL_FAILURE;
502 }
503
504 /* next */
505 cb -= PAGE_SIZE;
506 pu8Org += PAGE_SIZE;
507 if (pu8Org > &gabBigMem[sizeof(gabBigMem)])
508 pu8Org = &gabBigMem[0];
509 }
510
511 return 0;
512}
513
514
515/**
516 * Execute state save operation.
517 *
518 * @returns VBox status code.
519 * @param pDevIns Device instance of the device which registered the data unit.
520 * @param pSSM SSM operation handle.
521 */
522DECLCALLBACK(int) Item04Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
523{
524 uint64_t u64Start = RTTimeNanoTS();
525
526 /*
527 * Put the size.
528 */
529 uint32_t cb = 512*_1M;
530 int rc = SSMR3PutU32(pSSM, cb);
531 if (RT_FAILURE(rc))
532 {
533 RTPrintf("Item04: PutU32 -> %Rrc\n", rc);
534 return rc;
535 }
536
537 /*
538 * Put 512 MB page by page.
539 */
540 while (cb > 0)
541 {
542 rc = SSMR3PutMem(pSSM, gabPage, PAGE_SIZE);
543 if (RT_FAILURE(rc))
544 {
545 RTPrintf("Item04: PutMem(,%p,%#x) -> %Rrc\n", gabPage, PAGE_SIZE, rc);
546 return rc;
547 }
548
549 /* next */
550 cb -= PAGE_SIZE;
551 }
552
553 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
554 RTPrintf("tstSSM: Saved 4th item in %'RI64 ns\n", u64Elapsed);
555 return 0;
556}
557
558/**
559 * Prepare state load operation.
560 *
561 * @returns VBox status code.
562 * @param pDevIns Device instance of the device which registered the data unit.
563 * @param pSSM SSM operation handle.
564 * @param uVersion The data layout version.
565 * @param uPass The data pass.
566 */
567DECLCALLBACK(int) Item04Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
568{
569 if (uVersion != 42)
570 {
571 RTPrintf("Item04: uVersion=%#x, expected 42\n", uVersion);
572 return VERR_GENERAL_FAILURE;
573 }
574
575 /*
576 * Load the size.
577 */
578 uint32_t cb;
579 int rc = SSMR3GetU32(pSSM, &cb);
580 if (RT_FAILURE(rc))
581 {
582 RTPrintf("Item04: SSMR3GetU32 -> %Rrc\n", rc);
583 return rc;
584 }
585 if (cb != 512*_1M)
586 {
587 RTPrintf("Item04: loaded size doesn't match the real thing. %#x != %#x\n", cb, 512*_1M);
588 return VERR_GENERAL_FAILURE;
589 }
590
591 /*
592 * Load the memory page by page.
593 */
594 while (cb > 0)
595 {
596 char achPage[PAGE_SIZE];
597 rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
598 if (RT_FAILURE(rc))
599 {
600 RTPrintf("Item04: SSMR3GetMem(,,%#x) -> %Rrc offset %#x\n", PAGE_SIZE, rc, 512*_1M - cb);
601 return rc;
602 }
603 if (memcmp(achPage, gabPage, PAGE_SIZE))
604 {
605 RTPrintf("Item04: compare failed. mem offset=%#x\n", 512*_1M - cb);
606 return VERR_GENERAL_FAILURE;
607 }
608
609 /* next */
610 cb -= PAGE_SIZE;
611 }
612
613 return 0;
614}
615
616
617/**
618 * Creates a mockup VM structure for testing SSM.
619 *
620 * @returns 0 on success, 1 on failure.
621 * @param ppVM Where to store the VM handle.
622 *
623 * @todo Move this to VMM/VM since it's stuff done by several testcases.
624 */
625static int createFakeVM(PVM *ppVM)
626{
627 /*
628 * Allocate and init the UVM structure.
629 */
630 PUVM pUVM = (PUVM)RTMemAllocZ(sizeof(*pUVM));
631 AssertReturn(pUVM, 1);
632 pUVM->u32Magic = UVM_MAGIC;
633 pUVM->vm.s.idxTLS = RTTlsAlloc();
634 int rc = RTTlsSet(pUVM->vm.s.idxTLS, &pUVM->aCpus[0]);
635 if (RT_SUCCESS(rc))
636 {
637 pUVM->aCpus[0].pUVM = pUVM;
638 pUVM->aCpus[0].vm.s.NativeThreadEMT = RTThreadNativeSelf();
639
640 rc = STAMR3InitUVM(pUVM);
641 if (RT_SUCCESS(rc))
642 {
643 rc = MMR3InitUVM(pUVM);
644 if (RT_SUCCESS(rc))
645 {
646 /*
647 * Allocate and init the VM structure.
648 */
649 PVM pVM;
650 rc = SUPR3PageAlloc((sizeof(*pVM) + PAGE_SIZE - 1) >> PAGE_SHIFT, (void **)&pVM);
651 if (RT_SUCCESS(rc))
652 {
653 pVM->enmVMState = VMSTATE_CREATED;
654 pVM->pVMR3 = pVM;
655 pVM->pUVM = pUVM;
656 pVM->cCpus = 1;
657 pVM->aCpus[0].pVMR3 = pVM;
658 pVM->aCpus[0].hNativeThread = RTThreadNativeSelf();
659
660 pUVM->pVM = pVM;
661 *ppVM = pVM;
662 return 0;
663 }
664
665 RTPrintf("Fatal error: failed to allocated pages for the VM structure, rc=%Rrc\n", rc);
666 }
667 else
668 RTPrintf("Fatal error: MMR3InitUVM failed, rc=%Rrc\n", rc);
669 }
670 else
671 RTPrintf("Fatal error: SSMR3InitUVM failed, rc=%Rrc\n", rc);
672 }
673 else
674 RTPrintf("Fatal error: RTTlsSet failed, rc=%Rrc\n", rc);
675
676 *ppVM = NULL;
677 return 1;
678}
679
680
681int main(int argc, char **argv)
682{
683 /*
684 * Init runtime and static data.
685 */
686 RTR3InitAndSUPLib();
687 RTPrintf("tstSSM: TESTING...\n");
688 initBigMem();
689 const char *pszFilename = "SSMTestSave#1";
690
691 /*
692 * Create an fake VM structure and init SSM.
693 */
694 int rc = SUPR3Init(NULL);
695 if (RT_FAILURE(rc))
696 {
697 RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc);
698 return 1;
699 }
700 PVM pVM;
701 if (createFakeVM(&pVM))
702 return 1;
703
704 /*
705 * Register a few callbacks.
706 */
707 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.1 (all types)", 1, 0, 256, NULL,
708 NULL, NULL, NULL,
709 NULL, Item01Save, NULL,
710 NULL, Item01Load, NULL);
711 if (RT_FAILURE(rc))
712 {
713 RTPrintf("SSMR3Register #1 -> %Rrc\n", rc);
714 return 1;
715 }
716
717 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.2 (rand mem)", 2, 0, _1M * 8, NULL,
718 NULL, NULL, NULL,
719 NULL, Item02Save, NULL,
720 NULL, Item02Load, NULL);
721 if (RT_FAILURE(rc))
722 {
723 RTPrintf("SSMR3Register #2 -> %Rrc\n", rc);
724 return 1;
725 }
726
727 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.3 (big mem)", 0, 123, 512*_1M, NULL,
728 NULL, NULL, NULL,
729 NULL, Item03Save, NULL,
730 NULL, Item03Load, NULL);
731 if (RT_FAILURE(rc))
732 {
733 RTPrintf("SSMR3Register #3 -> %Rrc\n", rc);
734 return 1;
735 }
736
737 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.4 (big zero mem)", 0, 42, 512*_1M, NULL,
738 NULL, NULL, NULL,
739 NULL, Item04Save, NULL,
740 NULL, Item04Load, NULL);
741 if (RT_FAILURE(rc))
742 {
743 RTPrintf("SSMR3Register #4 -> %Rrc\n", rc);
744 return 1;
745 }
746
747 /*
748 * Attempt a save.
749 */
750 uint64_t u64Start = RTTimeNanoTS();
751 rc = SSMR3Save(pVM, pszFilename, SSMAFTER_DESTROY, NULL, NULL);
752 if (RT_FAILURE(rc))
753 {
754 RTPrintf("SSMR3Save #1 -> %Rrc\n", rc);
755 return 1;
756 }
757 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
758 RTPrintf("tstSSM: Saved in %'RI64 ns\n", u64Elapsed);
759
760 RTFSOBJINFO Info;
761 rc = RTPathQueryInfo(pszFilename, &Info, RTFSOBJATTRADD_NOTHING);
762 if (RT_FAILURE(rc))
763 {
764 RTPrintf("tstSSM: failed to query file size: %Rrc\n", rc);
765 return 1;
766 }
767 RTPrintf("tstSSM: file size %'RI64 bytes\n", Info.cbObject);
768
769 /*
770 * Attempt a load.
771 */
772 u64Start = RTTimeNanoTS();
773 rc = SSMR3Load(pVM, pszFilename, NULL /*pStreamOps*/, NULL /*pStreamOpsUser*/,
774 SSMAFTER_RESUME, NULL /*pfnProgress*/, NULL /*pvProgressUser*/);
775 if (RT_FAILURE(rc))
776 {
777 RTPrintf("SSMR3Load #1 -> %Rrc\n", rc);
778 return 1;
779 }
780 u64Elapsed = RTTimeNanoTS() - u64Start;
781 RTPrintf("tstSSM: Loaded in %'RI64 ns\n", u64Elapsed);
782
783 /*
784 * Validate it.
785 */
786 u64Start = RTTimeNanoTS();
787 rc = SSMR3ValidateFile(pszFilename, false /* fChecksumIt*/ );
788 if (RT_FAILURE(rc))
789 {
790 RTPrintf("SSMR3ValidateFile #1 -> %Rrc\n", rc);
791 return 1;
792 }
793 u64Elapsed = RTTimeNanoTS() - u64Start;
794 RTPrintf("tstSSM: Validated without checksumming in %'RI64 ns\n", u64Elapsed);
795
796 u64Start = RTTimeNanoTS();
797 rc = SSMR3ValidateFile(pszFilename, true /* fChecksumIt */);
798 if (RT_FAILURE(rc))
799 {
800 RTPrintf("SSMR3ValidateFile #1 -> %Rrc\n", rc);
801 return 1;
802 }
803 u64Elapsed = RTTimeNanoTS() - u64Start;
804 RTPrintf("tstSSM: Validated and checksummed in %'RI64 ns\n", u64Elapsed);
805
806 /*
807 * Open it and read.
808 */
809 u64Start = RTTimeNanoTS();
810 PSSMHANDLE pSSM;
811 rc = SSMR3Open(pszFilename, 0, &pSSM);
812 if (RT_FAILURE(rc))
813 {
814 RTPrintf("SSMR3Open #1 -> %Rrc\n", rc);
815 return 1;
816 }
817 u64Elapsed = RTTimeNanoTS() - u64Start;
818 RTPrintf("tstSSM: Opened in %'RI64 ns\n", u64Elapsed);
819
820 /* negative */
821 u64Start = RTTimeNanoTS();
822 rc = SSMR3Seek(pSSM, "some unit that doesn't exist", 0, NULL);
823 if (rc != VERR_SSM_UNIT_NOT_FOUND)
824 {
825 RTPrintf("SSMR3Seek #1 negative -> %Rrc\n", rc);
826 return 1;
827 }
828 u64Elapsed = RTTimeNanoTS() - u64Start;
829 RTPrintf("tstSSM: Failed seek in %'RI64 ns\n", u64Elapsed);
830
831 /* another negative, now only the instance number isn't matching. */
832 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 0, NULL);
833 if (rc != VERR_SSM_UNIT_NOT_FOUND)
834 {
835 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc\n", rc);
836 return 1;
837 }
838
839 /* 2nd unit */
840 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 2, NULL);
841 if (RT_FAILURE(rc))
842 {
843 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc [2]\n", rc);
844 return 1;
845 }
846 uint32_t uVersion = 0xbadc0ded;
847 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 2, &uVersion);
848 if (RT_FAILURE(rc))
849 {
850 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc [3]\n", rc);
851 return 1;
852 }
853 u64Start = RTTimeNanoTS();
854 rc = Item02Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
855 if (RT_FAILURE(rc))
856 {
857 RTPrintf("Item02Load #1 -> %Rrc\n", rc);
858 return 1;
859 }
860 u64Elapsed = RTTimeNanoTS() - u64Start;
861 RTPrintf("tstSSM: Loaded 2nd item in %'RI64 ns\n", u64Elapsed);
862
863 /* 1st unit */
864 uVersion = 0xbadc0ded;
865 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.1 (all types)", 1, &uVersion);
866 if (RT_FAILURE(rc))
867 {
868 RTPrintf("SSMR3Seek #1 unit 1 -> %Rrc\n", rc);
869 return 1;
870 }
871 u64Start = RTTimeNanoTS();
872 rc = Item01Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
873 if (RT_FAILURE(rc))
874 {
875 RTPrintf("Item01Load #1 -> %Rrc\n", rc);
876 return 1;
877 }
878 u64Elapsed = RTTimeNanoTS() - u64Start;
879 RTPrintf("tstSSM: Loaded 1st item in %'RI64 ns\n", u64Elapsed);
880
881 /* 3st unit */
882 uVersion = 0xbadc0ded;
883 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.3 (big mem)", 0, &uVersion);
884 if (RT_FAILURE(rc))
885 {
886 RTPrintf("SSMR3Seek #3 unit 1 -> %Rrc\n", rc);
887 return 1;
888 }
889 u64Start = RTTimeNanoTS();
890 rc = Item03Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
891 if (RT_FAILURE(rc))
892 {
893 RTPrintf("Item01Load #3 -> %Rrc\n", rc);
894 return 1;
895 }
896 u64Elapsed = RTTimeNanoTS() - u64Start;
897 RTPrintf("tstSSM: Loaded 3rd item in %'RI64 ns\n", u64Elapsed);
898
899 /* close */
900 rc = SSMR3Close(pSSM);
901 if (RT_FAILURE(rc))
902 {
903 RTPrintf("SSMR3Close #1 -> %Rrc\n", rc);
904 return 1;
905 }
906
907 RTPrintf("tstSSM: SUCCESS\n");
908 return 0;
909}
910
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette