/*! \file cpu_sched_vty.c
 * Implementation to CPU / Threading / Scheduler properties from VTY configuration.
 */
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 *
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPLv2+
 */

#define _GNU_SOURCE

#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <sched.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <pthread.h>
#include <inttypes.h>

#include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/tdef_vty.h>
#include <osmocom/core/tdef.h>
#include <osmocom/core/fsm.h>
#include <osmocom/core/linuxlist.h>

/*! \addtogroup Tdef_VTY
 *
 * CPU Scheduling related VTY API.
 *
 * @{
 * \file cpu_sched_vty.c
 */

enum sched_vty_thread_id {
	SCHED_VTY_THREAD_SELF,
	SCHED_VTY_THREAD_ALL,
	SCHED_VTY_THREAD_ID,
	SCHED_VTY_THREAD_NAME,
	SCHED_VTY_THREAD_UNKNOWN,
};

struct cpu_affinity_it {
	struct llist_head entry;
	enum sched_vty_thread_id tid_type;
	char bufname[64];
	cpu_set_t *cpuset;
	size_t cpuset_size;
	bool delay;
};

struct sched_vty_opts {
	void *tall_ctx;
	int sched_rr_prio;
	struct llist_head cpu_affinity_li;
	pthread_mutex_t cpu_affinity_li_mutex;
};

static struct sched_vty_opts *sched_vty_opts;

static struct cmd_node sched_node = {
	L_CPU_SCHED_NODE,
	"%s(config-cpu-sched)# ",
	1,
};

/* returns number of configured CPUs in the system, or negative otherwise */
static int get_num_cpus() {
	static unsigned int num_cpus = 0;
	long ln;

	if (num_cpus)
		return num_cpus;

	/* This is expensive (goes across /sys, so let's do it only once. It is
	 * guaranteed it won't change during process span anyway). */
	ln = sysconf(_SC_NPROCESSORS_CONF);
	if (ln < 0) {
		LOGP(DLGLOBAL, LOGL_ERROR, "sysconf(_SC_NPROCESSORS_CONF) failed: %s\n",
		     strerror(errno));
		return -1;
	}
	num_cpus = (unsigned int) ln;
	return num_cpus;
}

/* Parses string with CPU hex Affinity Mask, with right-most bit being CPU0, and
 * fills a cpuset of size cpuset_size.
 */
static int parse_cpu_hex_mask(const char *str, cpu_set_t *cpuset, size_t cpuset_size)
{
	int len = strlen(str);
	const char *ptr = str + len - 1;
	int cpu = 0;

	/* skip optional '0x' prefix format */
	if (len >= 2 && str[0] == '0' && str[1] == 'x')
		str += 2;
	CPU_ZERO_S(cpuset_size, cpuset);

	while (ptr >= str) {
		char c = *ptr;
		uint8_t val;

		if (c >= '0' && c <= '9') {
			val = c - '0';
		} else {
			c = (char)tolower((int)c);
			if (c >= 'a' && c <= 'f')
				val = c + (10 - 'a');
			else
				return -1;
		}
		if (val & 0x01)
			CPU_SET_S(cpu, cpuset_size, cpuset);
		if (val & 0x02)
			CPU_SET_S(cpu + 1, cpuset_size, cpuset);
		if (val & 0x04)
			CPU_SET_S(cpu + 2, cpuset_size, cpuset);
		if (val & 0x08)
			CPU_SET_S(cpu + 3, cpuset_size, cpuset);
		ptr--;
		cpu += 4;
	}

	return 0;
}

/* Generates a hexstring in str from cpuset of size cpuset_size */
static int generate_cpu_hex_mask(char *str, size_t str_buf_size,
				 cpu_set_t *cpuset, size_t cpuset_size)
{
	char *ptr = str;
	int cpu;
	bool first_nonzero_found = false;

	/* 2 char per byte, + '0x' prefix + '\0' */
	if (cpuset_size * 2 + 2 + 1 > str_buf_size)
		return -1;

	*ptr++ = '0';
	*ptr++ = 'x';

	for (cpu = cpuset_size*8 - 4; cpu >= 0; cpu -= 4) {
		uint8_t val = 0;

		if (CPU_ISSET_S(cpu, cpuset_size, cpuset))
			val |= 0x01;
		if (CPU_ISSET_S(cpu + 1, cpuset_size, cpuset))
			val |= 0x02;
		if (CPU_ISSET_S(cpu + 2, cpuset_size, cpuset))
			val |= 0x04;
		if (CPU_ISSET_S(cpu + 3, cpuset_size, cpuset))
			val |= 0x08;

		if (val < 10)
			*ptr = '0' + val;
		else
			*ptr = ('a' - 10) + val;
		if (val)
			first_nonzero_found = true;
		if (first_nonzero_found)
			ptr++;

	}
	if (!first_nonzero_found)
		*ptr++ = '0';
	*ptr = '\0';
	return 0;
}

