VirtualBox

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

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

*: scm cleanup run.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 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-2011 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/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/*********************************************************************************************************************************
35* Global Variables *
36*********************************************************************************************************************************/
37/** The error count. */
38unsigned g_cErrors = 0;
39
40
41static void tstVDError(void *pvUser, int rc, RT_SRC_POS_DECL,
42 const char *pszFormat, va_list va)
43{
44 g_cErrors++;
45 RTPrintf("tstVD: Error %Rrc at %s:%u (%s): ", rc, RT_SRC_POS_ARGS);
46 RTPrintfV(pszFormat, va);
47 RTPrintf("\n");
48}
49
50int main(int argc, char *argv[])
51{
52 int rc;
53
54 RTR3InitExe(argc, &argv, 0);
55
56 if (argc != 3)
57 {
58 RTPrintf("Usage: ./tstVDCopy <hdd1> <hdd2>\n");
59 return 1;
60 }
61
62 RTPrintf("tstVDCopy: TESTING...\n");
63
64 PVBOXHDD pVD1 = NULL;
65 PVBOXHDD pVD2 = NULL;
66 PVDINTERFACE pVDIfs = NULL;
67 VDINTERFACEERROR VDIfError;
68 char *pszVD1 = NULL;
69 char *pszVD2 = NULL;
70 char *pbBuf1 = NULL;
71 char *pbBuf2 = NULL;
72 VDTYPE enmTypeVD1 = VDTYPE_INVALID;
73 VDTYPE enmTypeVD2 = VDTYPE_INVALID;
74
75#define CHECK(str) \
76 do \
77 { \
78 if (RT_FAILURE(rc)) \
79 { \
80 RTPrintf("%s rc=%Rrc\n", str, rc); \
81 if (pVD1) \
82 VDCloseAll(pVD1); \
83 if (pVD2) \
84 VDCloseAll(pVD2); \
85 return rc; \
86 } \
87 } while (0)
88
89 pbBuf1 = (char *)RTMemAllocZ(VD_MERGE_BUFFER_SIZE);
90 pbBuf2 = (char *)RTMemAllocZ(VD_MERGE_BUFFER_SIZE);
91
92 /* Create error interface. */
93 VDIfError.pfnError = tstVDError;
94
95 rc = VDInterfaceAdd(&VDIfError.Core, "tstVD_Error", VDINTERFACETYPE_ERROR,
96 NULL, sizeof(VDINTERFACEERROR), &pVDIfs);
97 AssertRC(rc);
98
99 rc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */,
100 argv[1], &pszVD1, &enmTypeVD1);
101 CHECK("VDGetFormat() hdd1");
102
103 rc = VDGetFormat(NULL /* pVDIfsDisk */, NULL /* pVDIfsImage */,
104 argv[2], &pszVD2, &enmTypeVD2);
105 CHECK("VDGetFormat() hdd2");
106
107 rc = VDCreate(pVDIfs, VDTYPE_HDD, &pVD1);
108 CHECK("VDCreate() hdd1");
109
110 rc = VDCreate(pVDIfs, VDTYPE_HDD, &pVD2);
111 CHECK("VDCreate() hdd1");
112
113 rc = VDOpen(pVD1, pszVD1, argv[1], VD_OPEN_FLAGS_NORMAL, NULL);
114 CHECK("VDOpen() hdd1");
115
116 rc = VDOpen(pVD2, pszVD2, argv[2], VD_OPEN_FLAGS_NORMAL, NULL);
117 CHECK("VDOpen() hdd2");
118
119 uint64_t cbSize1 = 0;
120 uint64_t cbSize2 = 0;
121
122 cbSize1 = VDGetSize(pVD1, 0);
123 Assert(cbSize1 != 0);
124 cbSize2 = VDGetSize(pVD1, 0);
125 Assert(cbSize1 != 0);
126
127 if (cbSize1 == cbSize2)
128 {
129 uint64_t uOffCurr = 0;
130
131 /* Compare block by block. */
132 while (uOffCurr < cbSize1)
133 {
134 size_t cbRead = RT_MIN((cbSize1 - uOffCurr), VD_MERGE_BUFFER_SIZE);
135
136 rc = VDRead(pVD1, uOffCurr, pbBuf1, cbRead);
137 CHECK("VDRead() hdd1");
138
139 rc = VDRead(pVD2, uOffCurr, pbBuf2, cbRead);
140 CHECK("VDRead() hdd2");
141
142 if (memcmp(pbBuf1, pbBuf2, cbRead))
143 {
144 RTPrintf("tstVDCopy: Images differ uOffCurr=%llu\n", uOffCurr);
145 /* Do byte by byte comparison. */
146 for (size_t i = 0; i < cbRead; i++)
147 {
148 if (pbBuf1[i] != pbBuf2[i])
149 {
150 RTPrintf("tstVDCopy: First different byte is at offset %llu\n", uOffCurr + i);
151 break;
152 }
153 }
154 break;
155 }
156
157 uOffCurr += cbRead;
158 }
159 }
160 else
161 RTPrintf("tstVDCopy: Images have different size hdd1=%llu hdd2=%llu\n", cbSize1, cbSize2);
162
163 VDClose(pVD1, false);
164 CHECK("VDClose() hdd1");
165
166 VDClose(pVD2, false);
167 CHECK("VDClose() hdd2");
168
169 VDDestroy(pVD1);
170 VDDestroy(pVD2);
171 RTMemFree(pbBuf1);
172 RTMemFree(pbBuf2);
173#undef CHECK
174
175 rc = VDShutdown();
176 if (RT_FAILURE(rc))
177 {
178 RTPrintf("tstVDCopy: unloading backends failed! rc=%Rrc\n", rc);
179 g_cErrors++;
180 }
181 /*
182 * Summary
183 */
184 if (!g_cErrors)
185 RTPrintf("tstVDCopy: SUCCESS\n");
186 else
187 RTPrintf("tstVDCopy: FAILURE - %d errors\n", g_cErrors);
188
189 return !!g_cErrors;
190}
191
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