VirtualBox

Changeset 84554 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
May 27, 2020 8:16:59 AM (5 years ago)
Author:
vboxsync
Message:

Guest Control/Main: Implemented host side support for gracefully rebooting / shutting down the guest. Untested. bugref:9320

Location:
trunk/src/VBox/Main
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r84532 r84554  
    1179011790
    1179111791  <enum
     11792    name="GuestShutdownFlag"
     11793    uuid="587309CD-DDDA-4619-82B0-4B764D9D3BC1"
     11794  >
     11795    <desc>
     11796      Guest shutdown flags.
     11797    </desc>
     11798
     11799    <const name="None"                      value="0">
     11800      <desc>No flag set.</desc>
     11801    </const>
     11802    <const name="PowerOff"                  value="1">
     11803      <desc>Performs a reboot after shutdown.</desc>
     11804    </const>
     11805    <const name="Reboot"                    value="2">
     11806      <desc>Performs a reboot after shutdown.</desc>
     11807    </const>
     11808  </enum>
     11809
     11810  <enum
    1179211811    name="GuestSessionStatus"
    1179311812    uuid="ac2669da-4624-44f2-85b5-0b0bfb8d8673"
     
    1505215071  <interface
    1505315072    name="IGuest" extends="$unknown"
    15054     uuid="13a11514-402e-022e-6180-c3944de3f9c8"
     15073    uuid="00892186-A4AF-4627-B21F-FC561CE4473C"
    1505515074    wsmap="managed"
    1505615075    reservedMethods="8" reservedAttributes="16"
     
    1531915338        <desc>
    1532015339          Array with all guest sessions found matching the name specified.
     15340        </desc>
     15341      </param>
     15342    </method>
     15343
     15344    <method name="shutdown">
     15345      <desc>
     15346        Shuts down (and optionally halts and/or reboots) the guest.
     15347        Needs supported Guest Additions installed.
     15348
     15349        <result name="VBOX_E_NOT_SUPPORTED">
     15350          Guest OS is not supported for shutting down, or the
     15351          already installed Guest Additions are not supported.
     15352        </result>
     15353
     15354        <result name="VBOX_E_IPRT_ERROR">
     15355          Error while shutting down.
     15356        </result>
     15357
     15358      </desc>
     15359      <param name="flags" type="GuestShutdownFlag" dir="in" safearray="yes">
     15360        <desc>
     15361          <link to="GuestShutdownFlag"/> flags.
    1532115362        </desc>
    1532215363      </param>
  • trunk/src/VBox/Main/include/GuestImpl.h

    r82968 r84554  
    173173     HRESULT findSession(const com::Utf8Str &aSessionName,
    174174                         std::vector<ComPtr<IGuestSession> > &aSessions);
     175     HRESULT shutdown(const std::vector<GuestShutdownFlag_T> &aFlags);
    175176     HRESULT updateGuestAdditions(const com::Utf8Str &aSource,
    176177                                  const std::vector<com::Utf8Str> &aArguments,
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r83321 r84554  
    338338    int                     i_setSessionStatus(GuestSessionStatus_T sessionStatus, int sessionRc);
    339339    int                     i_signalWaiters(GuestSessionWaitResult_T enmWaitResult, int rc /*= VINF_SUCCESS */);
     340    int                     i_shutdown(uint32_t fFlags, int *prcGuest);
    340341    int                     i_determineProtocolVersion(void);
    341342    int                     i_waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestSessionWaitResult_T &waitResult, int *pGuestRc);
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r83323 r84554  
    490490                         tr("Could not find sessions with name '%s'"),
    491491                         aSessionName.c_str());
     492#endif /* VBOX_WITH_GUEST_CONTROL */
     493}
     494
     495HRESULT Guest::shutdown(const std::vector<GuestShutdownFlag_T> &aFlags)
     496{
     497#ifndef VBOX_WITH_GUEST_CONTROL
     498    ReturnComNotImplemented();
     499#else /* VBOX_WITH_GUEST_CONTROL */
     500
     501    /* Validate flags. */
     502    uint32_t fFlags = GuestShutdownFlag_None;
     503    if (aFlags.size())
     504        for (size_t i = 0; i < aFlags.size(); ++i)
     505            fFlags |= aFlags[i];
     506
     507    const uint32_t fValidFlags = GuestShutdownFlag_None | GuestShutdownFlag_PowerOff | GuestShutdownFlag_Reboot;
     508    if (fFlags & ~fValidFlags)
     509        return setError(E_INVALIDARG,tr("Unknown flags: flags value %#x, invalid: %#x"), fFlags, fFlags & ~fValidFlags);
     510
     511    if (   (fFlags & GuestShutdownFlag_PowerOff)
     512        && (fFlags & GuestShutdownFlag_Reboot))
     513        return setError(E_INVALIDARG, tr("Invalid combination of flags (%#x)"), fFlags);
     514
     515    /*
     516     * Create an anonymous session. This is required to run shutting down / rebooting
     517     * the guest with administrative rights.
     518     */
     519    GuestSessionStartupInfo startupInfo;
     520    startupInfo.mName = "Shutting down guest";
     521
     522    GuestCredentials guestCreds;
     523
     524    HRESULT hrc;
     525    ComObjPtr<GuestSession> pSession;
     526    int vrc = i_sessionCreate(startupInfo, guestCreds, pSession);
     527    if (RT_SUCCESS(vrc))
     528    {
     529        Assert(!pSession.isNull());
     530
     531        int rcGuest = VERR_GSTCTL_GUEST_ERROR;
     532        vrc = pSession->i_startSession(&rcGuest);
     533        if (RT_SUCCESS(vrc))
     534        {
     535            vrc = pSession->i_shutdown(fFlags, &rcGuest);
     536            if (RT_FAILURE(vrc))
     537            {
     538                switch (vrc)
     539                {
     540                    case VERR_NOT_SUPPORTED:
     541                        hrc = setErrorBoth(VBOX_E_NOT_SUPPORTED, vrc,
     542                                           tr("Shutting down not supported by installed Guest Additions"), vrc);
     543                        break;
     544
     545                    default:
     546                    {
     547                        if (vrc == VERR_GSTCTL_GUEST_ERROR)
     548                            vrc = rcGuest;
     549                        hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Could not shut down guest: %Rrc"), vrc);
     550                        break;
     551                    }
     552                }
     553            }
     554        }
     555        else
     556        {
     557            if (vrc == VERR_GSTCTL_GUEST_ERROR)
     558                vrc = rcGuest;
     559            hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Could not open guest session: %Rrc"), vrc);
     560        }
     561    }
     562    else
     563    {
     564        switch (vrc)
     565        {
     566            case VERR_MAX_PROCS_REACHED:
     567                hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Maximum number of concurrent guest sessions (%d) reached"),
     568                                  VBOX_GUESTCTRL_MAX_SESSIONS);
     569                break;
     570
     571            /** @todo Add more errors here. */
     572
     573           default:
     574                hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Could not create guest session: %Rrc"), vrc);
     575                break;
     576        }
     577    }
     578
     579    LogFlowFunc(("Returning hrc=%Rhrc\n", hrc));
     580    return hrc;
    492581#endif /* VBOX_WITH_GUEST_CONTROL */
    493582}
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r84343 r84554  
    27072707
    27082708/**
     2709 * Shuts down (and optionally powers off / reboots) the guest.
     2710 * Needs supported Guest Additions installed.
     2711 *
     2712 * @returns VBox status code. VERR_NOT_SUPPORTED if not supported by Guest Additions.
     2713 * @param  fFlags               Guest shutdown flags.
     2714 * @param  prcGuest             Guest rc, when returning VERR_GSTCTL_GUEST_ERROR.
     2715 *                              Any other return code indicates some host side error.
     2716 */
     2717int GuestSession::i_shutdown(uint32_t fFlags, int *prcGuest)
     2718{
     2719    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     2720
     2721    AssertPtrReturn(mParent, VERR_INVALID_POINTER);
     2722    if (!(mParent->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_SHUTDOWN))
     2723        return VERR_NOT_SUPPORTED;
     2724
     2725    LogRel(("Guest Control: Shutting down guest (flags = %#x) ...\n", fFlags));
     2726
     2727    GuestWaitEvent *pEvent = NULL;
     2728    int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
     2729    if (RT_FAILURE(vrc))
     2730        return vrc;
     2731
     2732    /* Prepare HGCM call. */
     2733    VBOXHGCMSVCPARM paParms[2];
     2734    int i = 0;
     2735    HGCMSvcSetU32(&paParms[i++], pEvent->ContextID());
     2736    HGCMSvcSetU32(&paParms[i++], fFlags);
     2737
     2738    alock.release(); /* Drop write lock before sending. */
     2739
     2740    int rcGuest = VERR_IPE_UNINITIALIZED_STATUS;
     2741
     2742    vrc = i_sendMessage(HOST_MSG_SHUTDOWN, i, paParms);
     2743    if (RT_SUCCESS(vrc))
     2744    {
     2745        vrc = pEvent->Wait(30 * 1000);
     2746        if (RT_FAILURE(vrc))
     2747        {
     2748            if (vrc == VERR_GSTCTL_GUEST_ERROR)
     2749                rcGuest = pEvent->GuestResult();
     2750        }
     2751    }
     2752
     2753    if (RT_FAILURE(vrc))
     2754    {
     2755        LogRel(("Guest Control: Shutting down guest failed, rc=%Rrc\n",
     2756                vrc == VERR_GSTCTL_GUEST_ERROR ? rcGuest : vrc));
     2757
     2758        if (   vrc == VERR_GSTCTL_GUEST_ERROR
     2759            && prcGuest)
     2760            *prcGuest = rcGuest;
     2761    }
     2762
     2763    unregisterWaitEvent(pEvent);
     2764
     2765    LogFlowFuncLeaveRC(vrc);
     2766    return vrc;
     2767}
     2768
     2769/**
    27092770 * Determines the protocol version (sets mData.mProtocolVersion).
    27102771 *
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