VirtualBox

Changeset 97360 in vbox for trunk


Ignore:
Timestamp:
Nov 1, 2022 1:33:46 AM (2 years ago)
Author:
vboxsync
Message:

bugref:10180 - fixed issue where some files are not cleaned up after vm deletion or vm execution interruption, ensured enum value ordering stayed consistent

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/manual/en_US/man_VBoxManage-unregistervm.xml

    r96407 r97360  
    5555      </group>
    5656      <arg>--delete</arg>
     57      <arg>--delete-all</arg>
    5758    </cmdsynopsis>
    5859  </refsynopsisdiv>
     
    9596          </itemizedlist></listitem>
    9697      </varlistentry>
     98      <varlistentry>
     99        <term><option>--delete-all</option></term>
     100        <listitem><para>
     101            Deletes the files described in the <option>--delete</option> option,
     102            as well as all DVDs and Floppy disks located in the VM folder and
     103            attached only to this VM.
     104          </para></listitem>
     105      </varlistentry>
    97106    </variablelist>
    98107  </refsect1>
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r96620 r97360  
    171171    { "--delete",       'd', RTGETOPT_REQ_NOTHING },
    172172    { "-delete",        'd', RTGETOPT_REQ_NOTHING },    // deprecated
     173    { "--delete-all",   'a', RTGETOPT_REQ_NOTHING },
     174    { "-delete-all",    'a', RTGETOPT_REQ_NOTHING },    // deprecated
    173175};
    174176
     
    178180    const char *VMName = NULL;
    179181    bool fDelete = false;
     182    bool fDeleteAll = false;
    180183
    181184    int c;
     
    191194            case 'd':   // --delete
    192195                fDelete = true;
     196                break;
     197
     198            case 'a':   // --delete-all
     199                fDeleteAll = true;
    193200                break;
    194201
     
    224231                    RTEXITCODE_FAILURE);
    225232    SafeIfaceArray<IMedium> aMedia;
    226     CHECK_ERROR_RET(machine, Unregister(CleanupMode_DetachAllReturnHardDisksOnly,
     233    CHECK_ERROR_RET(machine, Unregister(fDeleteAll ? CleanupMode_DetachAllReturnHardDisksAndVMRemovable
     234                                                   :CleanupMode_DetachAllReturnHardDisksOnly,
    227235                                        ComSafeArrayAsOutParam(aMedia)),
    228236                    RTEXITCODE_FAILURE);
    229     if (fDelete)
     237    if (fDelete || fDeleteAll)
    230238    {
    231239        ComPtr<IProgress> pProgress;
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r96888 r97360  
    65176517  <enum
    65186518    name="CleanupMode"
    6519     uuid="67897c50-7cca-47a9-83f6-ce8fd8eb5441"
     6519    uuid="1ec1df9e-9b0e-43cd-ad4d-a34e10edb0c5"
    65206520    >
    65216521    <desc>Cleanup mode, used with <link to="IMachine::unregister" />.
    65226522    </desc>
    6523     <const name="UnregisterOnly"                  value="1">
     6523    <const name="UnregisterOnly"                          value="1">
    65246524      <desc>Unregister only the machine, but neither delete snapshots nor detach media.</desc>
    65256525    </const>
    6526     <const name="DetachAllReturnNone"             value="2">
     6526    <const name="DetachAllReturnNone"                     value="2">
    65276527      <desc>Delete all snapshots and detach all media but return none; this will keep all media registered.</desc>
    65286528    </const>
    6529     <const name="DetachAllReturnHardDisksOnly"    value="3">
     6529    <const name="DetachAllReturnHardDisksOnly"            value="3">
    65306530      <desc>Delete all snapshots, detach all media and return hard disks for closing, but not removable media.</desc>
    65316531    </const>
    6532     <const name="Full"                            value="4">
     6532    <const name="Full"                                    value="4">
    65336533      <desc>Delete all snapshots, detach all media and return all media for closing.</desc>
     6534    </const>
     6535    <const name="DetachAllReturnHardDisksAndVMRemovable"  value="5">
     6536      <desc>Delete all snapshots, detach all media and return hard disks and removable locating in the folder of the machine to be deleted and referenced only to this machine, for closing.</desc>
    65346537    </const>
    65356538  </enum>
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r96407 r97360  
    55285528
    55295529        if (    !(m->formatObj->i_getCapabilities() & (  MediumFormatCapabilities_CreateDynamic
    5530                                                        | MediumFormatCapabilities_CreateFixed)))
     5530                                                       | MediumFormatCapabilities_CreateFixed
     5531                                                       | MediumFormatCapabilities_File)))
    55315532            throw setError(VBOX_E_NOT_SUPPORTED,
    55325533                           tr("Medium format '%s' does not support storage deletion"),
  • trunk/src/VBox/Main/src-server/UnattendedImpl.cpp

    r96862 r97360  
    141141    bool            fMountOnly;
    142142    Utf8Str         strImagePath;
     143    bool            fAuxiliary;
    143144
    144145    UnattendedInstallationDisk(StorageBus_T a_enmBusType, Utf8Str const &a_rBusName, DeviceType_T a_enmDeviceType,
    145146                               AccessMode_T a_enmAccessType, LONG a_iPort, LONG a_iDevice, bool a_fMountOnly,
    146                                Utf8Str const &a_rImagePath)
     147                               Utf8Str const &a_rImagePath, bool a_fAuxiliary)
    147148        : enmBusType(a_enmBusType), strControllerName(a_rBusName), enmDeviceType(a_enmDeviceType), enmAccessType(a_enmAccessType)
    148         , iPort(a_iPort), iDevice(a_iDevice), fMountOnly(a_fMountOnly), strImagePath(a_rImagePath)
     149        , iPort(a_iPort), iDevice(a_iDevice), fMountOnly(a_fMountOnly), strImagePath(a_rImagePath), fAuxiliary(a_fAuxiliary)
    149150    {
    150151        Assert(strControllerName.length() > 0);
    151152    }
    152153
    153     UnattendedInstallationDisk(std::list<ControllerSlot>::const_iterator const &itDvdSlot, Utf8Str const &a_rImagePath)
     154    UnattendedInstallationDisk(std::list<ControllerSlot>::const_iterator const &itDvdSlot, Utf8Str const &a_rImagePath,
     155                               bool a_fAuxiliary)
    154156        : enmBusType(itDvdSlot->enmBus), strControllerName(itDvdSlot->strControllerName), enmDeviceType(DeviceType_DVD)
    155157        , enmAccessType(AccessMode_ReadOnly), iPort(itDvdSlot->iPort), iDevice(itDvdSlot->iDevice)
    156         , fMountOnly(!itDvdSlot->fFree), strImagePath(a_rImagePath)
     158        , fMountOnly(!itDvdSlot->fFree), strImagePath(a_rImagePath), fAuxiliary(a_fAuxiliary)
    157159    {
    158160        Assert(strControllerName.length() > 0);
     
    30523054                                                                 0, 0,
    30533055                                                                 fFoundPort0Dev0 /*fMountOnly*/,
    3054                                                                  mpInstaller->getAuxiliaryFloppyFilePath()));
     3056                                                                 mpInstaller->getAuxiliaryFloppyFilePath(), false));
    30553057    return S_OK;
    30563058}
     
    32113213    if (mpInstaller->isAuxiliaryIsoNeeded() && mpInstaller->bootFromAuxiliaryIso())
    32123214    {
    3213         rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, mpInstaller->getAuxiliaryIsoFilePath()));
     3215        rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, mpInstaller->getAuxiliaryIsoFilePath(), true));
    32143216        ++itDvdSlot;
    32153217    }
     
    32173219    if (mpInstaller->isOriginalIsoNeeded())
    32183220    {
    3219         rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, i_getIsoPath()));
     3221        rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, i_getIsoPath(), false));
    32203222        ++itDvdSlot;
    32213223    }
     
    32233225    if (mpInstaller->isAuxiliaryIsoNeeded() && !mpInstaller->bootFromAuxiliaryIso())
    32243226    {
    3225         rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, mpInstaller->getAuxiliaryIsoFilePath()));
     3227        rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, mpInstaller->getAuxiliaryIsoFilePath(), true));
    32263228        ++itDvdSlot;
    32273229    }
     
    32303232    if (mpInstaller->isAdditionsIsoNeeded())
    32313233    {
    3232         rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, i_getAdditionsIsoPath()));
     3234        rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, i_getAdditionsIsoPath(), false));
    32333235        ++itDvdSlot;
    32343236    }
     
    32363238    if (mpInstaller->isValidationKitIsoNeeded())
    32373239    {
    3238         rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, i_getValidationKitIsoPath()));
     3240        rVecInstallatationDisks.push_back(UnattendedInstallationDisk(itDvdSlot, i_getValidationKitIsoPath(), false));
    32393241        ++itDvdSlot;
    32403242    }
     
    42154217    if (SUCCEEDED(rc))
    42164218    {
     4219        if (pImage->fAuxiliary && pImage->strImagePath.endsWith(".viso"))
     4220        {
     4221            rc = ptrMedium->SetProperty(L"UnattendedInstall", L"1");
     4222            LogRelFlowFunc(("Medium::SetProperty -> %Rhrc\n", rc));
     4223        }
     4224
    42174225        if (pImage->fMountOnly)
    42184226        {
  • trunk/src/VBox/Storage/VISO.cpp

    r96407 r97360  
    105105    { "viso",           VDTYPE_OPTICAL_DISC },
    106106    { NULL,             VDTYPE_INVALID      }
     107};
     108
     109/** NULL-terminated array of configuration option. */
     110static const VDCONFIGINFO s_aVisoConfigInfo[] =
     111{
     112    /* Options for VMDK raw disks */
     113    { "UnattendedInstall",     NULL,    VDCFGVALUETYPE_STRING,  VD_CFGKEY_EXPERT },
     114    /* End of options list */
     115    { NULL,                    NULL,    VDCFGVALUETYPE_INTEGER, 0 }
    107116};
    108117
     
    515524}
    516525
    517 
    518 /**
    519  * @interface_method_impl{VDIMAGEBACKEND,pfnClose}
     526/**
     527 * Scans the VISO file and removes all references to files
     528 * which are in the same folder as the VISO and
     529 * whose names begin with "Unattended-".
     530 *
     531 * @return VBox status code.
     532 *
     533 * @param pThis Pointer to VISO backend data.
     534 */
     535static int deleteReferences(PVISOIMAGE pThis)
     536{
     537    /*
     538     * Open the file and read it into memory.
     539     */
     540    PVDIOSTORAGE pStorage = NULL;
     541    int vrc = vdIfIoIntFileOpen(pThis->pIfIo, pThis->pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE, &pStorage);
     542    if (RT_FAILURE(vrc))
     543    {
     544        LogRel(("VISO: Unable to open file '%s': %Rrc\n", pThis->pszFilename, vrc));
     545        return vrc;
     546    }
     547
     548    LogRel(("VISO: Handling file '%s' references\n", pThis->pszFilename));
     549
     550    /*
     551     * Read the file into memory.
     552     */
     553    uint64_t cbFile = 0;
     554    vrc = vdIfIoIntFileGetSize(pThis->pIfIo, pStorage, &cbFile);
     555    if (RT_SUCCESS(vrc))
     556    {
     557        if (cbFile <= VISO_MAX_FILE_SIZE)
     558        {
     559            char *pszContent = (char *)RTMemTmpAlloc(cbFile + 1);
     560            if (pszContent)
     561            {
     562                vrc = vdIfIoIntFileReadSync(pThis->pIfIo, pStorage, 0 /*off*/, pszContent, (size_t)cbFile);
     563                if (RT_SUCCESS(vrc))
     564                {
     565                    /*
     566                     * Check the file marker.
     567                     * Ignore leading blanks.
     568                     */
     569                    pszContent[(size_t)cbFile] = '\0';
     570
     571                    char *pszReadDst = pszContent;
     572                    while (RT_C_IS_SPACE(*pszReadDst))
     573                        pszReadDst++;
     574                    if (strncmp(pszReadDst, RT_STR_TUPLE("--iprt-iso-maker-file-marker")) == 0)
     575                    {
     576                        vrc = visoParseUuid(pszReadDst, &pThis->Uuid);
     577                        if (RT_SUCCESS(vrc))
     578                        {
     579                            /*
     580                             * Make sure it's valid UTF-8 before letting
     581                             */
     582                            vrc = RTStrValidateEncodingEx(pszContent, cbFile + 1,
     583                                                          RTSTR_VALIDATE_ENCODING_EXACT_LENGTH
     584                                                          | RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
     585                            if (RT_SUCCESS(vrc))
     586                            {
     587                                /*
     588                                 * Convert it into an argument vector.
     589                                 * Free the content afterwards to reduce memory pressure.
     590                                 */
     591                                uint32_t fGetOpt = strncmp(pszReadDst, RT_STR_TUPLE("--iprt-iso-maker-file-marker-ms")) != 0
     592                                                 ? RTGETOPTARGV_CNV_QUOTE_BOURNE_SH : RTGETOPTARGV_CNV_QUOTE_MS_CRT;
     593                                fGetOpt |= RTGETOPTARGV_CNV_MODIFY_INPUT;
     594                                char **papszArgs;
     595                                int    cArgs;
     596                                vrc = RTGetOptArgvFromString(&papszArgs, &cArgs, pszContent, fGetOpt, NULL);
     597
     598                                if (RT_SUCCESS(vrc))
     599                                {
     600                                    for (int i = 0; i < cArgs; ++i)
     601                                    {
     602                                        char *pszArg = papszArgs[i];
     603                                        char *pszOffset = strrchr(pszArg, '=');
     604                                        if (pszOffset != NULL)
     605                                            pszArg = pszOffset + 1;
     606
     607                                        /* if it isn't option */
     608                                        if (pszArg[0] != '-')
     609                                        {
     610                                            char *pszPath = RTPathAbsExDup(pThis->pszCwd, pszArg, 0);
     611                                            if (RTStrStartsWith((const char *)pszPath, pThis->pszCwd))
     612                                            {
     613                                                char *pszFileName = RTPathFilename(pszPath);
     614                                                if (   pszFileName != NULL
     615                                                    && RTStrStartsWith((const char *)pszFileName, "Unattended-"))
     616                                                {
     617                                                    vrc = RTFileDelete(pszPath);
     618                                                    if (RT_SUCCESS(vrc))
     619                                                        LogRel(("VISO: file '%s' deleted\n", pszPath));
     620                                                    else
     621                                                        LogRel(("VISO: Failed to delete the file '%s' (%Rrc)\n", pszPath, vrc));
     622                                                    vrc = VINF_SUCCESS;
     623                                                }
     624                                            }
     625                                            RTStrFree(pszPath);
     626                                        }
     627                                    }
     628                                    RTGetOptArgvFreeEx(papszArgs, fGetOpt);
     629                                    papszArgs = NULL;
     630                                }
     631                                else
     632                                    vdIfError(pThis->pIfError, vrc, RT_SRC_POS, "VISO: RTGetOptArgvFromString failed: %Rrc", vrc);
     633                            }
     634                            else
     635                                vdIfError(pThis->pIfError, vrc, RT_SRC_POS, "VISO: Invalid file encoding");
     636                        }
     637                        else
     638                            vdIfError(pThis->pIfError, vrc, RT_SRC_POS, "VISO: Parsing UUID failed: %Rrc", vrc);
     639                    }
     640                    else
     641                        vrc = VERR_VD_GEN_INVALID_HEADER;
     642                }
     643                else
     644                    vdIfError(pThis->pIfError, vrc, RT_SRC_POS, "VISO: Reading file failed: %Rrc", vrc);
     645
     646                RTMemTmpFree(pszContent);
     647            }
     648            else
     649                vrc = VERR_NO_TMP_MEMORY;
     650        }
     651        else
     652        {
     653            LogRel(("visoOpen: VERR_VD_INVALID_SIZE - cbFile=%#RX64 cbMaxFile=%#RX64\n",
     654                    cbFile, (uint64_t)VISO_MAX_FILE_SIZE));
     655            vrc = VERR_VD_INVALID_SIZE;
     656        }
     657    }
     658
     659    if (RT_FAILURE(vrc))
     660        LogRel(("VISO: Handling of file '%s' failed with %Rrc\n", pThis->pszFilename, vrc));
     661
     662    vdIfIoIntFileClose(pThis->pIfIo, pStorage);
     663    return vrc;
     664}
     665
     666/**
     667* @interface_method_impl{VDIMAGEBACKEND,pfnClose}
    520668 */
    521669static DECLCALLBACK(int) visoClose(void *pBackendData, bool fDelete)
     
    527675    {
    528676        if (fDelete)
     677        {
     678            PVDINTERFACECONFIG pImgCfg = VDIfConfigGet(&pThis->pIfIo->Core);
     679
     680            bool fUnattendedInstall = false;
     681            int vrc = VDCFGQueryBool(pImgCfg, "UnattendedInstall", &fUnattendedInstall);
     682
     683            /*
     684            * The VISO created by unattended installer, so delete all generated files
     685            * included in the VISO. the file is considered generated if it is located
     686            * in the same folder as VISO and its name begins with "Unattended-"
     687            */
     688            if (RT_SUCCESS(vrc) && fUnattendedInstall)
     689                deleteReferences(pThis);
    529690            vdIfIoIntFileDelete(pThis->pIfIo, pThis->pszFilename);
     691        }
    530692
    531693        if (pThis->hIsoFile != NIL_RTVFSFILE)
     
    8691031    g_aVBoXIsoMakerFileExtensions,
    8701032    /* paConfigInfo */
    871     NULL,
     1033    s_aVisoConfigInfo,
    8721034    /* pfnProbe */
    8731035    visoProbe,
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