/*****************************************************************************\
 *  slurm.h - Definitions for all of the SLURM RPCs
 *****************************************************************************
 *  Copyright (C) 2002-2006 The Regents of the University of California.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Morris Jette <jette1@llnl.gov>, 
 *	Joey Ekstrom <ekstrom1@llnl.gov> et. al.
 *  UCRL-CODE-217948.
 *  
 *  This file is part of SLURM, a resource management program.
 *  For details, see <http://www.llnl.gov/linux/slurm/>.
 *  
 *  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.
 *  
 *  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.,
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
\*****************************************************************************/

#ifndef _SLURM_H
#define _SLURM_H

/* BEGIN_C_DECLS should be used at the beginning of your declarations,
   so that C++ compilers don't mangle their names.  Use _END_C_DECLS at
   the end of C declarations. */
#undef BEGIN_C_DECLS
#undef END_C_DECLS
#ifdef __cplusplus
# define BEGIN_C_DECLS	extern "C" {
# define END_C_DECLS	}
#else
# define BEGIN_C_DECLS	/* empty */
# define END_C_DECLS	/* empty */
#endif

/* PARAMS is a macro used to wrap function prototypes, so that compilers
   that don't understand ANSI C prototypes still work, and ANSI C
   compilers can issue warnings about type mismatches.  */
#undef PARAMS
#if defined (__STDC__) || defined (_AIX) \
	|| (defined (__mips) && defined (_SYSTYPE_SVR4)) \
	|| defined(WIN32) || defined(__cplusplus)
# define PARAMS(protos)	protos
#else
# define PARAMS(protos)	()
#endif

/* Define to 1 if you have Blue Gene system support. */
#undef HAVE_BG

/* Define to 1 if you have the `elan3' library (-lelan3). */
#undef HAVE_ELAN

/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H

BEGIN_C_DECLS

#include <slurm/slurm_errno.h>

#if HAVE_STDINT_H
#  include <stdint.h>		/* for uint16_t, uint32_t definitions */
#endif
#if HAVE_INTTYPES_H
#  include <inttypes.h>		/* for uint16_t, uint32_t definitions */
#endif
#include <stdio.h>		/* for FILE definitions */
#include <time.h>		/* for time_t definitions */
#include <stdbool.h>

/* Define slurm_addr below to avoid including extraneous slurm headers */
#ifdef	HAVE_SYS_SOCKET_H
#  ifndef __slurm_addr_defined
#    include <netinet/in.h>
#    define  __slurm_addr_defined
     typedef struct sockaddr_in slurm_addr ;
#  endif
#endif

#ifndef __slurm_cred_t_defined
#  define __slurm_cred_t_defined
   typedef struct slurm_job_credential * slurm_cred_t;
#endif

/* Define switch_jobinfo_t below to avoid including extraneous slurm headers */
#ifndef __switch_jobinfo_t_defined
#  define  __switch_jobinfo_t_defined
   typedef struct switch_jobinfo *switch_jobinfo_t;	/* opaque data type */
#endif

/* Define select_jobinfo_t below to avoid including extraneous slurm headers */
#ifndef __select_jobinfo_t_defined
#  define  __select_jobinfo_t_defined
   typedef struct select_jobinfo *select_jobinfo_t;     /* opaque data type */
#endif

/* Define jobacctinfo_t below to avoid including extraneous slurm headers */
#ifndef __jobacctinfo_t_defined
#  define  __jobacctinfo_t_defined
   typedef struct jobacctinfo *jobacctinfo_t;     /* opaque data type */
#endif

/*****************************************************************************\
 *      DEFINITIONS FOR VERSION MANAGEMENT
\*****************************************************************************/

#define SLURM_VERSION_NUM(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#define SLURM_VERSION_MAJOR(a)   (((a) >> 16) & 0xff)
#define SLURM_VERSION_MINOR(a)   (((a) >>  8) & 0xff)
#define SLURM_VERSION_MICRO(a)    ((a)        & 0xff)

/* Define the API's version. Update in META as needed. 
 * Also defined in config.h. 
 * High-order byte is major version. Update when existing APIs change.
 * Middle byte     is minor version. Update when new functions are added.
 * Low-order byte  is micro version. Update on patches and bug fixes. */
#ifndef SLURM_API_VERSION
#undef SLURM_API_VERSION
#endif

/*****************************************************************************\
 *	DEFINITIONS FOR INPUT VALUES
\*****************************************************************************/

/* INFINITE is used to identify unlimited configurations,  */
/* eg. the maximum count of nodes any job may use in some partition */
#define	INFINITE (0xffffffff)
#define NO_VAL	 (0xfffffffe)
#define MAX_TASKS_PER_NODE 64

/* Job step ID of batch scripts */
#define SLURM_BATCH_SCRIPT (0xfffffffe)

/* last entry must be JOB_END, keep in sync with job_state_string and 
 *	job_state_string_compact, if a job is in the process of de-
 *	allocating nodes, its final state is ORed with JOB_COMPLETING */
enum job_states {
	JOB_PENDING,		/* queued waiting for initiation */
	JOB_RUNNING,		/* allocated resources and executing */
	JOB_SUSPENDED,		/* allocated resources, execution suspended */
	JOB_COMPLETE,		/* completed execution successfully */
	JOB_CANCELLED,		/* cancelled by user */
	JOB_FAILED,		/* completed execution unsuccessfully */
	JOB_TIMEOUT,		/* terminated on reaching time limit */
	JOB_NODE_FAIL,		/* terminated on node failure */
	JOB_END			/* not a real state, last entry in table */
};
#define JOB_COMPLETING (0x8000)

#define MAIL_JOB_BEGIN 0x0001	/* notify when job begins */
#define MAIL_JOB_END   0x0002	/* notify when job ends */
#define MAIL_JOB_FAIL  0x0004	/* notify if job fails */

#define NICE_OFFSET 10000	/* offset for job's nice value */

/* Reason for job to be pending rather than executing. If multiple reasons 
 * exists, only one is given for the sake of system efficiency */
enum job_wait_reason {
	WAIT_NO_REASON = 0,	/* not set or job not pending */
	WAIT_PRIORITY,		/* higher priority jobs exist */
	WAIT_DEPENDENCY,	/* depedent job has not completed */
	WAIT_RESOURCES,		/* required resources not available */
	WAIT_PART_NODE_LIMIT,	/* request exceeds partition node limit */
	WAIT_PART_TIME_LIMIT,	/* request exceeds partition time limit */
	WAIT_PART_STATE,	/* requested partition is down */
	WAIT_HELD,		/* job is held, priority==0 */
	WAIT_TIME		/* job waiting for specific begin time */
};

enum job_acct_types {
	JOB_START,
	JOB_STEP,
	JOB_SUSPEND,
	JOB_TERMINATED
};

#ifdef HAVE_BG
#  define SYSTEM_DIMENSIONS 3	/* for job geometry */
#else
#  define SYSTEM_DIMENSIONS 0	/* for job geometry */
#endif

enum connection_type {
	SELECT_MESH, 		/* nodes wired in mesh */
	SELECT_TORUS, 		/* nodes wired in torus */
	SELECT_NAV,		/* nodes wired in torus else mesh */
	SELECT_SMALL 		/* nodes in a small partition */
};

enum node_use_type {
	SELECT_COPROCESSOR_MODE,/* use extra processor for communications */
	SELECT_VIRTUAL_NODE_MODE,/* application uses both processors */
	SELECT_NAV_MODE		/* either mode is acceptable */
};

enum select_data_type {
	SELECT_DATA_START,	/* data-> uint16_t start[SYSTEM_DIMENSIONS] */
	SELECT_DATA_GEOMETRY,	/* data-> uint16_t geometry[SYSTEM_DIMENSIONS] */
	SELECT_DATA_ROTATE,	/* data-> uint16_t rotate */
	SELECT_DATA_NODE_USE,	/* data-> uint16_t node_use */
	SELECT_DATA_CONN_TYPE,	/* data-> uint16_t connection_type */
	SELECT_DATA_BLOCK_ID,	/* data-> char bg_block_id */
	SELECT_DATA_QUARTER,	/* data-> uint16_t quarter */
	SELECT_DATA_NODECARD,	/* data-> uint16_t nodecard */
	SELECT_DATA_NODE_CNT,	/* data-> uint32_t node_cnt */
	SELECT_DATA_ALTERED,    /* data-> uint16_t altered */
	SELECT_DATA_MAX_PROCS	/* data-> uint32_t max_procs */
};

