/*****************************************************************************\
 *  trigger_mgr.c - Event trigger management
 *****************************************************************************
 *  Copyright (C) 2007 The Regents of the University of California.
 *  Copyright (C) 2008-2010 Lawrence Livermore National Security.
 *  Copyright (C) SchedMD LLC.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Morris Jette <jette1@llnl.gov> et. al.
 *  CODE-OCEC-09-009. All rights reserved.
 *
 *  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 "config.h"

#define _GNU_SOURCE	/* for setresuid() */

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "src/common/bitstring.h"
#include "src/common/fd.h"
#include "src/common/list.h"
#include "src/common/slurmdbd_defs.h"
#include "src/common/slurm_protocol_defs.h"
#include "src/common/state_save.h"
#include "src/common/uid.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#include "src/slurmctld/locks.h"
#include "src/slurmctld/slurmctld.h"
#include "src/slurmctld/state_save.h"
#include "src/slurmctld/trigger_mgr.h"

#define MAX_PROG_TIME 300	/* maximum run time for program */

/* Change TRIGGER_STATE_VERSION value when changing the state save format */
#define TRIGGER_STATE_VERSION        "PROTOCOL_VERSION"

list_t *trigger_list = NULL;
uint32_t next_trigger_id = 1;
static pthread_mutex_t trigger_mutex = PTHREAD_MUTEX_INITIALIZER;
bitstr_t *trigger_down_nodes_bitmap = NULL;
bitstr_t *trigger_drained_nodes_bitmap = NULL;
bitstr_t *trigger_fail_nodes_bitmap = NULL;
bitstr_t *trigger_up_nodes_bitmap   = NULL;
bitstr_t *trigger_draining_nodes_bitmap = NULL;
bitstr_t *trigger_resume_nodes_bitmap = NULL;
static bool trigger_bb_error = false;
static bool trigger_node_reconfig = false;
static bool trigger_pri_ctld_fail = false;
static bool trigger_pri_ctld_res_op = false;
static bool trigger_pri_ctld_res_ctrl = false;
static bool trigger_pri_ctld_acct_buffer_full = false;
static bool trigger_bu_ctld_fail = false;
static bool trigger_bu_ctld_res_op = false;
static bool trigger_bu_ctld_as_ctrl = false;
static bool trigger_pri_dbd_fail = false;
static bool trigger_pri_dbd_res_op = false;
static bool trigger_pri_db_fail = false;
static bool trigger_pri_db_res_op = false;

/* Current trigger pull states (saved and restored) */
uint8_t ctld_failure = 0;
uint8_t bu_ctld_failure = 0;
uint8_t db_failure = 0;
uint8_t dbd_failure = 0;

typedef struct trig_mgr_info {
	uint32_t child_pid;	/* pid of child process */
	uint16_t flags;		/* TRIGGER_FLAG_* */
	uint32_t trig_id;	/* trigger ID */
	uint16_t res_type;	/* TRIGGER_RES_TYPE_* */
	char *   res_id;	/* node name or job_id (string) */
	bitstr_t *nodes_bitmap;	/* bitmap of requested nodes (if applicable) */
	uint32_t job_id;	/* job ID (if applicable) */
	uint32_t trig_type;	/* TRIGGER_TYPE_* */
	time_t   trig_time;	/* offset (pending) or time stamp (complete) */
	uint32_t user_id;	/* user requesting trigger */
	uint32_t group_id;	/* user's group id */
	char *   program;	/* program to execute */
	uint8_t  state;		/* 0=pending, 1=pulled, 2=completed */

	/* The orig_ fields are used to save  and clone the original values */
	bitstr_t *orig_bitmap;	/* bitmap of requested nodes (if applicable) */
	char *   orig_res_id;	/* original node name or job_id (string) */
	time_t   orig_time;	/* offset (pending) or time stamp (complete) */
} trig_mgr_info_t;

static void _trig_del(void *x)
{
	trig_mgr_info_t *tmp = x;

	xfree(tmp->res_id);
	xfree(tmp->orig_res_id);
	xfree(tmp->program);
	FREE_NULL_BITMAP(tmp->nodes_bitmap);
	FREE_NULL_BITMAP(tmp->orig_bitmap);
	xfree(tmp);
}

static int _trig_offset(uint16_t offset)
{
	static int rc;
	rc  = offset;
	rc -= 0x8000;
	return rc;
}

static void _dump_trigger_msg(char *header, trigger_info_msg_t *msg)
{
	int i;

	if (!(slurm_conf.debug_flags & DEBUG_FLAG_TRIGGERS))
		return;

	info("%s", header);
	if ((msg == NULL) || (msg->record_count == 0)) {
		info("Trigger has no entries");
		return;
	}

	info("INDEX TRIG_ID RES_TYPE RES_ID TRIG_TYPE OFFSET UID PROGRAM");
	for (i=0; i<msg->record_count; i++) {
		info("trigger[%u] %u %s %s %s %d %u %s", i,
		     msg->trigger_array[i].trig_id,
		     trigger_res_type(msg->trigger_array[i].res_type),
		     msg->trigger_array[i].res_id,
		     trigger_type(msg->trigger_array[i].trig_type),
		     _trig_offset(msg->trigger_array[i].offset),
		     msg->trigger_array[i].user_id,
		     msg->trigger_array[i].program);
	}
}

/* Validate trigger program */
static bool _validate_trigger(trig_mgr_info_t *trig_in)
{
	struct stat buf;
	int i, modes;
	char *program = xstrdup(trig_in->program);

	for (i = 0; program[i]; i++) {
		if (isspace(program[i])) {
			program[i] = '\0';
			break;
		}
	}

	if (stat(program, &buf) != 0) {
		info("trigger program %s not found", trig_in->program);
		xfree(program);
		return false;
	}
	xfree(program);

	if (!S_ISREG(buf.st_mode)) {
		info("trigger program %s not a regular file", trig_in->program);
		return false;
	}
	if (buf.st_uid == trig_in->user_id)
		modes =  (buf.st_mode >> 6) & 07;
	else if (buf.st_gid == trig_in->group_id)
		modes =  (buf.st_mode >> 3) & 07;
	else
		modes = buf.st_mode  & 07;
	if (modes & 01)
		return true;

	info("trigger program %s not executable", trig_in->program);
	return false;
}