/* Checks whther a thread identified by tid exists and belongs to the running process */
static bool proc_tid_exists(pid_t tid)
{
	DIR *proc_dir;
	struct dirent *entry;
	char dirname[100];
	int tid_it;
	bool found = false;

	snprintf(dirname, sizeof(dirname), "/proc/%ld/task", (long int)getpid());
	proc_dir = opendir(dirname);
	if (!proc_dir)
		return false; /*FIXME; print error */

	while ((entry = readdir(proc_dir))) {
		if (entry->d_name[0] == '.')
			continue;
		tid_it = atoi(entry->d_name);
		if (tid_it == tid) {
			found = true;
			break;
		}
	}

	closedir(proc_dir);
	return found;
}

/* Checks whther a thread identified by name exists and belongs to the running
 * process, and returns its disocevered TID in res_pid.
 */
static bool proc_name_exists(const char *name, pid_t *res_pid)
{
	DIR *proc_dir;
	struct dirent *entry;
	char path[100];
	char buf[17]; /* 15 + \n + \0 */
	int tid_it;
	int fd;
	pid_t mypid = getpid();
	bool found = false;
	int rc;

	*res_pid = 0;

	snprintf(path, sizeof(path), "/proc/%ld/task", (long int)mypid);
	proc_dir = opendir(path);
	if (!proc_dir)
		return false;

	while ((entry = readdir(proc_dir)))
	{
		if (entry->d_name[0] == '.')
			continue;

		tid_it = atoi(entry->d_name);
		snprintf(path, sizeof(path), "/proc/%ld/task/%ld/comm", (long int)mypid, (long int) tid_it);
		if ((fd = open(path, O_RDONLY)) == -1)
			continue;
		rc = read(fd, buf, sizeof(buf) - 1);
		if (rc >= 0) {
			/* Last may char contain a '\n', get rid of it */
			if (rc > 0 && buf[rc - 1] == '\n')
				buf[rc - 1] = '\0';
			else
				buf[rc] = '\0';
			if (strcmp(name, buf) == 0) {
				*res_pid = tid_it;
				found = true;
			}
		}
		close(fd);

		if (found)
			break;
	}

	closedir(proc_dir);
	return found;
}

/* Parse VTY THREADNAME variable, return its type and fill discovered res_pid if required */
static enum sched_vty_thread_id procname2pid(pid_t *res_pid, const char *str, bool applynow)
{
	size_t i, len;
	char *end;
	bool is_pid = true;

	if (strcmp(str, "all") == 0) {
		*res_pid = 0;
		return SCHED_VTY_THREAD_ALL;
	}

	if (strcmp(str, "self") == 0) {
		*res_pid = 0;
		return SCHED_VTY_THREAD_SELF;
	}

	len = strlen(str);
	for (i = 0; i < len; i++) {
		if (!isdigit(str[i])) {
			is_pid = false;
			break;
		}
	}
	if (is_pid) {
		errno = 0;
		*res_pid = strtoul(str, &end, 0);
		if ((errno == ERANGE && *res_pid == ULONG_MAX) || (errno && !*res_pid) ||
		    str == end) {
			return SCHED_VTY_THREAD_UNKNOWN;
		}
		if (!applynow || proc_tid_exists(*res_pid))
			return SCHED_VTY_THREAD_ID;
		else
			return SCHED_VTY_THREAD_UNKNOWN;
	}

	if (len > 15) {
		/* Thread names only allow up to 15+1 null chars, see man pthread_setname_np */
		return SCHED_VTY_THREAD_UNKNOWN;
	}

	if (applynow) {
		if (proc_name_exists(str, res_pid))
			return SCHED_VTY_THREAD_NAME;
		else
			return SCHED_VTY_THREAD_UNKNOWN;
	} else  {
		/* assume a thread will be named after it */
		*res_pid = 0;
		return SCHED_VTY_THREAD_NAME;
	}
}

