/*****************************************************************************\
 *  signal.c - signals for connection manager
 *****************************************************************************
 *  Copyright (C) SchedMD LLC.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm 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.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm 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 Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#include <signal.h>

#include "src/common/fd.h"
#include "src/common/macros.h"
#include "src/common/proc_args.h"
#include "src/common/read_config.h"
#include "src/common/xmalloc.h"

#include "src/conmgr/conmgr.h"
#include "src/conmgr/mgr.h"

#define SIGNAL_FD_FAILED -250

typedef struct {
#define MAGIC_SIGNAL_HANDLER 0xC20A444A
	int magic; /* MAGIC_SIGNAL_HANDLER */
	struct sigaction prior;
	struct sigaction new;
	int signal;
} signal_handler_t;

/* protects all of the static variables here */
pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;

/* protected by lock */
static bool one_time_init = false;

/* list of all registered signal handlers */
static signal_handler_t *signal_handlers = NULL;
static int signal_handler_count = 0;

/* list of all registered signal work */
static work_t **signal_work = NULL;
static int signal_work_count = 0;

/* interrupt handler (_signal_handler()) will send signal to this fd */
static volatile sig_atomic_t signal_fd = -1;
static conmgr_fd_t *signal_con = NULL;

static void _signal_handler(int signo)
{
	/*
	 * Per the sigaction man page:
	 * 	A child created via fork(2) inherits a copy of its parent's
	 * 	signal dispositions.
	 *
	 * Signal handler registration survives fork() but the signal_mgr()
	 * thread will be lost. Gracefully ignore signals when signal_fd_send is
	 * -1 to avoid trying to write a non-existent file descriptor.
	 */
	if (signal_fd < 0)
		return;

try_again:
	if (write(signal_fd, &signo, sizeof(signo)) != sizeof(signo)) {
		if ((errno == EPIPE) || (errno == EBADF)) {
			/*
			 * write() after conmgr shutdown before reading that
			 * signal_fd was closed. Ignoring this race condition
			 * entirely. Set signal_fd to an invalid value that is
			 * not -1 to distinguish it from the normal "unset"
			 * state.
			 */
			signal_fd = SIGNAL_FD_FAILED;
			return;
		}

		if (errno == EINTR)
			goto try_again;

		/*
		 * Drop signal as the buffer is already full which means
		 * something bad has already happened and having the exact
		 * signal numbers isn't going to make much difference.
		 */
		if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
			return;

		/* TODO: replace with signal_safe_fatal() */
		fatal_abort("%s: unable to signal connection manager: %m",
			    __func__);
	}
}

/* caller must hold write lock */
static void _register_signal_handler(int signal)
{
	signal_handler_t *handler;

	for (int i = 0; i < signal_handler_count; i++) {
		xassert(signal_handlers[i].magic == MAGIC_SIGNAL_HANDLER);

		if (signal_handlers[i].signal == signal)
			return;
	}

	xrecalloc(signal_handlers, (signal_handler_count + 1),
		  sizeof(*signal_handlers));

	handler = &signal_handlers[signal_handler_count];
	handler->magic = MAGIC_SIGNAL_HANDLER;
	handler->signal = signal;
	handler->new.sa_handler = _signal_handler;

	if (sigaction(signal, &handler->new, &handler->prior))
		fatal("%s: unable to catch %s: %m",
		      __func__, strsignal(signal));

	if (slurm_conf.debug_flags & DEBUG_FLAG_CONMGR) {
		char *signame = sig_num2name(handler->signal);

		log_flag(CONMGR, "%s: installed signal %s[%d] handler: Prior=0x%"PRIxPTR" is now replaced with New=0x%"PRIxPTR,
			 __func__, signame, signal,
			 (uintptr_t) handler->prior.sa_handler,
			 (uintptr_t) handler->new.sa_handler);
		xfree(signame);
	}

	signal_handler_count++;
}

/* caller must hold write lock */
static void _init_signal_handler(void)
{
	if (signal_handlers)
		return;

	for (int i = 0; i < signal_work_count; i++) {
		work_t *work = signal_work[i];
		xassert(work->magic == MAGIC_WORK);

		_register_signal_handler(work->control.on_signal_number);
	}
}