extern int trigger_pull(trigger_info_msg_t *msg)
{
	int rc = SLURM_SUCCESS;
	list_itr_t *trig_iter;
	trigger_info_t *trig_in;
	trig_mgr_info_t *trig_test;

	if (trigger_list == NULL) {
		trigger_list = list_create(_trig_del);
	}

	/* validate the request, designated trigger must be set */
	_dump_trigger_msg("trigger_pull", msg);
	if (msg->record_count != 1)
		return ESRCH;
	trig_in = msg->trigger_array;

	if ((trig_in->res_type != TRIGGER_RES_TYPE_SLURMCTLD) &&
	    (trig_in->res_type != TRIGGER_RES_TYPE_SLURMDBD)  &&
	    (trig_in->res_type != TRIGGER_RES_TYPE_DATABASE)) {
		return EINVAL;
	}

	/* now look for a valid request */
	trig_iter = list_iterator_create(trigger_list);
	while ((trig_test = list_next(trig_iter))) {
		if ((trig_test->res_type  == trig_in->res_type) &&
   		    (trig_test->trig_type == trig_in->trig_type)) {
			switch(trig_test->trig_type) {
			case TRIGGER_TYPE_PRI_CTLD_ACCT_FULL:
				trigger_primary_ctld_acct_full();
				break;
			case TRIGGER_TYPE_BU_CTLD_FAIL:
				trigger_backup_ctld_fail(trig_in->control_inx);
				break;
			case TRIGGER_TYPE_BU_CTLD_RES_OP:
				trigger_backup_ctld_res_op(trig_in->control_inx);
				break;
			case TRIGGER_TYPE_BU_CTLD_AS_CTRL:
				trigger_backup_ctld_as_ctrl();
				break;
			case TRIGGER_TYPE_PRI_DBD_FAIL:
				trigger_primary_dbd_fail();
				break;
			case TRIGGER_TYPE_PRI_DBD_RES_OP:
				trigger_primary_dbd_res_op();
				break;
			case TRIGGER_TYPE_PRI_DB_FAIL:
				trigger_primary_db_fail();
				break;
			case TRIGGER_TYPE_PRI_DB_RES_OP:
				trigger_primary_db_res_op();
				break;
			default:
				error("trigger_pull call has invalid type: %u",
				      trig_test->trig_type);
				rc = EINVAL;
				break;
			}
		}
	}
	list_iterator_destroy(trig_iter);

	return rc;
}

extern int trigger_clear(uid_t uid, trigger_info_msg_t *msg)
{
	int rc = ESRCH;
	list_itr_t *trig_iter;
	trigger_info_t *trig_in;
	trig_mgr_info_t *trig_test;
	uint32_t job_id = 0;

	slurm_mutex_lock(&trigger_mutex);
	if (trigger_list == NULL)
		trigger_list = list_create(_trig_del);

	/* validate the request, need a job_id and/or trigger_id */
	_dump_trigger_msg("trigger_clear", msg);
	if (msg->record_count != 1)
		goto fini;
	trig_in = msg->trigger_array;
	if (trig_in->res_type == TRIGGER_RES_TYPE_JOB) {
		job_id = (uint32_t) atol(trig_in->res_id);
		if (job_id == 0) {
			rc = ESLURM_INVALID_JOB_ID;
			goto fini;
		}
	} else if ((trig_in->trig_id == 0) && (trig_in->user_id == NO_VAL)) {
		rc = EINVAL;
		goto fini;
	}

	/* now look for a valid request, matching uid */
	trig_iter = list_iterator_create(trigger_list);
	while ((trig_test = list_next(trig_iter))) {
		if (trig_in->trig_id &&
		    (trig_in->trig_id != trig_test->trig_id))
			continue;
		if (job_id && (job_id != trig_test->job_id))
			continue;
		if ((trig_in->user_id != NO_VAL) &&
		    (trig_in->user_id != trig_test->user_id))
			continue;
		if (trig_test->state == 2)	/* wait for proc termination */
			continue;
		if ((trig_test->user_id != (uint32_t) uid) && (uid != 0)) {
			rc = ESLURM_ACCESS_DENIED;
			continue;
		}
		list_delete_item(trig_iter);
		rc = SLURM_SUCCESS;
	}
	list_iterator_destroy(trig_iter);
	schedule_trigger_save();

fini:	slurm_mutex_unlock(&trigger_mutex);
	return rc;
}

extern trigger_info_msg_t * trigger_get(uid_t uid, trigger_info_msg_t *msg)
{
	trigger_info_msg_t *resp_data;
	list_itr_t *trig_iter;
	trigger_info_t *trig_out;
	trig_mgr_info_t *trig_in;
	int recs_written = 0;

	slurm_mutex_lock(&trigger_mutex);
	if (trigger_list == NULL)
		trigger_list = list_create(_trig_del);

	_dump_trigger_msg("trigger_get", NULL);
	resp_data = xmalloc(sizeof(trigger_info_msg_t));
	resp_data->record_count = list_count(trigger_list);
	resp_data->trigger_array = xcalloc(resp_data->record_count,
					   sizeof(trigger_info_t));
	trig_iter = list_iterator_create(trigger_list);
	trig_out = resp_data->trigger_array;
	while ((trig_in = list_next(trig_iter))) {
		/* Note: Filtering currently done by strigger */
		if ((trig_in->state >= 1) &&
		    ((trig_out->flags & TRIGGER_FLAG_PERM) == 0))
			continue;	/* no longer pending */
		trig_out->flags     = trig_in->flags;
		trig_out->trig_id   = trig_in->trig_id;
		trig_out->res_type  = trig_in->res_type;
		trig_out->res_id    = xstrdup(trig_in->res_id);
		trig_out->trig_type = trig_in->trig_type;
		trig_out->offset    = trig_in->trig_time;
		trig_out->user_id   = trig_in->user_id;
		trig_out->program   = xstrdup(trig_in->program);
		trig_out++;
		recs_written++;
	}
	list_iterator_destroy(trig_iter);
	slurm_mutex_unlock(&trigger_mutex);
	resp_data->record_count = recs_written;

	_dump_trigger_msg("trigger_got", resp_data);
	return resp_data;
}

static bool _duplicate_trigger(trigger_info_t *trig_desc)
{
	bool found_dup = false;
	list_itr_t *trig_iter;
	trig_mgr_info_t *trig_rec;

	trig_iter = list_iterator_create(trigger_list);
	while ((trig_rec = list_next(trig_iter))) {
		if ((trig_desc->flags     == trig_rec->flags)      &&
		    (trig_desc->res_type  == trig_rec->res_type)   &&
		    (trig_desc->trig_type == trig_rec->trig_type)  &&
		    (trig_desc->offset    == trig_rec->trig_time)  &&
		    (trig_desc->user_id   == trig_rec->user_id)    &&
		    !xstrcmp(trig_desc->program, trig_rec->program) &&
		    !xstrcmp(trig_desc->res_id, trig_rec->res_id)) {
			found_dup = true;
			break;
		}
	}
	list_iterator_destroy(trig_iter);
	return found_dup;
}

