VirtualBox

Changeset 55977 in vbox for trunk/src


Ignore:
Timestamp:
May 20, 2015 4:52:25 PM (10 years ago)
Author:
vboxsync
Message:

Main/Snapshot: add a parameter to IMachine.takeSnapshot, returning the snapshot UUID, which is useful for finding the snapshot reliably (using the non-unique name is error prone), plus the necessary code adaptions everywhere.
Frontends/VBoxManage: add a feature for creating unique snapshot names (by appending a number or timestamp).

Location:
trunk/src/VBox
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r55923 r55977  
    519519        RTStrmPrintf(pStrm,
    520520                           "%s snapshot %s        <uuid|vmname>\n"
    521                      "                            take <name> [--description <desc>] [--live] |\n"
     521                     "                            take <name> [--description <desc>] [--live]\n"
     522                     "                                 [--uniquename Number,Timestamp,Space,Force] |\n"
    522523                     "                            delete <uuid|snapname> |\n"
    523524                     "                            restore <uuid|snapname> |\n"
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageSnapshot.cpp

    r55234 r55977  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2929#include <iprt/stream.h>
    3030#include <iprt/getopt.h>
     31#include <iprt/time.h>
    3132
    3233#include "VBoxManage.h"
     
    260261}
    261262
     263typedef enum SnapshotUniqueFlags
     264{
     265    SnapshotUniqueFlags_Null = 0,
     266    SnapshotUniqueFlags_Number = RT_BIT(1),
     267    SnapshotUniqueFlags_Timestamp = RT_BIT(2),
     268    SnapshotUniqueFlags_Space = RT_BIT(16),
     269    SnapshotUniqueFlags_Force = RT_BIT(30)
     270} SnapshotUniqueFlags;
     271
     272static int parseSnapshotUniqueFlags(const char *psz, SnapshotUniqueFlags *pUnique)
     273{
     274    int rc = VINF_SUCCESS;
     275    unsigned uUnique = 0;
     276    while (psz && *psz && RT_SUCCESS(rc))
     277    {
     278        size_t len;
     279        const char *pszComma = strchr(psz, ',');
     280        if (pszComma)
     281            len = pszComma - psz;
     282        else
     283            len = strlen(psz);
     284        if (len > 0)
     285        {
     286            if (!RTStrNICmp(psz, "number", len))
     287                uUnique |= SnapshotUniqueFlags_Number;
     288            else if (!RTStrNICmp(psz, "timestamp", len))
     289                uUnique |= SnapshotUniqueFlags_Timestamp;
     290            else if (!RTStrNICmp(psz, "space", len))
     291                uUnique |= SnapshotUniqueFlags_Space;
     292            else if (!RTStrNICmp(psz, "force", len))
     293                uUnique |= SnapshotUniqueFlags_Force;
     294            else
     295                rc = VERR_PARSE_ERROR;
     296        }
     297        if (pszComma)
     298            psz += len + 1;
     299        else
     300            psz += len;
     301    }
     302
     303    if (RT_SUCCESS(rc))
     304        *pUnique = (SnapshotUniqueFlags)uUnique;
     305    return rc;
     306}
     307
    262308/**
    263309 * Implementation for all VBoxManage snapshot ... subcommands.
     
    308354            Bstr desc;
    309355            bool fPause = true; /* default is NO live snapshot */
     356            SnapshotUniqueFlags enmUnique = SnapshotUniqueFlags_Null;
    310357            static const RTGETOPTDEF s_aTakeOptions[] =
    311358            {
     
    314361                { "-desc",         'd', RTGETOPT_REQ_STRING },
    315362                { "--pause",       'p', RTGETOPT_REQ_NOTHING },
    316                 { "--live",        'l', RTGETOPT_REQ_NOTHING }
     363                { "--live",        'l', RTGETOPT_REQ_NOTHING },
     364                { "--uniquename",  'u', RTGETOPT_REQ_STRING }
    317365            };
    318366            RTGETOPTSTATE GetOptState;
     
    321369            int ch;
    322370            RTGETOPTUNION Value;
     371            int vrc;
    323372            while (   SUCCEEDED(rc)
    324373                   && (ch = RTGetOpt(&GetOptState, &Value)))
     
    338387                        break;
    339388
     389                    case 'u':
     390                        vrc = parseSnapshotUniqueFlags(Value.psz, &enmUnique);
     391                        if (RT_FAILURE(vrc))
     392                            return errorArgument("Invalid unique name description '%s'", Value.psz);
     393                        break;
     394
    340395                    default:
    341396                        errorGetOpt(USAGE_SNAPSHOT, ch, &Value);
     
    347402                break;
    348403
     404            if (enmUnique & (SnapshotUniqueFlags_Number | SnapshotUniqueFlags_Timestamp))
     405            {
     406                ComPtr<ISnapshot> pSnapshot;
     407                rc = sessionMachine->FindSnapshot(name.raw(),
     408                                                  pSnapshot.asOutParam());
     409                if (SUCCEEDED(rc) || (enmUnique & SnapshotUniqueFlags_Force))
     410                {
     411                    /* there is a duplicate, need to create a unique name */
     412                    uint32_t count = 0;
     413                    RTTIMESPEC now;
     414
     415                    if (enmUnique & SnapshotUniqueFlags_Number)
     416                    {
     417                        if (enmUnique & SnapshotUniqueFlags_Force)
     418                            count = 1;
     419                        else
     420                            count = 2;
     421                    }
     422                    else
     423                        RTTimeNow(&now);
     424
     425                    while (count < 500)
     426                    {
     427                        Utf8Str suffix;
     428                        if (enmUnique & SnapshotUniqueFlags_Number)
     429                            suffix = Utf8StrFmt("%u", count);
     430                        else
     431                        {
     432                            RTTIMESPEC nowplus = now;
     433                            RTTimeSpecAddSeconds(&nowplus, count);
     434                            RTTIME stamp;
     435                            RTTimeExplode(&stamp, &nowplus);
     436                            suffix = Utf8StrFmt("%04u-%02u-%02uT%02u:%02u:%02uZ", stamp.i32Year, stamp.u8Month, stamp.u8MonthDay, stamp.u8Hour, stamp.u8Minute, stamp.u8Second);
     437                        }
     438                        Bstr tryName = name;
     439                        if (enmUnique & SnapshotUniqueFlags_Space)
     440                            tryName = BstrFmt("%ls %s", name.raw(), suffix.c_str());
     441                        else
     442                            tryName = BstrFmt("%ls%s", name.raw(), suffix.c_str());
     443                        count++;
     444                        rc = sessionMachine->FindSnapshot(tryName.raw(),
     445                                                          pSnapshot.asOutParam());
     446                        if (FAILED(rc))
     447                        {
     448                            name = tryName;
     449                            break;
     450                        }
     451                    }
     452                    if (SUCCEEDED(rc))
     453                    {
     454                        errorArgument("Failed to generate a unique snapshot name");
     455                        rc = E_FAIL;
     456                        break;
     457                    }
     458                }
     459                rc = S_OK;
     460            }
     461
    349462            ComPtr<IProgress> progress;
     463            Bstr snapId;
    350464            CHECK_ERROR_BREAK(sessionMachine, TakeSnapshot(name.raw(), desc.raw(),
    351                                                            fPause,
     465                                                           fPause, snapId.asOutParam(),
    352466                                                           progress.asOutParam()));
    353467
    354468            rc = showProgress(progress);
    355             CHECK_PROGRESS_ERROR(progress, ("Failed to take snapshot"));
     469            if (SUCCEEDED(rc))
     470                RTPrintf("Snapshot taken. UUID: %ls\n", snapId.raw());
     471            else
     472                CHECK_PROGRESS_ERROR(progress, ("Failed to take snapshot"));
    356473        }
    357474        else if (    (fDelete = !strcmp(a->argv[1], "delete"))
     
    389506                // restore or delete snapshot: then resolve cmd line argument to snapshot instance
    390507                CHECK_ERROR_BREAK(sessionMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
    391                                                          pSnapshot.asOutParam()));
     508                                                               pSnapshot.asOutParam()));
    392509            }
    393510
     
    397514            {
    398515                CHECK_ERROR_BREAK(sessionMachine, DeleteSnapshot(bstrSnapGuid.raw(),
    399                                                            pProgress.asOutParam()));
     516                                                                 pProgress.asOutParam()));
    400517            }
    401518            else
     
    428545            {
    429546                CHECK_ERROR_BREAK(sessionMachine, FindSnapshot(Bstr(a->argv[2]).raw(),
    430                                                          pSnapshot.asOutParam()));
     547                                                               pSnapshot.asOutParam()));
    431548            }
    432549
  • trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp

    r55800 r55977  
    49584958            gpProgress = NULL;
    49594959            HRESULT rc;
     4960            Bstr snapId;
    49604961            CHECK_ERROR(gpMachine, TakeSnapshot(Bstr(pszSnapshotName).raw(),
    49614962                                                Bstr("Taken by VBoxSDL").raw(),
    4962                                                 TRUE,
     4963                                                TRUE, snapId.asOutParam(),
    49634964                                                gpProgress.asOutParam()));
    49644965            if (FAILED(rc))
  • trunk/src/VBox/Frontends/VBoxShell/vboxshell.py

    r55214 r55977  
    26352635        else:
    26362636            desc = ""
    2637         cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, mach.takeSnapshot(name, desc, true)))
     2637        cmdAnyVm(ctx, mach, lambda ctx, mach, console, args: progressBar(ctx, mach.takeSnapshot(name, desc, true)[-1]))
    26382638        return 0
    26392639
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp

    r55750 r55977  
    55
    66/*
    7  * Copyright (C) 2010-2014 Oracle Corporation
     7 * Copyright (C) 2010-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    14241424    if (fDialogAccepted)
    14251425    {
     1426        QString strSnapshotId;
    14261427        /* Prepare the take-snapshot progress: */
    1427         CProgress progress = machine().TakeSnapshot(strSnapshotName, strSnapshotDescription, true);
     1428        CProgress progress = machine().TakeSnapshot(strSnapshotName, strSnapshotDescription, true, strSnapshotId);
    14281429        if (machine().isOk())
    14291430        {
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp

    r55934 r55977  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    889889            if (fDialogAccepted)
    890890            {
     891                QString strSnapshotId;
    891892                /* Prepare the take-snapshot progress: */
    892                 CProgress progress = machine.TakeSnapshot(strSnapshotName, strSnapshotDescription, true);
     893                CProgress progress = machine.TakeSnapshot(strSnapshotName, strSnapshotDescription, true, strSnapshotId);
    893894                if (machine.isOk())
    894895                {
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVM.cpp

    r55214 r55977  
    55
    66/*
    7  * Copyright (C) 2011-2014 Oracle Corporation
     7 * Copyright (C) 2011-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    8484        /* Take the snapshot: */
    8585        QString strSnapshotName = tr("Linked Base for %1 and %2").arg(m_machine.GetName()).arg(strName);
    86         CProgress progress = machine.TakeSnapshot(strSnapshotName, "", true);
     86        QString strSnapshotId;
     87        CProgress progress = machine.TakeSnapshot(strSnapshotName, "", true, strSnapshotId);
    8788
    8889        if (machine.isOk())
     
    107108
    108109        /* Get the new snapshot and the snapshot machine. */
    109         const CSnapshot &newSnapshot = m_machine.FindSnapshot(strSnapshotName);
     110        const CSnapshot &newSnapshot = m_machine.FindSnapshot(strSnapshotId);
    110111        if (newSnapshot.isNull())
    111112        {
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r55885 r55977  
    41704170  <interface
    41714171    name="IMachine" extends="$unknown"
    4172     uuid="feb138aa-dbce-4a89-8ec0-380fc7ec4913"
     4172    uuid="520a0c22-8dbc-458d-b637-31eb078b5526"
    41734173    wsmap="managed"
    41744174    wrap-hint-server-addinterfaces="IInternalMachineControl"
     
    73927392          (@c true) and live (@c false) snapshots. When the VM is not running
    73937393          the result is always an offline snapshot.</desc>
     7394      </param>
     7395      <param name="id" type="uuid" mod="string" dir="out">
     7396        <desc>UUID of the snapshot which will be created. Useful for follow-up
     7397        operations after the snapshot has been created.</desc>
    73947398      </param>
    73957399      <param name="progress" type="IProgress" dir="return">
  • trunk/src/VBox/Main/include/MachineImpl.h

    r55854 r55977  
    11931193                         const com::Utf8Str &aDescription,
    11941194                         BOOL aPause,
     1195                         com::Guid &aId,
    11951196                         ComPtr<IProgress> &aProgress);
    11961197    HRESULT deleteSnapshot(const com::Guid &aId,
     
    14391440                         const com::Utf8Str &aDescription,
    14401441                         BOOL aPause,
     1442                         com::Guid &aId,
    14411443                         ComPtr<IProgress> &aProgress);
    14421444    HRESULT deleteSnapshot(const com::Guid &aId,
  • trunk/src/VBox/Main/src-server/SnapshotImpl.cpp

    r55749 r55977  
    13321332                     const Utf8Str &strName,
    13331333                     const Utf8Str &strDescription,
     1334                     const Guid &uuidSnapshot,
    13341335                     bool fPause,
    13351336                     uint32_t uMemSize,
     
    13381339          m_strName(strName),
    13391340          m_strDescription(strDescription),
     1341          m_uuidSnapshot(uuidSnapshot),
    13401342          m_fPause(fPause),
    13411343          m_uMemSize(uMemSize),
     
    13571359    Utf8Str m_strName;
    13581360    Utf8Str m_strDescription;
     1361    Guid m_uuidSnapshot;
    13591362    Utf8Str m_strStateFilePath;
    13601363    ComPtr<IInternalSessionControl> m_pDirectControl;
     
    14121415                              const com::Utf8Str &aDescription,
    14131416                              BOOL fPause,
     1417                              com::Guid &aId,
    14141418                              ComPtr<IProgress> &aProgress)
    14151419{
     
    14171421    NOREF(aDescription);
    14181422    NOREF(fPause);
     1423    NOREF(aId);
    14191424    NOREF(aProgress);
    14201425    ReturnComNotImplemented();
     
    14241429                                     const com::Utf8Str &aDescription,
    14251430                                     BOOL fPause,
     1431                                     com::Guid &aId,
    14261432                                     ComPtr<IProgress> &aProgress)
    14271433{
     
    14821488        return rc;
    14831489
     1490    /* create an ID for the snapshot */
     1491    Guid snapshotId;
     1492    snapshotId.create();
     1493
    14841494    /* create and start the task on a separate thread (note that it will not
    14851495     * start working until we release alock) */
     
    14901500                                                   aName,
    14911501                                                   aDescription,
     1502                                                   snapshotId,
    14921503                                                   !!fPause,
    14931504                                                   mHWData->mMemorySize,
     
    15091520        i_setMachineState(MachineState_Snapshotting);
    15101521
     1522    aId = snapshotId;
    15111523    pTask->m_pProgress.queryInterfaceTo(aProgress.asOutParam());
    15121524
     
    15551567    bool fBeganTakingSnapshot = false;
    15561568    BOOL fSuspendedBySave     = FALSE;
    1557     Guid snapshotId;
    15581569
    15591570    try
     
    16061617        /* STEP 1: create the snapshot object */
    16071618
    1608         /* create an ID for the snapshot */
    1609         snapshotId.create();
    1610 
    16111619        /* create a snapshot machine object */
    16121620        ComObjPtr<SnapshotMachine> pSnapshotMachine;
    16131621        pSnapshotMachine.createObject();
    1614         rc = pSnapshotMachine->init(this, snapshotId.ref(), task.m_strStateFilePath);
     1622        rc = pSnapshotMachine->init(this, task.m_uuidSnapshot.ref(), task.m_strStateFilePath);
    16151623        AssertComRCThrowRC(rc);
    16161624
     
    16201628        task.m_pSnapshot.createObject();
    16211629        rc = task.m_pSnapshot->init(mParent,
    1622                                     snapshotId,
     1630                                    task.m_uuidSnapshot,
    16231631                                    task.m_strName,
    16241632                                    task.m_strDescription,
     
    17971805
    17981806    if (SUCCEEDED(rc))
    1799         mParent->i_onSnapshotTaken(mData->mUuid, snapshotId);
     1807        mParent->i_onSnapshotTaken(mData->mUuid, task.m_uuidSnapshot);
    18001808    LogFlowThisFuncLeave();
    18011809}
  • trunk/src/VBox/ValidationKit/testdriver/vboxwrappers.py

    r55760 r55977  
    22502250                self.o.console.pause();
    22512251            if self.fpApiVer >= 5.0:
    2252                 oProgressCom = self.o.machine.takeSnapshot(sName, sDescription, True);
     2252                (sSnapId, oProgressCom) = self.o.machine.takeSnapshot(sName, sDescription, True);
    22532253            else:
    22542254                oProgressCom = self.o.console.takeSnapshot(sName, sDescription);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette