// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2018 VMware Inc, Slavomir Kaslev <kaslevs@vmware.com>
 *
 * based on prior implementation by Yoshihiro Yunomae
 * Copyright (C) 2013 Hitachi, Ltd.
 * Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
 */

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <linux/vm_sockets.h>

#include "trace-local.h"
#include "trace-msg.h"

#define GET_LOCAL_CID	0x7b9

static int get_local_cid(unsigned int *cid)
{
	int fd, ret = 0;

	fd = open("/dev/vsock", O_RDONLY);
	if (fd < 0)
		return -errno;

	if (ioctl(fd, GET_LOCAL_CID, cid))
		ret = -errno;

	close(fd);
	return ret;
}

static int make_vsock(unsigned int port)
{
	struct sockaddr_vm addr = {
		.svm_family = AF_VSOCK,
		.svm_cid = VMADDR_CID_ANY,
		.svm_port = port,
	};
	int sd;

	sd = socket(AF_VSOCK, SOCK_STREAM, 0);
	if (sd < 0)
		return -errno;

	setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));

	if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)))
		return -errno;

	if (listen(sd, SOMAXCONN))
		return -errno;

	return sd;
}

static int get_vsock_port(int sd, unsigned int *port)
{
	struct sockaddr_vm addr;
	socklen_t addr_len = sizeof(addr);

	if (getsockname(sd, (struct sockaddr *)&addr, &addr_len))
		return -errno;

	if (addr.svm_family != AF_VSOCK)
		return -errno;

	if (port)
		*port = addr.svm_port;

	return 0;
}

static void make_vsocks(int nr, int *fds, unsigned int *ports)
{
	unsigned int port;
	int i, fd, ret;

	for (i = 0; i < nr; i++) {
		fd = make_vsock(VMADDR_PORT_ANY);
		if (fd < 0)
			die("Failed to open vsocket");

		ret = get_vsock_port(fd, &port);
		if (ret < 0)
			die("Failed to get vsocket address");

		fds[i] = fd;
		ports[i] = port;
	}
}

static int open_agent_fifos(int nr_cpus, int *fds)
{
	char path[PATH_MAX];
	int i, fd, ret;

	for (i = 0; i < nr_cpus; i++) {
		snprintf(path, sizeof(path), VIRTIO_FIFO_FMT, i);
		fd = open(path, O_WRONLY);
		if (fd < 0) {
			ret = -errno;
			goto cleanup;
		}

		fds[i] = fd;
	}

	return 0;

cleanup:
	while (--i >= 0)
		close(fds[i]);

	return ret;
}

static void agent_handle(int sd, int nr_cpus, int page_size)
{
	struct tracecmd_msg_handle *msg_handle;
	unsigned int *ports;
	char **argv = NULL;
	int argc = 0;
	bool use_fifos;
	bool do_tsync;
	int *fds;
	int ret;

	fds = calloc(nr_cpus, sizeof(*fds));
	ports = calloc(nr_cpus, sizeof(*ports));
	if (!fds || !ports)
		die("Failed to allocate memory");

	msg_handle = tracecmd_msg_handle_alloc(sd, 0);
	if (!msg_handle)
		die("Failed to allocate message handle");

	ret = tracecmd_msg_recv_trace_req(msg_handle, &argc, &argv,
					  &use_fifos, &do_tsync);
	if (ret < 0)
		die("Failed to receive trace request");

	if (use_fifos && open_agent_fifos(nr_cpus, fds))
		use_fifos = false;

	if (!use_fifos)
		make_vsocks(nr_cpus, fds, ports);
	if (do_tsync) {
		do_tsync = tracecmd_time_sync_check();
		if (!do_tsync)
			warning("Failed to negotiate timestamps synchronization with the host");
	}

	ret = tracecmd_msg_send_trace_resp(msg_handle, nr_cpus, page_size,
					   ports, use_fifos, do_tsync);
	if (ret < 0)
		die("Failed to send trace response");

	trace_record_agent(msg_handle, nr_cpus, fds, argc, argv, use_fifos, do_tsync);

	free(argv[0]);
	free(argv);
	free(ports);
	free(fds);
	tracecmd_msg_handle_close(msg_handle);
	exit(0);
}

static volatile pid_t handler_pid;

static void handle_sigchld(int sig)
{
	int wstatus;
	pid_t pid;

	for (;;) {
		pid = waitpid(-1, &wstatus, WNOHANG);
		if (pid <= 0)
			break;

		if (pid == handler_pid)
			handler_pid = 0;
	}
}

static pid_t do_fork()
{
	/* in debug mode, we do not fork off children */
	if (debug)
		return 0;

	return fork();
}

static void agent_serve(unsigned int port)
{
	int sd, cd, nr_cpus;
	unsigned int cid;
	pid_t pid;

	signal(SIGCHLD, handle_sigchld);

	nr_cpus = count_cpus();
	page_size = getpagesize();

	sd = make_vsock(port);
	if (sd < 0)
		die("Failed to open vsocket");

	if (!get_local_cid(&cid))
		printf("listening on @%u:%u\n", cid, port);

	for (;;) {
		cd = accept(sd, NULL, NULL);
		if (cd < 0) {
			if (errno == EINTR)
				continue;
			die("accept");
		}

		if (handler_pid)
			goto busy;

		pid = do_fork();
		if (pid == 0) {
			close(sd);
			signal(SIGCHLD, SIG_DFL);
			agent_handle(cd, nr_cpus, page_size);
		}
		if (pid > 0)
			handler_pid = pid;

busy:
		close(cd);
	}
}

enum {
	DO_DEBUG	= 255
};

void trace_agent(int argc, char **argv)
{
	bool do_daemon = false;
	unsigned int port = TRACE_AGENT_DEFAULT_PORT;

	if (argc < 2)
		usage(argv);

	if (strcmp(argv[1], "agent") != 0)
		usage(argv);

	for (;;) {
		int c, option_index = 0;
		static struct option long_options[] = {
			{"port", required_argument, NULL, 'p'},
			{"help", no_argument, NULL, '?'},
			{"debug", no_argument, NULL, DO_DEBUG},
			{NULL, 0, NULL, 0}
		};

		c = getopt_long(argc-1, argv+1, "+hp:D",
				long_options, &option_index);
		if (c == -1)
			break;
		switch (c) {
		case 'h':
			usage(argv);
			break;
		case 'p':
			port = atoi(optarg);
			break;
		case 'D':
			do_daemon = true;
			break;
		case DO_DEBUG:
			debug = true;
			break;
		default:
			usage(argv);
		}
	}

	if (optind < argc-1)
		usage(argv);

	if (do_daemon && daemon(1, 0))
		die("daemon");

	agent_serve(port);
}
