VirtualBox

source: vbox/trunk/src/VBox/Storage/testcase/vditool.cpp@ 57444

Last change on this file since 57444 was 57358, checked in by vboxsync, 9 years ago

*: scm cleanup run.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.7 KB
Line 
1/** @file
2 *
3 * VBox HDD container maintenance/conversion utility
4 */
5
6/*
7 * Copyright (C) 2006-2011 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
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <VBox/vd.h>
23#include <iprt/alloc.h>
24#include <iprt/file.h>
25#include <iprt/stream.h>
26#include <iprt/string.h>
27#include <iprt/initterm.h>
28#include <VBox/err.h>
29#include <VBox/log.h>
30#include <VBox/version.h>
31
32#include <stdlib.h>
33
34
35
36static void ascii2upper(char *psz)
37{
38 for (;*psz; psz++)
39 if (*psz >= 'a' && *psz <= 'z')
40 *psz += 'A' - 'a';
41}
42
43static int UsageExit()
44{
45 RTPrintf("Usage: vditool <Command> [Params]\n"
46 "Commands and params:\n"
47 " NEW Filename Mbytes - create new image\n"
48#if 0
49 " DD Filename DDFilename - create new image from DD format image\n"
50 " CONVERT Filename - convert VDI image from old format\n"
51 " DUMP Filename - debug dump\n"
52 " RESETGEO Filename - reset geometry information\n"
53 " COPY FromImage ToImage - make image copy\n"
54 " COPYDD FromImage DDFilename - make a DD copy of the image\n"
55 " SHRINK Filename - optimize (reduce) VDI image size\n"
56#endif
57 );
58 return 1;
59}
60
61static int SyntaxError(const char *pszMsg)
62{
63 RTPrintf("Syntax error: %s\n\n", pszMsg);
64 UsageExit();
65 return 1;
66}
67
68/**
69 * Our internal functions use UTF8
70 */
71static int FilenameToUtf8(char **pszUtf8Filename, const char *pszFilename)
72{
73 int rc = RTStrCurrentCPToUtf8(pszUtf8Filename, pszFilename);
74 if (RT_FAILURE(rc))
75 RTPrintf("Error converting filename '%s' to UTF8! (rc=%Rrc)\n",
76 pszFilename, rc);
77 return rc;
78}
79
80/**
81 * Prints a done message indicating success or failure.
82 * @returns rc
83 * @param rc Status code.
84 */
85static int PrintDone(int rc)
86{
87 if (rc == VINF_SUCCESS)
88 RTPrintf("The operation completed successfully!\n");
89 else if (RT_SUCCESS(rc))
90 RTPrintf("The operation completed successfully! (rc=%Rrc)\n", rc);
91 else
92 RTPrintf("FAILURE: %Rrf (%Rrc)\n", rc, rc);
93 return rc;
94}
95
96static int NewImage(const char *pszFilename, uint64_t cMBs)
97{
98 RTPrintf("Creating VDI: file=\"%s\" size=%RU64MB...\n",
99 pszFilename, cMBs);
100
101 /* translate argv[] to UTF8 */
102 char *pszUtf8Filename;
103 int rc = FilenameToUtf8(&pszUtf8Filename, pszFilename);
104 if (RT_FAILURE(rc))
105 return rc;
106
107 PVBOXHDD hdd;
108 rc = VDCreate(NULL, VDTYPE_HDD, &hdd);
109 if (RT_FAILURE(rc))
110 return PrintDone(rc);
111
112 VDGEOMETRY geo = { 0, 0, 0 }; /* auto-detect */
113 rc = VDCreateBase(hdd, "vdi", pszUtf8Filename,
114 (uint64_t)cMBs * _1M,
115 VD_IMAGE_FLAGS_NONE,
116 "Newly created test image",
117 &geo, &geo, NULL,
118 VD_OPEN_FLAGS_NORMAL,
119 NULL, NULL);
120 return PrintDone(rc);
121}
122
123#if 0
124static int ConvertDDImage(const char *pszFilename, const char *pszDDFilename)
125{
126 RTPrintf("Converting VDI: from DD image file=\"%s\" to file=\"%s\"...\n",
127 pszDDFilename, pszFilename);
128
129 /* translate argv[] to UTF8 */
130 char *pszUtf8Filename, *pszUtf8DDFilename;
131 int rc = FilenameToUtf8(&pszUtf8Filename, pszFilename);
132 if (RT_FAILURE(rc))
133 return rc;
134 rc = FilenameToUtf8(&pszUtf8DDFilename, pszDDFilename);
135 if (RT_FAILURE(rc))
136 return rc;
137
138 /* open raw image file. */
139 RTFILE File;
140 rc = RTFileOpen(&File, pszUtf8DDFilename, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
141 if (RT_FAILURE(rc))
142 {
143 RTPrintf("File=\"%s\" open error: %Rrf\n", pszDDFilename, rc);
144 return rc;
145 }
146
147 /* get image size. */
148 uint64_t cbFile;
149 rc = RTFileGetSize(File, &cbFile);
150 if (RT_SUCCESS(rc))
151 {
152 RTPrintf("Creating fixed image with size %u Bytes...\n", (unsigned)cbFile);
153 rc = VDICreateBaseImage(pszUtf8Filename,
154 VDI_IMAGE_TYPE_FIXED,
155 cbFile,
156 "Converted from DD test image", NULL, NULL);
157 PrintDone(rc);
158 if (RT_SUCCESS(rc))
159 {
160 RTPrintf("Writing data...\n");
161 PVDIDISK pVdi = VDIDiskCreate();
162 rc = VDIDiskOpenImage(pVdi, pszUtf8Filename, VDI_OPEN_FLAGS_NORMAL);
163 if (RT_SUCCESS(rc))
164 {
165 /* alloc work buffer. */
166 void *pvBuf = RTMemAlloc(VDIDiskGetBufferSize(pVdi));
167 if (pvBuf)
168 {
169 uint64_t off = 0;
170 while (off < cbFile)
171 {
172 size_t cbRead = 0;
173 rc = RTFileRead(File, pvBuf, VDIDiskGetBufferSize(pVdi), &cbRead);
174 if (RT_FAILURE(rc) || !cbRead)
175 break;
176 rc = VDIDiskWrite(pVdi, off, pvBuf, cbRead);
177 if (RT_FAILURE(rc))
178 break;
179 off += cbRead;
180 }
181
182 RTMemFree(pvBuf);
183 }
184 else
185 rc = VERR_NO_MEMORY;
186
187 VDIDiskCloseImage(pVdi);
188 }
189
190 if (RT_FAILURE(rc))
191 {
192 /* delete image on error */
193 VDIDeleteImage(pszUtf8Filename);
194 }
195 PrintDone(rc);
196 }
197 }
198 RTFileClose(File);
199
200 return rc;
201}
202#endif
203
204#if 0
205static DECLCALLBACK(int) ProcessCallback(PVM pVM, unsigned uPercent, void *pvUser)
206{
207 unsigned *pPercent = (unsigned *)pvUser;
208
209 if (*pPercent != uPercent)
210 {
211 *pPercent = uPercent;
212 RTPrintf(".");
213 if ((uPercent % 10) == 0 && uPercent)
214 RTPrintf("%d%%", uPercent);
215 RTStrmFlush(g_pStdOut);
216 }
217
218 return VINF_SUCCESS;
219}
220#endif
221
222#if 0
223static int ConvertOldImage(const char *pszFilename)
224{
225 RTPrintf("Converting VDI image file=\"%s\" to a new format...\n"
226 "progress: 0%%",
227 pszFilename);
228
229 /* translate argv[] to UTF8 */
230 char *pszUtf8Filename;
231 int rc = FilenameToUtf8(&pszUtf8Filename, pszFilename);
232 if (RT_FAILURE(rc))
233 return rc;
234
235 unsigned uPercent = 0;
236 rc = VDIConvertImage(pszUtf8Filename, ProcessCallback, &uPercent);
237 RTPrintf("\n");
238 return PrintDone(rc);
239}
240#endif
241
242#if 0
243static int DumpImage(const char *pszFilename)
244{
245 RTPrintf("Dumping VDI image file=\"%s\" into the log file...\n", pszFilename);
246 PVDIDISK pVdi = VDIDiskCreate();
247
248 /* translate argv[] to UTF8 */
249 char *pszUtf8Filename;
250 int rc = FilenameToUtf8(&pszUtf8Filename, pszFilename);
251 if (RT_FAILURE(rc))
252 return rc;
253 rc = VDIDiskOpenImage(pVdi, pszUtf8Filename, VDI_OPEN_FLAGS_READONLY);
254 if (RT_SUCCESS(rc))
255 {
256 VDIDiskDumpImages(pVdi);
257 VDIDiskCloseAllImages(pVdi);
258 }
259 return PrintDone(rc);
260}
261#endif
262
263#if 0
264static int ResetImageGeometry(const char *pszFilename)
265{
266 RTPrintf("Resetting geometry info of VDI image file=\"%s\"\n", pszFilename);
267 PVDIDISK pVdi = VDIDiskCreate();
268
269 /* translate argv[] to UTF8 */
270 char *pszUtf8Filename;
271 int rc = FilenameToUtf8(&pszUtf8Filename, pszFilename);
272 if (RT_FAILURE(rc))
273 return rc;
274
275 rc = VDIDiskOpenImage(pVdi, pszUtf8Filename, VDI_OPEN_FLAGS_NORMAL);
276 if (RT_SUCCESS(rc))
277 {
278 VDGEOMETRY LCHSGeometry = {0, 0, 0};
279 rc = VDIDiskSetLCHSGeometry(pVdi, &LCHSGeometry);
280 }
281 VDIDiskCloseImage(pVdi);
282 return PrintDone(rc);
283}
284#endif
285
286#if 0
287static int CopyImage(const char *pszDstFile, const char *pszSrcFile)
288{
289 RTPrintf("Copying VDI image file=\"%s\" to image file=\"%s\"...\n"
290 "progress: 0%%",
291 pszSrcFile, pszDstFile);
292
293 /* translate argv[] to UTF8 */
294 char *pszUtf8SrcFile, *pszUtf8DstFile;
295 int rc = FilenameToUtf8(&pszUtf8SrcFile, pszSrcFile);
296 if (RT_FAILURE(rc))
297 return rc;
298 rc = FilenameToUtf8(&pszUtf8DstFile, pszDstFile);
299 if (RT_FAILURE(rc))
300 return rc;
301
302 unsigned uPrecent = 0;
303 rc = VDICopyImage(pszUtf8DstFile, pszUtf8SrcFile, NULL, ProcessCallback, &uPrecent);
304 RTPrintf("\n");
305 return PrintDone(rc);
306}
307#endif
308
309#if 0
310static int CopyToDD(const char *pszDstFile, const char *pszSrcFile)
311{
312 RTPrintf("Copying VDI image file=\"%s\" to DD file=\"%s\"...\n",
313 pszSrcFile, pszDstFile);
314 PVDIDISK pVdi = VDIDiskCreate();
315
316 /* translate argv[] to UTF8 */
317 char *pszUtf8SrcFile, *pszUtf8DstFile;
318 int rc = FilenameToUtf8(&pszUtf8SrcFile, pszSrcFile);
319 if (RT_FAILURE(rc))
320 return rc;
321 rc = FilenameToUtf8(&pszUtf8DstFile, pszDstFile);
322 if (RT_FAILURE(rc))
323 return rc;
324
325 rc = VDIDiskOpenImage(pVdi, pszUtf8SrcFile, VDI_OPEN_FLAGS_NORMAL);
326 if (RT_SUCCESS(rc))
327 {
328 RTFILE FileDst;
329 rc = RTFileOpen(&FileDst, pszUtf8DstFile, RTFILE_O_CREATE | RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE);
330 if (RT_SUCCESS(rc))
331 {
332 uint64_t cbSrc = VDIDiskGetSize(pVdi);
333 const unsigned cbBuf = VDIDiskGetBlockSize(pVdi); /* or perhaps VDIDiskGetBufferSize(pVdi)? */
334 void *pvBuf = RTMemAlloc(cbBuf);
335 if (pvBuf)
336 {
337 uint64_t off = 0;
338 while (off < cbSrc)
339 {
340 rc = VDIDiskRead(pVdi, off, pvBuf, cbBuf);
341 if (RT_FAILURE(rc))
342 break;
343 rc = RTFileWrite(FileDst, pvBuf, cbBuf, NULL);
344 if (RT_FAILURE(rc))
345 break;
346 off += cbBuf;
347 }
348 RTMemFree(pvBuf);
349 }
350 RTFileClose(FileDst);
351 }
352 }
353 VDIDiskCloseImage(pVdi);
354 return PrintDone(rc);
355}
356#endif
357
358#if 0
359static int ShrinkImage(const char *pszFilename)
360{
361 RTPrintf("Shrinking VDI image file=\"%s\"...\n"
362 "progress: 0%%",
363 pszFilename);
364
365 /* translate argv[] to UTF8 */
366 char *pszUtf8Filename;
367 int rc = FilenameToUtf8(&pszUtf8Filename, pszFilename);
368 if (RT_FAILURE(rc))
369 return rc;
370
371 unsigned uPrecent;
372 rc = VDIShrinkImage(pszUtf8Filename, ProcessCallback, &uPrecent);
373 RTPrintf("\n");
374 return PrintDone(rc);
375}
376#endif
377
378int main(int argc, char **argv)
379{
380 putenv((char*)"VBOX_LOG_DEST=stdout");
381 putenv((char*)"VBOX_LOG_FLAGS=");
382
383 RTR3InitExe(argc, &argv, 0);
384 RTPrintf("vditool -- for internal use only!\n"
385 "Copyright (C) 2009-" VBOX_C_YEAR " " VBOX_VENDOR "\n\n");
386
387 /*
388 * Do cmd line parsing.
389 */
390 if (argc < 2)
391 return UsageExit();
392
393 char szCmd[16];
394 if (strlen(argv[1]) >= sizeof(szCmd))
395 return SyntaxError("Invalid command!");
396 strcpy(szCmd, argv[1]);
397 ascii2upper(szCmd);
398
399 PRTLOGGER pLogger;
400 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
401 int rc = RTLogCreate(&pLogger, 0 /*fFlags*/, "all" /*pszGroupSettings*/,
402 NULL /*pszEnvVarBase*/, RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT,
403 NULL /*pszFilenameFmt*/);
404 RTLogRelSetDefaultInstance(pLogger);
405
406 if (strcmp(szCmd, "NEW") == 0)
407 {
408 if (argc != 4)
409 return SyntaxError("Invalid argument count!");
410
411 uint64_t cMBs;
412 rc = RTStrToUInt64Ex(argv[3], NULL, 10, &cMBs);
413 if (RT_FAILURE(rc))
414 return SyntaxError("Invalid number!");
415 if (cMBs < 2)
416 {
417 RTPrintf("error: Disk size %RU64MB must be at least 2MB!\n", cMBs);
418 return 1;
419 }
420
421 rc = NewImage(argv[2], cMBs);
422 }
423#if 0
424 else if (strcmp(szCmd, "DD") == 0)
425 {
426 if (argc != 4)
427 return SyntaxError("Invalid argument count!");
428 rc = ConvertDDImage(argv[2], argv[3]);
429 }
430 else if (strcmp(szCmd, "CONVERT") == 0)
431 {
432 if (argc != 3)
433 return SyntaxError("Invalid argument count!");
434 rc = ConvertOldImage(argv[2]);
435 }
436 else if (strcmp(szCmd, "DUMP") == 0)
437 {
438 if (argc != 3)
439 return SyntaxError("Invalid argument count!");
440 rc = DumpImage(argv[2]);
441 }
442 else if (strcmp(szCmd, "RESETGEO") == 0)
443 {
444 if (argc != 3)
445 return SyntaxError("Invalid argument count!");
446 rc = ResetImageGeometry(argv[2]);
447 }
448 else if (strcmp(szCmd, "COPY") == 0)
449 {
450 if (argc != 4)
451 return SyntaxError("Invalid argument count!");
452 rc = CopyImage(argv[3], argv[2]);
453 }
454 else if (strcmp(szCmd, "COPYDD") == 0)
455 {
456 if (argc != 4)
457 return SyntaxError("Invalid argument count!");
458 rc = CopyToDD(argv[3], argv[2]);
459 }
460 else if (strcmp(szCmd, "SHRINK") == 0)
461 {
462 if (argc != 3)
463 return SyntaxError("Invalid argument count!");
464 rc = ShrinkImage(argv[2]);
465 }
466#endif
467 else
468 return SyntaxError("Invalid command!");
469
470 RTLogFlush(NULL);
471 return !RT_SUCCESS(rc);
472}
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