extern int trigger_set(uid_t uid, gid_t gid, trigger_info_msg_t *msg)
{
	int i;
	int rc = SLURM_SUCCESS;
	uint32_t job_id;
	bitstr_t *bitmap = NULL;
	trig_mgr_info_t * trig_add;
	job_record_t *job_ptr;
	/* Read config and job info */
	slurmctld_lock_t job_read_lock =
		{ READ_LOCK, READ_LOCK, NO_LOCK, NO_LOCK, NO_LOCK };

	lock_slurmctld(job_read_lock);
	slurm_mutex_lock(&trigger_mutex);

	if ((slurm_conf.slurm_user_id != 0) &&
	    (slurm_conf.slurm_user_id != uid)) {
		/* If SlurmUser is not root, then it is unable to set the
		 * appropriate user id and group id for the program to be
		 * launched. To prevent the launched program for an arbitrary
		 * user being executed as user SlurmUser, disable all other
		 * users from setting triggers. */
		info("Attempt to set trigger by uid %u != SlurmUser", uid);
		rc = ESLURM_ACCESS_DENIED;
		goto fini;
	}

	if (trigger_list == NULL) {
		trigger_list = list_create(_trig_del);
	} else if ((uid != 0) &&
	           (list_count(trigger_list) >= slurm_conf.max_job_cnt)) {
		rc = EAGAIN;
		goto fini;
	}

	_dump_trigger_msg("trigger_set", msg);
	for (i = 0; i < msg->record_count; i++) {
		if (msg->trigger_array[i].res_type ==
		    TRIGGER_RES_TYPE_JOB) {
			job_id = (uint32_t) atol(
				 msg->trigger_array[i].res_id);
			job_ptr = find_job_record(job_id);
			if (job_ptr == NULL) {
				rc = ESLURM_INVALID_JOB_ID;
				continue;
			}
			if (IS_JOB_FINISHED(job_ptr)) {
				rc = ESLURM_ALREADY_DONE;
				continue;
			}
		} else {
			job_id = 0;
			job_ptr = NULL;
			if ((msg->trigger_array[i].res_id != NULL)   &&
			    (msg->trigger_array[i].res_id[0] != '*') &&
			    (node_name2bitmap(msg->trigger_array[i].res_id,
					      false, &bitmap, NULL))) {
				FREE_NULL_BITMAP(bitmap);
				rc = ESLURM_INVALID_NODE_NAME;
				continue;
			}
		}
		msg->trigger_array[i].user_id = (uint32_t) uid;
		if (_duplicate_trigger(&msg->trigger_array[i])) {
			FREE_NULL_BITMAP(bitmap);
			rc = ESLURM_TRIGGER_DUP;
			continue;
		}
		trig_add = xmalloc(sizeof(trig_mgr_info_t));
		msg->trigger_array[i].trig_id = next_trigger_id;
		trig_add->trig_id = next_trigger_id;
		next_trigger_id++;
		trig_add->flags = msg->trigger_array[i].flags;
		trig_add->res_type = msg->trigger_array[i].res_type;
		if (bitmap) {
			trig_add->nodes_bitmap = bitmap;
			trig_add->orig_bitmap  = bit_copy(bitmap);
			bitmap = NULL;
		}
		trig_add->job_id = job_id;
		if (msg->trigger_array[i].res_id) {
			trig_add->res_id = msg->trigger_array[i].res_id;
			trig_add->orig_res_id = xstrdup(trig_add->res_id);
			msg->trigger_array[i].res_id = NULL; /* moved */
		}
		trig_add->trig_type = msg->trigger_array[i].trig_type;
		trig_add->trig_time = msg->trigger_array[i].offset;
		trig_add->orig_time = msg->trigger_array[i].offset;
		trig_add->user_id   = msg->trigger_array[i].user_id;
		trig_add->group_id  = (uint32_t) gid;
		/* move don't copy "program" */
		trig_add->program = msg->trigger_array[i].program;
		msg->trigger_array[i].program = NULL;
		if (!_validate_trigger(trig_add)) {
			rc = ESLURM_ACCESS_DENIED;
			FREE_NULL_BITMAP(trig_add->nodes_bitmap);
			FREE_NULL_BITMAP(trig_add->orig_bitmap);
			xfree(trig_add->program);
			xfree(trig_add->res_id);
			xfree(trig_add);
			continue;
		}
		list_append(trigger_list, trig_add);
		schedule_trigger_save();
	}

fini:	slurm_mutex_unlock(&trigger_mutex);
	unlock_slurmctld(job_read_lock);
	return rc;
}