/* Wrapper for sched_setaffinity applying to single thread or all threads in process based on tid_type. */
static int my_sched_setaffinity(enum sched_vty_thread_id tid_type, pid_t pid,
				cpu_set_t *cpuset, size_t cpuset_size)
{
	DIR *proc_dir;
	struct dirent *entry;
	char dirname[100];
	char str_mask[1024];
	int tid_it;
	int rc = 0;

	if (generate_cpu_hex_mask(str_mask, sizeof(str_mask), cpuset, cpuset_size) < 0)
		str_mask[0] = '\0';

	if (tid_type != SCHED_VTY_THREAD_ALL) {
		LOGP(DLGLOBAL, LOGL_NOTICE, "Setting CPU affinity mask for tid %lu to: %s\n",
		     (unsigned long) pid, str_mask);

		rc = sched_setaffinity(pid, sizeof(cpu_set_t), cpuset);
		return rc;
	}

	snprintf(dirname, sizeof(dirname), "/proc/%ld/task", (long int)getpid());
	proc_dir = opendir(dirname);
	if (!proc_dir)
		return -EINVAL;

	while ((entry = readdir(proc_dir)))
	{
		if (entry->d_name[0] == '.')
			continue;
		tid_it = atoi(entry->d_name);
		LOGP(DLGLOBAL, LOGL_NOTICE, "Setting CPU affinity mask for tid %lu to: %s\n",
		     (unsigned long) tid_it, str_mask);

		rc = sched_setaffinity(tid_it, sizeof(cpu_set_t), cpuset);
		if (rc == -1)
			break;
	}

	closedir(proc_dir);
	return rc;

}

DEFUN(cfg_sched_cpu_affinity, cfg_sched_cpu_affinity_cmd,
	"cpu-affinity (self|all|<0-4294967295>|THREADNAME) CPUHEXMASK [delay]",
	"Set CPU affinity mask on a (group of) thread(s)\n"
	"Set CPU affinity mask on thread running the VTY\n"
	"Set CPU affinity mask on all process' threads\n"
	"Set CPU affinity mask on a thread with specified PID\n"
	"Set CPU affinity mask on a thread with specified thread name\n"
	"CPU affinity mask\n"
	"If set, delay applying the affinity mask now and let the app handle it at a later point\n")
{
	const char* str_who = argv[0];
	const char *str_mask = argv[1];
	bool applynow = (argc != 3);
	int rc;
	pid_t pid;
	enum sched_vty_thread_id tid_type;
	struct cpu_affinity_it *it, *it_next;
	cpu_set_t *cpuset;
	size_t cpuset_size;

	tid_type = procname2pid(&pid, str_who, applynow);
	if (tid_type == SCHED_VTY_THREAD_UNKNOWN) {
		vty_out(vty, "%% Failed parsing target thread %s%s",
		        str_who, VTY_NEWLINE);
		return CMD_WARNING;
	}

	if (tid_type == SCHED_VTY_THREAD_ID && !applynow)  {
		vty_out(vty, "%% It makes no sense to delay applying cpu-affinity on tid %lu%s",
			(unsigned long)pid, VTY_NEWLINE);
		return CMD_WARNING;
	}
	if (tid_type == SCHED_VTY_THREAD_ALL && !applynow)  {
		vty_out(vty, "%% It makes no sense to delay applying cpu-affinity on all threads%s",
			VTY_NEWLINE);
		return CMD_WARNING;
	}

	cpuset = CPU_ALLOC(get_num_cpus());
	cpuset_size = CPU_ALLOC_SIZE(get_num_cpus());
	if (parse_cpu_hex_mask(str_mask, cpuset, cpuset_size) < 0) {
		vty_out(vty, "%% Failed parsing CPU Affinity Mask %s%s",
		    str_mask, VTY_NEWLINE);
		CPU_FREE(cpuset);
		return CMD_WARNING;
	}

	if (applynow) {
		rc = my_sched_setaffinity(tid_type, pid, cpuset, cpuset_size);
		if (rc == -1) {
			vty_out(vty, "%% Failed setting sched CPU Affinity Mask %s: %s%s",
				str_mask, strerror(errno), VTY_NEWLINE);
			CPU_FREE(cpuset);
			return CMD_WARNING;
		}
	}

	/* Keep history of cmds applied to be able to rewrite config. If PID was passed
	   directly it makes no sense to store it since PIDs are temporary */
	if (tid_type == SCHED_VTY_THREAD_SELF ||
	    tid_type == SCHED_VTY_THREAD_ALL ||
	    tid_type == SCHED_VTY_THREAD_NAME) {
		pthread_mutex_lock(&sched_vty_opts->cpu_affinity_li_mutex);

		/* Drop previous entries matching, since they will be overwritten */
		llist_for_each_entry_safe(it, it_next, &sched_vty_opts->cpu_affinity_li, entry) {
			if (strcmp(it->bufname, str_who) == 0) {
				llist_del(&it->entry);
				CPU_FREE(it->cpuset);
				talloc_free(it);
				break;
			}
		}
		it = talloc_zero(sched_vty_opts->tall_ctx, struct cpu_affinity_it);
		OSMO_STRLCPY_ARRAY(it->bufname, str_who);
		it->tid_type = tid_type;
		it->cpuset = cpuset;
		it->cpuset_size = cpuset_size;
		it->delay = !applynow;
		llist_add_tail(&it->entry, &sched_vty_opts->cpu_affinity_li);

		pthread_mutex_unlock(&sched_vty_opts->cpu_affinity_li_mutex);
	} else {
		/* We don't need cpuset for later, free it: */
		CPU_FREE(cpuset);
	}
	return CMD_SUCCESS;
}

