VirtualBox

Changeset 75663 in vbox for trunk/src/VBox/Main/src-all


Ignore:
Timestamp:
Nov 22, 2018 2:00:59 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126855
Message:

Main/ExtPackManager+CloudProviderManager+VirtualBox: Handle runtime install and uninstall of extension packs containing cloud providers. This is a safeguard against uninstalling active cloud providers (which would cause crashes), and makes the install more convcenient. At the same time it eliminated the need to have a special "detect all cloud providers" logic when VBoxSVC is started. It achieves perfect singleton property of the per-extpack CloudProviderManager and the related CloudProvider objects. Nothing is ever created twice (which would cause trouble with coordinating e.g. the profile file updates).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp

    r74814 r75663  
    2121*********************************************************************************************************************************/
    2222#include "ExtPackManagerImpl.h"
     23#include "CloudProviderManagerImpl.h"
    2324#include "ExtPackUtil.h"
    2425#include "ThreadTask.h"
     
    928929            a_pLock->release();
    929930            m->pReg->pfnVirtualBoxReady(m->pReg, a_pVirtualBox);
     931            i_notifyCloudProviderManager();
    930932            a_pLock->acquire();
    931933            return true;
     
    10851087    return false;
    10861088}
    1087 #endif /* !VBOX_COM_INPROC */
     1089#endif /* VBOX_COM_INPROC */
    10881090
    10891091/**
     
    12481250    return S_OK;
    12491251}
     1252
     1253#ifndef VBOX_COM_INPROC
     1254/**
     1255 * Checks if there are cloud providers vetoing extension pack uninstall.
     1256 *
     1257 * This needs going through the cloud provider singleton in VirtualBox,
     1258 * the job cannot be done purely by using the code in the extension pack).
     1259 * It cannot be integrated into i_callUninstallHookAndClose, because it
     1260 * can only do its job when the extpack lock is not held, whereas the
     1261 * actual uninstall must be done with the lock held all the time for
     1262 * consistency reasons.
     1263 *
     1264 * This is called when uninstalling or replacing an extension pack.
     1265 *
     1266 * @returns true / false
     1267 */
     1268bool ExtPack::i_areThereCloudProviderUninstallVetos()
     1269{
     1270    Assert(m->pVirtualBox != NULL); /* Only called from VBoxSVC. */
     1271
     1272    ComObjPtr<CloudProviderManager> cpm(m->pVirtualBox->i_getCloudProviderManager());
     1273    AssertReturn(!cpm.isNull(), false);
     1274
     1275    return !cpm->i_canRemoveExtPack(static_cast<IExtPack *>(this));
     1276}
     1277
     1278/**
     1279 * Notifies the Cloud Provider Manager that there is a new extension pack.
     1280 *
     1281 * This is called when installing an extension pack.
     1282 *
     1283 * @param   a_pExtPack          The extension pack to be added.
     1284 */
     1285void ExtPack::i_notifyCloudProviderManager()
     1286{
     1287    Assert(m->pVirtualBox != NULL); /* Only called from VBoxSVC. */
     1288
     1289    ComObjPtr<CloudProviderManager> cpm(m->pVirtualBox->i_getCloudProviderManager());
     1290    AssertReturnVoid(!cpm.isNull());
     1291
     1292    cpm->i_addExtPack(static_cast<IExtPack *>(this));
     1293}
     1294
     1295#endif /* !VBOX_COM_INPROC */
    12501296
    12511297/**
     
    28492895                autoLock.release();
    28502896                bool fRunningVMs = i_areThereAnyRunningVMs();
     2897                bool fVetoingCP = pExtPack->i_areThereCloudProviderUninstallVetos();
    28512898                autoLock.acquire();
    28522899                hrc = i_refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
    28532900                if (fRunningVMs)
    28542901                {
    2855                     LogRel(("Install extension pack '%s' failed because at least one VM is still running.", pStrName->c_str()));
    2856                     hrc = setError(E_FAIL, tr("Install extension pack '%s' failed because at least one VM is still running"),
     2902                    LogRel(("Upgrading extension pack '%s' failed because at least one VM is still running.", pStrName->c_str()));
     2903                    hrc = setError(E_FAIL, tr("Upgrading extension pack '%s' failed because at least one VM is still running"),
     2904                                   pStrName->c_str());
     2905                }
     2906                else if (fVetoingCP)
     2907                {
     2908                    LogRel(("Upgrading extension pack '%s' failed because at least one Cloud Provider is still busy.", pStrName->c_str()));
     2909                    hrc = setError(E_FAIL, tr("Upgrading extension pack '%s' failed because at least one Cloud Provider is still busy"),
    28572910                                   pStrName->c_str());
    28582911                }
     
    29563009    if (SUCCEEDED(hrc))
    29573010    {
    2958         if (a_fForcedRemoval || !i_areThereAnyRunningVMs())
    2959         {
    2960             AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
    2961 
    2962             /*
    2963              * Refresh the data we have on the extension pack as it may be made
    2964              * stale by direct meddling or some other user.
    2965              */
    2966             ExtPack *pExtPack;
    2967             hrc = i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
    2968             if (SUCCEEDED(hrc))
     3011        AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
     3012
     3013        /*
     3014         * Refresh the data we have on the extension pack as it
     3015         * may be made stale by direct meddling or some other user.
     3016         */
     3017        ExtPack *pExtPack;
     3018        hrc = i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
     3019        if (SUCCEEDED(hrc) && pExtPack)
     3020        {
     3021            /* We must leave the lock when calling i_areThereAnyRunningVMs,
     3022               which means we have to redo the refresh call afterwards. */
     3023            autoLock.release();
     3024            bool fRunningVMs = i_areThereAnyRunningVMs();
     3025            bool fVetoingCP = pExtPack->i_areThereCloudProviderUninstallVetos();
     3026            autoLock.acquire();
     3027            if (a_fForcedRemoval || (!fRunningVMs && !fVetoingCP))
    29693028            {
    2970                 if (!pExtPack)
     3029                hrc = i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
     3030                if (SUCCEEDED(hrc))
    29713031                {
    2972                     LogRel(("ExtPackManager: Extension pack '%s' is not installed, so nothing to uninstall.\n", a_pstrName->c_str()));
    2973                     hrc = S_OK;             /* nothing to uninstall */
    2974                 }
    2975                 else
    2976                 {
    2977                     /*
    2978                      * Call the uninstall hook and unload the main dll.
    2979                      */
    2980                     hrc = pExtPack->i_callUninstallHookAndClose(m->pVirtualBox, a_fForcedRemoval);
    2981                     if (SUCCEEDED(hrc))
     3032                    if (!pExtPack)
     3033                    {
     3034                        LogRel(("ExtPackManager: Extension pack '%s' is not installed, so nothing to uninstall.\n", a_pstrName->c_str()));
     3035                        hrc = S_OK;             /* nothing to uninstall */
     3036                    }
     3037                    else
    29823038                    {
    29833039                        /*
    2984                          * Run the set-uid-to-root binary that performs the
    2985                          * uninstallation.  Then refresh the object.
    2986                          *
    2987                          * This refresh is theorically subject to races, but it's of
    2988                          * the don't-do-that variety.
     3040                         * Call the uninstall hook and unload the main dll.
    29893041                         */
    2990                         const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL;
    2991                         hrc = i_runSetUidToRootHelper(a_pstrDisplayInfo,
    2992                                                       "uninstall",
    2993                                                       "--base-dir", m->strBaseDir.c_str(),
    2994                                                       "--name",     a_pstrName->c_str(),
    2995                                                       pszForcedOpt, /* Last as it may be NULL. */
    2996                                                       (const char *)NULL);
     3042                        hrc = pExtPack->i_callUninstallHookAndClose(m->pVirtualBox, a_fForcedRemoval);
    29973043                        if (SUCCEEDED(hrc))
    29983044                        {
    2999                             hrc = i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
     3045                            /*
     3046                             * Run the set-uid-to-root binary that performs the
     3047                             * uninstallation.  Then refresh the object.
     3048                             *
     3049                             * This refresh is theorically subject to races, but it's of
     3050                             * the don't-do-that variety.
     3051                             */
     3052                            const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL;
     3053                            hrc = i_runSetUidToRootHelper(a_pstrDisplayInfo,
     3054                                                          "uninstall",
     3055                                                          "--base-dir", m->strBaseDir.c_str(),
     3056                                                          "--name",     a_pstrName->c_str(),
     3057                                                          pszForcedOpt, /* Last as it may be NULL. */
     3058                                                          (const char *)NULL);
    30003059                            if (SUCCEEDED(hrc))
    30013060                            {
    3002                                 if (!pExtPack)
    3003                                     LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", a_pstrName->c_str()));
    3004                                 else
    3005                                     hrc = setError(E_FAIL,
    3006                                                    tr("Uninstall extension pack '%s' failed under mysterious circumstances"),
    3007                                                    a_pstrName->c_str());
     3061                                hrc = i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
     3062                                if (SUCCEEDED(hrc))
     3063                                {
     3064                                    if (!pExtPack)
     3065                                        LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", a_pstrName->c_str()));
     3066                                    else
     3067                                        hrc = setError(E_FAIL,
     3068                                                       tr("Uninstall extension pack '%s' failed under mysterious circumstances"),
     3069                                                       a_pstrName->c_str());
     3070                                }
    30083071                            }
    3009                         }
    3010                         else
    3011                         {
    3012                             ErrorInfoKeeper Eik;
    3013                             i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, NULL);
     3072                            else
     3073                            {
     3074                                ErrorInfoKeeper Eik;
     3075                                i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, NULL);
     3076                            }
    30143077                        }
    30153078                    }
    30163079                }
    30173080            }
    3018         }
    3019         else
    3020         {
    3021             LogRel(("Uninstall extension pack '%s' failed because at least one VM is still running.", a_pstrName->c_str()));
    3022             hrc = setError(E_FAIL, tr("Uninstall extension pack '%s' failed because at least one VM is still running"),
    3023                            a_pstrName->c_str());
     3081            else
     3082            {
     3083                if (fRunningVMs)
     3084                {
     3085                    LogRel(("Uninstall extension pack '%s' failed because at least one VM is still running.", a_pstrName->c_str()));
     3086                    hrc = setError(E_FAIL, tr("Uninstall extension pack '%s' failed because at least one VM is still running"),
     3087                                   a_pstrName->c_str());
     3088                }
     3089                else if (fVetoingCP)
     3090                {
     3091                    LogRel(("Uninstall extension pack '%s' failed because at least one Cloud Provider is still busy.", a_pstrName->c_str()));
     3092                    hrc = setError(E_FAIL, tr("Uninstall extension pack '%s' failed because at least one Cloud Provider is still busy"),
     3093                                   a_pstrName->c_str());
     3094                }
     3095                else
     3096                {
     3097                    LogRel(("Uninstall extension pack '%s' failed for an unknown reason.", a_pstrName->c_str()));
     3098                    hrc = setError(E_FAIL, tr("Uninstall extension pack '%s' failed for an unknown reason"),
     3099                                   a_pstrName->c_str());
     3100
     3101                }
     3102            }
    30243103        }
    30253104
     
    30293108         */
    30303109        if (m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON)
     3110        {
     3111            autoLock.release();
    30313112            i_callAllVirtualBoxReadyHooks();
     3113        }
    30323114    }
    30333115
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