extern void trigger_node_down(node_record_t *node_ptr)
{
	xassert(verify_lock(NODE_LOCK, READ_LOCK));

	slurm_mutex_lock(&trigger_mutex);
	if (trigger_down_nodes_bitmap == NULL)
		trigger_down_nodes_bitmap = bit_alloc(node_record_count);
	bit_set(trigger_down_nodes_bitmap, node_ptr->index);
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_node_drained(node_record_t *node_ptr)
{
	xassert(verify_lock(NODE_LOCK, READ_LOCK));

	slurm_mutex_lock(&trigger_mutex);
	if (trigger_drained_nodes_bitmap == NULL)
		trigger_drained_nodes_bitmap = bit_alloc(node_record_count);
	bit_set(trigger_drained_nodes_bitmap, node_ptr->index);
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_node_failing(node_record_t *node_ptr)
{
	xassert(verify_lock(NODE_LOCK, READ_LOCK));

	slurm_mutex_lock(&trigger_mutex);
	if (trigger_fail_nodes_bitmap == NULL)
		trigger_fail_nodes_bitmap = bit_alloc(node_record_count);
	bit_set(trigger_fail_nodes_bitmap, node_ptr->index);
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_node_up(node_record_t *node_ptr)
{
	xassert(verify_lock(NODE_LOCK, READ_LOCK));

	slurm_mutex_lock(&trigger_mutex);
	if (trigger_up_nodes_bitmap == NULL)
		trigger_up_nodes_bitmap = bit_alloc(node_record_count);
	bit_set(trigger_up_nodes_bitmap, node_ptr->index);
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_node_draining(node_record_t *node_ptr)
{
	xassert(verify_lock(NODE_LOCK, READ_LOCK));

	slurm_mutex_lock(&trigger_mutex);
	if (!trigger_draining_nodes_bitmap)
		trigger_draining_nodes_bitmap = bit_alloc(node_record_count);
	bit_set(trigger_draining_nodes_bitmap, node_ptr->index);
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_node_resume(node_record_t *node_ptr)
{
	xassert(verify_lock(NODE_LOCK, READ_LOCK));

	slurm_mutex_lock(&trigger_mutex);
	if (!trigger_resume_nodes_bitmap)
		trigger_resume_nodes_bitmap = bit_alloc(node_record_count);
	bit_set(trigger_resume_nodes_bitmap, node_ptr->index);
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_reconfig(void)
{
	slurmctld_lock_t node_read_lock = { .node = READ_LOCK };

	lock_slurmctld(node_read_lock);
	slurm_mutex_lock(&trigger_mutex);
	trigger_node_reconfig = true;
	slurm_mutex_unlock(&trigger_mutex);
	unlock_slurmctld(node_read_lock);
}

extern void trigger_primary_ctld_fail(void)
{
	slurm_mutex_lock(&trigger_mutex);
	if (ctld_failure != 1) {
		trigger_pri_ctld_fail = true;
		ctld_failure = 1;
	}
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_primary_ctld_res_op(void)
{
	slurm_mutex_lock(&trigger_mutex);
	trigger_pri_ctld_res_op = true;
	ctld_failure = 0;
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_primary_ctld_res_ctrl(void)
{
	slurm_mutex_lock(&trigger_mutex);
	trigger_pri_ctld_res_ctrl = true;
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_primary_ctld_acct_full(void)
{
	slurm_mutex_lock(&trigger_mutex);
	trigger_pri_ctld_acct_buffer_full = true;
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_backup_ctld_fail(int index)
{
	slurm_mutex_lock(&trigger_mutex);
	if (bu_ctld_failure != 1) {
		trigger_bu_ctld_fail = true;
		bu_ctld_failure = 1;
	}
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_backup_ctld_res_op(int index)
{
	slurm_mutex_lock(&trigger_mutex);
	trigger_bu_ctld_res_op = true;
	bu_ctld_failure = 0;
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_backup_ctld_as_ctrl(void)
{
	slurm_mutex_lock(&trigger_mutex);
	trigger_bu_ctld_as_ctrl = true;
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_primary_dbd_fail(void)
{
	slurm_mutex_lock(&trigger_mutex);
	if (dbd_failure != 1) {
		trigger_pri_dbd_fail = true;
		dbd_failure = 1;
	}
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_primary_dbd_res_op(void)
{
	slurm_mutex_lock(&trigger_mutex);
	trigger_pri_dbd_res_op = true;
	dbd_failure = 0;
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_primary_db_fail(void)
{
	slurm_mutex_lock(&trigger_mutex);
	if (db_failure != 1) {
		trigger_pri_db_fail = true;
		db_failure = 1;
	}
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_primary_db_res_op(void)
{
	slurm_mutex_lock(&trigger_mutex);
		trigger_pri_db_res_op = true;
		db_failure = 0;
	slurm_mutex_unlock(&trigger_mutex);
}

extern void trigger_burst_buffer(void)
{
	slurm_mutex_lock(&trigger_mutex);
	trigger_bb_error = true;
	slurm_mutex_unlock(&trigger_mutex);
}

static void _dump_trigger_state(trig_mgr_info_t *trig_ptr, buf_t *buffer)
{
	/* write trigger pull state flags */
	pack8(ctld_failure,    buffer);
	pack8(bu_ctld_failure, buffer);
	pack8(dbd_failure,     buffer);
	pack8(db_failure,      buffer);

	pack16   (trig_ptr->flags,     buffer);
	pack32   (trig_ptr->trig_id,   buffer);
	pack16   (trig_ptr->res_type,  buffer);
	packstr  (trig_ptr->orig_res_id, buffer);  /* restores res_id too */
	/* rebuild nodes_bitmap as needed from res_id */
	/* rebuild job_id as needed from res_id */
	pack32   (trig_ptr->trig_type, buffer);
	pack_time(trig_ptr->orig_time, buffer);    /* restores trig_time too */
	pack32   (trig_ptr->user_id,   buffer);
	pack32   (trig_ptr->group_id,  buffer);
	packstr  (trig_ptr->program,   buffer);
	pack8    (trig_ptr->state,     buffer);
}

static int _load_trigger_state(buf_t *buffer, uint16_t protocol_version)
{
	trig_mgr_info_t *trig_ptr;

	xassert(verify_lock(JOB_LOCK, READ_LOCK));

	trig_ptr = xmalloc(sizeof(trig_mgr_info_t));

	if (protocol_version >= SLURM_MIN_PROTOCOL_VERSION) {
		/* restore trigger pull state flags */
		safe_unpack8(&ctld_failure, buffer);
		safe_unpack8(&bu_ctld_failure, buffer);
		safe_unpack8(&dbd_failure, buffer);
		safe_unpack8(&db_failure, buffer);

		safe_unpack16   (&trig_ptr->flags,     buffer);
		safe_unpack32   (&trig_ptr->trig_id,   buffer);
		safe_unpack16   (&trig_ptr->res_type,  buffer);
		safe_unpackstr(&trig_ptr->res_id, buffer);
		/* rebuild nodes_bitmap as needed from res_id */
		/* rebuild job_id as needed from res_id */
		safe_unpack32   (&trig_ptr->trig_type, buffer);
		safe_unpack_time(&trig_ptr->trig_time, buffer);
		safe_unpack32   (&trig_ptr->user_id,   buffer);
		safe_unpack32   (&trig_ptr->group_id,  buffer);
		safe_unpackstr(&trig_ptr->program, buffer);
		safe_unpack8    (&trig_ptr->state,     buffer);
	} else {
		error("_load_trigger_state: protocol_version "
		      "%hu not supported", protocol_version);
		goto unpack_error;
	}

	if ((trig_ptr->res_type < TRIGGER_RES_TYPE_JOB)  ||
	    (trig_ptr->res_type > TRIGGER_RES_TYPE_OTHER) ||
	    (trig_ptr->state > 2))
		goto unpack_error;
	if (trig_ptr->res_type == TRIGGER_RES_TYPE_JOB) {
		job_record_t *job_ptr;
		trig_ptr->job_id = (uint32_t) atol(trig_ptr->res_id);
		job_ptr = find_job_record(trig_ptr->job_id);
		if (((trig_ptr->job_id == 0) || (job_ptr == NULL)) &&
		    (trig_ptr->state != 2))
			goto unpack_error;
	} else if (trig_ptr->res_type == TRIGGER_RES_TYPE_NODE) {
		trig_ptr->job_id = 0;
		if ((trig_ptr->res_id != NULL)   &&
		    (trig_ptr->res_id[0] != '*') &&
		    (node_name2bitmap(trig_ptr->res_id, false,
				      &trig_ptr->nodes_bitmap, NULL)))
			goto unpack_error;
	}
	if (trig_ptr->nodes_bitmap)
		trig_ptr->orig_bitmap = bit_copy(trig_ptr->nodes_bitmap);
	if (trig_ptr->res_id)
		trig_ptr->orig_res_id = xstrdup(trig_ptr->res_id);
	trig_ptr->orig_time = trig_ptr->trig_time;

	slurm_mutex_lock(&trigger_mutex);
	if (trigger_list == NULL)
		trigger_list = list_create(_trig_del);
	list_append(trigger_list, trig_ptr);
	next_trigger_id = MAX(next_trigger_id, trig_ptr->trig_id + 1);
	slurm_mutex_unlock(&trigger_mutex);

	return SLURM_SUCCESS;

unpack_error:
	error("Incomplete trigger record");
	xfree(trig_ptr->res_id);
	xfree(trig_ptr->program);
	FREE_NULL_BITMAP(trig_ptr->nodes_bitmap);
	xfree(trig_ptr);
	return SLURM_ERROR;
}

extern int trigger_state_save(void)
{
	/* Save high-water mark to avoid buffer growth with copies */
	static uint32_t high_buffer_size = (1024 * 1024);
	int error_code = 0;
	buf_t *buffer = init_buf(high_buffer_size);
	list_itr_t *trig_iter;
	trig_mgr_info_t *trig_in;

	/* write header: version, time */
	packstr(TRIGGER_STATE_VERSION, buffer);
	pack16(SLURM_PROTOCOL_VERSION, buffer);
	pack_time(time(NULL), buffer);

	/* write individual trigger records */
	slurm_mutex_lock(&trigger_mutex);
	if (trigger_list == NULL)
		trigger_list = list_create(_trig_del);

	trig_iter = list_iterator_create(trigger_list);
	while ((trig_in = list_next(trig_iter)))
		_dump_trigger_state(trig_in, buffer);
	list_iterator_destroy(trig_iter);
	slurm_mutex_unlock(&trigger_mutex);

	error_code = save_buf_to_state("trigger_state", buffer,
				       &high_buffer_size);

	FREE_NULL_BUFFER(buffer);
	return error_code;
}

extern void trigger_state_restore(void)
{
	uint16_t protocol_version = NO_VAL16;
	int trigger_cnt = 0;
	char *state_file;
	buf_t *buffer;
	time_t buf_time;
	char *ver_str = NULL;

	/* read the file */
	xassert(verify_lock(CONF_LOCK, READ_LOCK));

	if (!(buffer = state_save_open("trigger_state", &state_file))) {
		if ((clustername_existed == 1) && (!ignore_state_errors))
			fatal("No trigger state file (%s) to recover",
			      state_file);
		info("No trigger state file (%s) to recover", state_file);
		xfree(state_file);
		return;
	}
	xfree(state_file);

	safe_unpackstr(&ver_str, buffer);
	if (ver_str && !xstrcmp(ver_str, TRIGGER_STATE_VERSION))
		safe_unpack16(&protocol_version, buffer);

	if (protocol_version == NO_VAL16) {
		if (!ignore_state_errors)
			fatal("Can't recover trigger state, data version incompatible, start with '-i' to ignore this. Warning: using -i will lose the data that can't be recovered.");
		error("Can't recover trigger state, data version "
		      "incompatible");
		xfree(ver_str);
		FREE_NULL_BUFFER(buffer);
		return;
	}
	xfree(ver_str);

	safe_unpack_time(&buf_time, buffer);
	if (trigger_list)
		list_flush(trigger_list);
	while (remaining_buf(buffer) > 0) {
		if (_load_trigger_state(buffer, protocol_version) !=
		    SLURM_SUCCESS)
			goto unpack_error;
		trigger_cnt++;
	}
	goto fini;

unpack_error:
	if (!ignore_state_errors)
		fatal("Incomplete trigger data checkpoint file, start with '-i' to ignore this. Warning: using -i will lose the data that can't be recovered.");
	error("Incomplete trigger data checkpoint file");
fini:	verbose("State of %d triggers recovered", trigger_cnt);
	FREE_NULL_BUFFER(buffer);
}

/* Test if the event has been triggered, change trigger state as needed */
static void _trigger_job_event(trig_mgr_info_t *trig_in, time_t now)
{
	job_record_t *job_ptr;
	xassert(verify_lock(JOB_LOCK, READ_LOCK));

	job_ptr = find_job_record(trig_in->job_id);

	if ((trig_in->trig_type & TRIGGER_TYPE_FINI) &&
	    ((job_ptr == NULL) || (IS_JOB_COMPLETED(job_ptr)))) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		log_flag(TRIGGERS, "trigger[%u] event for job %u fini",
			 trig_in->trig_id, trig_in->job_id);
		return;
	}

	if (job_ptr == NULL) {
		log_flag(TRIGGERS, "trigger[%u] for defunct job %u",
			 trig_in->trig_id, trig_in->job_id);
		trig_in->state = 2;
		trig_in->trig_time = now;
		return;
	}

	if (!IS_JOB_PENDING(job_ptr) &&
	    (trig_in->trig_type & TRIGGER_TYPE_TIME)) {
		long rem_time = (job_ptr->end_time - now);
		if (rem_time <= (0x8000 - trig_in->trig_time)) {
			trig_in->state = 1;
			trig_in->trig_time = now;
			log_flag(TRIGGERS, "trigger[%u] for job %u time",
				 trig_in->trig_id, trig_in->job_id);
			return;
		}
	}

	if (trig_in->trig_type & TRIGGER_TYPE_DOWN) {
		if (trigger_down_nodes_bitmap &&
		    bit_overlap_any(job_ptr->node_bitmap,
				    trigger_down_nodes_bitmap)) {
			log_flag(TRIGGERS, "trigger[%u] for job %u down",
				 trig_in->trig_id, trig_in->job_id);
			trig_in->state = 1;
			trig_in->trig_time = now +
					    (trig_in->trig_time - 0x8000);
			return;
		}
	}

	if (trig_in->trig_type & TRIGGER_TYPE_FAIL) {
		if (trigger_fail_nodes_bitmap &&
		    bit_overlap_any(job_ptr->node_bitmap,
				    trigger_fail_nodes_bitmap)) {
			log_flag(TRIGGERS, "trigger[%u] for job %u node fail",
				 trig_in->trig_id, trig_in->job_id);
			trig_in->state = 1;
			trig_in->trig_time = now +
					     (trig_in->trig_time - 0x8000);
			return;
		}
	}

	if (trig_in->trig_type & TRIGGER_TYPE_UP) {
		if (trigger_up_nodes_bitmap &&
		    bit_overlap_any(job_ptr->node_bitmap,
				    trigger_up_nodes_bitmap)) {
			trig_in->state = 1;
			trig_in->trig_time = now +
					    (0x8000 - trig_in->trig_time);
			log_flag(TRIGGERS, "trigger[%u] for job %u up",
				 trig_in->trig_id, trig_in->job_id);
			return;
		}
	}
}

static void _trigger_other_event(trig_mgr_info_t *trig_in, time_t now)
{
	if ((trig_in->trig_type & TRIGGER_TYPE_BURST_BUFFER) &&
	    trigger_bb_error) {
		trig_in->state = 1;
		trig_in->trig_time = now;
		log_flag(TRIGGERS, "trigger[%u] for burst buffer",
			 trig_in->trig_id);
		return;
	}
}

static void _trigger_node_event(trig_mgr_info_t *trig_in, time_t now)
{
	xassert(verify_lock(NODE_LOCK, READ_LOCK));

	if ((trig_in->trig_type & TRIGGER_TYPE_DOWN) &&
	    trigger_down_nodes_bitmap                &&
	    (bit_ffs(trigger_down_nodes_bitmap) != -1)) {
		if (trig_in->nodes_bitmap == NULL) {	/* all nodes */
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trigger_down_nodes_bitmap);
			trig_in->state = 1;
		} else if (bit_overlap_any(trig_in->nodes_bitmap,
				           trigger_down_nodes_bitmap)) {
			bit_and(trig_in->nodes_bitmap,
				trigger_down_nodes_bitmap);
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					 trig_in->nodes_bitmap);
			trig_in->state = 1;
		}
		if (trig_in->state == 1) {
			trig_in->trig_time = now +
					     (trig_in->trig_time - 0x8000);
			log_flag(TRIGGERS, "trigger[%u] for node %s down",
				 trig_in->trig_id, trig_in->res_id);
			return;
		}
	}

	if ((trig_in->trig_type & TRIGGER_TYPE_DRAINED) &&
	    trigger_drained_nodes_bitmap                &&
	    (bit_ffs(trigger_drained_nodes_bitmap) != -1)) {
		if (trig_in->nodes_bitmap == NULL) {	/* all nodes */
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trigger_drained_nodes_bitmap);
			trig_in->state = 1;
		} else if (bit_overlap_any(trig_in->nodes_bitmap,
				           trigger_drained_nodes_bitmap)) {
			bit_and(trig_in->nodes_bitmap,
				trigger_drained_nodes_bitmap);
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trig_in->nodes_bitmap);
			trig_in->state = 1;
		}
		if (trig_in->state == 1) {
			trig_in->trig_time = now +
					     (trig_in->trig_time - 0x8000);
			log_flag(TRIGGERS, "trigger[%u] for node %s drained",
				 trig_in->trig_id, trig_in->res_id);
			return;
		}
	}

	if ((trig_in->trig_type & TRIGGER_TYPE_FAIL) &&
	    trigger_fail_nodes_bitmap                &&
	    (bit_ffs(trigger_fail_nodes_bitmap) != -1)) {
		if (trig_in->nodes_bitmap == NULL) {	/* all nodes */
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trigger_fail_nodes_bitmap);
			trig_in->state = 1;
		} else if (bit_overlap_any(trig_in->nodes_bitmap,
					   trigger_fail_nodes_bitmap)) {
			bit_and(trig_in->nodes_bitmap,
				trigger_fail_nodes_bitmap);
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trig_in->nodes_bitmap);
			trig_in->state = 1;
		}
		if (trig_in->state == 1) {
			trig_in->trig_time = now +
					     (trig_in->trig_time - 0x8000);
			log_flag(TRIGGERS, "trigger[%u] for node %s fail",
				 trig_in->trig_id, trig_in->res_id);
			return;
		}
	}

	if (trig_in->trig_type & TRIGGER_TYPE_IDLE) {
		/* We need to determine which (if any) of these
		 * nodes have been idle for at least the offset time */
		time_t min_idle = now - (trig_in->trig_time - 0x8000);
		int i;
		node_record_t *node_ptr;
		bitstr_t *trigger_idle_node_bitmap;

		trigger_idle_node_bitmap = bit_alloc(node_record_count);
		for (i = 0; (node_ptr = next_node(&i)); i++) {
			if (!IS_NODE_IDLE(node_ptr) ||
			    (node_ptr->last_busy > min_idle))
				continue;
			bit_set(trigger_idle_node_bitmap, node_ptr->index);
		}
		if (trig_in->nodes_bitmap == NULL) {    /* all nodes */
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trigger_idle_node_bitmap);
			trig_in->state = 1;
		} else if (bit_overlap_any(trig_in->nodes_bitmap,
					   trigger_idle_node_bitmap)) {
			bit_and(trig_in->nodes_bitmap,
				trigger_idle_node_bitmap);
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trig_in->nodes_bitmap);
			trig_in->state = 1;
		}
		FREE_NULL_BITMAP(trigger_idle_node_bitmap);
		if (trig_in->state == 1) {
			trig_in->trig_time = now;
			log_flag(TRIGGERS, "trigger[%u] for node %s idle",
				 trig_in->trig_id, trig_in->res_id);
			return;
		}
	}

	if ((trig_in->trig_type & TRIGGER_TYPE_UP) &&
	    trigger_up_nodes_bitmap                &&
	    (bit_ffs(trigger_up_nodes_bitmap) != -1)) {
		if (trig_in->nodes_bitmap == NULL) {	/* all nodes */
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trigger_up_nodes_bitmap);
			trig_in->state = 1;
		} else if (bit_overlap_any(trig_in->nodes_bitmap,
					   trigger_up_nodes_bitmap)) {
			bit_and(trig_in->nodes_bitmap,
				trigger_up_nodes_bitmap);
			xfree(trig_in->res_id);
			trig_in->res_id = bitmap2node_name(
					  trig_in->nodes_bitmap);
			trig_in->state = 1;
		}
		if (trig_in->state == 1) {
			trig_in->trig_time = now +
					     (trig_in->trig_time - 0x8000);
			log_flag(TRIGGERS, "trigger[%u] for node %s up",
				 trig_in->trig_id, trig_in->res_id);
			return;
		}
	}

	if ((trig_in->trig_type & TRIGGER_TYPE_DRAINING) &&
	    trigger_draining_nodes_bitmap &&
	    (bit_ffs(trigger_draining_nodes_bitmap) != -1)) {
		if (!trig_in->nodes_bitmap) { /* all nodes */
			xfree(trig_in->res_id);
			trig_in->res_id =
				bitmap2node_name(trigger_draining_nodes_bitmap);
			trig_in->state = 1;
		} else if (bit_overlap_any(trig_in->nodes_bitmap,
					   trigger_draining_nodes_bitmap)) {
			bit_and(trig_in->nodes_bitmap,
				trigger_draining_nodes_bitmap);
			xfree(trig_in->res_id);
			trig_in->res_id =
				bitmap2node_name(trig_in->nodes_bitmap);
			trig_in->state = 1;
		}
		if (trig_in->state == 1) {
			trig_in->trig_time =
				now + (trig_in->trig_time - 0x8000);
			log_flag(TRIGGERS, "trigger[%u] for node %s draining",
				 trig_in->trig_id, trig_in->res_id);
			return;
		}
	}

	if ((trig_in->trig_type & TRIGGER_TYPE_RESUME) &&
	    trigger_resume_nodes_bitmap &&
	    (bit_ffs(trigger_resume_nodes_bitmap) != -1)) {
		if (!trig_in->nodes_bitmap) { /* all nodes */
			xfree(trig_in->res_id);
			trig_in->res_id =
				bitmap2node_name(trigger_resume_nodes_bitmap);
			trig_in->state = 1;
		} else if (bit_overlap_any(trig_in->nodes_bitmap,
					   trigger_resume_nodes_bitmap)) {
			bit_and(trig_in->nodes_bitmap,
				trigger_resume_nodes_bitmap);
			xfree(trig_in->res_id);
			trig_in->res_id =
				bitmap2node_name(trig_in->nodes_bitmap);
			trig_in->state = 1;
		}
		if (trig_in->state == 1) {
			trig_in->trig_time =
				now + (trig_in->trig_time - 0x8000);
			log_flag(TRIGGERS, "trigger[%u] for node %s resume",
				 trig_in->trig_id, trig_in->res_id);
			return;
		}
	}

	if ((trig_in->trig_type & TRIGGER_TYPE_RECONFIG) &&
	    trigger_node_reconfig) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("reconfig");
		log_flag(TRIGGERS, "trigger[%u] for reconfig",
			 trig_in->trig_id);
		return;
	}
}

static void _trigger_slurmctld_event(trig_mgr_info_t *trig_in, time_t now)
{
	if ((trig_in->trig_type & TRIGGER_TYPE_PRI_CTLD_FAIL) &&
	    trigger_pri_ctld_fail) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("primary_slurmctld_failure");
		log_flag(TRIGGERS, "trigger[%u] for primary_slurmctld_failure",
			 trig_in->trig_id);
		return;
	}
	if ((trig_in->trig_type & TRIGGER_TYPE_PRI_CTLD_RES_OP) &&
	    trigger_pri_ctld_res_op) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id =
			xstrdup("primary_slurmctld_resumed_operation");
		log_flag(TRIGGERS, "trigger[%u] for primary_slurmctld_resumed_operation",
			 trig_in->trig_id);
		return;
	}
	if ((trig_in->trig_type & TRIGGER_TYPE_PRI_CTLD_RES_CTRL) &&
	    trigger_pri_ctld_res_ctrl) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("primary_slurmctld_resumed_control");
		log_flag(TRIGGERS, "trigger[%u] for primary_slurmctld_resumed_control",
			 trig_in->trig_id);
		return;
	}
	if ((trig_in->trig_type & TRIGGER_TYPE_PRI_CTLD_ACCT_FULL) &&
	    trigger_pri_ctld_acct_buffer_full) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("primary_slurmctld_acct_buffer_full");
		log_flag(TRIGGERS, "trigger[%u] for primary_slurmctld_acct_buffer_full",
			 trig_in->trig_id);
		return;
	}
	if ((trig_in->trig_type & TRIGGER_TYPE_BU_CTLD_FAIL) &&
	    trigger_bu_ctld_fail) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("backup_slurmctld_failure");
		log_flag(TRIGGERS, "trigger[%u] for backup_slurmctld_failure",
			 trig_in->trig_id);
		return;
	}
	if ((trig_in->trig_type & TRIGGER_TYPE_BU_CTLD_RES_OP) &&
	    trigger_bu_ctld_res_op) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("backup_slurmctld_resumed_operation");
		log_flag(TRIGGERS, "trigger[%u] for backup_slurmctld_resumed_operation",
			 trig_in->trig_id);
		return;
	}
	if ((trig_in->trig_type & TRIGGER_TYPE_BU_CTLD_AS_CTRL) &&
	    trigger_bu_ctld_as_ctrl) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("backup_slurmctld_assumed_control");
		log_flag(TRIGGERS, "trigger[%u] for bu_slurmctld_assumed_control",
			 trig_in->trig_id);
		return;
	}
}