/* mgr.mutex should be locked */
static void _on_signal(int signal)
{
	bool matched = false;

	slurm_rwlock_rdlock(&lock);

	if (slurm_conf.debug_flags & DEBUG_FLAG_CONMGR) {
		char *str = sig_num2name(signal);
		log_flag(CONMGR, "%s: [%s] got signal: %s(%d)",
			 __func__, signal_con->name, str, signal);
		xfree(str);
	}

	for (int i = 0; i < signal_work_count; i++) {
		work_t *work = signal_work[i];

		xassert(work->magic == MAGIC_WORK);

		if (work->control.on_signal_number != signal)
			continue;

		matched = true;
		add_work(true, NULL, work->callback, work->control,
			 ~CONMGR_WORK_DEP_SIGNAL, __func__);
	}

	slurm_rwlock_unlock(&lock);

	if (!matched)
		warning("%s: caught and ignoring signal %s",
			__func__, strsignal(signal));
}

extern void add_work_signal(work_t *work)
{
	xassert(!work->ref);
	xassert(work->control.depend_type & CONMGR_WORK_DEP_SIGNAL);
	xassert(work->control.on_signal_number > 0);

	slurm_rwlock_wrlock(&lock);

	xrecalloc(signal_work, (signal_work_count + 1), sizeof(*signal_work));

	signal_work[signal_work_count] = work;
	signal_work_count++;

	/*
	 * Directly register new signal handler since connection already started
	 * and init_signal_handler() already ran
	 */
	if (signal_con)
		_register_signal_handler(work->control.on_signal_number);

	slurm_rwlock_unlock(&lock);
}

static void *_on_connection(conmgr_fd_t *con, void *arg)
{
	slurm_rwlock_wrlock(&lock);

	_init_signal_handler();
	signal_con = con;

	slurm_rwlock_unlock(&lock);

	return con;
}

static int _on_data(conmgr_fd_t *con, void *arg)
{
	const void *data = NULL;
	size_t bytes = 0, read = 0;
	int signo;

	xassert(arg == con);

	conmgr_fd_get_in_buffer(con, &data, &bytes);

	slurm_mutex_lock(&mgr.mutex);
	while ((read + sizeof(signo)) <= bytes) {
		signo = *(int *) (data + read);

		_on_signal(signo);

		read += sizeof(signo);
	}
	slurm_mutex_unlock(&mgr.mutex);

	conmgr_fd_mark_consumed_in_buffer(con, read);

	return SLURM_SUCCESS;
}

static void _on_finish(conmgr_fd_t *con, void *arg)
{
	int fd;

	xassert(arg == con);

	slurm_rwlock_wrlock(&lock);

	fd = signal_fd;
	signal_fd = -1;

	xassert(fd != -1);
	fd_close(&fd);

	xassert((con == signal_con) || !signal_con);
	signal_con = NULL;

	slurm_rwlock_unlock(&lock);
}

static void _atfork_child(void)
{
	/*
	 * Force state to return to default state before it was initialized at
	 * forking as all of the prior state is completely unusable.
	 */
	lock = (pthread_rwlock_t) PTHREAD_RWLOCK_INITIALIZER;
	one_time_init = false;
	signal_handlers = NULL;
	signal_handler_count = 0;
	signal_work = NULL;
	signal_work_count = 0;
	signal_fd = -1;
	signal_con = NULL;
}

extern void signal_mgr_start(conmgr_callback_args_t conmgr_args, void *arg)
{
	static const conmgr_events_t events = {
		.on_connection = _on_connection,
		.on_data = _on_data,
		.on_finish = _on_finish,
	};
	int fd[2] = { -1, -1 };
	int rc;

	if (conmgr_args.status == CONMGR_WORK_STATUS_CANCELLED)
		return;

	slurm_rwlock_wrlock(&lock);

	if (signal_fd >= 0) {
		slurm_rwlock_unlock(&lock);
		log_flag(CONMGR, "%s: skipping - already initialized",
			 __func__);
		return;
	}

	if (pipe(fd))
		fatal_abort("%s: pipe() failed: %m", __func__);

	if (!one_time_init) {
		if ((rc = pthread_atfork(NULL, NULL, _atfork_child)))
			fatal_abort("%s: pthread_atfork() failed: %s",
				    __func__, slurm_strerror(rc));
		one_time_init = true;
	}

	xassert(signal_fd == -1);
	xassert(!signal_con);

	fd_set_close_on_exec(fd[0]);
	fd_set_close_on_exec(fd[1]);

	fd_set_nonblocking(fd[1]);
	signal_fd = fd[1];

	slurm_rwlock_unlock(&lock);

	if (add_connection(CON_TYPE_RAW, NULL, fd[0], -1, &events,
			    CON_FLAG_NONE, NULL, 0, false, NULL, NULL, NULL)) {
		fatal_abort("%s: [fd:%d] unable to a register new connection",
			    __func__, fd[0]);
	}
}

extern void signal_mgr_stop(void)
{
	slurm_rwlock_wrlock(&lock);

	if (signal_con) {
		close_con(true, signal_con);
		signal_con = NULL;
	}

	slurm_rwlock_unlock(&lock);
}

extern void signal_mgr_fini(void)
{
	signal_handler_t *handlers = NULL;
	int signal_fd_close = -1, count = 0;

	signal_mgr_stop();

	slurm_rwlock_wrlock(&lock);

	if (!one_time_init) {
		slurm_rwlock_unlock(&lock);
		return;
	}

	xassert(one_time_init);
	/* should already be cleaned up by signal_mgr_stop() */
	xassert(!signal_con);

	/* try to be as atomic as possible to close(signal_fd) */
	signal_fd_close = signal_fd;
	signal_fd = SIGNAL_FD_FAILED;
	fd_close(&signal_fd_close);

	/* Swap out handlers array before cleanup */
	SWAP(signal_handler_count, count);
	SWAP(signal_handlers, handlers);

	for (int i = 0; i < signal_handler_count; i++) {
		signal_handler_t *handler = &handlers[signal_handler_count];

		xassert(handler->magic == MAGIC_SIGNAL_HANDLER);
		xassert(handler->signal > 0);

		if (sigaction(handler->signal, &handler->prior, &handler->new))
			fatal("%s: unable to revert %s: %m",
			      __func__, strsignal(handler->signal));

		/* clear handler entirely */
		*handler = (signal_handler_t) {
			.magic = ~MAGIC_SIGNAL_HANDLER,
		};
	}

	xfree(handlers);

	for (int i = 0; i < signal_work_count; i++) {
		work_t *work = NULL;

		SWAP(signal_work[i], work);
		xassert(work->magic == MAGIC_WORK);

		work->status = CONMGR_WORK_STATUS_CANCELLED;
		handle_work(true, work);
	}

	xfree(signal_work);
	signal_work_count = 0;

	slurm_rwlock_unlock(&lock);
}

extern bool is_signal_connection(conmgr_fd_t *con)
{
	bool match;

	slurm_rwlock_rdlock(&lock);
	match = (signal_con == con);
	slurm_rwlock_unlock(&lock);

	return match;
}

extern bool signal_mgr_has_incoming(void)
{
	bool has_data = false;

	slurm_rwlock_rdlock(&lock);

	if (signal_con) {
		if (signal_con->input_fd >= 0) {
			int readable = -1;

			/*
			 * Force (blocking) check of signal_fd since poll() may
			 * have not run yet but need to make sure to catch any
			 * pending data if possible.
			 *
			 * Ignore failure of FIONREAD here as we only care if
			 * there is pending data
			 */
			(void) fd_get_readable_bytes(signal_con->input_fd,
						     &readable,
						     signal_con->name);

			if (readable > 0)
				has_data = true;
		}

		if (!has_data)
			has_data =
				con_flag(signal_con, FLAG_CAN_READ) ||
				(signal_con->in &&
				 get_buf_offset(signal_con->in)) ||
				(signal_con->work &&
				 !list_is_empty(signal_con->work)) ||
				(signal_con->write_complete_work &&
				 !list_is_empty(signal_con->write_complete_work));
	}

	slurm_rwlock_unlock(&lock);

	return has_data;
}
