VBoxManageDisk.cpp revision aeb9498c4d9854ed42b271541d34c7bad97b4c77
/* $Id$ */
/** @file
* VBoxManage - The disk related commands.
*/
/*
* Copyright (C) 2006-2010 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;
}
static const RTGETOPTDEF g_aCreateHardDiskOptions[] =
{
};
int handleCreateHardDisk(HandlerArg *a)
{
int vrc;
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 */
|| size == 0)
/* check for filename extension */
{
else
}
hardDisk.asOutParam()));
{
{
{
if (info.isBasicAvailable())
else
RTMsgError("Failed to create hard disk. No error message available!");
}
else
{
}
}
}
}
static const RTGETOPTDEF g_aModifyHardDiskOptions[] =
{
};
int handleModifyHardDisk(HandlerArg *a)
{
int vrc;
bool AutoReset = false;
bool fModifyResize = false;
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_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 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)
/* first guess is that it's a UUID */
hardDisk.asOutParam()));
return 1;
if (fModifyDiskType)
{
/* hard disk must be registered */
{
}
else
return errorArgument("Hard disk image not registered");
}
if (fModifyAutoReset)
{
}
if (fModifyCompact)
{
bool unknown = false;
/* the hard disk image might not be registered */
if (!hardDisk)
{
unknown = true;
hardDisk.asOutParam());
if (rc == VBOX_E_FILE_ERROR)
{
if (RT_FAILURE(irc))
{
return 1;
}
hardDisk.asOutParam()));
}
}
{
{
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 (unknown)
}
}
if (fModifyResize)
{
bool unknown = false;
/* the hard disk image might not be registered */
if (!hardDisk)
{
unknown = true;
hardDisk.asOutParam());
if (rc == VBOX_E_FILE_ERROR)
{
if (RT_FAILURE(irc))
{
return 1;
}
hardDisk.asOutParam()));
}
}
{
{
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;
bool fRemember = false;
bool fSetDiskType = 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 'r': // --remember
fRemember = true;
break;
case 't': // --type
if (RT_FAILURE(vrc))
fSetDiskType = true;
break;
case VINF_GETOPT_NOT_OPTION:
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
}
}
bool fSrcUnknown = false;
bool fDstUnknown = false;
srcDisk.asOutParam());
/* no? well, then it's an unknown image */
{
srcDisk.asOutParam());
if (rc == VBOX_E_FILE_ERROR)
{
if (RT_FAILURE(irc))
{
return 1;
}
srcDisk.asOutParam()));
}
fSrcUnknown = true;
else
{
return 1;
}
}
do
{
if (fExisting)
{
dstDisk.asOutParam());
/* no? well, then it's an unknown image */
{
dstDisk.asOutParam());
if (rc == VBOX_E_FILE_ERROR)
{
if (RT_FAILURE(irc))
{
return 1;
}
dstDisk.asOutParam()));
}
fDstUnknown = true;
else
{
break;
}
}
else
fRemember = true;
{
/* Perform accessibility check now. */
}
}
else
{
/* use the format of the source hard disk if unspecified */
dstDisk.asOutParam()));
}
{
if (info.isBasicAvailable())
else
RTMsgError("Failed to clone hard disk. No error message available!");
break;
}
RTPrintf("Clone hard disk created in format '%ls'. UUID: %s\n",
}
while (0);
{
/* forget the created clone */
}
else if (fSetDiskType)
{
}
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 '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;
/* first guess is that it's a UUID */
hardDisk.asOutParam());
/* no? well, then it's an unknown image */
{
hardDisk.asOutParam());
if (rc == VBOX_E_FILE_ERROR)
{
if (RT_FAILURE(vrc))
{
return 1;
}
hardDisk.asOutParam()));
}
unknown = true;
else
{
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;
}
/// @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)
medium.asOutParam()));
medium.asOutParam()));
else if (cmd == CMD_FLOPPY)
medium.asOutParam()));
{
if (fDelete)
{
{
{
if (info.isBasicAvailable())
else
RTMsgError("Failed to delete medium. No error message available!");
}
}
else
}
}
}
#endif /* !VBOX_ONLY_DOCS */