static void _trigger_slurmdbd_event(trig_mgr_info_t *trig_in, time_t now)
{
	if ((trig_in->trig_type & TRIGGER_TYPE_PRI_DBD_FAIL) &&
	    trigger_pri_dbd_fail) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("primary_slurmdbd_failure");
		log_flag(TRIGGERS, "trigger[%u] for primary_slurmcdbd_failure",
			 trig_in->trig_id);
	}
	if ((trig_in->trig_type & TRIGGER_TYPE_PRI_DBD_RES_OP) &&
	    trigger_pri_dbd_res_op) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("primary_slurmdbd_resumed_operation");
		log_flag(TRIGGERS, "trigger[%u] for primary_slurmdbd_resumed_operation",
			 trig_in->trig_id);
		return;
	}
}

static void _trigger_database_event(trig_mgr_info_t *trig_in, time_t now)
{
	if ((trig_in->trig_type & TRIGGER_TYPE_PRI_DB_FAIL) &&
	    trigger_pri_db_fail) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("primary_database_failure");
		log_flag(TRIGGERS, "trigger[%u] for primary_database_failure",
			 trig_in->trig_id);
		return;
	}
	if ((trig_in->trig_type & TRIGGER_TYPE_PRI_DB_RES_OP) &&
	    trigger_pri_db_res_op) {
		trig_in->state = 1;
		trig_in->trig_time = now + (trig_in->trig_time - 0x8000);
		xfree(trig_in->res_id);
		trig_in->res_id = xstrdup("primary_database_resumed_operation");
		log_flag(TRIGGERS, "trigger[%u] for primary_database_resumed_operation",
			 trig_in->trig_id);
		return;
	}
}

