VirtualBox

source: vbox/trunk/src/VBox/Storage/testcase/tstVDCopy.cpp@ 38469

Last change on this file since 38469 was 38469, checked in by vboxsync, 14 years ago

VD: Interface cleanup. Merge the two involved structures (generic interface descriptor and callback table) into one, remove the duplicated interface wrappers in the backends and move the interface definitions into separate headers separating public and private interfaces.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.1 KB
Line 
1/** @file
2 *
3 * Simple VBox HDD container test utility. Compares two images and prints
4 * differences. Mainly used to check cloning of disk images.
5 */
6
7/*
8 * Copyright (C) 2006-2010 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.215389.xyz. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include <VBox/err.h>
20#include <VBox/vd.h>
21#include <iprt/string.h>
22#include <iprt/stream.h>
23#include <iprt/file.h>
24#include <iprt/mem.h>
25#include <iprt/initterm.h>
26#include <iprt/rand.h>
27#include "stdio.h"
28#include "stdlib.h"
29
30/* from VBoxHDD.cpp */
31#define VD_MERGE_BUFFER_SIZE (16 * _1M)
32
33/*******************************************************************************
34* Global Variables *
35*******************************************************************************/
36/** The error count. */
37unsigned g_cErrors = 0;
38
39
40static void tstVDError(void *pvUser, int rc, RT_SRC_POS_DECL,
41 const char *pszFormat, va_list va)
42{
43 g_cErrors++;
44 RTPrintf("tstVD: Error %Rrc at %s:%u (%s): ", rc, RT_SRC_POS_ARGS);
45 RTPrintfV(pszFormat, va);
46 RTPrintf("\n");
47}
48
49int main(int argc, char *argv[])
50{
51 int rc;
52
53 RTR3Init();
54
55 if (argc != 3)
56 {
57 RTPrintf("Usage: ./tstVDCopy <hdd1> <hdd2>\n");
58 return 1;
59 }
60
61 RTPrintf("tstVDCopy: TESTING...\n");
62
63 PVBOXHDD pVD1 = NULL;
64 PVBOXHDD pVD2 = NULL;
65 PVDINTERFACE pVDIfs = NULL;
66 VDINTERFACEERROR VDIfError;
67 char *pszVD1 = NULL;
68 char *pszVD2 = NULL;
69 char *pbBuf1 = NULL;
70 char *pbBuf2 = NULL;
71 VDTYPE enmTypeVD1 = VDTYPE_INVALID;
72 VDTYPE enmTypeVD2 = VDTYPE_INVALID;
73
74#define CHECK(str) \
75 do \
76 { \
77 if (RT_FAILURE(rc)) \
78 { \
79 RTPrintf("%s rc=%Rrc\n", str, rc); \
80 if (pVD1) \
81 VDCloseAll(pVD1); \
82 if (pVD2) \
83 VDCloseAll(pVD2); \
84 return rc; \
85 } \
86 } while (0)
87
88 pbBuf1 = (char *)RTMemAllocZ(VD_MERGE_BUFFER_SIZE);
89 pbBuf2 = (char *)RTMemAllocZ(VD_MERGE_BUFFER_SIZE);
90
91 /* Create error interface. */
92 VDIfError.pfnError = tstVDError;
93
94 rc = VDInterfaceAdd(&VDIfError.Core, "tstVD_Error", VDINTERFACETYPE_ERROR,
95 NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
96 AssertRC(rc);
97
98 rc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */,
99 argv[1], &pszVD1, &enmTypeVD1);
100 CHECK("VDGetFormat() hdd1");
101
102 rc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */,
103 argv[2], &pszVD2, &enmTypeVD2);
104 CHECK("VDGetFormat() hdd2");
105
106 rc = VDCreate(pVDIfs, VDTYPE_HDD, &pVD1);
107 CHECK("VDCreate() hdd1");
108
109 rc = VDCreate(pVDIfs, VDTYPE_HDD, &pVD2);
110 CHECK("VDCreate() hdd1");
111
112 rc = VDOpen(pVD1, pszVD1, argv[1], VD_OPEN_FLAGS_NORMAL, NULL);
113 CHECK("VDOpen() hdd1");
114
115 rc = VDOpen(pVD2, pszVD2, argv[2], VD_OPEN_FLAGS_NORMAL, NULL);
116 CHECK("VDOpen() hdd2");
117
118 uint64_t cbSize1 = 0;
119 uint64_t cbSize2 = 0;
120
121 cbSize1 = VDGetSize(pVD1, 0);
122 Assert(cbSize1 != 0);
123 cbSize2 = VDGetSize(pVD1, 0);
124 Assert(cbSize1 != 0);
125
126 if (cbSize1 == cbSize2)
127 {
128 uint64_t uOffCurr = 0;
129
130 /* Compare block by block. */
131 while (uOffCurr < cbSize1)
132 {
133 size_t cbRead = RT_MIN((cbSize1 - uOffCurr), VD_MERGE_BUFFER_SIZE);
134
135 rc = VDRead(pVD1, uOffCurr, pbBuf1, cbRead);
136 CHECK("VDRead() hdd1");
137
138 rc = VDRead(pVD2, uOffCurr, pbBuf2, cbRead);
139 CHECK("VDRead() hdd2");
140
141 if (memcmp(pbBuf1, pbBuf2, cbRead))
142 {
143 RTPrintf("tstVDCopy: Images differ uOffCurr=%llu\n", uOffCurr);
144 /* Do byte by byte comparison. */
145 for (size_t i = 0; i < cbRead; i++)
146 {
147 if (pbBuf1[i] != pbBuf2[i])
148 {
149 RTPrintf("tstVDCopy: First different byte is at offset %llu\n", uOffCurr + i);
150 break;
151 }
152 }
153 break;
154 }
155
156 uOffCurr += cbRead;
157 }
158 }
159 else
160 RTPrintf("tstVDCopy: Images have different size hdd1=%llu hdd2=%llu\n", cbSize1, cbSize2);
161
162 VDClose(pVD1, false);
163 CHECK("VDClose() hdd1");
164
165 VDClose(pVD2, false);
166 CHECK("VDClose() hdd2");
167
168 VDDestroy(pVD1);
169 VDDestroy(pVD2);
170 RTMemFree(pbBuf1);
171 RTMemFree(pbBuf2);
172#undef CHECK
173
174 rc = VDShutdown();
175 if (RT_FAILURE(rc))
176 {
177 RTPrintf("tstVDCopy: unloading backends failed! rc=%Rrc\n", rc);
178 g_cErrors++;
179 }
180 /*
181 * Summary
182 */
183 if (!g_cErrors)
184 RTPrintf("tstVDCopy: SUCCESS\n");
185 else
186 RTPrintf("tstVDCopy: FAILURE - %d errors\n", g_cErrors);
187
188 return !!g_cErrors;
189}
190
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