diff options
Diffstat (limited to 'src/VBox/Additions/common/VBoxService/VBoxServiceControl.h')
-rw-r--r-- | src/VBox/Additions/common/VBoxService/VBoxServiceControl.h | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h new file mode 100644 index 00000000..7afe7cb4 --- /dev/null +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h @@ -0,0 +1,325 @@ +/* $Id: VBoxServiceControl.h $ */ +/** @file + * VBoxServiceControl.h - Internal guest control definitions. + */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +#ifndef ___VBoxServiceControl_h +#define ___VBoxServiceControl_h + +#include <iprt/critsect.h> +#include <iprt/list.h> +#include <iprt/req.h> + +#include <VBox/VBoxGuestLib.h> +#include <VBox/HostServices/GuestControlSvc.h> + + +/** + * Pipe IDs for handling the guest process poll set. + */ +typedef enum VBOXSERVICECTRLPIPEID +{ + VBOXSERVICECTRLPIPEID_UNKNOWN = 0, + VBOXSERVICECTRLPIPEID_STDIN = 10, + VBOXSERVICECTRLPIPEID_STDIN_WRITABLE = 11, + /** Pipe for reading from guest process' stdout. */ + VBOXSERVICECTRLPIPEID_STDOUT = 40, + /** Pipe for reading from guest process' stderr. */ + VBOXSERVICECTRLPIPEID_STDERR = 50, + /** Notification pipe for waking up the guest process + * control thread. */ + VBOXSERVICECTRLPIPEID_IPC_NOTIFY = 100 +} VBOXSERVICECTRLPIPEID; + +/** + * Structure for one (opened) guest file. + */ +typedef struct VBOXSERVICECTRLFILE +{ + /** Pointer to list archor of following + * list node. + * @todo Would be nice to have a RTListGetAnchor(). */ + PRTLISTANCHOR pAnchor; + /** Node to global guest control file list. */ + /** @todo Use a map later? */ + RTLISTNODE Node; + /** The file name. */ + char szName[RTPATH_MAX]; + /** The file handle on the guest. */ + RTFILE hFile; + /** File handle to identify this file. */ + uint32_t uHandle; + /** Context ID. */ + uint32_t uContextID; +} VBOXSERVICECTRLFILE; +/** Pointer to thread data. */ +typedef VBOXSERVICECTRLFILE *PVBOXSERVICECTRLFILE; + +typedef struct VBOXSERVICECTRLSESSIONSTARTUPINFO +{ + /** The session's protocol version to use. */ + uint32_t uProtocol; + /** The session's ID. */ + uint32_t uSessionID; + /** User name (account) to start the guest session under. */ + char szUser[GUESTPROCESS_MAX_USER_LEN]; + /** Password of specified user name (account). */ + char szPassword[GUESTPROCESS_MAX_PASSWORD_LEN]; + /** Domain of the user account. */ + char szDomain[GUESTPROCESS_MAX_DOMAIN_LEN]; + /** Session creation flags. + * @sa VBOXSERVICECTRLSESSIONSTARTUPFLAG_* flags. */ + uint32_t uFlags; +} VBOXSERVICECTRLSESSIONSTARTUPINFO; +/** Pointer to thread data. */ +typedef VBOXSERVICECTRLSESSIONSTARTUPINFO *PVBOXSERVICECTRLSESSIONSTARTUPINFO; + +/** + * Structure for a guest session thread to + * observe/control the forked session instance from + * the VBoxService main executable. + */ +typedef struct VBOXSERVICECTRLSESSIONTHREAD +{ + /** Node to global guest control session list. */ + /** @todo Use a map later? */ + RTLISTNODE Node; + /** The sessions's startup info. */ + VBOXSERVICECTRLSESSIONSTARTUPINFO + StartupInfo; + /** The worker thread. */ + RTTHREAD Thread; + /** Critical section for thread-safe use. */ + RTCRITSECT CritSect; + /** Process handle for forked child. */ + RTPROCESS hProcess; + /** Shutdown indicator; will be set when the thread + * needs (or is asked) to shutdown. */ + bool volatile fShutdown; + /** Indicator set by the service thread exiting. */ + bool volatile fStopped; + /** Whether the thread was started or not. */ + bool fStarted; +#if 0 /* Pipe IPC not used yet. */ + /** Pollset containing all the pipes. */ + RTPOLLSET hPollSet; + RTPIPE hStdInW; + RTPIPE hStdOutR; + RTPIPE hStdErrR; + struct StdPipe + { + RTHANDLE hChild; + PRTHANDLE phChild; + } StdIn, + StdOut, + StdErr; + /** The notification pipe associated with this guest session. + * This is NIL_RTPIPE for output pipes. */ + RTPIPE hNotificationPipeW; + /** The other end of hNotificationPipeW. */ + RTPIPE hNotificationPipeR; +#endif +} VBOXSERVICECTRLSESSIONTHREAD; +/** Pointer to thread data. */ +typedef VBOXSERVICECTRLSESSIONTHREAD *PVBOXSERVICECTRLSESSIONTHREAD; + +/** Flag indicating that this session has been forked from + * the main executable. */ +#define VBOXSERVICECTRLSESSION_FLAG_FORK RT_BIT(0) +/** Flag indicating that this session is anonymous, that is, + * it will run start guest processes with the same credentials + * as the main executable. */ +#define VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS RT_BIT(1) +/** Flag indicating that started guest processes will dump their + * stdout output to a separate file on disk. For debugging. */ +#define VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT RT_BIT(2) +/** Flag indicating that started guest processes will dump their + * stderr output to a separate file on disk. For debugging. */ +#define VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR RT_BIT(3) + +/** + * Structure for maintaining a guest session. This also + * contains all started threads (e.g. for guest processes). + * + * This structure can act in two different ways: + * - For legacy guest control handling (protocol version < 2) + * this acts as a per-guest process structure containing all + * the information needed to get a guest process up and running. + * - For newer guest control protocols (>= 2) this structure is + * part of the forked session child, maintaining all guest + * control objects under it. + */ +typedef struct VBOXSERVICECTRLSESSION +{ + /* The session's startup information. */ + VBOXSERVICECTRLSESSIONSTARTUPINFO + StartupInfo; + /** List of active guest process threads + * (VBOXSERVICECTRLPROCESS). */ + RTLISTANCHOR lstProcesses; + /** List of guest control files (VBOXSERVICECTRLFILE). */ + RTLISTANCHOR lstFiles; + /** The session's critical section. */ + RTCRITSECT CritSect; + /** Internal session flags, not related + * to StartupInfo stuff. + * @sa VBOXSERVICECTRLSESSION_FLAG_* flags. */ + uint32_t uFlags; + /** How many processes do we allow keeping around at a time? */ + uint32_t uProcsMaxKept; +} VBOXSERVICECTRLSESSION; +/** Pointer to guest session. */ +typedef VBOXSERVICECTRLSESSION *PVBOXSERVICECTRLSESSION; + +/** + * Structure holding information for starting a guest + * process. + */ +typedef struct VBOXSERVICECTRLPROCSTARTUPINFO +{ + /** Full qualified path of process to start (without arguments). */ + char szCmd[GUESTPROCESS_MAX_CMD_LEN]; + /** Process execution flags. @sa */ + uint32_t uFlags; + /** Command line arguments. */ + char szArgs[GUESTPROCESS_MAX_ARGS_LEN]; + /** Number of arguments specified in pszArgs. */ + uint32_t uNumArgs; + /** String of environment variables ("FOO=BAR") to pass to the process + * to start. */ + char szEnv[GUESTPROCESS_MAX_ENV_LEN]; + /** Size (in bytes) of environment variables block. */ + uint32_t cbEnv; + /** Number of environment variables specified in pszEnv. */ + uint32_t uNumEnvVars; + /** User name (account) to start the process under. */ + char szUser[GUESTPROCESS_MAX_USER_LEN]; + /** Password of specified user name (account). */ + char szPassword[GUESTPROCESS_MAX_PASSWORD_LEN]; + /** Time limit (in ms) of the process' life time. */ + uint32_t uTimeLimitMS; + /** Process priority. */ + uint32_t uPriority; + /** Process affinity. At the moment we support + * up to 4 * 64 = 256 CPUs. */ + uint64_t uAffinity[4]; + /** Number of used process affinity blocks. */ + uint32_t uNumAffinity; +} VBOXSERVICECTRLPROCSTARTUPINFO; +/** Pointer to a guest process block. */ +typedef VBOXSERVICECTRLPROCSTARTUPINFO *PVBOXSERVICECTRLPROCSTARTUPINFO; + +/** + * Structure for holding data for one (started) guest process. + */ +typedef struct VBOXSERVICECTRLPROCESS +{ + /** Node. */ + RTLISTNODE Node; + /** Process handle. */ + RTPROCESS hProcess; + /** Number of references using this struct. */ + uint32_t cRefs; + /** The worker thread. */ + RTTHREAD Thread; + /** The session this guest process + * is bound to. */ + PVBOXSERVICECTRLSESSION pSession; + /** Shutdown indicator; will be set when the thread + * needs (or is asked) to shutdown. */ + bool volatile fShutdown; + /** Whether the guest process thread was stopped + * or not. */ + bool volatile fStopped; + /** Whether the guest process thread was started + * or not. */ + bool fStarted; + /** Client ID. */ + uint32_t uClientID; + /** Context ID. */ + uint32_t uContextID; + /** Critical section for thread-safe use. */ + RTCRITSECT CritSect; + /** Process startup information. */ + VBOXSERVICECTRLPROCSTARTUPINFO + StartupInfo; + /** The process' PID assigned by the guest OS. */ + uint32_t uPID; + /** The process' request queue to handle requests + * from the outside, e.g. the session. */ + RTREQQUEUE hReqQueue; + /** Our pollset, used for accessing the process' + * std* pipes + the notification pipe. */ + RTPOLLSET hPollSet; + /** StdIn pipe for addressing writes to the + * guest process' stdin.*/ + RTPIPE hPipeStdInW; + /** StdOut pipe for addressing reads from + * guest process' stdout.*/ + RTPIPE hPipeStdOutR; + /** StdOut pipe for addressing reads from + * guest process' stdout.*/ + RTPIPE hPipeStdErrR; + /** The notification pipe associated with this guest process. + * This is NIL_RTPIPE for output pipes. */ + RTPIPE hNotificationPipeW; + /** The other end of hNotificationPipeW. */ + RTPIPE hNotificationPipeR; +} VBOXSERVICECTRLPROCESS; +/** Pointer to thread data. */ +typedef VBOXSERVICECTRLPROCESS *PVBOXSERVICECTRLPROCESS; + +RT_C_DECLS_BEGIN + +/** + * Note on naming conventions: + * - VBoxServiceControl* is named everything sub service module related, e.g. + * everything which is callable by main() and/or the service dispatcher(s). + * - GstCntl* is named everything which declared extern and thus can be called + * by different guest control modules as needed. + * - gstcntl (all lowercase) is a purely static function to split up functionality + * inside a module. + */ + +/* Guest session thread handling. */ +extern int GstCntlSessionThreadCreate(PRTLISTANCHOR pList, const PVBOXSERVICECTRLSESSIONSTARTUPINFO pSessionStartupInfo, PVBOXSERVICECTRLSESSIONTHREAD *ppSessionThread); +extern int GstCntlSessionThreadDestroy(PVBOXSERVICECTRLSESSIONTHREAD pSession, uint32_t uFlags); +extern int GstCntlSessionThreadDestroyAll(PRTLISTANCHOR pList, uint32_t uFlags); +extern int GstCntlSessionThreadTerminate(PVBOXSERVICECTRLSESSIONTHREAD pSession); +extern RTEXITCODE VBoxServiceControlSessionForkInit(int argc, char **argv); +/* Per-session functions. */ +extern PVBOXSERVICECTRLPROCESS GstCntlSessionRetainProcess(PVBOXSERVICECTRLSESSION pSession, uint32_t uPID); +extern int GstCntlSessionClose(PVBOXSERVICECTRLSESSION pSession); +extern int GstCntlSessionDestroy(PVBOXSERVICECTRLSESSION pSession); +extern int GstCntlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t uFlags); +extern int GstCntlSessionHandler(PVBOXSERVICECTRLSESSION pSession, uint32_t uMsg, PVBGLR3GUESTCTRLCMDCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf, volatile bool *pfShutdown); +extern int GstCntlSessionProcessAdd(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLPROCESS pProcess); +extern int GstCntlSessionProcessRemove(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLPROCESS pProcess); +extern int GstCntlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession, bool *pbAllowed); +extern int GstCntlSessionReapProcesses(PVBOXSERVICECTRLSESSION pSession); +/* Per-guest process functions. */ +extern int GstCntlProcessFree(PVBOXSERVICECTRLPROCESS pProcess); +extern int GstCntlProcessHandleInput(PVBOXSERVICECTRLPROCESS pProcess, PVBGLR3GUESTCTRLCMDCTX pHostCtx, bool fPendingClose, void *pvBuf, uint32_t cbBuf); +extern int GstCntlProcessHandleOutput(PVBOXSERVICECTRLPROCESS pProcess, PVBGLR3GUESTCTRLCMDCTX pHostCtx, uint32_t uHandle, uint32_t cbToRead, uint32_t uFlags); +extern int GstCntlProcessHandleTerm(PVBOXSERVICECTRLPROCESS pProcess); +extern void GstCntlProcessRelease(PVBOXSERVICECTRLPROCESS pProcess); +extern int GstCntlProcessStart(const PVBOXSERVICECTRLSESSION pSession, const PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo, uint32_t uContext); +extern int GstCntlProcessStop(PVBOXSERVICECTRLPROCESS pProcess); +extern int GstCntlProcessWait(const PVBOXSERVICECTRLPROCESS pProcess, RTMSINTERVAL msTimeout, int *pRc); + +RT_C_DECLS_END + +#endif /* ___VBoxServiceControl_h */ + |