enum select_print_mode {
	SELECT_PRINT_HEAD,	/* Print just the header */
	SELECT_PRINT_DATA,	/* Print just the data */
	SELECT_PRINT_MIXED,	/* Print "field=value" */
	SELECT_PRINT_BG_ID	/* Print just the BG_ID */
};

enum select_node_cnt {
	SELECT_GET_NODE_SCALING,      /* Give scaling factor for node count */ 
	SELECT_APPLY_NODE_MIN_OFFSET, /* Apply min offset to variable */
	SELECT_APPLY_NODE_MAX_OFFSET, /* Apply max offset to variable */
	SELECT_SET_NODE_CNT	      /* Set altered node cnt */
};

/* jobacct data types */
enum jobacct_data_type {
	JOBACCT_DATA_TOTAL,	/* data-> jobacctinfo_t */
	JOBACCT_DATA_PIPE,      /* data-> file descriptor */
	JOBACCT_DATA_RUSAGE,	/* data-> struct rusage */
	JOBACCT_DATA_MAX_VSIZE,	/* data-> uint32_t vsize */
	JOBACCT_DATA_MAX_VSIZE_ID,	/* data-> jobacct_id_t vsize */
	JOBACCT_DATA_TOT_VSIZE,	/* data-> uint32_t vsize */
	JOBACCT_DATA_MAX_RSS,	/* data-> uint32_t psize */
	JOBACCT_DATA_MAX_RSS_ID,	/* data-> jobacct_id_t psize */
	JOBACCT_DATA_TOT_RSS,	/* data-> uint32_t psize */
	JOBACCT_DATA_MAX_PAGES,	/* data-> uint32_t psize */
	JOBACCT_DATA_MAX_PAGES_ID,	/* data-> jobacct_id_t psize */
	JOBACCT_DATA_TOT_PAGES,	/* data-> uint32_t psize */
	JOBACCT_DATA_MIN_CPU,	/* data-> uint32_t psize */
	JOBACCT_DATA_MIN_CPU_ID,	/* data-> jobacct_id_t psize */
	JOBACCT_DATA_TOT_CPU	/* data-> uint32_t psize */
};

/* Possible task distributions across the nodes */
enum task_dist_states {
	SLURM_DIST_CYCLIC,	/* distribute tasks 1 per node, round robin */
	SLURM_DIST_BLOCK,	/* distribute tasks filling node by node */
	SLURM_DIST_ARBITRARY	/* arbitrary task distribution  */
};

typedef enum cpu_bind_type {	/* cpu binding type from --cpu_bind=... */
	CPU_BIND_VERBOSE= 0x01,	/* =v, */
	CPU_BIND_NONE	= 0x02,	/* =no */
	CPU_BIND_RANK  	= 0x04,	/* =rank */
	CPU_BIND_MAPCPU	= 0x08,	/* =map_cpu:<list of CPU IDs> */
	CPU_BIND_MASKCPU= 0x10	/* =mask_cpu:<list of CPU masks> */
} cpu_bind_type_t;

typedef enum mem_bind_type {    /* memory binding type from --mem_bind=... */
	MEM_BIND_VERBOSE= 0x01,	/* =v, */
	MEM_BIND_NONE   = 0x02,	/* =no */
	MEM_BIND_RANK   = 0x04,	/* =rank */
	MEM_BIND_MAPCPU = 0x08,	/* =map_mem:<list of CPU IDs> */
	MEM_BIND_MASKCPU= 0x10,	/* =mask_mem:<list of CPU masks> */
	MEM_BIND_LOCAL  = 0x20	/* =local */
} mem_bind_type_t;

/* The last entry in node_states must be STATE_END, keep in sync with 
 * node_state_string. values may be ORed with NODE_STATE_FLAGS below. 
 * Node states typically alternate between NODE_STATE_IDLE and 
 * NODE_STATE_ALLOCATED. The NODE_STATE_COMPLETING flag will be set 
 * when jobs are in the process of terminating. */
enum node_states {
	NODE_STATE_UNKNOWN,	/* node's initial state, unknown */
	NODE_STATE_DOWN,	/* node in non-usable state */
	NODE_STATE_IDLE,	/* node idle and available for use */
	NODE_STATE_ALLOCATED,	/* node has been allocated to a job */
	NODE_STATE_END		/* last entry in table */
};
#define NODE_STATE_BASE       0x00ff
#define NODE_STATE_FLAGS      0xff00
#define NODE_RESUME           0x0100	/* Restore a DRAINED, DRAINING, or 
					 * DOWN node to service (e.g. IDLE or 
					 * ALLOCATED). Used in 
					 * slurm_update_node() request */
#define NODE_STATE_DRAIN      0x0200	/* node not be be allocated work */
#define NODE_STATE_COMPLETING 0x0400	/* node is completing allocated job */
#define NODE_STATE_NO_RESPOND 0x0800	/* node is not responding */

/* used to define the size of the credential.signature size
 * used to define the key size of the io_stream_header_t
 */
#define SLURM_SSL_SIGNATURE_LENGTH 128

/* Used as show_flags for slurm_get_ and slurm_load_ function calls.
 * Values can be can be ORed */
#define SHOW_ALL	1	/* Show info for "hidden" partitions */

/* Define keys for ctx_key argument of slurm_step_ctx_get() and
 * slurm_step_ctx_set() */
enum ctx_keys {
	SLURM_STEP_CTX_ARGS,	/* set argument count and values */
	SLURM_STEP_CTX_CHDIR,	/* set directory to run from */
	SLURM_STEP_CTX_ENV,	/* set environment variable count and values */
	SLURM_STEP_CTX_STEPID,	/* get the created job step id */
	SLURM_STEP_CTX_TASKS,	/* get array of task count on each node */
	SLURM_STEP_CTX_TID,	/* get array of task IDs for specified node */
	SLURM_STEP_CTX_RESP,	/* get job step create response message */
	SLURM_STEP_CTX_CRED,
	SLURM_STEP_CTX_SWITCH_JOB,
	SLURM_STEP_CTX_NUM_HOSTS,
	SLURM_STEP_CTX_HOST
};

/*****************************************************************************\
 *	PROTOCOL DATA STRUCTURE DEFINITIONS
\*****************************************************************************/

