VirtualBox

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

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

IPRT/Dvm: Commit BSD disklabel support.

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