VBoxManageDisk.cpp revision 2ffaf4dbec17570ea5bde49e506cd4a77529e10f
199767f8919635c4928607450d9e0abb932109ceToomas Soome * VBoxManage - The disk delated commands.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (C) 2006-2008 Sun Microsystems, Inc.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This file is part of VirtualBox Open Source Edition (OSE), as
199767f8919635c4928607450d9e0abb932109ceToomas Soome * available from http://www.virtualbox.org. This file is free software;
199767f8919635c4928607450d9e0abb932109ceToomas Soome * you can redistribute it and/or modify it under the terms of the GNU
199767f8919635c4928607450d9e0abb932109ceToomas Soome * General Public License (GPL) as published by the Free Software
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Foundation, in version 2 as it comes in the "COPYING" file of the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Clara, CA 95054 USA or visit http://www.sun.com if you need
199767f8919635c4928607450d9e0abb932109ceToomas Soome * additional information or have any questions.
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*******************************************************************************
199767f8919635c4928607450d9e0abb932109ceToomas Soome* Header Files *
199767f8919635c4928607450d9e0abb932109ceToomas Soome*******************************************************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soomeusing namespace com;
199767f8919635c4928607450d9e0abb932109ceToomas Soome///////////////////////////////////////////////////////////////////////////////
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTPrintf("Error code %Rrc at %s(%u) in function %s\n", rc, RT_SRC_POS_ARGS);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int parseDiskVariant(const char *psz, HardDiskVariant_T *pDiskVariant)
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned DiskVariant = (unsigned)(*pDiskVariant);
199767f8919635c4928607450d9e0abb932109ceToomas Soome // Parsing is intentionally inconsistent: "standard" resets the
199767f8919635c4928607450d9e0abb932109ceToomas Soome // variant, whereas the other flags are cumulative.
199767f8919635c4928607450d9e0abb932109ceToomas Soome DiskVariant |= HardDiskVariant_VmdkStreamOptimized;
199767f8919635c4928607450d9e0abb932109ceToomas Soome *pDiskVariant = (HardDiskVariant_T)DiskVariant;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int parseDiskType(const char *psz, HardDiskType_T *pDiskType)
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic const RTGETOPTDEF g_aCreateHardDiskOptions[] =
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-filename", 'f', RTGETOPT_REQ_STRING }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-size", 's', RTGETOPT_REQ_UINT64 }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-format", 'o', RTGETOPT_REQ_STRING }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-static", 'F', RTGETOPT_REQ_NOTHING }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-variant", 'm', RTGETOPT_REQ_STRING }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-type", 't', RTGETOPT_REQ_STRING }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-comment", 'c', RTGETOPT_REQ_STRING }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-remember", 'r', RTGETOPT_REQ_NOTHING }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "--register", 'r', RTGETOPT_REQ_NOTHING }, // deprecated (inofficial)
199767f8919635c4928607450d9e0abb932109ceToomas Soome { "-register", 'r', RTGETOPT_REQ_NOTHING }, // deprecated
199767f8919635c4928607450d9e0abb932109ceToomas Soome HardDiskVariant_T DiskVariant = HardDiskVariant_Standard;
199767f8919635c4928607450d9e0abb932109ceToomas Soome // start at 0 because main() has hacked both the argc and argv given to us
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTGetOptInit(&GetState, a->argc, a->argv, g_aCreateHardDiskOptions, RT_ELEMENTS(g_aCreateHardDiskOptions), 0, 0 /* fFlags */);
199767f8919635c4928607450d9e0abb932109ceToomas Soome rc = parseDiskVariant(ValueUnion.psz, &DiskVariant);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Invalid hard disk variant '%s'", ValueUnion.psz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome || (DiskType != HardDiskType_Normal && DiskType != HardDiskType_Writethrough))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CREATEHD, "Invalid parameter '%s'", ValueUnion.psz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CREATEHD, "Invalid option -%c", c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CREATEHD, "Invalid option case %i", c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CREATEHD, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CREATEHD, "error: %Rrs", c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check the outcome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CREATEHD, "Parameters -filename and -size are required");
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(a->virtualBox, CreateHardDisk(format, filename, hardDisk.asOutParam()));
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* we will close the hard disk after the storage has been successfully
199767f8919635c4928607450d9e0abb932109ceToomas Soome * created unless fRemember is set */
199767f8919635c4928607450d9e0abb932109ceToomas Soome bool doClose = false;
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk,COMSETTER(Description)(comment));
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, CreateBaseStorage(sizeMB, DiskVariant, progress.asOutParam()));
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTPrintf("Error: failed to create hard disk. Error message: %lS\n", info.getText().raw());
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTPrintf("Error: failed to create hard disk. No error message available!\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam()));
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTPrintf("Disk image created. UUID: %s\n", uuid.toString().raw());
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if 0 /* disabled until disk shrinking is implemented based on VBoxHDD */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic DECLCALLBACK(int) hardDiskProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* The uuid/filename and a command */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_MODIFYHD, "Incorrect number of parameters");
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* first guess is that it's a UUID */
199767f8919635c4928607450d9e0abb932109ceToomas Soome rc = a->virtualBox->GetHardDisk(uuid, hardDisk.asOutParam());
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* no? then it must be a filename */
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(a->virtualBox, FindHardDisk(filepath, hardDisk.asOutParam()));
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* let's find out which command */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* hard disk must be registered */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Missing argument for settype");
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Hard disk image not registered");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Missing argument for autoreset");
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, COMSETTER(AutoReset)(TRUE));
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(hardDisk, COMSETTER(AutoReset)(FALSE));
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Invalid autoreset argument '%s' specified",
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTPrintf("Error: Shrink hard disk operation is not implemented!\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* the hard disk image might not be registered */
199767f8919635c4928607450d9e0abb932109ceToomas Soome a->virtualBox->OpenHardDisk(Bstr(a->argv[0]), AccessMode_ReadWrite, hardDisk.asOutParam());
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Hard disk image not found");
199767f8919635c4928607450d9e0abb932109ceToomas Soome hardDisk->COMGETTER(Format)(format.asOutParam());
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Invalid hard disk type. The command only works on VDI files\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome hardDisk->COMGETTER(Location)(fileName.asOutParam());
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* make sure the object reference is released */
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTPrintf("Shrinking '%lS': 0%%", fileName.raw());
199767f8919635c4928607450d9e0abb932109ceToomas Soome int vrc = VDIShrinkImage(Utf8Str(fileName).raw(), hardDiskProgressCallback, &uProcent);
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTPrintf("Error while shrinking hard disk image: %Rrc\n", vrc);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_MODIFYHD, "Invalid parameter '%s'", Utf8Str(a->argv[1]).raw());
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic const RTGETOPTDEF g_aCloneHardDiskOptions[] =
199767f8919635c4928607450d9e0abb932109ceToomas Soome HardDiskVariant_T DiskVariant = HardDiskVariant_Standard;
199767f8919635c4928607450d9e0abb932109ceToomas Soome // start at 0 because main() has hacked both the argc and argv given to us
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTGetOptInit(&GetState, a->argc, a->argv, g_aCloneHardDiskOptions, RT_ELEMENTS(g_aCloneHardDiskOptions), 0, 0 /* fFlags */);
199767f8919635c4928607450d9e0abb932109ceToomas Soome rc = parseDiskVariant(ValueUnion.psz, &DiskVariant);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Invalid hard disk variant '%s'", ValueUnion.psz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CLONEHD, "Invalid parameter '%s'", ValueUnion.psz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CLONEHD, "unhandled option: -%c", c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CLONEHD, "unhandled option: %i", c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CLONEHD, "unknown option: %s", ValueUnion.psz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CLONEHD, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CLONEHD, "error: %Rrs", c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CLONEHD, "Mandatory UUID or input file parameter missing");
199767f8919635c4928607450d9e0abb932109ceToomas Soome return errorSyntax(USAGE_CLONEHD, "Mandatory output file parameter missing");
199767f8919635c4928607450d9e0abb932109ceToomas Soome bool unknown = false;
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* first guess is that it's a UUID */
199767f8919635c4928607450d9e0abb932109ceToomas Soome rc = a->virtualBox->GetHardDisk(uuid, srcDisk.asOutParam());
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* no? then it must be a filename */
199767f8919635c4928607450d9e0abb932109ceToomas Soome rc = a->virtualBox->FindHardDisk(src, srcDisk.asOutParam());
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* no? well, then it's an unkwnown image */
199767f8919635c4928607450d9e0abb932109ceToomas Soome CHECK_ERROR(a->virtualBox, OpenHardDisk(src, AccessMode_ReadWrite, srcDisk.asOutParam()));
if (unknown)
bool fReadFromStdIn = false;
RTGetOptInit(&GetState, argc, argv, g_aConvertFromRawHardDiskOptions, RT_ELEMENTS(g_aConvertFromRawHardDiskOptions), 0, 0 /* fFlags */);
case VINF_GETOPT_NOT_OPTION:
if (!srcfilename)
else if (!dstfilename)
if (RT_C_IS_PRINT(c))
if (fReadFromStdIn)
File = 0;
goto out;
if (fReadFromStdIn)
goto out;
RTPrintf("Creating %s image with size %RU64 bytes (%RU64MB)...\n", (uImageFlags & VD_IMAGE_FLAGS_FIXED) ? "fixed" : "dynamic", cbFile, (cbFile + _1M - 1) / _1M);
goto out;
goto out;
if (!pvBuf)
goto out;
offFile = 0;
cbRead = 0;
goto out;
out:
if (pvBuf)
if (pDisk)
bool fIntNet = false;
for (int i = 0; i < a->argc; i++)
fIntNet = true;
if (fIntNet)
bool unknown = false;
unknown = true;
if (description)
switch (type)
case HardDiskType_Normal:
case HardDiskType_Immutable:
if (!unknown)
if (unknown)
if (type)
if (!hardDisk)
if (!dvdImage)
if (!floppyImage)