VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h@ 45604

Last change on this file since 45604 was 45604, checked in by vboxsync, 12 years ago

VBoxService/GuestCtrl: Added asynchronous request handling, more fixes for testcases.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.5 KB
Line 
1/* $Id: VBoxServiceControl.h 45604 2013-04-18 12:21:20Z vboxsync $ */
2/** @file
3 * VBoxServiceControl.h - Internal guest control definitions.
4 */
5
6/*
7 * Copyright (C) 2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___VBoxServiceControl_h
19#define ___VBoxServiceControl_h
20
21#include <iprt/list.h>
22#include <iprt/critsect.h>
23
24#include <VBox/VBoxGuestLib.h>
25#include <VBox/HostServices/GuestControlSvc.h>
26
27
28/**
29 * Pipe IDs for handling the guest process poll set.
30 */
31typedef enum VBOXSERVICECTRLPIPEID
32{
33 VBOXSERVICECTRLPIPEID_UNKNOWN = 0,
34 VBOXSERVICECTRLPIPEID_STDIN = 10,
35 VBOXSERVICECTRLPIPEID_STDIN_WRITABLE = 11,
36 /** Pipe for reading from guest process' stdout. */
37 VBOXSERVICECTRLPIPEID_STDOUT = 40,
38 /** Pipe for reading from guest process' stderr. */
39 VBOXSERVICECTRLPIPEID_STDERR = 50,
40 /** Notification pipe for waking up the guest process
41 * control thread. */
42 VBOXSERVICECTRLPIPEID_IPC_NOTIFY = 100
43} VBOXSERVICECTRLPIPEID;
44
45/**
46 * Request types to perform on a started guest process.
47 */
48typedef enum VBOXSERVICECTRLREQUESTTYPE
49{
50 /** Unknown request. */
51 VBOXSERVICECTRLREQUEST_UNKNOWN = 0,
52 /** Performs reading from stdout. */
53 VBOXSERVICECTRLREQUEST_PROC_STDOUT = 50,
54 /** Performs reading from stderr. */
55 VBOXSERVICECTRLREQUEST_PROC_STDERR = 60,
56 /** Performs writing to stdin. */
57 VBOXSERVICECTRLREQUEST_PROC_STDIN = 70,
58 /** Same as VBOXSERVICECTRLREQUEST_STDIN_WRITE, but
59 * marks the end of input. */
60 VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF = 71,
61 /** Kill/terminate process. */
62 VBOXSERVICECTRLREQUEST_PROC_TERM = 90,
63 /** Gently ask process to terminate. */
64 /** @todo Implement this! */
65 VBOXSERVICECTRLREQUEST_PROC_HUP = 91,
66 /** Wait for a certain event to happen. */
67 VBOXSERVICECTRLREQUEST_WAIT_FOR = 100
68} VBOXSERVICECTRLREQUESTTYPE;
69
70/**
71 * Thread list types.
72 */
73typedef enum VBOXSERVICECTRLTHREADLISTTYPE
74{
75 /** Unknown list -- uncool to use. */
76 VBOXSERVICECTRLTHREADLIST_UNKNOWN = 0,
77 /** Stopped list: Here all guest threads end up
78 * when they reached the stopped state and can
79 * be shut down / free'd safely. */
80 VBOXSERVICECTRLTHREADLIST_STOPPED = 1,
81 /**
82 * Started list: Here all threads are registered
83 * when they're up and running (that is, accepting
84 * commands).
85 */
86 VBOXSERVICECTRLTHREADLIST_RUNNING = 2
87} VBOXSERVICECTRLTHREADLISTTYPE;
88
89/**
90 * Structure to perform a request on a started guest
91 * process. Needed for letting the main guest control thread
92 * to communicate (and wait) for a certain operation which
93 * will be done in context of the started guest process thread.
94 */
95typedef struct VBOXSERVICECTRLREQUEST
96{
97 /** Event semaphore to serialize access. */
98 RTSEMEVENTMULTI Event;
99 /** Flag indicating if this request is asynchronous or not. */
100 bool fAsync;
101 /** The request type to handle. */
102 VBOXSERVICECTRLREQUESTTYPE enmType;
103 /** Payload size; on input, this contains the (maximum) amount
104 * of data the caller wants to write or to read. On output,
105 * this show the actual amount of data read/written. */
106 size_t cbData;
107 /** Payload data; a pre-allocated data buffer for input/output. */
108 void *pvData;
109 /** The context ID which is required to complete the
110 * request. Not used at the moment. */
111 uint32_t uCID;
112 /** The overall result of the operation. */
113 int rc;
114} VBOXSERVICECTRLREQUEST;
115/** Pointer to request. */
116typedef VBOXSERVICECTRLREQUEST *PVBOXSERVICECTRLREQUEST;
117
118typedef struct VBOXSERVICECTRLREQDATA_WAIT_FOR
119{
120 /** Waiting flags. */
121 uint32_t uWaitFlags;
122 /** Timeout in (ms) for the waiting operation. */
123 uint32_t uTimeoutMS;
124} VBOXSERVICECTRLREQDATA_WAIT_FOR, *PVBOXSERVICECTRLREQDATA_WAIT_FOR;
125
126/**
127 * Structure for one (opened) guest file.
128 */
129typedef struct VBOXSERVICECTRLFILE
130{
131 /** Pointer to list archor of following
132 * list node.
133 * @todo Would be nice to have a RTListGetAnchor(). */
134 PRTLISTANCHOR pAnchor;
135 /** Node to global guest control file list. */
136 /** @todo Use a map later? */
137 RTLISTNODE Node;
138 /** The file name. */
139 char szName[RTPATH_MAX];
140 /** The file handle on the guest. */
141 RTFILE hFile;
142 /** File handle to identify this file. */
143 uint32_t uHandle;
144 /** Context ID. */
145 uint32_t uContextID;
146} VBOXSERVICECTRLFILE;
147/** Pointer to thread data. */
148typedef VBOXSERVICECTRLFILE *PVBOXSERVICECTRLFILE;
149
150typedef struct VBOXSERVICECTRLSESSIONSTARTUPINFO
151{
152 /** The session's protocol version to use. */
153 uint32_t uProtocol;
154 /** The session's ID. */
155 uint32_t uSessionID;
156 /** User name (account) to start the guest session under. */
157 char szUser[GUESTPROCESS_MAX_USER_LEN];
158 /** Password of specified user name (account). */
159 char szPassword[GUESTPROCESS_MAX_PASSWORD_LEN];
160 /** Domain of the user account. */
161 char szDomain[GUESTPROCESS_MAX_DOMAIN_LEN];
162 /** Session creation flags.
163 * @sa VBOXSERVICECTRLSESSIONSTARTUPFLAG_* flags. */
164 uint32_t uFlags;
165} VBOXSERVICECTRLSESSIONSTARTUPINFO;
166/** Pointer to thread data. */
167typedef VBOXSERVICECTRLSESSIONSTARTUPINFO *PVBOXSERVICECTRLSESSIONSTARTUPINFO;
168
169/**
170 * Structure for a guest session thread to
171 * observe/control the forked session instance from
172 * the VBoxService main executable.
173 */
174typedef struct VBOXSERVICECTRLSESSIONTHREAD
175{
176 /** Node to global guest control session list. */
177 /** @todo Use a map later? */
178 RTLISTNODE Node;
179 /** The sessions's startup info. */
180 VBOXSERVICECTRLSESSIONSTARTUPINFO
181 StartupInfo;
182 /** The worker thread. */
183 RTTHREAD Thread;
184 /** Critical section for thread-safe use. */
185 RTCRITSECT CritSect;
186 /** Process handle for forked child. */
187 RTPROCESS hProcess;
188 /** Shutdown indicator; will be set when the thread
189 * needs (or is asked) to shutdown. */
190 bool volatile fShutdown;
191 /** Indicator set by the service thread exiting. */
192 bool volatile fStopped;
193 /** Whether the thread was started or not. */
194 bool fStarted;
195#if 0 /* Pipe IPC not used yet. */
196 /** Pollset containing all the pipes. */
197 RTPOLLSET hPollSet;
198 RTPIPE hStdInW;
199 RTPIPE hStdOutR;
200 RTPIPE hStdErrR;
201 struct StdPipe
202 {
203 RTHANDLE hChild;
204 PRTHANDLE phChild;
205 } StdIn,
206 StdOut,
207 StdErr;
208 /** The notification pipe associated with this guest session.
209 * This is NIL_RTPIPE for output pipes. */
210 RTPIPE hNotificationPipeW;
211 /** The other end of hNotificationPipeW. */
212 RTPIPE hNotificationPipeR;
213#endif
214} VBOXSERVICECTRLSESSIONTHREAD;
215/** Pointer to thread data. */
216typedef VBOXSERVICECTRLSESSIONTHREAD *PVBOXSERVICECTRLSESSIONTHREAD;
217
218/** Flag indicating that this session has been forked from
219 * the main executable. */
220#define VBOXSERVICECTRLSESSION_FLAG_FORK RT_BIT(0)
221/** Flag indicating that this session is anonymous, that is,
222 * it will run start guest processes with the same credentials
223 * as the main executable. */
224#define VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS RT_BIT(1)
225/** Flag indicating that start guest processes will dump their
226 * stdout output to a separate file on disk. For debugging. */
227#define VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT RT_BIT(2)
228/** Flag indicating that start guest processes will dump their
229 * stderr output to a separate file on disk. For debugging. */
230#define VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR RT_BIT(3)
231
232/**
233 * Strucutre for maintaining a guest session. This also
234 * contains all started threads (e.g. for guest processes).
235 *
236 * This structure can act in two different ways:
237 * - For legacy guest control handling (protocol version < 2)
238 * this acts as a per-guest process structure containing all
239 * the information needed to get a guest process up and running.
240 * - For newer guest control protocols (>= 2) this structure is
241 * part of the forked session child, maintaining all guest
242 * control objects under it.
243 */
244typedef struct VBOXSERVICECTRLSESSION
245{
246 /* The session's startup information. */
247 VBOXSERVICECTRLSESSIONSTARTUPINFO
248 StartupInfo;
249 /** List of active guest process threads (VBOXSERVICECTRLPROCESS). */
250 RTLISTANCHOR lstProcessesActive;
251 /** List of inactive guest process threads (VBOXSERVICECTRLPROCESS). */
252 /** @todo Still needed? */
253 RTLISTANCHOR lstProcessesInactive;
254 /** List of guest control files (VBOXSERVICECTRLFILE). */
255 RTLISTANCHOR lstFiles;
256 /** The session's critical section. */
257 RTCRITSECT CritSect;
258 /** Session flags. */
259 uint32_t uFlags;
260 /** How many processes do we allow keeping around at a time? */
261 uint32_t uProcsMaxKept;
262} VBOXSERVICECTRLSESSION;
263/** Pointer to guest session. */
264typedef VBOXSERVICECTRLSESSION *PVBOXSERVICECTRLSESSION;
265
266/**
267 * Structure holding information for starting a guest
268 * process.
269 */
270typedef struct VBOXSERVICECTRLPROCSTARTUPINFO
271{
272 /** Full qualified path of process to start (without arguments). */
273 char szCmd[GUESTPROCESS_MAX_CMD_LEN];
274 /** Process execution flags. @sa */
275 uint32_t uFlags;
276 /** Command line arguments. */
277 char szArgs[GUESTPROCESS_MAX_ARGS_LEN];
278 /** Number of arguments specified in pszArgs. */
279 uint32_t uNumArgs;
280 /** String of environment variables ("FOO=BAR") to pass to the process
281 * to start. */
282 char szEnv[GUESTPROCESS_MAX_ENV_LEN];
283 /** Size (in bytes) of environment variables block. */
284 uint32_t cbEnv;
285 /** Number of environment variables specified in pszEnv. */
286 uint32_t uNumEnvVars;
287 /** User name (account) to start the process under. */
288 char szUser[GUESTPROCESS_MAX_USER_LEN];
289 /** Password of specified user name (account). */
290 char szPassword[GUESTPROCESS_MAX_PASSWORD_LEN];
291 /** Time limit (in ms) of the process' life time. */
292 uint32_t uTimeLimitMS;
293 /** Process priority. */
294 uint32_t uPriority;
295 /** Process affinity. At the moment we support
296 * up to 4 * 64 = 256 CPUs. */
297 uint64_t uAffinity[4];
298 /** Number of used process affinity blocks. */
299 uint32_t uNumAffinity;
300} VBOXSERVICECTRLPROCSTARTUPINFO;
301/** Pointer to a guest process block. */
302typedef VBOXSERVICECTRLPROCSTARTUPINFO *PVBOXSERVICECTRLPROCSTARTUPINFO;
303
304/**
305 * Structure for holding data for one (started) guest process.
306 */
307typedef struct VBOXSERVICECTRLPROCESS
308{
309 /** Pointer to list archor of following
310 * list node.
311 * @todo Would be nice to have a RTListGetAnchor(). */
312 PRTLISTANCHOR pAnchor;
313 /** Node. */
314 RTLISTNODE Node;
315 /** The worker thread. */
316 RTTHREAD Thread;
317 /** The session this guest process
318 * is bound to. */
319 PVBOXSERVICECTRLSESSION pSession;
320 /** Shutdown indicator; will be set when the thread
321 * needs (or is asked) to shutdown. */
322 bool volatile fShutdown;
323 /** Whether the guest process thread already was
324 * stopped or not. */
325 bool volatile fStopped;
326 /** Whether the guest process thread was started
327 * or not. */
328 bool fStarted;
329 /** Client ID. */
330 uint32_t uClientID;
331 /** Context ID. */
332 uint32_t uContextID;
333 /** Critical section for thread-safe use. */
334 RTCRITSECT CritSect;
335 /** Process startup information. */
336 VBOXSERVICECTRLPROCSTARTUPINFO
337 StartupInfo;
338 /** The process' PID assigned by the guest OS. */
339 uint32_t uPID;
340 /** Pointer to the current IPC request being
341 * processed. We only support one request at a
342 * time at the moment.
343 ** @todo Implemenet a request queue. */
344 PVBOXSERVICECTRLREQUEST pRequest;
345 /** StdIn pipe for addressing writes to the
346 * guest process' stdin.*/
347 RTPIPE pipeStdInW;
348 /** The notification pipe associated with this guest process.
349 * This is NIL_RTPIPE for output pipes. */
350 RTPIPE hNotificationPipeW;
351 /** The other end of hNotificationPipeW. */
352 RTPIPE hNotificationPipeR;
353} VBOXSERVICECTRLPROCESS;
354/** Pointer to thread data. */
355typedef VBOXSERVICECTRLPROCESS *PVBOXSERVICECTRLPROCESS;
356
357RT_C_DECLS_BEGIN
358
359/**
360 * Note on naming conventions:
361 * - VBoxServiceControl* is named everything sub service module related, e.g.
362 * everything which is callable by main() and/or the service dispatcher(s).
363 * - GstCntl* is named everything which declared extern and thus can be called
364 * by different guest control modules as needed.
365 * - gstcntl (all lowercase) is a purely static function to split up functionality
366 * inside a module.
367 */
368
369/* Guest session thread handling. */
370extern int GstCntlSessionThreadCreate(PRTLISTANCHOR pList, const PVBOXSERVICECTRLSESSIONSTARTUPINFO pSessionStartupInfo, PVBOXSERVICECTRLSESSIONTHREAD *ppSessionThread);
371extern int GstCntlSessionThreadDestroy(PVBOXSERVICECTRLSESSIONTHREAD pSession, uint32_t uFlags);
372extern int GstCntlSessionThreadDestroyAll(PRTLISTANCHOR pList, uint32_t uFlags);
373extern int GstCntlSessionThreadTerminate(PVBOXSERVICECTRLSESSIONTHREAD pSession);
374extern RTEXITCODE VBoxServiceControlSessionForkInit(int argc, char **argv);
375
376/* asdf */
377extern PVBOXSERVICECTRLPROCESS GstCntlSessionAcquireProcess(PVBOXSERVICECTRLSESSION pSession, uint32_t uPID);
378extern int GstCntlSessionClose(PVBOXSERVICECTRLSESSION pSession);
379extern int GstCntlSessionDestroy(PVBOXSERVICECTRLSESSION pSession);
380extern int GstCntlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t uFlags);
381extern int GstCntlSessionHandler(PVBOXSERVICECTRLSESSION pSession, uint32_t uMsg, PVBGLR3GUESTCTRLCMDCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf, volatile bool *pfShutdown);
382extern int GstCntlSessionListSet(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLPROCESS pThread, VBOXSERVICECTRLTHREADLISTTYPE enmList);
383extern int GstCntlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession, bool *pbAllowed);
384extern int GstCntlSessionReapProcesses(PVBOXSERVICECTRLSESSION pSession);
385/* Per-thread guest process functions. */
386extern int GstCntlProcessPerform(PVBOXSERVICECTRLPROCESS pProcess, PVBOXSERVICECTRLREQUEST pRequest, bool fAsync);
387extern int GstCntlProcessStart(const PVBOXSERVICECTRLSESSION pSession, const PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo, uint32_t uContext);
388extern int GstCntlProcessStop(PVBOXSERVICECTRLPROCESS pProcess);
389extern void GstCntlProcessRelease(const PVBOXSERVICECTRLPROCESS pProcess);
390extern int GstCntlProcessWait(const PVBOXSERVICECTRLPROCESS pProcess, RTMSINTERVAL msTimeout, int *pRc);
391extern int GstCntlProcessFree(PVBOXSERVICECTRLPROCESS pProcess);
392/* Process request handling. */
393extern int GstCntlProcessRequestAlloc(PVBOXSERVICECTRLREQUEST *ppReq, VBOXSERVICECTRLREQUESTTYPE enmType);
394extern int GstCntlProcessRequestAllocEx(PVBOXSERVICECTRLREQUEST *ppReq, VBOXSERVICECTRLREQUESTTYPE enmType, void *pvData, size_t cbData, uint32_t uCID);
395extern void GstCntlProcessRequestFree(PVBOXSERVICECTRLREQUEST pReq);
396/* Per-session functions. */
397extern int GstCntlSessionHandleProcExec(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
398extern int GstCntlSessionHandleProcInput(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf);
399extern int GstCntlSessionHandleProcOutput(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
400extern int GstCntlSessionHandleProcTerminate(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
401extern int GstCntlSessionHandleProcWaitFor(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
402
403RT_C_DECLS_END
404
405#endif /* ___VBoxServiceControl_h */
406
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette