Commit 55f64c36 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

lib/trace_parser: map/unmap the trace file



Copied code responsible for mapping/unmapping the trace file.  The
only modifications were related with tying it to the spdk_trace_parser
object.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ia575101532c612b185bd971c69157623b52b9e81
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9429


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 9f671238
Loading
Loading
Loading
Loading
+117 −2
Original line number Diff line number Diff line
@@ -32,14 +32,129 @@
 */

#include "spdk/stdinc.h"
#include "spdk/log.h"
#include "spdk/trace_parser.h"

#include <exception>
#include <new>

struct spdk_trace_parser {
	spdk_trace_parser(const spdk_trace_parser_opts *opts);
	~spdk_trace_parser();
	spdk_trace_parser(const spdk_trace_parser &) = delete;
	spdk_trace_parser &operator=(const spdk_trace_parser &) = delete;
private:
	bool init(const spdk_trace_parser_opts *opts);
	void cleanup();

	spdk_trace_histories	*_histories;
	size_t			_map_size;
	int			_fd;
};

bool
spdk_trace_parser::init(const spdk_trace_parser_opts *opts)
{
	struct stat st;
	int rc;

	switch (opts->mode) {
	case SPDK_TRACE_PARSER_MODE_FILE:
		_fd = open(opts->filename, O_RDONLY);
		break;
	case SPDK_TRACE_PARSER_MODE_SHM:
		_fd = shm_open(opts->filename, O_RDONLY, 0600);
		break;
	default:
		SPDK_ERRLOG("Invalid mode: %d\n", opts->mode);
		return false;
	}

	if (_fd < 0) {
		SPDK_ERRLOG("Could not open trace file: %s (%d)\n", opts->filename, errno);
		return false;
	}

	rc = fstat(_fd, &st);
	if (rc < 0) {
		SPDK_ERRLOG("Could not get size of trace file: %s\n", opts->filename);
		return false;
	}

	if ((size_t)st.st_size < sizeof(*_histories)) {
		SPDK_ERRLOG("Invalid trace file: %s\n", opts->filename);
		return false;
	}

	/* Map the header of trace file */
	_map_size = sizeof(*_histories);
	_histories = static_cast<spdk_trace_histories *>(mmap(NULL, _map_size, PROT_READ,
			MAP_SHARED, _fd, 0));
	if (_histories == MAP_FAILED) {
		SPDK_ERRLOG("Could not mmap trace file: %s\n", opts->filename);
		_histories = NULL;
		return false;
	}

	/* Remap the entire trace file */
	_map_size = spdk_get_trace_histories_size(_histories);
	munmap(_histories, sizeof(*_histories));
	if ((size_t)st.st_size < _map_size) {
		SPDK_ERRLOG("Trace file %s is not valid\n", opts->filename);
		_histories = NULL;
		return false;
	}
	_histories = static_cast<spdk_trace_histories *>(mmap(NULL, _map_size, PROT_READ,
			MAP_SHARED, _fd, 0));
	if (_histories == MAP_FAILED) {
		SPDK_ERRLOG("Could not mmap trace file: %s\n", opts->filename);
		_histories = NULL;
		return false;
	}

	return true;
}

void
spdk_trace_parser::cleanup()
{
	if (_histories != NULL) {
		munmap(_histories, _map_size);
	}

	if (_fd > 0) {
		close(_fd);
	}
}

spdk_trace_parser::spdk_trace_parser(const spdk_trace_parser_opts *opts) :
	_histories(NULL),
	_map_size(0),
	_fd(-1)
{
	if (!init(opts)) {
		cleanup();
		throw std::exception();
	}
}

spdk_trace_parser::~spdk_trace_parser()
{
	cleanup();
}

struct spdk_trace_parser *
spdk_trace_parser_init(const struct spdk_trace_parser_opts *opts)
{
	try {
		return new spdk_trace_parser(opts);
	} catch (...) {
		return NULL;
	}
}

void
spdk_trace_parser_cleanup(struct spdk_trace_parser *parser)
{}
{
	delete parser;
}
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ DEPDIRS-sock := log $(JSON_LIBS)
DEPDIRS-util := log
DEPDIRS-vmd := log
DEPDIRS-dma := log
DEPDIRS-trace_parser := log
ifeq ($(CONFIG_VFIO_USER),y)
DEPDIRS-vfio_user := log
endif