typedef struct job_descriptor {	/* For submit, allocate, and update requests */
	uint16_t contiguous;	/* 1 if job requires contiguous nodes,
				 * 0 otherwise,default=0 */
	uint16_t kill_on_node_fail; /* 1 if node failure to kill job, 
				 * 0 otherwise,default=1 */
	char **environment;	/* environment variables to set for job, 
				 *  name=value pairs, one per line */
	uint16_t env_size;	/* element count in environment */
	char *features;		/* comma separated list of required features, 
				 * default NONE */
	uint16_t immediate;	/* 1 if allocate to run or fail immediately, 
				 * 0 if to be queued awaiting resources */
	uint32_t job_id;	/* job ID, default set by SLURM */
	char *name;		/* name of the job, default "" */
	uint32_t min_procs;	/* minimum processors per node, default=0 */
	uint32_t min_memory;	/* minimum real memory per node, default=0 */
	uint32_t min_tmp_disk;	/* minimum temporary disk per node, 
				 * default=0 */
	char *partition;	/* name of requested partition, 
				 * default in SLURM config */
	uint32_t priority;	/* relative priority of the job,  
				 * explicitly set only for user root, 
				 * 0 == held (don't initiate) */
	char *req_nodes;	/* comma separated list of required nodes
				 * default NONE */
	char *exc_nodes;	/* comma separated list of nodes excluded
				 * from job's allocation, default NONE */
	uint16_t shared;	/* 1 if job can share nodes with other jobs,
				 * 0 otherwise */
	uint32_t time_limit;	/* maximum run time in minutes, default is
				 * partition limit */
	uint32_t num_procs;	/* total count of processors required, 
				 * default=0 */
	uint32_t min_nodes;	/* minimum number of nodes required by job, 
				 * default=0 */
	uint32_t max_nodes;	/* maximum number of nodes usable by job, 
				 * default=0 */
	uint16_t cpus_per_task;	/* number of processors required for each task */
	char *script;		/* the actual job script, default NONE */
	char **argv;		/* arguments to the script */
	uint16_t argc;		/* number of arguments to the script */
	char *err;		/* pathname of stderr */
	char *in;		/* pathname of stdin */
	char *out;		/* pathname of stdout */
	uint32_t user_id;	/* set only if different from current UID, 
				 * can only be explicitly set by user root */
	uint32_t group_id;	/* group to assume, if run as root. */ 
	char *work_dir;		/* pathname of working directory */
	char *alloc_node;	/* node making resource allocation request
				 * NOTE: Normally set by slurm_submit* or 
				 * slurm_allocate* function */
	uint32_t alloc_sid;	/* local sid making resource allocation request
				 * NOTE: Normally set by slurm_submit* or 
				 * slurm_allocate* function */

	/* If the requested allocation is not immediately available,
	 * The controller sends the RESPONSE_RESOURCE_ALLOCATION message to
	 * the address designated by the alloc_hostname and alloc_port.
	 * All other messages (SRUN_PING, SRUN_TIMEOUT, etc.) are sent to
	 * the address designated by other_hostname/other_port.
	 */
	char    *alloc_resp_hostname;
	uint16_t alloc_resp_port;
	char    *other_hostname;
	uint16_t other_port;

	uint32_t dependency;	/* defer until specified job completes */
	uint16_t overcommit;	/* over subscribe resources, for batch only */
	uint32_t num_tasks;	/* number of tasks to be started, for batch only */
	uint16_t nice;		/* requested priority change, 
				 * NICE_OFFSET == no change */
	char *account;		/* charge to specified account */
	char *network;		/* network use spec */
	uint16_t exclusive;	/* 1 if job requires exclusive nodes,
				 * 0 otherwise, default=0. Only useful
				 * when Consumable Resources are
				 * enabled */
	time_t begin_time;	/* delay initiation until this time */
	uint16_t mail_type;	/* see MAIL_JOB_ definitions above */
	char *mail_user;	/* user to receive notification */
	uint16_t no_requeue;	/* disable job requeue option */
/*
 * The following parameters are only meaningful on a Blue Gene
 * system at present. Some will be of value on other system. Don't remove these
 * they are needed for LCRM and others that can't talk to the opaque data type
 * select_jobinfo.
 */
#if SYSTEM_DIMENSIONS
	uint16_t geometry[SYSTEM_DIMENSIONS];	/* node count in various
				 * dimensions, e.g. X, Y, and Z */
#endif
	uint16_t conn_type;	/* see enum connection_type */
	uint16_t rotate;	/* permit geometry rotation if set */
/* End of Blue Gene specific values */

	select_jobinfo_t select_jobinfo; /* opaque data type,
			* SLURM internal use only */
} job_desc_msg_t;

typedef struct job_info {
	uint32_t job_id;	/* job ID */
	char *name;		/* name of the job */
	uint16_t batch_flag;	/* 1 if batch: queued job with script */
	uint32_t alloc_sid;	/* local sid making resource alloc */
	char    *alloc_node;	/* local node making resource alloc */
	uint32_t user_id;	/* user the job runs as */
	uint32_t group_id;	/* group job sumitted as */
	uint16_t job_state;	/* state of the job, see enum job_states */
	uint32_t time_limit;	/* maximum run time in minutes or INFINITE */
	time_t submit_time;	/* time of job submission */
	time_t start_time;	/* time execution begins, actual or expected */
	time_t end_time;	/* time of termination, actual or expected */
	time_t suspend_time;	/* time job last suspended or resumed */
	time_t pre_sus_time;	/* time job ran prior to last suspend */
	uint32_t priority;	/* relative priority of the job, 
				 * 0=held, 1=required nodes DOWN/DRAINED */
	char *nodes;		/* list of nodes allocated to job */
	int *node_inx;		/* list index pairs into node_table for *nodes:
				 * start_range_1, end_range_1, 
				 * start_range_2, .., -1  */
	char *partition;	/* name of assigned partition */
	uint32_t num_procs;	/* number of processors required by job */
	uint32_t num_nodes;	/* number of nodes required by job */
	uint16_t shared;	/* 1 if job can share nodes with other jobs */
	uint16_t contiguous;	/* 1 if job requires contiguous nodes */
	uint16_t cpus_per_task;	/* number of processors required for each task */
	uint32_t min_procs;	/* minimum processors required per node */
	uint32_t min_memory;	/* minimum real memory required per node */
	uint32_t min_tmp_disk;	/* minimum temporary disk required per node */
	char *req_nodes;	/* comma separated list of required nodes */
	int *req_node_inx;	/* required list index pairs into node_table: 
				 * start_range_1, end_range_1, 
				 * start_range_2, .., -1  */
	char *exc_nodes;	/* comma separated list of excluded nodes */
	int *exc_node_inx;	/* exclueded list index pairs into node_table: 
				 * start_range_1, end_range_1, 
				 * start_range_2, .., -1  */
	char *features;		/* comma separated list of required features */
	uint32_t dependency;	/* defer until specified job completes */
	char *account;		/* charge to specified account */
	uint16_t wait_reason;	/* reason job still pending, see
				 * slurm.h:enum job_wait_reason */
	char *network;		/* network specification */
	select_jobinfo_t select_jobinfo; /* opaque data type,
			* process using select_g_get_jobinfo() */
} job_info_t;

typedef struct job_info_msg {
	time_t last_update;	/* time of latest info */
	uint32_t record_count;	/* number of records */
	job_info_t *job_array;	/* the job records */
} job_info_msg_t;

typedef struct job_step_specs {
	uint32_t job_id;	/* job ID */
	uint32_t user_id;	/* user the job runs as */
	uint32_t node_count;	/* count of required nodes */
	uint32_t cpu_count;	/* count of required processors */
	uint32_t num_tasks;	/* number of tasks required */
	uint16_t relative;	/* first node to use of job's allocation */
	uint16_t task_dist;	/* see enum task_dist_state */
	uint16_t port;		/* port to contact initiating srun */
	char *host;		/* host to contact initiating srun */
	char *node_list;	/* list of required nodes */
	char *network;		/* network use spec */
	char *name;		/* name of the job step, default "" */
	uint8_t overcommit;     /* flag, 1 to allow overcommit of processors,
				   0 to disallow overcommit. */
} job_step_create_request_msg_t;

typedef struct slurm_step_layout {
	uint16_t node_cnt;	/* node count */
	uint32_t task_cnt;	/* total number of tasks in the step */
	char *node_list;        /* list of nodes in step */
	slurm_addr *node_addr;  /* corresponding addresses */
	
	/* Array of length "node_cnt". Each element of the array
	   is the number of tasks assigned to the corresponding node */
	uint32_t *tasks;

	/* Array (of length "node_cnt") of task ID arrays.  The length
	   of each subarray is designated by the corresponding value in
           the tasks array. */
	uint32_t **tids;	/* host id => task id mapping */
} slurm_step_layout_t;

typedef struct job_step_create_response_msg {
	uint32_t job_step_id;	/* assigned job step id */
	slurm_step_layout_t *step_layout; /* information about how the 
                                             step is laid out */
	slurm_cred_t cred;      /* slurm job credential */
	switch_jobinfo_t switch_job;	/* switch context, opaque 
                                           data structure */
} job_step_create_response_msg_t;

typedef struct slurm_step_io_fds {
	struct {
		int fd;
		uint32_t taskid;
		uint32_t nodeid;
	} in, out, err;
} slurm_step_io_fds_t;

#define SLURM_STEP_IO_FDS_INITIALIZER {{0, (uint32_t)-1, (uint32_t)-1},\
                                   {1, (uint32_t)-1, (uint32_t)-1},\
                                   {2, (uint32_t)-1, (uint32_t)-1}}

typedef struct launch_tasks_response_msg {
	uint32_t return_code;
	char    *node_name;
	uint32_t srun_node_id;
	uint32_t count_of_pids;
	uint32_t *local_pids;
	uint32_t *task_ids; /* array of lenght count_of_pids */
} launch_tasks_response_msg_t;

typedef struct task_ext_msg {
	uint32_t num_tasks;
	uint32_t *task_id_list;
	uint32_t return_code;
} task_exit_msg_t;