static int set_sched_rr(unsigned int prio)
{
	struct sched_param param;
	int rc;
	memset(&param, 0, sizeof(param));
	param.sched_priority = prio;
	LOGP(DLGLOBAL, LOGL_NOTICE, "Setting SCHED_RR priority %d\n", param.sched_priority);
	rc = sched_setscheduler(getpid(), SCHED_RR, &param);
	if (rc == -1) {
		LOGP(DLGLOBAL, LOGL_ERROR, "Setting SCHED_RR priority %d failed: %s\n",
		     param.sched_priority, strerror(errno));
		return -1;
	}
	return 0;
}

DEFUN(cfg_sched_policy, cfg_sched_policy_cmd,
	"policy rr <1-32>",
	"Set the scheduling policy to use for the process\n"
	"Use the SCHED_RR real-time scheduling algorithm\n"
	"Set the SCHED_RR real-time priority\n")
{
	sched_vty_opts->sched_rr_prio = atoi(argv[0]);

	if (set_sched_rr(sched_vty_opts->sched_rr_prio) < 0) {
		vty_out(vty, "%% Failed setting SCHED_RR priority %d%s",
			sched_vty_opts->sched_rr_prio, VTY_NEWLINE);
		return CMD_WARNING;
	}

	return CMD_SUCCESS;
}

DEFUN(cfg_sched,
      cfg_sched_cmd,
      "cpu-sched", "Configure CPU Scheduler related settings")
{
	vty->index = NULL;
	vty->node = L_CPU_SCHED_NODE;

	return CMD_SUCCESS;
}

DEFUN(show_sched_threads, show_sched_threads_cmd,
	"show cpu-sched threads",
	SHOW_STR
	"Show Sched section information\n"
	"Show information about running threads)\n")
{
	DIR *proc_dir;
	struct dirent *entry;
	char path[100];
	char name[17];
	char str_mask[1024];
	int tid_it;
	int fd;
	pid_t mypid = getpid();
	int rc;
	cpu_set_t *cpuset;
	size_t cpuset_size;

	vty_out(vty, "Thread list for PID %lu:%s", (unsigned long) mypid, VTY_NEWLINE);

	snprintf(path, sizeof(path), "/proc/%ld/task", (long int)mypid);
	proc_dir = opendir(path);
	if (!proc_dir) {
		vty_out(vty, "%% Failed opening dir%s%s", path, VTY_NEWLINE);
		return CMD_WARNING;
	}

	while ((entry = readdir(proc_dir)))
	{
		if (entry->d_name[0] == '.')
			continue;

		tid_it = atoi(entry->d_name);
		snprintf(path, sizeof(path), "/proc/%ld/task/%ld/comm", (long int)mypid, (long int)tid_it);
		if ((fd = open(path, O_RDONLY)) != -1) {
			rc = read(fd, name, sizeof(name) - 1);
			if (rc >= 0) {
				/* Last may char contain a '\n', get rid of it */
				if (rc > 0 && name[rc - 1] == '\n')
					name[rc - 1] = '\0';
				else
					name[rc] = '\0';
			}
			close(fd);
		} else {
			name[0] = '\0';
		}

		str_mask[0] = '\0';
		cpuset = CPU_ALLOC(get_num_cpus());
		cpuset_size = CPU_ALLOC_SIZE(get_num_cpus());
		CPU_ZERO_S(cpuset_size, cpuset);
		if (sched_getaffinity(tid_it, cpuset_size, cpuset) == 0) {
			if (generate_cpu_hex_mask(str_mask, sizeof(str_mask), cpuset, cpuset_size) < 0)
				str_mask[0] = '\0';
		}
		CPU_FREE(cpuset);

		vty_out(vty, " TID: %lu, NAME: '%s', cpu-affinity: %s%s",
			(unsigned long) tid_it, name, str_mask, VTY_NEWLINE);
	}

	closedir(proc_dir);
	return CMD_SUCCESS;
}

