VirtualBox

source: vbox/trunk/include/VBox/vd.h@ 38378

Last change on this file since 38378 was 38203, checked in by vboxsync, 14 years ago

VD: New VDCopyEx() API which can speedup cloning of diff images when cloning a VM

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 109.8 KB
Line 
1/** @file
2 * VBox HDD Container API.
3 */
4
5/*
6 * Copyright (C) 2006-2010 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_VD_h
27#define ___VBox_VD_h
28
29#include <iprt/assert.h>
30#include <iprt/string.h>
31#include <iprt/mem.h>
32#include <iprt/file.h>
33#include <iprt/net.h>
34#include <iprt/sg.h>
35#include <VBox/cdefs.h>
36#include <VBox/types.h>
37#include <VBox/err.h>
38
39RT_C_DECLS_BEGIN
40
41#ifdef IN_RING0
42# error "There are no VBox HDD Container APIs available in Ring-0 Host Context!"
43#endif
44
45/** @defgroup grp_vd VBox HDD Container
46 * @{
47 */
48
49/** Current VMDK image version. */
50#define VMDK_IMAGE_VERSION (0x0001)
51
52/** Current VDI image major version. */
53#define VDI_IMAGE_VERSION_MAJOR (0x0001)
54/** Current VDI image minor version. */
55#define VDI_IMAGE_VERSION_MINOR (0x0001)
56/** Current VDI image version. */
57#define VDI_IMAGE_VERSION ((VDI_IMAGE_VERSION_MAJOR << 16) | VDI_IMAGE_VERSION_MINOR)
58
59/** Get VDI major version from combined version. */
60#define VDI_GET_VERSION_MAJOR(uVer) ((uVer) >> 16)
61/** Get VDI minor version from combined version. */
62#define VDI_GET_VERSION_MINOR(uVer) ((uVer) & 0xffff)
63
64/** Placeholder for specifying the last opened image. */
65#define VD_LAST_IMAGE 0xffffffffU
66
67/** Placeholder for VDCopyEx to indicate that the image content is unknown. */
68#define VD_IMAGE_CONTENT_UNKNOWN 0xffffffffU
69
70/** @name VBox HDD container image flags
71 * @{
72 */
73/** No flags. */
74#define VD_IMAGE_FLAGS_NONE (0)
75/** Fixed image. */
76#define VD_IMAGE_FLAGS_FIXED (0x10000)
77/** Diff image. Mutually exclusive with fixed image. */
78#define VD_IMAGE_FLAGS_DIFF (0x20000)
79/** VMDK: Split image into 2GB extents. */
80#define VD_VMDK_IMAGE_FLAGS_SPLIT_2G (0x0001)
81/** VMDK: Raw disk image (giving access to a number of host partitions). */
82#define VD_VMDK_IMAGE_FLAGS_RAWDISK (0x0002)
83/** VMDK: stream optimized image, read only. */
84#define VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED (0x0004)
85/** VMDK: ESX variant, use in addition to other flags. */
86#define VD_VMDK_IMAGE_FLAGS_ESX (0x0008)
87/** VDI: Fill new blocks with zeroes while expanding image file. Only valid
88 * for newly created images, never set for opened existing images. */
89#define VD_VDI_IMAGE_FLAGS_ZERO_EXPAND (0x0100)
90
91/** Mask of valid image flags for VMDK. */
92#define VD_VMDK_IMAGE_FLAGS_MASK ( VD_IMAGE_FLAGS_FIXED | VD_IMAGE_FLAGS_DIFF | VD_IMAGE_FLAGS_NONE \
93 | VD_VMDK_IMAGE_FLAGS_SPLIT_2G | VD_VMDK_IMAGE_FLAGS_RAWDISK \
94 | VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED | VD_VMDK_IMAGE_FLAGS_ESX)
95
96/** Mask of valid image flags for VDI. */
97#define VD_VDI_IMAGE_FLAGS_MASK (VD_IMAGE_FLAGS_FIXED | VD_IMAGE_FLAGS_DIFF | VD_IMAGE_FLAGS_NONE | VD_VDI_IMAGE_FLAGS_ZERO_EXPAND)
98
99/** Mask of all valid image flags for all formats. */
100#define VD_IMAGE_FLAGS_MASK (VD_VMDK_IMAGE_FLAGS_MASK | VD_VDI_IMAGE_FLAGS_MASK)
101
102/** Default image flags. */
103#define VD_IMAGE_FLAGS_DEFAULT (VD_IMAGE_FLAGS_NONE)
104/** @} */
105
106
107/**
108 * Auxiliary type for describing partitions on raw disks. The entries must be
109 * in ascending order (as far as uStart is concerned), and must not overlap.
110 * Note that this does not correspond 1:1 to partitions, it is describing the
111 * general meaning of contiguous areas on the disk.
112 */
113typedef struct VBOXHDDRAWPARTDESC
114{
115 /** Device to use for this partition/data area. Can be the disk device if
116 * the offset field is set appropriately. If this is NULL, then this
117 * partition will not be accessible to the guest. The size of the data area
118 * must still be set correctly. */
119 const char *pszRawDevice;
120 /** Pointer to the partitioning info. NULL means this is a regular data
121 * area on disk, non-NULL denotes data which should be copied to the
122 * partition data overlay. */
123 const void *pvPartitionData;
124 /** Offset where the data starts in this device. */
125 uint64_t uStartOffset;
126 /** Offset where the data starts in the disk. */
127 uint64_t uStart;
128 /** Size of the data area. */
129 uint64_t cbData;
130} VBOXHDDRAWPARTDESC, *PVBOXHDDRAWPARTDESC;
131
132/**
133 * Auxiliary data structure for creating raw disks.
134 */
135typedef struct VBOXHDDRAW
136{
137 /** Signature for structure. Must be 'R', 'A', 'W', '\\0'. Actually a trick
138 * to make logging of the comment string produce sensible results. */
139 char szSignature[4];
140 /** Flag whether access to full disk should be given (ignoring the
141 * partition information below). */
142 bool fRawDisk;
143 /** Filename for the raw disk. Ignored for partitioned raw disks.
144 * For Linux e.g. /dev/sda, and for Windows e.g. \\\\.\\PhysicalDisk0. */
145 const char *pszRawDisk;
146 /** Number of entries in the partition descriptor array. */
147 unsigned cPartDescs;
148 /** Pointer to the partition descriptor array. */
149 PVBOXHDDRAWPARTDESC pPartDescs;
150} VBOXHDDRAW, *PVBOXHDDRAW;
151
152/** @name VBox HDD container image open mode flags
153 * @{
154 */
155/** Try to open image in read/write exclusive access mode if possible, or in read-only elsewhere. */
156#define VD_OPEN_FLAGS_NORMAL 0
157/** Open image in read-only mode with sharing access with others. */
158#define VD_OPEN_FLAGS_READONLY RT_BIT(0)
159/** Honor zero block writes instead of ignoring them whenever possible.
160 * This is not supported by all formats. It is silently ignored in this case. */
161#define VD_OPEN_FLAGS_HONOR_ZEROES RT_BIT(1)
162/** Honor writes of the same data instead of ignoring whenever possible.
163 * This is handled generically, and is only meaningful for differential image
164 * formats. It is silently ignored otherwise. */
165#define VD_OPEN_FLAGS_HONOR_SAME RT_BIT(2)
166/** Do not perform the base/diff image check on open. This does NOT imply
167 * opening the image as readonly (would break e.g. adding UUIDs to VMDK files
168 * created by other products). Images opened with this flag should only be
169 * used for querying information, and nothing else. */
170#define VD_OPEN_FLAGS_INFO RT_BIT(3)
171/** Open image for asynchronous access. Only available if VD_CAP_ASYNC_IO is
172 * set. VDOpen fails with VERR_NOT_SUPPORTED if this operation is not supported for
173 * this kind of image. */
174#define VD_OPEN_FLAGS_ASYNC_IO RT_BIT(4)
175/** Allow sharing of the image for writable images. May be ignored if the
176 * format backend doesn't support this type of concurrent access. */
177#define VD_OPEN_FLAGS_SHAREABLE RT_BIT(5)
178/** Ask the backend to switch to sequential accesses if possible. Opening
179 * will not fail if it cannot do this, the flag will be simply ignored. */
180#define VD_OPEN_FLAGS_SEQUENTIAL RT_BIT(6)
181/** Mask of valid flags. */
182#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL)
183/** @}*/
184
185/**
186 * Helper functions to handle open flags.
187 */
188
189/**
190 * Translate VD_OPEN_FLAGS_* to RTFile open flags.
191 *
192 * @return RTFile open flags.
193 * @param uOpenFlags VD_OPEN_FLAGS_* open flags.
194 * @param fCreate Flag that the file should be created.
195 */
196DECLINLINE(uint32_t) VDOpenFlagsToFileOpenFlags(unsigned uOpenFlags, bool fCreate)
197{
198 AssertMsg(!((uOpenFlags & VD_OPEN_FLAGS_READONLY) && fCreate), ("Image can't be opened readonly while being created\n"));
199
200 uint32_t fOpen = 0;
201
202 if (RT_UNLIKELY(uOpenFlags & VD_OPEN_FLAGS_READONLY))
203 fOpen |= RTFILE_O_READ | RTFILE_O_DENY_NONE;
204 else
205 {
206 fOpen |= RTFILE_O_READWRITE;
207
208 if (RT_UNLIKELY(uOpenFlags & VD_OPEN_FLAGS_SHAREABLE))
209 fOpen |= RTFILE_O_DENY_NONE;
210 else
211 fOpen |= RTFILE_O_DENY_WRITE;
212 }
213
214 if (RT_UNLIKELY(fCreate))
215 fOpen |= RTFILE_O_CREATE | RTFILE_O_NOT_CONTENT_INDEXED;
216 else
217 fOpen |= RTFILE_O_OPEN;
218
219 return fOpen;
220}
221
222
223/** @name VBox HDD container backend capability flags
224 * @{
225 */
226/** Supports UUIDs as expected by VirtualBox code. */
227#define VD_CAP_UUID RT_BIT(0)
228/** Supports creating fixed size images, allocating all space instantly. */
229#define VD_CAP_CREATE_FIXED RT_BIT(1)
230/** Supports creating dynamically growing images, allocating space on demand. */
231#define VD_CAP_CREATE_DYNAMIC RT_BIT(2)
232/** Supports creating images split in chunks of a bit less than 2GBytes. */
233#define VD_CAP_CREATE_SPLIT_2G RT_BIT(3)
234/** Supports being used as differencing image format backend. */
235#define VD_CAP_DIFF RT_BIT(4)
236/** Supports asynchronous I/O operations for at least some configurations. */
237#define VD_CAP_ASYNC RT_BIT(5)
238/** The backend operates on files. The caller needs to know to handle the
239 * location appropriately. */
240#define VD_CAP_FILE RT_BIT(6)
241/** The backend uses the config interface. The caller needs to know how to
242 * provide the mandatory configuration parts this way. */
243#define VD_CAP_CONFIG RT_BIT(7)
244/** The backend uses the network stack interface. The caller has to provide
245 * the appropriate interface. */
246#define VD_CAP_TCPNET RT_BIT(8)
247/** The backend supports VFS (virtual filesystem) functionality since it uses
248 * VDINTERFACEIO exclusively for all file operations. */
249#define VD_CAP_VFS RT_BIT(9)
250/** @}*/
251
252/** @name VBox HDD container type.
253 * @{
254 */
255typedef enum VDTYPE
256{
257 /** Invalid. */
258 VDTYPE_INVALID = 0,
259 /** HardDisk */
260 VDTYPE_HDD,
261 /** CD/DVD */
262 VDTYPE_DVD,
263 /** Floppy. */
264 VDTYPE_FLOPPY
265} VDTYPE;
266/** @}*/
267
268/**
269 * Supported interface types.
270 */
271typedef enum VDINTERFACETYPE
272{
273 /** First valid interface. */
274 VDINTERFACETYPE_FIRST = 0,
275 /** Interface to pass error message to upper layers. Per-disk. */
276 VDINTERFACETYPE_ERROR = VDINTERFACETYPE_FIRST,
277 /** Interface for I/O operations. Per-image. */
278 VDINTERFACETYPE_IO,
279 /** Interface for progress notification. Per-operation. */
280 VDINTERFACETYPE_PROGRESS,
281 /** Interface for configuration information. Per-image. */
282 VDINTERFACETYPE_CONFIG,
283 /** Interface for TCP network stack. Per-image. */
284 VDINTERFACETYPE_TCPNET,
285 /** Interface for getting parent image state. Per-operation. */
286 VDINTERFACETYPE_PARENTSTATE,
287 /** Interface for synchronizing accesses from several threads. Per-disk. */
288 VDINTERFACETYPE_THREADSYNC,
289 /** Interface for I/O between the generic VBoxHDD code and the backend. Per-image (internal).
290 * This interface is completely internal and must not be used elsewhere. */
291 VDINTERFACETYPE_IOINT,
292 /** invalid interface. */
293 VDINTERFACETYPE_INVALID
294} VDINTERFACETYPE;
295
296/**
297 * Common structure for all interfaces.
298 */
299typedef struct VDINTERFACE
300{
301 /** Human readable interface name. */
302 const char *pszInterfaceName;
303 /** The size of the struct. */
304 uint32_t cbSize;
305 /** Pointer to the next common interface structure. */
306 struct VDINTERFACE *pNext;
307 /** Interface type. */
308 VDINTERFACETYPE enmInterface;
309 /** Opaque user data which is passed on every call. */
310 void *pvUser;
311 /** Pointer to the function call table of the interface.
312 * As this is opaque this must be casted to the right interface
313 * struct defined below based on the interface type in enmInterface. */
314 void *pCallbacks;
315} VDINTERFACE;
316/** Pointer to a VDINTERFACE. */
317typedef VDINTERFACE *PVDINTERFACE;
318/** Pointer to a const VDINTERFACE. */
319typedef const VDINTERFACE *PCVDINTERFACE;
320
321/**
322 * Helper functions to handle interface lists.
323 *
324 * @note These interface lists are used consistently to pass per-disk,
325 * per-image and/or per-operation callbacks. Those three purposes are strictly
326 * separate. See the individual interface declarations for what context they
327 * apply to. The caller is responsible for ensuring that the lifetime of the
328 * interface descriptors is appropriate for the category of interface.
329 */
330
331/**
332 * Get a specific interface from a list of interfaces specified by the type.
333 *
334 * @return Pointer to the matching interface or NULL if none was found.
335 * @param pVDIfs Pointer to the VD interface list.
336 * @param enmInterface Interface to search for.
337 */
338DECLINLINE(PVDINTERFACE) VDInterfaceGet(PVDINTERFACE pVDIfs, VDINTERFACETYPE enmInterface)
339{
340 AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST
341 && enmInterface < VDINTERFACETYPE_INVALID,
342 ("enmInterface=%u", enmInterface), NULL);
343
344 while (pVDIfs)
345 {
346 /* Sanity checks. */
347 AssertMsgBreak(pVDIfs->cbSize == sizeof(VDINTERFACE),
348 ("cbSize=%u\n", pVDIfs->cbSize));
349
350 if (pVDIfs->enmInterface == enmInterface)
351 return pVDIfs;
352 pVDIfs = pVDIfs->pNext;
353 }
354
355 /* No matching interface was found. */
356 return NULL;
357}
358
359/**
360 * Add an interface to a list of interfaces.
361 *
362 * @return VBox status code.
363 * @param pInterface Pointer to an unitialized common interface structure.
364 * @param pszName Name of the interface.
365 * @param enmInterface Type of the interface.
366 * @param pCallbacks The callback table of the interface.
367 * @param pvUser Opaque user data passed on every function call.
368 * @param ppVDIfs Pointer to the VD interface list.
369 */
370DECLINLINE(int) VDInterfaceAdd(PVDINTERFACE pInterface, const char *pszName,
371 VDINTERFACETYPE enmInterface, void *pCallbacks,
372 void *pvUser, PVDINTERFACE *ppVDIfs)
373{
374 /* Argument checks. */
375 AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST
376 && enmInterface < VDINTERFACETYPE_INVALID,
377 ("enmInterface=%u", enmInterface), VERR_INVALID_PARAMETER);
378
379 AssertMsgReturn(VALID_PTR(pCallbacks),
380 ("pCallbacks=%#p", pCallbacks),
381 VERR_INVALID_PARAMETER);
382
383 AssertMsgReturn(VALID_PTR(ppVDIfs),
384 ("pInterfaceList=%#p", ppVDIfs),
385 VERR_INVALID_PARAMETER);
386
387 /* Fill out interface descriptor. */
388 pInterface->cbSize = sizeof(VDINTERFACE);
389 pInterface->pszInterfaceName = pszName;
390 pInterface->enmInterface = enmInterface;
391 pInterface->pCallbacks = pCallbacks;
392 pInterface->pvUser = pvUser;
393 pInterface->pNext = *ppVDIfs;
394
395 /* Remember the new start of the list. */
396 *ppVDIfs = pInterface;
397
398 return VINF_SUCCESS;
399}
400
401/**
402 * Removes an interface from a list of interfaces.
403 *
404 * @return VBox status code
405 * @param pInterface Pointer to an initialized common interface structure to remove.
406 * @param ppVDIfs Pointer to the VD interface list to remove from.
407 */
408DECLINLINE(int) VDInterfaceRemove(PVDINTERFACE pInterface, PVDINTERFACE *ppVDIfs)
409{
410 int rc = VERR_NOT_FOUND;
411
412 /* Argument checks. */
413 AssertMsgReturn(VALID_PTR(pInterface),
414 ("pInterface=%#p", pInterface),
415 VERR_INVALID_PARAMETER);
416
417 AssertMsgReturn(VALID_PTR(ppVDIfs),
418 ("pInterfaceList=%#p", ppVDIfs),
419 VERR_INVALID_PARAMETER);
420
421 if (*ppVDIfs)
422 {
423 PVDINTERFACE pPrev = NULL;
424 PVDINTERFACE pCurr = *ppVDIfs;
425
426 while ( pCurr
427 && (pCurr != pInterface))
428 {
429 pPrev = pCurr;
430 pCurr = pCurr->pNext;
431 }
432
433 /* First interface */
434 if (!pPrev)
435 {
436 *ppVDIfs = pCurr->pNext;
437 rc = VINF_SUCCESS;
438 }
439 else if (pCurr)
440 {
441 pPrev = pCurr->pNext;
442 rc = VINF_SUCCESS;
443 }
444 }
445
446 return rc;
447}
448
449/**
450 * Interface to deliver error messages (and also informational messages)
451 * to upper layers.
452 *
453 * Per-disk interface. Optional, but think twice if you want to miss the
454 * opportunity of reporting better human-readable error messages.
455 */
456typedef struct VDINTERFACEERROR
457{
458 /**
459 * Size of the error interface.
460 */
461 uint32_t cbSize;
462
463 /**
464 * Interface type.
465 */
466 VDINTERFACETYPE enmInterface;
467
468 /**
469 * Error message callback. Must be able to accept special IPRT format
470 * strings.
471 *
472 * @param pvUser The opaque data passed on container creation.
473 * @param rc The VBox error code.
474 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
475 * @param pszFormat Error message format string.
476 * @param va Error message arguments.
477 */
478 DECLR3CALLBACKMEMBER(void, pfnError, (void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
479
480 /**
481 * Informational message callback. May be NULL. Used e.g. in
482 * VDDumpImages(). Must be able to accept special IPRT format strings.
483 *
484 * @return VBox status code.
485 * @param pvUser The opaque data passed on container creation.
486 * @param pszFormat Message format string.
487 * @param va Message arguments.
488 */
489 DECLR3CALLBACKMEMBER(int, pfnMessage, (void *pvUser, const char *pszFormat, va_list va));
490
491} VDINTERFACEERROR, *PVDINTERFACEERROR;
492
493/**
494 * Get error interface from opaque callback table.
495 *
496 * @return Pointer to the callback table.
497 * @param pInterface Pointer to the interface descriptor.
498 */
499DECLINLINE(PVDINTERFACEERROR) VDGetInterfaceError(PVDINTERFACE pInterface)
500{
501 PVDINTERFACEERROR pInterfaceError;
502
503 /* Check that the interface descriptor is a error interface. */
504 AssertMsgReturn( pInterface->enmInterface == VDINTERFACETYPE_ERROR
505 && pInterface->cbSize == sizeof(VDINTERFACE),
506 ("Not an error interface"), NULL);
507
508 pInterfaceError = (PVDINTERFACEERROR)pInterface->pCallbacks;
509
510 /* Do basic checks. */
511 AssertMsgReturn( pInterfaceError->cbSize == sizeof(VDINTERFACEERROR)
512 && pInterfaceError->enmInterface == VDINTERFACETYPE_ERROR,
513 ("A non error callback table attached to a error interface descriptor\n"), NULL);
514
515 return pInterfaceError;
516}
517
518/**
519 * Completion callback which is called by the interface owner
520 * to inform the backend that a task finished.
521 *
522 * @return VBox status code.
523 * @param pvUser Opaque user data which is passed on request submission.
524 * @param rcReq Status code of the completed request.
525 */
526typedef DECLCALLBACK(int) FNVDCOMPLETED(void *pvUser, int rcReq);
527/** Pointer to FNVDCOMPLETED() */
528typedef FNVDCOMPLETED *PFNVDCOMPLETED;
529
530/**
531 * Support interface for I/O
532 *
533 * Per-image. Optional as input.
534 */
535typedef struct VDINTERFACEIO
536{
537 /**
538 * Size of the I/O interface.
539 */
540 uint32_t cbSize;
541
542 /**
543 * Interface type.
544 */
545 VDINTERFACETYPE enmInterface;
546
547 /**
548 * Open callback
549 *
550 * @return VBox status code.
551 * @param pvUser The opaque data passed on container creation.
552 * @param pszLocation Name of the location to open.
553 * @param fOpen Flags for opening the backend.
554 * See RTFILE_O_* #defines, inventing another set
555 * of open flags is not worth the mapping effort.
556 * @param pfnCompleted The callback which is called whenever a task
557 * completed. The backend has to pass the user data
558 * of the request initiator (ie the one who calls
559 * VDAsyncRead or VDAsyncWrite) in pvCompletion
560 * if this is NULL.
561 * @param ppStorage Where to store the opaque storage handle.
562 */
563 DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,
564 uint32_t fOpen,
565 PFNVDCOMPLETED pfnCompleted,
566 void **ppStorage));
567
568 /**
569 * Close callback.
570 *
571 * @return VBox status code.
572 * @param pvUser The opaque data passed on container creation.
573 * @param pStorage The opaque storage handle to close.
574 */
575 DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, void *pStorage));
576
577 /**
578 * Delete callback.
579 *
580 * @return VBox status code.
581 * @param pvUser The opaque data passed on container creation.
582 * @param pcszFilename Name of the file to delete.
583 */
584 DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));
585
586 /**
587 * Move callback.
588 *
589 * @return VBox status code.
590 * @param pvUser The opaque data passed on container creation.
591 * @param pcszSrc The path to the source file.
592 * @param pcszDst The path to the destination file.
593 * This file will be created.
594 * @param fMove A combination of the RTFILEMOVE_* flags.
595 */
596 DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));
597
598 /**
599 * Returns the free space on a disk.
600 *
601 * @return VBox status code.
602 * @param pvUser The opaque data passed on container creation.
603 * @param pcszFilename Name of a file to identify the disk.
604 * @param pcbFreeSpace Where to store the free space of the disk.
605 */
606 DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));
607
608 /**
609 * Returns the last modification timestamp of a file.
610 *
611 * @return VBox status code.
612 * @param pvUser The opaque data passed on container creation.
613 * @param pcszFilename Name of a file to identify the disk.
614 * @param pModificationTime Where to store the timestamp of the file.
615 */
616 DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));
617
618 /**
619 * Returns the size of the opened storage backend.
620 *
621 * @return VBox status code.
622 * @param pvUser The opaque data passed on container creation.
623 * @param pStorage The opaque storage handle to close.
624 * @param pcbSize Where to store the size of the storage backend.
625 */
626 DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, void *pStorage, uint64_t *pcbSize));
627
628 /**
629 * Sets the size of the opened storage backend if possible.
630 *
631 * @return VBox status code.
632 * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
633 * @param pvUser The opaque data passed on container creation.
634 * @param pStorage The opaque storage handle to close.
635 * @param cbSize The new size of the image.
636 */
637 DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, void *pStorage, uint64_t cbSize));
638
639 /**
640 * Synchronous write callback.
641 *
642 * @return VBox status code.
643 * @param pvUser The opaque data passed on container creation.
644 * @param pStorage The storage handle to use.
645 * @param uOffset The offset to start from.
646 * @param pvBuffer Pointer to the bits need to be written.
647 * @param cbBuffer How many bytes to write.
648 * @param pcbWritten Where to store how many bytes were actually written.
649 */
650 DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, void *pStorage, uint64_t uOffset,
651 const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
652
653 /**
654 * Synchronous read callback.
655 *
656 * @return VBox status code.
657 * @param pvUser The opaque data passed on container creation.
658 * @param pStorage The storage handle to use.
659 * @param uOffset The offset to start from.
660 * @param pvBuffer Where to store the read bits.
661 * @param cbBuffer How many bytes to read.
662 * @param pcbRead Where to store how many bytes were actually read.
663 */
664 DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, void *pStorage, uint64_t uOffset,
665 void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
666
667 /**
668 * Flush data to the storage backend.
669 *
670 * @return VBox status code.
671 * @param pvUser The opaque data passed on container creation.
672 * @param pStorage The storage handle to flush.
673 */
674 DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, void *pStorage));
675
676 /**
677 * Initiate an asynchronous read request.
678 *
679 * @return VBox status code.
680 * @param pvUser The opaque user data passed on container creation.
681 * @param pStorage The storage handle.
682 * @param uOffset The offset to start reading from.
683 * @param paSegments Scatter gather list to store the data in.
684 * @param cSegments Number of segments in the list.
685 * @param cbRead How many bytes to read.
686 * @param pvCompletion The opaque user data which is returned upon completion.
687 * @param ppTask Where to store the opaque task handle.
688 */
689 DECLR3CALLBACKMEMBER(int, pfnReadAsync, (void *pvUser, void *pStorage, uint64_t uOffset,
690 PCRTSGSEG paSegments, size_t cSegments,
691 size_t cbRead, void *pvCompletion,
692 void **ppTask));
693
694 /**
695 * Initiate an asynchronous write request.
696 *
697 * @return VBox status code.
698 * @param pvUser The opaque user data passed on conatiner creation.
699 * @param pStorage The storage handle.
700 * @param uOffset The offset to start writing to.
701 * @param paSegments Scatter gather list of the data to write
702 * @param cSegments Number of segments in the list.
703 * @param cbWrite How many bytes to write.
704 * @param pvCompletion The opaque user data which is returned upon completion.
705 * @param ppTask Where to store the opaque task handle.
706 */
707 DECLR3CALLBACKMEMBER(int, pfnWriteAsync, (void *pvUser, void *pStorage, uint64_t uOffset,
708 PCRTSGSEG paSegments, size_t cSegments,
709 size_t cbWrite, void *pvCompletion,
710 void **ppTask));
711
712 /**
713 * Initiates an async flush request.
714 *
715 * @return VBox status code.
716 * @param pvUser The opaque data passed on container creation.
717 * @param pStorage The storage handle to flush.
718 * @param pvCompletion The opaque user data which is returned upon completion.
719 * @param ppTask Where to store the opaque task handle.
720 */
721 DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, void *pStorage,
722 void *pvCompletion, void **ppTask));
723
724} VDINTERFACEIO, *PVDINTERFACEIO;
725
726/**
727 * Get I/O interface from opaque callback table.
728 *
729 * @return Pointer to the callback table.
730 * @param pInterface Pointer to the interface descriptor.
731 */
732DECLINLINE(PVDINTERFACEIO) VDGetInterfaceIO(PVDINTERFACE pInterface)
733{
734 PVDINTERFACEIO pInterfaceIO;
735
736 /* Check that the interface descriptor is an I/O interface. */
737 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_IO)
738 && (pInterface->cbSize == sizeof(VDINTERFACE)),
739 ("Not an I/O interface"), NULL);
740
741 pInterfaceIO = (PVDINTERFACEIO)pInterface->pCallbacks;
742
743 /* Do basic checks. */
744 AssertMsgReturn( (pInterfaceIO->cbSize == sizeof(VDINTERFACEIO))
745 && (pInterfaceIO->enmInterface == VDINTERFACETYPE_IO),
746 ("A non I/O callback table attached to an I/O interface descriptor\n"), NULL);
747
748 return pInterfaceIO;
749}
750
751/**
752 * Callback which provides progress information about a currently running
753 * lengthy operation.
754 *
755 * @return VBox status code.
756 * @param pvUser The opaque user data associated with this interface.
757 * @param uPercent Completion percentage.
758 */
759typedef DECLCALLBACK(int) FNVDPROGRESS(void *pvUser, unsigned uPercentage);
760/** Pointer to FNVDPROGRESS() */
761typedef FNVDPROGRESS *PFNVDPROGRESS;
762
763/**
764 * Progress notification interface
765 *
766 * Per-operation. Optional.
767 */
768typedef struct VDINTERFACEPROGRESS
769{
770 /**
771 * Size of the progress interface.
772 */
773 uint32_t cbSize;
774
775 /**
776 * Interface type.
777 */
778 VDINTERFACETYPE enmInterface;
779
780 /**
781 * Progress notification callbacks.
782 */
783 PFNVDPROGRESS pfnProgress;
784
785} VDINTERFACEPROGRESS, *PVDINTERFACEPROGRESS;
786
787/**
788 * Get progress interface from opaque callback table.
789 *
790 * @return Pointer to the callback table.
791 * @param pInterface Pointer to the interface descriptor.
792 */
793DECLINLINE(PVDINTERFACEPROGRESS) VDGetInterfaceProgress(PVDINTERFACE pInterface)
794{
795 PVDINTERFACEPROGRESS pInterfaceProgress;
796
797 /* Check that the interface descriptor is a progress interface. */
798 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_PROGRESS)
799 && (pInterface->cbSize == sizeof(VDINTERFACE)),
800 ("Not a progress interface"), NULL);
801
802
803 pInterfaceProgress = (PVDINTERFACEPROGRESS)pInterface->pCallbacks;
804
805 /* Do basic checks. */
806 AssertMsgReturn( (pInterfaceProgress->cbSize == sizeof(VDINTERFACEPROGRESS))
807 && (pInterfaceProgress->enmInterface == VDINTERFACETYPE_PROGRESS),
808 ("A non progress callback table attached to a progress interface descriptor\n"), NULL);
809
810 return pInterfaceProgress;
811}
812
813
814/**
815 * Configuration information interface
816 *
817 * Per-image. Optional for most backends, but mandatory for images which do
818 * not operate on files (including standard block or character devices).
819 */
820typedef struct VDINTERFACECONFIG
821{
822 /**
823 * Size of the configuration interface.
824 */
825 uint32_t cbSize;
826
827 /**
828 * Interface type.
829 */
830 VDINTERFACETYPE enmInterface;
831
832 /**
833 * Validates that the keys are within a set of valid names.
834 *
835 * @return true if all key names are found in pszzAllowed.
836 * @return false if not.
837 * @param pvUser The opaque user data associated with this interface.
838 * @param pszzValid List of valid key names separated by '\\0' and ending with
839 * a double '\\0'.
840 */
841 DECLR3CALLBACKMEMBER(bool, pfnAreKeysValid, (void *pvUser, const char *pszzValid));
842
843 /**
844 * Retrieves the length of the string value associated with a key (including
845 * the terminator, for compatibility with CFGMR3QuerySize).
846 *
847 * @return VBox status code.
848 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
849 * @param pvUser The opaque user data associated with this interface.
850 * @param pszName Name of the key to query.
851 * @param pcbValue Where to store the value length. Non-NULL.
852 */
853 DECLR3CALLBACKMEMBER(int, pfnQuerySize, (void *pvUser, const char *pszName, size_t *pcbValue));
854
855 /**
856 * Query the string value associated with a key.
857 *
858 * @return VBox status code.
859 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
860 * VERR_CFGM_NOT_ENOUGH_SPACE means that the buffer is not big enough.
861 * @param pvUser The opaque user data associated with this interface.
862 * @param pszName Name of the key to query.
863 * @param pszValue Pointer to buffer where to store value.
864 * @param cchValue Length of value buffer.
865 */
866 DECLR3CALLBACKMEMBER(int, pfnQuery, (void *pvUser, const char *pszName, char *pszValue, size_t cchValue));
867
868} VDINTERFACECONFIG, *PVDINTERFACECONFIG;
869
870/**
871 * Get configuration information interface from opaque callback table.
872 *
873 * @return Pointer to the callback table.
874 * @param pInterface Pointer to the interface descriptor.
875 */
876DECLINLINE(PVDINTERFACECONFIG) VDGetInterfaceConfig(PVDINTERFACE pInterface)
877{
878 PVDINTERFACECONFIG pInterfaceConfig;
879
880 /* Check that the interface descriptor is a config interface. */
881 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_CONFIG)
882 && (pInterface->cbSize == sizeof(VDINTERFACE)),
883 ("Not a config interface"), NULL);
884
885 pInterfaceConfig = (PVDINTERFACECONFIG)pInterface->pCallbacks;
886
887 /* Do basic checks. */
888 AssertMsgReturn( (pInterfaceConfig->cbSize == sizeof(VDINTERFACECONFIG))
889 && (pInterfaceConfig->enmInterface == VDINTERFACETYPE_CONFIG),
890 ("A non config callback table attached to a config interface descriptor\n"), NULL);
891
892 return pInterfaceConfig;
893}
894
895/**
896 * Query configuration, validates that the keys are within a set of valid names.
897 *
898 * @return true if all key names are found in pszzAllowed.
899 * @return false if not.
900 * @param pCfgIf Pointer to configuration callback table.
901 * @param pvUser The opaque user data associated with this interface.
902 * @param pszzValid List of valid names separated by '\\0' and ending with
903 * a double '\\0'.
904 */
905DECLINLINE(bool) VDCFGAreKeysValid(PVDINTERFACECONFIG pCfgIf, void *pvUser,
906 const char *pszzValid)
907{
908 return pCfgIf->pfnAreKeysValid(pvUser, pszzValid);
909}
910
911/**
912 * Query configuration, unsigned 64-bit integer value with default.
913 *
914 * @return VBox status code.
915 * @param pCfgIf Pointer to configuration callback table.
916 * @param pvUser The opaque user data associated with this interface.
917 * @param pszName Name of an integer value
918 * @param pu64 Where to store the value. Set to default on failure.
919 * @param u64Def The default value.
920 */
921DECLINLINE(int) VDCFGQueryU64Def(PVDINTERFACECONFIG pCfgIf, void *pvUser,
922 const char *pszName, uint64_t *pu64,
923 uint64_t u64Def)
924{
925 char aszBuf[32];
926 int rc = pCfgIf->pfnQuery(pvUser, pszName, aszBuf, sizeof(aszBuf));
927 if (RT_SUCCESS(rc))
928 {
929 rc = RTStrToUInt64Full(aszBuf, 0, pu64);
930 }
931 else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
932 {
933 rc = VINF_SUCCESS;
934 *pu64 = u64Def;
935 }
936 return rc;
937}
938
939/**
940 * Query configuration, unsigned 32-bit integer value with default.
941 *
942 * @return VBox status code.
943 * @param pCfgIf Pointer to configuration callback table.
944 * @param pvUser The opaque user data associated with this interface.
945 * @param pszName Name of an integer value
946 * @param pu32 Where to store the value. Set to default on failure.
947 * @param u32Def The default value.
948 */
949DECLINLINE(int) VDCFGQueryU32Def(PVDINTERFACECONFIG pCfgIf, void *pvUser,
950 const char *pszName, uint32_t *pu32,
951 uint32_t u32Def)
952{
953 uint64_t u64;
954 int rc = VDCFGQueryU64Def(pCfgIf, pvUser, pszName, &u64, u32Def);
955 if (RT_SUCCESS(rc))
956 {
957 if (!(u64 & UINT64_C(0xffffffff00000000)))
958 *pu32 = (uint32_t)u64;
959 else
960 rc = VERR_CFGM_INTEGER_TOO_BIG;
961 }
962 return rc;
963}
964
965/**
966 * Query configuration, bool value with default.
967 *
968 * @return VBox status code.
969 * @param pCfgIf Pointer to configuration callback table.
970 * @param pvUser The opaque user data associated with this interface.
971 * @param pszName Name of an integer value
972 * @param pf Where to store the value. Set to default on failure.
973 * @param fDef The default value.
974 */
975DECLINLINE(int) VDCFGQueryBoolDef(PVDINTERFACECONFIG pCfgIf, void *pvUser,
976 const char *pszName, bool *pf,
977 bool fDef)
978{
979 uint64_t u64;
980 int rc = VDCFGQueryU64Def(pCfgIf, pvUser, pszName, &u64, fDef);
981 if (RT_SUCCESS(rc))
982 *pf = u64 ? true : false;
983 return rc;
984}
985
986/**
987 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
988 * character value.
989 *
990 * @return VBox status code.
991 * @param pCfgIf Pointer to configuration callback table.
992 * @param pvUser The opaque user data associated with this interface.
993 * @param pszName Name of an zero terminated character value
994 * @param ppszString Where to store the string pointer. Not set on failure.
995 * Free this using RTMemFree().
996 */
997DECLINLINE(int) VDCFGQueryStringAlloc(PVDINTERFACECONFIG pCfgIf,
998 void *pvUser, const char *pszName,
999 char **ppszString)
1000{
1001 size_t cb;
1002 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);
1003 if (RT_SUCCESS(rc))
1004 {
1005 char *pszString = (char *)RTMemAlloc(cb);
1006 if (pszString)
1007 {
1008 rc = pCfgIf->pfnQuery(pvUser, pszName, pszString, cb);
1009 if (RT_SUCCESS(rc))
1010 *ppszString = pszString;
1011 else
1012 RTMemFree(pszString);
1013 }
1014 else
1015 rc = VERR_NO_MEMORY;
1016 }
1017 return rc;
1018}
1019
1020/**
1021 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
1022 * character value with default.
1023 *
1024 * @return VBox status code.
1025 * @param pCfgIf Pointer to configuration callback table.
1026 * @param pvUser The opaque user data associated with this interface.
1027 * @param pszName Name of an zero terminated character value
1028 * @param ppszString Where to store the string pointer. Not set on failure.
1029 * Free this using RTMemFree().
1030 * @param pszDef The default value.
1031 */
1032DECLINLINE(int) VDCFGQueryStringAllocDef(PVDINTERFACECONFIG pCfgIf,
1033 void *pvUser, const char *pszName,
1034 char **ppszString,
1035 const char *pszDef)
1036{
1037 size_t cb;
1038 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);
1039 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
1040 {
1041 cb = strlen(pszDef) + 1;
1042 rc = VINF_SUCCESS;
1043 }
1044 if (RT_SUCCESS(rc))
1045 {
1046 char *pszString = (char *)RTMemAlloc(cb);
1047 if (pszString)
1048 {
1049 rc = pCfgIf->pfnQuery(pvUser, pszName, pszString, cb);
1050 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
1051 {
1052 memcpy(pszString, pszDef, cb);
1053 rc = VINF_SUCCESS;
1054 }
1055 if (RT_SUCCESS(rc))
1056 *ppszString = pszString;
1057 else
1058 RTMemFree(pszString);
1059 }
1060 else
1061 rc = VERR_NO_MEMORY;
1062 }
1063 return rc;
1064}
1065
1066/**
1067 * Query configuration, dynamically allocated (RTMemAlloc) byte string value.
1068 *
1069 * @return VBox status code.
1070 * @param pCfgIf Pointer to configuration callback table.
1071 * @param pvUser The opaque user data associated with this interface.
1072 * @param pszName Name of an zero terminated character value
1073 * @param ppvData Where to store the byte string pointer. Not set on failure.
1074 * Free this using RTMemFree().
1075 * @param pcbData Where to store the byte string length.
1076 */
1077DECLINLINE(int) VDCFGQueryBytesAlloc(PVDINTERFACECONFIG pCfgIf,
1078 void *pvUser, const char *pszName,
1079 void **ppvData, size_t *pcbData)
1080{
1081 size_t cb;
1082 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);
1083 if (RT_SUCCESS(rc))
1084 {
1085 char *pbData;
1086 Assert(cb);
1087
1088 pbData = (char *)RTMemAlloc(cb);
1089 if (pbData)
1090 {
1091 rc = pCfgIf->pfnQuery(pvUser, pszName, pbData, cb);
1092 if (RT_SUCCESS(rc))
1093 {
1094 *ppvData = pbData;
1095 *pcbData = cb - 1; /* Exclude terminator of the queried string. */
1096 }
1097 else
1098 RTMemFree(pbData);
1099 }
1100 else
1101 rc = VERR_NO_MEMORY;
1102 }
1103 return rc;
1104}
1105
1106/** Forward declaration of a VD socket. */
1107typedef struct VDSOCKETINT *VDSOCKET;
1108/** Pointer to a VD socket. */
1109typedef VDSOCKET *PVDSOCKET;
1110/** Nil socket handle. */
1111#define NIL_VDSOCKET ((VDSOCKET)0)
1112
1113/** Connect flag to indicate that the backend wants to use the extended
1114 * socket I/O multiplexing call. This might not be supported on all configurations
1115 * (internal networking and iSCSI)
1116 * and the backend needs to take appropriate action.
1117 */
1118#define VD_INTERFACETCPNET_CONNECT_EXTENDED_SELECT RT_BIT_32(0)
1119
1120/** @name Select events
1121 * @{ */
1122/** Readable without blocking. */
1123#define VD_INTERFACETCPNET_EVT_READ RT_BIT_32(0)
1124/** Writable without blocking. */
1125#define VD_INTERFACETCPNET_EVT_WRITE RT_BIT_32(1)
1126/** Error condition, hangup, exception or similar. */
1127#define VD_INTERFACETCPNET_EVT_ERROR RT_BIT_32(2)
1128/** Hint for the select that getting interrupted while waiting is more likely.
1129 * The interface implementation can optimize the waiting strategy based on this.
1130 * It is assumed that it is more likely to get one of the above socket events
1131 * instead of being interrupted if the flag is not set. */
1132#define VD_INTERFACETCPNET_HINT_INTERRUPT RT_BIT_32(3)
1133/** Mask of the valid bits. */
1134#define VD_INTERFACETCPNET_EVT_VALID_MASK UINT32_C(0x0000000f)
1135/** @} */
1136
1137/**
1138 * TCP network stack interface
1139 *
1140 * Per-image. Mandatory for backends which have the VD_CAP_TCPNET bit set.
1141 */
1142typedef struct VDINTERFACETCPNET
1143{
1144 /**
1145 * Size of the configuration interface.
1146 */
1147 uint32_t cbSize;
1148
1149 /**
1150 * Interface type.
1151 */
1152 VDINTERFACETYPE enmInterface;
1153
1154 /**
1155 * Creates a socket. The socket is not connected if this succeeds.
1156 *
1157 * @return iprt status code.
1158 * @retval VERR_NOT_SUPPORTED if the combination of flags is not supported.
1159 * @param fFlags Combination of the VD_INTERFACETCPNET_CONNECT_* #defines.
1160 * @param pSock Where to store the handle.
1161 */
1162 DECLR3CALLBACKMEMBER(int, pfnSocketCreate, (uint32_t fFlags, PVDSOCKET pSock));
1163
1164 /**
1165 * Destroys the socket.
1166 *
1167 * @return iprt status code.
1168 * @param Sock Socket descriptor.
1169 */
1170 DECLR3CALLBACKMEMBER(int, pfnSocketDestroy, (VDSOCKET Sock));
1171
1172 /**
1173 * Connect as a client to a TCP port.
1174 *
1175 * @return iprt status code.
1176 * @param Sock Socket descriptor.
1177 * @param pszAddress The address to connect to.
1178 * @param uPort The port to connect to.
1179 */
1180 DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET Sock, const char *pszAddress, uint32_t uPort));
1181
1182 /**
1183 * Close a TCP connection.
1184 *
1185 * @return iprt status code.
1186 * @param Sock Socket descriptor.
1187 */
1188 DECLR3CALLBACKMEMBER(int, pfnClientClose, (VDSOCKET Sock));
1189
1190 /**
1191 * Returns whether the socket is currently connected to the client.
1192 *
1193 * @returns true if the socket is connected.
1194 * false otherwise.
1195 * @param Sock Socket descriptor.
1196 */
1197 DECLR3CALLBACKMEMBER(bool, pfnIsClientConnected, (VDSOCKET Sock));
1198
1199 /**
1200 * Socket I/O multiplexing.
1201 * Checks if the socket is ready for reading.
1202 *
1203 * @return iprt status code.
1204 * @param Sock Socket descriptor.
1205 * @param cMillies Number of milliseconds to wait for the socket.
1206 * Use RT_INDEFINITE_WAIT to wait for ever.
1207 */
1208 DECLR3CALLBACKMEMBER(int, pfnSelectOne, (VDSOCKET Sock, RTMSINTERVAL cMillies));
1209
1210 /**
1211 * Receive data from a socket.
1212 *
1213 * @return iprt status code.
1214 * @param Sock Socket descriptor.
1215 * @param pvBuffer Where to put the data we read.
1216 * @param cbBuffer Read buffer size.
1217 * @param pcbRead Number of bytes read.
1218 * If NULL the entire buffer will be filled upon successful return.
1219 * If not NULL a partial read can be done successfully.
1220 */
1221 DECLR3CALLBACKMEMBER(int, pfnRead, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1222
1223 /**
1224 * Send data to a socket.
1225 *
1226 * @return iprt status code.
1227 * @param Sock Socket descriptor.
1228 * @param pvBuffer Buffer to write data to socket.
1229 * @param cbBuffer How much to write.
1230 */
1231 DECLR3CALLBACKMEMBER(int, pfnWrite, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer));
1232
1233 /**
1234 * Send data from scatter/gather buffer to a socket.
1235 *
1236 * @return iprt status code.
1237 * @param Sock Socket descriptor.
1238 * @param pSgBuffer Scatter/gather buffer to write data to socket.
1239 */
1240 DECLR3CALLBACKMEMBER(int, pfnSgWrite, (VDSOCKET Sock, PCRTSGBUF pSgBuffer));
1241
1242 /**
1243 * Receive data from a socket - not blocking.
1244 *
1245 * @return iprt status code.
1246 * @param Sock Socket descriptor.
1247 * @param pvBuffer Where to put the data we read.
1248 * @param cbBuffer Read buffer size.
1249 * @param pcbRead Number of bytes read.
1250 */
1251 DECLR3CALLBACKMEMBER(int, pfnReadNB, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1252
1253 /**
1254 * Send data to a socket - not blocking.
1255 *
1256 * @return iprt status code.
1257 * @param Sock Socket descriptor.
1258 * @param pvBuffer Buffer to write data to socket.
1259 * @param cbBuffer How much to write.
1260 * @param pcbWritten Number of bytes written.
1261 */
1262 DECLR3CALLBACKMEMBER(int, pfnWriteNB, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
1263
1264 /**
1265 * Send data from scatter/gather buffer to a socket - not blocking.
1266 *
1267 * @return iprt status code.
1268 * @param Sock Socket descriptor.
1269 * @param pSgBuffer Scatter/gather buffer to write data to socket.
1270 * @param pcbWritten Number of bytes written.
1271 */
1272 DECLR3CALLBACKMEMBER(int, pfnSgWriteNB, (VDSOCKET Sock, PRTSGBUF pSgBuffer, size_t *pcbWritten));
1273
1274 /**
1275 * Flush socket write buffers.
1276 *
1277 * @return iprt status code.
1278 * @param Sock Socket descriptor.
1279 */
1280 DECLR3CALLBACKMEMBER(int, pfnFlush, (VDSOCKET Sock));
1281
1282 /**
1283 * Enables or disables delaying sends to coalesce packets.
1284 *
1285 * @return iprt status code.
1286 * @param Sock Socket descriptor.
1287 * @param fEnable When set to true enables coalescing.
1288 */
1289 DECLR3CALLBACKMEMBER(int, pfnSetSendCoalescing, (VDSOCKET Sock, bool fEnable));
1290
1291 /**
1292 * Gets the address of the local side.
1293 *
1294 * @return iprt status code.
1295 * @param Sock Socket descriptor.
1296 * @param pAddr Where to store the local address on success.
1297 */
1298 DECLR3CALLBACKMEMBER(int, pfnGetLocalAddress, (VDSOCKET Sock, PRTNETADDR pAddr));
1299
1300 /**
1301 * Gets the address of the other party.
1302 *
1303 * @return iprt status code.
1304 * @param Sock Socket descriptor.
1305 * @param pAddr Where to store the peer address on success.
1306 */
1307 DECLR3CALLBACKMEMBER(int, pfnGetPeerAddress, (VDSOCKET Sock, PRTNETADDR pAddr));
1308
1309 /**
1310 * Socket I/O multiplexing - extended version which can be woken up.
1311 * Checks if the socket is ready for reading or writing.
1312 *
1313 * @return iprt status code.
1314 * @retval VERR_INTERRUPTED if the thread was woken up by a pfnPoke call.
1315 * @param Sock Socket descriptor.
1316 * @param fEvents Mask of events to wait for.
1317 * @param pfEvents Where to store the received events.
1318 * @param cMillies Number of milliseconds to wait for the socket.
1319 * Use RT_INDEFINITE_WAIT to wait for ever.
1320 */
1321 DECLR3CALLBACKMEMBER(int, pfnSelectOneEx, (VDSOCKET Sock, uint32_t fEvents,
1322 uint32_t *pfEvents, RTMSINTERVAL cMillies));
1323
1324 /**
1325 * Wakes up the thread waiting in pfnSelectOneEx.
1326 *
1327 * @return iprt status code.
1328 * @param Sock Socket descriptor.
1329 */
1330 DECLR3CALLBACKMEMBER(int, pfnPoke, (VDSOCKET Sock));
1331
1332} VDINTERFACETCPNET, *PVDINTERFACETCPNET;
1333
1334/**
1335 * Get TCP network stack interface from opaque callback table.
1336 *
1337 * @return Pointer to the callback table.
1338 * @param pInterface Pointer to the interface descriptor.
1339 */
1340DECLINLINE(PVDINTERFACETCPNET) VDGetInterfaceTcpNet(PVDINTERFACE pInterface)
1341{
1342 PVDINTERFACETCPNET pInterfaceTcpNet;
1343
1344 /* Check that the interface descriptor is a TCP network stack interface. */
1345 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_TCPNET)
1346 && (pInterface->cbSize == sizeof(VDINTERFACE)),
1347 ("Not a TCP network stack interface"), NULL);
1348
1349 pInterfaceTcpNet = (PVDINTERFACETCPNET)pInterface->pCallbacks;
1350
1351 /* Do basic checks. */
1352 AssertMsgReturn( (pInterfaceTcpNet->cbSize == sizeof(VDINTERFACETCPNET))
1353 && (pInterfaceTcpNet->enmInterface == VDINTERFACETYPE_TCPNET),
1354 ("A non TCP network stack callback table attached to a TCP network stack interface descriptor\n"), NULL);
1355
1356 return pInterfaceTcpNet;
1357}
1358
1359/**
1360 * Interface to get the parent state.
1361 *
1362 * Per-operation interface. Optional, present only if there is a parent, and
1363 * used only internally for compacting.
1364 */
1365typedef struct VDINTERFACEPARENTSTATE
1366{
1367 /**
1368 * Size of the parent state interface.
1369 */
1370 uint32_t cbSize;
1371
1372 /**
1373 * Interface type.
1374 */
1375 VDINTERFACETYPE enmInterface;
1376
1377 /**
1378 * Read data callback.
1379 *
1380 * @return VBox status code.
1381 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
1382 * @param pvUser The opaque data passed for the operation.
1383 * @param uOffset Offset of first reading byte from start of disk.
1384 * Must be aligned to a sector boundary.
1385 * @param pvBuffer Pointer to buffer for reading data.
1386 * @param cbBuffer Number of bytes to read.
1387 * Must be aligned to a sector boundary.
1388 */
1389 DECLR3CALLBACKMEMBER(int, pfnParentRead, (void *pvUser, uint64_t uOffset, void *pvBuffer, size_t cbBuffer));
1390
1391} VDINTERFACEPARENTSTATE, *PVDINTERFACEPARENTSTATE;
1392
1393
1394/**
1395 * Get parent state interface from opaque callback table.
1396 *
1397 * @return Pointer to the callback table.
1398 * @param pInterface Pointer to the interface descriptor.
1399 */
1400DECLINLINE(PVDINTERFACEPARENTSTATE) VDGetInterfaceParentState(PVDINTERFACE pInterface)
1401{
1402 PVDINTERFACEPARENTSTATE pInterfaceParentState;
1403
1404 /* Check that the interface descriptor is a parent state interface. */
1405 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_PARENTSTATE)
1406 && (pInterface->cbSize == sizeof(VDINTERFACE)),
1407 ("Not a parent state interface"), NULL);
1408
1409 pInterfaceParentState = (PVDINTERFACEPARENTSTATE)pInterface->pCallbacks;
1410
1411 /* Do basic checks. */
1412 AssertMsgReturn( (pInterfaceParentState->cbSize == sizeof(VDINTERFACEPARENTSTATE))
1413 && (pInterfaceParentState->enmInterface == VDINTERFACETYPE_PARENTSTATE),
1414 ("A non parent state callback table attached to a parent state interface descriptor\n"), NULL);
1415
1416 return pInterfaceParentState;
1417}
1418
1419/**
1420 * Interface to synchronize concurrent accesses by several threads.
1421 *
1422 * @note The scope of this interface is to manage concurrent accesses after
1423 * the HDD container has been created, and they must stop before destroying the
1424 * container. Opening or closing images is covered by the synchronization, but
1425 * that does not mean it is safe to close images while a thread executes
1426 * <link to="VDMerge"/> or <link to="VDCopy"/> operating on these images.
1427 * Making them safe would require the lock to be held during the entire
1428 * operation, which prevents other concurrent acitivities.
1429 *
1430 * @note Right now this is kept as simple as possible, and does not even
1431 * attempt to provide enough information to allow e.g. concurrent write
1432 * accesses to different areas of the disk. The reason is that it is very
1433 * difficult to predict which area of a disk is affected by a write,
1434 * especially when different image formats are mixed. Maybe later a more
1435 * sophisticated interface will be provided which has the necessary information
1436 * about worst case affected areas.
1437 *
1438 * Per-disk interface. Optional, needed if the disk is accessed concurrently
1439 * by several threads, e.g. when merging diff images while a VM is running.
1440 */
1441typedef struct VDINTERFACETHREADSYNC
1442{
1443 /**
1444 * Size of the thread synchronization interface.
1445 */
1446 uint32_t cbSize;
1447
1448 /**
1449 * Interface type.
1450 */
1451 VDINTERFACETYPE enmInterface;
1452
1453 /**
1454 * Start a read operation.
1455 */
1456 DECLR3CALLBACKMEMBER(int, pfnStartRead, (void *pvUser));
1457
1458 /**
1459 * Finish a read operation.
1460 */
1461 DECLR3CALLBACKMEMBER(int, pfnFinishRead, (void *pvUser));
1462
1463 /**
1464 * Start a write operation.
1465 */
1466 DECLR3CALLBACKMEMBER(int, pfnStartWrite, (void *pvUser));
1467
1468 /**
1469 * Finish a write operation.
1470 */
1471 DECLR3CALLBACKMEMBER(int, pfnFinishWrite, (void *pvUser));
1472
1473} VDINTERFACETHREADSYNC, *PVDINTERFACETHREADSYNC;
1474
1475/**
1476 * Get thread synchronization interface from opaque callback table.
1477 *
1478 * @return Pointer to the callback table.
1479 * @param pInterface Pointer to the interface descriptor.
1480 */
1481DECLINLINE(PVDINTERFACETHREADSYNC) VDGetInterfaceThreadSync(PVDINTERFACE pInterface)
1482{
1483 PVDINTERFACETHREADSYNC pInterfaceThreadSync;
1484
1485 /* Check that the interface descriptor is a thread synchronization interface. */
1486 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_THREADSYNC)
1487 && (pInterface->cbSize == sizeof(VDINTERFACE)),
1488 ("Not a thread synchronization interface"), NULL);
1489
1490 pInterfaceThreadSync = (PVDINTERFACETHREADSYNC)pInterface->pCallbacks;
1491
1492 /* Do basic checks. */
1493 AssertMsgReturn( (pInterfaceThreadSync->cbSize == sizeof(VDINTERFACETHREADSYNC))
1494 && (pInterfaceThreadSync->enmInterface == VDINTERFACETYPE_THREADSYNC),
1495 ("A non thread synchronization callback table attached to a thread synchronization interface descriptor\n"), NULL);
1496
1497 return pInterfaceThreadSync;
1498}
1499
1500/** @name Configuration interface key handling flags.
1501 * @{
1502 */
1503/** Mandatory config key. Not providing a value for this key will cause
1504 * the backend to fail. */
1505#define VD_CFGKEY_MANDATORY RT_BIT(0)
1506/** Expert config key. Not showing it by default in the GUI is is probably
1507 * a good idea, as the average user won't understand it easily. */
1508#define VD_CFGKEY_EXPERT RT_BIT(1)
1509/** @}*/
1510
1511
1512/**
1513 * Configuration value type for configuration information interface.
1514 */
1515typedef enum VDCFGVALUETYPE
1516{
1517 /** Integer value. */
1518 VDCFGVALUETYPE_INTEGER = 1,
1519 /** String value. */
1520 VDCFGVALUETYPE_STRING,
1521 /** Bytestring value. */
1522 VDCFGVALUETYPE_BYTES
1523} VDCFGVALUETYPE;
1524
1525
1526/**
1527 * Structure describing configuration keys required/supported by a backend
1528 * through the config interface.
1529 */
1530typedef struct VDCONFIGINFO
1531{
1532 /** Key name of the configuration. */
1533 const char *pszKey;
1534 /** Pointer to default value (descriptor). NULL if no useful default value
1535 * can be specified. */
1536 const char *pszDefaultValue;
1537 /** Value type for this key. */
1538 VDCFGVALUETYPE enmValueType;
1539 /** Key handling flags (a combination of VD_CFGKEY_* flags). */
1540 uint64_t uKeyFlags;
1541} VDCONFIGINFO;
1542
1543/** Pointer to structure describing configuration keys. */
1544typedef VDCONFIGINFO *PVDCONFIGINFO;
1545
1546/** Pointer to const structure describing configuration keys. */
1547typedef const VDCONFIGINFO *PCVDCONFIGINFO;
1548
1549/**
1550 * Structure describing a file extension.
1551 */
1552typedef struct VDFILEEXTENSION
1553{
1554 /** Pointer to the NULL-terminated string containing the extension. */
1555 const char *pszExtension;
1556 /** The device type the extension supports. */
1557 VDTYPE enmType;
1558} VDFILEEXTENSION;
1559
1560/** Pointer to a structure describing a file extension. */
1561typedef VDFILEEXTENSION *PVDFILEEXTENSION;
1562
1563/** Pointer to a const structure describing a file extension. */
1564typedef const VDFILEEXTENSION *PCVDFILEEXTENSION;
1565
1566/**
1567 * Data structure for returning a list of backend capabilities.
1568 */
1569typedef struct VDBACKENDINFO
1570{
1571 /** Name of the backend. Must be unique even with case insensitive comparison. */
1572 const char *pszBackend;
1573 /** Capabilities of the backend (a combination of the VD_CAP_* flags). */
1574 uint64_t uBackendCaps;
1575 /** Pointer to a NULL-terminated array of strings, containing the supported
1576 * file extensions. Note that some backends do not work on files, so this
1577 * pointer may just contain NULL. */
1578 PCVDFILEEXTENSION paFileExtensions;
1579 /** Pointer to an array of structs describing each supported config key.
1580 * Terminated by a NULL config key. Note that some backends do not support
1581 * the configuration interface, so this pointer may just contain NULL.
1582 * Mandatory if the backend sets VD_CAP_CONFIG. */
1583 PCVDCONFIGINFO paConfigInfo;
1584 /** Returns a human readable hard disk location string given a
1585 * set of hard disk configuration keys. The returned string is an
1586 * equivalent of the full file path for image-based hard disks.
1587 * Mandatory for backends with no VD_CAP_FILE and NULL otherwise. */
1588 DECLR3CALLBACKMEMBER(int, pfnComposeLocation, (PVDINTERFACE pConfig, char **pszLocation));
1589 /** Returns a human readable hard disk name string given a
1590 * set of hard disk configuration keys. The returned string is an
1591 * equivalent of the file name part in the full file path for
1592 * image-based hard disks. Mandatory for backends with no
1593 * VD_CAP_FILE and NULL otherwise. */
1594 DECLR3CALLBACKMEMBER(int, pfnComposeName, (PVDINTERFACE pConfig, char **pszName));
1595} VDBACKENDINFO, *PVDBACKENDINFO;
1596
1597
1598/** Forward declaration. Only visible in the VBoxHDD module. */
1599/** I/O context */
1600typedef struct VDIOCTX *PVDIOCTX;
1601/** Storage backend handle. */
1602typedef struct VDIOSTORAGE *PVDIOSTORAGE;
1603/** Pointer to a storage backend handle. */
1604typedef PVDIOSTORAGE *PPVDIOSTORAGE;
1605
1606/**
1607 * Completion callback for meta/userdata reads or writes.
1608 *
1609 * @return VBox status code.
1610 * VINF_SUCCESS if everything was successful and the transfer can continue.
1611 * VERR_VD_ASYNC_IO_IN_PROGRESS if there is another data transfer pending.
1612 * @param pBackendData The opaque backend data.
1613 * @param pIoCtx I/O context associated with this request.
1614 * @param pvUser Opaque user data passed during a read/write request.
1615 * @param rcReq Status code for the completed request.
1616 */
1617typedef DECLCALLBACK(int) FNVDXFERCOMPLETED(void *pBackendData, PVDIOCTX pIoCtx, void *pvUser, int rcReq);
1618/** Pointer to FNVDXFERCOMPLETED() */
1619typedef FNVDXFERCOMPLETED *PFNVDXFERCOMPLETED;
1620
1621/** Metadata transfer handle. */
1622typedef struct VDMETAXFER *PVDMETAXFER;
1623/** Pointer to a metadata transfer handle. */
1624typedef PVDMETAXFER *PPVDMETAXFER;
1625
1626
1627/**
1628 * Internal I/O interface between the generic VD layer and the backends.
1629 *
1630 * Per-image. Always passed to backends.
1631 */
1632typedef struct VDINTERFACEIOINT
1633{
1634 /**
1635 * Size of the internal I/O interface.
1636 */
1637 uint32_t cbSize;
1638
1639 /**
1640 * Interface type.
1641 */
1642 VDINTERFACETYPE enmInterface;
1643
1644 /**
1645 * Open callback
1646 *
1647 * @return VBox status code.
1648 * @param pvUser The opaque data passed on container creation.
1649 * @param pszLocation Name of the location to open.
1650 * @param fOpen Flags for opening the backend.
1651 * See RTFILE_O_* #defines, inventing another set
1652 * of open flags is not worth the mapping effort.
1653 * @param ppStorage Where to store the storage handle.
1654 */
1655 DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,
1656 uint32_t fOpen, PPVDIOSTORAGE ppStorage));
1657
1658 /**
1659 * Close callback.
1660 *
1661 * @return VBox status code.
1662 * @param pvUser The opaque data passed on container creation.
1663 * @param pStorage The storage handle to close.
1664 */
1665 DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, PVDIOSTORAGE pStorage));
1666
1667 /**
1668 * Delete callback.
1669 *
1670 * @return VBox status code.
1671 * @param pvUser The opaque data passed on container creation.
1672 * @param pcszFilename Name of the file to delete.
1673 */
1674 DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));
1675
1676 /**
1677 * Move callback.
1678 *
1679 * @return VBox status code.
1680 * @param pvUser The opaque data passed on container creation.
1681 * @param pcszSrc The path to the source file.
1682 * @param pcszDst The path to the destination file.
1683 * This file will be created.
1684 * @param fMove A combination of the RTFILEMOVE_* flags.
1685 */
1686 DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));
1687
1688 /**
1689 * Returns the free space on a disk.
1690 *
1691 * @return VBox status code.
1692 * @param pvUser The opaque data passed on container creation.
1693 * @param pcszFilename Name of a file to identify the disk.
1694 * @param pcbFreeSpace Where to store the free space of the disk.
1695 */
1696 DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));
1697
1698 /**
1699 * Returns the last modification timestamp of a file.
1700 *
1701 * @return VBox status code.
1702 * @param pvUser The opaque data passed on container creation.
1703 * @param pcszFilename Name of a file to identify the disk.
1704 * @param pModificationTime Where to store the timestamp of the file.
1705 */
1706 DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));
1707
1708 /**
1709 * Returns the size of the opened storage backend.
1710 *
1711 * @return VBox status code.
1712 * @param pvUser The opaque data passed on container creation.
1713 * @param pStorage The storage handle to get the size from.
1714 * @param pcbSize Where to store the size of the storage backend.
1715 */
1716 DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, PVDIOSTORAGE pStorage,
1717 uint64_t *pcbSize));
1718
1719 /**
1720 * Sets the size of the opened storage backend if possible.
1721 *
1722 * @return VBox status code.
1723 * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
1724 * @param pvUser The opaque data passed on container creation.
1725 * @param pStorage The storage handle.
1726 * @param cbSize The new size of the image.
1727 */
1728 DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, PVDIOSTORAGE pStorage,
1729 uint64_t cbSize));
1730
1731 /**
1732 * Synchronous write callback.
1733 *
1734 * @return VBox status code.
1735 * @param pvUser The opaque data passed on container creation.
1736 * @param pStorage The storage handle to use.
1737 * @param uOffset The offset to start from.
1738 * @param pvBuffer Pointer to the bits need to be written.
1739 * @param cbBuffer How many bytes to write.
1740 * @param pcbWritten Where to store how many bytes were actually written.
1741 *
1742 * @notes Do not use in code called from the async read/write entry points in the backends.
1743 * This should be only used during open/close of images and for the support functions
1744 * which are not called while a VM is running (pfnCompact).
1745 */
1746 DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset,
1747 const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
1748
1749 /**
1750 * Synchronous read callback.
1751 *
1752 * @return VBox status code.
1753 * @param pvUser The opaque data passed on container creation.
1754 * @param pStorage The storage handle to use.
1755 * @param uOffset The offset to start from.
1756 * @param pvBuffer Where to store the read bits.
1757 * @param cbBuffer How many bytes to read.
1758 * @param pcbRead Where to store how many bytes were actually read.
1759 *
1760 * @notes See pfnWriteSync()
1761 */
1762 DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset,
1763 void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
1764
1765 /**
1766 * Flush data to the storage backend.
1767 *
1768 * @return VBox status code.
1769 * @param pvUser The opaque data passed on container creation.
1770 * @param pStorage The storage handle to flush.
1771 *
1772 * @notes See pfnWriteSync()
1773 */
1774 DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, PVDIOSTORAGE pStorage));
1775
1776 /**
1777 * Initiate an asynchronous read request for user data.
1778 *
1779 * @return VBox status code.
1780 * @param pvUser The opaque user data passed on container creation.
1781 * @param pStorage The storage handle.
1782 * @param uOffset The offset to start reading from.
1783 * @param pIoCtx I/O context passed in VDAsyncRead/Write.
1784 * @param cbRead How many bytes to read.
1785 */
1786 DECLR3CALLBACKMEMBER(int, pfnReadUserAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1787 uint64_t uOffset, PVDIOCTX pIoCtx,
1788 size_t cbRead));
1789
1790 /**
1791 * Initiate an asynchronous write request for user data.
1792 *
1793 * @return VBox status code.
1794 * @param pvUser The opaque user data passed on container creation.
1795 * @param pStorage The storage handle.
1796 * @param uOffset The offset to start writing to.
1797 * @param pIoCtx I/O context passed in VDAsyncRead/Write
1798 * @param cbWrite How many bytes to write.
1799 * @param pfnCompleted Completion callback.
1800 * @param pvCompleteUser Opaque user data passed in the completion callback.
1801 */
1802 DECLR3CALLBACKMEMBER(int, pfnWriteUserAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1803 uint64_t uOffset, PVDIOCTX pIoCtx,
1804 size_t cbWrite,
1805 PFNVDXFERCOMPLETED pfnComplete,
1806 void *pvCompleteUser));
1807
1808 /**
1809 * Reads metadata asynchronously from storage.
1810 * The current I/O context will be halted.
1811 *
1812 * @returns VBox status code.
1813 * @param pvUser The opaque user data passed on container creation.
1814 * @param pStorage The storage handle.
1815 * @param uOffset Offset to start reading from.
1816 * @param pvBuffer Where to store the data.
1817 * @param cbBuffer How many bytes to read.
1818 * @param pIoCtx The I/O context which triggered the read.
1819 * @param ppMetaXfer Where to store the metadata transfer handle on success.
1820 * @param pfnCompleted Completion callback.
1821 * @param pvCompleteUser Opaque user data passed in the completion callback.
1822 */
1823 DECLR3CALLBACKMEMBER(int, pfnReadMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1824 uint64_t uOffset, void *pvBuffer,
1825 size_t cbBuffer, PVDIOCTX pIoCtx,
1826 PPVDMETAXFER ppMetaXfer,
1827 PFNVDXFERCOMPLETED pfnComplete,
1828 void *pvCompleteUser));
1829
1830 /**
1831 * Writes metadata asynchronously to storage.
1832 *
1833 * @returns VBox status code.
1834 * @param pvUser The opaque user data passed on container creation.
1835 * @param pStorage The storage handle.
1836 * @param uOffset Offset to start writing to.
1837 * @param pvBuffer Written data.
1838 * @param cbBuffer How many bytes to write.
1839 * @param pIoCtx The I/O context which triggered the write.
1840 * @param pfnCompleted Completion callback.
1841 * @param pvCompleteUser Opaque user data passed in the completion callback.
1842 */
1843 DECLR3CALLBACKMEMBER(int, pfnWriteMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1844 uint64_t uOffset, void *pvBuffer,
1845 size_t cbBuffer, PVDIOCTX pIoCtx,
1846 PFNVDXFERCOMPLETED pfnComplete,
1847 void *pvCompleteUser));
1848
1849 /**
1850 * Releases a metadata transfer handle.
1851 * The free space can be used for another transfer.
1852 *
1853 * @returns nothing.
1854 * @param pvUser The opaque user data passed on container creation.
1855 * @param pMetaXfer The metadata transfer handle to release.
1856 */
1857 DECLR3CALLBACKMEMBER(void, pfnMetaXferRelease, (void *pvUser, PVDMETAXFER pMetaXfer));
1858
1859 /**
1860 * Initiates an async flush request.
1861 *
1862 * @return VBox status code.
1863 * @param pvUser The opaque data passed on container creation.
1864 * @param pStorage The storage handle to flush.
1865 * @param pIoCtx I/O context which triggered the flush.
1866 * @param pfnCompleted Completion callback.
1867 * @param pvCompleteUser Opaque user data passed in the completion callback.
1868 */
1869 DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, PVDIOSTORAGE pStorage,
1870 PVDIOCTX pIoCtx,
1871 PFNVDXFERCOMPLETED pfnComplete,
1872 void *pvCompleteUser));
1873
1874 /**
1875 * Copies a buffer into the I/O context.
1876 *
1877 * @return Number of bytes copied.
1878 * @param pvUser The opaque user data passed on container creation.
1879 * @param pIoCtx I/O context to copy the data to.
1880 * @param pvBuffer Buffer to copy.
1881 * @param cbBuffer Number of bytes to copy.
1882 */
1883 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyTo, (void *pvUser, PVDIOCTX pIoCtx,
1884 void *pvBuffer, size_t cbBuffer));
1885
1886 /**
1887 * Copies data from the I/O context into a buffer.
1888 *
1889 * @return Number of bytes copied.
1890 * @param pvUser The opaque user data passed on container creation.
1891 * @param pIoCtx I/O context to copy the data from.
1892 * @param pvBuffer Destination buffer.
1893 * @param cbBuffer Number of bytes to copy.
1894 */
1895 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyFrom, (void *pvUser, PVDIOCTX pIoCtx,
1896 void *pvBuffer, size_t cbBuffer));
1897
1898 /**
1899 * Sets the buffer of the given context to a specific byte.
1900 *
1901 * @return Number of bytes set.
1902 * @param pvUser The opaque user data passed on container creation.
1903 * @param pIoCtx I/O context to copy the data from.
1904 * @param ch The byte to set.
1905 * @param cbSet Number of bytes to set.
1906 */
1907 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSet, (void *pvUser, PVDIOCTX pIoCtx,
1908 int ch, size_t cbSet));
1909
1910 /**
1911 * Creates a segment array from the I/O context data buffer.
1912 *
1913 * @returns Number of bytes the array describes.
1914 * @param pvUser The opaque user data passed on container creation.
1915 * @param pIoCtx I/O context to copy the data from.
1916 * @param paSeg The uninitialized segment array.
1917 * If NULL pcSeg will contain the number of segments needed
1918 * to describe the requested amount of data.
1919 * @param pcSeg The number of segments the given array has.
1920 * This will hold the actual number of entries needed upon return.
1921 * @param cbData Number of bytes the new array should describe.
1922 */
1923 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSegArrayCreate, (void *pvUser, PVDIOCTX pIoCtx,
1924 PRTSGSEG paSeg, unsigned *pcSeg,
1925 size_t cbData));
1926 /**
1927 * Marks the given number of bytes as completed and continues the I/O context.
1928 *
1929 * @returns nothing.
1930 * @param pvUser The opaque user data passed on container creation.
1931 * @param pIoCtx The I/O context.
1932 * @param rcReq Status code the request completed with.
1933 * @param cbCompleted Number of bytes completed.
1934 */
1935 DECLR3CALLBACKMEMBER(void, pfnIoCtxCompleted, (void *pvUser, PVDIOCTX pIoCtx,
1936 int rcReq, size_t cbCompleted));
1937} VDINTERFACEIOINT, *PVDINTERFACEIOINT;
1938
1939/**
1940 * Get internal I/O interface from opaque callback table.
1941 *
1942 * @return Pointer to the callback table.
1943 * @param pInterface Pointer to the interface descriptor.
1944 */
1945DECLINLINE(PVDINTERFACEIOINT) VDGetInterfaceIOInt(PVDINTERFACE pInterface)
1946{
1947 PVDINTERFACEIOINT pInterfaceIOInt;
1948
1949 /* Check that the interface descriptor is an internal I/O interface. */
1950 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_IOINT)
1951 && (pInterface->cbSize == sizeof(VDINTERFACE)),
1952 ("Not an internal I/O interface"), NULL);
1953
1954 pInterfaceIOInt = (PVDINTERFACEIOINT)pInterface->pCallbacks;
1955
1956 /* Do basic checks. */
1957 AssertMsgReturn( (pInterfaceIOInt->cbSize == sizeof(VDINTERFACEIOINT))
1958 && (pInterfaceIOInt->enmInterface == VDINTERFACETYPE_IOINT),
1959 ("A non internal I/O callback table attached to an internal I/O interface descriptor\n"), NULL);
1960
1961 return pInterfaceIOInt;
1962}
1963
1964/**
1965 * Request completion callback for the async read/write API.
1966 */
1967typedef void (FNVDASYNCTRANSFERCOMPLETE) (void *pvUser1, void *pvUser2, int rcReq);
1968/** Pointer to a transfer compelte callback. */
1969typedef FNVDASYNCTRANSFERCOMPLETE *PFNVDASYNCTRANSFERCOMPLETE;
1970
1971/**
1972 * Disk geometry.
1973 */
1974typedef struct VDGEOMETRY
1975{
1976 /** Number of cylinders. */
1977 uint32_t cCylinders;
1978 /** Number of heads. */
1979 uint32_t cHeads;
1980 /** Number of sectors. */
1981 uint32_t cSectors;
1982} VDGEOMETRY;
1983
1984/** Pointer to disk geometry. */
1985typedef VDGEOMETRY *PVDGEOMETRY;
1986/** Pointer to constant disk geometry. */
1987typedef const VDGEOMETRY *PCVDGEOMETRY;
1988
1989/**
1990 * VBox HDD Container main structure.
1991 */
1992/* Forward declaration, VBOXHDD structure is visible only inside VBox HDD module. */
1993struct VBOXHDD;
1994typedef struct VBOXHDD VBOXHDD;
1995typedef VBOXHDD *PVBOXHDD;
1996
1997/**
1998 * Initializes HDD backends.
1999 *
2000 * @returns VBox status code.
2001 */
2002VBOXDDU_DECL(int) VDInit(void);
2003
2004/**
2005 * Destroys loaded HDD backends.
2006 *
2007 * @returns VBox status code.
2008 */
2009VBOXDDU_DECL(int) VDShutdown(void);
2010
2011/**
2012 * Lists all HDD backends and their capabilities in a caller-provided buffer.
2013 *
2014 * @return VBox status code.
2015 * VERR_BUFFER_OVERFLOW if not enough space is passed.
2016 * @param cEntriesAlloc Number of list entries available.
2017 * @param pEntries Pointer to array for the entries.
2018 * @param pcEntriesUsed Number of entries returned.
2019 */
2020VBOXDDU_DECL(int) VDBackendInfo(unsigned cEntriesAlloc, PVDBACKENDINFO pEntries,
2021 unsigned *pcEntriesUsed);
2022
2023/**
2024 * Lists the capabilities of a backend identified by its name.
2025 *
2026 * @return VBox status code.
2027 * @param pszBackend The backend name (case insensitive).
2028 * @param pEntries Pointer to an entry.
2029 */
2030VBOXDDU_DECL(int) VDBackendInfoOne(const char *pszBackend, PVDBACKENDINFO pEntry);
2031
2032/**
2033 * Allocates and initializes an empty HDD container.
2034 * No image files are opened.
2035 *
2036 * @return VBox status code.
2037 * @param pVDIfsDisk Pointer to the per-disk VD interface list.
2038 * @param enmType Type of the image container.
2039 * @param ppDisk Where to store the reference to HDD container.
2040 */
2041VBOXDDU_DECL(int) VDCreate(PVDINTERFACE pVDIfsDisk, VDTYPE enmType, PVBOXHDD *ppDisk);
2042
2043/**
2044 * Destroys HDD container.
2045 * If container has opened image files they will be closed.
2046 *
2047 * @param pDisk Pointer to HDD container.
2048 */
2049VBOXDDU_DECL(void) VDDestroy(PVBOXHDD pDisk);
2050
2051/**
2052 * Try to get the backend name which can use this image.
2053 *
2054 * @return VBox status code.
2055 * VINF_SUCCESS if a plugin was found.
2056 * ppszFormat contains the string which can be used as backend name.
2057 * VERR_NOT_SUPPORTED if no backend was found.
2058 * @param pVDIfsDisk Pointer to the per-disk VD interface list.
2059 * @param pVDIfsImage Pointer to the per-image VD interface list.
2060 * @param pszFilename Name of the image file for which the backend is queried.
2061 * @param ppszFormat Receives pointer of the UTF-8 string which contains the format name.
2062 * The returned pointer must be freed using RTStrFree().
2063 * @param penmType Where to store the type of the image.
2064 */
2065VBOXDDU_DECL(int) VDGetFormat(PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
2066 const char *pszFilename, char **ppszFormat, VDTYPE *penmType);
2067
2068/**
2069 * Opens an image file.
2070 *
2071 * The first opened image file in HDD container must have a base image type,
2072 * others (next opened images) must be differencing or undo images.
2073 * Linkage is checked for differencing image to be consistent with the previously opened image.
2074 * When another differencing image is opened and the last image was opened in read/write access
2075 * mode, then the last image is reopened in read-only with deny write sharing mode. This allows
2076 * other processes to use images in read-only mode too.
2077 *
2078 * Note that the image is opened in read-only mode if a read/write open is not possible.
2079 * Use VDIsReadOnly to check open mode.
2080 *
2081 * @return VBox status code.
2082 * @param pDisk Pointer to HDD container.
2083 * @param pszBackend Name of the image file backend to use (case insensitive).
2084 * @param pszFilename Name of the image file to open.
2085 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2086 * @param pVDIfsImage Pointer to the per-image VD interface list.
2087 */
2088VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend,
2089 const char *pszFilename, unsigned uOpenFlags,
2090 PVDINTERFACE pVDIfsImage);
2091
2092/**
2093 * Opens a cache image.
2094 *
2095 * @return VBox status code.
2096 * @param pDisk Pointer to the HDD container which should use the cache image.
2097 * @param pszBackend Name of the cache file backend to use (case insensitive).
2098 * @param pszFilename Name of the cache image to open.
2099 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2100 * @param pVDIfsCache Pointer to the per-cache VD interface list.
2101 */
2102VBOXDDU_DECL(int) VDCacheOpen(PVBOXHDD pDisk, const char *pszBackend,
2103 const char *pszFilename, unsigned uOpenFlags,
2104 PVDINTERFACE pVDIfsCache);
2105
2106/**
2107 * Creates and opens a new base image file.
2108 *
2109 * @return VBox status code.
2110 * @param pDisk Pointer to HDD container.
2111 * @param pszBackend Name of the image file backend to use (case insensitive).
2112 * @param pszFilename Name of the image file to create.
2113 * @param cbSize Image size in bytes.
2114 * @param uImageFlags Flags specifying special image features.
2115 * @param pszComment Pointer to image comment. NULL is ok.
2116 * @param pPCHSGeometry Pointer to physical disk geometry <= (16383,16,63). Not NULL.
2117 * @param pLCHSGeometry Pointer to logical disk geometry <= (x,255,63). Not NULL.
2118 * @param pUuid New UUID of the image. If NULL, a new UUID is created.
2119 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2120 * @param pVDIfsImage Pointer to the per-image VD interface list.
2121 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2122 */
2123VBOXDDU_DECL(int) VDCreateBase(PVBOXHDD pDisk, const char *pszBackend,
2124 const char *pszFilename, uint64_t cbSize,
2125 unsigned uImageFlags, const char *pszComment,
2126 PCVDGEOMETRY pPCHSGeometry,
2127 PCVDGEOMETRY pLCHSGeometry,
2128 PCRTUUID pUuid, unsigned uOpenFlags,
2129 PVDINTERFACE pVDIfsImage,
2130 PVDINTERFACE pVDIfsOperation);
2131
2132/**
2133 * Creates and opens a new differencing image file in HDD container.
2134 * See comments for VDOpen function about differencing images.
2135 *
2136 * @return VBox status code.
2137 * @param pDisk Pointer to HDD container.
2138 * @param pszBackend Name of the image file backend to use (case insensitive).
2139 * @param pszFilename Name of the differencing image file to create.
2140 * @param uImageFlags Flags specifying special image features.
2141 * @param pszComment Pointer to image comment. NULL is ok.
2142 * @param pUuid New UUID of the image. If NULL, a new UUID is created.
2143 * @param pParentUuid New parent UUID of the image. If NULL, the UUID is queried automatically.
2144 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2145 * @param pVDIfsImage Pointer to the per-image VD interface list.
2146 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2147 */
2148VBOXDDU_DECL(int) VDCreateDiff(PVBOXHDD pDisk, const char *pszBackend,
2149 const char *pszFilename, unsigned uImageFlags,
2150 const char *pszComment, PCRTUUID pUuid,
2151 PCRTUUID pParentUuid, unsigned uOpenFlags,
2152 PVDINTERFACE pVDIfsImage,
2153 PVDINTERFACE pVDIfsOperation);
2154
2155/**
2156 * Creates and opens new cache image file in HDD container.
2157 *
2158 * @return VBox status code.
2159 * @param pDisk Name of the cache file backend to use (case insensitive).
2160 * @param pszFilename Name of the differencing cache file to create.
2161 * @param cbSize Maximum size of the cache.
2162 * @param uImageFlags Flags specifying special cache features.
2163 * @param pszComment Pointer to image comment. NULL is ok.
2164 * @param pUuid New UUID of the image. If NULL, a new UUID is created.
2165 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2166 * @param pVDIfsCache Pointer to the per-cache VD interface list.
2167 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2168 */
2169VBOXDDU_DECL(int) VDCreateCache(PVBOXHDD pDisk, const char *pszBackend,
2170 const char *pszFilename, uint64_t cbSize,
2171 unsigned uImageFlags, const char *pszComment,
2172 PCRTUUID pUuid, unsigned uOpenFlags,
2173 PVDINTERFACE pVDIfsCache, PVDINTERFACE pVDIfsOperation);
2174
2175/**
2176 * Merges two images (not necessarily with direct parent/child relationship).
2177 * As a side effect the source image and potentially the other images which
2178 * are also merged to the destination are deleted from both the disk and the
2179 * images in the HDD container.
2180 *
2181 * @return VBox status code.
2182 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2183 * @param pDisk Pointer to HDD container.
2184 * @param nImageFrom Image number to merge from, counts from 0. 0 is always base image of container.
2185 * @param nImageTo Image number to merge to, counts from 0. 0 is always base image of container.
2186 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2187 */
2188VBOXDDU_DECL(int) VDMerge(PVBOXHDD pDisk, unsigned nImageFrom,
2189 unsigned nImageTo, PVDINTERFACE pVDIfsOperation);
2190
2191/**
2192 * Copies an image from one HDD container to another - extended version.
2193 * The copy is opened in the target HDD container.
2194 * It is possible to convert between different image formats, because the
2195 * backend for the destination may be different from the source.
2196 * If both the source and destination reference the same HDD container,
2197 * then the image is moved (by copying/deleting or renaming) to the new location.
2198 * The source container is unchanged if the move operation fails, otherwise
2199 * the image at the new location is opened in the same way as the old one was.
2200 *
2201 * @note The read/write accesses across disks are not synchronized, just the
2202 * accesses to each disk. Once there is a use case which requires a defined
2203 * read/write behavior in this situation this needs to be extended.
2204 *
2205 * @return VBox status code.
2206 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2207 * @param pDiskFrom Pointer to source HDD container.
2208 * @param nImage Image number, counts from 0. 0 is always base image of container.
2209 * @param pDiskTo Pointer to destination HDD container.
2210 * @param pszBackend Name of the image file backend to use (may be NULL to use the same as the source, case insensitive).
2211 * @param pszFilename New name of the image (may be NULL to specify that the
2212 * copy destination is the destination container, or
2213 * if pDiskFrom == pDiskTo, i.e. when moving).
2214 * @param fMoveByRename If true, attempt to perform a move by renaming (if successful the new size is ignored).
2215 * @param cbSize New image size (0 means leave unchanged).
2216 * @param nImageSameFrom The number of the last image in the source chain having the same content as the
2217 * image in the destination chain given by nImageSameTo or
2218 * VD_IMAGE_CONTENT_UNKNOWN to indicate that the content of both containers is unknown.
2219 * See the notes for further information.
2220 * @param nImageSameTo The number of the last image in the destination chain having the same content as the
2221 * image in the source chain given by nImageSameFrom or
2222 * VD_IMAGE_CONTENT_UNKNOWN to indicate that the content of both containers is unknown.
2223 * See the notes for further information.
2224 * @param uImageFlags Flags specifying special destination image features.
2225 * @param pDstUuid New UUID of the destination image. If NULL, a new UUID is created.
2226 * This parameter is used if and only if a true copy is created.
2227 * In all rename/move cases or copy to existing image cases the modification UUIDs are copied over.
2228 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2229 * Only used if the destination image is created.
2230 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2231 * @param pDstVDIfsImage Pointer to the per-image VD interface list, for the
2232 * destination image.
2233 * @param pDstVDIfsOperation Pointer to the per-operation VD interface list,
2234 * for the destination operation.
2235 *
2236 * @note Using nImageSameFrom and nImageSameTo can lead to a significant speedup
2237 * when copying an image but can also lead to a corrupted copy if used incorrectly.
2238 * It is mainly useful when cloning a chain of images and it is known that
2239 * the virtual disk content of the two chains is exactly the same upto a certain image.
2240 * Example:
2241 * Imagine the chain of images which consist of a base and one diff image.
2242 * Copying the chain starts with the base image. When copying the first
2243 * diff image VDCopy() will read the data from the diff of the source chain
2244 * and probably from the base image again in case the diff doesn't has data
2245 * for the block. However the block will be optimized away because VDCopy()
2246 * reads data from the base image of the destination chain compares the to
2247 * and suppresses the write because the data is unchanged.
2248 * For a lot of diff images this will be a huge waste of I/O bandwidth if
2249 * the diff images contain only few changes.
2250 * Because it is known that the base image of the source and the destination chain
2251 * have the same content it is enough to check the diff image for changed data
2252 * and copy it to the destination diff image which is achieved with
2253 * nImageSameFrom and nImageSameTo. Setting both to 0 can suppress a lot of I/O.
2254 */
2255VBOXDDU_DECL(int) VDCopyEx(PVBOXHDD pDiskFrom, unsigned nImage, PVBOXHDD pDiskTo,
2256 const char *pszBackend, const char *pszFilename,
2257 bool fMoveByRename, uint64_t cbSize,
2258 unsigned nImageFromSame, unsigned nImageToSame,
2259 unsigned uImageFlags, PCRTUUID pDstUuid,
2260 unsigned uOpenFlags, PVDINTERFACE pVDIfsOperation,
2261 PVDINTERFACE pDstVDIfsImage,
2262 PVDINTERFACE pDstVDIfsOperation);
2263
2264/**
2265 * Copies an image from one HDD container to another.
2266 * The copy is opened in the target HDD container.
2267 * It is possible to convert between different image formats, because the
2268 * backend for the destination may be different from the source.
2269 * If both the source and destination reference the same HDD container,
2270 * then the image is moved (by copying/deleting or renaming) to the new location.
2271 * The source container is unchanged if the move operation fails, otherwise
2272 * the image at the new location is opened in the same way as the old one was.
2273 *
2274 * @note The read/write accesses across disks are not synchronized, just the
2275 * accesses to each disk. Once there is a use case which requires a defined
2276 * read/write behavior in this situation this needs to be extended.
2277 *
2278 * @return VBox status code.
2279 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2280 * @param pDiskFrom Pointer to source HDD container.
2281 * @param nImage Image number, counts from 0. 0 is always base image of container.
2282 * @param pDiskTo Pointer to destination HDD container.
2283 * @param pszBackend Name of the image file backend to use (may be NULL to use the same as the source, case insensitive).
2284 * @param pszFilename New name of the image (may be NULL to specify that the
2285 * copy destination is the destination container, or
2286 * if pDiskFrom == pDiskTo, i.e. when moving).
2287 * @param fMoveByRename If true, attempt to perform a move by renaming (if successful the new size is ignored).
2288 * @param cbSize New image size (0 means leave unchanged).
2289 * @param uImageFlags Flags specifying special destination image features.
2290 * @param pDstUuid New UUID of the destination image. If NULL, a new UUID is created.
2291 * This parameter is used if and only if a true copy is created.
2292 * In all rename/move cases or copy to existing image cases the modification UUIDs are copied over.
2293 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2294 * Only used if the destination image is created.
2295 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2296 * @param pDstVDIfsImage Pointer to the per-image VD interface list, for the
2297 * destination image.
2298 * @param pDstVDIfsOperation Pointer to the per-operation VD interface list,
2299 * for the destination operation.
2300 */
2301VBOXDDU_DECL(int) VDCopy(PVBOXHDD pDiskFrom, unsigned nImage, PVBOXHDD pDiskTo,
2302 const char *pszBackend, const char *pszFilename,
2303 bool fMoveByRename, uint64_t cbSize,
2304 unsigned uImageFlags, PCRTUUID pDstUuid,
2305 unsigned uOpenFlags, PVDINTERFACE pVDIfsOperation,
2306 PVDINTERFACE pDstVDIfsImage,
2307 PVDINTERFACE pDstVDIfsOperation);
2308
2309/**
2310 * Optimizes the storage consumption of an image. Typically the unused blocks
2311 * have to be wiped with zeroes to achieve a substantial reduced storage use.
2312 * Another optimization done is reordering the image blocks, which can provide
2313 * a significant performance boost, as reads and writes tend to use less random
2314 * file offsets.
2315 *
2316 * @note Compaction is treated as a single operation with regard to thread
2317 * synchronization, which means that it potentially blocks other activities for
2318 * a long time. The complexity of compaction would grow even more if concurrent
2319 * accesses have to be handled.
2320 *
2321 * @return VBox status code.
2322 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2323 * @return VERR_VD_IMAGE_READ_ONLY if image is not writable.
2324 * @return VERR_NOT_SUPPORTED if this kind of image can be compacted, but
2325 * this isn't supported yet.
2326 * @param pDisk Pointer to HDD container.
2327 * @param nImage Image number, counts from 0. 0 is always base image of container.
2328 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2329 */
2330VBOXDDU_DECL(int) VDCompact(PVBOXHDD pDisk, unsigned nImage,
2331 PVDINTERFACE pVDIfsOperation);
2332
2333/**
2334 * Resizes the given disk image to the given size.
2335 *
2336 * @return VBox status
2337 * @return VERR_VD_IMAGE_READ_ONLY if image is not writable.
2338 * @return VERR_NOT_SUPPORTED if this kind of image can be compacted, but
2339 *
2340 * @param pDisk Pointer to the HDD container.
2341 * @param cbSize New size of the image.
2342 * @param pPCHSGeometry Pointer to the new physical disk geometry <= (16383,16,63). Not NULL.
2343 * @param pLCHSGeometry Pointer to the new logical disk geometry <= (x,255,63). Not NULL.
2344 * @param pVDIfsOperation Pointer to the per-operation VD interface list.
2345 */
2346VBOXDDU_DECL(int) VDResize(PVBOXHDD pDisk, uint64_t cbSize,
2347 PCVDGEOMETRY pPCHSGeometry,
2348 PCVDGEOMETRY pLCHSGeometry,
2349 PVDINTERFACE pVDIfsOperation);
2350
2351/**
2352 * Closes the last opened image file in HDD container.
2353 * If previous image file was opened in read-only mode (the normal case) and
2354 * the last opened image is in read-write mode then the previous image will be
2355 * reopened in read/write mode.
2356 *
2357 * @return VBox status code.
2358 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
2359 * @param pDisk Pointer to HDD container.
2360 * @param fDelete If true, delete the image from the host disk.
2361 */
2362VBOXDDU_DECL(int) VDClose(PVBOXHDD pDisk, bool fDelete);
2363
2364/**
2365 * Closes the currently opened cache image file in HDD container.
2366 *
2367 * @return VBox status code.
2368 * @return VERR_VD_NOT_OPENED if no cache is opened in HDD container.
2369 * @param pDisk Pointer to HDD container.
2370 * @param fDelete If true, delete the image from the host disk.
2371 */
2372VBOXDDU_DECL(int) VDCacheClose(PVBOXHDD pDisk, bool fDelete);
2373
2374/**
2375 * Closes all opened image files in HDD container.
2376 *
2377 * @return VBox status code.
2378 * @param pDisk Pointer to HDD container.
2379 */
2380VBOXDDU_DECL(int) VDCloseAll(PVBOXHDD pDisk);
2381
2382/**
2383 * Read data from virtual HDD.
2384 *
2385 * @return VBox status code.
2386 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
2387 * @param pDisk Pointer to HDD container.
2388 * @param uOffset Offset of first reading byte from start of disk.
2389 * Must be aligned to a sector boundary.
2390 * @param pvBuffer Pointer to buffer for reading data.
2391 * @param cbBuffer Number of bytes to read.
2392 * Must be aligned to a sector boundary.
2393 */
2394VBOXDDU_DECL(int) VDRead(PVBOXHDD pDisk, uint64_t uOffset, void *pvBuffer, size_t cbBuffer);
2395
2396/**
2397 * Write data to virtual HDD.
2398 *
2399 * @return VBox status code.
2400 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
2401 * @param pDisk Pointer to HDD container.
2402 * @param uOffset Offset of first writing byte from start of disk.
2403 * Must be aligned to a sector boundary.
2404 * @param pvBuffer Pointer to buffer for writing data.
2405 * @param cbBuffer Number of bytes to write.
2406 * Must be aligned to a sector boundary.
2407 */
2408VBOXDDU_DECL(int) VDWrite(PVBOXHDD pDisk, uint64_t uOffset, const void *pvBuffer, size_t cbBuffer);
2409
2410/**
2411 * Make sure the on disk representation of a virtual HDD is up to date.
2412 *
2413 * @return VBox status code.
2414 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
2415 * @param pDisk Pointer to HDD container.
2416 */
2417VBOXDDU_DECL(int) VDFlush(PVBOXHDD pDisk);
2418
2419/**
2420 * Get number of opened images in HDD container.
2421 *
2422 * @return Number of opened images for HDD container. 0 if no images have been opened.
2423 * @param pDisk Pointer to HDD container.
2424 */
2425VBOXDDU_DECL(unsigned) VDGetCount(PVBOXHDD pDisk);
2426
2427/**
2428 * Get read/write mode of HDD container.
2429 *
2430 * @return Virtual disk ReadOnly status.
2431 * @return true if no image is opened in HDD container.
2432 * @param pDisk Pointer to HDD container.
2433 */
2434VBOXDDU_DECL(bool) VDIsReadOnly(PVBOXHDD pDisk);
2435
2436/**
2437 * Get total capacity of an image in HDD container.
2438 *
2439 * @return Virtual disk size in bytes.
2440 * @return 0 if image with specified number was not opened.
2441 * @param pDisk Pointer to HDD container.
2442 * @param nImage Image number, counts from 0. 0 is always base image of container.
2443 */
2444VBOXDDU_DECL(uint64_t) VDGetSize(PVBOXHDD pDisk, unsigned nImage);
2445
2446/**
2447 * Get total file size of an image in HDD container.
2448 *
2449 * @return Virtual disk size in bytes.
2450 * @return 0 if image with specified number was not opened.
2451 * @param pDisk Pointer to HDD container.
2452 * @param nImage Image number, counts from 0. 0 is always base image of container.
2453 */
2454VBOXDDU_DECL(uint64_t) VDGetFileSize(PVBOXHDD pDisk, unsigned nImage);
2455
2456/**
2457 * Get virtual disk PCHS geometry of an image in HDD container.
2458 *
2459 * @return VBox status code.
2460 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2461 * @return VERR_VD_GEOMETRY_NOT_SET if no geometry present in the HDD container.
2462 * @param pDisk Pointer to HDD container.
2463 * @param nImage Image number, counts from 0. 0 is always base image of container.
2464 * @param pPCHSGeometry Where to store PCHS geometry. Not NULL.
2465 */
2466VBOXDDU_DECL(int) VDGetPCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
2467 PVDGEOMETRY pPCHSGeometry);
2468
2469/**
2470 * Store virtual disk PCHS geometry of an image in HDD container.
2471 *
2472 * @return VBox status code.
2473 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2474 * @param pDisk Pointer to HDD container.
2475 * @param nImage Image number, counts from 0. 0 is always base image of container.
2476 * @param pPCHSGeometry Where to load PCHS geometry from. Not NULL.
2477 */
2478VBOXDDU_DECL(int) VDSetPCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
2479 PCVDGEOMETRY pPCHSGeometry);
2480
2481/**
2482 * Get virtual disk LCHS geometry of an image in HDD container.
2483 *
2484 * @return VBox status code.
2485 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2486 * @return VERR_VD_GEOMETRY_NOT_SET if no geometry present in the HDD container.
2487 * @param pDisk Pointer to HDD container.
2488 * @param nImage Image number, counts from 0. 0 is always base image of container.
2489 * @param pLCHSGeometry Where to store LCHS geometry. Not NULL.
2490 */
2491VBOXDDU_DECL(int) VDGetLCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
2492 PVDGEOMETRY pLCHSGeometry);
2493
2494/**
2495 * Store virtual disk LCHS geometry of an image in HDD container.
2496 *
2497 * @return VBox status code.
2498 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2499 * @param pDisk Pointer to HDD container.
2500 * @param nImage Image number, counts from 0. 0 is always base image of container.
2501 * @param pLCHSGeometry Where to load LCHS geometry from. Not NULL.
2502 */
2503VBOXDDU_DECL(int) VDSetLCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
2504 PCVDGEOMETRY pLCHSGeometry);
2505
2506/**
2507 * Get version of image in HDD container.
2508 *
2509 * @return VBox status code.
2510 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2511 * @param pDisk Pointer to HDD container.
2512 * @param nImage Image number, counts from 0. 0 is always base image of container.
2513 * @param puVersion Where to store the image version.
2514 */
2515VBOXDDU_DECL(int) VDGetVersion(PVBOXHDD pDisk, unsigned nImage,
2516 unsigned *puVersion);
2517
2518/**
2519 * List the capabilities of image backend in HDD container.
2520 *
2521 * @return VBox status code.
2522 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2523 * @param pDisk Pointer to the HDD container.
2524 * @param nImage Image number, counts from 0. 0 is always base image of container.
2525 * @param pbackendInfo Where to store the backend information.
2526 */
2527VBOXDDU_DECL(int) VDBackendInfoSingle(PVBOXHDD pDisk, unsigned nImage,
2528 PVDBACKENDINFO pBackendInfo);
2529
2530/**
2531 * Get flags of image in HDD container.
2532 *
2533 * @return VBox status code.
2534 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2535 * @param pDisk Pointer to HDD container.
2536 * @param nImage Image number, counts from 0. 0 is always base image of container.
2537 * @param puImageFlags Where to store the image flags.
2538 */
2539VBOXDDU_DECL(int) VDGetImageFlags(PVBOXHDD pDisk, unsigned nImage, unsigned *puImageFlags);
2540
2541/**
2542 * Get open flags of image in HDD container.
2543 *
2544 * @return VBox status code.
2545 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2546 * @param pDisk Pointer to HDD container.
2547 * @param nImage Image number, counts from 0. 0 is always base image of container.
2548 * @param puOpenFlags Where to store the image open flags.
2549 */
2550VBOXDDU_DECL(int) VDGetOpenFlags(PVBOXHDD pDisk, unsigned nImage,
2551 unsigned *puOpenFlags);
2552
2553/**
2554 * Set open flags of image in HDD container.
2555 * This operation may cause file locking changes and/or files being reopened.
2556 * Note that in case of unrecoverable error all images in HDD container will be closed.
2557 *
2558 * @return VBox status code.
2559 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2560 * @param pDisk Pointer to HDD container.
2561 * @param nImage Image number, counts from 0. 0 is always base image of container.
2562 * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
2563 */
2564VBOXDDU_DECL(int) VDSetOpenFlags(PVBOXHDD pDisk, unsigned nImage,
2565 unsigned uOpenFlags);
2566
2567/**
2568 * Get base filename of image in HDD container. Some image formats use
2569 * other filenames as well, so don't use this for anything but informational
2570 * purposes.
2571 *
2572 * @return VBox status code.
2573 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2574 * @return VERR_BUFFER_OVERFLOW if pszFilename buffer too small to hold filename.
2575 * @param pDisk Pointer to HDD container.
2576 * @param nImage Image number, counts from 0. 0 is always base image of container.
2577 * @param pszFilename Where to store the image file name.
2578 * @param cbFilename Size of buffer pszFilename points to.
2579 */
2580VBOXDDU_DECL(int) VDGetFilename(PVBOXHDD pDisk, unsigned nImage,
2581 char *pszFilename, unsigned cbFilename);
2582
2583/**
2584 * Get the comment line of image in HDD container.
2585 *
2586 * @return VBox status code.
2587 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2588 * @return VERR_BUFFER_OVERFLOW if pszComment buffer too small to hold comment text.
2589 * @param pDisk Pointer to HDD container.
2590 * @param nImage Image number, counts from 0. 0 is always base image of container.
2591 * @param pszComment Where to store the comment string of image. NULL is ok.
2592 * @param cbComment The size of pszComment buffer. 0 is ok.
2593 */
2594VBOXDDU_DECL(int) VDGetComment(PVBOXHDD pDisk, unsigned nImage,
2595 char *pszComment, unsigned cbComment);
2596
2597/**
2598 * Changes the comment line of image in HDD container.
2599 *
2600 * @return VBox status code.
2601 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2602 * @param pDisk Pointer to HDD container.
2603 * @param nImage Image number, counts from 0. 0 is always base image of container.
2604 * @param pszComment New comment string (UTF-8). NULL is allowed to reset the comment.
2605 */
2606VBOXDDU_DECL(int) VDSetComment(PVBOXHDD pDisk, unsigned nImage,
2607 const char *pszComment);
2608
2609/**
2610 * Get UUID of image in HDD container.
2611 *
2612 * @return VBox status code.
2613 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2614 * @param pDisk Pointer to HDD container.
2615 * @param nImage Image number, counts from 0. 0 is always base image of container.
2616 * @param pUuid Where to store the image UUID.
2617 */
2618VBOXDDU_DECL(int) VDGetUuid(PVBOXHDD pDisk, unsigned nImage, PRTUUID pUuid);
2619
2620/**
2621 * Set the image's UUID. Should not be used by normal applications.
2622 *
2623 * @return VBox status code.
2624 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2625 * @param pDisk Pointer to HDD container.
2626 * @param nImage Image number, counts from 0. 0 is always base image of container.
2627 * @param pUuid New UUID of the image. If NULL, a new UUID is created.
2628 */
2629VBOXDDU_DECL(int) VDSetUuid(PVBOXHDD pDisk, unsigned nImage, PCRTUUID pUuid);
2630
2631/**
2632 * Get last modification UUID of image in HDD container.
2633 *
2634 * @return VBox status code.
2635 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2636 * @param pDisk Pointer to HDD container.
2637 * @param nImage Image number, counts from 0. 0 is always base image of container.
2638 * @param pUuid Where to store the image modification UUID.
2639 */
2640VBOXDDU_DECL(int) VDGetModificationUuid(PVBOXHDD pDisk, unsigned nImage,
2641 PRTUUID pUuid);
2642
2643/**
2644 * Set the image's last modification UUID. Should not be used by normal applications.
2645 *
2646 * @return VBox status code.
2647 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2648 * @param pDisk Pointer to HDD container.
2649 * @param nImage Image number, counts from 0. 0 is always base image of container.
2650 * @param pUuid New modification UUID of the image. If NULL, a new UUID is created.
2651 */
2652VBOXDDU_DECL(int) VDSetModificationUuid(PVBOXHDD pDisk, unsigned nImage,
2653 PCRTUUID pUuid);
2654
2655/**
2656 * Get parent UUID of image in HDD container.
2657 *
2658 * @return VBox status code.
2659 * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
2660 * @param pDisk Pointer to HDD container.
2661 * @param nImage Image number, counts from 0. 0 is always base image of the container.
2662 * @param pUuid Where to store the parent image UUID.
2663 */
2664VBOXDDU_DECL(int) VDGetParentUuid(PVBOXHDD pDisk, unsigned nImage,
2665 PRTUUID pUuid);
2666
2667/**
2668 * Set the image's parent UUID. Should not be used by normal applications.
2669 *
2670 * @return VBox status code.
2671 * @param pDisk Pointer to HDD container.
2672 * @param nImage Image number, counts from 0. 0 is always base image of container.
2673 * @param pUuid New parent UUID of the image. If NULL, a new UUID is created.
2674 */
2675VBOXDDU_DECL(int) VDSetParentUuid(PVBOXHDD pDisk, unsigned nImage,
2676 PCRTUUID pUuid);
2677
2678
2679/**
2680 * Debug helper - dumps all opened images in HDD container into the log file.
2681 *
2682 * @param pDisk Pointer to HDD container.
2683 */
2684VBOXDDU_DECL(void) VDDumpImages(PVBOXHDD pDisk);
2685
2686
2687/**
2688 * Start an asynchronous read request.
2689 *
2690 * @return VBox status code.
2691 * @param pDisk Pointer to the HDD container.
2692 * @param uOffset The offset of the virtual disk to read from.
2693 * @param cbRead How many bytes to read.
2694 * @param pcSgBuf Pointer to the S/G buffer to read into.
2695 * @param pfnComplete Completion callback.
2696 * @param pvUser User data which is passed on completion
2697 */
2698VBOXDDU_DECL(int) VDAsyncRead(PVBOXHDD pDisk, uint64_t uOffset, size_t cbRead,
2699 PCRTSGBUF pcSgBuf,
2700 PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
2701 void *pvUser1, void *pvUser2);
2702
2703
2704/**
2705 * Start an asynchronous write request.
2706 *
2707 * @return VBox status code.
2708 * @param pDisk Pointer to the HDD container.
2709 * @param uOffset The offset of the virtual disk to write to.
2710 * @param cbWrtie How many bytes to write.
2711 * @param pcSgBuf Pointer to the S/G buffer to write from.
2712 * @param pfnComplete Completion callback.
2713 * @param pvUser User data which is passed on completion.
2714 */
2715VBOXDDU_DECL(int) VDAsyncWrite(PVBOXHDD pDisk, uint64_t uOffset, size_t cbWrite,
2716 PCRTSGBUF pcSgBuf,
2717 PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
2718 void *pvUser1, void *pvUser2);
2719
2720
2721/**
2722 * Start an asynchronous flush request.
2723 *
2724 * @return VBox status code.
2725 * @param pDisk Pointer to the HDD container.
2726 * @param pfnComplete Completion callback.
2727 * @param pvUser User data which is passed on completion.
2728 */
2729VBOXDDU_DECL(int) VDAsyncFlush(PVBOXHDD pDisk,
2730 PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
2731 void *pvUser1, void *pvUser2);
2732RT_C_DECLS_END
2733
2734/** @} */
2735
2736#endif
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