typedef struct {
	uint16_t argc;
	char **argv;
	uint16_t envc;
	char **env;
	char *cwd;
	bool buffered_stdio;
	bool labelio;
	char *remote_output_filename;
	char *remote_error_filename;
	char *remote_input_filename;
	slurm_step_io_fds_t local_fds;
	uint32_t gid;
	bool multi_prog;
	uint32_t slurmd_debug;  /* remote slurmd debug level */
	bool parallel_debug;
	void (*task_start_callback)(launch_tasks_response_msg_t *);
	void (*task_finish_callback)(task_exit_msg_t *);
} slurm_job_step_launch_t;

typedef struct {
	uint32_t job_id;	/* job ID */
	uint16_t step_id;	/* step ID */
	uint32_t user_id;	/* user the job runs as */
	uint32_t num_tasks;	/* number of tasks */
	time_t start_time;	/* step start time */
	char *partition;	/* name of assigned partition */
	char *nodes;		/* list of nodes allocated to job_step */
	char *name;		/* name of job step */
	char *network;		/* network specs for job step */
} job_step_info_t;

typedef struct job_step_info_response_msg {
	time_t last_update;		/* time of latest info */
	uint32_t job_step_count;	/* number of records */
	job_step_info_t *job_steps;	/* the job step records */
} job_step_info_response_msg_t;

typedef struct node_info {
	char *name;		/* node name */
	uint16_t node_state;	/* see enum node_states */
	uint32_t cpus;		/* configured count of cpus running on 
				 * the node */
	uint32_t real_memory;	/* configured MB of real memory on the node */
	uint32_t tmp_disk;	/* configured MB of total disk in TMP_FS */
	uint32_t weight;	/* arbitrary priority of node for scheduling */
	char *features;		/* arbitrary list of features for node */
	char *reason;   	/* reason for node being DOWN or DRAINING */
} node_info_t;

typedef struct node_info_msg {
	time_t last_update;		/* time of latest info */
	uint32_t record_count;		/* number of records */
	node_info_t *node_array;	/* the node records */
} node_info_msg_t;

typedef struct job_alloc_info_msg {
	uint32_t job_id;	/* job ID */
} job_alloc_info_msg_t;

typedef struct partition_info {
	char *name;		/* name of the partition */
	uint32_t max_time;	/* minutes or INFINITE */
	uint32_t max_nodes;	/* per job or INFINITE */
	uint32_t min_nodes;	/* per job */
	uint32_t total_nodes;	/* total number of nodes in the partition */
	uint32_t total_cpus;	/* total number of cpus in the partition */
	uint32_t node_scaling;	/* select plugin node scaling factor */
	uint16_t default_part;	/* 1 if this is default partition */
	uint16_t hidden;	/* 1 if partition is hidden by default */
	uint16_t root_only;	/* 1 if allocate must come for user root */
	uint16_t shared;	/* 1 if job can share nodes, 
				 * 2 if job must share nodes */
	uint16_t state_up;	/* 1 if state is up, 0 if down */
	char *nodes;		/* list names of nodes in partition */
	int *node_inx;		/* list index pairs into node_table:
				 * start_range_1, end_range_1, 
				 * start_range_2, .., -1  */
	char *allow_groups;	/* comma delimited list of groups, 
				 * null indicates all */
} partition_info_t;

typedef struct delete_partition_msg {
	char *name;		/* name of partition to be delete */
} delete_part_msg_t;

typedef struct resource_allocation_response_msg {
	uint32_t job_id;	/* assigned job id */
	char *node_list;	/* assigned list of nodes */
	uint16_t num_cpu_groups;/* elements in below cpu arrays */
	uint32_t *cpus_per_node;/* cpus per node */
	uint32_t *cpu_count_reps;/* how many nodes have same cpu count */
	uint16_t node_cnt;	/* count of nodes */
	uint32_t error_code;	/* error code for warning message */
	select_jobinfo_t select_jobinfo;	/* opaque data structure,
			* use select_g_get_jobinfo() to access conents */
} resource_allocation_response_msg_t;

typedef struct job_alloc_info_response_msg {
	uint32_t job_id;	/* assigned job id */
	char *node_list;	/* assigned list of nodes */
	uint16_t num_cpu_groups;/* elements in below cpu arrays */
	uint32_t *cpus_per_node;/* cpus per node */
	uint32_t *cpu_count_reps;/* how many nodes have same cpu count */
	uint16_t node_cnt;	/* count of nodes */
	slurm_addr *node_addr;	/* network addresses */
	uint32_t error_code;	/* error code for warning message */
	select_jobinfo_t select_jobinfo;	/* opaque data structure,
			* use select_g_get_jobinfo() to access conents */
} job_alloc_info_response_msg_t;

typedef struct partition_info_msg {
	time_t last_update;	/* time of latest info */
	uint32_t record_count;	/* number of records */
	partition_info_t *partition_array; /* the partition records */
} partition_info_msg_t;

typedef struct slurm_ctl_conf {
	time_t last_update;	/* last update time of the build parameters */
	char *authtype;		/* authentication type */
	char *backup_addr;	/* comm path of slurmctld secondary server */
	char *backup_controller;/* name of slurmctld secondary server */
	uint16_t cache_groups;	/* cache /etc/groups to avoid initgroups(2) */
	char *checkpoint_type;	/* checkpoint plugin type */
	char *control_addr;	/* comm path of slurmctld primary server */
	char *control_machine;	/* name of slurmctld primary server */
	char *epilog;		/* pathname of job epilog */
	uint32_t first_job_id;	/* first slurm generated job_id to assign */
	uint16_t fast_schedule;	/* 1 to *not* check configurations by node 
				 * (only check configuration file, faster) */
	uint16_t inactive_limit;/* seconds of inactivity before a
				 * inactive resource allocation is released */
	char *job_acct_logfile;	/* job accounting log location */
	uint16_t job_acct_freq; /* poll frequency for job accounting plugins */
	char *job_acct_type;	/* job accounting type */
	char *job_comp_type;	/* job completion logger type */
	char *job_comp_loc;	/* job completion logging location */
	uint16_t kill_wait;	/* seconds between SIGXCPU to SIGKILL 
				 * on job termination */
	uint16_t max_job_cnt;	/* maximum number of active jobs */
	uint16_t min_job_age;	/* COMPLETED jobs over this age (secs) 
	                         * purged from in memory records */
	char *mpi_default;	/* Default version of MPI in use */
	uint16_t msg_timeout;	/* message timeout */
	char *plugindir;	/* pathname to plugins */
	char *plugstack;        /* pathname to plugin stack config file */
	char *proctrack_type;	/* process tracking plugin type */
	char *prolog;		/* pathname of job prolog */
	uint16_t propagate_prio_process; /* 1 if process priority should
				          * be propagated */
        char *propagate_rlimits;/* Propagate (all/specific) resource limits */
        char *propagate_rlimits_except;/* Propagate all rlimits except these */
	uint16_t ret2service;	/* 1 return DOWN node to service at 
				 * registration */
	char *schedtype;	/* type of scheduler to use */
	char *schedauth;	/* credential for scheduler (if needed) */
	uint16_t schedport;	/* port for scheduler connection */
	uint16_t schedrootfltr;	/* 1 if rootOnly partitions should be
				 * filtered from scheduling (if needed) */
	char *select_type;	/* type of node selector to use */
	uint32_t slurm_user_id;	/* uid of slurm_user_name */
	char *slurm_user_name;	/* user that slurmctld runs as */
	uint16_t slurmctld_debug; /* slurmctld logging level */
	char *slurmctld_logfile;/* where slurmctld error log gets written */
	char *slurmctld_pidfile;/* where to put slurmctld pidfile         */
	uint32_t slurmctld_port;/* default communications port to slurmctld */
	uint16_t slurmctld_timeout;/* seconds that backup controller waits 
				 * on non-responding primarly controller */
	uint16_t slurmd_debug;	/* slurmd logging level */
	char *slurmd_logfile;	/* where slurmd error log gets written */
	uint32_t slurmd_port;	/* default communications port to slurmd */
	char *slurmd_spooldir;	/* where slurmd put temporary state info */
	char *slurmd_pidfile;   /* where to put slurmd pidfile           */
	uint16_t slurmd_timeout;/* how long slurmctld waits for slurmd before 
				 * considering node DOWN */
	char *slurm_conf;	/* pathname of slurm config file */
	char *state_save_location;/* pathname of slurmctld state save
				 * directory */
	char *switch_type;	/* switch or interconnect type */
	char *task_epilog;	/* pathname of task launch epilog */
	char *task_plugin;	/* task launch plugin */
	char *task_prolog;	/* pathname of task launch prolog */
	char *tmp_fs;		/* pathname of temporary file system */
	uint16_t wait_time;	/* default job --wait time */
	char *job_credential_private_key;	/* path to private key */
	char *job_credential_public_certificate;/* path to public certificate*/
	char *srun_prolog;      /* srun prolog program */
	char *srun_epilog;      /* srun epilog program */
	char *node_prefix;      /* prefix of nodes in partition only set in 
				   bluegene clusters NULL otherwise */
	uint16_t tree_width;    /* number of threads per node to span */
	uint16_t use_pam;	/* enable/disable PAM support */
} slurm_ctl_conf_t;

