/* $Id: heartbeat.h,v 1.39.2.6 2005/08/19 16:18:15 sunjd Exp $ */
/*
* heartbeat.h: core definitions for the Linux-HA heartbeat program
*
* Copyright (C) 2000 Alan Robertson <alanr@unix.sh>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _HEARTBEAT_H
# define _HEARTBEAT_H 1
#ifdef SYSV
# include <sys/termio.h>
# define TERMIOS termio
# define GETATTR(fd, s) ioctl(fd, TCGETA, s)
# define SETATTR(fd, s) ioctl(fd, TCSETA, s)
# define FLUSH(fd) ioctl(fd, TCFLSH, 2)
#else
# define TERMIOS termios
# include <termios.h>
# define GETATTR(fd, s) tcgetattr(fd, s)
# define SETATTR(fd, s) tcsetattr(fd, TCSAFLUSH, s)
# define FLUSH(fd) tcflush(fd, TCIOFLUSH)
#endif
#include <limits.h>
#include <syslog.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
#include <sys/times.h>
#include <netinet/in.h>
#include <HBauth.h>
#include <ha_msg.h>
#include <HBcomm.h>
#include <stonith/stonith.h>
#include <clplumbing/cl_log.h>
#include <clplumbing/longclock.h>
#include <clplumbing/ipc.h>
#include <clplumbing/cl_malloc.h>
#define index FooIndex
#define time FooTime
#include <glib.h>
#undef index
#undef time
/*
* <syslog.h> might not contain LOG_PRI...
* So, we define it ourselves, or error out if we can't...
*/
#ifndef LOG_PRI
# ifdef LOG_PRIMASK
/* David Lee <T.D.Lee@durham.ac.uk> reports this works on Solaris */
# define LOG_PRI(p) ((p) & LOG_PRIMASK)
# else
# error "Syslog.h does not define either LOG_PRI or LOG_PRIMASK."
# endif
#endif
#define MAXLINE MAXMSG
#define MAXFIELDS 30 /* Max # of fields in a msg */
#define HOSTLENG 100 /* Maximum size of "uname -a" return */
#define STATUSLENG 32 /* Maximum size of status field */
#define MAXIFACELEN 30 /* Maximum interface length */
#define MAXSERIAL 4
#define MAXMEDIA 64
#define MAXNODE 100
#define MAXPROCS ((2*MAXMEDIA)+2)
#define FIFOMODE 0600
#define RQSTDELAY 10
#ifndef HA_D
# define HA_D "/etc/ha.d"
#endif
#ifndef VAR_RUN_D
# define VAR_RUN_D HA_VARRUNDIR
#endif
#ifndef VAR_LOG_D
# define VAR_LOG_D "/var/log"
#endif
#ifndef HALIB
# define HALIB "/usr/lib/heartbeat"
#endif
#ifndef HA_MODULE_D
# define HA_MODULE_D HALIB "/modules"
#endif
#ifndef HA_PLUGIN_D
# define HA_PLUGIN_D HALIB "/plugins"
#endif
#ifndef TTY_LOCK_D
# if defined(linux)
# define TTY_LOCK_D "/var/lock"
# else
# define TTY_LOCK_D "/var/spool/lock"
# endif
#endif
#ifndef RSC_TMPDIR
# define RSC_TMPDIR VAR_LIB_D "/rsctmp"
#endif
/* #define HA_DEBUG */
#define DEFAULTLOG VAR_LOG_D "/ha-log"
#define DEFAULTDEBUG VAR_LOG_D "/ha-debug"
#define DEVNULL "/dev/null"
#define HA_OKEXIT 0
#define HA_FAILEXIT 1
#define WHITESPACE " \t\n\r\f"
#define DELIMS ", \t\n\r\f"
#define COMMENTCHAR '#'
#define CRLF "\r\n"
#define STATUS "STATUS"
#define INITSTATUS "init" /* Status of a node we've never heard from */
#define UPSTATUS "up" /* Listening (we might not be xmitting) */
#define ACTIVESTATUS "active" /* fully functional, and all links are up */
#define DEADSTATUS "dead" /* Status of non-working link or machine */
#define PINGSTATUS "ping" /* Status of a working ping node */
#define JOINSTATUS "join" /* Status when an api client joins */
#define LEAVESTATUS "leave" /* Status when an api client leaves */
#define ONLINESTATUS "online" /* Status of an online client */
#define OFFLINESTATUS "offline" /* Status of an offline client */
#define LINKUP "up" /* The status assigned to a working link */
#define LOADAVG "/proc/loadavg"
#define PIDFILE VAR_RUN_D "/heartbeat.pid"
#define KEYFILE HA_D "/authkeys"
#define HA_SERVICENAME "ha-cluster" /* Our official reg'd service name */
#define UDPPORT 694 /* Our official reg'd port number */
/* Environment variables we pass to our scripts... */
#define CURHOSTENV "HA_CURHOST"
#define OLDSTATUS "HA_OSTATUS"
#define DATEFMT "HA_DATEFMT" /* Format string for date(1) */
#define LOGFENV "HA_LOGFILE" /* well-formed log file :-) */
#define DEBUGFENV "HA_DEBUGLOG" /* Debug log file */
#define LOGFACILITY "HA_LOGFACILITY"/* Facility to use for logger */
#define HADIRENV "HA_DIR" /* The base HA directory */
#define HAFUNCENV "HA_FUNCS" /* Location of ha shell functions */
#define HANICEFAILBACK "HA_NICEFAILBACK" /* "yes" when nice_failback is on */
#define HADONTASK "HA_DONTASK" /* "yes" when no other nodes "active" ...*/
#define HADEBUGVAL "HA_DEBUG" /* current debug value (if nonzero) */
#define DEFAULTBAUD B19200 /* Default serial link speed */
#define DEFAULTBAUDRATE 19200 /* Default serial link speed as int */
#define DEFAULTBAUDSTR "19200" /* Default serial link speed as string */
/* multicast defaults */
#define DEFAULT_MCAST_IPADDR "225.0.0.1" /* Default multicast group */
#define DEFAULT_MCAST_TTL 1 /* Default multicast TTL */
#define DEFAULT_MCAST_LOOP 0 /* Default mulitcast loopback option */
#define HB_STATIC_PRIO 1 /* Used with soft realtime scheduling */
#ifndef PPP_D
# define PPP_D VAR_RUN_D "/ppp.d"
#endif
#ifndef FIFONAME
# define FIFONAME VAR_LIB_D "/fifo"
#endif
#define RCSCRIPT HA_D "/harc"
#define CONFIG_NAME HA_D "/ha.cf"
#define RESOURCE_CFG HA_D "/haresources"
/* dynamic module directories */
#define COMM_MODULE_DIR HA_MODULE_D "/comm"
#define AUTH_MODULE_DIR HA_MODULE_D "/auth"
#define STATIC /* static */
/* You may need to change this for your compiler */
#ifdef HAVE_STRINGIZE
# define ASSERT(X) {if(!(X)) ha_assert(#X, __LINE__, __FILE__);}
#else
# define ASSERT(X) {if(!(X)) ha_assert("X", __LINE__, __FILE__);}
#endif
#define HA_DATEFMT "%Y/%m/%d_%T\t"
#define HA_FUNCS HA_D "/shellfuncs"
#define RC_ARG0 "harc"
/* Which side of a pipe is which? */
#define P_READFD 0
#define P_WRITEFD 1
#define FD_STDIN 0
#define FD_STDOUT 1
#define FD_STDERR 2
typedef unsigned long seqno_t;
#define MAXMISSING 16
#define NOSEQUENCE 0xffffffffUL
struct seqtrack {
longclock_t last_rexmit_req;
int nmissing;
seqno_t generation; /* Heartbeat generation # */
seqno_t last_seq;
seqno_t seqmissing[MAXMISSING];
const char * last_iface;
};
struct link {
longclock_t lastupdate;
const char * name;
int isping;
char status[STATUSLENG]; /* up or down */
TIME_T rmt_lastupdate; /* node's idea of last update time for this link */
};
#define NORMALNODE_I 0
#define PINGNODE_I 1
#define NORMALNODE "normal"
#define PINGNODE "ping"
#define UNKNOWNNODE "unknown"
struct node_info {
int nodetype;
char nodename[HOSTLENG]; /* Host name from config file */
char status[STATUSLENG]; /* Status from heartbeat */
struct link links[MAXMEDIA];
int nlinks;
TIME_T rmt_lastupdate; /* node's idea of last update time */
seqno_t status_seqno; /* Seqno of last status update */
longclock_t dead_ticks; /* # ticks to declare dead */
longclock_t local_lastupdate;/* Date of last update in clock_t time*/
int anypacketsyet; /* True after reception of 1st pkt */
struct seqtrack track;
int has_resources; /* TRUE if node may have resources */
};
#define MAXAUTH 16
#ifndef PATH_MAX
# define PATH_MAX MAXPATHLEN
#endif
struct sys_config {
TIME_T cfg_time; /* Timestamp of config file */
TIME_T auth_time; /* Timestamp of authorization file */
TIME_T rsc_time; /* Timestamp of haresources file */
int format_vers; /* Version of this info */
int nodecount; /* Number of nodes in cluster */
long heartbeat_ms; /* Milliseconds between heartbeats */
long deadtime_ms; /* Ticks before declaring dead */
long deadping_ms; /* Ticks before declaring ping nodes */
long initial_deadtime_ms; /* Ticks before saying dead 1st time*/
long warntime_ms; /* Ticks before issuing warning */
int hopfudge; /* hops beyond nodecount allowed */
int log_facility; /* syslog facility, if any */
char facilityname[PATH_MAX]; /* syslog facility name (if any) */
char logfile[PATH_MAX]; /* path to log file, if any */
int use_logfile; /* Flag to use the log file*/
char dbgfile[PATH_MAX]; /* path to debug file, if any */
int use_dbgfile; /* Flag to use the debug file*/
int rereadauth; /* 1 if we need to reread auth file */
seqno_t generation; /* Heartbeat generation # */
int authnum;
Stonith* stonith; /* Stonith method: WE NEED A LIST TO SUPPORT MULTIPLE STONITH DEVICES PER NODE -EZA */
struct HBauth_info* authmethod; /* auth_config[authnum] */
struct node_info nodes[MAXNODE];
struct HBauth_info auth_config[MAXAUTH];
GList* client_list;
/* List data: struct client_child */
/* These all show up in client_children */
/* when they're spawned (and have a pid) */
GHashTable* client_children;/* Indexed by pid */
/* associated data: struct client_child */
/* They appear here after being spawned */
};
struct hb_media {
void * pd; /* Private Data */
const char * name; /* Unique medium name */
char* type; /* Medium type */
char* description; /* Medium description */
const struct hb_media_fns*vf; /* Virtual Functions */
IPC_Channel* wchan[2];
/* Read by the write child processes. */
IPC_Channel* rchan[2];
/* Written to by the read child processes. */
};
int parse_authfile(void);
#define MAXMSGHIST 1000
struct msg_xmit_hist {
struct ha_msg* msgq[MAXMSGHIST];
seqno_t seqnos[MAXMSGHIST];
longclock_t lastrexmit[MAXMSGHIST];
int lastmsg;
seqno_t hiseq;
seqno_t lowseq; /* one less than min actually present */
};
/*
* client_child: information on clients that we spawn and keep track of
* They don't strictly have to use the client API, but most probably do.
* We start them when we start up, and shut them down when we shut down.
* Normally, if they they die, we restart them.
*/
struct client_child {
pid_t pid; /* Process id of child process */
int respawn; /* Respawn it if it dies? */
uid_t u_runas; /* Which user to run as? */
gid_t g_runas; /* Which group id to run as? */
int respawncount; /* Last time we respawned this command */
int shortrcount; /* How many times has it respawned too fast? */
char* command; /* What command to run? */
char* path; /* Path (argv[0])? */
};
int api_remove_client_pid(pid_t c_pid, const char * reason);
extern struct sys_config * config;
extern int debug;
extern int udpport;
extern int RestartRequested;
extern char * localnodename;
#define ANYDEBUG (debug)
#define DEBUGDETAILS (debug >= 2)
#define DEBUGAUTH (debug >=3)
#define DEBUGMODULE (debug >=3)
#define DEBUGPKT (debug >= 4)
#define DEBUGPKTCONT (debug >= 5)
#define ha_log cl_log
#define ha_perror cl_perror
/* Generally useful exportable HA heartbeat routines... */
extern void ha_assert(const char *s, int line, const char * file);
extern int send_cluster_msg(struct ha_msg*msg);
extern void cleanexit(int exitcode);
extern void check_auth_change(struct sys_config *);
extern void (*localdie)(void);
extern int should_ring_copy_msg(struct ha_msg* m);
extern int controlipc2msg(IPC_Channel * channel
, struct ha_msg **);
extern int add_msg_auth(struct ha_msg * msg);
extern unsigned char * calc_cksum(const char * authmethod, const char * key, const char * value);
struct node_info * lookup_node(const char *);
struct link * lookup_iface(struct node_info * hip, const char *iface);
struct link * iface_lookup_node(const char *);
int add_node(const char * value, int nodetype);
void SetParameterValue(const char * name, const char * value);
#ifndef HA_HAVE_SETENV
int setenv(const char *name, const char * value, int why);
#endif
#ifndef HA_HAVE_SCANDIR
#include <dirent.h>
int
scandir (const char *directory_name,
struct dirent ***array_pointer,
int (*select_function) (const struct dirent *),
#ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT
/* This is what the Linux man page says */
int (*compare_function) (const struct dirent**, const struct dirent**)
#else
/* This is what the Linux header file says ... */
int (*compare_function) (const void *, const void *)
#endif
);
#endif /* HAVE_SCANDIR */
#endif /* _HEARTBEAT_H */
syntax highlighted by Code2HTML, v. 0.9.1