/* Ideally we would use the existing proctrack plugin to prevent any
 * processes from escaping our control, but that plugin is tied
 * to various slurmd data structures. We just the process group ID
 * to kill the spawned program after MAX_PROG_TIME. Since triggers are
 * meant primarily for system administrators rather than users, this
 * may be sufficient. */
static void _trigger_run_program(trig_mgr_info_t *trig_in)
{
	char *tmp, *save_ptr = NULL, *tok;
	char *program, *args[64];
	char *pname, *uname;
	uid_t uid;
	gid_t gid;
	pid_t child_pid;
	int i;

	if (!_validate_trigger(trig_in))
		return;

	tmp = xstrdup(trig_in->program);
	tok = strtok_r(trig_in->program, " ", &save_ptr);
	program = xstrdup(tok);
	pname = strrchr(program, '/');
	if (pname == NULL)
		pname = program;
	else
		pname++;
	args[0] = xstrdup(pname);
	for (i = 1; i < 63; i++) {
		tok = strtok_r(NULL, " ", &save_ptr);
		if (!tok) {
			args[i] = xstrdup(trig_in->res_id);
			break;
		}
		args[i] = xstrdup(tok);
	}
	for (i++; i < 64; i++)
		args[i] = NULL;
	xfree(tmp);

	uid = trig_in->user_id;
	gid = trig_in->group_id;
	uname = uid_to_string(uid);

	child_pid = fork();
	if (child_pid > 0) {
		trig_in->child_pid = child_pid;
	} else if (child_pid == 0) {
		bool run_as_self = (uid == slurm_conf.slurm_user_id);
		closeall(0);
		setpgid(0, 0);
		setsid();
		if ((initgroups(uname, gid) == -1) && !run_as_self) {
			error("trigger: initgroups: %m");
			exit(1);
		}
		if ((setgid(gid) == -1) && !run_as_self){
			error("trigger: setgid: %m");
			exit(1);
		}
		if ((setresuid(uid, uid, -1) == -1) && !run_as_self) {
			error("trigger: setresuid: %m");
			exit(1);
		}
		execv(program, args);
		exit(1);
	} else {
		error("fork: %m");
	}
	xfree(uname);
	xfree(program);
	for (i = 0; i < 64; i++)
		xfree(args[i]);
}

