VirtualBox

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

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

GuestCtrl: Implemented using (public) VirtualBox events instead of own callback mechanisms. Bugfixes for testcases (still work in progress).

  • 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 45415 2013-04-08 21:40:42Z 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 /** Main control thread asked used to quit. */
53 VBOXSERVICECTRLREQUEST_QUIT = 1,
54 /** Performs reading from stdout. */
55 VBOXSERVICECTRLREQUEST_PROC_STDOUT = 50,
56 /** Performs reading from stderr. */
57 VBOXSERVICECTRLREQUEST_PROC_STDERR = 60,
58 /** Performs writing to stdin. */
59 VBOXSERVICECTRLREQUEST_PROC_STDIN = 70,
60 /** Same as VBOXSERVICECTRLREQUEST_STDIN_WRITE, but
61 * marks the end of input. */
62 VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF = 71,
63 /** Kill/terminate process. */
64 VBOXSERVICECTRLREQUEST_PROC_TERM = 90,
65 /** Gently ask process to terminate. */
66 /** @todo Implement this! */
67 VBOXSERVICECTRLREQUEST_PROC_HUP = 91,
68 /** Wait for a certain event to happen. */
69 VBOXSERVICECTRLREQUEST_WAIT_FOR = 100
70} VBOXSERVICECTRLREQUESTTYPE;
71
72/**
73 * Thread list types.
74 */
75typedef enum VBOXSERVICECTRLTHREADLISTTYPE
76{
77 /** Unknown list -- uncool to use. */
78 VBOXSERVICECTRLTHREADLIST_UNKNOWN = 0,
79 /** Stopped list: Here all guest threads end up
80 * when they reached the stopped state and can
81 * be shut down / free'd safely. */
82 VBOXSERVICECTRLTHREADLIST_STOPPED = 1,
83 /**
84 * Started list: Here all threads are registered
85 * when they're up and running (that is, accepting
86 * commands).
87 */
88 VBOXSERVICECTRLTHREADLIST_RUNNING = 2
89} VBOXSERVICECTRLTHREADLISTTYPE;
90
91/**
92 * Structure to perform a request on a started guest
93 * process. Needed for letting the main guest control thread
94 * to communicate (and wait) for a certain operation which
95 * will be done in context of the started guest process thread.
96 */
97typedef struct VBOXSERVICECTRLREQUEST
98{
99 /** Event semaphore to serialize access. */
100 RTSEMEVENTMULTI Event;
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 /** Indicator set by the service thread exiting. */
324 bool volatile fStopped;
325 /** Whether the service was started or not. */
326 bool fStarted;
327 /** Client ID. */
328 uint32_t uClientID;
329 /** Context ID. */
330 uint32_t uContextID;
331 /** Critical section for thread-safe use. */
332 RTCRITSECT CritSect;
333 /** Process startup information. */
334 VBOXSERVICECTRLPROCSTARTUPINFO
335 StartupInfo;
336 /** The process' PID assigned by the guest OS. */
337 uint32_t uPID;
338 /** Pointer to the current IPC request being
339 * processed. We only support one request at a
340 * time at the moment.
341 ** @todo Implemenet a request queue. */
342 PVBOXSERVICECTRLREQUEST pRequest;
343 /** StdIn pipe for addressing writes to the
344 * guest process' stdin.*/
345 RTPIPE pipeStdInW;
346 /** The notification pipe associated with this guest process.
347 * This is NIL_RTPIPE for output pipes. */
348 RTPIPE hNotificationPipeW;
349 /** The other end of hNotificationPipeW. */
350 RTPIPE hNotificationPipeR;
351} VBOXSERVICECTRLPROCESS;
352/** Pointer to thread data. */
353typedef VBOXSERVICECTRLPROCESS *PVBOXSERVICECTRLPROCESS;
354
355RT_C_DECLS_BEGIN
356
357/**
358 * Note on naming conventions:
359 * - VBoxServiceControl* is named everything sub service module related, e.g.
360 * everything which is callable by main() and/or the service dispatcher(s).
361 * - GstCntl* is named everything which declared extern and thus can be called
362 * by different guest control modules as needed.
363 * - gstcntl (all lowercase) is a purely static function to split up functionality
364 * inside a module.
365 */
366
367/* Guest session thread handling. */
368extern int GstCntlSessionThreadCreate(PRTLISTANCHOR pList, const PVBOXSERVICECTRLSESSIONSTARTUPINFO pSessionStartupInfo, PVBOXSERVICECTRLSESSIONTHREAD *ppSessionThread);
369extern int GstCntlSessionThreadDestroy(PVBOXSERVICECTRLSESSIONTHREAD pSession, uint32_t uFlags);
370extern int GstCntlSessionThreadDestroyAll(PRTLISTANCHOR pList, uint32_t uFlags);
371extern int GstCntlSessionThreadTerminate(PVBOXSERVICECTRLSESSIONTHREAD pSession);
372extern RTEXITCODE VBoxServiceControlSessionForkInit(int argc, char **argv);
373
374/* asdf */
375extern PVBOXSERVICECTRLPROCESS GstCntlSessionAcquireProcess(PVBOXSERVICECTRLSESSION pSession, uint32_t uPID);
376extern int GstCntlSessionClose(PVBOXSERVICECTRLSESSION pSession);
377extern int GstCntlSessionDestroy(PVBOXSERVICECTRLSESSION pSession);
378extern int GstCntlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t uFlags);
379extern int GstCntlSessionHandler(PVBOXSERVICECTRLSESSION pSession, uint32_t uMsg, PVBGLR3GUESTCTRLCMDCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf, volatile bool *pfShutdown);
380extern int GstCntlSessionListSet(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLPROCESS pThread, VBOXSERVICECTRLTHREADLISTTYPE enmList);
381extern int GstCntlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession, bool *pbAllowed);
382extern int GstCntlSessionReapProcesses(PVBOXSERVICECTRLSESSION pSession);
383/* Per-thread guest process functions. */
384extern int GstCntlProcessPerform(PVBOXSERVICECTRLPROCESS pProcess, PVBOXSERVICECTRLREQUEST pRequest);
385extern int GstCntlProcessStart(const PVBOXSERVICECTRLSESSION pSession, const PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo, uint32_t uContext);
386extern int GstCntlProcessStop(PVBOXSERVICECTRLPROCESS pProcess);
387extern void GstCntlProcessRelease(const PVBOXSERVICECTRLPROCESS pProcess);
388extern int GstCntlProcessWait(const PVBOXSERVICECTRLPROCESS pProcess, RTMSINTERVAL msTimeout, int *pRc);
389extern int GstCntlProcessFree(PVBOXSERVICECTRLPROCESS pProcess);
390/* Process request handling. */
391extern int GstCntlProcessRequestAlloc(PVBOXSERVICECTRLREQUEST *ppReq, VBOXSERVICECTRLREQUESTTYPE enmType);
392extern int GstCntlProcessRequestAllocEx(PVBOXSERVICECTRLREQUEST *ppReq, VBOXSERVICECTRLREQUESTTYPE enmType, void *pvData, size_t cbData, uint32_t uCID);
393extern void GstCntlProcessRequestFree(PVBOXSERVICECTRLREQUEST pReq);
394/* Per-session functions. */
395extern int GstCntlSessionHandleProcExec(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
396extern int GstCntlSessionHandleProcInput(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf);
397extern int GstCntlSessionHandleProcOutput(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
398extern int GstCntlSessionHandleProcTerminate(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
399extern int GstCntlSessionHandleProcWaitFor(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx);
400
401RT_C_DECLS_END
402
403#endif /* ___VBoxServiceControl_h */
404
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