VirtualBox

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

Last change on this file since 77807 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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