VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp@ 23770

Last change on this file since 23770 was 23713, checked in by vboxsync, 16 years ago

Async Completion: bugfixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.4 KB
Line 
1/* $Id: tstPDMAsyncCompletionStress.cpp 23713 2009-10-12 20:53:50Z vboxsync $ */
2/** @file
3 * PDM Asynchronous Completion Stresstest.
4 *
5 * This testcase is for stress testing the async completion interface.
6 */
7
8/*
9 * Copyright (C) 2008-2009 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.215389.xyz. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
28
29#include "../VMInternal.h" /* UVM */
30#include <VBox/vm.h>
31#include <VBox/uvm.h>
32#include <VBox/pdmasynccompletion.h>
33#include <VBox/vmm.h>
34#include <VBox/cpum.h>
35#include <VBox/err.h>
36#include <VBox/log.h>
37#include <VBox/pdmapi.h>
38#include <VBox/pdmthread.h>
39#include <iprt/alloc.h>
40#include <iprt/asm.h>
41#include <iprt/assert.h>
42#include <iprt/file.h>
43#include <iprt/initterm.h>
44#include <iprt/semaphore.h>
45#include <iprt/rand.h>
46#include <iprt/string.h>
47#include <iprt/path.h>
48#include <iprt/stream.h>
49#include <iprt/thread.h>
50#include <iprt/param.h>
51
52#define TESTCASE "tstPDMAsyncCompletionStress"
53
54#if 0
55/** Number of simultaneous open endpoints for reading and writing. */
56#define NR_OPEN_ENDPOINTS 10
57/** Test pattern size. */
58#define TEST_PATTERN_SIZE (100*_1M)
59/** Minimum file size. */
60#define FILE_SIZE_MIN (100 * _1M)
61/** Maximum file size. */
62#define FILE_SIZE_MAX (10000UL * _1M)
63/** Minimum segment size. */
64#define SEGMENT_SIZE_MIN (512)
65/** Maximum segment size. */
66#define SEGMENT_SIZE_MAX (TEST_PATTERN_SIZE)
67/** Maximum number of active tasks. */
68#define TASK_ACTIVE_MAX (1024)
69/** Maximum size of a transfer. */
70#define TASK_TRANSFER_SIZE_MAX (10*_1M)
71#else
72/** Number of simultaneous open endpoints for reading and writing. */
73#define NR_OPEN_ENDPOINTS 5
74/** Test pattern size. */
75#define TEST_PATTERN_SIZE (10*_1M)
76/** Minimum file size. */
77#define FILE_SIZE_MIN (100 * _1M)
78/** Maximum file size. */
79#define FILE_SIZE_MAX (1000UL * _1M)
80/** Minimum segment size. */
81#define SEGMENT_SIZE_MIN (512)
82/** Maximum segment size. */
83#define SEGMENT_SIZE_MAX (TEST_PATTERN_SIZE)
84/** Maximum number of active tasks. */
85#define TASK_ACTIVE_MAX (512)
86/** Maximum size of a transfer. */
87#define TASK_TRANSFER_SIZE_MAX (_1M)
88#endif
89
90/**
91 * Structure defining a file segment.
92 */
93typedef struct PDMACTESTFILESEG
94{
95 /** Start offset in the file. */
96 RTFOFF off;
97 /** Size of the segment. */
98 size_t cbSegment;
99 /** Pointer to the start of the data in the test pattern used for the segment. */
100 uint8_t *pbData;
101} PDMACTESTFILESEG, *PPDMACTESTFILESEG;
102
103/**
104 * Structure defining a I/O task.
105 */
106typedef struct PDMACTESTFILETASK
107{
108 /** Flag whether the task is currently active. */
109 bool fActive;
110 /** Flag whether this is a write. */
111 bool fWrite;
112 /** Start offset. */
113 RTFOFF off;
114 /** Data segment */
115 PDMDATASEG DataSeg;
116 /** Task handle. */
117 PPDMASYNCCOMPLETIONTASK hTask;
118} PDMACTESTFILETASK, *PPDMACTESTFILETASK;
119
120/**
121 * Structure defining a test file.
122 */
123typedef struct PDMACTESTFILE
124{
125 /** The PDM async completion endpoint handle. */
126 PPDMASYNCCOMPLETIONENDPOINT hEndpoint;
127 /** Template used for this file. */
128 PPDMASYNCCOMPLETIONTEMPLATE pTemplate;
129 /** Maximum size of the file. */
130 uint64_t cbFileMax;
131 /** Current size of the file. */
132 uint64_t cbFileCurr;
133 /** Size of a file segment. */
134 size_t cbFileSegment;
135 /** Maximum number of segments. */
136 unsigned cSegments;
137 /** Pointer to the array describing how the file is assembled
138 * of the test pattern. Used for comparing read data to ensure
139 * that no corruption occured.
140 */
141 PPDMACTESTFILESEG paSegs;
142 /** Maximum number of active tasks for this endpoint. */
143 uint32_t cTasksActiveMax;
144 /** Number of current active tasks. */
145 volatile uint32_t cTasksActiveCurr;
146 /** Pointer to the array of task. */
147 PPDMACTESTFILETASK paTasks;
148 /** I/O thread handle. */
149 PPDMTHREAD hThread;
150 /** Flag whether the thread should terminate. */
151 bool fRunning;
152} PDMACTESTFILE, *PPDMACTESTFILE;
153
154/** Buffer storing the random test pattern. */
155uint8_t *g_pbTestPattern = NULL;
156/** Size of the test pattern. */
157size_t g_cbTestPattern;
158/** Array holding test files. */
159PDMACTESTFILE g_aTestFiles[NR_OPEN_ENDPOINTS];
160
161static void tstPDMACStressTestFileVerify(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
162{
163 size_t cbLeft = pTestTask->DataSeg.cbSeg;
164 RTFOFF off = pTestTask->off;
165 uint8_t *pbBuf = (uint8_t *)pTestTask->DataSeg.pvSeg;
166
167 while (cbLeft)
168 {
169 size_t cbCompare;
170 unsigned iSeg = off / pTestFile->cbFileSegment;;
171 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[iSeg];
172 uint8_t *pbTestPattern;
173 unsigned offSeg = off - pSeg->off;
174
175 cbCompare = RT_MIN(cbLeft, pSeg->cbSegment - offSeg);
176 pbTestPattern = pSeg->pbData + offSeg;
177
178 if (memcmp(pbBuf, pbTestPattern, cbCompare))
179 AssertMsgFailed(("Unexpected data for off=%RTfoff size=%u\n", pTestTask->off, pTestTask->DataSeg.cbSeg));
180
181 pbBuf += cbCompare;
182 off += cbCompare;
183 cbLeft -= cbCompare;
184 }
185}
186
187static void tstPDMACStressTestFileFillBuffer(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
188{
189 uint8_t *pbBuf = (uint8_t *)pTestTask->DataSeg.pvSeg;
190 size_t cbLeft = pTestTask->DataSeg.cbSeg;
191 RTFOFF off = pTestTask->off;
192
193 Assert(pTestTask->fWrite && pTestTask->fActive);
194
195 while (cbLeft)
196 {
197 size_t cbFill;
198 unsigned iSeg = off / pTestFile->cbFileSegment;;
199 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[iSeg];
200 uint8_t *pbTestPattern;
201 unsigned offSeg = off - pSeg->off;
202
203 cbFill = RT_MIN(cbLeft, pSeg->cbSegment - offSeg);
204 pbTestPattern = pSeg->pbData + offSeg;
205
206 memcpy(pbBuf, pbTestPattern, cbFill);
207
208 pbBuf += cbFill;
209 off += cbFill;
210 cbLeft -= cbFill;
211 }
212}
213
214static int tstPDMACStressTestFileWrite(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
215{
216 int rc = VINF_SUCCESS;
217
218 Assert(!pTestTask->fActive);
219
220 pTestTask->fActive = true;
221 pTestTask->fWrite = true;
222 pTestTask->DataSeg.cbSeg = RTRandU32Ex(512, TASK_TRANSFER_SIZE_MAX) & ~511;
223
224 RTFOFF offMax;
225
226 /* Did we reached the maximum file size */
227 if (pTestFile->cbFileCurr < pTestFile->cbFileMax)
228 {
229 offMax = (pTestFile->cbFileMax - pTestFile->cbFileCurr) < pTestTask->DataSeg.cbSeg
230 ? pTestFile->cbFileCurr + pTestTask->DataSeg.cbSeg
231 : pTestFile->cbFileCurr;
232 }
233 else
234 offMax = pTestFile->cbFileMax - pTestTask->DataSeg.cbSeg;
235
236 pTestTask->off = RTRandU64Ex(0, offMax) & ~511;
237
238 /* Set new file size of required */
239 if ((uint64_t)pTestTask->off + pTestTask->DataSeg.cbSeg > pTestFile->cbFileCurr)
240 pTestFile->cbFileCurr = pTestTask->off + pTestTask->DataSeg.cbSeg;
241
242 /* Allocate data buffer. */
243 pTestTask->DataSeg.pvSeg = RTMemAlloc(pTestTask->DataSeg.cbSeg);
244 if (!pTestTask->DataSeg.pvSeg)
245 return VERR_NO_MEMORY;
246
247 /* Fill data into buffer. */
248 tstPDMACStressTestFileFillBuffer(pTestFile, pTestTask);
249
250 /* Engage */
251 rc = PDMR3AsyncCompletionEpWrite(pTestFile->hEndpoint, pTestTask->off,
252 &pTestTask->DataSeg, 1,
253 pTestTask->DataSeg.cbSeg,
254 pTestTask,
255 &pTestTask->hTask);
256
257 return rc;
258}
259
260static int tstPDMACStressTestFileRead(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
261{
262 int rc = VINF_SUCCESS;
263
264 Assert(!pTestTask->fActive);
265
266 pTestTask->fActive = true;
267 pTestTask->fWrite = false;
268 pTestTask->DataSeg.cbSeg = RTRandU32Ex(1, RT_MIN(pTestFile->cbFileCurr, TASK_TRANSFER_SIZE_MAX));
269
270 AssertMsg(pTestFile->cbFileCurr >= pTestTask->DataSeg.cbSeg, ("Impossible\n"));
271 pTestTask->off = RTRandU64Ex(0, pTestFile->cbFileCurr - pTestTask->DataSeg.cbSeg);
272
273 /* Allocate data buffer. */
274 pTestTask->DataSeg.pvSeg = RTMemAlloc(pTestTask->DataSeg.cbSeg);
275 if (!pTestTask->DataSeg.pvSeg)
276 return VERR_NO_MEMORY;
277
278 /* Engage */
279 rc = PDMR3AsyncCompletionEpRead(pTestFile->hEndpoint, pTestTask->off,
280 &pTestTask->DataSeg, 1,
281 pTestTask->DataSeg.cbSeg,
282 pTestTask,
283 &pTestTask->hTask);
284
285 return rc;
286}
287
288/**
289 * Returns true with the given chance in percent.
290 *
291 * @returns true or false
292 * @param iPercentage The percentage of the chance to return true.
293 */
294static bool tstPDMACTestIsTrue(int iPercentage)
295{
296 int uRnd = RTRandU32Ex(0, 100);
297
298 return (uRnd < iPercentage); /* This should be enough for our purpose */
299}
300
301static int tstPDMACTestFileThread(PVM pVM, PPDMTHREAD pThread)
302{
303 PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pThread->pvUser;
304 int iWriteChance = 100; /* Chance to get a write task in percent. */
305 uint32_t cTasksStarted = 0;
306 int rc = VINF_SUCCESS;
307
308 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
309 return VINF_SUCCESS;
310
311 while (pTestFile->fRunning)
312 {
313 unsigned iTaskCurr = 0;
314
315
316 /* Fill all tasks */
317 while ( (pTestFile->cTasksActiveCurr < pTestFile->cTasksActiveMax)
318 && (iTaskCurr < pTestFile->cTasksActiveMax))
319 {
320 PPDMACTESTFILETASK pTask = &pTestFile->paTasks[iTaskCurr];
321
322 if (!pTask->fActive)
323 {
324 /* Read or write task? */
325 bool fWrite = tstPDMACTestIsTrue(iWriteChance);
326
327 ASMAtomicIncU32(&pTestFile->cTasksActiveCurr);
328
329 if (fWrite)
330 rc = tstPDMACStressTestFileWrite(pTestFile, pTask);
331 else
332 rc = tstPDMACStressTestFileRead(pTestFile, pTask);
333
334 AssertRC(rc);
335
336 cTasksStarted++;
337 }
338
339 iTaskCurr++;
340 }
341
342 /*
343 * Recalc write chance. The bigger the file the lower the chance to have a write.
344 * The minimum chance is 33 percent.
345 */
346 iWriteChance = (int)(((float)100.0 / pTestFile->cbFileMax) * (float)pTestFile->cbFileCurr);
347 iWriteChance = RT_MAX(33, iWriteChance);
348
349 /* Wait a random amount of time. (1ms - 10s) */
350 RTThreadSleep(RTRandU32Ex(1, 10000));
351 }
352
353 /* Wait for the rest to complete. */
354 while (pTestFile->cTasksActiveCurr)
355 RTThreadSleep(250);
356
357 RTPrintf("Thread exiting: processed %u tasks\n", cTasksStarted);
358 return rc;
359}
360
361static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2)
362{
363 PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pvUser2;
364 PPDMACTESTFILETASK pTestTask = (PPDMACTESTFILETASK)pvUser;
365
366 if (pTestTask->fWrite)
367 {
368 /* @todo Do something sensible here. */
369 }
370 else
371 {
372 tstPDMACStressTestFileVerify(pTestFile, pTestTask); /* Will assert if it fails */
373 }
374
375 RTMemFree(pTestTask->DataSeg.pvSeg);
376 pTestTask->fActive = false;
377 AssertMsg(pTestFile->cTasksActiveCurr > 0, ("Trying to complete a non active task\n"));
378 ASMAtomicDecU32(&pTestFile->cTasksActiveCurr);
379}
380
381/**
382 * Sets up a test file creating the I/O thread.
383 *
384 * @returns VBox status code.
385 * @param pVM Pointer to the shared VM instance structure.
386 * @param pTestFile Pointer to the uninitialized test file structure.
387 * @param iTestId Unique test id.
388 */
389static int tstPDMACStressTestFileOpen(PVM pVM, PPDMACTESTFILE pTestFile, unsigned iTestId)
390{
391 int rc = VERR_NO_MEMORY;
392
393 /* Size is a multiple of 512 */
394 pTestFile->cbFileMax = RTRandU64Ex(FILE_SIZE_MIN, FILE_SIZE_MAX) & ~(511UL);
395 pTestFile->cbFileCurr = 0;
396 pTestFile->cbFileSegment = RTRandU32Ex(SEGMENT_SIZE_MIN, RT_MIN(pTestFile->cbFileMax, SEGMENT_SIZE_MAX)) & ~((size_t)511);
397
398 Assert(pTestFile->cbFileMax >= pTestFile->cbFileSegment);
399
400 /* Set up the segments array. */
401 pTestFile->cSegments = pTestFile->cbFileMax / pTestFile->cbFileSegment;
402 pTestFile->cSegments += ((pTestFile->cbFileMax % pTestFile->cbFileSegment) > 0) ? 1 : 0;
403
404 pTestFile->paSegs = (PPDMACTESTFILESEG)RTMemAllocZ(pTestFile->cSegments * sizeof(PDMACTESTFILESEG));
405 if (pTestFile->paSegs)
406 {
407 /* Init the segments */
408 for (unsigned i = 0; i < pTestFile->cSegments; i++)
409 {
410 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[i];
411
412 pSeg->off = (RTFOFF)i * pTestFile->cbFileSegment;
413 pSeg->cbSegment = pTestFile->cbFileSegment;
414
415 /* Let the buffer point to a random position in the test pattern. */
416 uint32_t offTestPattern = RTRandU64Ex(0, g_cbTestPattern - pSeg->cbSegment);
417
418 pSeg->pbData = g_pbTestPattern + offTestPattern;
419 }
420
421 /* Init task array. */
422 pTestFile->cTasksActiveMax = RTRandU32Ex(1, TASK_ACTIVE_MAX);
423 pTestFile->paTasks = (PPDMACTESTFILETASK)RTMemAllocZ(pTestFile->cTasksActiveMax * sizeof(PDMACTESTFILETASK));
424 if (pTestFile->paTasks)
425 {
426 /* Create the template */
427 char szDesc[256];
428
429 RTStrPrintf(szDesc, sizeof(szDesc), "Template-%d", iTestId);
430 rc = PDMR3AsyncCompletionTemplateCreateInternal(pVM, &pTestFile->pTemplate, tstPDMACStressTestFileTaskCompleted, pTestFile, szDesc);
431 if (RT_SUCCESS(rc))
432 {
433 /* Open the endpoint now. Because async completion endpoints cannot create files we have to do it before. */
434 char szFile[RTPATH_MAX];
435
436 RTStrPrintf(szFile, sizeof(szFile), "tstPDMAsyncCompletionStress-%d.tmp", iTestId);
437
438 RTFILE FileTmp;
439 rc = RTFileOpen(&FileTmp, szFile, RTFILE_O_CREATE | RTFILE_O_READWRITE);
440 if (RT_SUCCESS(rc))
441 {
442 RTFileClose(FileTmp);
443
444 rc = PDMR3AsyncCompletionEpCreateForFile(&pTestFile->hEndpoint, szFile, PDMACEP_FILE_FLAGS_CACHING, pTestFile->pTemplate);
445 if (RT_SUCCESS(rc))
446 {
447 char szThreadDesc[256];
448
449 pTestFile->fRunning = true;
450
451 /* Create the thread creating the I/O for the given file. */
452 RTStrPrintf(szThreadDesc, sizeof(szThreadDesc), "PDMACThread-%d", iTestId);
453 rc = PDMR3ThreadCreate(pVM, &pTestFile->hThread, pTestFile, tstPDMACTestFileThread,
454 NULL, 0, RTTHREADTYPE_IO, szThreadDesc);
455 if (RT_SUCCESS(rc))
456 {
457 rc = PDMR3ThreadResume(pTestFile->hThread);
458 AssertRC(rc);
459
460 RTPrintf(TESTCASE ": Created test file %s cbFileMax=%llu cbFileSegment=%u cSegments=%u cTasksActiveMax=%u\n",
461 szFile, pTestFile->cbFileMax, pTestFile->cbFileSegment, pTestFile->cSegments, pTestFile->cTasksActiveMax);
462 return VINF_SUCCESS;
463 }
464
465 PDMR3AsyncCompletionEpClose(pTestFile->hEndpoint);
466 }
467
468 RTFileDelete(szFile);
469 }
470
471 PDMR3AsyncCompletionTemplateDestroy(pTestFile->pTemplate);
472 }
473
474 RTMemFree(pTestFile->paTasks);
475 }
476 else
477 rc = VERR_NO_MEMORY;
478
479 RTMemFree(pTestFile->paSegs);
480 }
481 else
482 rc = VERR_NO_MEMORY;
483
484 RTPrintf(TESTCASE ": Opening test file with id %d failed rc=%Rrc\n", iTestId, rc);
485
486 return rc;
487}
488
489/**
490 * Closes a test file.
491 *
492 * @returns nothing.
493 * @param pTestFile Pointer to the test file.
494 */
495static void tstPDMACStressTestFileClose(PPDMACTESTFILE pTestFile)
496{
497 int rcThread;
498 int rc;
499
500 RTPrintf("Terminating I/O thread, please wait...\n");
501
502 /* Let the thread know that it should terminate. */
503 pTestFile->fRunning = false;
504
505 /* Wait for the thread to terminate. */
506 rc = PDMR3ThreadDestroy(pTestFile->hThread, &rcThread);
507
508 RTPrintf("Thread terminated with status code rc=%Rrc\n", rcThread);
509
510 /* Free resources */
511 RTMemFree(pTestFile->paTasks);
512 RTMemFree(pTestFile->paSegs);
513 PDMR3AsyncCompletionEpClose(pTestFile->hEndpoint);
514 PDMR3AsyncCompletionTemplateDestroy(pTestFile->pTemplate);
515}
516
517/**
518 * Inits the test pattern.
519 *
520 * @returns VBox status code.
521 */
522static int tstPDMACStressTestPatternInit(void)
523{
524 RTPrintf(TESTCASE ": Creating test pattern. Please wait...\n");
525 g_cbTestPattern = TEST_PATTERN_SIZE;
526 g_pbTestPattern = (uint8_t *)RTMemAlloc(g_cbTestPattern);
527 if (!g_pbTestPattern)
528 return VERR_NO_MEMORY;
529
530 RTRandBytes(g_pbTestPattern, g_cbTestPattern);
531 return VINF_SUCCESS;
532}
533
534static void tstPDMACStressTestPatternDestroy(void)
535{
536 RTPrintf(TESTCASE ": Destroying test pattern\n");
537 RTMemFree(g_pbTestPattern);
538}
539
540int main(int argc, char *argv[])
541{
542 int rcRet = 0; /* error count */
543 int rc = VINF_SUCCESS;
544
545 RTR3InitAndSUPLib();
546
547 PVM pVM;
548 rc = VMR3Create(1, NULL, NULL, NULL, NULL, &pVM);
549 if (RT_SUCCESS(rc))
550 {
551 /*
552 * Little hack to avoid the VM_ASSERT_EMT assertion.
553 */
554 RTTlsSet(pVM->pUVM->vm.s.idxTLS, &pVM->pUVM->aCpus[0]);
555 pVM->pUVM->aCpus[0].pUVM = pVM->pUVM;
556 pVM->pUVM->aCpus[0].vm.s.NativeThreadEMT = RTThreadNativeSelf();
557
558 rc = tstPDMACStressTestPatternInit();
559 if (RT_SUCCESS(rc))
560 {
561 unsigned cFilesOpened = 0;
562
563 /* Open the endpoints. */
564 for (cFilesOpened = 0; cFilesOpened < NR_OPEN_ENDPOINTS; cFilesOpened++)
565 {
566 rc = tstPDMACStressTestFileOpen(pVM, &g_aTestFiles[cFilesOpened], cFilesOpened);
567 if (RT_FAILURE(rc))
568 break;
569 }
570
571 if (RT_SUCCESS(rc))
572 {
573 /* Tests are running now. */
574 RTPrintf(TESTCASE ": Successfully opened all files. Running tests forever now or until an error is hit :)\n");
575 RTThreadSleep(RT_INDEFINITE_WAIT);
576 }
577
578 /* Close opened endpoints. */
579 for (unsigned i = 0; i < cFilesOpened; i++)
580 tstPDMACStressTestFileClose(&g_aTestFiles[i]);
581
582 tstPDMACStressTestPatternDestroy();
583 }
584 else
585 {
586 RTPrintf(TESTCASE ": failed to init test pattern!! rc=%Rrc\n", rc);
587 rcRet++;
588 }
589
590 rc = VMR3Destroy(pVM);
591 AssertMsg(rc == VINF_SUCCESS, ("%s: Destroying VM failed rc=%Rrc!!\n", __FUNCTION__, rc));
592 }
593 else
594 {
595 RTPrintf(TESTCASE ": failed to create VM!! rc=%Rrc\n", rc);
596 rcRet++;
597 }
598
599 return rcRet;
600}
601
Note: See TracBrowser for help on using the repository browser.

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