// SPDX-License-Identifier: GPL-2.0-only
/*
 * Guest agent for virtio-trace
 *
 * Copyright (C) 2012 Hitachi, Ltd.
 * Created by Yoshihiro Yunomae <yoshihiro.yunomae.ez@hitachi.com>
 *            Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
 */

#define _GNU_SOURCE
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "trace-agent.h"

#define PAGE_SIZE		(sysconf(_SC_PAGE_SIZE))
#define PIPE_DEF_BUFS		16
#define PIPE_MIN_SIZE		(PAGE_SIZE*PIPE_DEF_BUFS)
#define PIPE_MAX_SIZE		(1024*1024)
#define TRACEFS 		"/sys/kernel/tracing"
#define DEBUGFS 		"/sys/kernel/debug/tracing"
#define READ_PATH_FMT		"%s/per_cpu/cpu%d/trace_pipe_raw"
#define WRITE_PATH_FMT		"/dev/virtio-ports/trace-path-cpu%d"
#define CTL_PATH		"/dev/virtio-ports/agent-ctl-path"

pthread_mutex_t mutex_notify = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_wakeup = PTHREAD_COND_INITIALIZER;

static int get_total_cpus(void)
{
	int nr_cpus = (int)sysconf(_SC_NPROCESSORS_CONF);

	if (nr_cpus <= 0) {
		pr_err("Could not read cpus\n");
		goto error;
	} else if (nr_cpus > MAX_CPUS) {
		pr_err("Exceed max cpus(%d)\n", (int)MAX_CPUS);
		goto error;
	}

	return nr_cpus;

error:
	exit(EXIT_FAILURE);
}

static void *agent_info_new(void)
{
	struct agent_info *s;
	int i;

	s = zalloc(sizeof(struct agent_info));
	if (s == NULL) {
		pr_err("agent_info zalloc error\n");
		exit(EXIT_FAILURE);
	}

	s->pipe_size = PIPE_INIT;
	s->use_stdout = false;
	s->cpus = get_total_cpus();
	s->ctl_fd = -1;

	/* read/write threads init */
	for (i = 0; i < s->cpus; i++)
		s->rw_ti[i] = rw_thread_info_new();

	return s;
}

static unsigned long parse_size(const char *arg)
{
	unsigned long value, round;
	char *ptr;

	value = strtoul(arg, &ptr, 10);
	switch (*ptr) {
	case 'K': case 'k':
		value <<= 10;
		break;
	case 'M': case 'm':
		value <<= 20;
		break;
	default:
		break;
	}

	if (value > PIPE_MAX_SIZE) {
		pr_err("Pipe size must be less than 1MB\n");
		goto error;
	} else if (value < PIPE_MIN_SIZE) {
		pr_err("Pipe size must be over 64KB\n");
		goto error;
	}

	/* Align buffer size with page unit */
	round = value & (PAGE_SIZE - 1);
	value = value - round;

	return value;
error:
	return 0;
}

static void usage(char const *prg)
{
	pr_err("usage: %s [-h] [-o] [-s <size of pipe>]\n", prg);
}

static const char *make_path(int cpu_num, bool this_is_write_path)
{
	int ret;
	char *buf;

	buf = zalloc(PATH_MAX);
	if (buf == NULL) {
		pr_err("Could not allocate buffer\n");
		goto error;
	}

	if (this_is_write_path)
		/* write(output) path */
		ret = snprintf(buf, PATH_MAX, WRITE_PATH_FMT, cpu_num);
	else {
		/* read(input) path */
		ret = snprintf(buf, PATH_MAX, READ_PATH_FMT, TRACEFS, cpu_num);
		if (ret > 0 && access(buf, F_OK) != 0)
			ret = snprintf(buf, PATH_MAX, READ_PATH_FMT, DEBUGFS, cpu_num);
	}

	if (ret <= 0) {
		pr_err("Failed to generate %s path(CPU#%d):%d\n",
			this_is_write_path ? "read" : "write", cpu_num, ret);
		goto error;
	}

	return buf;

error:
	free(buf);
	return NULL;
}

static const char *make_input_path(int cpu_num)
{
	return make_path(cpu_num, false);
}

static const char *make_output_path(int cpu_num)
{
	return make_path(cpu_num, true);
}

static void *agent_info_init(struct agent_info *s)
{
	int cpu;
	const char *in_path = NULL;
	const char *out_path = NULL;

	/* init read/write threads */
	for (cpu = 0; cpu < s->cpus; cpu++) {
		/* set read(input) path per read/write thread */
		in_path = make_input_path(cpu);
		if (in_path == NULL)
			goto error;

		/* set write(output) path per read/write thread*/
		if (!s->use_stdout) {
			out_path = make_output_path(cpu);
			if (out_path == NULL)
				goto error;
		} else
			/* stdout mode */
			pr_debug("stdout mode\n");

		rw_thread_init(cpu, in_path, out_path, s->use_stdout,
						s->pipe_size, s->rw_ti[cpu]);
	}

	/* init controller of read/write threads */
	s->ctl_fd = rw_ctl_init((const char *)CTL_PATH);

	return NULL;

error:
	exit(EXIT_FAILURE);
}

static void *parse_args(int argc, char *argv[], struct agent_info *s)
{
	int cmd;
	unsigned long size;

	while ((cmd = getopt(argc, argv, "hos:")) != -1) {
		switch (cmd) {
		/* stdout mode */
		case 'o':
			s->use_stdout = true;
			break;
		/* size of pipe */
		case 's':
			size = parse_size(optarg);
			if (size == 0)
				goto error;
			s->pipe_size = size;
			break;
		case 'h':
		default:
			usage(argv[0]);
			goto error;
		}
	}

	agent_info_init(s);

	return NULL;

error:
	exit(EXIT_FAILURE);
}

static void agent_main_loop(struct agent_info *s)
{
	int cpu;
	pthread_t rw_thread_per_cpu[MAX_CPUS];

	/* Start all read/write threads */
	for (cpu = 0; cpu < s->cpus; cpu++)
		rw_thread_per_cpu[cpu] = rw_thread_run(s->rw_ti[cpu]);

	rw_ctl_loop(s->ctl_fd);

	/* Finish all read/write threads */
	for (cpu = 0; cpu < s->cpus; cpu++) {
		int ret;

		ret = pthread_join(rw_thread_per_cpu[cpu], NULL);
		if (ret != 0) {
			pr_err("pthread_join() error:%d (cpu %d)\n", ret, cpu);
			exit(EXIT_FAILURE);
		}
	}
}

static void agent_info_free(struct agent_info *s)
{
	int i;

	close(s->ctl_fd);
	for (i = 0; i < s->cpus; i++) {
		close(s->rw_ti[i]->in_fd);
		close(s->rw_ti[i]->out_fd);
		close(s->rw_ti[i]->read_pipe);
		close(s->rw_ti[i]->write_pipe);
		free(s->rw_ti[i]);
	}
	free(s);
}

int main(int argc, char *argv[])
{
	struct agent_info *s = NULL;

	s = agent_info_new();
	parse_args(argc, argv, s);

	agent_main_loop(s);

	agent_info_free(s);

	return 0;
}