typedef struct submit_response_msg {
	uint32_t job_id;	/* job ID */
	uint32_t step_id;	/* step ID */
	uint32_t error_code;	/* error code for warning message */
} submit_response_msg_t;

typedef struct slurm_update_node_msg {
	char *node_names;	/* comma separated list of required nodes */
	uint16_t node_state;	/* see enum node_states */
	char *reason;   	/* reason for node being DOWN or DRAINING */
} update_node_msg_t;

typedef struct partition_info update_part_msg_t;

/* Opaque data type for slurm_step_ctx_*, slurm_step_launch, slurm_spawn, and
 * slurm_spawn_kill functions */
typedef struct slurm_step_ctx_struct *slurm_step_ctx;


/*****************************************************************************\
 *	RESOURCE ALLOCATION FUNCTIONS
\*****************************************************************************/

/*
 * slurm_init_job_desc_msg - initialize job descriptor with 
 *	default values 
 * OUT job_desc_msg - user defined job descriptor
 */
extern void slurm_init_job_desc_msg PARAMS((job_desc_msg_t * job_desc_msg));

/*
 * slurm_allocate_resources - allocate resources for a job request
 *   If the requested resources are not immediately available, the slurmctld
 *   will send the job_alloc_resp_msg to the sepecified node and port.
 * IN job_desc_msg - description of resource allocation request
 * OUT job_alloc_resp_msg - response to request.  This only represents
 *   a job allocation if resources are immediately.  Otherwise it just contains
 *   the job id of the enqueued job request.
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 * NOTE: free the allocated using slurm_free_resource_allocation_response_msg
 */
extern int slurm_allocate_resources PARAMS((
	job_desc_msg_t * job_desc_msg , 
	resource_allocation_response_msg_t ** job_alloc_resp_msg));

/*
 * slurm_allocate_resources_blocking
 *	allocate resources for a job request.  This call will block until
 *	the allocation is granted, or the specified timeout limit is reached.
 * IN req - description of resource allocation request
 * IN timeout - amount of time to wait for a response before giving up.
 *	A timeout of zero will wait indefinitely.
 * 
 * RET allocation structure on success, NULL on error set errno to
 *	indicate the error (errno will be ETIMEDOUT if the timeout is reached
 *      with no allocation granted)
 * NOTE: free the allocation structure using
 *	slurm_free_resource_allocation_response_msg
 */
extern resource_allocation_response_msg_t *
	slurm_allocate_resources_blocking PARAMS((
	const job_desc_msg_t *user_req, time_t timeout));

/*
 * slurm_free_resource_allocation_response_msg - free slurm resource
 *	allocation response message
 * IN msg - pointer to allocation response message
 * NOTE: buffer is loaded by slurm_allocate_resources
 */
extern void slurm_free_resource_allocation_response_msg PARAMS((
	resource_allocation_response_msg_t * msg));

/*
 * slurm_free_job_alloc_info_response_msg - free slurm resource
 *	allocation lookup message
 * IN msg - pointer to job allocation info response message
 * NOTE: buffer is loaded by slurm_allocation_lookup
 */
extern void slurm_free_job_alloc_info_response_msg PARAMS((
	job_alloc_info_response_msg_t * msg));

/*
 * slurm_allocation_lookup - retrieve info for an existing resource allocation
 * IN job_id - job allocation identifier
 * OUT resp - job allocation information
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 * NOTE: free "info" using slurm_free_job_alloc_info_response_msg
 */
extern int slurm_allocation_lookup PARAMS((
	uint32_t job_id, job_alloc_info_response_msg_t **info));
/*
 * slurm_allocation_lookup_lite - retrieve minor info for an existing 
 *				  resource allocation
 * IN job_id - job allocation identifier
 * OUT resp - job allocation information
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 * NOTE: free "info" using slurm_free_job_alloc_info_response_msg
 */
extern int slurm_allocation_lookup_lite PARAMS((
	uint32_t job_id, resource_allocation_response_msg_t **info));

/*
 * slurm_job_step_create - create a job step for a given job id
 * IN slurm_step_alloc_req_msg - description of job step request
 * OUT slurm_step_alloc_resp_msg - response to request
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 * NOTE: free the response using slurm_free_job_step_create_response_msg
 */
extern int slurm_job_step_create PARAMS((
	job_step_create_request_msg_t * slurm_step_alloc_req_msg, 
	job_step_create_response_msg_t ** slurm_step_alloc_resp_msg));

/*
 * slurm_read_hostfile - Read a SLURM hostfile specified by "filename".
 *	"filename" must contain a list of SLURM NodeNames, one per line.
 *	Reads up to "n" number of hostnames from the file. Returns a
 *	string representing a hostlist ranged string of the contents of
 *	the file.  This is a helper function, it does not contact any
 *	SLURM daemons.
 *
 * IN filename - name of SLURM Hostlist file to be read.
 * IN n - number of NodeNames required
 * RET - a string representing the hostlist.  Returns NULL if there are
 *	fewer than "n" hostnames in the file, or if an error occurs.
 *
 * NOTE: Returned string must be freed with free().
 */
extern char *slurm_read_hostfile PARAMS((char *filename, int n));

/*
 * slurm_free_job_step_create_response_msg - free slurm 
 *	job step create response message
 * IN msg - pointer to job step create response message
 * NOTE: buffer is loaded by slurm_job_step_create
 */
extern void slurm_free_job_step_create_response_msg PARAMS((
	job_step_create_response_msg_t *msg));

/*
 * slurm_submit_batch_job - issue RPC to submit a job for later execution
 * NOTE: free the response using slurm_free_submit_response_response_msg
 * IN job_desc_msg - description of batch job request
 * OUT slurm_alloc_msg - response to request
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_submit_batch_job PARAMS((
	job_desc_msg_t * job_desc_msg, 
	submit_response_msg_t ** slurm_alloc_msg));

/*
 * slurm_free_submit_response_response_msg - free slurm 
 *	job submit response message
 * IN msg - pointer to job submit response message
 * NOTE: buffer is loaded by slurm_submit_batch_job
 */
extern void slurm_free_submit_response_response_msg PARAMS((
		submit_response_msg_t *msg));

/*
 * slurm_job_will_run - determine if a job would execute immediately if 
 *	submitted now
 * IN job_desc_msg - description of resource allocation request
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_job_will_run PARAMS((
	job_desc_msg_t * job_desc_msg));


/*****************************************************************************\
 *	JOB/STEP SIGNALING FUNCTIONS
\*****************************************************************************/

/*
 * slurm_kill_job - send the specified signal to all steps of an existing job
 * IN job_id     - the job's id
 * IN signal     - signal number
 * IN batch_flag - 1 to signal batch shell only, otherwise 0
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_kill_job PARAMS((uint32_t job_id, uint16_t signal, 
			uint16_t batch_flag));

/*
 * slurm_kill_job_step - send the specified signal to an existing job step
 * IN job_id  - the job's id
 * IN step_id - the job step's id
 * IN signal  - signal number
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_kill_job_step PARAMS((uint32_t job_id, uint32_t step_id, 
				       uint16_t signal));

/*
 * slurm_signal_job - send the specified signal to all steps of an existing job
 * IN job_id     - the job's id
 * IN signal     - signal number
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_signal_job PARAMS((uint32_t job_id, uint16_t signal));

/*
 * slurm_signal_job_step - send the specified signal to an existing job step
 * IN job_id  - the job's id
 * IN step_id - the job step's id - use SLURM_BATCH_SCRIPT as the step_id
 *              to send a signal to a job's batch script
 * IN signal  - signal number
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_signal_job_step PARAMS((uint32_t job_id, uint32_t step_id,
					 uint16_t signal));


/*****************************************************************************\
 *	JOB/STEP COMPLETION FUNCTIONS
\*****************************************************************************/

