VBoxManageDisk.cpp revision 36159dd2122bfe6f3cc172b6c6c4323a02cee365
/* $Id$ */
/** @file
* VBoxManage - The disk related commands.
*/
/*
* Copyright (C) 2006-2011 Oracle Corporation
*
* 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.
*/
#ifndef VBOX_ONLY_DOCS
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "VBoxManage.h"
using namespace com;
// funcs
///////////////////////////////////////////////////////////////////////////////
static DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
{
}
{
int rc = VINF_SUCCESS;
unsigned DiskVariant = (unsigned)(*pDiskVariant);
{
if (pszComma)
else
if (len > 0)
{
// Parsing is intentionally inconsistent: "standard" resets the
// variant, whereas the other flags are cumulative.
else
}
if (pszComma)
else
}
if (RT_SUCCESS(rc))
return rc;
}
{
int rc = VINF_SUCCESS;
else
if (RT_SUCCESS(rc))
return rc;
}
/** @todo move this into getopt, as getting bool values is generic */
{
int rc = VINF_SUCCESS;
{
*pb = true;
}
{
*pb = false;
}
else
return rc;
}
{
/* If it is no UUID, convert the filename to an absolute one. */
{
if (RT_FAILURE(irc))
{
if (!fSilent)
return E_FAIL;
}
}
if (!fSilent)
else
return rc;
}
bool fForceNewUuidOnOpen, bool *pfWasUnknown)
{
bool fWasUnknown = false;
/* If it is no UUID, convert the filename to an absolute one. */
{
if (RT_FAILURE(irc))
{
return E_FAIL;
}
}
pMedium.asOutParam());
/* If the medium is unknown try to open it. */
if (!pMedium)
{
pMedium.asOutParam()));
fWasUnknown = true;
}
if (RT_VALID_PTR(pfWasUnknown))
return rc;
}
{
/** @todo laziness shortcut. should really check the MediumFormatCapabilities */
{
if (RT_FAILURE(irc))
{
return E_FAIL;
}
}
pMedium.asOutParam()));
return rc;
}
static const RTGETOPTDEF g_aCreateHardDiskOptions[] =
{
};
int handleCreateHardDisk(HandlerArg *a)
{
int vrc;
const char *format = "VDI";
int c;
// start at 0 because main() has hacked both the argc and argv given to us
RTGetOptInit(&GetState, a->argc, a->argv, g_aCreateHardDiskOptions, RT_ELEMENTS(g_aCreateHardDiskOptions),
{
switch (c)
{
case 'f': // --filename
break;
case 's': // --size
break;
case 'S': // --sizebyte
break;
case 'o': // --format
break;
case 'F': // --static ("fixed"/"flat")
{
unsigned uDiskVariant = (unsigned)DiskVariant;
break;
}
case 'm': // --variant
if (RT_FAILURE(vrc))
break;
case VINF_GETOPT_NOT_OPTION:
default:
if (c > 0)
{
if (RT_C_IS_PRINT(c))
else
}
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
else if (ValueUnion.pDef)
else
}
}
/* check the outcome */
if ( !filename
|| !*filename
|| size == 0)
/* check for filename extension */
/** @todo use IMediumFormat to cover all extensions generically */
{
else
}
{
{
{
}
}
}
}
static const RTGETOPTDEF g_aModifyHardDiskOptions[] =
{
};
int handleModifyHardDisk(HandlerArg *a)
{
int vrc;
bool AutoReset = false;
bool fModifyResize = false;
const char *FilenameOrUuid = NULL;
bool unknown = false;
int c;
// start at 0 because main() has hacked both the argc and argv given to us
RTGetOptInit(&GetState, a->argc, a->argv, g_aModifyHardDiskOptions, RT_ELEMENTS(g_aModifyHardDiskOptions),
{
switch (c)
{
case 't': // --type
if (RT_FAILURE(vrc))
fModifyDiskType = true;
break;
case 'z': // --autoreset
if (RT_FAILURE(vrc))
fModifyAutoReset = true;
break;
case 'c': // --compact
fModifyCompact = true;
break;
case 'r': // --resize
fModifyResize = true;
break;
case 'R': // --resizebyte
fModifyResize = true;
break;
case VINF_GETOPT_NOT_OPTION:
if (!FilenameOrUuid)
else
break;
default:
if (c > 0)
{
if (RT_C_IS_PRINT(c))
else
}
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
else if (ValueUnion.pDef)
else
}
}
if (!FilenameOrUuid)
/* Depending on the operation the medium must be in the registry or
* may be opened on demand. */
if (fModifyDiskType || fModifyAutoReset)
else
return 1;
{
RTMsgError("Invalid hard disk reference, avoiding crash");
return 1;
}
if (fModifyDiskType)
{
}
if (fModifyAutoReset)
{
}
if (fModifyCompact)
{
{
RTMsgError("Compact hard disk operation is not implemented!");
else if (rc == VBOX_E_NOT_SUPPORTED)
RTMsgError("Compact hard disk operation for this format is not implemented yet!");
else
}
}
if (fModifyResize)
{
{
RTMsgError("Resize hard disk operation is not implemented!");
else if (rc == VBOX_E_NOT_SUPPORTED)
RTMsgError("Resize hard disk operation for this format is not implemented yet!");
else
}
}
if (unknown)
}
static const RTGETOPTDEF g_aCloneHardDiskOptions[] =
{
};
int handleCloneHardDisk(HandlerArg *a)
{
int vrc;
bool fExisting = false;
int c;
// start at 0 because main() has hacked both the argc and argv given to us
RTGetOptInit(&GetState, a->argc, a->argv, g_aCloneHardDiskOptions, RT_ELEMENTS(g_aCloneHardDiskOptions),
{
switch (c)
{
case 'o': // --format
break;
case 'F': // --static
{
unsigned uDiskVariant = (unsigned)DiskVariant;
break;
}
case 'E': // --existing
fExisting = true;
break;
case 'm': // --variant
if (RT_FAILURE(vrc))
break;
case VINF_GETOPT_NOT_OPTION:
if (!pszSrc)
else if (!pszDst)
else
break;
default:
if (c > 0)
{
if (RT_C_IS_GRAPH(c))
else
}
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
else if (ValueUnion.pDef)
else
}
}
if (!pszSrc)
if (!pszDst)
bool fSrcUnknown = false;
bool fDstUnknown = false;
false /* fForceNewUuidOnOpen */, &fSrcUnknown);
return 1;
do
{
if (fExisting)
{
false /* fForceNewUuidOnOpen */, &fDstUnknown);
break;
/* Perform accessibility check now. */
}
else
{
/* use the format of the source hard disk if unspecified */
break;
}
RTPrintf("Clone hard disk created in format '%ls'. UUID: %s\n",
}
while (0);
{
/* forget the created clone */
}
if (fSrcUnknown)
{
/* close the unknown hard disk to forget it again */
}
}
static const RTGETOPTDEF g_aConvertFromRawHardDiskOptions[] =
{
};
{
int rc = VINF_SUCCESS;
bool fReadFromStdIn = false;
const char *format = "VDI";
const char *srcfilename = NULL;
const char *dstfilename = NULL;
unsigned uImageFlags = VD_IMAGE_FLAGS_NONE;
int c;
// start at 0 because main() has hacked both the argc and argv given to us
RTGetOptInit(&GetState, argc, argv, g_aConvertFromRawHardDiskOptions, RT_ELEMENTS(g_aConvertFromRawHardDiskOptions),
{
switch (c)
{
case 'u': // --uuid
break;
case 'o': // --format
break;
case 'm': // --variant
if (RT_FAILURE(rc))
/// @todo cleaner solution than assuming 1:1 mapping?
uImageFlags = (unsigned)DiskVariant;
break;
case VINF_GETOPT_NOT_OPTION:
if (!srcfilename)
{
// If you change the OS list here don't forget to update VBoxManageHelp.cpp.
#ifndef RT_OS_WINDOWS
#endif
}
else if (!dstfilename)
else if (fReadFromStdIn && !filesize)
else
break;
default:
}
}
/* open raw image file. */
if (fReadFromStdIn)
File = 0;
else
if (RT_FAILURE(rc))
{
goto out;
}
/* get image size. */
if (fReadFromStdIn)
else
if (RT_FAILURE(rc))
{
goto out;
}
char pszComment[256];
if (RT_FAILURE(rc))
{
goto out;
}
LCHS.cCylinders = 0;
if (RT_FAILURE(rc))
{
goto out;
}
if (!pvBuf)
{
rc = VERR_NO_MEMORY;
goto out;
}
offFile = 0;
{
cbRead = 0;
break;
if (RT_FAILURE(rc))
{
goto out;
}
}
out:
if (pvBuf)
if (pDisk)
if (File != NIL_RTFILE)
}
static const RTGETOPTDEF g_aShowHardDiskInfoOptions[] =
{
};
int handleShowHardDiskInfo(HandlerArg *a)
{
const char *FilenameOrUuid = NULL;
int c;
// start at 0 because main() has hacked both the argc and argv given to us
RTGetOptInit(&GetState, a->argc, a->argv, g_aShowHardDiskInfoOptions, RT_ELEMENTS(g_aShowHardDiskInfoOptions),
{
switch (c)
{
case VINF_GETOPT_NOT_OPTION:
if (!FilenameOrUuid)
else
break;
default:
if (c > 0)
{
if (RT_C_IS_PRINT(c))
else
}
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
else if (ValueUnion.pDef)
else
}
}
/* check for required options */
if (!FilenameOrUuid)
bool unknown = false;
false /* fForceNewUuidOnOpen */, &unknown);
return 1;
do
{
/* check for accessibility */
/// @todo NEWMEDIA check accessibility of all parents
/// @todo NEWMEDIA print the full state value
if (state == MediumState_Inaccessible)
{
}
if (!description.isEmpty())
{
}
const char *typeStr = "unknown";
switch (type)
{
case MediumType_Normal:
typeStr = "normal (differencing)";
else
typeStr = "normal (base)";
break;
case MediumType_Immutable:
typeStr = "immutable";
break;
case MediumType_Writethrough:
typeStr = "writethrough";
break;
case MediumType_Shareable:
typeStr = "shareable";
break;
case MediumType_Readonly:
typeStr = "readonly";
break;
case MediumType_MultiAttach:
typeStr = "multiattach";
break;
}
const char *variantStr = "unknown";
{
variantStr = "split2G";
break;
variantStr = "streamOptimized";
break;
case MediumVariant_VmdkESX:
variantStr = "ESX";
break;
case MediumVariant_Standard:
variantStr = "default";
break;
}
const char *variantTypeStr = "dynamic";
if (variant & MediumVariant_Fixed)
variantTypeStr = "fixed";
else if (variant & MediumVariant_Diff)
variantTypeStr = "differencing";
/// @todo also dump config parameters (iSCSI)
if (!unknown)
{
{
RTPrintf("%s%lS (UUID: %lS)\n",
j == 0 ? "In use by VMs: " : " ",
}
/// @todo NEWMEDIA check usage in snapshots too
/// @todo NEWMEDIA also list children
}
/* print out information specific for differencing hard disks */
{
}
}
while (0);
if (unknown)
{
/* close the unknown hard disk to forget it again */
}
}
static const RTGETOPTDEF g_aCloseMediumOptions[] =
{
};
int handleCloseMedium(HandlerArg *a)
{
enum {
const char *FilenameOrUuid = NULL;
bool fDelete = false;
int c;
// start at 0 because main() has hacked both the argc and argv given to us
RTGetOptInit(&GetState, a->argc, a->argv, g_aCloseMediumOptions, RT_ELEMENTS(g_aCloseMediumOptions),
{
switch (c)
{
case 'd': // disk
break;
case 'D': // DVD
break;
case 'f': // floppy
cmd = CMD_FLOPPY;
break;
case 'r': // --delete
fDelete = true;
break;
case VINF_GETOPT_NOT_OPTION:
if (!FilenameOrUuid)
else
break;
default:
if (c > 0)
{
if (RT_C_IS_PRINT(c))
else
}
else if (c == VERR_GETOPT_UNKNOWN_OPTION)
else if (ValueUnion.pDef)
else
}
}
/* check for required options */
if (!FilenameOrUuid)
else if (cmd == CMD_FLOPPY)
{
if (fDelete)
{
{
}
else
}
}
}
#endif /* !VBOX_ONLY_DOCS */