VDDbgIoLog.cpp revision f0c94ab153ce14e9218d36949f474a37a94ede9c
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/* $Id$ */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/** @file
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * VD Debug library - I/O logger.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/*
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * Copyright (C) 2011 Oracle Corporation
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * available from http://www.virtualbox.org. This file is free software;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * you can redistribute it and/or modify it under the terms of the GNU
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * General Public License (GPL) as published by the Free Software
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/*******************************************************************************
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync* Header Files *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync*******************************************************************************/
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#define LOGGROUP LOGGROUP_DEFAULT
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#include <VBox/vddbg.h>
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#include <VBox/err.h>
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#include <VBox/log.h>
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#include <iprt/mem.h>
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#include <iprt/memcache.h>
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#include <iprt/file.h>
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#include <iprt/string.h>
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#include <iprt/semaphore.h>
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/*******************************************************************************
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync* Structures in a I/O log file, little endian *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync*******************************************************************************/
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/**
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * I/O log header.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#pragma pack(1)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsynctypedef struct IoLogHeader
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Magic string */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync char szMagic[8];
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Flags for the log file. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint32_t fFlags;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Id counter. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t u64Id;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync} IoLogHeader;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#pragma pack()
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#define VDIOLOG_MAGIC "VDIOLOG"
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/** Event type - I/O request start. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#define VDIOLOG_EVENT_START 0x01
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/** Event type - I/O request complete. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#define VDIOLOG_EVENT_COMPLETE 0x02
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/**
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * I/O log entry marking the start of a new I/O transaction.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#pragma pack(1)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsynctypedef struct IoLogEntryStart
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Event type. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint32_t u32Type;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Transfer type. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint32_t u32ReqType;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Flag whether this is a sync or async request. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint8_t u8AsyncIo;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Id of the entry. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t u64Id;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Type dependent data. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync union
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** I/O. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync struct
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Start offset. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint64_t u64Off;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Size of the request. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint64_t u64IoSize;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync } Io;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Discard */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync struct
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Number of ranges to discard. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint32_t cRanges;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync } Discard;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync };
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync} IoLogEntryStart;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#pragma pack()
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/**
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * I/O log entry markign the completion of an I/O transaction.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#pragma pack(1)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsynctypedef struct IoLogEntryComplete
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Event type. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint8_t u32Type;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Id of the matching start entry. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t u64Id;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Status code the request completed with */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int32_t i32Rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Number of milliseconds the request needed to complete. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t msDuration;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Number of bytes of data following this entry. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t u64IoBuffer;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync} IoLogEntryComplete;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync#pragma pack()
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync#pragma pack(1)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsynctypedef struct IoLogEntryDiscard
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync{
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Start offset. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint64_t u64Off;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Number of bytes to discard. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint32_t u32Discard;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync} IoLogEntryDiscard;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync#pragma pack()
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/*******************************************************************************
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync* Constants And Macros, Structures and Typedefs *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync*******************************************************************************/
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/**
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * I/O logger instance data.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsynctypedef struct VDIOLOGGERINT
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** File handle. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTFILE hFile;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Current offset to append new entries to. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t offWriteNext;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Offset to read the next entry from. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t offReadNext;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Flags given during creation. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint32_t fFlags;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Id for the next entry. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t idNext;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Memory cache for the I/O log entries. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTMEMCACHE hMemCacheIoLogEntries;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Mutex section protecting the logger. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSEMFASTMUTEX hMtx;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Cached event type of the next event. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint32_t u32EventTypeNext;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /** Cached request type of the next request. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync VDDBGIOLOGREQ enmReqTypeNext;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync} VDIOLOGGERINT;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/** Pointer to the internal I/O logger instance data. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsynctypedef VDIOLOGGERINT *PVDIOLOGGERINT;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/**
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * I/O log entry data.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsynctypedef struct VDIOLOGENTINT
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Id of the start entry. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t idStart;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Timestamnp when the request started. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t tsStart;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /** Size of the buffer to write on success. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync size_t cbIo;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync} VDIOLOGENTINT;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/** Pointer to the internal I/O log entry data. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsynctypedef VDIOLOGENTINT *PVDIOLOGENTINT;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/*******************************************************************************
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync* Internal Functions *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync*******************************************************************************/
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/**
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * Creates a new empty I/O logger.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @returns VBox status code.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @param ppIoLogger Where to store the new I/O logger handle.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncstatic int vddbgIoLoggerCreate(PVDIOLOGGERINT *ppIoLogger)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = NULL;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger = (PVDIOLOGGERINT)RTMemAllocZ(sizeof(VDIOLOGGERINT));
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (pIoLogger)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTSemFastMutexCreate(&pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTMemCacheCreate(&pIoLogger->hMemCacheIoLogEntries, sizeof(VDIOLOGENTINT),
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync 0, UINT32_MAX, NULL, NULL, NULL, 0);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *ppIoLogger = pIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTMemFree(pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = VERR_NO_MEMORY;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/**
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * Update the header of the I/O logger to the current state.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @returns VBox status code.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @param pIoLogger The I/O logger to update.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncstatic int vddbgIoLoggerHeaderUpdate(PVDIOLOGGERINT pIoLogger)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync IoLogHeader Hdr;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync memcpy(Hdr.szMagic, VDIOLOG_MAGIC, sizeof(Hdr.szMagic));
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync Hdr.fFlags = RT_H2LE_U32(pIoLogger->fFlags);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync Hdr.u64Id = RT_H2LE_U64(pIoLogger->idNext);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileWriteAt(pIoLogger->hFile, 0, &Hdr, sizeof(Hdr), NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync/**
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * Writes data from the given S/G buffer into the I/O log.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @returns VBox status code.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @param pIoLogger The I/O logger to use.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @param off The start offset in the log to write to.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @param pSgBuf The S/G buffer to write.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync * @param cbSgBuf How much data to write.
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncstatic int vddbgIoLogWriteSgBuf(PVDIOLOGGERINT pIoLogger, uint64_t off, PCRTSGBUF pSgBuf, size_t cbSgBuf)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSGBUF SgBuf;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSgBufClone(&SgBuf, pSgBuf);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync while (cbSgBuf)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync void *pvSeg;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync size_t cbSeg = cbSgBuf;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pvSeg = RTSgBufGetNextSegment(&SgBuf, &cbSeg);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrBreakStmt(pvSeg, rc = VERR_INTERNAL_ERROR);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileWriteAt(pIoLogger->hFile, off, pvSeg, cbSeg, NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_FAILURE(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync break;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync cbSgBuf -= cbSeg;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync off += cbSeg;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncVBOXDDU_DECL(int) VDDbgIoLogCreate(PVDIOLOGGER phIoLogger, const char *pszFilename, uint32_t fFlags)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = NULL;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(phIoLogger, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertReturn(!(fFlags & ~VDDBG_IOLOG_VALID_MASK), VERR_INVALID_PARAMETER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = vddbgIoLoggerCreate(&pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->fFlags = fFlags;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->hFile = NIL_RTFILE;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /* Create new log. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileOpen(&pIoLogger->hFile, pszFilename, RTFILE_O_DENY_NONE | RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_READ);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = vddbgIoLoggerHeaderUpdate(pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offWriteNext = sizeof(IoLogHeader);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offReadNext = sizeof(IoLogHeader);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *phIoLogger = pIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (pIoLogger->hFile != NIL_RTFILE)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTFileClose(pIoLogger->hFile);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTMemFree(pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncVBOXDDU_DECL(int) VDDbgIoLogOpen(PVDIOLOGGER phIoLogger, const char *pszFilename)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = NULL;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(phIoLogger, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = vddbgIoLoggerCreate(&pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /* open existing log. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileOpen(&pIoLogger->hFile, pszFilename, RTFILE_O_DENY_NONE | RTFILE_O_OPEN | RTFILE_O_WRITE | RTFILE_O_READ);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync IoLogHeader Hdr;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t cbLog;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileGetSize(pIoLogger->hFile, &cbLog);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /* Read the header. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileRead(pIoLogger->hFile, &Hdr, sizeof(Hdr), NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if ( RT_SUCCESS(rc)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync && !memcmp(Hdr.szMagic, VDIOLOG_MAGIC, sizeof(Hdr.szMagic)))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->fFlags = RT_LE2H_U32(Hdr.fFlags);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offWriteNext = cbLog;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offReadNext = sizeof(Hdr);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->idNext = RT_LE2H_U64(Hdr.u64Id);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = VERR_INVALID_PARAMETER;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncVBOXDDU_DECL(void) VDDbgIoLogDestroy(VDIOLOGGER hIoLogger)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturnVoid(pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync vddbgIoLoggerHeaderUpdate(pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTFileFlush(pIoLogger->hFile);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTFileClose(pIoLogger->hFile);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTMemCacheDestroy(pIoLogger->hMemCacheIoLogEntries);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSemFastMutexDestroy(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTMemFree(pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncVBOXDDU_DECL(int) VDDbgIoLogCommit(VDIOLOGGER hIoLogger)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = vddbgIoLoggerHeaderUpdate(pIoLogger);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileFlush(pIoLogger->hFile);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncVBOXDDU_DECL(uint32_t) VDDbgIoLogGetFlags(VDIOLOGGER hIoLogger)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return pIoLogger->fFlags;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsyncVBOXDDU_DECL(int) VDDbgIoLogStart(VDIOLOGGER hIoLogger, bool fAsync, VDDBGIOLOGREQ enmTxDir, uint64_t off, size_t cbIo, PCRTSGBUF pSgBuf,
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGENT phIoLogEntry)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGENTINT pIoLogEntry = NULL;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertReturn(enmTxDir > VDDBGIOLOGREQ_INVALID && enmTxDir <= VDDBGIOLOGREQ_FLUSH, VERR_INVALID_PARAMETER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTSemFastMutexRequest(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertRCReturn(rc, rc);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (pIoLogEntry)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync IoLogEntryStart Entry;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogEntry->idStart = pIoLogger->idNext++;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.u32Type = VDIOLOG_EVENT_START;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.u8AsyncIo = fAsync ? 1 : 0;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.u32ReqType = enmTxDir;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.u64Id = RT_H2LE_U64(pIoLogEntry->idStart);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.Io.u64Off = RT_H2LE_U64(off);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.Io.u64IoSize = RT_H2LE_U64(cbIo);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /* Write new entry. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offWriteNext += sizeof(Entry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if ( enmTxDir == VDDBGIOLOGREQ_WRITE
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /* Write data. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = vddbgIoLogWriteSgBuf(pIoLogger, pIoLogger->offWriteNext, pSgBuf, cbIo);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_FAILURE(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offWriteNext -= sizeof(Entry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offWriteNext += cbIo;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogEntry->tsStart = RTTimeProgramMilliTS();
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if ( enmTxDir == VDDBGIOLOGREQ_READ
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_READ))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogEntry->cbIo = cbIo;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogEntry->cbIo = 0;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *phIoLogEntry = pIoLogEntry;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->idNext--;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = VERR_NO_MEMORY;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsyncVBOXDDU_DECL(int) VDDbgIoLogStartDiscard(VDIOLOGGER hIoLogger, bool fAsync, PVDRANGE paRanges, unsigned cRanges,
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync PVDIOLOGENT phIoLogEntry)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync{
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync int rc = VINF_SUCCESS;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync PVDIOLOGENTINT pIoLogEntry = NULL;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTSemFastMutexRequest(pIoLogger->hMtx);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertRCReturn(rc, rc);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (pIoLogEntry)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync IoLogEntryStart Entry;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogEntry->idStart = pIoLogger->idNext++;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.u32Type = VDIOLOG_EVENT_START;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.u8AsyncIo = fAsync ? 1 : 0;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.u32ReqType = VDDBGIOLOGREQ_DISCARD;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.Discard.cRanges = RT_H2LE_U32(cRanges);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync /* Write new entry. */
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_SUCCESS(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->offWriteNext += sizeof(Entry);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync IoLogEntryDiscard DiscardRange;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync for (unsigned i = 0; i < cRanges; i++)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync DiscardRange.u64Off = RT_H2LE_U64(paRanges[i].offStart);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync DiscardRange.u32Discard = RT_H2LE_U32(paRanges[i].cbRange);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext + i*sizeof(DiscardRange),
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync &DiscardRange, sizeof(DiscardRange), NULL);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_FAILURE(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync break;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_FAILURE(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->offWriteNext -= sizeof(Entry);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync else
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->offWriteNext += cRanges * sizeof(DiscardRange);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_SUCCESS(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogEntry->tsStart = RTTimeProgramMilliTS();
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogEntry->cbIo = 0;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *phIoLogEntry = pIoLogEntry;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync else
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->idNext--;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync else
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = VERR_NO_MEMORY;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync return rc;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync}
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncVBOXDDU_DECL(int) VDDbgIoLogComplete(VDIOLOGGER hIoLogger, VDIOLOGENT hIoLogEntry, int rcReq, PCRTSGBUF pSgBuf)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGENTINT pIoLogEntry = hIoLogEntry;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pIoLogEntry, VERR_INVALID_HANDLE);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTSemFastMutexRequest(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertRCReturn(rc, rc);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync IoLogEntryComplete Entry;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Entry.u32Type = VDIOLOG_EVENT_COMPLETE;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync Entry.u64Id = RT_H2LE_U64(pIoLogEntry->idStart);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync Entry.msDuration = RTTimeProgramMilliTS() - RT_H2LE_U64(pIoLogEntry->tsStart);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync Entry.i32Rc = (int32_t)RT_H2LE_U32((uint32_t)rcReq);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync Entry.u64IoBuffer = RT_H2LE_U64(pIoLogEntry->cbIo);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /* Write new entry. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offWriteNext += sizeof(Entry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (pIoLogEntry->cbIo)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = vddbgIoLogWriteSgBuf(pIoLogger, pIoLogger->offWriteNext, pSgBuf, pIoLogEntry->cbIo);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offWriteNext += pIoLogEntry->cbIo;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offWriteNext -= sizeof(Entry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncVBOXDDU_DECL(int) VDDbgIoLogEventTypeGetNext(VDIOLOGGER hIoLogger, VDIOLOGEVENT *penmEvent)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(penmEvent, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTSemFastMutexRequest(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertRCReturn(rc, rc);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (pIoLogger->offReadNext == pIoLogger->offWriteNext)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *penmEvent = VDIOLOGEVENT_END;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (!pIoLogger->u32EventTypeNext)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync uint32_t abBuf[2];
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &abBuf, sizeof(abBuf), NULL);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_SUCCESS(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->u32EventTypeNext = (VDIOLOGEVENT)abBuf[0];
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->enmReqTypeNext = (VDDBGIOLOGREQ)abBuf[1];
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Assert(pIoLogger->u32EventTypeNext != VDIOLOGEVENT_INVALID);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync switch (pIoLogger->u32EventTypeNext)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync case VDIOLOG_EVENT_START:
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *penmEvent = VDIOLOGEVENT_START;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync break;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync case VDIOLOG_EVENT_COMPLETE:
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *penmEvent = VDIOLOGEVENT_COMPLETE;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync break;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync default:
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertMsgFailed(("Invalid event type %d\n", pIoLogger->u32EventTypeNext));
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsyncVBOXDDU_DECL(int) VDDbgIoLogReqTypeGetNext(VDIOLOGGER hIoLogger, PVDDBGIOLOGREQ penmReq)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync{
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync int rc = VINF_SUCCESS;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertPtrReturn(penmReq, VERR_INVALID_POINTER);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTSemFastMutexRequest(pIoLogger->hMtx);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertRCReturn(rc, rc);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (pIoLogger->offReadNext == pIoLogger->offWriteNext)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *penmReq = VDDBGIOLOGREQ_INVALID;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync return VERR_INVALID_STATE;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_SUCCESS(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync Assert(pIoLogger->enmReqTypeNext != VDDBGIOLOGREQ_INVALID);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *penmReq = pIoLogger->enmReqTypeNext;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync return rc;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync}
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsyncVBOXDDU_DECL(int) VDDbgIoLogEventGetStart(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t *poff, size_t *pcbIo, size_t cbBuf, void *pvBuf)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(poff, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pcbIo, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTSemFastMutexRequest(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertRCReturn(rc, rc);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync IoLogEntryStart Entry;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *pfAsync = (bool)Entry.u8AsyncIo;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *pidEvent = RT_LE2H_U64(Entry.u64Id);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *poff = RT_LE2H_U64(Entry.Io.u64Off);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *pcbIo = RT_LE2H_U64(Entry.Io.u64IoSize);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if ( pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_WRITE
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /* Read data. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (cbBuf < *pcbIo)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = VERR_BUFFER_OVERFLOW;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (rc != VERR_BUFFER_OVERFLOW)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offReadNext += *pcbIo + sizeof(Entry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offReadNext += sizeof(Entry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = VERR_INVALID_STATE;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsyncVBOXDDU_DECL(int) VDDbgIoLogEventGetStartDiscard(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync PVDRANGE *ppaRanges, unsigned *pcRanges)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync{
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync int rc = VINF_SUCCESS;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTSemFastMutexRequest(pIoLogger->hMtx);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync AssertRCReturn(rc, rc);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if ( pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync && pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_DISCARD)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync IoLogEntryStart Entry;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_SUCCESS(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync PVDRANGE paRanges = NULL;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync IoLogEntryDiscard DiscardRange;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->offReadNext += sizeof(Entry);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *pfAsync = (bool)Entry.u8AsyncIo;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *pidEvent = RT_LE2H_U64(Entry.u64Id);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *pcRanges = RT_LE2H_U32(Entry.Discard.cRanges);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync paRanges = (PVDRANGE)RTMemAllocZ(*pcRanges * sizeof(VDRANGE));
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (paRanges)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync for (unsigned i = 0; i < *pcRanges; i++)
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + i*sizeof(DiscardRange),
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync &DiscardRange, sizeof(DiscardRange), NULL);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_FAILURE(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync break;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync paRanges[i].offStart = RT_LE2H_U64(DiscardRange.u64Off);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync paRanges[i].cbRange = RT_LE2H_U32(DiscardRange.u32Discard);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (RT_SUCCESS(rc))
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync {
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->offReadNext += *pcRanges * sizeof(DiscardRange);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync *ppaRanges = paRanges;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync else
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync pIoLogger->offReadNext -= sizeof(Entry);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync else
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = VERR_NO_MEMORY;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync }
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync else
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync rc = VERR_INVALID_STATE;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync return rc;
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync}
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsyncVBOXDDU_DECL(int) VDDbgIoLogEventGetComplete(VDIOLOGGER hIoLogger, uint64_t *pidEvent, int *pRc,
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync uint64_t *pmsDuration, size_t *pcbIo, size_t cbBuf, void *pvBuf)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync{
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync int rc = VINF_SUCCESS;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync PVDIOLOGGERINT pIoLogger = hIoLogger;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pmsDuration, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertPtrReturn(pcbIo, VERR_INVALID_POINTER);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTSemFastMutexRequest(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync AssertRCReturn(rc, rc);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
f0c94ab153ce14e9218d36949f474a37a94ede9cvboxsync if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_COMPLETE)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync IoLogEntryComplete Entry;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (RT_SUCCESS(rc))
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *pidEvent = RT_LE2H_U64(Entry.u64Id);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *pRc = (int)RT_LE2H_U32((int32_t)Entry.i32Rc);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *pmsDuration = RT_LE2H_U64(Entry.msDuration);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync *pcbIo = RT_LE2H_U64(Entry.u64IoBuffer);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (*pcbIo)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync {
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync /* Read data. */
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (cbBuf < *pcbIo)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = VERR_BUFFER_OVERFLOW;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync if (rc != VERR_BUFFER_OVERFLOW)
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offReadNext += *pcbIo + sizeof(Entry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync pIoLogger->offReadNext += sizeof(Entry);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync }
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync else
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync rc = VERR_INVALID_STATE;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync RTSemFastMutexRelease(pIoLogger->hMtx);
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync return rc;
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync}
0560d845b0638cde2d51fe9ba84b4847eb9fbb47vboxsync