DrvVD.cpp revision 1c94c0a63ba68be1a7b2c640e70d7a06464e4fca
/** $Id$ */
/** @file
*
* VBox storage devices:
* Media implementation for VBox disk container
*/
/*
* Copyright (C) 2006-2008 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DRV_VD
#include <VBox/VBoxHDD-new.h>
#include "Builtins.h"
/*******************************************************************************
* Defined types, constants and macros *
*******************************************************************************/
/** Converts a pointer to VDIDISK::IMedia to a PVBOXDISK. */
#define PDMIMEDIA_2_VBOXDISK(pInterface) \
/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
#define PDMIBASE_2_DRVINS(pInterface) \
/** Converts a pointer to PDMDRVINS::IBase to a PVBOXDISK. */
#define PDMIBASE_2_VBOXDISK(pInterface) \
/**
* VBox disk container media main structure, private part.
*/
typedef struct VBOXDISK
{
/** The VBox disk container. */
/** The media interface. */
/** Pointer to the driver instance. */
/** Flag whether suspend has changed image open mode to read only. */
bool fTempReadOnly;
/*******************************************************************************
* Error reporting callback *
*******************************************************************************/
{
}
/*******************************************************************************
* Media interface methods *
*******************************************************************************/
/** @copydoc PDMIMEDIA::pfnRead */
{
if (VBOX_SUCCESS(rc))
return rc;
}
/** @copydoc PDMIMEDIA::pfnWrite */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnFlush */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnGetSize */
{
return cb;
}
/** @copydoc PDMIMEDIA::pfnIsReadOnly */
{
return f;
}
/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
{
if (VBOX_FAILURE(rc))
{
}
return rc;
}
/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
{
if (VBOX_FAILURE(rc))
{
}
return rc;
}
/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnGetUuid */
{
return rc;
}
/*******************************************************************************
* Base interface methods *
*******************************************************************************/
/** @copydoc PDMIBASE::pfnQueryInterface */
{
switch (enmInterface)
{
case PDMINTERFACE_BASE:
case PDMINTERFACE_MEDIA:
default:
return NULL;
}
}
/*******************************************************************************
* Driver methods *
*******************************************************************************/
/**
* Construct a VBox disk media driver instance.
*
* @returns VBox status.
* @param pDrvIns The driver instance data.
* If the registration structure is needed, pDrvIns->pDrvReg points to it.
* @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
* of the driver instance. It's also found in pDrvIns->pCfgHandle as it's expected
* to be used frequently in this function.
*/
{
int rc = VINF_SUCCESS;
bool fReadOnly; /**< True if the media is readonly. */
bool fHonorZeroWrites; /**< True if zero blocks should be written. */
/*
* Init the static parts.
*/
pData->fTempReadOnly = false;
/* IMedia */
/*
* Validate configuration and find all parent images.
* It's sort of up side down from the image dependency tree.
*/
unsigned iLevel = 0;
for (;;)
{
bool fValid;
if (pCurNode == pCfgHandle)
{
/* Toplevel configuration additionally contains the global image
* open flags. Some might be converted to per-image flags later. */
"Format\0Path\0"
"ReadOnly\0HonorZeroWrites\0");
}
else
{
/* All other image configurations only contain image name and
* the format information. */
}
if (!fValid)
{
break;
}
if (!pParent)
break;
iLevel++;
}
/*
* Open the images.
*/
if (VBOX_SUCCESS(rc))
{
/* Error message is already set correctly. */
}
{
/*
* Read the image configuration.
*/
if (VBOX_FAILURE(rc))
{
N_("DrvVD: Configuration error: Querying \"Path\" as string failed"));
break;
}
if (VBOX_FAILURE(rc))
{
N_("DrvVD: Configuration error: Querying \"Format\" as string failed"));
break;
}
if (iLevel == 0)
{
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
fReadOnly = false;
else if (VBOX_FAILURE(rc))
{
N_("DrvVD: Configuration error: Querying \"ReadOnly\" as boolean failed"));
break;
}
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
fHonorZeroWrites = false;
else if (VBOX_FAILURE(rc))
{
N_("DrvVD: Configuration error: Querying \"HonorZeroWrites\" as boolean failed"));
break;
}
}
else
{
fReadOnly = true;
fHonorZeroWrites = false;
}
/*
* Open the image.
*/
unsigned uOpenFlags;
if (fReadOnly)
else
if (fHonorZeroWrites)
if (VBOX_SUCCESS(rc))
else
{
break;
}
/* next */
iLevel--;
}
if (VBOX_FAILURE(rc))
{
{
}
}
return rc;
}
/**
* Destruct a driver instance.
*
* Most VM resources are freed by the VM. This callback is provided so that any non-VM
* resources can be freed correctly.
*
* @param pDrvIns The driver instance data.
*/
{
}
/**
* When the VM has been suspended we'll change the image mode to read-only
* so that main and others can read the VDIs. This is important when
* saving state and so forth.
*
* @param pDrvIns The driver instance data.
*/
{
{
unsigned uOpenFlags;
pData->fTempReadOnly = true;
}
}
/**
* Before the VM resumes we'll have to undo the read-only mode change
* done in drvvdSuspend.
*
* @param pDrvIns The driver instance data.
*/
{
if (pData->fTempReadOnly)
{
unsigned uOpenFlags;
pData->fTempReadOnly = false;
}
}
/**
* VBox disk container media driver registration record.
*/
{
/* u32Version */
/* szDriverName */
"VD",
/* pszDescription */
"Generic VBox disk media driver.",
/* fFlags */
/* fClass. */
/* cMaxInstances */
~0,
/* cbInstance */
sizeof(VBOXDISK),
/* pfnConstruct */
/* pfnDestruct */
/* pfnIOCtl */
NULL,
/* pfnPowerOn */
NULL,
/* pfnReset */
NULL,
/* pfnSuspend */
/* pfnResume */
/* pfnDetach */
};