VirtualBox

source: vbox/trunk/src/VBox/Storage/testcase/tstVDFill.cpp@ 61908

Last change on this file since 61908 was 61731, checked in by vboxsync, 9 years ago

Storage/tstVDFill: Add flag for stream optimized variants

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1/** @file
2 *
3 * Test utility to fill a given image with random data up to a certain size (sequentially).
4 */
5
6/*
7 * Copyright (C) 2016 Oracle Corporation
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
18#include <VBox/vd.h>
19#include <VBox/err.h>
20#include <VBox/log.h>
21#include <iprt/asm.h>
22#include <iprt/dir.h>
23#include <iprt/string.h>
24#include <iprt/stream.h>
25#include <iprt/file.h>
26#include <iprt/mem.h>
27#include <iprt/initterm.h>
28#include <iprt/getopt.h>
29#include <iprt/rand.h>
30
31/*********************************************************************************************************************************
32* Global Variables *
33*********************************************************************************************************************************/
34/** The error count. */
35unsigned g_cErrors = 0;
36/** Global RNG state. */
37RTRAND g_hRand;
38
39#define TSTVDFILL_TEST_PATTERN_SIZE _1M
40
41static DECLCALLBACK(void) tstVDError(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
42{
43 g_cErrors++;
44 RTPrintf("tstVDFill: Error %Rrc at %s:%u (%s): ", rc, RT_SRC_POS_ARGS);
45 RTPrintfV(pszFormat, va);
46 RTPrintf("\n");
47}
48
49static DECLCALLBACK(int) tstVDMessage(void *pvUser, const char *pszFormat, va_list va)
50{
51 RTPrintf("tstVDFill: ");
52 RTPrintfV(pszFormat, va);
53 return VINF_SUCCESS;
54}
55
56static int tstFill(const char *pszFilename, const char *pszFormat, bool fStreamOptimized, uint64_t cbDisk, uint64_t cbFill)
57{
58 int rc;
59 PVBOXHDD pVD = NULL;
60 VDGEOMETRY PCHS = { 0, 0, 0 };
61 VDGEOMETRY LCHS = { 0, 0, 0 };
62 PVDINTERFACE pVDIfs = NULL;
63 VDINTERFACEERROR VDIfError;
64
65 /** Buffer storing the random test pattern. */
66 uint8_t *pbTestPattern = NULL;
67
68 /* Create the virtual disk test data */
69 pbTestPattern = (uint8_t *)RTMemAlloc(TSTVDFILL_TEST_PATTERN_SIZE);
70
71 RTRandAdvBytes(g_hRand, pbTestPattern, TSTVDFILL_TEST_PATTERN_SIZE);
72
73 RTPrintf("Disk size is %llu bytes\n", cbDisk);
74
75 /* Create error interface. */
76 /* Create error interface. */
77 VDIfError.pfnError = tstVDError;
78 VDIfError.pfnMessage = tstVDMessage;
79
80 rc = VDInterfaceAdd(&VDIfError.Core, "tstVD_Error", VDINTERFACETYPE_ERROR,
81 NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
82 AssertRC(rc);
83
84#define CHECK(str) \
85 do \
86 { \
87 RTPrintf("%s rc=%Rrc\n", str, rc); \
88 if (RT_FAILURE(rc)) \
89 { \
90 if (pbTestPattern) \
91 RTMemFree(pbTestPattern); \
92 VDDestroy(pVD); \
93 g_cErrors++; \
94 return rc; \
95 } \
96 } while (0)
97
98 rc = VDCreate(pVDIfs, VDTYPE_HDD, &pVD);
99 CHECK("VDCreate()");
100
101 rc = VDCreateBase(pVD, pszFormat, pszFilename, cbDisk,
102 fStreamOptimized ? VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED : VD_IMAGE_FLAGS_NONE,
103 "Test image", &PCHS, &LCHS, NULL, VD_OPEN_FLAGS_NORMAL,
104 NULL, NULL);
105 CHECK("VDCreateBase()");
106
107 uint64_t uOff = 0;
108 uint64_t cbGb = 0;
109 while ( uOff < cbFill
110 && RT_SUCCESS(rc))
111 {
112 size_t cbThisWrite = RT_MIN(TSTVDFILL_TEST_PATTERN_SIZE, cbFill - uOff);
113 rc = VDWrite(pVD, uOff, pbTestPattern, cbThisWrite);
114 if (RT_SUCCESS(rc))
115 {
116 uOff += cbThisWrite;
117 cbGb += cbThisWrite;
118 /* Print a message for every GB we wrote. */
119 if (cbGb >= _1G)
120 {
121 RTStrmPrintf(g_pStdErr, "Wrote %llu bytes\n", uOff);
122 cbGb = 0;
123 }
124 }
125 }
126
127 VDDestroy(pVD);
128 if (pbTestPattern)
129 RTMemFree(pbTestPattern);
130
131#undef CHECK
132 return rc;
133}
134
135/**
136 * Shows help message.
137 */
138static void printUsage(void)
139{
140 RTPrintf("Usage:\n"
141 "--disk-size <size in MB> Size of the disk\n"
142 "--fill-size <size in MB> How much to fill\n"
143 "--filename <filename> Filename of the image\n"
144 "--format <VDI|VMDK|...> Format to use\n"
145 "--streamoptimized Use the stream optimized format\n"
146 "--help Show this text\n");
147}
148
149static const RTGETOPTDEF g_aOptions[] =
150{
151 { "--disk-size", 's', RTGETOPT_REQ_UINT64 },
152 { "--fill-size", 'f', RTGETOPT_REQ_UINT64 },
153 { "--filename", 'p', RTGETOPT_REQ_STRING },
154 { "--format", 't', RTGETOPT_REQ_STRING },
155 { "--streamoptimized", 'r', RTGETOPT_REQ_NOTHING },
156 { "--help", 'h', RTGETOPT_REQ_NOTHING }
157};
158
159int main(int argc, char *argv[])
160{
161 RTR3InitExe(argc, &argv, 0);
162 int rc;
163 RTGETOPTUNION ValueUnion;
164 RTGETOPTSTATE GetState;
165 char c;
166 uint64_t cbDisk = 0;
167 uint64_t cbFill = 0;
168 const char *pszFilename = NULL;
169 const char *pszFormat = NULL;
170 bool fStreamOptimized = false;
171
172 rc = VDInit();
173 if (RT_FAILURE(rc))
174 return RTEXITCODE_FAILURE;
175
176 RTGetOptInit(&GetState, argc, argv, g_aOptions,
177 RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
178
179 while ( RT_SUCCESS(rc)
180 && (c = RTGetOpt(&GetState, &ValueUnion)))
181 {
182 switch (c)
183 {
184 case 's':
185 cbDisk = ValueUnion.u64 * _1M;
186 break;
187 case 'f':
188 cbFill = ValueUnion.u64 * _1M;
189 break;
190 case 'p':
191 pszFilename = ValueUnion.psz;
192 break;
193 case 't':
194 pszFormat = ValueUnion.psz;
195 break;
196 case 'r':
197 fStreamOptimized = true;
198 break;
199 case 'h':
200 default:
201 printUsage();
202 break;
203 }
204 }
205
206 if (!cbDisk || !cbFill || !pszFilename || !pszFormat)
207 {
208 RTPrintf("tstVDFill: Arguments missing!\n");
209 return 1;
210 }
211
212 rc = RTRandAdvCreateParkMiller(&g_hRand);
213 if (RT_FAILURE(rc))
214 {
215 RTPrintf("tstVDFill: Creating RNG failed rc=%Rrc\n", rc);
216 return 1;
217 }
218
219 RTRandAdvSeed(g_hRand, 0x12345678);
220
221 rc = tstFill(pszFilename, pszFormat, fStreamOptimized, cbDisk, cbFill);
222 if (RT_FAILURE(rc))
223 RTPrintf("tstVDFill: Filling disk failed! rc=%Rrc\n", rc);
224
225 rc = VDShutdown();
226 if (RT_FAILURE(rc))
227 RTPrintf("tstVDFill: unloading backends failed! rc=%Rrc\n", rc);
228
229 return RTEXITCODE_SUCCESS;
230}
231
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