VirtualBox

Changeset 98472 in vbox for trunk


Ignore:
Timestamp:
Feb 3, 2023 6:56:59 PM (2 years ago)
Author:
vboxsync
Message:

Guest Library: Introduce VbglR3DaemonizeEx and VbglR3PidfileWait, bugref:10359.

VbglR3DaemonizeEx is a wrapper function for VbglR3Daemonize. In addition to the
original version it sets pidfile lock for the parent process and notifies caller
when child process terminates with exit status VBGLR3EXITCODERELOAD (currently
equal to 2) indicating that parent process should release its reference to vboxguest
kernel module and wait for SIGUSR2 in order to restart itself. This is a part of
the procedure to install and reload/restart Guest Additions kernel modules and
user services without requiring guest reboot. It is currently only has effect
on X11 guests.

VbglR3PidfileWait is a wrapper function for VbglR3Pidfile. In addition to the
original version, it waits specified amount of time until pidfile lock become
available or fails on timeout.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxGuestLib.h

    r98103 r98472  
    554554/** @name General-purpose functions
    555555 * @{ */
     556/** Exit code which is returned by VBoxClient child process to notify
     557 * parent to release VBoxGuest driver resources on Unix-like guests. */
     558#define VBGLR3EXITCODERELOAD    (2)
     559
    556560VBGLR3DECL(int)     VbglR3Init(void);
    557561VBGLR3DECL(int)     VbglR3InitUser(void);
     
    564568VBGLR3DECL(int)     VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot);
    565569VBGLR3DECL(int)     VbglR3Daemonize(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn);
     570VBGLR3DECL(int)     VbglR3DaemonizeEx(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn,
     571                                      bool fReturnOnUpdate, bool *pfUpdateStarted, const char *szPidfile,
     572                                      RTFILE *phPidfile);
    566573VBGLR3DECL(int)     VbglR3PidFile(const char *pszPath, PRTFILE phFile);
    567574VBGLR3DECL(void)    VbglR3ClosePidFile(const char *pszPath, RTFILE hFile);
     575VBGLR3DECL(int)     VbglR3PidfileWait(const char *szPidfile, RTFILE *phPidfile, uint64_t u64TimeoutMs);
    568576VBGLR3DECL(int)     VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot);
    569577VBGLR3DECL(int)     VbglR3AcquireGuestCaps(uint32_t fOr, uint32_t fNot, bool fConfig);
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDaemonize.cpp

    r98103 r98472  
    6464#include <iprt/process.h>
    6565#include <iprt/string.h>
     66#include <VBox/err.h>
     67#include <VBox/log.h>
     68
    6669#include "VBoxGuestR3LibInternal.h"
    6770
     
    7477 * @returns 0 on success
    7578 *
    76  * @param   fNoChDir    Pass false to change working directory to root.
    77  * @param   fNoClose    Pass false to redirect standard file streams to /dev/null.
    78  * @param   fRespawn    Restart the daemonised process after five seconds if it
    79  *                      terminates abnormally.
    80  * @param   pcRespawn   Where to store a count of how often we have respawned,
    81  *                      intended for avoiding error spamming.  Optional.
     79 * @param   fNoChDir        Pass false to change working directory to root.
     80 * @param   fNoClose        Pass false to redirect standard file streams to /dev/null.
     81 * @param   fRespawn        Restart the daemonised process after five seconds if it
     82 *                          terminates abnormally.
     83 * @param   pcRespawn       Where to store a count of how often we have respawned,
     84 *                          intended for avoiding error spamming.  Optional.
     85 * @param   fReturnOnUpdate If True, this function will return control to caller when
     86 *                          child process will terminate with exit code of VBGLR3EXITCODERELOAD,
     87 *                          indicating that Guest Additions update has been started and this running
     88 *                          process will be asked to be restarted by arrival of the next SIGUSR1
     89 *                          signal (caller should wait for SIGUSR1). If False, this functions will
     90 *                          never return, but rather exit() when child process terminates with
     91 *                          exit code 0.
     92 * @param   pfUpdateStarted A flag which passed to caller if fReturnOnUpdate is True (can be NULL).
     93 * @param   szPidfile       Optional path to parent process' pidfile (can be NULL).
     94 * @param   phPidfile       Optional path to parent process' pidfile handle (can not be NULL if
     95 *                          szPidfile was specified).
    8296 *
    8397 * @todo    Use RTProcDaemonize instead of this.
     
    86100 *          actually needs that.
    87101 */
    88 VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn)
     102VBGLR3DECL(int) VbglR3DaemonizeEx(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn,
     103                                  bool fReturnOnUpdate, bool *pfUpdateStarted, const char *szPidfile,
     104                                  RTFILE *phPidfile)
    89105{
    90106#if defined(RT_OS_OS2)
     
    92108    PTIB pTib;
    93109    DosGetInfoBlocks(&pTib, &pPib);
     110
     111    RT_NOREF(fReturnOnUpdate);
     112    RT_NOREF(pfUpdateStarted);
     113    RT_NOREF(szPidfile);
     114    RT_NOREF(phPidfile);
    94115
    95116    AssertRelease(!fRespawn);
     
    230251    if (pid != 0)
    231252        exit(0);
     253
     254    /* Check if another instance is already running. */
     255    if (szPidfile != NULL)
     256    {
     257        if (phPidfile != NULL)
     258        {
     259            int rc = VbglR3PidfileWait(szPidfile, phPidfile, 5000);
     260
     261             /* Another instance of process is already running. */
     262            if (rc == VERR_FILE_LOCK_VIOLATION)
     263            {
     264                LogRel(("cannot aquire pidfile %s, exitting\n", szPidfile));
     265                exit(1);
     266            }
     267
     268            /* Unable to lock on pidfile. */
     269            if (RT_FAILURE(rc))
     270                exit(1);
     271        }
     272        else
     273            return VERR_INVALID_PARAMETER;
     274    }
    232275# endif /* RT_OS_LINUX */
    233276
     
    254297            if (rcWait == -1)
    255298                exit(1);
    256             if (WIFEXITED(iStatus) && WEXITSTATUS(iStatus) == 0)
    257                 exit(0);
     299            if (WIFEXITED(iStatus))
     300            {
     301                if (WEXITSTATUS(iStatus) == 0)
     302                    exit(0);
     303                else if (fReturnOnUpdate && WEXITSTATUS(iStatus) == VBGLR3EXITCODERELOAD)
     304                {
     305                    /* Tell caller that update has been started. */
     306                    if (pfUpdateStarted != NULL)
     307                        *pfUpdateStarted = true;
     308
     309                    return VINF_SUCCESS;
     310                }
     311            }
    258312            sleep(5);
    259313            ++cRespawn;
     
    263317#endif
    264318}
     319
     320/**
     321 * A wrapper function for VbglR3DaemonizeEx.
     322 */
     323VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn)
     324{
     325    return VbglR3DaemonizeEx(fNoChDir, fNoClose, fRespawn, pcRespawn, false, NULL, NULL, NULL);
     326}
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibPidFile.cpp

    r98103 r98472  
    4343#include <iprt/string.h>
    4444#include <iprt/process.h>
     45#include <iprt/err.h>
    4546#include "VBoxGuestR3LibInternal.h"
     47
     48/* A time to wait before starting the next attempt to check a pidfile. */
     49#define VBGL_PIDFILE_WAIT_RELAX_TIME_MS (250)
    4650
    4751/**
     
    117121}
    118122
     123
     124/**
     125 * Wait for other process to release pidfile.
     126 *
     127 * This function is a wrapper to VbglR3PidFile().
     128 *
     129 * @returns IPRT status code.
     130 * @param   szPidfile       Path to pidfile.
     131 * @param   phPidfile       Handle to pidfile.
     132 * @param   u64TimeoutMs    A timeout value in milliseconds to wait for
     133 *                          other process to release pidfile.
     134 */
     135VBGLR3DECL(int) VbglR3PidfileWait(const char *szPidfile, RTFILE *phPidfile, uint64_t u64TimeoutMs)
     136{
     137    int rc = VERR_FILE_LOCK_VIOLATION;
     138    uint64_t u64Start = RTTimeSystemMilliTS();
     139
     140    AssertPtrReturn(szPidfile, VERR_INVALID_PARAMETER);
     141    AssertPtrReturn(phPidfile, VERR_INVALID_PARAMETER);
     142
     143    while (   !RT_SUCCESS((rc = VbglR3PidFile(szPidfile, phPidfile)))
     144           && (RTTimeSystemMilliTS() - u64Start < u64TimeoutMs))
     145    {
     146        RTThreadSleep(VBGL_PIDFILE_WAIT_RELAX_TIME_MS);
     147    }
     148
     149    return rc;
     150}
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