static void _clear_event_triggers(void)
{
	if (trigger_down_nodes_bitmap)
		bit_clear_all(trigger_down_nodes_bitmap);
	if (trigger_drained_nodes_bitmap)
		bit_clear_all(trigger_drained_nodes_bitmap);
	if (trigger_up_nodes_bitmap)
		bit_clear_all(trigger_up_nodes_bitmap);
	if (trigger_draining_nodes_bitmap)
		bit_clear_all(trigger_draining_nodes_bitmap);
	if (trigger_resume_nodes_bitmap)
		bit_clear_all(trigger_resume_nodes_bitmap);
	trigger_node_reconfig = false;
	trigger_bb_error = false;
	trigger_pri_ctld_fail = false;
	trigger_pri_ctld_res_op = false;
	trigger_pri_ctld_res_ctrl = false;
	trigger_pri_ctld_acct_buffer_full = false;
	trigger_bu_ctld_fail = false;
	trigger_bu_ctld_res_op = false;
	trigger_bu_ctld_as_ctrl = false;
	trigger_pri_dbd_fail = false;
	trigger_pri_dbd_res_op = false;
	trigger_pri_db_fail = false;
	trigger_pri_db_res_op = false;
}

/* Make a copy of a trigger and prepend it on our list */
static void _trigger_clone(trig_mgr_info_t *trig_in)
{
	trig_mgr_info_t *trig_add;

	trig_add = xmalloc(sizeof(trig_mgr_info_t));
	trig_add->flags     = trig_in->flags;
	trig_add->trig_id   = trig_in->trig_id;
	trig_add->res_type  = trig_in->res_type;
	if (trig_in->orig_res_id) {
		trig_add->res_id = xstrdup(trig_in->orig_res_id);
		trig_add->orig_res_id = xstrdup(trig_in->orig_res_id);
	}
	if (trig_in->orig_bitmap) {
		trig_add->nodes_bitmap = bit_copy(trig_in->orig_bitmap);
		trig_add->orig_bitmap  = bit_copy(trig_in->orig_bitmap);
	}
	trig_add->job_id    = trig_in->job_id;
	trig_add->trig_type = trig_in->trig_type;
	trig_add->trig_time = trig_in->orig_time;
	trig_add->orig_time = trig_in->orig_time;
	trig_add->user_id   = trig_in->user_id;
	trig_add->group_id  = trig_in->group_id;
	trig_add->program   = xstrdup(trig_in->program);;
	list_prepend(trigger_list, trig_add);
}

