VBoxManageSnapshot.cpp revision dfd1cc060e48ca92057e20f7966ef0a65ab27bb9
/* $Id$ */
/** @file
* VBoxManage - The 'snapshot' command.
*/
/*
* Copyright (C) 2006-2014 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.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "VBoxManage.h"
using namespace com;
/**
* Helper function used with "VBoxManage snapshot ... dump". Gets called to find the
* snapshot in the machine's snapshot tree that uses a particular diff image child of
* a medium.
* Horribly inefficient since we keep re-querying the snapshots tree for each image,
* but this is for quick debugging only.
* @param pMedium
* @param pThisSnapshot
* @param pCurrentSnapshot
* @param uMediumLevel
* @param uSnapshotLevel
* @return
*/
{
do
{
// get snapshot machine so we can figure out which diff image this created
// get media attachments
CHECK_ERROR_BREAK(pSnapshotMachine, COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(aAttachments)));
for (uint32_t i = 0;
i < aAttachments.size();
++i)
{
if (type == DeviceType_HardDisk)
{
if (pMediumInSnapshot == pMedium)
{
// get snapshot name
RTPrintf("%*s \"%ls\"%s\n",
return true; // found
}
}
}
// not found: then recurse into child snapshots
for (uint32_t i = 0;
i < aSnapshots.size();
++i)
{
uSnapshotLevel + 1))
// found:
break;
}
} while (0);
return false;
}
/**
* Helper function used with "VBoxManage snapshot ... dump". Called from DumpSnapshot()
* for each hard disk attachment found in a virtual machine. This then writes out the
* root (base) medium for that hard disk attachment and recurses into the children
* tree of that medium, correlating it with the snapshots of the machine.
* @param pCurrentStateMedium constant, the medium listed in the current machine data (latest diff image).
* @param pMedium variant, initially the base medium, then a child of the base medium when recursing.
* @param pRootSnapshot constant, the root snapshot of the machine, if any; this then looks into the child snapshots.
* @param pCurrentSnapshot constant, the machine's current snapshot (so we can mark it in the output).
* @param uLevel variant, the recursion level for output indentation.
*/
{
do
{
// print this medium
RTPrintf("%*s \"%ls\"%s\n",
// find and print the snapshot that uses this particular medium (diff image)
// recurse into children
for (uint32_t i = 0;
++i)
{
}
} while (0);
}
/**
* Handles the 'snapshot myvm list' sub-command.
* @returns Exit code.
* @param pArgs The handler argument package.
* @param pMachine Reference to the VM (locked) we're operating on.
*/
{
static const RTGETOPTDEF g_aOptions[] =
{
};
int c;
RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, g_aOptions, RT_ELEMENTS(g_aOptions), 2 /*iArg*/, 0 /*fFlags*/);
{
switch (c)
{
}
}
{
RTPrintf("This machine does not have any snapshots\n");
return RTEXITCODE_FAILURE;
}
if (pSnapshot)
{
CHECK_ERROR2_RET(pMachine, COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam()), RTEXITCODE_FAILURE);
return RTEXITCODE_FAILURE;
}
return RTEXITCODE_SUCCESS;
}
/**
* Implementation for "VBoxManage snapshot ... dump". This goes thru the machine's
* medium attachments and calls DumpMediumWithChildren() for each hard disk medium found,
* snapshots.
* @param pMachine Machine to dump snapshots for.
*/
{
do
{
// get root snapshot
// get current snapshot
// get media attachments
for (uint32_t i = 0;
i < aAttachments.size();
++i)
{
if (type == DeviceType_HardDisk)
{
0);
}
}
} while (0);
}
/**
* Implementation for all VBoxManage snapshot ... subcommands.
* @param a
* @return
*/
int handleSnapshot(HandlerArg *a)
{
/* we need at least a VM and a command */
if (a->argc < 2)
/* the first argument must be the VM */
pMachine.asOutParam()));
if (!pMachine)
return 1;
/* we have to open a session for this task (new or shared) */
do
{
/* replace the (read-only) IMachine object by a writable one */
/* switch based on the command */
bool fDelete = false,
fRestore = false,
fRestoreCurrent = false;
{
/* there must be a name */
if (a->argc < 3)
{
break;
}
/* parse the optional arguments */
bool fPause = true; /* default is NO live snapshot */
static const RTGETOPTDEF s_aTakeOptions[] =
{
};
int ch;
{
switch (ch)
{
case 'p':
fPause = true;
break;
case 'l':
fPause = false;
break;
case 'd':
break;
default:
break;
}
}
break;
progress.asOutParam()));
}
)
{
if (fRestoreCurrent)
{
if (a->argc > 2)
{
break;
}
}
/* exactly one parameter: snapshot name */
else if (a->argc != 3)
{
break;
}
if (fRestoreCurrent)
{
}
else
{
// restore or delete snapshot: then resolve cmd line argument to snapshot instance
pSnapshot.asOutParam()));
}
if (fDelete)
{
pProgress.asOutParam()));
}
else
{
// restore or restore current
}
}
{
if (a->argc < 3)
{
break;
}
{
}
else
{
pSnapshot.asOutParam()));
}
/* parse options */
for (int i = 3; i < a->argc; i++)
{
{
if (a->argc <= i + 1)
{
break;
}
i++;
}
{
if (a->argc <= i + 1)
{
break;
}
i++;
}
else
{
break;
}
}
}
{
/* exactly one parameter: snapshot name */
if (a->argc != 3)
{
break;
}
pSnapshot.asOutParam()));
/* get the machine of the given snapshot */
}
else
{
}
} while (0);
a->session->UnlockMachine();
}