/*
 * slurm_complete_job - note the completion of a job and all of its steps 
 * IN job_id - the job's id
 * IN job_return_code - the highest exit code of any task of the job
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_complete_job PARAMS((uint32_t job_id,
	uint32_t job_return_code));

/*
 * slurm_terminate_job - terminates all steps of an existing job by sending
 * 	a REQUEST_TERMINATE_JOB rpc to all slurmd in the the job allocation,
 *      and then calls slurm_complete_job().
 * IN job_id     - the job's id
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_terminate_job PARAMS((uint32_t job_id));

/*
 * slurm_terminate_job_step - terminates a job step by sending a
 * 	REQUEST_TERMINATE_TASKS rpc to all slurmd of a job step, and then
 *	calls slurm_complete_job_step() after verifying that all
 *	nodes in the job step no longer have running tasks from the job
 *	step.  (May take over 35 seconds to return.)
 * IN job_id  - the job's id
 * IN step_id - the job step's id - use SLURM_BATCH_SCRIPT as the step_id
 *              to terminate a job's batch script
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_terminate_job_step PARAMS((
	uint32_t job_id, uint32_t step_id));

/*****************************************************************************\
 *	SLURM TASK SPAWNING FUNCTIONS
\*****************************************************************************/

/*
 * slurm_step_ctx_create - Create a job step and its context. 
 * IN step_req - description of job step request
 * RET the step context or NULL on failure with slurm errno set
 * NOTE: Free allocated memory using slurm_step_ctx_destroy.
 */
extern slurm_step_ctx slurm_step_ctx_create PARAMS((
	job_step_create_request_msg_t *step_req));

/*
 * slurm_step_ctx_get - get parameters from a job step context.
 * IN ctx - job step context generated by slurm_step_ctx_create
 * RET SLURM_SUCCESS or SLURM_ERROR (with slurm_errno set)
 */
extern int slurm_step_ctx_get PARAMS((slurm_step_ctx ctx, 
	int ctx_key, ...));

/*
 * slurm_jobinfo_ctx_get - get parameters from jobinfo context.
 * IN jobinfo - job information from context, returned by slurm_step_ctx_get()
 * IN data_type - type of data required, specific to the switch type
 * OUT data - the requested data type
 * RET SLURM_SUCCESS or SLURM_ERROR (with slurm_errno set)
 */
extern int slurm_jobinfo_ctx_get PARAMS((switch_jobinfo_t jobinfo, 
	int data_type, void *data));

/*
 * slurm_step_ctx_set - set parameters in job step context.
 * IN ctx - job step context generated by slurm_step_ctx_create
 * RET SLURM_SUCCESS or SLURM_ERROR (with slurm_errno set)
 */
extern int slurm_step_ctx_set PARAMS((slurm_step_ctx ctx, 
	int ctx_key, ...));

/*
 * slurm_step_ctx_destroy - free allocated memory for a job step context.
 * IN ctx - job step context generated by slurm_step_ctx_create
 * RET SLURM_SUCCESS or SLURM_ERROR (with slurm_errno set)
 */
extern int slurm_step_ctx_destroy PARAMS((slurm_step_ctx ctx));


/*
 * slurm_spawn - spawn tasks for the given job step context
 * IN ctx - job step context generated by slurm_step_ctx_create
 * IN fd_array  - array of socket file descriptors to connect with 
 *	stdin, stdout, and stderr of spawned task
 * RET SLURM_SUCCESS or SLURM_ERROR (with slurm_errno set)
 */
extern int slurm_spawn PARAMS((slurm_step_ctx ctx, 
				       int *fd_array));

/*
 * slurm_spawn_kill - send the specified signal to an existing job step
 * IN ctx - job step context generated by slurm_step_ctx_create
 * IN signal  - signal number
 * RET SLURM_SUCCESS or SLURM_ERROR (with slurm_errno set)
 */
extern int slurm_spawn_kill PARAMS((slurm_step_ctx ctx, 
				       uint16_t signal));


/* 
 * slurm_job_step_launch_t_init - initialize a user-allocated
 *      slurm_job_step_launch_t structure with default values.
 *	default values.  This function will NOT allocate any new memory.
 * IN ptr - pointer to a structure allocated by the use.  The structure will
 *      be intialized.
 */
extern void slurm_job_step_launch_t_init PARAMS((slurm_job_step_launch_t *ptr));

/*
 * slurm_step_launch - launch a parallel job step
 * IN ctx - job step context generated by slurm_step_ctx_create
 * RET SLURM_SUCCESS or SLURM_ERROR (with errno set)
 */
extern int slurm_step_launch PARAMS((slurm_step_ctx ctx,
	const slurm_job_step_launch_t *params));

/*
 * Block until all tasks have started.
 */
extern int slurm_step_launch_wait_start PARAMS((slurm_step_ctx ctx));

/*
 * Block until all tasks have finished (or failed to start altogether).
 */
extern void slurm_step_launch_wait_finish PARAMS((slurm_step_ctx ctx));

/*****************************************************************************\
 *	SLURM CONTROL CONFIGURATION READ/PRINT/UPDATE FUNCTIONS
\*****************************************************************************/

/*
 * slurm_api_version - Return a single number reflecting the SLURM API's 
 *	version number. Use the macros SLURM_VERSION_NUM, SLURM_VERSION_MAJOR, 
 *	SLURM_VERSION_MINOR, and SLURM_VERSION_MICRO to work with this value
 * RET API's version number
 */
extern long slurm_api_version PARAMS((void));

/*
 * slurm_load_ctl_conf - issue RPC to get slurm control configuration  
 *	information if changed since update_time 
 * IN update_time - time of current configuration data
 * IN slurm_ctl_conf_ptr - place to store slurm control configuration 
 *	pointer
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 * NOTE: free the response using slurm_free_ctl_conf
 */
extern int slurm_load_ctl_conf PARAMS((
	time_t update_time, 
	slurm_ctl_conf_t  **slurm_ctl_conf_ptr));

/*
 * slurm_free_ctl_conf - free slurm control information response message
 * IN msg - pointer to slurm control information response message
 * NOTE: buffer is loaded by slurm_load_ctl_conf
 */
extern void slurm_free_ctl_conf PARAMS((slurm_ctl_conf_t* slurm_ctl_conf_ptr));

/*
 * slurm_print_ctl_conf - output the contents of slurm control configuration 
 *	message as loaded using slurm_load_ctl_conf
 * IN out - file to write to
 * IN slurm_ctl_conf_ptr - slurm control configuration pointer
 */
extern void slurm_print_ctl_conf PARAMS((
	FILE * out, slurm_ctl_conf_t* slurm_ctl_conf));


/*****************************************************************************\
 *	SLURM JOB CONTROL CONFIGURATION READ/PRINT/UPDATE FUNCTIONS
\*****************************************************************************/

/*
 * slurm_load_jobs - issue RPC to get slurm all job configuration  
 *	information if changed since update_time 
 * IN update_time - time of current configuration data
 * IN job_info_msg_pptr - place to store a job configuration pointer
 * IN show_flags - job filtering options
 * RET 0 or -1 on error
 * NOTE: free the response using slurm_free_job_info_msg
 */
extern int slurm_load_jobs PARAMS((
	time_t update_time, job_info_msg_t **job_info_msg_pptr,
	uint16_t show_flags));

/*
 * slurm_free_job_info - free the job information response message
 * IN msg - pointer to job information response message
 * NOTE: buffer is loaded by slurm_load_jobs.
 */
extern void slurm_free_job_info_msg PARAMS((job_info_msg_t * job_buffer_ptr));