static int config_write_sched(struct vty *vty)
{
	struct cpu_affinity_it *it;
	char str_mask[1024];

	/* Only add the node if there's something to write under it */
	if (sched_vty_opts->sched_rr_prio || !llist_empty(&sched_vty_opts->cpu_affinity_li))
		vty_out(vty, "cpu-sched%s", VTY_NEWLINE);

	if (sched_vty_opts->sched_rr_prio)
		vty_out(vty, " policy rr %d%s", sched_vty_opts->sched_rr_prio, VTY_NEWLINE);

	llist_for_each_entry(it, &sched_vty_opts->cpu_affinity_li, entry) {
		if (generate_cpu_hex_mask(str_mask, sizeof(str_mask), it->cpuset, it->cpuset_size) < 0)
			OSMO_STRLCPY_ARRAY(str_mask, "ERROR");
		vty_out(vty, " cpu-affinity %s %s%s%s", it->bufname, str_mask,
			it->delay ? " delay" : "", VTY_NEWLINE);
	}

	return CMD_SUCCESS;
}

/*! Initialize sched VTY nodes
 * \param[in] tall_ctx  Talloc context to use internally by vty_sched subsystem.
 * \return 0 on success, non-zero on error.
 */
int osmo_cpu_sched_vty_init(void *tall_ctx)
{
	OSMO_ASSERT(!sched_vty_opts); /* assert only called once */

	sched_vty_opts = talloc_zero(tall_ctx, struct sched_vty_opts);
	sched_vty_opts->tall_ctx = tall_ctx;
	INIT_LLIST_HEAD(&sched_vty_opts->cpu_affinity_li);
	pthread_mutex_init(&sched_vty_opts->cpu_affinity_li_mutex, NULL);

	install_element(CONFIG_NODE, &cfg_sched_cmd);
	install_node(&sched_node, config_write_sched);

	install_element(L_CPU_SCHED_NODE, &cfg_sched_policy_cmd);
	install_element(L_CPU_SCHED_NODE, &cfg_sched_cpu_affinity_cmd);

	install_element_ve(&show_sched_threads_cmd);

	/* Initialize amount of cpus now */
	if (get_num_cpus() < 0)
		return -1;

	return 0;
}

/*! Apply cpu-affinity on calling thread based on VTY configuration
 * \return 0 on success, non-zero on error.
 */
int osmo_cpu_sched_vty_apply_localthread(void)
{
	struct cpu_affinity_it *it, *it_match = NULL;
	char name[16];  /* 15 + \0 */
	char str_mask[1024];
	bool has_name = false;
	int rc = 0;

	/* Assert subsystem was inited and structs are preset */
	if (!sched_vty_opts) {
		LOGP(DLGLOBAL, LOGL_FATAL, "Setting cpu-affinity mask impossible: no opts!\n");
		return 0;
	}

	if (pthread_getname_np(pthread_self(), name, sizeof(name)) == 0)
		has_name = true;

	/* Get latest matching mask for the thread */
	pthread_mutex_lock(&sched_vty_opts->cpu_affinity_li_mutex);
	llist_for_each_entry(it, &sched_vty_opts->cpu_affinity_li, entry) {
		switch (it->tid_type) {
		case SCHED_VTY_THREAD_SELF:
			continue; /* self to the VTY thread, not us */
		case SCHED_VTY_THREAD_ALL:
			it_match = it;
			break;
		case SCHED_VTY_THREAD_NAME:
			if (!has_name)
				continue;
			if (strcmp(name, it->bufname) != 0)
				continue;
			it_match = it;
			break;
		default:
			OSMO_ASSERT(0);
		}
	}

	if (it_match) {
		rc = my_sched_setaffinity(SCHED_VTY_THREAD_SELF, 0, it_match->cpuset, it_match->cpuset_size);
		if (rc == -1) {
			if (generate_cpu_hex_mask(str_mask, sizeof(str_mask),
						  it_match->cpuset, it_match->cpuset_size) < 0)
				str_mask[0] = '\0';
			LOGP(DLGLOBAL, LOGL_FATAL, "Setting cpu-affinity mask %s failed: %s\n",
			     str_mask, strerror(errno));
		}
	}
	pthread_mutex_unlock(&sched_vty_opts->cpu_affinity_li_mutex);
	return rc;
}

/*! @} */
