VirtualBox

source: vbox/trunk/src/VBox/Devices/Trace/DrvIfsTrace.cpp

Last change on this file was 104992, checked in by vboxsync, 3 months ago

Devices/Trace: Log VM reset/suspend/resume events in the tracelog, bugref:10701

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/* $Id: DrvIfsTrace.cpp 104992 2024-06-21 08:50:59Z vboxsync $ */
2/** @file
3 * VBox interface callback tracing driver.
4 */
5
6/*
7 * Copyright (C) 2020-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_MISC
33#include <VBox/log.h>
34#include <VBox/version.h>
35
36#include <iprt/errcore.h>
37#include <iprt/buildconfig.h>
38#include <iprt/tracelog.h>
39#include <iprt/uuid.h>
40
41#include "VBoxDD.h"
42#include "DrvIfsTraceInternal.h"
43
44
45/*
46 *
47 * IBase Implementation.
48 *
49 */
50
51
52static DECLCALLBACK(void *) drvIfTraceIBase_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
53{
54 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
55 PDRVIFTRACE pThis = PDMINS_2_DATA(pDrvIns, PDRVIFTRACE);
56
57 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
58 if (pThis->pISerialConBelow)
59 PDMIBASE_RETURN_INTERFACE(pszIID, PDMISERIALCONNECTOR, &pThis->ISerialConnector);
60 if (pThis->pISerialPortAbove)
61 PDMIBASE_RETURN_INTERFACE(pszIID, PDMISERIALPORT, &pThis->ISerialPort);
62
63 if (pThis->pITpmConBelow)
64 PDMIBASE_RETURN_INTERFACE(pszIID, PDMITPMCONNECTOR, &pThis->ITpmConnector);
65 if (pThis->pITpmPortAbove)
66 PDMIBASE_RETURN_INTERFACE(pszIID, PDMITPMPORT, &pThis->ITpmPort);
67
68 return NULL;
69}
70
71
72/*
73 *
74 * PDMDRVREG Methods
75 *
76 */
77static const RTTRACELOGEVTDESC g_IfTraceVmResumeEvtDesc =
78{
79 "IfTrace.VmResume",
80 "VM was resumed",
81 RTTRACELOGEVTSEVERITY_DEBUG,
82 0,
83 NULL
84};
85
86
87/**
88 * @callback_method_impl{FNPDMDRVRESUME}
89 */
90static DECLCALLBACK(void) drvIfTrace_Resume(PPDMDRVINS pDrvIns)
91{
92 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
93 PDRVIFTRACE pThis = PDMINS_2_DATA(pDrvIns, PDRVIFTRACE);
94 LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
95
96 int rcTraceLog = RTTraceLogWrEvtAddL(pThis->hTraceLog, &g_IfTraceVmResumeEvtDesc, 0, 0, 0);
97 if (RT_FAILURE(rcTraceLog))
98 LogRelMax(10, ("DrvIfTrace#%d: Failed to add event to trace log %Rrc\n", pThis->pDrvIns->iInstance, rcTraceLog));
99}
100
101
102
103static const RTTRACELOGEVTDESC g_IfTraceVmSuspendEvtDesc =
104{
105 "IfTrace.VmSuspend",
106 "VM was suspended",
107 RTTRACELOGEVTSEVERITY_DEBUG,
108 0,
109 NULL
110};
111
112
113/**
114 * @callback_method_impl{FNPDMDRVSUSPEND}
115 */
116static DECLCALLBACK(void) drvIfTrace_Suspend(PPDMDRVINS pDrvIns)
117{
118 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
119 PDRVIFTRACE pThis = PDMINS_2_DATA(pDrvIns, PDRVIFTRACE);
120 LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
121
122 int rcTraceLog = RTTraceLogWrEvtAddL(pThis->hTraceLog, &g_IfTraceVmSuspendEvtDesc, 0, 0, 0);
123 if (RT_FAILURE(rcTraceLog))
124 LogRelMax(10, ("DrvIfTrace#%d: Failed to add event to trace log %Rrc\n", pThis->pDrvIns->iInstance, rcTraceLog));
125}
126
127
128static const RTTRACELOGEVTDESC g_IfTraceVmResetEvtDesc =
129{
130 "IfTrace.VmReset",
131 "VM was reset",
132 RTTRACELOGEVTSEVERITY_DEBUG,
133 0,
134 NULL
135};
136
137/**
138 * @callback_method_impl{FNPDMDRVRESET}
139 */
140static DECLCALLBACK(void) drvIfTrace_Reset(PPDMDRVINS pDrvIns)
141{
142 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
143 PDRVIFTRACE pThis = PDMINS_2_DATA(pDrvIns, PDRVIFTRACE);
144 LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
145
146 int rcTraceLog = RTTraceLogWrEvtAddL(pThis->hTraceLog, &g_IfTraceVmResetEvtDesc, 0, 0, 0);
147 if (RT_FAILURE(rcTraceLog))
148 LogRelMax(10, ("DrvIfTrace#%d: Failed to add event to trace log %Rrc\n", pThis->pDrvIns->iInstance, rcTraceLog));
149}
150
151
152
153/**
154 * Destroys a interface filter driver instance.
155 *
156 * @copydoc FNPDMDRVDESTRUCT
157 */
158static DECLCALLBACK(void) drvIfTrace_Destruct(PPDMDRVINS pDrvIns)
159{
160 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
161 PDRVIFTRACE pThis = PDMINS_2_DATA(pDrvIns, PDRVIFTRACE);
162 LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
163
164 if (pThis->hTraceLog != NIL_RTTRACELOGWR)
165 {
166 RTTraceLogWrDestroy(pThis->hTraceLog);
167 pThis->hTraceLog = NIL_RTTRACELOGWR;
168 }
169}
170
171
172/**
173 * Construct a interface filter driver instance.
174 *
175 * @copydoc FNPDMDRVCONSTRUCT
176 */
177static DECLCALLBACK(int) drvIfTrace_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
178{
179 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
180 PDRVIFTRACE pThis = PDMINS_2_DATA(pDrvIns, PDRVIFTRACE);
181 PCPDMDRVHLPR3 pHlp = pDrvIns->pHlpR3;
182
183
184 /*
185 * Initialize the instance data.
186 */
187 pThis->pDrvIns = pDrvIns;
188 pThis->hTraceLog = NIL_RTTRACELOGWR;
189 pDrvIns->IBase.pfnQueryInterface = drvIfTraceIBase_QueryInterface;
190
191 drvIfsTrace_SerialIfInit(pThis);
192 drvIfsTrace_TpmIfInit(pThis);
193
194 /*
195 * Validate and read config.
196 */
197 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "TraceFilePath|TraceLocation", "");
198
199 char *pszLocation = NULL;
200 int rc = pHlp->pfnCFGMQueryStringAlloc(pCfg, "TraceFilePath", &pszLocation);
201 if (RT_SUCCESS(rc))
202 {
203 /* Try to create a file based trace log. */
204 rc = RTTraceLogWrCreateFile(&pThis->hTraceLog, RTBldCfgVersion(), pszLocation);
205 PDMDrvHlpMMHeapFree(pDrvIns, pszLocation);
206
207 AssertLogRelRCReturn(rc, rc);
208 }
209 else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
210 {
211 /* Try to connect to an external server. */
212 rc = pHlp->pfnCFGMQueryStringAlloc(pCfg, "TraceLocation", &pszLocation);
213 if (RT_FAILURE(rc))
214 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
215 N_("Configuration error: querying \"TraceLocation\" resulted in %Rrc"), rc);
216
217 char *pszPort = strchr(pszLocation, ':');
218 if (!pszPort)
219 return PDMDrvHlpVMSetError(pDrvIns, VERR_NOT_FOUND, RT_SRC_POS,
220 N_("IfTrace#%d: The location misses the port to connect to"),
221 pDrvIns->iInstance);
222
223 *pszPort = '\0'; /* Overwrite temporarily to avoid copying the hostname into a temporary buffer. */
224 uint32_t uPort = 0;
225 rc = RTStrToUInt32Ex(pszPort + 1, NULL, 10, &uPort);
226 if (RT_FAILURE(rc))
227 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
228 N_("IfTrace#%d: The port part of the location is not a numerical value"),
229 pDrvIns->iInstance);
230
231 rc = RTTraceLogWrCreateTcpClient(&pThis->hTraceLog, RTBldCfgVersion(), pszLocation, uPort);
232 *pszPort = ':'; /* Restore delimiter before checking the status. */
233 if (RT_FAILURE(rc))
234 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
235 N_("IfTrace#%d: Failed to connect to socket %s"),
236 pDrvIns->iInstance, pszLocation);
237
238 PDMDrvHlpMMHeapFree(pDrvIns, pszLocation);
239 }
240
241
242 /*
243 * Query interfaces from the driver/device above us.
244 */
245 pThis->pISerialPortAbove = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMISERIALPORT);
246 pThis->pITpmPortAbove = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMITPMPORT);
247
248 /*
249 * Attach driver below us.
250 */
251 PPDMIBASE pIBaseBelow;
252 rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pIBaseBelow);
253 AssertLogRelRCReturn(rc, rc);
254
255 pThis->pISerialConBelow = PDMIBASE_QUERY_INTERFACE(pIBaseBelow, PDMISERIALCONNECTOR);
256 pThis->pITpmConBelow = PDMIBASE_QUERY_INTERFACE(pIBaseBelow, PDMITPMCONNECTOR);
257
258 return VINF_SUCCESS;
259}
260
261
262/**
263 * Storage filter driver registration record.
264 */
265const PDMDRVREG g_DrvIfTrace =
266{
267 /* u32Version */
268 PDM_DRVREG_VERSION,
269 /* szName */
270 "IfTrace",
271 /* szRCMod */
272 "",
273 /* szR0Mod */
274 "",
275 /* pszDescription */
276 "Interface callback tracing driver",
277 /* fFlags */
278 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
279 /* fClass. */
280 PDM_DRVREG_CLASS_STATUS,
281 /* cMaxInstances */
282 ~0U,
283 /* cbInstance */
284 sizeof(DRVIFTRACE),
285 /* pfnConstruct */
286 drvIfTrace_Construct,
287 /* pfnDestruct */
288 drvIfTrace_Destruct,
289 /* pfnRelocate */
290 NULL,
291 /* pfnIOCtl */
292 NULL,
293 /* pfnPowerOn */
294 NULL,
295 /* pfnReset */
296 drvIfTrace_Reset,
297 /* pfnSuspend */
298 drvIfTrace_Suspend,
299 /* pfnResume */
300 drvIfTrace_Resume,
301 /* pfnAttach */
302 NULL,
303 /* pfnDetach */
304 NULL,
305 /* pfnPowerOff */
306 NULL,
307 /* pfnSoftReset */
308 NULL,
309 /* u32EndVersion */
310 PDM_DRVREG_VERSION
311};
312
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle
ContactPrivacy/Do Not Sell My InfoTerms of Use