VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTDvm.cpp@ 68155

Last change on this file since 68155 was 62477, checked in by vboxsync, 8 years ago

(C) 2016

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/* $Id: tstRTDvm.cpp 62477 2016-07-22 18:27:37Z vboxsync $ */
2/** @file
3 * IPRT Testcase - IPRT Disk Volume Management (DVM)
4 */
5
6/*
7 * Copyright (C) 2009-2016 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/dvm.h>
32
33#include <iprt/err.h>
34#include <iprt/test.h>
35#include <iprt/file.h>
36#include <iprt/string.h>
37
38
39/*********************************************************************************************************************************
40* Structures and Typedefs *
41*********************************************************************************************************************************/
42/**
43 * Disk structure.
44 */
45typedef struct TSTRTDVMDISK
46{
47 /** Flag whether this disk uses the image file or a volume. */
48 bool fUseImage;
49 /** Data dependent on the flag. */
50 union
51 {
52 /** File handle of the image. */
53 RTFILE hImage;
54 /** Handle of the volume. */
55 RTDVMVOLUME hVol;
56 };
57} TSTRTDVMDISK, *PTSTRTDVMDISK;
58
59
60
61static DECLCALLBACK(int) dvmDiskRead(void *pvUser, uint64_t off, void *pvBuf, size_t cbRead)
62{
63 PTSTRTDVMDISK pDisk = (PTSTRTDVMDISK)pvUser;
64
65 if (pDisk->fUseImage)
66 return RTFileReadAt(pDisk->hImage, off, pvBuf, cbRead, NULL);
67 return RTDvmVolumeRead(pDisk->hVol, off, pvBuf, cbRead);
68}
69
70static DECLCALLBACK(int) dvmDiskWrite(void *pvUser, uint64_t off, const void *pvBuf, size_t cbWrite)
71{
72 PTSTRTDVMDISK pDisk = (PTSTRTDVMDISK)pvUser;
73
74 if (pDisk->fUseImage)
75 return RTFileWriteAt(pDisk->hImage, off, pvBuf, cbWrite, NULL);
76 return RTDvmVolumeWrite(pDisk->hVol, off, pvBuf, cbWrite);
77}
78
79static int tstRTDvmVolume(RTTEST hTest, PTSTRTDVMDISK pDisk, uint64_t cb, unsigned cNesting)
80{
81 char szPrefix[100];
82 int rc = VINF_SUCCESS;
83
84 RT_ZERO(szPrefix);
85
86 if (cNesting < sizeof(szPrefix) - 1)
87 {
88 for (unsigned i = 0; i < cNesting; i++)
89 szPrefix[i] = '\t';
90 }
91
92 RTTestSubF(hTest, "Create DVM");
93 RTDVM hVolMgr;
94 rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, 0, pDisk);
95 if (RT_FAILURE(rc))
96 {
97 RTTestIFailed("RTDvmCreate -> %Rrc", rc);
98 return RTTestSummaryAndDestroy(hTest);
99 }
100
101 RTTestSubF(hTest, "Open volume map");
102 rc = RTDvmMapOpen(hVolMgr);
103 if ( RT_FAILURE(rc)
104 && rc != VERR_NOT_SUPPORTED)
105 {
106 RTTestIFailed("RTDvmOpen -> %Rrc", rc);
107 return RTTestSummaryAndDestroy(hTest);
108 }
109 if (rc == VERR_NOT_SUPPORTED)
110 return VINF_SUCCESS;
111
112 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Successfully opened map with format: %s.\n", szPrefix, RTDvmMapGetFormat(hVolMgr));
113
114 /* Dump all volumes. */
115 RTTestSubF(hTest, "Dump volumes");
116 uint32_t cVolume = 0;
117 RTDVMVOLUME hVol;
118
119 rc = RTDvmMapQueryFirstVolume(hVolMgr, &hVol);
120
121 while (RT_SUCCESS(rc))
122 {
123 char *pszVolName = NULL;
124 RTDVMVOLTYPE enmVolType = RTDvmVolumeGetType(hVol);
125 uint64_t fVolFlags = RTDvmVolumeGetFlags(hVol);
126
127 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume %u:\n", szPrefix, cVolume);
128 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume type %s\n", szPrefix, RTDvmVolumeTypeGetDescr(enmVolType));
129 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume size %llu\n", szPrefix, RTDvmVolumeGetSize(hVol));
130 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume flags %s %s\n\n", szPrefix,
131 fVolFlags & DVMVOLUME_FLAGS_BOOTABLE ? "Bootable" : "",
132 fVolFlags & DVMVOLUME_FLAGS_ACTIVE ? "Active" : "");
133
134 rc = RTDvmVolumeQueryName(hVol, &pszVolName);
135 if (RT_SUCCESS(rc))
136 {
137 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Volume name %s.\n", szPrefix, pszVolName);
138 RTStrFree(pszVolName);
139 }
140 else if (rc != VERR_NOT_SUPPORTED)
141 RTTestIFailed("RTDvmVolumeQueryName -> %Rrc", rc);
142 else
143 rc = VINF_SUCCESS;
144
145 /*
146 * Query all volumes which might be inside this.
147 * (think of MBR partitions with a bsdlabel inside)
148 */
149 TSTRTDVMDISK Disk;
150 Disk.fUseImage = false;
151 Disk.hVol = hVol;
152 rc = tstRTDvmVolume(hTest, &Disk, RTDvmVolumeGetSize(hVol), cNesting + 1);
153
154 RTDVMVOLUME hVolNext;
155 rc = RTDvmMapQueryNextVolume(hVolMgr, hVol, &hVolNext);
156 RTDvmVolumeRelease(hVol);
157 hVol = hVolNext;
158 cVolume++;
159 }
160
161 RTTestIPrintf(RTTESTLVL_ALWAYS, "%s Dumped %u volumes\n", szPrefix, cVolume);
162
163 if ( rc == VERR_DVM_MAP_EMPTY
164 || rc == VERR_DVM_MAP_NO_VOLUME)
165 rc = VINF_SUCCESS;
166
167 RTTESTI_CHECK(rc == VINF_SUCCESS);
168
169 RTDvmRelease(hVolMgr);
170
171 return rc;
172}
173
174int main(int argc, char **argv)
175{
176 /*
177 * Initialize IPRT and create the test.
178 */
179 RTTEST hTest;
180 int rc = RTTestInitAndCreate("tstRTDvm", &hTest);
181 if (rc)
182 return rc;
183 RTTestBanner(hTest);
184
185 /*
186 * If no args, display usage.
187 */
188 if (argc < 2)
189 {
190 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "Syntax: %s <image>\n", argv[0]);
191 return RTTestSkipAndDestroy(hTest, "Missing required arguments\n");
192 }
193
194 /* Open image. */
195 RTFILE hFile;
196 uint64_t cb = 0;
197 rc = RTFileOpen(&hFile, argv[1], RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_READWRITE);
198 if (RT_FAILURE(rc))
199 {
200 RTTestIFailed("RTFileOpen -> %Rrc", rc);
201 return RTTestSummaryAndDestroy(hTest);
202 }
203
204 rc = RTFileGetSize(hFile, &cb);
205 if ( RT_FAILURE(rc)
206 || cb % 512 != 0) /* Assume 512 byte sector size. */
207 {
208 RTTestIFailed("RTFileGetSize -> %Rrc", rc);
209 return RTTestSummaryAndDestroy(hTest);
210 }
211
212 TSTRTDVMDISK Disk;
213
214 Disk.fUseImage = true;
215 Disk.hImage = hFile;
216 rc = tstRTDvmVolume(hTest, &Disk, cb, 0);
217
218 RTTESTI_CHECK(rc == VINF_SUCCESS);
219
220 /*
221 * Summary
222 */
223 return RTTestSummaryAndDestroy(hTest);
224}
225
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