VirtualBox

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

Last change on this file since 62534 was 62471, checked in by vboxsync, 9 years ago

Misc: scm

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