/*
 * slurm_print_job_info_msg - output information about all Slurm 
 *	jobs based upon message as loaded using slurm_load_jobs
 * IN out - file to write to
 * IN job_info_msg_ptr - job information message pointer
 * IN one_liner - print as a single line if true
 */
extern void slurm_print_job_info_msg PARAMS((
	FILE * out, job_info_msg_t * job_info_msg_ptr, int one_liner ));

/*
 * slurm_print_job_info - output information about a specific Slurm 
 *	job based upon message as loaded using slurm_load_jobs
 * IN out - file to write to
 * IN job_ptr - an individual job information record pointer
 * IN one_liner - print as a single line if true
 */
extern void slurm_print_job_info PARAMS(( FILE*, job_info_t * job_ptr, 
					  int one_liner ));

/*
 * slurm_sprint_job_info - output information about a specific Slurm 
 *	job based upon message as loaded using slurm_load_jobs
 * IN job_ptr - an individual job information record pointer
 * IN one_liner - print as a single line if true
 * RET out - char * containing formatted output (must be freed after call)
 *           NULL is returned on failure.
 */
extern char *slurm_sprint_job_info PARAMS(( job_info_t * job_ptr, 
				            int one_liner ));

/*
 * slurm_get_end_time - get the expected end time for a given slurm job
 * IN jobid     - slurm job id
 * end_time_ptr - location in which to store scheduled end time for job 
 * RET 0 or -1 on error
 */
extern int slurm_get_end_time PARAMS((uint32_t jobid, time_t *end_time_ptr));

/*
 * slurm_get_rem_time - get the expected time remaining for a given job
 * IN jobid     - slurm job id
 * RET remaining time in seconds or -1 on error
 */
extern long slurm_get_rem_time PARAMS((uint32_t jobid));

/*
 * slurm_pid2jobid - issue RPC to get the slurm job_id given a process_id 
 *	on this machine
 * IN job_pid - process_id of interest on this machine
 * OUT job_id_ptr - place to store a slurm job_id
 * RET 0 or -1 on error
 */
extern int slurm_pid2jobid PARAMS(( pid_t job_pid, uint32_t * job_id_ptr )) ;

/*
 * slurm_update_job - issue RPC to a job's configuration per request, 
 *	only usable by user root or (for some parameters) the job's owner
 * IN job_msg - description of job updates
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_update_job PARAMS(( job_desc_msg_t * job_msg )) ;

/*
 * slurm_get_select_jobinfo - get data from a select job credential
 * IN jobinfo  - updated select job credential
 * IN data_type - type of data to enter into job credential
 * IN/OUT data - the data to enter into job credential
 * RET 0 or -1 on error
 */
extern int slurm_get_select_jobinfo PARAMS((select_jobinfo_t jobinfo,
		enum select_data_type data_type, void *data));

/*****************************************************************************\
 *	SLURM JOB STEP CONFIGURATION READ/PRINT/UPDATE FUNCTIONS
\*****************************************************************************/

/*
 * slurm_get_job_steps - issue RPC to get specific slurm job step   
 *	configuration information if changed since update_time.
 *	a job_id value of zero implies all jobs, a step_id value of 
 *	zero implies all steps
 * IN update_time - time of current configuration data
 * IN job_id - get information for specific job id, zero for all jobs
 * IN step_id - get information for specific job step id, zero for all 
 *	job steps
 * IN step_response_pptr - place to store a step response pointer
 * IN show_flags - job step filtering options
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 * NOTE: free the response using slurm_free_job_step_info_response_msg
 */
extern int slurm_get_job_steps PARAMS((
	time_t update_time, uint32_t job_id, uint32_t step_id, 
	job_step_info_response_msg_t **step_response_pptr,
	uint16_t show_flags));

/*
 * slurm_free_job_step_info_response_msg - free the job step 
 *	information response message
 * IN msg - pointer to job step information response message
 * NOTE: buffer is loaded by slurm_get_job_steps.
 */
extern void slurm_free_job_step_info_response_msg PARAMS((
	job_step_info_response_msg_t * msg));

/*
 * slurm_print_job_step_info_msg - output information about all Slurm 
 *	job steps based upon message as loaded using slurm_get_job_steps
 * IN out - file to write to
 * IN job_step_info_msg_ptr - job step information message pointer
 * IN one_liner - print as a single line if true
 */
extern void slurm_print_job_step_info_msg PARAMS(( 
	FILE * out, job_step_info_response_msg_t * job_step_info_msg_ptr, 
	int one_liner ));

/*
 * slurm_print_job_step_info - output information about a specific Slurm 
 *	job step based upon message as loaded using slurm_get_job_steps
 * IN out - file to write to
 * IN job_ptr - an individual job step information record pointer
 * IN one_liner - print as a single line if true
 */
extern void slurm_print_job_step_info PARAMS(( 
	FILE * out, job_step_info_t * step_ptr, int one_liner ));

/*
 * slurm_job_step_layout_get - get the slurm_step_layout_t structure for
 *      a particular job step
 *
 * IN job_id
 * IN step_id
 * RET pointer to a slurm_step_layout_t (free with
 *   slurm_free_step_layout) on success, and NULL on error.
 */
extern slurm_step_layout_t *slurm_job_step_layout_get PARAMS((uint32_t job_id,
	                                                    uint32_t step_id));
/*
 * slurm_sprint_job_step_info - output information about a specific Slurm 
 *	job step based upon message as loaded using slurm_get_job_steps
 * IN job_ptr - an individual job step information record pointer
 * IN one_liner - print as a single line if true
 * RET out - char * containing formatted output (must be freed after call)
 *           NULL is returned on failure.
 */
extern char *slurm_sprint_job_step_info PARAMS(( job_step_info_t * step_ptr, 
					         int one_liner ));

void slurm_job_step_layout_free PARAMS((slurm_step_layout_t *layout));

/*****************************************************************************\
 *	SLURM NODE CONFIGURATION READ/PRINT/UPDATE FUNCTIONS
\*****************************************************************************/

/*
 * slurm_load_node - issue RPC to get slurm all node configuration information 
 *	if changed since update_time 
 * IN update_time - time of current configuration data
 * IN node_info_msg_pptr - place to store a node configuration pointer
 * IN show_flags - node filtering options
 * RET 0 or a slurm error code
 * NOTE: free the response using slurm_free_node_info_msg
 */
extern int slurm_load_node PARAMS((
	time_t update_time, node_info_msg_t **node_info_msg_pptr,
	uint16_t show_flags));

/*
 * slurm_free_node_info - free the node information response message
 * IN msg - pointer to node information response message
 * NOTE: buffer is loaded by slurm_load_node.
 */
extern void slurm_free_node_info_msg PARAMS((
	node_info_msg_t * node_buffer_ptr ));

/*
 * slurm_print_node_info_msg - output information about all Slurm nodes
 *	based upon message as loaded using slurm_load_node
 * IN out - file to write to
 * IN node_info_msg_ptr - node information message pointer
 * IN one_liner - print as a single line if true
 */
extern void slurm_print_node_info_msg PARAMS(( 
	FILE * out, node_info_msg_t * node_info_msg_ptr, int one_liner )) ;

/*
 * slurm_print_node_table - output information about a specific Slurm nodes
 *	based upon message as loaded using slurm_load_node
 * IN out - file to write to
 * IN node_ptr - an individual node information record pointer
 * IN one_liner - print as a single line if true
 */
extern void slurm_print_node_table PARAMS(( 
	FILE * out, node_info_t * node_ptr, int one_liner ));

/*
 * slurm_sprint_node_table - output information about a specific Slurm nodes
 *	based upon message as loaded using slurm_load_node
 * IN node_ptr - an individual node information record pointer
 * IN one_liner - print as a single line if true
 * RET out - char * containing formatted output (must be freed after call)
 *           NULL is returned on failure.
 */
extern char *slurm_sprint_node_table PARAMS(( node_info_t * node_ptr, 
					     int one_liner ));

/*
 * slurm_update_node - issue RPC to a node's configuration per request, 
 *	only usable by user root
 * IN node_msg - description of node updates
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_update_node PARAMS(( update_node_msg_t * node_msg ));


/*****************************************************************************\
 *	SLURM PARTITION CONFIGURATION READ/PRINT/UPDATE FUNCTIONS
\*****************************************************************************/