extern void trigger_process(void)
{
	list_itr_t *trig_iter;
	trig_mgr_info_t *trig_in;
	time_t now = time(NULL);
	bool state_change = false;
	pid_t rc;
	int prog_stat;

	slurm_mutex_lock(&trigger_mutex);
	if (trigger_list == NULL)
		trigger_list = list_create(_trig_del);

	trig_iter = list_iterator_create(trigger_list);
	while ((trig_in = list_next(trig_iter))) {
		if (trig_in->state == 0) {
			if (trig_in->res_type == TRIGGER_RES_TYPE_OTHER)
				_trigger_other_event(trig_in, now);
			else if (trig_in->res_type == TRIGGER_RES_TYPE_JOB)
				_trigger_job_event(trig_in, now);
			else if (trig_in->res_type == TRIGGER_RES_TYPE_NODE)
				_trigger_node_event(trig_in, now);
			else if (trig_in->res_type ==
				 TRIGGER_RES_TYPE_SLURMCTLD)
				_trigger_slurmctld_event(trig_in, now);
			else if (trig_in->res_type ==
				 TRIGGER_RES_TYPE_SLURMDBD)
				_trigger_slurmdbd_event(trig_in, now);
			else if (trig_in->res_type ==
				 TRIGGER_RES_TYPE_DATABASE)
			 	_trigger_database_event(trig_in, now);
		}
		if ((trig_in->state == 1) &&
		    (trig_in->trig_time <= now)) {
			log_flag(TRIGGERS, "launching program for trigger[%u]: uid=%u gid=%u program=%s arg=%s",
				 trig_in->trig_id, trig_in->user_id,
				 trig_in->group_id, trig_in->program,
				 trig_in->res_id);
			if (trig_in->flags & TRIGGER_FLAG_PERM) {
				_trigger_clone(trig_in);
			}
			trig_in->state = 2;
			trig_in->trig_time = now;
			state_change = true;
			_trigger_run_program(trig_in);
		} else if ((trig_in->state == 2) &&
			   (difftime(now, trig_in->trig_time) >
			    MAX_PROG_TIME)) {
			if (trig_in->child_pid != 0) {
				killpg(trig_in->child_pid, SIGKILL);
				rc = waitpid(trig_in->child_pid, &prog_stat,
					     WNOHANG);
				if ((rc > 0) && prog_stat) {
					info("trigger uid=%u type=%s:%s "
					     "exit=%u:%u",
					     trig_in->user_id,
					     trigger_res_type(trig_in->res_type),
					     trigger_type(trig_in->trig_type),
					     WIFEXITED(prog_stat),
					     WTERMSIG(prog_stat));
				}
				if ((rc == trig_in->child_pid) ||
				    ((rc == -1) && (errno == ECHILD)))
					trig_in->child_pid = 0;
			}

			if (trig_in->child_pid == 0) {
				log_flag(TRIGGERS, "purging trigger[%u]",
					 trig_in->trig_id);
				list_delete_item(trig_iter);
				state_change = true;
			}
		} else if (trig_in->state == 2) {
			/* Eliminate zombie processes right away.
			 * Purge trigger entry above MAX_PROG_TIME later */
			rc = waitpid(trig_in->child_pid, &prog_stat, WNOHANG);
			if ((rc > 0) && prog_stat) {
				info("trigger uid=%u type=%s:%s exit=%u:%u",
				     trig_in->user_id,
				     trigger_res_type(trig_in->res_type),
				     trigger_type(trig_in->trig_type),
				     WIFEXITED(prog_stat),
				     WTERMSIG(prog_stat));
			}
			if ((rc == trig_in->child_pid) ||
			    ((rc == -1) && (errno == ECHILD)))
				trig_in->child_pid = 0;
		}
	}
	list_iterator_destroy(trig_iter);
	_clear_event_triggers();
	slurm_mutex_unlock(&trigger_mutex);
	if (state_change)
		schedule_trigger_save();
}

/* Free all allocated memory */
extern void trigger_fini(void)
{
	FREE_NULL_LIST(trigger_list);
	FREE_NULL_BITMAP(trigger_down_nodes_bitmap);
	FREE_NULL_BITMAP(trigger_drained_nodes_bitmap);
	FREE_NULL_BITMAP(trigger_fail_nodes_bitmap);
	FREE_NULL_BITMAP(trigger_up_nodes_bitmap);
	FREE_NULL_BITMAP(trigger_draining_nodes_bitmap);
	FREE_NULL_BITMAP(trigger_resume_nodes_bitmap);
}
