VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.0 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-2007 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. 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/VBoxHDD.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 VDINTERFACE VDIError;
67 VDINTERFACEERROR VDIErrorCallbacks;
68 char *pszVD1 = NULL;
69 char *pszVD2 = NULL;
70 char *pbBuf1 = NULL;
71 char *pbBuf2 = NULL;
72
73#define CHECK(str) \
74 do \
75 { \
76 if (RT_FAILURE(rc)) \
77 { \
78 RTPrintf("%s rc=%Rrc\n", str, rc); \
79 if (pVD1) \
80 VDCloseAll(pVD1); \
81 if (pVD2) \
82 VDCloseAll(pVD2); \
83 return rc; \
84 } \
85 } while (0)
86
87 pbBuf1 = (char *)RTMemAllocZ(VD_MERGE_BUFFER_SIZE);
88 pbBuf2 = (char *)RTMemAllocZ(VD_MERGE_BUFFER_SIZE);
89
90 /* Create error interface. */
91 VDIErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
92 VDIErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
93 VDIErrorCallbacks.pfnError = tstVDError;
94
95 rc = VDInterfaceAdd(&VDIError, "tstVD_Error", VDINTERFACETYPE_ERROR, &VDIErrorCallbacks,
96 NULL, &pVDIfs);
97 AssertRC(rc);
98
99 rc = VDGetFormat(NULL, argv[1], &pszVD1);
100 CHECK("VDGetFormat() hdd1");
101
102 rc = VDGetFormat(NULL, argv[2], &pszVD2);
103 CHECK("VDGetFormat() hdd2");
104
105 rc = VDCreate(&VDIError, &pVD1);
106 CHECK("VDCreate() hdd1");
107
108 rc = VDCreate(&VDIError, &pVD2);
109 CHECK("VDCreate() hdd1");
110
111 rc = VDOpen(pVD1, pszVD1, argv[1], VD_OPEN_FLAGS_NORMAL, NULL);
112 CHECK("VDOpen() hdd1");
113
114 rc = VDOpen(pVD2, pszVD2, argv[2], VD_OPEN_FLAGS_NORMAL, NULL);
115 CHECK("VDOpen() hdd2");
116
117 uint64_t cbSize1 = 0;
118 uint64_t cbSize2 = 0;
119
120 cbSize1 = VDGetSize(pVD1, 0);
121 Assert(cbSize1 != 0);
122 cbSize2 = VDGetSize(pVD1, 0);
123 Assert(cbSize1 != 0);
124
125 if (cbSize1 == cbSize2)
126 {
127 uint64_t uOffCurr = 0;
128
129 /* Compare block by block. */
130 while (uOffCurr < cbSize1)
131 {
132 size_t cbRead = RT_MIN((cbSize1 - uOffCurr), VD_MERGE_BUFFER_SIZE);
133
134 rc = VDRead(pVD1, uOffCurr, pbBuf1, cbRead);
135 CHECK("VDRead() hdd1");
136
137 rc = VDRead(pVD2, uOffCurr, pbBuf2, cbRead);
138 CHECK("VDRead() hdd2");
139
140 if (memcmp(pbBuf1, pbBuf2, cbRead))
141 {
142 RTPrintf("tstVDCopy: Images differ uOffCurr=%llu\n", uOffCurr);
143 /* Do byte by byte comaprison. */
144 for (size_t i = 0; i < cbRead; i++)
145 {
146 if (pbBuf1[i] != pbBuf2[i])
147 {
148 RTPrintf("tstVDCopy: First different byte is at offset %llu\n", uOffCurr + i);
149 break;
150 }
151 }
152 break;
153 }
154
155 uOffCurr += cbRead;
156 }
157 }
158 else
159 RTPrintf("tstVDCopy: Images have different size hdd1=%llu hdd2=%llu\n", cbSize1, cbSize2);
160
161 VDClose(pVD1, false);
162 CHECK("VDClose() hdd1");
163
164 VDClose(pVD2, false);
165 CHECK("VDClose() hdd2");
166
167 VDDestroy(pVD1);
168 VDDestroy(pVD2);
169 RTMemFree(pbBuf1);
170 RTMemFree(pbBuf2);
171#undef CHECK
172
173 rc = VDShutdown();
174 if (RT_FAILURE(rc))
175 {
176 RTPrintf("tstVD-2: unloading backends failed! rc=%Rrc\n", rc);
177 g_cErrors++;
178 }
179 /*
180 * Summary
181 */
182 if (!g_cErrors)
183 RTPrintf("tstVD-2: SUCCESS\n");
184 else
185 RTPrintf("tstVD-2: FAILURE - %d errors\n", g_cErrors);
186
187 return !!g_cErrors;
188}
189
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use