/* 
 * slurm_init_part_desc_msg - initialize partition descriptor with 
 *	default values 
 * OUT job_desc_msg - user defined partition descriptor
 */
extern void slurm_init_part_desc_msg PARAMS((update_part_msg_t * update_part_msg ));

/*
 * slurm_load_partitions - issue RPC to get slurm all partition configuration  
 *	information if changed since update_time 
 * IN update_time - time of current configuration data
 * IN partition_info_msg_pptr - place to store a partition configuration 
 *	pointer
 * IN show_flags - partitions filtering options
 * RET 0 or a slurm error code
 * NOTE: free the response using slurm_free_partition_info_msg
 */
extern int slurm_load_partitions PARAMS((
	time_t update_time, partition_info_msg_t **part_buffer_ptr,
	uint16_t show_flags));

/*
 * slurm_free_partition_info_msg - free the partition information 
 *	response message
 * IN msg - pointer to partition information response message
 * NOTE: buffer is loaded by slurm_load_partitions
 */
extern void slurm_free_partition_info_msg PARAMS(( 
	partition_info_msg_t * part_info_ptr ));

/*
 * slurm_print_partition_info_msg - output information about all Slurm 
 *	partitions based upon message as loaded using slurm_load_partitions
 * IN out - file to write to
 * IN part_info_ptr - partitions information message pointer
 * IN one_liner - print as a single line if true
 */
extern void slurm_print_partition_info_msg PARAMS((
	FILE * out, partition_info_msg_t * part_info_ptr, int one_liner ));

/*
 * slurm_print_partition_info - output information about a specific Slurm 
 *	partition based upon message as loaded using slurm_load_partitions
 * IN out - file to write to
 * IN part_ptr - an individual partition information record pointer
 * IN one_liner - print as a single line if true
 */
extern void slurm_print_partition_info PARAMS(( 
	FILE *out , partition_info_t * part_ptr, int one_liner ));

/*
 * slurm_sprint_partition_info - output information about a specific Slurm 
 *	partition based upon message as loaded using slurm_load_partitions
 * IN part_ptr - an individual partition information record pointer
 * IN one_liner - print as a single line if true
 * RET out - char * with formatted output (must be freed after call)
 *           NULL is returned on failure.
 */
extern char *slurm_sprint_partition_info PARAMS(( 
		partition_info_t * part_ptr, int one_liner ));
/*
 * slurm_update_partition - issue RPC to update a partition's configuration
 *	per request, only usable by user root
 * IN part_msg - description of partition updates
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_update_partition PARAMS(( update_part_msg_t * part_msg ));

/*
 * slurm_delete_partition - issue RPC to delete a partition, only usable
 *	by user root
 * IN part_msg - description of partition to delete
 * RET 0 on success, otherwise return -1 and set errno to indicate the error
 */
extern int slurm_delete_partition PARAMS(( delete_part_msg_t * part_msg ));

/*****************************************************************************\
 *	SLURM PING/RECONFIGURE/SHUTDOWN FUNCTIONS
\*****************************************************************************/

/*
 * slurm_ping - issue RPC to have Slurm controller (slurmctld)
 * IN controller - 1==primary controller, 2==secondary controller
 * RET 0 or a slurm error code
 */
extern int slurm_ping PARAMS(( int primary ));

/*
 * slurm_reconfigure - issue RPC to have Slurm controller (slurmctld)
 *	reload its configuration file 
 * RET 0 or a slurm error code
 */
extern int slurm_reconfigure PARAMS(( void ));

/*
 * slurm_shutdown - issue RPC to have Slurm controller (slurmctld)
 *	cease operations, both the primary and backup controller 
 *	are shutdown.
 * IN core - controller generates a core file if set
 * RET 0 or a slurm error code
 */
extern int slurm_shutdown PARAMS(( uint16_t core ));

/*****************************************************************************\
 *      SLURM JOB SUSPEND FUNCTIONS
\*****************************************************************************/

/*
 * slurm_suspend - suspend execution of a job.
 * IN job_id  - job on which to perform operation
 * RET 0 or a slurm error code
 */
extern int slurm_suspend PARAMS(( uint32_t job_id ));

/*
 * slurm_resume - resume execution of a previously suspended job.
 * IN job_id  - job on which to perform operation
 * RET 0 or a slurm error code
 */
extern int slurm_resume PARAMS(( uint32_t job_id ));

/*
 * slurm_requeue - re-queue a batch job, if already running
 *	then terminate it first
 * RET 0 or a slurm error code
 */
extern int slurm_requeue PARAMS(( uint32_t job_id ));

/*****************************************************************************\
 *      SLURM JOB CHECKPOINT FUNCTIONS
\*****************************************************************************/

/*
 * slurm_checkpoint_able - determine if the specified job step can presently
 *	be checkpointed
 * IN job_id  - job on which to perform operation
 * IN step_id - job step on which to perform operation
 * OUT start_time - time at which checkpoint request was issued
 * RET 0 (can be checkpoined) or a slurm error code
 */
extern int slurm_checkpoint_able (uint32_t job_id, uint32_t step_id,
		time_t *start_time);

/*
 * slurm_checkpoint_disable - disable checkpoint requests for some job step
 * IN job_id  - job on which to perform operation
 * IN step_id - job step on which to perform operation
 * RET 0 or a slurm error code
 */
extern int slurm_checkpoint_disable (uint32_t job_id, uint32_t step_id);


/*
 * slurm_checkpoint_enable - enable checkpoint requests for some job step
 * IN job_id  - job on which to perform operation
 * IN step_id - job step on which to perform operation
 * RET 0 or a slurm error code
 */
extern int slurm_checkpoint_enable (uint32_t job_id, uint32_t step_id);

/*
 * slurm_checkpoint_create - initiate a checkpoint requests for some job step.
 *	the job will continue execution after the checkpoint operation completes
 * IN job_id  - job on which to perform operation
 * IN step_id - job step on which to perform operation
 * IN max_wait - maximum wait for operation to complete, in seconds
 * RET 0 or a slurm error code
 */
extern int slurm_checkpoint_create (uint32_t job_id, uint32_t step_id, 
		uint16_t max_wait);

/*
 * slurm_checkpoint_vacate - initiate a checkpoint requests for some job step.
 *	the job will terminate after the checkpoint operation completes
 * IN job_id  - job on which to perform operation
 * IN step_id - job step on which to perform operation
 * IN max_wait - maximum wait for operation to complete, in seconds
 * RET 0 or a slurm error code
 */
extern int slurm_checkpoint_vacate (uint32_t job_id, uint32_t step_id, 
		uint16_t max_wait);

/*
 * slurm_checkpoint_restart - restart execution of a checkpointed job step.
 * IN job_id  - job on which to perform operation
 * IN step_id - job step on which to perform operation
 * RET 0 or a slurm error code
 */
extern int slurm_checkpoint_restart (uint32_t job_id, uint32_t step_id);

/*
 * slurm_checkpoint_complete - note the completion of a job step's checkpoint
 *	operation.
 * IN job_id  - job on which to perform operation
 * IN step_id - job step on which to perform operation
 * IN begin_time - time at which checkpoint began
 * IN error_code - error code, highest value for all complete calls is preserved
 * IN error_msg - error message, preserved for highest error_code
 * RET 0 or a slurm error code
 */
extern int slurm_checkpoint_complete (uint32_t job_id, uint32_t step_id,
		time_t begin_time, uint32_t error_code, char *error_msg);

/*
 * slurm_checkpoint_error - gather error information for the last checkpoint
 *	operation for some job step
 * IN job_id  - job on which to perform operation
 * IN step_id - job step on which to perform operation
 * OUT error_code - error number associated with the last checkpoint operation,
 *	this value is dependent upon the checkpoint plugin used and may be
 *	completely unrelated to slurm error codes, the highest value for all
 *	complete calls is preserved
 * OUT error_msg - error message, preserved for highest error_code, value
 *	must be freed by the caller to prevent memory leak
 * RET 0 or a slurm error code
 */
extern int slurm_checkpoint_error ( uint32_t job_id, uint32_t step_id,
		uint32_t *error_code, char **error_msg);


/*****************************************************************************\
 *      SLURM JOB STEP CLIENT-SIDE I/O FUNCTIONS
\*****************************************************************************/
END_C_DECLS

#endif

