VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/testcase/tstVDSetUuid.cpp@ 32204

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

Devices/Storage: new testcase for tweaking image/parent UUID values

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/* $Id: tstVDSetUuid.cpp 31488 2010-08-09 15:56:27Z vboxsync $ */
2/** @file
3 * Simple VBox HDD container test utility for changing the uuid of images.
4 */
5
6/*
7 * Copyright (C) 2010 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* Header Files *
20*******************************************************************************/
21#include <VBox/VBoxHDD.h>
22#include <VBox/err.h>
23#include <iprt/initterm.h>
24#include <iprt/buildconfig.h>
25#include <iprt/path.h>
26#include <iprt/string.h>
27#include <iprt/uuid.h>
28#include <iprt/stream.h>
29#include <iprt/message.h>
30#include <iprt/getopt.h>
31
32const char *g_pszProgName = "";
33
34static const RTGETOPTDEF s_aOptions[] =
35{
36 { "--filename", 'f', RTGETOPT_REQ_STRING },
37 { "--format", 'o', RTGETOPT_REQ_STRING },
38 { "--uuid", 'u', RTGETOPT_REQ_UUID },
39 { "--parentuuid", 'p', RTGETOPT_REQ_UUID },
40 { "--zeroparentuuid", 'P', RTGETOPT_REQ_NOTHING }
41};
42
43static void showUsage(void)
44{
45 RTStrmPrintf(g_pStdErr,
46 "Usage: %s\n"
47 " --filename <filename>\n"
48 " [--format VDI|VMDK|VHD|...]\n"
49 " [--uuid <uuid>]\n"
50 " [--parentuuid <uuid>]\n"
51 " [--zeroparentuuid]\n",
52 g_pszProgName);
53}
54
55static DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL,
56 const char *pszFormat, va_list va)
57{
58 NOREF(pvUser);
59 NOREF(rc);
60 RTMsgErrorV(pszFormat, va);
61}
62
63static int handleVDMessage(void *pvUser, const char *pszFormat, ...)
64{
65 NOREF(pvUser);
66 va_list args;
67 va_start(args, pszFormat);
68 RTMsgWarningV(pszFormat, args);
69 va_end(args);
70 return VINF_SUCCESS;
71}
72
73int main(int argc, char *argv[])
74{
75 RTR3Init();
76 int rc;
77 const char *pszFilename = NULL;
78 char *pszFormat = NULL;
79 RTUUID imageUuid;
80 RTUUID parentUuid;
81 bool fSetImageUuid = false;
82 bool fSetParentUuid = false;
83
84 g_pszProgName = RTPathFilename(argv[0]);
85
86 RTUuidClear(&imageUuid);
87 RTUuidClear(&parentUuid);
88
89 /* Parse the command line. */
90 int ch;
91 RTGETOPTUNION ValueUnion;
92 RTGETOPTSTATE GetState;
93 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /* fFlags */);
94 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
95 {
96 switch (ch)
97 {
98 case 'f': // --filename
99 pszFilename = ValueUnion.psz;
100 break;
101 case 'o': // --format
102 pszFormat = RTStrDup(ValueUnion.psz);
103 break;
104 case 'u': // --uuid
105 imageUuid = ValueUnion.Uuid;
106 fSetImageUuid = true;
107 break;
108 case 'p': // --parentuuid
109 parentUuid = ValueUnion.Uuid;
110 fSetParentUuid = true;
111 break;
112 case 'P': // --zeroparentuuid
113 RTUuidClear(&parentUuid);
114 fSetParentUuid = true;
115 break;
116 case 'h': // --help
117 showUsage();
118 return 0;
119 case 'V': // --version
120 RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
121 return 0;
122 default:
123 ch = RTGetOptPrintError(ch, &ValueUnion);
124 showUsage();
125 return ch;
126 }
127 }
128
129 /* Check for mandatory parameters. */
130 if (!pszFilename)
131 {
132 RTMsgError("Mandatory --filename option missing\n");
133 showUsage();
134 return 1;
135 }
136
137 /* Check for consistency of optional parameters. */
138 if (fSetImageUuid && RTUuidIsNull(&imageUuid))
139 {
140 RTMsgError("Invalid parameter to --uuid option\n");
141 showUsage();
142 return 1;
143 }
144
145 PVDINTERFACE pVDIfs = NULL;
146 VDINTERFACE vdInterfaceError;
147 VDINTERFACEERROR vdInterfaceErrorCallbacks;
148 vdInterfaceErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
149 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
150 vdInterfaceErrorCallbacks.pfnError = handleVDError;
151 vdInterfaceErrorCallbacks.pfnMessage = handleVDMessage;
152
153 rc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
154 &vdInterfaceErrorCallbacks, NULL, &pVDIfs);
155
156 /* Autodetect image format. */
157 if (!pszFormat)
158 {
159 /* Don't pass error interface, as that would triggers error messages
160 * because some backends fail to open the image. */
161 rc = VDGetFormat(NULL, pszFilename, &pszFormat);
162 if (RT_FAILURE(rc))
163 {
164 RTMsgError("Format autodetect failed: %Rrc\n", rc);
165 return 1;
166 }
167 }
168
169 PVBOXHDD pVD = NULL;
170 rc = VDCreate(pVDIfs, &pVD);
171 if (RT_FAILURE(rc))
172 {
173 RTMsgError("Cannot create the virtual disk container: %Rrc\n", rc);
174 return 1;
175 }
176
177 rc = VDOpen(pVD, pszFormat, pszFilename, VD_OPEN_FLAGS_NORMAL, NULL);
178 if (RT_FAILURE(rc))
179 {
180 RTMsgError("Cannot open the virtual disk image \"%s\": %Rrc\n",
181 pszFilename, rc);
182 return 1;
183 }
184
185 RTUUID oldImageUuid;
186 rc = VDGetUuid(pVD, VD_LAST_IMAGE, &oldImageUuid);
187 if (RT_FAILURE(rc))
188 {
189 RTMsgError("Cannot get UUID of virtual disk image \"%s\": %Rrc\n",
190 pszFilename, rc);
191 return 1;
192 }
193 RTPrintf("Old image UUID: %RTuuid\n", &oldImageUuid);
194
195 RTUUID oldParentUuid;
196 rc = VDGetParentUuid(pVD, VD_LAST_IMAGE, &oldParentUuid);
197 if (RT_FAILURE(rc))
198 {
199 RTMsgError("Cannot get parent UUID of virtual disk image \"%s\": %Rrc\n",
200 pszFilename, rc);
201 return 1;
202 }
203 RTPrintf("Old parent UUID: %RTuuid\n", &oldParentUuid);
204
205 if (fSetImageUuid)
206 {
207 RTPrintf("New image UUID: %RTuuid\n", &imageUuid);
208 rc = VDSetUuid(pVD, VD_LAST_IMAGE, &imageUuid);
209 if (RT_FAILURE(rc))
210 {
211 RTMsgError("Cannot set UUID of virtual disk image \"%s\": %Rrc\n",
212 pszFilename, rc);
213 return 1;
214 }
215 }
216
217 if (fSetParentUuid)
218 {
219 RTPrintf("New parent UUID: %RTuuid\n", &parentUuid);
220 rc = VDSetParentUuid(pVD, VD_LAST_IMAGE, &parentUuid);
221 if (RT_FAILURE(rc))
222 {
223 RTMsgError("Cannot set parent UUID of virtual disk image \"%s\": %Rrc\n",
224 pszFilename, rc);
225 return 1;
226 }
227 }
228
229 rc = VDCloseAll(pVD);
230 if (RT_FAILURE(rc))
231 {
232 RTMsgError("Closing image failed! rc=%Rrc\n", rc);
233 return 1;
234 }
235
236 if (pszFormat)
237 {
238 RTStrFree(pszFormat);
239 pszFormat = NULL;
240 }
241
242 rc = VDShutdown();
243 if (RT_FAILURE(rc))
244 {
245 RTMsgError("Unloading backends failed! rc=%Rrc\n", rc);
246 return 1;
247 }
248
249 return 0;
250}
251
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