VirtualBox

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

最後變更 在這個檔案從21400是 21400,由 vboxsync 提交於 16 年 前

export to OSE

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

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